Sfoglia il codice sorgente

Merge branch 'master' of http://1.14.104.71:10880/root/ylrz_his_scrm_java

caoliqin 2 giorni fa
parent
commit
c5eb3b4bb6

+ 11 - 0
fs-company-app/src/main/java/com/fs/app/controller/FsUserCourseVideoController.java

@@ -249,5 +249,16 @@ public class FsUserCourseVideoController extends AppBaseController {
         return fsUserCourseVideoService.setWatchCourseTime(collect);
     }
 
+    /**
+     * 获取跳转微信小程序的链接地址
+     * @param linkStr
+     * @return
+     */
+    @Login
+    @GetMapping("/getGotoWxAppLink")
+    @ApiOperation("获取跳转微信小程序的链接地址")
+    public ResponseResult<String> getGotoWxAppLink(String linkStr) {
+        return ResponseResult.ok(courseLinkService.getGotoWxAppLink(linkStr));
+    }
 
 }

+ 32 - 10
fs-company/src/main/java/com/fs/company/controller/qw/SopUserLogsInfoController.java

@@ -32,10 +32,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
+import java.io.IOException;
+import java.util.*;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
@@ -112,13 +110,28 @@ public class SopUserLogsInfoController extends BaseController
                 });
             }
 
+
+//            Predicate<SopUserLogsInfo> tagFilter = item ->
+//                    sopUserLogsInfo.getTagIds() == null ||
+//                            sopUserLogsInfo.getTagIds().isEmpty() ||
+//                            item.getTagIds().contains(sopUserLogsInfo.getTagIds());
+
+            Predicate<SopUserLogsInfo> tagFilter = item -> {
+                String queryTagIds = sopUserLogsInfo.getTagIds();
+                String itemTagIds = item.getTagIds();
+
+                if (queryTagIds == null || queryTagIds.trim().equals("[]")) {
+                    return true;
+                }
+                List<String> queryTags = parseTagIds(queryTagIds);
+                List<String> itemTags = parseTagIds(itemTagIds);
+
+                // 检查 itemTags 是否包含所有 queryTags(AND 关系)
+                return itemTags.containsAll(queryTags);
+            };
+
             // 优化过滤条件
             boolean isRemarkEmpty = StringUtil.strIsNullOrEmpty(sopUserLogsInfo.getRemark());
-            Predicate<SopUserLogsInfo> tagFilter = item ->
-                    sopUserLogsInfo.getTagIds() == null ||
-                            sopUserLogsInfo.getTagIds().isEmpty() ||
-                            item.getTagIds().contains(sopUserLogsInfo.getTagIds());
-
             Predicate<SopUserLogsInfo> remarkFilter = item ->
                     isRemarkEmpty ||
                             item.getRemark().contains(sopUserLogsInfo.getRemark());
@@ -196,7 +209,16 @@ public class SopUserLogsInfoController extends BaseController
 //        }
     }
 
-
+    private List<String> parseTagIds(String jsonTagIds) {
+        if (jsonTagIds == null || jsonTagIds.trim().isEmpty() || jsonTagIds.equals("[]")) {
+            return Collections.emptyList();
+        }
+        // 去掉开头和结尾的 [ ],然后按 "," 分割
+        return Arrays.stream(jsonTagIds.replaceAll("[\\[\\]\"]", "").split(","))
+                .map(String::trim)
+                .filter(s -> !s.isEmpty())
+                .collect(Collectors.toList());
+    }
 //    /**
 //     * 导出sopUserLogsInfo列表
 //     */

+ 15 - 9
fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java

