Просмотр исходного кода

1、迁移企微客户群成员的接口迁移到qw-api模块中
2、客户群发记录
3、群发成员发送任务及执行结果反馈记录
4、素材库

yys 12 часов назад
Родитель
Сommit
3640108a09

+ 34 - 8
fs-company/src/main/java/com/fs/company/controller/qw/QwGroupChatUserController.java

@@ -1,19 +1,25 @@
 package com.fs.company.controller.qw;
 
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.alibaba.fastjson.JSON;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
-import com.fs.framework.service.TokenService;
+import com.fs.common.utils.SecurityUtils;
 import com.fs.qw.domain.QwGroupChatUser;
 import com.fs.qw.param.QwGroupChatUserDataType;
 import com.fs.qw.param.QwInsertGroupChatUserParam;
 import com.fs.qw.service.IQwGroupChatUserService;
 import com.fs.qw.vo.QwGroupChatUserVO;
+import com.fs.qwApi.config.OpenQwConfig;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.*;
 
+import java.net.SocketTimeoutException;
 import java.util.List;
 
 /**
@@ -22,6 +28,7 @@ import java.util.List;
  * @author fs
  * @date 2024-06-20
  */
+@Slf4j
 @RestController
 @RequestMapping("/qw/group_chat_user")
 public class QwGroupChatUserController extends BaseController
@@ -29,8 +36,9 @@ public class QwGroupChatUserController extends BaseController
     @Autowired
     private IQwGroupChatUserService qwGroupChatUserService;
 
-    @Autowired
-    private TokenService tokenService;
+    /** HTTP调用超时时间(秒) */
+    @Value("${qw.api.timeout:30}")
+    private int apiTimeout;
 
     /**
      * 查询客户群成员列列表
@@ -62,11 +70,29 @@ public class QwGroupChatUserController extends BaseController
     }
 
     /**
-     *  同步 插入某个客户群信息
+     *  同步 插入某个客户群信息(远程调用fs-qw-api)
      */
-    @PutMapping("/cogradientGroupChatUser")
+    @PostMapping("/cogradientGroupChatUser")
     public R cogradientGroupChatUser(@RequestBody QwInsertGroupChatUserParam param) {
-
-        return qwGroupChatUserService.cogradientGroupChatUser(param.getCorpId(), param.getChatId());
+        Long tenantId = SecurityUtils.getTenantId();
+        String url = OpenQwConfig.api + "/qw/group_chat_user/cogradientGroupChatUser?tenantId=" + tenantId;
+        try {
+            HttpResponse response = HttpRequest.post(url)
+                    .body(JSON.toJSONString(param))
+                    .timeout(apiTimeout * 1000)
+                    .execute();
+            if (response.getStatus() == 200) {
+                return JSON.parseObject(response.body(), R.class);
+            } else {
+                log.error("同步客户群成员失败,HTTP状态码: {}", response.getStatus());
+                return R.error("同步客户群成员失败,服务返回状态码: " + response.getStatus());
+            }
+        } catch (Exception e) {
+            log.error("同步客户群成员异常, url={}", url, e);
+            if (e.getCause() instanceof SocketTimeoutException) {
+                return R.error("同步客户群成员超时,请稍后重试");
+            }
+            return R.error("同步客户群成员失败: " + e.getMessage());
+        }
     }
 }

+ 55 - 7
fs-company/src/main/java/com/fs/company/controller/qw/QwGroupMsgController.java

@@ -1,11 +1,15 @@
 package com.fs.company.controller.qw;
 
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.alibaba.fastjson.JSON;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.SecurityUtils;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.framework.security.LoginUser;
@@ -16,10 +20,14 @@ import com.fs.qw.param.QwGroupMsgParam;
 import com.fs.qw.service.IQwGroupMsgService;
 import com.fs.qw.vo.QwGroupMsgDetailsVO;
 import com.fs.qw.vo.QwGroupMsgVO;
+import com.fs.qwApi.config.OpenQwConfig;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
+import java.net.SocketTimeoutException;
 import java.util.List;
 
 /**
@@ -28,6 +36,7 @@ import java.util.List;
  * @author fs
  * @date 2024-06-20
  */
+@Slf4j
 @RestController
 @RequestMapping("/qw/groupMsg")
 public class QwGroupMsgController extends BaseController
@@ -37,6 +46,10 @@ public class QwGroupMsgController extends BaseController
 
     @Autowired
     private TokenService tokenService;
