18792927508 2 年 前
コミット
fd4a2e4c23
共有19 個のファイルを変更した1131 個の追加34 個の削除を含む
  1. 52
    1
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/wisdomarbitrate/mscase/MsCaseApplicationController.java
  2. 172
    0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/wisdomarbitrate/mscase/MsVideoConferenceController.java
  3. 1
    0
      ruoyi-common/src/main/java/com/ruoyi/common/enums/AnnexTypeEnum.java
  4. 3
    3
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/entity/mscase/MsCaseApplication.java
  5. 41
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/vo/mscase/BookingVO.java
  6. 18
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/vo/mscase/MsCaseApplicationReq.java
  7. 4
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/vo/mscase/MsCaseApplicationVO.java
  8. 29
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/vo/mscase/SendRoomNoMessageVO.java
  9. 26
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/vo/mscase/VideoCallBackVO.java
  10. 22
    13
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/mapper/mscase/MsCaseApplicationMapper.java
  11. 2
    3
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/mapper/mscase/MsCaseLogRecordMapper.java
  12. 22
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/mscase/MsCaseApplicationService.java
  13. 83
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/mscase/VideoConferenceService.java
  14. 171
    10
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/mscase/impl/MsCaseApplicationServiceImpl.java
  15. 2
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/mscase/impl/MsCasePaymentServiceImpl.java
  16. 457
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/mscase/impl/VideoConferenceServiceImpl.java
  17. 2
    2
      ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
  18. 16
    0
      ruoyi-system/src/main/resources/mapper/wisdomarbitrate/mscase/MsCaseApplicationMapper.xml
  19. 8
    2
      ruoyi-system/src/main/resources/mapper/wisdomarbitrate/mscase/MsCaseLogRecordMapper.xml

+ 52
- 1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/wisdomarbitrate/mscase/MsCaseApplicationController.java ファイルの表示

@@ -1,11 +1,13 @@
1 1
 package com.ruoyi.web.controller.wisdomarbitrate.mscase;
2 2
 
3 3
 
4
+import cn.hutool.core.collection.CollectionUtil;
4 5
 import cn.hutool.core.util.StrUtil;
5 6
 import com.ruoyi.common.core.controller.BaseController;
6 7
 import com.ruoyi.common.core.domain.AjaxResult;
7 8
 import com.ruoyi.common.core.page.TableDataInfo;
8 9
 import com.ruoyi.wisdomarbitrate.domain.entity.mscase.MsCaseApplication;
10
+import com.ruoyi.wisdomarbitrate.domain.vo.mscase.BookingVO;
9 11
 import com.ruoyi.wisdomarbitrate.domain.vo.mscase.MsCaseApplicationReq;
10 12
 import com.ruoyi.wisdomarbitrate.domain.vo.mscase.MsCaseApplicationVO;
11 13
 import com.ruoyi.wisdomarbitrate.service.mscase.MsCaseApplicationService;