@@ -635,7 +635,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
 
                         insertSopUserLogs(sopUserLogsInfos, logVo, sendTime, ruleTimeVO, content, qwUserId,
                                 companyUserId, companyId, qwUserByRedis.getWelcomeText(),qwUserByRedis.getQwUserName(),
-                                groupChatMap, miniAppId);
+                                groupChatMap, miniAppId,config);
 
                     }
                 } catch (Exception e) {
@@ -678,7 +678,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     private void insertSopUserLogs(List<SopUserLogsInfo> sopUserLogsInfos, SopUserLogsVo logVo, Date sendTime,
                                    QwSopRuleTimeVO ruleTimeVO, QwSopTempSetting.Content content,
                                    String qwUserId,String companyUserId,String companyId,String welcomeText,String qwUserName,
-                                   Map<String, QwGroupChat> groupChatMap,String miniAppId) {
+                                   Map<String, QwGroupChat> groupChatMap,String miniAppId,CourseConfig config) {
         String formattedSendTime = sendTime.toInstant()
                 .atZone(ZoneId.systemDefault())
                 .format(DATE_TIME_FORMATTER);
@@ -704,7 +704,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             if (content.getIndex() == 0) {
                 QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, groupChat.getChatId(), groupChat.getName(), null, isOfficial, null);
                 handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
-                        type, qwUserId, companyUserId, companyId, groupChat.getChatId(), welcomeText, qwUserName, null, true, miniAppId, groupChat);
+                        type, qwUserId, companyUserId, companyId, groupChat.getChatId(), welcomeText, qwUserName,
+                        null, true, miniAppId, groupChat,config);
             } else {
                 if(groupChat.getChatUserList() != null && !groupChat.getChatUserList().isEmpty()){
                     groupChat.getChatUserList().forEach(user -> {
@@ -712,7 +713,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                         ruleTimeVO.setRemark("客户群催课");
                         QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, user.getUserId(), user.getName(), null, isOfficial, null);
                         handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
-                                type, qwUserId, companyUserId, companyId, user.getId().toString(), welcomeText, qwUserName, null, false, miniAppId, groupChat);
+                                type, qwUserId, companyUserId, companyId, user.getId().toString(), welcomeText, qwUserName,
+                                null, false, miniAppId, groupChat,config);
                     });
                 }
             }
@@ -725,7 +727,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                     Long fsUserId = contactId.getFsUserId();
                     QwSopLogs sopLogs = createBaseLog(formattedSendTime, logVo, ruleTimeVO, contactId.getExternalContactId(), externalUserName, fsUserId, isOfficial, contactId.getExternalId());
                     handleLogBasedOnType(sopLogs, content, logVo, sendTime, courseId, videoId,
-                            type, qwUserId, companyUserId, companyId, externalId, welcomeText, qwUserName, fsUserId, false, miniAppId, null);
+                            type, qwUserId, companyUserId, companyId, externalId, welcomeText, qwUserName, fsUserId, false, miniAppId, null,config);
                 } catch (Exception e) {
                     log.error("处理 externalContactId {} 时发生异常: {}", contactId, e.getMessage(), e);
                 }
@@ -833,14 +835,16 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                                       SopUserLogsVo logVo, Date sendTime, Long courseId,
                                       Long videoId, int type, String qwUserId,
                                       String companyUserId, String companyId, String externalId, String welcomeText,