+
+    /** HTTP调用超时时间(秒) */
+    @Value("${qw.api.timeout:30}")
+    private int apiTimeout;
     /**
      * 查询客户群发记录主列表
      */
@@ -90,16 +103,34 @@ public class QwGroupMsgController extends BaseController
     }
 
     /**
-     * 新增客户群发/客户群群发记录
+     * 新增客户群发/客户群群发记录(远程调用fs-qw-api)
      */
     @PreAuthorize("@ss.hasPermi('qw:groupMsg:add')")
     @Log(title = "客户群发记录", businessType = BusinessType.INSERT)
     @PostMapping
     public R add(@RequestBody QwGroupMsgParam qwGroupMsgParam) throws Exception {
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-//        Long companyId = loginUser.getCompany().getCompanyId();
         qwGroupMsgParam.setCreateName(loginUser.getUser().getNickName());
-        return qwGroupMsgService.insertQwGroupMsg(qwGroupMsgParam);
+        Long tenantId = SecurityUtils.getTenantId();
+        String url = OpenQwConfig.api + "/qw/groupMsg/add?tenantId=" + tenantId;
+        try {
+            HttpResponse response = HttpRequest.post(url)
+                    .timeout(apiTimeout * 1000)
+                    .body(JSON.toJSONString(qwGroupMsgParam))
+                    .execute();
+            if (response.getStatus() == 200) {
+                return JSON.parseObject(response.body(), R.class);
+            } else {
+                log.error("新增客户群发记录失败,HTTP状态码: {}", response.getStatus());
+                return R.error("新增客户群发记录失败,服务返回状态码: " + response.getStatus());
+            }
+        } catch (Exception e) {
+            log.error("新增客户群发记录异常, url={}", url, e);
+            if (e.getCause() instanceof SocketTimeoutException) {
+                return R.error("新增客户群发记录超时,请稍后重试");
+            }
+            return R.error("新增客户群发记录失败: " + e.getMessage());
+        }
     }
 
     /** 统计数据详情,已发送,未发送,已接收,未接收等
@@ -129,13 +160,30 @@ public class QwGroupMsgController extends BaseController
         return getDataTable(list);
     }
 
-    /** 提醒成员群发 */
+    /** 提醒成员群发(远程调用fs-qw-api) */
     @PreAuthorize("@ss.hasPermi('qw:groupMsg:remindGroupMsg')")
     @GetMapping("/remindGroupMsg")
     public R remindGroupMsg(QwGroupMsgDetailsParam qwGroupMsgDetailsParam){
-
-
-        return  qwGroupMsgService.remindGroupMsg(qwGroupMsgDetailsParam);
+        Long tenantId = SecurityUtils.getTenantId();
+        String url = OpenQwConfig.api + "/qw/groupMsg/remindGroupMsg?tenantId=" + tenantId;
+        try {
+            HttpResponse response = HttpRequest.post(url)
+                    .timeout(apiTimeout * 1000)
+                    .body(JSON.toJSONString(qwGroupMsgDetailsParam))
+                    .execute();
+            if (response.getStatus() == 200) {
+                return JSON.parseObject(response.body(), R.class);
+            } else {
+                log.error("提醒成员群发失败,HTTP状态码: {}", response.getStatus());
+                return R.error("提醒成员群发失败,服务返回状态码: " + response.getStatus());
+            }
+        } catch (Exception e) {
+            log.error("提醒成员群发异常, url={}", url, e);
+            if (e.getCause() instanceof SocketTimeoutException) {
+                return R.error("提醒成员群发超时,请稍后重试");
+            }
+            return R.error("提醒成员群发失败: " + e.getMessage());
+        }
     }
 
 //    /**

+ 56 - 11
fs-company/src/main/java/com/fs/company/controller/qw/QwGroupMsgUserController.java

@@ -1,20 +1,27 @@
 package com.fs.company.controller.qw;
 
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.alibaba.fastjson.JSON;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.SecurityUtils;
 import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.framework.service.TokenService;
 import com.fs.qw.domain.QwGroupMsgUser;
 import com.fs.qw.service.IQwGroupMsgUserService;
 import com.fs.qw.vo.QwGroupMsgDetailsVO;
+import com.fs.qwApi.config.OpenQwConfig;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
+import java.net.SocketTimeoutException;
 import java.util.List;
 
 /**
@@ -23,6 +30,7 @@ import java.util.List;
  * @author fs
  * @date 2024-06-20
  */
+@Slf4j
 @RestController
 @RequestMapping("/qw/groupMsgUser")
 public class QwGroupMsgUserController extends BaseController