@@ -33,7 +35,7 @@ public class MsCaseApplicationController extends BaseController {
33 35
     @GetMapping("/list")
34 36
     public TableDataInfo page(MsCaseApplicationReq req)
35 37
     {
36
-        startPage();
38
+        //startPage();
37 39
         List<MsCaseApplicationVO> list = caseApplicationService.list(req);
38 40
         return getDataTable(list);
39 41
     }
@@ -150,5 +152,54 @@ public class MsCaseApplicationController extends BaseController {
150 152
     public AjaxResult listMediator( ) {
151 153
         return caseApplicationService.listMediator();
152 154
     }
155
+    /**
156
+     * 保存预约
157
+     * @param
158
+     * @return
159
+     */
160
+    @PostMapping("/updateBooking")
161
+    public AjaxResult updateBooking(@RequestBody BookingVO vo ) {
162
+        if(vo.getId()==null || CollectionUtil.isEmpty(vo.getHerDates())|| CollectionUtil.isEmpty(vo.getUserList())){
163
+            return error("参数校验失败");
164
+        }
165
+        return caseApplicationService.updateBooking(vo);
166
+    }
167
+    /**
168
+     * 核实调解员
169
+     * @param
170
+     * @return
171
+     */
172
+    @PostMapping("/verifyMediator")
173
+    public AjaxResult verifyMediator(@RequestBody BookingVO vo ) {
174
+        if((vo.getId() == null && StrUtil.isEmpty(vo.getBatchNumber()))
175
+                || vo.getCaseFlowId()==null
176
+                || CollectionUtil.isEmpty(vo.getUserList())){
177
+            return error("参数校验失败");
178
+        }
179
+        return caseApplicationService.verifyMediator(vo);
180
+    }
181
+    /**
182
+     * 确认调解时间
183
+     * @param
184
+     * @return
185
+     */
186
+    @PostMapping("/confirmDate")
187
+    public AjaxResult confirmDate(@RequestBody BookingVO vo ) {
188
+        if((vo.getId() == null && StrUtil.isEmpty(vo.getBatchNumber()))
189
+                || vo.getCaseFlowId()==null
190
+                || CollectionUtil.isEmpty(vo.getHerDates())){
191
+            return error("参数校验失败");
192
+        }
193
+        return caseApplicationService.verifyMediator(vo);
194
+    }
195
+    /**
196
+     * 查询预约信息
197
+     * @param
198
+     * @return
199
+     */
200
+    @GetMapping("/selectReservation")
201
+    public AjaxResult selectReservation(@RequestParam("id") Long id ) {
202
+        return caseApplicationService.selectReservation(id);
203
+    }
153 204
 
154 205
 }

+ 172
- 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/wisdomarbitrate/mscase/MsVideoConferenceController.java ファイルの表示

@@ -0,0 +1,172 @@
1
+package com.ruoyi.web.controller.wisdomarbitrate.mscase;
2
+
3
+import cn.hutool.core.util.StrUtil;
4
+import com.ruoyi.common.annotation.Anonymous;
5
+import com.ruoyi.common.core.controller.BaseController;
6
+import com.ruoyi.common.core.domain.AjaxResult;
7
+import com.ruoyi.wisdomarbitrate.domain.vo.mscase.MsReservedConferenceVO;
8
+import com.ruoyi.wisdomarbitrate.domain.vo.mscase.SendRoomNoMessageVO;
9
+import com.ruoyi.wisdomarbitrate.domain.vo.mscase.VideoCallBackVO;
10
+import com.ruoyi.wisdomarbitrate.service.mscase.VideoConferenceService;
11
+import org.springframework.beans.factory.annotation.Autowired;
12
+import org.springframework.validation.annotation.Validated;
13
+import org.springframework.web.bind.annotation.*;
14
+
15
+import javax.validation.Valid;
16
+
17
+/**
18
+ * 视频会议控制层
19
+ * @Author wangqiong
20
+ * @Date 2024/01/8
21
+ * @Version V1.0
22
+ */
23
+@RestController
24
+@RequestMapping("/video")
25
+public class MsVideoConferenceController extends BaseController {
26
+    @Autowired
27
+    private VideoConferenceService videoService;
28
+    /**
29
+     * 根据案件ID查询视频
30
+     * @param caseId 案件id
31
+     * @return
32
+     */
33
+    @GetMapping("/videoList")
34
+    public AjaxResult videoList(@RequestParam("caseId") Long caseId) {
35
+
36
+        return videoService.videoList(caseId);
37
+    }
38
+    /**
39
+     * 获取userSign
40
+     * @param userId
41
+     * @return
42
+     */
43
+    @Anonymous
44
+    @GetMapping("/generateUserSign")
45
+    public AjaxResult generateUserSign(@RequestParam(required = true) String userId){
46
+        if(StrUtil.isEmpty(userId)){
47
+            error("参数校验失败");
48
+        }
49
+        return AjaxResult.success(videoService.generateUserSign(userId));
50
+    }
51
+    /**
52
+     * 生成房间号
53
+     * @return
54
+     */
55
+    @Anonymous
56
+    @GetMapping("/createRoomId")
57
+    public AjaxResult createRoomId(@RequestParam("caseId") Long caseId) {
58
+
59
+        return  success(videoService.createRoomId(caseId));
60
+    }
61
+    /**
62
+     * 根据案件id查询已预约的会议
63
+     * @param caseId
64
+     * @return
65
+     */
66
+    @Anonymous
67
+    @GetMapping("/reserveConferenceList")
68
+    public AjaxResult reserveConferenceList(  @RequestParam("caseId") Long caseId) {
69
+
70
+        return  success(videoService.reserveConferenceList(caseId));
71
+    }
72
+    /**
73
+     * 预约会议
74
+     * @param reservedConferenceVO
75
+     * @return
76
+     */
77
+    @PostMapping("/reservedConference")
78
+    public AjaxResult reservedConference(@Validated @RequestBody MsReservedConferenceVO reservedConferenceVO) throws Exception {
79
+
80
+        return videoService.reservedConference(reservedConferenceVO);
81
+    }
82
+    /**
83
+     * 从腾讯云下载文件到本地
84
+     * @param
85
+     * @return
86
+     */
87
+    @Anonymous
88
+    @PostMapping("/videoRollBack")
89
+    public AjaxResult videoRollBack(  @RequestBody VideoCallBackVO vo) {
90
+        if(StrUtil.isNotEmpty(vo.getFileId()) && StrUtil.isNotEmpty(vo.getVideoUrl()) && StrUtil.isNotEmpty(vo.getRoomId())) {
91
+            videoService.videoRollBack(vo.getFileId(), vo.getVideoUrl(), vo.getRoomId());
92
+        }
93
+        return success();
94
+    }
95
+    /**
96
+     * 根据房间号绑定案件ID
97
+     * @param
98
+     * @return
99
+     */
100
+    @Anonymous
101
+    @PostMapping("/bindCaseId")
102
+    public AjaxResult bindCaseId(@Valid @RequestBody SendRoomNoMessageVO vo) {
103
+
104
+        return videoService.bindCaseId(vo.getId(),vo.getRoomNo());
105
+    }
106
+
107
+    /**
108
+     * 开启腾讯云录制
109
+     * @param vo
110
+     * @return
111
+     * @throws Exception
112
+     */
113
+    @Anonymous
114
+    @PostMapping("/openCloudRecording")
115
+    private AjaxResult openCloudRecording( @RequestBody MsReservedConferenceVO vo)  {
116
+        if(vo.getCaseId()==null || vo.getRoomId()==null){
117
+            return AjaxResult.error("参数错误");
118
+        }
119
+        return videoService.openCloudRecording(vo.getCaseId(),vo.getRoomId());
120
+    }
121
+    /**
122
+     * 关闭腾讯云录制
123
+     * @param taskId 任务ID
124
+     * @return
125
+     */
126
+    @Anonymous
127
+    @PostMapping("/closeDeleteCloudRecording")
128
+    public AjaxResult closeDeleteCloudRecording(@RequestParam("taskId") String taskId){
129
+        return videoService.closeDeleteCloudRecording(taskId);
130
+    }
131
+    /**
132
+     * 解散房间
133
+     * @param reservedConferenceVO
134
+     * @return
135
+     */
136
+    @Anonymous
137
+    @PostMapping("/dissolveRoom")
138
+    public AjaxResult dissolveRoom(   @RequestBody MsReservedConferenceVO reservedConferenceVO) {
139
+        if( reservedConferenceVO.getRoomId()==null){
140
+            return error("参数校验失败");
141
+        }
142
+
143
+        return  videoService.dissolveRoom(reservedConferenceVO.getRoomId());
144
+    }
145
+    /**
146
+     * 根据userId查询该用户是否是秘书
147
+     * @param userId
148
+     * @return
149
+     */
150
+    @Anonymous
151
+    @GetMapping("secretaryRoleByUserId")
152
+    public AjaxResult secretaryRoleByUserId(   @RequestParam(value = "userId",required = true) Long userId) {
153
+
154
+        return  videoService.secretaryRoleByUserId(userId);
155
+    }
156
+    /**
157
+     * 根据html字符串转pdf并和案件关联
158
+     * @param reservedConferenceVO
159
+     * @return
160
+     */
161
+    @Anonymous
162
+    @PostMapping("htmlToPDF")
163
+    public AjaxResult secretaryRoleByUserId( @RequestBody MsReservedConferenceVO reservedConferenceVO) {
164
+        if( reservedConferenceVO.getCaseId()==null || StrUtil.isEmpty(reservedConferenceVO.getHtmlContent())){
165
+            return success();
166
+        }
167
+
168
+        return  videoService.htmlToPDF(reservedConferenceVO);
169
+    }
170
+
171
+
172
+}

+ 1
- 0
ruoyi-common/src/main/java/com/ruoyi/common/enums/AnnexTypeEnum.java ファイルの表示

@@ -14,6 +14,7 @@ public enum AnnexTypeEnum implements EnumsInterface {
14 14
     APPLICATION_EVIDENCE(2, "申请人证据"),
15 15
     MEDIATION_APPLICATION(3, "调解申请书"),
16 16
     PAYMENT_RECEIPT(4, "缴费单"),
17
+    MEETING_VIDEO(5, "会议视频"),
17 18
 
18 19
     ;
19 20
 

+ 3
- 3
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/entity/mscase/MsCaseApplication.java ファイルの表示

@@ -30,7 +30,7 @@ public class MsCaseApplication {
30 30
      * 批次
31 31
      */
32 32
     @Column(name = "batch_number")
33
-    private String batchNumber;
33
+    private String batchNumber=null;
34 34
 
35 35
     /**
36 36
      * 模板id
@@ -71,7 +71,7 @@ public class MsCaseApplication {
71 71
      * 开庭日期
72 72
      */
73 73
     @Column(name = "hear_date")
74
-    private Date hearDate;
74
+    private String hearDate;
75 75
 
76 76
     /**
77 77
      * 调解应缴费用
@@ -83,7 +83,7 @@ public class MsCaseApplication {
83 83
      * 调解员id
84 84
      */
85 85
     @Column(name = "mediator_id")
86
-    private Long mediatorId;
86
+    private String mediatorId;
87 87
 
88 88
     /**
89 89
      * 调解员名称

+ 41
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/vo/mscase/BookingVO.java ファイルの表示

@@ -0,0 +1,41 @@
1
+package com.ruoyi.wisdomarbitrate.domain.vo.mscase;
2
+
3
+import com.ruoyi.common.core.domain.entity.SysUser;
4
+import lombok.Data;
5
+
6
+import java.util.List;
7
+
8
+/**
9
+ * @Classname BookingVO
10
+ * @Description 保存预约
11
+ * @Version 1.0.0
12
+ * @Date 2024/1/16 16:40
13
+ * @Created wangqiong
14
+ */
15
+@Data
16
+public class BookingVO {
17
+    /**
18
+     * 调解员列表
19
+     */
20
+    private List<SysUser> userList;
21
+    /**
22
+     * 调解员列表
23
+     */
24
+    private List<MediatorVO> mediatorList;
25
+    /**
26
+     * 开庭日期集合
27
+     */
28
+    private List<String> herDates;
29
+    /**
30
+     * 案件id
31
+     */
32
+    private Long id;
33
+    /**
34
+     * 案件id
35
+     */
36
+    private Integer caseFlowId;
37
+    /**
38
+     * 批次
39
+     */
40
+    private String batchNumber;
41
+}

+ 18
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/vo/mscase/MsCaseApplicationReq.java ファイルの表示

@@ -41,6 +41,24 @@ public class MsCaseApplicationReq {
41 41
      * 结束时间
42 42
      */
43 43
     private String endTime;
44
+    /**
45
+     * 用户名
46
+     */
44 47
     private String userName;
48
+    /**
49
+     * 是否同意,0-否,1-是
50
+     */
51
+    private Integer yesOrNo;
52
+    /**
53
+     * 调解员id
54
+     */
55
+
56
+    private String mediatorId;
57
+
58
+    /**
59
+     * 调解员名称
60
+     */
61
+
62
+    private String mediatorName;
45 63
 
46 64
 }

+ 4
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/vo/mscase/MsCaseApplicationVO.java ファイルの表示

@@ -53,5 +53,9 @@ public class MsCaseApplicationVO extends MsCaseApplication {
53 53
      * 自定义字段
54 54
      */
55 55
     private List<MsColumnValueVO> columnValueList;
56
+    /**
57
+     * 待办状态,0-待办,1-已办
58
+     */
59
+    private Integer pendingStatus;
56 60
 
57 61
 }

+ 29
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/vo/mscase/SendRoomNoMessageVO.java ファイルの表示

@@ -0,0 +1,29 @@
1
+package com.ruoyi.wisdomarbitrate.domain.vo.mscase;
2
+
3
+import com.fasterxml.jackson.annotation.JsonFormat;
4
+import lombok.Data;
5
+
6
+import javax.validation.constraints.NotEmpty;
7
+import javax.validation.constraints.NotNull;
8
+import java.io.Serializable;
9
+import java.util.Date;
10
+
11
+/**
12
+ * @author wangqiong
13
+ * @description 发送房间号短信入参类
14
+ * @date 2023-10-10 15:20
15
+ */
16
+@Data
17
+public class SendRoomNoMessageVO implements Serializable {
18
+    private static final long serialVersionUID = 1L;
19
+    @NotNull(message = "案件id不能为空")
20
+    private Long id;
21
+    @NotEmpty(message = "房间号不能为空")
22
+    private String roomNo;
23
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
24
+    private Date scheduleStartTime;
25
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
26
+    private Date scheduleEndTime;
27
+
28
+
29
+}

+ 26
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/vo/mscase/VideoCallBackVO.java ファイルの表示

@@ -0,0 +1,26 @@
1
+package com.ruoyi.wisdomarbitrate.domain.vo.mscase;
2
+
3
+import lombok.Data;
4
+
5
+/**
6
+ * @Classname VideoCallBackVO
7
+ * @Description 视频回调VO
8
+ * @Version 1.0.0
9
+ * @Date 2024/1/18 15:02
10
+ * @Created wangqiong
11
+ */
12
+@Data
13
+public class VideoCallBackVO {
14
+    /**
15
+     * 附件id
16
+     */
17
+    private String fileId;
18
+    /**
19
+     * 视频地址
20
+     */
21
+    private String videoUrl;
22
+    /**
23
+     * 房间号
24
+     */
25
+    private String roomId;
26
+}

+ 22
- 13
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/mapper/mscase/MsCaseApplicationMapper.java ファイルの表示

@@ -1,7 +1,6 @@
1 1
 package com.ruoyi.wisdomarbitrate.mapper.mscase;
2 2
 
3 3
 import com.ruoyi.wisdomarbitrate.domain.entity.mscase.MsCaseApplication;
4
-import com.ruoyi.wisdomarbitrate.domain.vo.mscase.MediatorVO;
5 4
 import com.ruoyi.wisdomarbitrate.domain.vo.mscase.MsCaseApplicationReq;
6 5
 import com.ruoyi.wisdomarbitrate.domain.vo.mscase.MsCaseApplicationVO;
7 6
 import org.apache.ibatis.annotations.Param;
@@ -35,7 +34,7 @@ public interface MsCaseApplicationMapper extends Mapper<MsCaseApplication> {
35 34
      * @param caseStatusNames
36 35
      * @return
37 36
      */
38
-    @Select("<script> select t.* from (select c.id,c.case_flow_id caseFlowId,c.batch_number batchNumber,c.case_num caseNum,c.case_subject_amount caseSubjectAmount," +
37
+    @Select("<script> select t.* from (select c.id,0 AS pendingStatus,c.case_flow_id caseFlowId,c.batch_number batchNumber,c.case_num caseNum,c.case_subject_amount caseSubjectAmount," +
39 38
             "a.application_organ_name applicationOrganName,a.respondent_name respondentName,c.mediator_name mediatorName," +
40 39
             "c.hear_date hearDate,c.case_status_name caseStatusName,c.create_time createTime from ms_case_application c " +
41 40
             "join ms_case_affiliate a on c.id=a.case_appli_id <where> " +
@@ -62,17 +61,19 @@ public interface MsCaseApplicationMapper extends Mapper<MsCaseApplication> {
62 61
             "<if test=\"req.endTime != null and req.endTime != ''\">" +
63 62
             "and c.create_time &lt;= #{req.endTime}</if>" +
64 63
             "        </where> " +
65
-            "union  select c.id id,c.case_flow_id caseFlowId,c.batch_number batchNumber,c.case_num caseNum,c.case_subject_amount caseSubjectAmount," +
64
+            "union  select c.id id,1 AS pendingStatus,c.case_flow_id caseFlowId,c.batch_number batchNumber,c.case_num caseNum,c.case_subject_amount caseSubjectAmount," +
66 65
             "a.application_organ_name applicationOrganName,a.respondent_name respondentName,c.mediator_name mediatorName," +
67 66
             "c.hear_date hearDate,c.case_status_name caseStatusName,c.create_time createTime from ms_case_log_record r " +
68 67
             "join ms_case_application c on r.case_appli_id=c.id and r.case_status_name!=c.case_status_name " +
69 68
             "join ms_case_affiliate a on c.id=a.case_appli_id  <where> r.create_by=#{req.userName}  and c.id not in (" +
70
-            "select c1.id from  ms_case_application c1 JOIN ms_case_affiliate a1 ON a1.case_appli_id = c1.id" +
69
+            "select c1.id from  ms_case_application c1 JOIN ms_case_affiliate a1 ON a1.case_appli_id = c1.id"
70
+            +
71 71
             "<if test='caseStatusNames != null and caseStatusNames.size() > 0 '> and  c.case_status_name in" +
72 72
             "<foreach item='caseStatus' index='index' collection='caseStatusNames' open='(' separator=',' close=')'>" +
73 73
             "#{caseStatus}" +
74 74
             "</foreach>" +
75
-            "</if> " +
75
+            "</if> "
76
+            +
76 77
             "<if test=\"req.batchNumber != null and req.batchNumber != ''\">" +
77 78
             "    AND c1.batch_number = #{req.batchNumber} " +
78 79
             "</if> " +
@@ -90,12 +91,14 @@ public interface MsCaseApplicationMapper extends Mapper<MsCaseApplication> {
90 91
             "<if test=\"req.endTime != null and req.endTime != ''\">"  +
91 92
             "and c1.create_time &lt;= #{req.endTime}</if>" +
92 93
             "        </where> " +
93
-            "                    ) " +
94
-            "<if test='caseStatusNames != null and caseStatusNames.size() > 0 '> and  c.case_status_name in" +
95
-            "<foreach item='caseStatus' index='index' collection='caseStatusNames' open='(' separator=',' close=')'>" +
96
-            "#{caseStatus}" +
97
-            "</foreach>" +
98
-            "</if> " +
94
+            "                    ) "
95
+//            +
96
+//            "<if test='caseStatusNames != null and caseStatusNames.size() > 0 '> and  c.case_status_name in" +
97
+//            "<foreach item='caseStatus' index='index' collection='caseStatusNames' open='(' separator=',' close=')'>" +
98
+//            "#{caseStatus}" +
99
+//            "</foreach>" +
100
+//            "</if> "
101
+            +
99 102
             "<if test=\"req.batchNumber != null and req.batchNumber != ''\">" +
100 103
             "    AND c.batch_number = #{req.batchNumber} " +
101 104
             "</if> " +
@@ -120,6 +123,12 @@ public interface MsCaseApplicationMapper extends Mapper<MsCaseApplication> {
120 123
      * 查询调解员列表
121 124
      * @return
122 125
      */
123
-    @Select("select a.id id,a.mediator_name mediatorName,a.mediator_phone mediatorPhone,a.mediator_email mediatorEmail,a.mediator_address mediatorAddress,a.mediator_id mediatorId,a.mediator_type mediatorType,a.mediator_status mediatorStatus,a.mediator_remark mediatorRemark,a.create_time createTime from ms_case_mediator a")
124
-    List<MediatorVO> listMediator();
126
+    List<MsCaseApplication> listMediator( @Param("userIds") List<Long> userIds,@Param("recordCaeIdList") List<Long> recordCaeIdList);
127
+
128
+    /**
129
+     * 查询最大房间号
130
+     * @return
131
+     */
132
+    @Select("select max(room_id) maxRoomId from ms_reserved_conference")
133
+    Long selectMaxRoomId();
125 134
 }

+ 2
- 3
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/mapper/mscase/MsCaseLogRecordMapper.java ファイルの表示

@@ -11,11 +11,10 @@ import java.util.List;
11 11
 public interface MsCaseLogRecordMapper extends Mapper<MsCaseLogRecord> {
12 12
     /**
13 13
      * 查询调解员已办数量
14
-     * @param collect
14
+     * @param list
15 15
      * @return
16 16
      */
17
-    @Select("select create_by createBy,GROUP_CONCAT(DISTINCT case_appli_id) caseAppliId from ms_case_log_record where create_by in('hhl','gyj') group by create_by,case_appli_id")
18
-    List<MsCaseLogRecord> selectCompleteByCreateBy(List<Long> collect);
17
+    List<MsCaseLogRecord> selectCompleteByCreateBy(@Param("list") List<String> list);
19 18
 
20 19
     @Select("<script> select cl.case_node caseNode ,cl.case_node_time caseNodeTime ,cl.notes  ,cl.id ,cl.case_appli_id caseAppliId," +
21 20
             "    cl.create_by createBy,cl.create_nick_name createNickName,cl.create_time createTime, " +

+ 22
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/mscase/MsCaseApplicationService.java ファイルの表示

@@ -4,6 +4,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
4 4
 import com.ruoyi.system.domain.entity.flow.MsCaseFlow;
5 5
 import com.ruoyi.wisdomarbitrate.domain.entity.mscase.MsCaseAffiliate;
6 6
 import com.ruoyi.wisdomarbitrate.domain.entity.mscase.MsCaseApplication;
7
+import com.ruoyi.wisdomarbitrate.domain.vo.mscase.BookingVO;
7 8
 import com.ruoyi.wisdomarbitrate.domain.vo.mscase.MsCaseApplicationReq;
8 9
 import com.ruoyi.wisdomarbitrate.domain.vo.mscase.MsCaseApplicationVO;
9 10
 import org.springframework.web.multipart.MultipartFile;
@@ -118,4 +119,25 @@ public interface MsCaseApplicationService {
118 119
      * @return
119 120
      */
120 121
     AjaxResult listMediator();
122
+    /**
123
+     * 保存预约
124
+     * @param
125
+     * @return
126
+     */
127
+    AjaxResult updateBooking(BookingVO vo);
128
+
129
+    /**
130
+     * 核实调解员
131
+     * @param vo
132
+     * @return
133
+     */
134
+    AjaxResult verifyMediator(BookingVO vo);
135
+
136
+    /**
137
+     * 查询预约信息
138
+     * @param id
139
+     * @return
140
+     */
141
+    AjaxResult selectReservation(Long id);
142
+
121 143
 }

+ 83
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/mscase/VideoConferenceService.java ファイルの表示

@@ -0,0 +1,83 @@
1
+package com.ruoyi.wisdomarbitrate.service.mscase;
2
+
3
+import com.ruoyi.common.core.domain.AjaxResult;
4
+import com.ruoyi.wisdomarbitrate.domain.dto.mscase.ReservedConference;
5
+import com.ruoyi.wisdomarbitrate.domain.vo.mscase.MsReservedConferenceVO;
6
+
7
+import java.util.List;
8
+
9
+/**
10
+ * 视频录制
11
+ */
12
+public interface VideoConferenceService {
13
+
14
+
15
+    void videoRollBack(String fileId,String videoUrl,String roomId) ;
16
+
17
+    AjaxResult bindCaseId(Long caseId, String roomId);
18
+
19
+    AjaxResult videoList(Long caseId);
20
+
21
+    /**
22
+     * 开启腾讯云录制
23
+     * @param roomId
24
+     * @return
25
+     */
26
+    AjaxResult openCloudRecording(long caseId,long roomId);
27
+
28
+    /**
29
+     * 退出录制
30
+     * @param taskId
31
+     * @return
32
+     */
33
+
34
+    AjaxResult closeDeleteCloudRecording(String taskId);
35
+
36
+    /**
37
+     * 解散房间
38
+     * @param roomId
39
+     * @return
40
+     */
41
+    AjaxResult dissolveRoom( Long roomId);
42
+    /**
43
+     * 根据userId查询该用户是否是秘书
44
+     * @param userId
45
+     * @return
46
+     */
47
+    AjaxResult secretaryRoleByUserId(Long userId);
48
+
49
+    /**
50
+     * 根据html字符串转pdf并和案件关联
51
+     * @param reservedConferenceVO
52
+     * @return
53
+     */
54
+    AjaxResult htmlToPDF(MsReservedConferenceVO reservedConferenceVO);
55
+
56
+    /**
57
+     * 获取userSign
58
+     * @param userId
59
+     * @return
60
+     */
61
+    String generateUserSign(String userId);
62
+
63
+    /**
64
+     * 生成房间号
65
+     * @param caseId
66
+     * @return
67
+     */
68
+
69
+    String createRoomId(Long caseId);
70
+    /**
71
+     * 根据案件id查询已预约的会议
72
+     * @param caseId
73
+     * @return
74
+     */
75
+    List<ReservedConference> reserveConferenceList(Long caseId);
76
+    /**
77
+     * 预约会议
78
+     * @param reservedConferenceVO
79
+     * @return
80
+     * @throws Exception
81
+     */
82
+    AjaxResult reservedConference( MsReservedConferenceVO reservedConferenceVO) throws Exception;
83
+}

+ 171
- 10
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/mscase/impl/MsCaseApplicationServiceImpl.java ファイルの表示

@@ -27,10 +27,7 @@ import com.ruoyi.wisdomarbitrate.domain.entity.mscase.MsCaseAffiliate;
27 27
 import com.ruoyi.wisdomarbitrate.domain.entity.mscase.MsCaseApplication;
28 28
 import com.ruoyi.wisdomarbitrate.domain.entity.mscase.MsCaseAttach;
29 29
 import com.ruoyi.wisdomarbitrate.domain.entity.mscase.MsCaseLogRecord;
30
-import com.ruoyi.wisdomarbitrate.domain.vo.mscase.MediatorVO;
31
-import com.ruoyi.wisdomarbitrate.domain.vo.mscase.MsCaseApplicationReq;
32
-import com.ruoyi.wisdomarbitrate.domain.vo.mscase.MsCaseApplicationVO;
33
-import com.ruoyi.wisdomarbitrate.domain.vo.mscase.MsColumnValueVO;
30
+import com.ruoyi.wisdomarbitrate.domain.vo.mscase.*;
34 31
 import com.ruoyi.wisdomarbitrate.mapper.mscase.*;
35 32
 import com.ruoyi.wisdomarbitrate.mapper.sendrecord.SmsRecordMapper;
36 33
 import com.ruoyi.wisdomarbitrate.mapper.template.FatchRuleMapper;
@@ -61,6 +58,7 @@ import java.util.function.Function;
61 58
 import java.util.stream.Collectors;
62 59
 
63 60
 import static com.ruoyi.common.utils.BookMarkUtil.getBookmarkByDocx;
61
+import static com.ruoyi.common.utils.PageUtils.startPage;
64 62
 import static com.ruoyi.common.utils.SecurityUtils.getUsername;
65 63
 
66 64
 /**
@@ -124,6 +122,7 @@ public class MsCaseApplicationServiceImpl implements MsCaseApplicationService {
124 122
     public List<MsCaseApplicationVO> list(MsCaseApplicationReq req) {
125 123
         // admin查询所有案件
126 124
         if (StrUtil.equals(SecurityUtils.getUsername(), "admin")) {
125
+            startPage();
127 126
             return msCaseApplicationMapper.list(req, null);
128 127
         }
129 128
         // 根据用户查询角色
@@ -140,12 +139,14 @@ public class MsCaseApplicationServiceImpl implements MsCaseApplicationService {
140 139
         if (CollectionUtil.isEmpty(caseFlowRoleRelatedList)) {
141 140
             throw new ServiceException("该角色为绑定案件流程");
142 141
         }
142
+
143 143
         Example flowExample = new Example(MsCaseFlow.class);
144 144
         flowExample.createCriteria().andIn("id", caseFlowRoleRelatedList.stream().map(MsCaseFlowRoleRelated::getFlowId).collect(Collectors.toList()));
145 145
         List<MsCaseFlow> caseFlows = caseFlowMapper.selectByExample(flowExample);
146 146
         if (CollectionUtil.isEmpty(caseFlows)) {
147 147
             throw new ServiceException("该角色为绑定案件流程");
148 148
         }
149
+        startPage();
149 150
         // 查询案件列表
150 151
         List<MsCaseApplicationVO> caseApplicationList = msCaseApplicationMapper.list(req, caseFlows.stream().map(MsCaseFlow::getCaseStatusName).collect(Collectors.toList()));
151 152
         return caseApplicationList;
@@ -699,20 +700,178 @@ public class MsCaseApplicationServiceImpl implements MsCaseApplicationService {
699 700
         List<MediatorVO> mediatorVOS = new ArrayList<MediatorVO>();
700 701
         // 查出所有调解员
701 702
         List<SysUser> users = userMapper.selectUserByRole("调解员");
702
-        if(CollectionUtil.isEmpty(users)){
703
+        if (CollectionUtil.isEmpty(users)) {
703 704
             return AjaxResult.error("暂无调解员");
704 705
         }
706
+        List<Long> userIds = users.stream().map(SysUser::getUserId).collect(Collectors.toList());
705 707
         // 查询调解员已办数量
706
-        List<MsCaseLogRecord> recordList=caseLogRecordMapper.selectCompleteByCreateBy(users.stream().map(SysUser::getUserId).collect(Collectors.toList()));
707
-        if(CollectionUtil.isNotEmpty(recordList)){
708
+        Map<String, List<MsCaseLogRecord>> recordMap =null;
709
+        List<MsCaseLogRecord> recordList = caseLogRecordMapper.selectCompleteByCreateBy(users.stream().map(SysUser::getUserName).collect(Collectors.toList()));
710
+        List<Long> recordCaeIdList = null;
711
+        if (CollectionUtil.isNotEmpty(recordList)) {
708 712
             // 组装成id对应的list
709
-            recordList.stream().collect(Collectors.groupingBy(MsCaseLogRecord::getCaseAppliId, Collectors.toList()));
713
+            recordMap = recordList.stream().collect(Collectors.groupingBy(MsCaseLogRecord::getCreateBy, Collectors.toList()));
714
+            recordCaeIdList = recordList.stream().map(MsCaseLogRecord::getCaseAppliId).collect(Collectors.toList());
710 715
         }
711 716
         // 查询待办数量
717
+        Map<String, List<MsCaseApplication>> caseMap=null;
718
+        List<MsCaseApplication> caseApplicationList = msCaseApplicationMapper.listMediator(userIds, recordCaeIdList);
719
+        if (CollectionUtil.isNotEmpty(caseApplicationList)) {
720
+             caseMap = caseApplicationList.stream().collect(Collectors.groupingBy(MsCaseApplication::getMediatorId, Collectors.toList()));
712 721
 
713
-        mediatorVOS= msCaseApplicationMapper.listMediator();
722
+        }
723
+        for (SysUser user : users) {
724
+            MediatorVO mediatorVO = new MediatorVO();
725
+            mediatorVO.setMediatorId(user.getUserId());
726
+            mediatorVO.setMediatorName(user.getNickName());
727
+            mediatorVO.setSpecialty(user.getSpecialty());
728
+            if(recordMap!=null &&recordMap.containsKey(String.valueOf(user.getUserName()))) {
729
+                mediatorVO.setCompleteAmount(recordMap.get(String.valueOf(user.getUserName())).size());
730
+            }
731
+            if(caseMap!=null&&caseMap.containsKey(String.valueOf(user.getUserId()))) {
732
+                mediatorVO.setTodoAmount(caseMap.get(String.valueOf(user.getUserId())).size());
733
+            }
734
+            mediatorVOS.add(mediatorVO);
735
+        }
736
+        return AjaxResult.success(mediatorVOS);
737
+    }
738
+    @Transactional
739
+    @Override
740
+    public AjaxResult updateBooking(BookingVO vo) {
741
+        MsCaseApplication application = new MsCaseApplication();
742
+        application.setId(vo.getId());
743
+        setMediatorAndDate(application,vo);
744
+        msCaseApplicationMapper.updateByPrimaryKeySelective(application);
745
+        nextFlow(vo.getId(),vo.getCaseFlowId(),null);
746
+        return AjaxResult.success();
747
+    }
748
+
749
+    /**
750
+     * 设置调解员调解时间
751
+     * @param application
752
+     * @param vo
753
+     */
754
+    private void setMediatorAndDate(MsCaseApplication application, BookingVO vo) {
755
+        if(CollectionUtil.isNotEmpty(vo.getUserList())) {
756
+            List<SysUser> userList = vo.getUserList();
757
+            List<Long> userIds = userList.stream().map(SysUser::getUserId).collect(Collectors.toList());
758
+            List<String> userNames = userList.stream().map(SysUser::getUserName).collect(Collectors.toList());
759
+            String mediatorIds = StrUtil.join(",", userIds);
760
+            String mediatorNames = StrUtil.join(",", userNames);
761
+            application.setMediatorId(mediatorIds);
762
+            application.setMediatorName(mediatorNames);
763
+        }
764
+        if(CollectionUtil.isNotEmpty( vo.getHerDates())) {
765
+            String herDates = StrUtil.join(",", vo.getHerDates());
766
+            application.setHearDate(herDates);
767
+        }
768
+    }
769
+
770
+    /**
771
+     * 核实调解员
772
+     * @param vo
773
+     * @return
774
+     */
775
+    @Override
776
+    public AjaxResult verifyMediator(BookingVO vo) {
777
+        if(StrUtil.isNotEmpty(vo.getBatchNumber())){
778
+            // 批量
779
+            List<MsCaseApplication> list = listByBatchNumber(vo.getBatchNumber(), vo.getCaseFlowId());
780
+            if(CollectionUtil.isEmpty(list)){
781
+                return AjaxResult.error("该批次号下未找到案件");
782
+            }
783
+            for (MsCaseApplication application : list) {
784
+                verifyMediator(application,vo);
785
+            }
786
+        }else {
787
+            MsCaseApplication application = new MsCaseApplication();
788
+            application.setId(vo.getId());
789
+            verifyMediator(application,vo);
790
+        }
791
+        return AjaxResult.success();
792
+    }
793
+
794
+    /**
795
+     * 查询预约信息
796
+     * @param id
797
+     * @return
798
+     */
799
+    @Override
800
+    public AjaxResult selectReservation(Long id) {
801
+
802
+        MsCaseApplication caseApplication = msCaseApplicationMapper.selectByPrimaryKey(id);
803
+        if(caseApplication == null){
804
+            return AjaxResult.error("该案件不存在");
805
+        }
806
+        BookingVO result = new BookingVO();
807
+        // 调解员是一个的处理
808
+        if( StrUtil.isNotEmpty(caseApplication.getMediatorId()) && StrUtil.isNotEmpty(caseApplication.getMediatorName())){
809
+            // 查询用户
810
+            SysUser user = userMapper.selectUserById(Long.valueOf(caseApplication.getMediatorId()));
811
+            if(user==null){
812
+                return AjaxResult.error("调解员已被删除");
813
+            }
814
+            // 查询调解员已办数量
815
+            Map<String, List<MsCaseLogRecord>> recordMap =null;
816
+            List<String> mediatorNames = new ArrayList<>();
817
+            mediatorNames.add(user.getUserName());
818
+            List<MsCaseLogRecord> recordList = caseLogRecordMapper.selectCompleteByCreateBy(mediatorNames);
819
+            List<Long> recordCaeIdList = null;
820
+            if (CollectionUtil.isNotEmpty(recordList)) {
821
+                // 组装成id对应的list
822
+                recordMap = recordList.stream().collect(Collectors.groupingBy(MsCaseLogRecord::getCreateBy, Collectors.toList()));
823
+                recordCaeIdList = recordList.stream().map(MsCaseLogRecord::getCaseAppliId).collect(Collectors.toList());
824
+            }
825
+            // 查询待办数量
826
+            List<Long> mediatorIds = new ArrayList<>();
827
+            mediatorIds.add(user.getUserId());
828
+            Map<String, List<MsCaseApplication>> caseMap=null;
829
+            List<MsCaseApplication> caseApplicationList = msCaseApplicationMapper.listMediator(mediatorIds, recordCaeIdList);
830
+            if (CollectionUtil.isNotEmpty(caseApplicationList)) {
831
+                caseMap = caseApplicationList.stream().collect(Collectors.groupingBy(MsCaseApplication::getMediatorId, Collectors.toList()));
832
+
833
+            }
834
+            MediatorVO mediatorVO = new MediatorVO();
835
+            mediatorVO.setMediatorId(user.getUserId());
836
+            mediatorVO.setMediatorName(user.getNickName());
837
+            mediatorVO.setSpecialty(user.getSpecialty());
838
+            if(recordMap!=null &&recordMap.containsKey(String.valueOf(user.getUserName()))) {
839
+                mediatorVO.setCompleteAmount(recordMap.get(String.valueOf(user.getUserName())).size());
840
+            }
841
+            if(caseMap!=null&&caseMap.containsKey(String.valueOf(user.getUserId()))) {
842
+                mediatorVO.setTodoAmount(caseMap.get(String.valueOf(user.getUserId())).size());
843
+            }
844
+            List<MediatorVO> mediatorVOS = new ArrayList<>();
845
+            mediatorVOS.add(mediatorVO);
846
+            result.setMediatorList(mediatorVOS);
847
+        }
848
+        if(StrUtil.isNotEmpty(caseApplication.getHearDate())){
849
+            List<String> herdates = new ArrayList<>();
850
+            herdates.add(caseApplication.getHearDate());
851
+            result.setHerDates(herdates);
852
+        }
853
+        return AjaxResult.success(result);
854
+    }
855
+
856
+
857
+
858
+    /**
859
+     * 核实调解员
860
+     * @param
861
+     * @return
862
+     */
863
+    private void verifyMediator(MsCaseApplication application,BookingVO vo) {
864
+        MsCaseFlow nextFlow = caseFlowMapper.nextFlow(vo.getCaseFlowId());
865
+        if (nextFlow == null) {
866
+            throw new ServiceException("未找到下一个流程节点");
867
+        }
868
+        setMediatorAndDate(application,vo);
869
+        application.setCaseFlowId(nextFlow.getNodeId());
870
+        application.setCaseStatusName(nextFlow.getCaseStatusName());
871
+        msCaseApplicationMapper.updateByPrimaryKeySelective(application);
872
+        // 新增日志
873
+        CaseLogUtils.insertCaseLog(application.getId(), nextFlow.getNodeId(), nextFlow.getCaseStatusName(), "");
714 874
 
715
-        return null;
716 875
     }
717 876
 
718 877
     /**
@@ -724,6 +883,7 @@ public class MsCaseApplicationServiceImpl implements MsCaseApplicationService {
724 883
     private void accept(MsCaseApplication application, MsCaseApplication req, Map<Long, MsCaseAffiliate> affiliateMap) {
725 884
         application.setUpdateBy(SecurityUtils.getUsername());
726 885
         application.setUpdateTime(new Date());
886
+        application.setBatchNumber(null);
727 887
         msCaseApplicationMapper.updateByPrimaryKeySelective(application);
728 888
         MsCaseFlow caseFlow = nextFlow(application.getId(), req.getCaseFlowId(),req.getLockStatus());
729 889
         // 给申请人被申请人发送短信
@@ -776,6 +936,7 @@ public class MsCaseApplicationServiceImpl implements MsCaseApplicationService {
776 936
             throw new ServiceException("未找到下一个流程节点");
777 937
         }
778 938
         MsCaseApplication application = new MsCaseApplication();
939
+        application.setBatchNumber(null);
779 940
         application.setId(caseId);
780 941
         // 更改案件流程id和案件状态
781 942
         application.setCaseFlowId(nextFlow.getId());

+ 2
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/mscase/impl/MsCasePaymentServiceImpl.java ファイルの表示

@@ -301,6 +301,8 @@ public class MsCasePaymentServiceImpl implements MsCasePaymentService {
301 301
         caseApplicationMapper.updateByPrimaryKeySelective(application);
302 302
         // 新增日志
303 303
         CaseLogUtils.insertCaseLog(application.getId(), nextFlow.getNodeId(), nextFlow.getCaseStatusName(),"确认已缴费");
304
+        // todo 发送短信
305
+
304 306
 
305 307
     }
306 308
 

+ 457
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/mscase/impl/VideoConferenceServiceImpl.java ファイルの表示

@@ -0,0 +1,457 @@
1
+package com.ruoyi.wisdomarbitrate.service.mscase.impl;
2
+
3
+import cn.hutool.core.collection.CollectionUtil;
4
+import cn.hutool.http.HttpUtil;
5
+import com.alibaba.fastjson.JSON;
6
+import com.alibaba.fastjson.JSONObject;
7
+import com.ruoyi.common.config.RuoYiConfig;
8
+import com.ruoyi.common.core.domain.AjaxResult;
9
+import com.ruoyi.common.core.domain.entity.SysRole;
10
+import com.ruoyi.common.core.domain.entity.SysUser;
11
+import com.ruoyi.common.enums.AnnexTypeEnum;
12
+import com.ruoyi.common.utils.PdfUtils;
13
+import com.ruoyi.common.utils.SecurityUtils;
14
+import com.ruoyi.system.domain.entity.flow.MsCaseFlowRoleRelated;
15
+import com.ruoyi.system.mapper.SysRoleMapper;
16
+import com.ruoyi.system.mapper.SysUserMapper;
17
+import com.ruoyi.wisdomarbitrate.domain.dto.mscase.ReservedConference;
18
+import com.ruoyi.wisdomarbitrate.domain.entity.mscase.MsCaseApplication;
19
+import com.ruoyi.wisdomarbitrate.domain.entity.mscase.MsCaseAttach;
20
+import com.ruoyi.wisdomarbitrate.domain.vo.mscase.MsCaseApplicationVO;
21
+import com.ruoyi.wisdomarbitrate.domain.vo.mscase.MsReservedConferenceVO;
22
+import com.ruoyi.wisdomarbitrate.mapper.mscase.MsCaseApplicationMapper;
23
+import com.ruoyi.wisdomarbitrate.mapper.mscase.MsCaseAttachMapper;
24
+import com.ruoyi.wisdomarbitrate.mapper.mscase.ReservedConferenceMapper;
25
+import com.ruoyi.wisdomarbitrate.service.mscase.VideoConferenceService;
26
+import com.tencentcloudapi.common.Credential;
27
+import com.tencentcloudapi.common.exception.TencentCloudSDKException;
28
+import com.tencentcloudapi.common.profile.ClientProfile;
29
+import com.tencentcloudapi.common.profile.HttpProfile;
30
+import com.tencentcloudapi.trtc.v20190722.TrtcClient;
31
+import com.tencentcloudapi.trtc.v20190722.models.*;
32
+import com.tencentyun.TLSSigAPIv2;
33
+import lombok.extern.slf4j.Slf4j;
34
+import org.springframework.beans.factory.annotation.Autowired;
35
+import org.springframework.beans.factory.annotation.Value;
36
+import org.springframework.stereotype.Service;
37
+import org.springframework.transaction.annotation.Transactional;
38
+import tk.mybatis.mapper.entity.Example;
39
+
40
+import javax.crypto.Mac;
41
+import javax.crypto.spec.SecretKeySpec;
42
+import java.io.IOException;
43
+import java.nio.file.Paths;
44
+import java.util.Base64;
45
+import java.util.Date;
46
+import java.util.List;
47
+import java.util.Map;
48
+import java.util.stream.Collectors;
49
+
50
+import static com.ruoyi.common.core.domain.AjaxResult.success;
51
+import static com.ruoyi.common.utils.file.FileUploadUtils.getAbsoluteFile;
52
+import static com.ruoyi.common.utils.file.FileUploadUtils.getPathFileName;
53
+
54
+/**
55
+ * @author wangqiong
56
+ * @description 视频录制
57
+ * @date 2023-10-26 11:45
58
+ */
59
+@Service
60
+@Slf4j
61
+public class VideoConferenceServiceImpl implements VideoConferenceService {
62
+    // 腾讯云即时通信sdkAppId
63
+    @Value("${imConfig.sdkAppId}")
64
+    private long sdkAppId;
65
+    // 腾讯云即时通信密钥
66
+    @Value("${imConfig.sdkSecretKey}")
67
+    private String sdkSecretKey;
68
+    // 腾讯云个人账户secretId
69
+    @Value("${imConfig.secretId}")
70
+    private String secretId;
71
+    // 腾讯云个人账户密钥
72
+    @Value("${imConfig.secretKey}")
73
+    private String secretKey;
74
+    @Autowired
75
+    private MsCaseApplicationMapper caseApplicationMapper;
76
+    @Autowired
77
+    private MsCaseAttachMapper caseAttachMapper;
78
+    @Autowired
79
+    private SysRoleMapper roleMapper;
80
+    @Autowired
81
+    private ReservedConferenceMapper reservedConferenceMapper;
82
+    @Autowired
83
+    private SysUserMapper sysUserMapper;
84
+
85
+    /**
86
+        视频回调
87
+     * @throws Exception
88
+     */
89
+    @Override
90
+    public void videoRollBack(String fileId,String videoUrl,String roomId)  {
91
+        try {
92
+            downloadImage(fileId,videoUrl,roomId);
93
+        } catch (IOException e) {
94
+            throw new RuntimeException(e);
95
+        }
96
+
97
+    }
98
+    /**
99
+     * 获取userSign,默认过期时间10小时
100
+     *
101
+     * @param userId
102
+     * @return
103
+     */
104
+    @Override
105
+    public String generateUserSign(String userId) {
106
+        TLSSigAPIv2 tlsSigAPIv2 = new TLSSigAPIv2(sdkAppId, sdkSecretKey);
107
+        return tlsSigAPIv2.genUserSig(userId, 60 * 60 * 10);
108
+    }
109
+    /**
110
+     * 预约会议
111
+     *
112
+     * @param reservedConferenceVO
113
+     * @return
114
+     * @throws Exception
115
+     */
116
+    @Transactional
117
+    @Override
118
+    public AjaxResult reservedConference(MsReservedConferenceVO reservedConferenceVO) {
119
+
120
+        // 新增预约会议表
121
+        ReservedConference conference = new ReservedConference(reservedConferenceVO.getCaseId(), SecurityUtils.getUserId(), reservedConferenceVO.getRoomId(),
122
+                reservedConferenceVO.getScheduleStartTime(), reservedConferenceVO.getScheduleEndTime());
123
+        reservedConferenceMapper.insert(conference);
124
+        return success("预约会议成功");
125
+    }
126
+
127
+    /**
128
+     * 根据案件id查询已预约的会议
129
+     *
130
+     * @param caseId
131
+     * @return
132
+     */
133
+    @Override
134
+    @Transactional
135
+    public List<ReservedConference> reserveConferenceList(Long caseId) {
136
+        List<ReservedConference> reservedConferences = reservedConferenceMapper.selectListByCaseId(caseId);
137
+        if (CollectionUtil.isEmpty(reservedConferences)) {
138
+            return reservedConferences;
139
+        }
140
+        Map<Long, String> userIdMap = null;
141
+        List<Long> userIds = reservedConferences.stream().map(ReservedConference::getUserId).collect(Collectors.toList());
142
+        if (CollectionUtil.isNotEmpty(userIds)) {
143
+            // 根据userids查询用户名
144
+            List<SysUser> userList = sysUserMapper.selectUserListByIds(userIds);
145
+            if (CollectionUtil.isNotEmpty(userList)) {
146
+                userIdMap = userList.stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getUserName));
147
+            }
148
+        }
149
+        for (ReservedConference reservedConference : reservedConferences) {
150
+            if (null != reservedConference.getUserId() && null != userIdMap) {
151
+                reservedConference.setUserName(userIdMap.get(reservedConference.getUserId()));
152
+            }
153
+            Date startTime = reservedConference.getScheduleStartTime();
154
+            if (null == startTime) {
155
+                continue;
156
+            }
157
+            // 5分钟之内
158
+            long beforeMinutes = startTime.getTime() - 1000 * 60 * 5;
159
+            if (System.currentTimeMillis() < beforeMinutes) {
160
+                reservedConference.setIsBeforeFiveMinutes(true);
161
+            } else {
162
+                reservedConference.setIsBeforeFiveMinutes(false);
163
+            }
164
+        }
165
+
166
+
167
+        return reservedConferences;
168
+    }
169
+    /**
170
+     * 生成房间号
171
+     */
172
+    @Transactional
173
+    @Override
174
+    public String createRoomId(Long caseId) {
175
+        long roomId = generateRoomId();
176
+        // 绑定案件与房间号
177
+        bindCaseId(caseId, String.valueOf(roomId));
178
+        return String.valueOf(roomId);
179
+    }
180
+
181
+    /**
182
+     * 获取房间号
183
+     *
184
+     * @return
185
+     */
186
+    public Long generateRoomId() {
187
+        // 查询最大房间号
188
+        Long maxRoomId = caseApplicationMapper.selectMaxRoomId();
189
+
190
+        if (null == maxRoomId || maxRoomId > 4294967294L/2) {
191
+            return 4294967294L/2+1;
192
+        } else {
193
+            return maxRoomId + 1;
194
+        }
195
+
196
+    }
197
+
198
+    @Override
199
+    public AjaxResult bindCaseId(Long caseId, String roomId) {
200
+        MsCaseApplication caseApplication = new MsCaseApplication();
201
+        caseApplication.setId(caseId);
202
+        caseApplication.setRoomId(roomId);
203
+        caseApplicationMapper.updateByPrimaryKeySelective(caseApplication);
204
+        return success();
205
+    }
206
+
207
+    /**
208
+     * 根据案件id查询会议视频
209
+     * @param caseId
210
+     * @return
211
+     */
212
+    @Override
213
+    public AjaxResult videoList(Long caseId) {
214
+        MsCaseApplicationVO caseApplication = new MsCaseApplicationVO();
215
+        caseApplication.setId(caseId);
216
+        caseApplication.setAnnexType(AnnexTypeEnum.MEETING_VIDEO.getCode());
217
+        List<MsCaseAttach> caseAttachList = caseAttachMapper.queryCaseAttachList(caseApplication);
218
+        if(CollectionUtil.isEmpty(caseAttachList)){
219
+            return success();
220
+        }
221
+        return  success(caseAttachList);
222
+    }
223
+
224
+    /**
225
+     * 开启腾讯云录制
226
+     * @param roomId
227
+     * @return
228
+     */
229
+    @Override
230
+    public AjaxResult openCloudRecording(long caseId,long roomId) {
231
+        try {
232
+            String userId="recorder_"+roomId;
233
+
234
+            Credential cred = new Credential(secretId, secretKey);
235
+
236
+            // 实例化一个http选项,可选的,没有特殊需求可以跳过
237
+            HttpProfile httpProfile = new HttpProfile();
238
+            httpProfile.setEndpoint("trtc.tencentcloudapi.com");
239
+            // 实例化一个client选项,可选的,没有特殊需求可以跳过
240
+            ClientProfile clientProfile = new ClientProfile();
241
+            clientProfile.setHttpProfile(httpProfile);
242
+            // 实例化要请求产品的client对象,clientProfile是可选的
243
+            TrtcClient client = new TrtcClient(cred, "ap-beijing", clientProfile);
244
+
245
+            // 实例化一个请求对象,每个接口都会对应一个request对象
246
+            CreateCloudRecordingRequest req = new CreateCloudRecordingRequest();
247
+            req.setSdkAppId(sdkAppId); // SdkAppId – TRTC的[SdkAppId](https://cloud.tencent.com/document/product/647/46351#sdkappid),和录制的房间所对应的SdkAppId相同
248
+            req.setRoomId(String.valueOf(roomId)); // RoomId – TRTC的[RoomId](https://cloud.tencent.com/document/product/647/46351#roomid),录制的TRTC房间所对应的RoomId
249
+            req.setRoomIdType(1L);
250
+            /**
251
+             *  录制机器人用于进入TRTC房间拉流的[UserId](https://cloud.tencent.com/document/product/647/46351#userid),
252
+             *  注意这个UserId不能与其他TRTC房间内的主播或者其他录制任务等已经使用的UserId重复,建议可以把房间ID作为userId的标识的一部分,
253
+             *  即录制机器人进入房间的userid应保证独立且唯一
254
+             */
255
+            req.setUserId(userId);
256
+
257
+            TLSSigAPIv2 api = new TLSSigAPIv2(sdkAppId, sdkSecretKey);
258
+            String userSign = api.genUserSig(userId, 60 * 60 * 10);
259
+            req.setUserSig(userSign); // 录制机器人用于进入TRTC房间拉流的用户签名,当前 UserId 对应的验证签名,相当于登录密码
260
+            RecordParams recordParams = new RecordParams();
261
+            // 混流录制
262
+            recordParams.setMaxIdleTime(60L*5); // 5分钟内房间里面没有主播,自动停止录制
263
+            recordParams.setStreamType(0L); // 0:录制音频+视频流(默认); 1:仅录制音频流; 2:仅录制视频流
264
+            recordParams.setRecordMode(2L); // 1:单流录制,分别录制房间的订阅UserId的音频和视频,将录制文件上传至云存储; 2:混流录制,将房间内订阅UserId的音视频混录成一个音视频文件,将录制文件上传至云存储;
265
+            recordParams.setOutputFormat(0L); // 0:(默认)输出文件为hls格式。1:输出文件格式为hls+mp4。2:输出文件格式为hls+aac
266
+            MixLayoutParams mixLayoutParams = new MixLayoutParams();
267
+            // 	布局模式: 1:悬浮布局;2:屏幕分享布局;3:九宫格布局(默认);4:自定义布局;
268
+            mixLayoutParams.setMixLayoutMode(3L);
269
+            req.setMixLayoutParams(mixLayoutParams);
270
+
271
+            StorageParams storageParams1 = new StorageParams();
272
+            CloudVod cloudVod = new CloudVod();
273
+            TencentVod tencentVod = new TencentVod();
274
+            tencentVod.setSubAppId(1304001529L);
275
+            // 录制的文件永久保存
276
+            tencentVod.setExpireTime(0L);
277
+            // 录制文件名拼接前缀
278
+            tencentVod.setUserDefineRecordId(caseId+"");
279
+            cloudVod.setTencentVod(tencentVod); // 腾讯云点播相关参数。
280
+            storageParams1.setCloudVod(cloudVod); // 必填】腾讯云云点播的账号信息,目前仅支持存储至腾讯云点播VOD。
281
+            req.setRecordParams(recordParams); // 云端录制控制参数
282
+            req.setStorageParams(storageParams1); // 云端录制文件上传到云存储的参数(目前只支持使用腾讯云点播作为存储)
283
+            // 返回的resp是一个CreateCloudRecordingResponse的实例,与请求对象对应
284
+            CreateCloudRecordingResponse resp = client.CreateCloudRecording(req);
285
+
286
+            return success((JSONObject) JSON.toJSON(resp));
287
+        } catch (TencentCloudSDKException e) {
288
+            return AjaxResult.error(e.toString());
289
+        }
290
+    }
291
+
292
+    @Override
293
+    public AjaxResult closeDeleteCloudRecording(String taskId) {
294
+
295
+        try {
296
+            if (taskId != null) {
297
+                taskId = taskId.replaceAll(" ", "+");
298
+            }
299
+            // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
300
+            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
301
+            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
302
+            Credential cred = new Credential(secretId, secretKey);
303
+            // 实例化一个http选项,可选的,没有特殊需求可以跳过
304
+            HttpProfile httpProfile = new HttpProfile();
305
+            httpProfile.setEndpoint("trtc.tencentcloudapi.com");
306
+            // 实例化一个client选项,可选的,没有特殊需求可以跳过
307
+            ClientProfile clientProfile = new ClientProfile();
308
+            clientProfile.setHttpProfile(httpProfile);
309
+            // 实例化要请求产品的client对象,clientProfile是可选的
310
+            TrtcClient client = new TrtcClient(cred, "ap-beijing", clientProfile);
311
+            // 实例化一个请求对象,每个接口都会对应一个request对象
312
+            DeleteCloudRecordingRequest req = new DeleteCloudRecordingRequest();
313
+            req.setSdkAppId(sdkAppId); // SdkAppId – TRTC的SDKAppId,和录制的房间所对应的SDKAppId相同
314
+            req.setTaskId(taskId); // TaskId – 录制任务的唯一Id,在启动录制成功后会返回
315
+            // 返回的resp是一个DeleteCloudRecordingResponse的实例,与请求对象对应
316
+            DeleteCloudRecordingResponse resp = client.DeleteCloudRecording(req);
317
+            // 输出json格式的字符串回包
318
+            return success((JSONObject) JSON.toJSON(resp));
319
+        } catch (TencentCloudSDKException e) {
320
+            return AjaxResult.error(e.toString());
321
+        }
322
+
323
+    }
324
+
325
+    /**
326
+     * 解散房间
327
+     * @param roomId
328
+     * @return
329
+     */
330
+    @Override
331
+    public AjaxResult dissolveRoom( Long roomId) {
332
+        Credential cred = new Credential(secretId, secretKey);
333
+        // 实例化一个http选项,可选的,没有特殊需求可以跳过
334
+        HttpProfile httpProfile = new HttpProfile();
335
+        httpProfile.setEndpoint("trtc.tencentcloudapi.com");
336
+        // 实例化一个client选项,可选的,没有特殊需求可以跳过
337
+        ClientProfile clientProfile = new ClientProfile();
338
+        clientProfile.setHttpProfile(httpProfile);
339
+        // 实例化要请求产品的client对象,clientProfile是可选的
340
+        TrtcClient client = new TrtcClient(cred, "ap-beijing", clientProfile);
341
+        DismissRoomRequest req = new DismissRoomRequest();
342
+        req.setSdkAppId(sdkAppId);
343
+        req.setRoomId(roomId);
344
+        try {
345
+            DismissRoomResponse resp = client.DismissRoom(req);
346
+            return success((JSONObject) JSON.toJSON(resp));
347
+        } catch (TencentCloudSDKException e) {
348
+            return AjaxResult.error("解散房间失败");
349
+        }
350
+
351
+    }
352
+    /**
353
+     * 根据userId查询该用户是否是秘书
354
+     * @param userId
355
+     * @return
356
+     */
357
+    @Override
358
+    public AjaxResult secretaryRoleByUserId(Long userId) {
359
+        List<SysRole> roles = roleMapper.selectRolePermissionByUserId(userId);
360
+        JSONObject jsonObject = new JSONObject();
361
+        boolean isSecretaryRole=false;
362
+        if(CollectionUtil.isNotEmpty(roles)){
363
+            for (SysRole role : roles) {
364
+                if("法律顾问".equals(role.getRoleName()) || "秘书".equals(role.getRoleName())){
365
+                    isSecretaryRole=true;
366
+                    break;
367
+                }
368
+            }
369
+        }
370
+        jsonObject.put("isSecretaryRole",isSecretaryRole);
371
+        return success(jsonObject);
372
+    }
373
+
374
+    /**
375
+     * 根据html字符串转pdf并和案件关联
376
+     * @param reservedConferenceVO
377
+     * @return
378
+     */
379
+    @Override
380
+    public AjaxResult htmlToPDF(MsReservedConferenceVO reservedConferenceVO) {
381
+        String currentFileName = System.currentTimeMillis() + ".pdf";
382
+        String fileName = null;
383
+        try {
384
+            fileName = getPathFileName(RuoYiConfig.getHtml2PDFPath(), currentFileName);
385
+        } catch (IOException e) {
386
+            throw new RuntimeException(e);
387
+        }
388
+        String htmlContent = "<html><head> <title>庭审笔录</title></head><body style=\"font-size:12.0pt; font-family:SimSun;\"><h1 align=\"center\">庭审笔录</h1>" +reservedConferenceVO.getHtmlContent()+"</body></html>";
389
+        // html转pdf并上传到服务器
390
+        boolean convertFlag = PdfUtils.htmlStringConvertToPDF(RuoYiConfig.getHtml2PDFPath() +"/"+ currentFileName, htmlContent);
391
+
392
+        // 绑定案件
393
+        if(convertFlag){
394
+            MsCaseAttach caseAttach = MsCaseAttach.builder().caseAppliId(reservedConferenceVO.getCaseId())
395
+                    .annexName(fileName)
396
+                    .annexPath(RuoYiConfig.getHtml2PDFPath())
397
+                    .annexType(7)
398
+                    .build();
399
+            caseAttachMapper.save(caseAttach);
400
+            return AjaxResult.success();
401
+        }else {
402
+            return AjaxResult.error("pdf转换失败");
403
+        }
404
+    }
405
+
406
+
407
+
408
+    /**
409
+     * 将视频下载到本地
410
+     * @param fileUrl 视频路径
411
+     * @return
412
+     */
413
+    @Transactional
414
+    public  String downloadImage(String fileId,String fileUrl,String roomId) throws IOException {
415
+        String staticAndMksDir = null;
416
+        if (fileUrl != null) {
417
+            //下载时文件名称
418
+            String fileName = fileUrl.substring(fileUrl.lastIndexOf("/"));
419
+            fileName = fileName.replace("/", "");
420
+            fileName=fileId+fileName;
421
+                String absPath = getAbsoluteFile(RuoYiConfig.getVideoUploadPath(), fileName).getAbsolutePath();
422
+                staticAndMksDir = Paths.get(absPath).toFile().toString();
423
+            long downloadFile = HttpUtil.downloadFile(fileUrl, staticAndMksDir);
424
+            if(downloadFile>0) {
425
+                Example example = new Example(MsCaseFlowRoleRelated.class);
426
+                example.createCriteria().andEqualTo("romId", roomId);
427
+                MsCaseApplication caseApplication = caseApplicationMapper.selectOneByExample(example);
428
+                if(caseApplication != null) {
429
+                    String annexName = getPathFileName(RuoYiConfig.getVideoUploadPath(), fileName);
430
+                    // 存入数据库
431
+                    MsCaseAttach caseAttach = MsCaseAttach.builder().caseAppliId(caseApplication.getId())
432
+                            .annexName(fileName)
433
+                            .annexPath(annexName)
434
+                            .annexType(AnnexTypeEnum.MEETING_VIDEO.getCode())
435
+                            .build();
436
+                    caseAttachMapper.save(caseAttach);
437
+                    return annexName;
438
+                }
439
+            }
440
+        }
441
+        return "";
442
+
443
+    }
444
+    /**
445
+     * @param key 回调秘钥
446
+     * @param body 入参
447
+     * @return 签名 Sign 计算公式中 key 为计算签名 Sign 用的加密密钥。
448
+     * @throws Exception
449
+     */
450
+    private static String getResultSign(String key, String body) throws Exception {
451
+        Mac hmacSha256 = Mac.getInstance("HmacSHA256");
452
+        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
453
+        hmacSha256.init(secret_key);
454
+        return Base64.getEncoder().encodeToString(hmacSha256.doFinal(body.getBytes()));
455
+    }
456
+
457
+}

+ 2
- 2
ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml ファイルの表示

@@ -134,7 +134,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
134 134
 	
135 135
 	<select id="selectUserById" parameterType="Long" resultMap="SysUserResult">
136 136
 		<include refid="selectUserVo"/>
137
-		where u.user_id = #{userId}
137
+		where u.user_id = #{userId} and  u.del_flag = '0'
138 138
 	</select>
139 139
 
140 140
 	<select id="selectUserByDeptId" parameterType="Long" resultMap="SysUserResult">
@@ -320,7 +320,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
320 320
 	</select>
321 321
 
322 322
     <select id="selectUserByRole" resultType="com.ruoyi.common.core.domain.entity.SysUser">
323
-		select u.user_id,u.user_name,u.nick_name,u.specialty  from ms_sys_user u
323
+		select u.user_id userId,u.user_name userName,u.nick_name nickName,u.specialty  from ms_sys_user u
324 324
 		    join ms_sys_user_role ur on ur.user_id =u.user_id
325 325
 		    join ms_sys_role r on ur.role_id = r.role_id and r.role_name='调解员'
326 326
 		    where r.del_flag = '0' and r.status='0' and u.del_flag = '0' and u.status='0'

+ 16
- 0
ruoyi-system/src/main/resources/mapper/wisdomarbitrate/mscase/MsCaseApplicationMapper.xml ファイルの表示

@@ -37,4 +37,20 @@
37 37
     <result column="adjudica_counter_reason" jdbcType="LONGVARCHAR" property="adjudicaCounterReason" />
38 38
     <result column="mediation_agreement" jdbcType="LONGVARCHAR" property="mediationAgreement" />
39 39
   </resultMap>
40
+
41
+  <select id="listMediator" resultMap="BaseResultMap">
42
+    select mediator_id ,id  from ms_case_application <where>
43
+    <if test = 'userIds!=null and userIds.size()>0'>
44
+      and mediator_id in
45
+      <foreach item='item' index='index' collection='userIds' open='(' separator=',' close=')'>
46
+        #{item}
47
+        </foreach>
48
+      </if>
49
+    <if test = 'recordCaeIdList!=null and recordCaeIdList.size()>0'> and id not in
50
+      <foreach item='id' index='index' collection='recordCaeIdList' open='(' separator=',' close=')'>
51
+        #{id}
52
+        </foreach>
53
+      </if>
54
+    </where>
55
+    </select>
40 56
 </mapper>

+ 8
- 2
ruoyi-system/src/main/resources/mapper/wisdomarbitrate/mscase/MsCaseLogRecordMapper.xml ファイルの表示

@@ -12,8 +12,14 @@
12 12
     <result column="create_by" jdbcType="VARCHAR" property="createBy" />
13 13
     <result column="create_nick_name" jdbcType="VARCHAR" property="createNickName" />
14 14
     <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
15
-    <result column="update_by" jdbcType="VARCHAR" property="updateBy" />
16
-    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
17 15
     <result column="notes" jdbcType="LONGVARCHAR" property="notes" />
18 16
   </resultMap>
17
+
18
+  <select id="selectCompleteByCreateBy" resultMap="BaseResultMap">
19
+    select create_by,GROUP_CONCAT(DISTINCT case_appli_id)  case_appli_id from ms_case_log_record
20
+    where create_by in  <foreach collection="list" item="item" separator="," open="(" close=")">
21
+    #{item}
22
+  </foreach>
23
+    group by create_by,case_appli_id
24
+    </select>
19 25
 </mapper>