-                                      String qwUserName, Long fsUserId, boolean isGroupChat, String miniAppId, QwGroupChat groupChat) {
+                                      String qwUserName, Long fsUserId, boolean isGroupChat, String miniAppId,
+                                      QwGroupChat groupChat,CourseConfig config) {
         switch (type) {
             case 1:
                 handleNormalMessage(sopLogs, content,companyUserId);
                 break;
             case 2:
                 handleCourseMessage(sopLogs, content, logVo, sendTime, courseId, videoId,
-                        qwUserId, companyUserId, companyId, externalId, welcomeText,qwUserName, fsUserId, isGroupChat, miniAppId, groupChat);
+                        qwUserId, companyUserId, companyId, externalId, welcomeText,qwUserName, fsUserId,
+                        isGroupChat, miniAppId, groupChat,config);
                 break;
             case 3:
                 handleOrderMessage(sopLogs, content);
@@ -873,7 +877,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                                      SopUserLogsVo logVo, Date sendTime, Long courseId,
                                      Long videoId, String qwUserId, String companyUserId,
                                      String companyId, String externalId, String welcomeText, String qwUserName,
-                                     Long fsUserId, boolean isGroupChat, String miniAppId, QwGroupChat groupChat) {
+                                     Long fsUserId, boolean isGroupChat, String miniAppId, QwGroupChat groupChat,CourseConfig config) {
         // 深拷贝 Content 对象,避免使用 JSON
         QwSopTempSetting.Content clonedContent = deepCopyContent(content);
         if (clonedContent == null) {
@@ -974,7 +978,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                     setting.setMiniprogramPage(sortLink.replaceAll("^[\\s\\u2005]+", ""));
 
                     try {
-                        setting.setMiniprogramPicUrl(StringUtil.strIsNullOrEmpty(setting.getMiniprogramPicUrl())?"https://cos.his.cdwjyyh.com/fs/20250331/ec2b4e73be8048afbd526124a655ad56.png":setting.getMiniprogramPicUrl());
+                        setting.setMiniprogramPicUrl(StringUtil.strIsNullOrEmpty(setting.getMiniprogramPicUrl())? config.getSidebarImageUrl():setting.getMiniprogramPicUrl());
                     } catch (Exception e) {
                         log.error("赋值-小程序封面地址失败-" + e);
                     }
@@ -1241,6 +1245,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
             log.error("CourseConfig is not loaded.");
             return "";
         }
+
+
 //        if (StringUtils.isEmpty(config.getMiniprogramPage())){
 //            log.error("miniprogramPage is not loaded.");
 //            return "";

+ 2 - 0
fs-service/src/main/java/com/fs/common/param/LoginMaWxParam.java

@@ -53,4 +53,6 @@ public class LoginMaWxParam implements Serializable {
     @ApiModelProperty(value = "小程序授权类型")
     private Integer authType;
 
+    private String appId;
+
 }

+ 1 - 0
fs-service/src/main/java/com/fs/course/config/CourseConfig.java

@@ -36,6 +36,7 @@ public class CourseConfig implements Serializable {
 
     private String companyUserQRCode;// 默认客服二维码图片
     private String courseLogo;//课程Logo
+    private String sidebarImageUrl;//侧边栏公共图
     private Integer delayStart;
     private Integer delayEnd;
 

+ 9 - 0
fs-service/src/main/java/com/fs/course/service/IFsCourseLinkService.java

@@ -83,4 +83,13 @@ public interface IFsCourseLinkService
     R getRealLinkH5(String link);
 
     R createRoomLink(FsCourseLinkRoomParam param, QwUser qwUser);
+
+    String testGetAppLink();
+
+    /**
+     * 获取跳转微信小程序的链接地址
+     * @param linkStr
+     * @return
+     */
+    String getGotoWxAppLink(String linkStr);
 }

+ 162 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsCourseLinkServiceImpl.java

@@ -1,5 +1,6 @@
 package com.fs.course.service.impl;
 
+import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
@@ -10,6 +11,7 @@ import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.date.DateUtil;
 import com.fs.company.mapper.CompanyUserMapper;
 import com.fs.config.cloud.CloudHostProper;
+import com.fs.core.config.WxMaConfiguration;
 import com.fs.course.config.CourseConfig;
 import com.fs.course.domain.*;
 import com.fs.course.mapper.FsCourseDomainNameMapper;
@@ -20,6 +22,8 @@ import com.fs.course.param.FsCourseLinkCreateParam;
 import com.fs.course.param.FsCourseLinkRoomParam;
 import com.fs.course.service.IFsCourseLinkService;
 import com.fs.course.service.IFsUserCourseService;
+import com.fs.his.config.FsSysConfig;
+import com.fs.his.utils.ConfigUtil;
 import com.fs.qw.domain.QwGroupChat;
 import com.fs.qw.domain.QwGroupChatUser;
 import com.fs.qw.domain.QwUser;
@@ -32,13 +36,26 @@ import com.fs.system.service.ISysConfigService;
 import com.fs.voice.utils.StringUtil;
 import lombok.Synchronized;
 import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.api.WxMpService;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
@@ -661,4 +678,149 @@ public class FsCourseLinkServiceImpl implements IFsCourseLinkService
     }
 
 