@@ -30,8 +38,9 @@ public class QwGroupMsgUserController extends BaseController
     @Autowired
     private IQwGroupMsgUserService qwGroupMsgUserService;
 
-    @Autowired
-    private TokenService tokenService;
+    /** HTTP调用超时时间(秒) */
+    @Value("${qw.api.timeout:30}")
+    private int apiTimeout;
 
     /**
      * 查询群发成员发送任务及执行结果反馈记录列表
@@ -101,18 +110,54 @@ public class QwGroupMsgUserController extends BaseController
         return toAjax(qwGroupMsgUserService.deleteQwGroupMsgUserByIds(ids));
     }
 
-    /** 刷新/同步 客户群群发 结果 */
+    /** 刷新/同步 客户群群发 结果(远程调用fs-qw-api) */
     @PostMapping("/refreshResultsGroupMsgUser")
     public R refreshResultsGroupMsgUser(@RequestBody List<QwGroupMsgDetailsVO> list){
-
-
-        return  qwGroupMsgUserService.refreshResultsGroupMsgUser(list);
+        Long tenantId = SecurityUtils.getTenantId();
+        String url = OpenQwConfig.api + "/qw/groupMsgUser/refreshResultsGroupMsgUser?tenantId=" + tenantId;
+        try {
+            HttpResponse response = HttpRequest.post(url)
+                    .timeout(apiTimeout * 1000)
+                    .body(JSON.toJSONString(list))
+                    .execute();
+            if (response.getStatus() == 200) {
+                return JSON.parseObject(response.body(), R.class);
+            } else {
+                log.error("刷新客户群群发结果失败,HTTP状态码: {}", response.getStatus());
+                return R.error("刷新客户群群发结果失败,服务返回状态码: " + response.getStatus());
+            }
+        } catch (Exception e) {
+            log.error("刷新客户群群发结果异常, url={}", url, e);
+            if (e.getCause() instanceof SocketTimeoutException) {
+                return R.error("刷新客户群群发结果超时,请稍后重试");
+            }
+            return R.error("刷新客户群群发结果失败: " + e.getMessage());
+        }
     }
 
-    /** 刷新/同步 客户群发 结果 */
+    /** 刷新/同步 客户群发 结果(远程调用fs-qw-api) */
     @PostMapping("/refreshResultsMsgUser")
-    public R refreshResultsMsgUser(@RequestBody List<QwGroupMsgDetailsVO> list,String corpId){
-        QwGroupMsgDetailsVO qwGroupMsgDetailsVO = list.get(0);
-        return  qwGroupMsgUserService.refreshResultsMsgUser(list,qwGroupMsgDetailsVO.getCorpId() );
+    public R refreshResultsMsgUser(@RequestBody List<QwGroupMsgDetailsVO> list, String corpId){
+        Long tenantId = SecurityUtils.getTenantId();
+        String url = OpenQwConfig.api + "/qw/groupMsgUser/refreshResultsMsgUser?tenantId=" + tenantId
+                + "&corpId=" + corpId;
+        try {
+            HttpResponse response = HttpRequest.post(url)
+                    .timeout(apiTimeout * 1000)
+                    .body(JSON.toJSONString(list))
+                    .execute();
+            if (response.getStatus() == 200) {
+                return JSON.parseObject(response.body(), R.class);
+            } else {
+                log.error("刷新客户群发结果失败,HTTP状态码: {}", response.getStatus());
+                return R.error("刷新客户群发结果失败,服务返回状态码: " + response.getStatus());
+            }
+        } catch (Exception e) {
+            log.error("刷新客户群发结果异常, url={}", url, e);
+            if (e.getCause() instanceof SocketTimeoutException) {
+                return R.error("刷新客户群发结果超时,请稍后重试");
+            }
+            return R.error("刷新客户群发结果失败: " + e.getMessage());
+        }
     }
 }

+ 34 - 7
fs-company/src/main/java/com/fs/company/controller/qw/QwMaterialController.java

@@ -1,5 +1,8 @@
 package com.fs.company.controller.qw;
 
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.alibaba.fastjson.JSON;
 import com.fs.common.annotation.Log;
 import com.fs.common.annotation.RepeatSubmit;
 import com.fs.common.core.controller.BaseController;
@@ -7,6 +10,7 @@ import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.SecurityUtils;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.framework.security.LoginUser;
@@ -14,12 +18,15 @@ import com.fs.framework.service.TokenService;
 import com.fs.qw.domain.QwMaterial;
 import com.fs.qw.param.QwMaterialParam;
 import com.fs.qw.service.IQwMaterialService;
-import com.fs.qw.service.IQwUserService;
 import com.fs.qw.vo.QwMaterialVO;
+import com.fs.qwApi.config.OpenQwConfig;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
+import java.net.SocketTimeoutException;
 import java.util.List;
 
 /**
@@ -28,6 +35,7 @@ import java.util.List;
  * @author fs
  * @date 2024-06-20
  */
+@Slf4j
 @RestController
 @RequestMapping("/qw/material")
 public class QwMaterialController extends BaseController
@@ -35,12 +43,13 @@ public class QwMaterialController extends BaseController
     @Autowired
     private IQwMaterialService qwMaterialService;
 
-    @Autowired
-    private IQwUserService qwUserService;
-
     @Autowired
     private TokenService tokenService;
 
+    /** HTTP调用超时时间(秒) */
+    @Value("${qw.api.timeout:30}")
+    private int apiTimeout;
+
     /**
      * 查询我的素材库列表
      */
@@ -97,7 +106,7 @@ public class QwMaterialController extends BaseController
     }
 
     /**
-     * 新增素材库
+     * 新增素材库(远程调用fs-qw-api)
      */
     @PreAuthorize("@ss.hasPermi('qw:material:add')")
     @Log(title = "素材库", businessType = BusinessType.INSERT)
@@ -107,8 +116,26 @@ public class QwMaterialController extends BaseController
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         qwMaterial.setCreateUserId(loginUser.getUser().getUserId());
         qwMaterial.setCompanyId(loginUser.getUser().getCompanyId());
-
-        return qwMaterialService.insertQwMaterial(qwMaterial);
+        Long tenantId = SecurityUtils.getTenantId();
+        String url = OpenQwConfig.api + "/qw/material/add?tenantId=" + tenantId;
+        try {
+            HttpResponse response = HttpRequest.post(url)
+                    .timeout(apiTimeout * 1000)
+                    .body(JSON.toJSONString(qwMaterial))
+                    .execute();
+            if (response.getStatus() == 200) {
+                return JSON.parseObject(response.body(), R.class);
+            } else {
+                log.error("新增素材库失败,HTTP状态码: {}", response.getStatus());
+                return R.error("新增素材库失败,服务返回状态码: " + response.getStatus());
+            }
+        } catch (Exception e) {
+            log.error("新增素材库异常, url={}", url, e);
+            if (e.getCause() instanceof SocketTimeoutException) {
+                return R.error("新增素材库超时,请稍后重试");
+            }
+            return R.error("新增素材库失败: " + e.getMessage());
+        }
     }
 
     /**

+ 47 - 0
fs-qw-api/src/main/java/com/fs/app/controller/QwGroupChatUserController.java

@@ -0,0 +1,47 @@
+package com.fs.app.controller;
+
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.R;
+import com.fs.framework.datasource.TenantDataSourceUtil;
+import com.fs.qw.param.QwInsertGroupChatUserParam;
+import com.fs.qw.service.IQwGroupChatUserService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 客户群成员Controller(API端)
+ * 由Company端通过HTTP远程调用
+ *
+ * @author fs
+ */
+@Slf4j
+@RestController
+@RequestMapping("/qw/group_chat_user")
+public class QwGroupChatUserController extends BaseController {
+
+    @Autowired
+    private IQwGroupChatUserService qwGroupChatUserService;
+
+    @Autowired
+    private TenantDataSourceUtil tenantDataSourceUtil;
+
+    /**
+     * 同步插入某个客户群信息
+     */
+    @PostMapping("/cogradientGroupChatUser")
+    public R cogradientGroupChatUser(@RequestBody QwInsertGroupChatUserParam param, @RequestParam("tenantId") Long tenantId) {
+        try {
+            log.info("[GroupChatUser] 同步客户群成员,tenantId={}, corpId={}, chatId={}", tenantId, param.getCorpId(), param.getChatId());
+            return tenantDataSourceUtil.executeWithResult(tenantId, () -> {
+                return qwGroupChatUserService.cogradientGroupChatUser(param.getCorpId(), param.getChatId());
+            });
+        } catch (IllegalArgumentException e) {
+            log.error("[GroupChatUser] 同步客户群成员失败,租户不存在或已禁用,tenantId={}", tenantId, e);
+            return R.error("租户不存在或已禁用");
+        } catch (Exception e) {
+            log.error("[GroupChatUser] 同步客户群成员异常,tenantId={}, corpId={}, chatId={}", tenantId, param.getCorpId(), param.getChatId(), e);
+            return R.error("同步客户群成员失败: " + e.getMessage());
+        }
+    }
+}