+    /**
+     *
+     * 生成跳转微信小程序的链接 base
+     *
+     * @param appid 微信appid
+     * @param path  跳转页面路径
+     * @param query 需要传参的String
+     * @return
+     */
+    public String getWxAppLink(String appid, String path, String query) {
+
+        StringBuilder wxAppLink = new StringBuilder("weixin://dl/business/?");
+        try {
+            wxAppLink.append("appid=").append(appid);
+            wxAppLink.append("&path=").append(path);
+            String encodedQuery =  URLEncoder.encode(URLEncoder.encode(query, StandardCharsets.UTF_8.toString()));
+            wxAppLink.append("&query=").append(encodedQuery);
+//            wxAppLink.append("&env_version=trial");
+//            if(StringUtils.isNotBlank(envVersion)){
+//                wxAppLink.append("&env_version=").append(envVersion);
+//            }
+
+        } catch (UnsupportedEncodingException e) {
+            log.error("生成跳转微信小程序的链接失败" + e.getMessage());
+            return "生成失败";
+        }
+        return wxAppLink.toString();
+
+    }
+
+    @Override
+    public String testGetAppLink() {
+        String pageLink = "/pages_course/video.html?course\\u003d{\\\"companyId\\\":100,\\\"companyUserId\\\":2020,\\\"corpId\\\":\\\"ww51717e2b71d5e2d3\\\",\\\"courseId\\\":63,\\\"link\\\":\\\"1943203055923101696\\\",\\\"linkType\\\":3,\\\"qwExternalId\\\":20812637,\\\"qwUserId\\\":\\\"9112\\\",\\\"videoId\\\":400}";
+        String miniprogramAppid = "wx76cb55db092a41ae";
+        if (StringUtils.isNotBlank(pageLink)) {
+
+            //解析pageLink
+            String[] split = pageLink.split("\\?");
+            if (split.length == 2 && split[0].length() > 0 && split[1].length() > 0) {
+                //处理页面路径
+                String pageUrl =split[0];
+                if(pageUrl.startsWith("/")){
+                    pageUrl = pageUrl.substring(1);
+                }
+                if(pageUrl.contains(".html")){
+                    pageUrl = pageUrl.replace(".html", "");
+                }
+                //处理参数
+                String query = split[1];
+                query = query.replace("\\u003d", "=");
+                String wxAppLink = getWxAppLink(miniprogramAppid, pageUrl, query);
+                return wxAppLink;
+            } else {
+                return "页面链接错误,获取失败";
+            }
+        }
+        return pageLink;
+
+    }
+
+    /**
+     * 获取跳转微信小程序的链接地址
+     * @param linkStr
+     * @return
+     */
+    @Override
+    public String getGotoWxAppLink(String linkStr) {
+//        CloseableHttpClient client = null;
+//        try {
+//            client = HttpClients.createDefault();
+//            String[] split = linkStr.split("\\?");
+//            if (split.length == 2 && split[0].length() > 0 && split[1].length() > 0) {
+//                //处理页面路径
+//                String pageUrl = split[0];
+//                if (pageUrl.startsWith("/")) {
+//                    pageUrl = pageUrl.substring(1);
+//                }
+//                //处理参数
+//                String query = split[1];
+//                String json = configService.selectConfigByKey("course.config");
+//                CourseConfig config = JSON.parseObject(json, CourseConfig.class);
+//                String miniprogramAppid = config.getMiniprogramAppid();
+//                if (StringUtils.isBlank(miniprogramAppid)) {
+//                    return "未配置点播小程序id";
+//                }
+//                if(StringUtils.isBlank(code)){
+//                    return "参数错误,请传入code";
+//                }
+//                //获取微信token
+//                final WxMaService wxService = WxMaConfiguration.getMaService("wx76cb55db092a41ae");
+//                String token = wxService.getAccessToken();
+//                HttpPost httpPost = new HttpPost("https://api.weixin.qq.com/wxa/generate_urllink?access_token=" + token);
+//                JSONObject bodyObj = new JSONObject();
+//                bodyObj.put("path", pageUrl);
+//                bodyObj.put("query", query);
+//                log.info("微信小程序请求参数打印:{}", bodyObj.toJSONString());
+//                StringEntity entity = new StringEntity(bodyObj.toJSONString(),"UTF-8");
+//                httpPost.setEntity(entity);
+//                httpPost.setHeader("Content-type", "application/json");
+//                HttpEntity response = client.execute(httpPost).getEntity();
+//                String responseString = EntityUtils.toString(response);
+//                log.info("微信小程序接口响应数据:{}", responseString);
+//                JSONObject jsonObject = JSONObject.parseObject(responseString);
+//                if(null != jsonObject && !jsonObject.isEmpty() && jsonObject.containsKey("url_link")){
+//                    return jsonObject.getString("url_link");
+//                }
+//            } else {
+//                return "页面链接错误,获取失败";
+//            }
+//
+//        } catch (WxErrorException e) {
+//            throw new RuntimeException(e);
+//        } catch (ClientProtocolException e) {
+//            throw new RuntimeException(e);
+//        } catch (IOException e) {
+//            throw new RuntimeException(e);
+//        }
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSON.parseObject(json, CourseConfig.class);
+        String miniprogramAppid = config.getMiniprogramAppid();
+        if (StringUtils.isBlank(miniprogramAppid)) {
+                    return "未配置点播小程序id";
+                }
+//        String envVersion = "trial";
+//        String envVersion = version;
+        if (StringUtils.isNotBlank(linkStr)) {
+            //解析pageLink
+            String[] split = linkStr.split("\\?");
+            if (split.length == 2 && split[0].length() > 0 && split[1].length() > 0) {
+                //处理页面路径
+                String pageUrl =split[0];
+                if(pageUrl.startsWith("/")){
+                    pageUrl = pageUrl.substring(1);
+                }
+                //处理参数
+                String query = split[1];
+//                query = query.replace("\\u003d", "=");
+                String wxAppLink = getWxAppLink(miniprogramAppid, pageUrl, query);
+                return wxAppLink;
+            } else {
+                return "页面链接错误,获取失败";
+            }
+        }
+        return "";
+    }
 }

+ 11 - 3
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -1736,6 +1736,10 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     @Override
     public R createMiniLink(FsCourseLinkMiniParam param) {
 
+
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSON.parseObject(json, CourseConfig.class);
+
         QwUser qwUser = qwExternalContactService.getQwUserByRedis(param.getCorpId().trim(), param.getQwUserId().trim());
 
         if (qwUser==null||qwUser.getCompanyId()==null||qwUser.getCompanyUserId()==null){
@@ -1757,7 +1761,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         JSONObject news = new JSONObject(true);
         news.put("miniprogramAppid", qwCompany.getMiniAppId());
         news.put("miniprogramTitle", param.getTitle());
-        news.put("miniprogramPicUrl", "https://cos.his.cdwjyyh.com/fs/20250523/9c8af5735d784847818cada7fa776a7b.jpg");
+        news.put("miniprogramPicUrl", config.getSidebarImageUrl());
         news.put("miniprogramPage", linkByMiniApp);
 
         return R.ok().put("data",news);
@@ -1801,7 +1805,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         JSONObject news = new JSONObject(true); // true 表示保持字段顺序
         news.put("linkTitle", param.getTitle());
         news.put("linkDescribe", param.getTitle());
-        news.put("linkImageUrl", "https://cos.his.cdwjyyh.com/fs/20250523/9c8af5735d784847818cada7fa776a7b.jpg");
+        news.put("linkImageUrl", config.getSidebarImageUrl());
         news.put("linkUrl", linkByCartLink);
 
         return R.ok().put("data",news);
@@ -2011,6 +2015,10 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
     @Override
     public R createRoomMiniLink(FsCourseLinkMiniParam param) {
+
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSON.parseObject(json, CourseConfig.class);
+
         QwUser qwUser = qwExternalContactService.getQwUserByRedis(param.getCorpId().trim(), param.getQwUserId().trim());
 
         if (qwUser==null||qwUser.getCompanyId()==null||qwUser.getCompanyUserId()==null){
@@ -2029,7 +2037,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         JSONObject news = new JSONObject(true);
         news.put("miniprogramAppid", qwCompany.getMiniAppId());
         news.put("miniprogramTitle", param.getTitle());
-        news.put("miniprogramPicUrl", "https://cos.his.cdwjyyh.com/fs/20250523/9c8af5735d784847818cada7fa776a7b.jpg");
+        news.put("miniprogramPicUrl", config.getSidebarImageUrl());
         news.put("miniprogramPage", linkByMiniApp);
 
         return R.ok().put("data",news);

+ 77 - 22
fs-service/src/main/java/com/fs/statis/domain/FsStatisEveryDayWatch.java

@@ -1,15 +1,15 @@
 package com.fs.statis.domain;
 
+import com.fs.common.annotation.Excel;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
-import java.time.LocalDateTime;
+import java.time.LocalDate;
 
 /**
- * 每日统计数据实体类
- * 对应表 fs_statis_every_day_watch
+ * 销售观看统计实体类
  */
 @Data
 @NoArgsConstructor
@@ -20,86 +20,141 @@ public class FsStatisEveryDayWatch {
     /**
      * 主键ID
      */
-    private Integer id;
+    private Long id;
+
+    /**
+     * 部门
+     */
+    private Long deptId;
 
     /**
      * 数据日期
      */
-    private LocalDateTime dataDate;
+    @Excel(name = "日期")
+    private LocalDate dataDate;
 
     /**
-     * 训练营id
+     * 部门名称
+     */
+    private String deptName;
+
+    /**
+     * 销售id
+     */
+    private Long companyUserId;
+    /**
+     * 销售名称
      */
-    private Integer periodId;
+    private String companyUserName;
 
     /**
      * 训练营人数
      */
-    private Integer periodNum;
+    @Excel(name = "训练营人数")
+    private Long trainCampNum;
+
+    /**
+     * 发课数
+     */
+    @Excel(name = "发课数")
+    private Long sendNum;
 
     /**
      * 未报名人数
      */
-    private Integer notRegNum;
+    @Excel(name = "未报名人数")
+    private Long notRegisteredNum;
 
     /**
      * 已报名人数
      */
-    private Integer registeredNum;
+    @Excel(name = "已报名人数")
+    private Long registeredNum;
+    /**
+     * 完课人数
+     */
+    @Excel(name = "完课人数")
+    private Long completedNum;
+    /**
+     * 看课中断数
+     */
+    @Excel(name = "看课中断数")
+    private Long interruptNum;
+
+    /**
+     * 企微重粉
+     */
+    @Excel(name = "企微重粉")
+    private Long qwRepeatNum;
+
+    /**
+     * 小程序(看课)重粉
+     */
+    @Excel(name = "小程序(看课)重粉")
+    private Long userRepeatNum;
 
     /**
      * 报名率
      */
+    @Excel(name = "上线率")
     private Float regRate;
 
     /**
      * 完课率
      */
-    private Float completedRate;
+    @Excel(name = "完课率")
+    private Float finishedRate;
 
     /**
      * 未上线-总数
      */
-    private Integer offlineTotal;
+    private Long offlineTotal;
 
     /**
      * 未上线-未参与
      */
-    private Integer offlineNotRegNum;
+    private Long offlineNotPart;
 
     /**
-     * 未上线-未观看
+     * 未上线-未观看 (原SQL注释为'为观看',推测应为'未观看')
      */
-    private Integer offlineNotWatchNum;
+    private Long offlineNotWatched;
 
     /**
      * 已上线-总数
      */
-    private Integer onlineTotal;
+    private Long onlineTotal;
 
     /**
      * 已上线-上线率
      */
-    private Float onlineRate;
+    private Float onlineOnlineRate;
 
     /**
      * 已上线-完播率
      */
-    private Float onlineCompletedRate;
+    private Float onlinePlaybackCompleRate;
 
     /**
      * 已上线-未完播
      */
-    private Integer onlineNotCompRateNum;
+    private Long onlineIncompletePlayback;
 
     /**
      * 已上线-已完播
      */
-    private Integer onlineCompletedNum;
+    private Long onlineCompletePlayback;
 
     /**
-     * 销售id
+     * 营期id
+     */
+    private String periodId;
+
+    /**
+     * 营期名称
      */
-    private Integer companyUserId;
+    private String periodName;
+
 
+    private String sopId;
 }

+ 2 - 2
fs-service/src/main/resources/mapper/sop/QwSopLogsMapper.xml

@@ -741,10 +741,10 @@
         ORDER BY send_time desc
     </select>
     <select id="queryPeriodNameById" resultType="java.lang.String">
-        select concat(qw_user_key,'-',start_time) from sop_user_logs where id=#{periodId}
+        select concat(qw_user_id,'-',start_time) from sop_user_logs where id=#{periodId}
     </select>
     <select id="queryAllPeriod" resultType="com.fs.sop.domain.QwSopLogs">
-        select id,concat(qw_user_key,'-',start_time) as sop_title from sop_user_logs
+        select id,concat(qw_user_id,'-',start_time) as sop_title from sop_user_logs
     </select>
     <select id="selectQwSopLogsCountByQwUserId" resultType="java.lang.Long">
         select count(1) from qw_sop_logs

+ 3 - 0
fs-user-course/src/main/java/com/fs/course/controller/WxCompanyUserController.java

@@ -96,6 +96,9 @@ public class WxCompanyUserController extends AppBaseController {
         if (company.getCourseMiniAppId() == null) {
             return R.error("小程序参数错误!");
         }
+//        if (!param.getAppId().equals(company.getCourseMiniAppId())){
+//            return R.error("无权限,");
+//        }
 
         final WxMaService wxService = WxMaConfiguration.getMaService(company.getCourseMiniAppId());
         try {

+ 82 - 0
fs-user-course/src/main/java/com/fs/course/controller/WxPayController.java

@@ -0,0 +1,82 @@
+package com.fs.course.controller;
+
+
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.R;
+import com.fs.course.service.IFsCourseRedPacketLogService;
+import com.fs.course.service.IFsUserCourseOrderService;
+import com.fs.course.service.IFsUserVipOrderService;
+import com.fs.his.param.WxSendRedPacketParam;
+import com.fs.his.service.IFsInquiryOrderService;
+import com.fs.his.service.IFsPackageOrderService;
+import com.fs.his.service.IFsStoreOrderService;
+import com.fs.his.service.IFsStorePaymentService;
+import com.fs.sop.service.ISopUserLogsInfoService;
+import com.fs.system.service.ISysConfigService;
+import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
+import com.github.binarywang.wxpay.service.WxPayService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@Api("微信支付接口")
+@RestController
+@RequestMapping("/app/wxpay")
+public class WxPayController {
+    protected final Logger logger = LoggerFactory.getLogger(BaseController.class);
+    @Autowired
+    private WxPayService wxPayService;
+    @Autowired
+    private IFsInquiryOrderService inquiryOrderService;
+    @Autowired
+    private IFsStoreOrderService storeOrderService;
+    @Autowired
+    private IFsPackageOrderService packageOrderService;
+
+    @Autowired
+    private IFsUserCourseOrderService courseOrderService;
+
+    @Autowired
+    private IFsUserVipOrderService userVipOrderService;
+    @Autowired
+    private IFsStorePaymentService  paymentService;
+    @Autowired
+    private IFsCourseRedPacketLogService redPacketLogService;
+    @Autowired
+    private ISysConfigService configService;
+
+    @Autowired
+    private ISopUserLogsInfoService iSopUserLogsInfoService;
+
+    @PostMapping("/sendRedPacket")
+    public R sendRedPacket(@RequestBody WxSendRedPacketParam param){
+       return paymentService.sendRedPacketTest(param);
+    }
+
+    @PostMapping( "/TransferNotify")
+    public String TransferNotify(@RequestBody String notifyData,HttpServletRequest request, HttpServletResponse response) throws Exception {
+        return paymentService.transferNotify(notifyData,request);
+    }
+
+
+    @PostMapping( "/v3TransferNotify")
+    public String v3TransferNotify(@RequestBody String notifyData,HttpServletRequest request, HttpServletResponse response) throws Exception {
+        return paymentService.v3TransferNotify(notifyData,request);
+    }
+
+    @GetMapping("/test")
+    public void test(){
+        iSopUserLogsInfoService.updateSopUserInfoByExternalId(1L,123456L);
+    }
+
+
+
+}