+ 77 - 0
fs-qw-api/src/main/java/com/fs/app/controller/QwGroupMsgController.java

@@ -0,0 +1,77 @@
+package com.fs.app.controller;
+
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.R;
+import com.fs.framework.datasource.TenantDataSourceUtil;
+import com.fs.qw.param.QwGroupMsgDetailsParam;
+import com.fs.qw.param.QwGroupMsgParam;
+import com.fs.qw.service.IQwGroupMsgService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 客户群发记录主Controller(API端)
+ * 由Company端通过HTTP远程调用
+ *
+ * @author fs
+ */
+@Slf4j
+@RestController
+@RequestMapping("/qw/groupMsg")
+public class QwGroupMsgController extends BaseController {
+
+    @Autowired
+    private IQwGroupMsgService qwGroupMsgService;
+
+    @Autowired
+    private TenantDataSourceUtil tenantDataSourceUtil;
+
+    /**
+     * 新增客户群发/客户群群发记录
+     */
+    @PostMapping("/add")
+    public R add(@RequestBody QwGroupMsgParam qwGroupMsgParam, @RequestParam("tenantId") Long tenantId) {
+        try {
+            log.info("[GroupMsg] 新增客户群发记录,tenantId={}, corpId={}", tenantId, qwGroupMsgParam.getCorpId());
+            return tenantDataSourceUtil.executeWithResult(tenantId, () -> {
+                try {
+                    return qwGroupMsgService.insertQwGroupMsg(qwGroupMsgParam);
+                } catch (Exception e) {
+                    log.error("[GroupMsg] 新增客户群发记录异常", e);
+                    return R.error("新增客户群发记录失败: " + e.getMessage());
+                }
+            });
+        } catch (IllegalArgumentException e) {
+            log.error("[GroupMsg] 新增客户群发记录失败,租户不存在或已禁用,tenantId={}", tenantId, e);
+            return R.error("租户不存在或已禁用");
+        } catch (Exception e) {
+            log.error("[GroupMsg] 新增客户群发记录异常,tenantId={}", tenantId, e);
+            return R.error("新增客户群发记录失败: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 提醒成员群发
+     */
+    @PostMapping("/remindGroupMsg")
+    public R remindGroupMsg(@RequestBody QwGroupMsgDetailsParam qwGroupMsgDetailsParam, @RequestParam("tenantId") Long tenantId) {
+        try {
+            log.info("[GroupMsg] 提醒成员群发,tenantId={}", tenantId);
+            return tenantDataSourceUtil.executeWithResult(tenantId, () -> {
+                try {
+                    return qwGroupMsgService.remindGroupMsg(qwGroupMsgDetailsParam);
+                } catch (Exception e) {
+                    log.error("[GroupMsg] 提醒成员群发异常", e);
+                    return R.error("提醒成员群发失败: " + e.getMessage());
+                }
+            });
+        } catch (IllegalArgumentException e) {
+            log.error("[GroupMsg] 提醒成员群发失败,租户不存在或已禁用,tenantId={}", tenantId, e);
+            return R.error("租户不存在或已禁用");
+        } catch (Exception e) {
+            log.error("[GroupMsg] 提醒成员群发异常,tenantId={}", tenantId, e);
+            return R.error("提醒成员群发失败: " + e.getMessage());
+        }
+    }
+}

+ 80 - 0
fs-qw-api/src/main/java/com/fs/app/controller/QwGroupMsgUserController.java

@@ -0,0 +1,80 @@
+package com.fs.app.controller;
+
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.R;
+import com.fs.framework.datasource.TenantDataSourceUtil;
+import com.fs.qw.service.IQwGroupMsgUserService;
+import com.fs.qw.vo.QwGroupMsgDetailsVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 群发成员发送任务及执行结果反馈记录Controller(API端)
+ * 由Company端通过HTTP远程调用
+ *
+ * @author fs
+ */
+@Slf4j
+@RestController
+@RequestMapping("/qw/groupMsgUser")
+public class QwGroupMsgUserController extends BaseController {
+
+    @Autowired
+    private IQwGroupMsgUserService qwGroupMsgUserService;
+
+    @Autowired
+    private TenantDataSourceUtil tenantDataSourceUtil;
+
+    /**
+     * 刷新/同步 客户群群发 结果
+     */
+    @PostMapping("/refreshResultsGroupMsgUser")
+    public R refreshResultsGroupMsgUser(@RequestBody List<QwGroupMsgDetailsVO> list, @RequestParam("tenantId") Long tenantId) {
+        try {
+            log.info("[GroupMsgUser] 刷新客户群群发结果,tenantId={}", tenantId);
+            return tenantDataSourceUtil.executeWithResult(tenantId, () -> {
+                try {
+                    return qwGroupMsgUserService.refreshResultsGroupMsgUser(list);
+                } catch (Exception e) {
+                    log.error("[GroupMsgUser] 刷新客户群群发结果异常", e);
+                    return R.error("刷新客户群群发结果失败: " + e.getMessage());
+                }
+            });
+        } catch (IllegalArgumentException e) {
+            log.error("[GroupMsgUser] 刷新客户群群发结果失败,租户不存在或已禁用,tenantId={}", tenantId, e);
+            return R.error("租户不存在或已禁用");
+        } catch (Exception e) {
+            log.error("[GroupMsgUser] 刷新客户群群发结果异常,tenantId={}", tenantId, e);
+            return R.error("刷新客户群群发结果失败: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 刷新/同步 客户群发 结果
+     */
+    @PostMapping("/refreshResultsMsgUser")
+    public R refreshResultsMsgUser(@RequestBody List<QwGroupMsgDetailsVO> list,
+                                   @RequestParam("corpId") String corpId,
+                                   @RequestParam("tenantId") Long tenantId) {
+        try {
+            log.info("[GroupMsgUser] 刷新客户群发结果,tenantId={}, corpId={}", tenantId, corpId);
+            return tenantDataSourceUtil.executeWithResult(tenantId, () -> {
+                try {
+                    return qwGroupMsgUserService.refreshResultsMsgUser(list, corpId);
+                } catch (Exception e) {
+                    log.error("[GroupMsgUser] 刷新客户群发结果异常", e);
+                    return R.error("刷新客户群发结果失败: " + e.getMessage());
+                }
+            });
+        } catch (IllegalArgumentException e) {
+            log.error("[GroupMsgUser] 刷新客户群发结果失败,租户不存在或已禁用,tenantId={}", tenantId, e);
+            return R.error("租户不存在或已禁用");
+        } catch (Exception e) {
+            log.error("[GroupMsgUser] 刷新客户群发结果异常,tenantId={}", tenantId, e);
+            return R.error("刷新客户群发结果失败: " + e.getMessage());
+        }
+    }
+}

+ 52 - 0
fs-qw-api/src/main/java/com/fs/app/controller/QwMaterialController.java

@@ -0,0 +1,52 @@
+package com.fs.app.controller;
+
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.R;
+import com.fs.framework.datasource.TenantDataSourceUtil;
+import com.fs.qw.domain.QwMaterial;
+import com.fs.qw.service.IQwMaterialService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 素材库Controller(API端)
+ * 由Company端通过HTTP远程调用
+ *
+ * @author fs
+ */
+@Slf4j
+@RestController
+@RequestMapping("/qw/material")
+public class QwMaterialController extends BaseController {
+
+    @Autowired
+    private IQwMaterialService qwMaterialService;
+
+    @Autowired
+    private TenantDataSourceUtil tenantDataSourceUtil;
+
+    /**
+     * 新增素材库
+     */
+    @PostMapping("/add")
+    public R add(@RequestBody QwMaterial qwMaterial, @RequestParam("tenantId") Long tenantId) {
+        try {
+            log.info("[Material] 新增素材库,tenantId={}, corpId={}", tenantId, qwMaterial.getCorpId());
+            return tenantDataSourceUtil.executeWithResult(tenantId, () -> {
+                try {
+                    return qwMaterialService.insertQwMaterial(qwMaterial);
+                } catch (Exception e) {
+                    log.error("[Material] 新增素材库异常", e);
+                    return R.error("新增素材库失败: " + e.getMessage());
+                }
+            });
+        } catch (IllegalArgumentException e) {
+            log.error("[Material] 新增素材库失败,租户不存在或已禁用,tenantId={}", tenantId, e);
+            return R.error("租户不存在或已禁用");
+        } catch (Exception e) {
+            log.error("[Material] 新增素材库异常,tenantId={}", tenantId, e);
+            return R.error("新增素材库失败: " + e.getMessage());
+        }
+    }
+}