Bladeren bron

Merge remote-tracking branch 'origin/saas-api' into saas-api

吴树波 2 weken geleden
bovenliggende
commit
1b0cfa0124
27 gewijzigde bestanden met toevoegingen van 287 en 375 verwijderingen
  1. 2 2
      fs-admin-saas/src/main/resources/application-dev.yml
  2. 7 0
      fs-admin/src/main/java/com/fs/admin/controller/AiModelAdminController.java
  3. 4 2
      fs-company/src/main/java/com/fs/company/controller/qw/QwGroupChatController.java
  4. 4 3
      fs-company/src/main/resources/application-dev.yml
  5. 2 0
      fs-framework/src/main/java/com/fs/framework/config/SecurityConfig.java
  6. 0 180
      fs-ipad-task/src/main/java/com/fs/framework/aspectj/TenantDataSourceAspect.java
  7. 2 2
      fs-ipad-task/src/main/resources/application.yml
  8. 1 1
      fs-qw-api-msg/src/main/resources/application.yml
  9. 27 6
      fs-qw-api/src/main/java/com/fs/app/controller/OpenQwApiController.java
  10. 2 2
      fs-qw-api/src/main/java/com/fs/app/service/OpenQwApiService.java
  11. 9 6
      fs-qw-api/src/main/java/com/fs/app/service/impl/OpenQwApiServiceImpl.java
  12. 4 0
      fs-service/src/main/java/com/fs/qw/domain/QwUser.java
  13. 2 2
      fs-service/src/main/java/com/fs/qw/mapper/QwGroupChatMapper.java
  14. 5 2
      fs-service/src/main/java/com/fs/qw/mapper/QwUserMapper.java
  15. 1 1
      fs-service/src/main/java/com/fs/qw/service/IQwUserService.java
  16. 1 1
      fs-service/src/main/java/com/fs/qw/service/IQwUserServiceAsyncHelper.java
  17. 5 1
      fs-service/src/main/java/com/fs/qw/service/impl/QwGroupChatServiceImpl.java
  18. 27 27
      fs-service/src/main/java/com/fs/qw/service/impl/QwUserServiceAsyncHelperImpl.java
  19. 60 18
      fs-service/src/main/java/com/fs/qw/service/impl/QwUserServiceImpl.java
  20. 2 1
      fs-service/src/main/java/com/fs/qwApi/config/OpenQwConfig.java
  21. 0 1
      fs-service/src/main/java/com/fs/system/mapper/SysDictDataMapper.java
  22. 3 0
      fs-service/src/main/resources/application-common.yml
  23. 2 2
      fs-service/src/main/resources/application-dev.yml
  24. 112 112
      fs-service/src/main/resources/db/tenant-initTable.sql
  25. 1 1
      fs-task/src/main/java/com/fs/task/controller/TaskManualController.java
  26. 1 1
      fs-task/src/main/java/com/fs/task/jobs/QwUserAsyncTask.java
  27. 1 1
      fs-task/src/main/resources/application-dev.yml

+ 2 - 2
fs-admin-saas/src/main/resources/application-dev.yml

@@ -6,8 +6,8 @@ spring:
     # redis 配置
     redis:
         # 地址
-        #host: localhost
-        host: 172.27.0.7
+        host: localhost
+#        host: 172.27.0.7
         # 端口,默认为6379
         port: 6379
         # 数据库索引

+ 7 - 0
fs-admin/src/main/java/com/fs/admin/controller/AiModelAdminController.java

@@ -39,6 +39,13 @@ public class AiModelAdminController extends BaseController {
         return AjaxResult.success(list);
     }
 
+    /** 公开访问的模型列表(无需权限验证) */
+    @GetMapping("/public/list")
+    public AjaxResult publicList() {
+        List<AdminAiModel> list = modelService.listAll();
+        return AjaxResult.success(list);
+    }
+
     /** 模型详情 */
     @PreAuthorize("@ss.hasPermi('admin:aiModel:list')")
     @GetMapping("/{id}")

+ 4 - 2
fs-company/src/main/java/com/fs/company/controller/qw/QwGroupChatController.java

@@ -128,7 +128,8 @@ public class QwGroupChatController extends BaseController
         String url = OpenQwConfig.api + "/qw/groupChat/cogradientGroupChat/" + corpId + "?tenantId=" + tenantId;
         try {
             HttpResponse response = HttpRequest.get(url)
-                    .timeout(apiTimeout * 1000)
+                    .timeout(1200 * 1000)
+                    .setReadTimeout(1200 * 1000)
                     .execute();
             if (response.getStatus() == 200) {
                 return JSON.parseObject(response.body(), R.class);
@@ -157,7 +158,8 @@ public class QwGroupChatController extends BaseController
                 + "&companyUserId=" + loginUser.getUser().getUserId();
         try {
             HttpResponse response = HttpRequest.get(url)
-                    .timeout(apiTimeout * 1000)
+                    .timeout(1200 * 1000)
+                    .setReadTimeout(1200 * 1000)
                     .execute();
             if (response.getStatus() == 200) {
                 return JSON.parseObject(response.body(), R.class);

+ 4 - 3
fs-company/src/main/resources/application-dev.yml

@@ -1,10 +1,11 @@
 # 数据源配置
 spring:
-    # redis 配置
+#    devtools:
+#        restart:
+#            enabled: false
     redis:
-        # 地址
         host: localhost
-        # 端口,默认为6379
+#        host: 172.27.0.7
         port: 6379
         # 数据库索引
         database: 0

+ 2 - 0
fs-framework/src/main/java/com/fs/framework/config/SecurityConfig.java

@@ -102,6 +102,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 .antMatchers("/proxy/login").anonymous()
                 .antMatchers("/app/common/test").anonymous()
                 .antMatchers("/ad/adDyApi/authorized").anonymous()
+                .antMatchers("/admin/aiModel/public/**").anonymous()
                 .antMatchers(
                         HttpMethod.GET,
                         "/",
@@ -149,6 +150,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 .antMatchers("/course/userVideo/videoTranscode").anonymous()
                 .antMatchers("/system/config/getConfigByKey/his.adminUi.config").permitAll()
                 .antMatchers("/erp/call/**").anonymous()
+                .antMatchers("/app/common/**").anonymous()
                 // 除上面外的所有请求全部需要鉴权认证
                 .anyRequest().authenticated()
                 .and()

+ 0 - 180
fs-ipad-task/src/main/java/com/fs/framework/aspectj/TenantDataSourceAspect.java

@@ -1,180 +0,0 @@
-package com.fs.framework.aspectj;
-
-import com.alibaba.druid.pool.DruidDataSource;
-import com.fs.common.annotation.TenantDataScope;
-import com.fs.common.core.redis.RedisCacheT;
-import com.fs.common.enums.TenantIdType;
-import com.fs.common.exception.CustomException;
-import com.fs.common.utils.StringUtils;
-import com.fs.framework.datasource.DynamicDataSource;
-import com.fs.framework.datasource.DynamicDataSourceContextHolder;
-import com.fs.huifuPay.sdk.opps.core.exception.BasePayException;
-import com.fs.tenant.domain.TenantInfo;
-import com.fs.tenant.mapper.TenantInfoMapper;
-import lombok.extern.slf4j.Slf4j;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
-import org.aspectj.lang.reflect.MethodSignature;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.core.annotation.AnnotationUtils;
-import org.springframework.core.annotation.Order;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.Resource;
-import javax.sql.DataSource;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * 多数据源处理
- *
- */
-@Slf4j
-@Aspect
-@Order(1)
-@Component
-public class TenantDataSourceAspect {
-    private static final String TENANT_KEY = "tenant:info:";
-    @Resource
-    private DynamicDataSource dynamicDataSource;
-    @Value("${tenant-id}")
-    private Long ymlTenantId;
-    @Autowired
-    private TenantInfoMapper tenantInfoMapper;
-    @Autowired
-    private RedisCacheT<TenantInfo> redis;
-    /**
-     * 租户数据源缓存
-     */
-    private static final Map<String, DataSource> TENANT_DS_CACHE = new ConcurrentHashMap<>();
-
-    @Pointcut("@annotation(com.fs.common.annotation.TenantDataScope)"
-            + "|| @within(com.fs.common.annotation.TenantDataScope)")
-    public void dsPointCut() {
-
-    }
-
-    @Around("dsPointCut()")
-    public Object around(ProceedingJoinPoint point) throws Throwable {
-        MethodSignature signature = (MethodSignature) point.getSignature();
-        Method targetMethod = signature.getMethod(); // 拿到目标方法对象
-        log.info("执行方法:{}", targetMethod.getName());
-        TenantDataScope dataSource = getDataSource(point);
-        TenantIdType type = dataSource.type();
-        Long tenantId = 0L;
-        if(type.equals(TenantIdType.YML)){
-            tenantId = ymlTenantId;
-        }
-        if(type.equals(TenantIdType.REQUEST)){
-
-        }
-        switchTenant(tenantId);
-        try {
-            return point.proceed();
-        } finally {
-            // 销毁数据源 在执行方法之后
-            DynamicDataSourceContextHolder.clearDataSourceType();
-        }
-    }
-
-    public void switchTenant(Long id) {
-        TenantInfo tenantInfo = redis.getCacheObject(TENANT_KEY + id);
-        if(tenantInfo == null){
-            tenantInfo = tenantInfoMapper.selectById(id);
-            if(tenantInfo == null){
-                throw new CustomException("租户不存在请检查");
-            }
-            redis.setCacheObject(TENANT_KEY + id, tenantInfo);
-        }
-        // 用租户主键作为唯一标识
-        String tenantKey = buildTenantKey(tenantInfo.getId());
-
-        if (!TENANT_DS_CACHE.containsKey(tenantKey)) {
-            synchronized (this) {
-                if (!TENANT_DS_CACHE.containsKey(tenantKey)) {
-
-                    javax.sql.DataSource tenantDs = createTenantDataSource(tenantInfo);
-                    TENANT_DS_CACHE.put(tenantKey, tenantDs);
-
-                    // 动态追加到已解析的数据源
-                    Map<Object, DataSource> resolvedMap = getResolvedDataSources();
-                    resolvedMap.put(tenantKey, tenantDs);
-                }
-            }
-        }
-
-        // ThreadLocal 切库
-        DynamicDataSourceContextHolder.setDataSourceType(tenantKey);
-    }
-
-    private String buildTenantKey(Long tenantId) {
-        return "tenant:" + tenantId;
-    }
-
-
-
-    /**
-     * 清理 ThreadLocal
-     */
-    public void clear() {
-        DynamicDataSourceContextHolder.clearDataSourceType();
-    }
-
-    /**
-     * 创建租户数据源(MySQL + Druid)
-     */
-    private DataSource createTenantDataSource(TenantInfo tenant) {
-
-        DruidDataSource ds = new DruidDataSource();
-        ds.setUrl(tenant.getDbUrl());
-        ds.setUsername(tenant.getDbAccount());
-        ds.setPassword(tenant.getDbPwd());
-
-        // 统一 MySQL
-        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
-
-        ds.setInitialSize(5);
-        ds.setMinIdle(10);
-        ds.setMaxActive(20);
-        ds.setMaxWait(60000);
-
-        return ds;
-    }
-
-    /**
-     * 反射获取 AbstractRoutingDataSource.resolvedDataSources
-     */
-    @SuppressWarnings("unchecked")
-    private Map<Object, DataSource> getResolvedDataSources() {
-        try {
-            Field field = org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
-                    .class.getDeclaredField("resolvedDataSources");
-            field.setAccessible(true);
-            return (Map<Object, DataSource>) field.get(dynamicDataSource);
-        } catch (Exception e) {
-            throw new IllegalStateException("获取 resolvedDataSources 失败", e);
-        }
-    }
-
-    /**
-     * 获取需要切换的数据源
-     */
-    public TenantDataScope getDataSource(ProceedingJoinPoint point) {
-        MethodSignature signature = (MethodSignature) point.getSignature();
-        TenantDataScope dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), TenantDataScope.class);
-        if (Objects.nonNull(dataSource)) {
-            return dataSource;
-        }
-
-        return AnnotationUtils.findAnnotation(signature.getDeclaringType(), TenantDataScope.class);
-    }
-}

+ 2 - 2
fs-ipad-task/src/main/resources/application.yml

@@ -4,6 +4,6 @@ server:
 # Spring配置
 spring:
   profiles:
-    active: dev-test
+    active: dev,common
 group-no: 1
-tenant-id: 29
+tenant-id: 33

+ 1 - 1
fs-qw-api-msg/src/main/resources/application.yml

@@ -3,7 +3,7 @@ server:
 # Spring配置
 spring:
   profiles:
-    active: dev
+    active: dev,common
 #    active: druid-jzzx
 #    active: druid-hdt
 #    active: druid-sxjz

+ 27 - 6
fs-qw-api/src/main/java/com/fs/app/controller/OpenQwApiController.java

@@ -10,6 +10,7 @@ import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.param.QwExternalContactAddTagParam;
 import com.fs.qw.param.QwExternalContactUpdateNoteParam;
 import com.fs.qwApi.param.QwUploadImageByCourseParam;
+import com.fs.qwApi.service.QwApiService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
@@ -27,6 +28,9 @@ public class OpenQwApiController extends BaseController {
 
     @Autowired
     private TenantDataSourceUtil tenantDataSourceUtil;
+
+    @Autowired
+    private QwApiService qwApiService;
     /**
      * 同步企微员工
      * @param tenantId
@@ -116,9 +120,7 @@ public class OpenQwApiController extends BaseController {
         try {
             log.info("[QwFriendWelcome] 添加标签,tenantId={}", tenantId);
             // 切换到指定租户数据源执行操作(TenantDataSourceUtil 会自动设置 Redis 租户上下文)
-            return tenantDataSourceUtil.executeWithResult(tenantId, () -> {
-                return openQwApiService.addTag(param);
-            });
+            return tenantDataSourceUtil.executeWithResult(tenantId, () -> openQwApiService.addTag(param, tenantId));
         } catch (IllegalArgumentException e) {
             log.error("[QwFriendWelcome] 添加标签失败,租户不存在或已禁用,tenantId={}", tenantId, e);
             return R.error("租户不存在或已禁用");
@@ -137,9 +139,7 @@ public class OpenQwApiController extends BaseController {
         try {
             log.info("[QwFriendWelcome] 移除标签,tenantId={}", tenantId);
             // 切换到指定租户数据源执行操作(TenantDataSourceUtil 会自动设置 Redis 租户上下文)
-            return tenantDataSourceUtil.executeWithResult(tenantId, () -> {
-                return openQwApiService.delTag(param);
-            });
+            return tenantDataSourceUtil.executeWithResult(tenantId, () -> openQwApiService.delTag(param, tenantId));
         } catch (IllegalArgumentException e) {
             log.error("[QwFriendWelcome] 移除标签失败,租户不存在或已禁用,tenantId={}", tenantId, e);
             return R.error("租户不存在或已禁用");
@@ -169,6 +169,27 @@ public class OpenQwApiController extends BaseController {
         }
     }
 
+
+    /**
+     * 加密qwUser的userId
+     */
+    @PostMapping("/getOpenUserid")
+    public R getOpenUserid(@RequestParam("userId") String  userId,
+                                   @RequestParam("corpId") String  corpId,
+                                   @RequestParam("permanentCode") String  permanentCode,
+                                   @RequestParam(value = "tenantId", required = true) Long tenantId){
+        try {
+            return R.ok().put("userId",tenantDataSourceUtil.executeWithResult(tenantId,
+                    () ->  qwApiService.getOpenUserid(qwApiService.getToken(corpId,permanentCode),userId,corpId)));
+        } catch (IllegalArgumentException e) {
+            log.error("加密ExternalUserid,租户不存在或已禁用,tenantId={}", tenantId, e);
+            return R.error("租户不存在或已禁用");
+        } catch (Exception e) {
+            log.error("加密ExternalUserid,tenantId={}", tenantId, e);
+            return R.error("加密ExternalUserid失败: " + e.getMessage());
+        }
+    }
+
     /**
      * 上传图片
      */

+ 2 - 2
fs-qw-api/src/main/java/com/fs/app/service/OpenQwApiService.java

@@ -17,9 +17,9 @@ public interface OpenQwApiService {
 
     int edit(QwExternalContact qwExternalContact);
 
-    R addTag(QwExternalContactAddTagParam param);
+    R addTag(QwExternalContactAddTagParam param, Long tenantId);
 
-    R delTag(QwExternalContactAddTagParam param);
+    R delTag(QwExternalContactAddTagParam param, Long tenantId);
 
     R getOpenExternalUserid(String externalUserid,String corpId,String qwUserId);
 

+ 9 - 6
fs-qw-api/src/main/java/com/fs/app/service/impl/OpenQwApiServiceImpl.java

@@ -274,6 +274,7 @@ public class OpenQwApiServiceImpl implements OpenQwApiService {
         qwUser.setIsDel(0);
         qwUser.setOpenid(openid);
         qwUser.setQwOpenUserId(apiUser.getUserid());
+        qwUser.setQwUserId(apiUser.getUserid());
 
         // 设置部门(取第一个部门)
         List<Integer> depts = apiUser.getDepartment();
@@ -540,7 +541,7 @@ public class OpenQwApiServiceImpl implements OpenQwApiService {
     }
 
     @Override
-    public R addTag(QwExternalContactAddTagParam param) {
+    public R addTag(QwExternalContactAddTagParam param, Long tenantId) {
         // 获取当前日期和时间
         LocalDate currentDate = LocalDate.now();
         LocalTime localTime = LocalTime.now();
@@ -605,9 +606,11 @@ public class OpenQwApiServiceImpl implements OpenQwApiService {
                             qwExternal.setTagIds(JSON.toJSONString(uniqueIds));
                             qwExternal.setId(qwExternalContact.getId());
 
-                            List<String> tagIdsList = new ArrayList<>();
+                            List<String> tagIdsList;
                             if (qwExternal.getTagIds() != null && !qwExternal.getTagIds().isEmpty()) {
                                 tagIdsList = JSON.parseArray(qwExternal.getTagIds(), String.class);
+                            } else {
+                                tagIdsList = new ArrayList<>();
                             }
 
                             log.info("客户添加标签addUserTag:" + qwExternalContact.getName() +
@@ -616,8 +619,8 @@ public class OpenQwApiServiceImpl implements OpenQwApiService {
                                     "|总标签" + tagIdsList);
 
                             // 插件sop处理
-                            processTagsAll(qwExternalContact, qwExternalContact.getCorpId(),
-                                    tagIdsList, currentDate, localTime);
+                            tenantDataSourceUtil.execute(tenantId, () -> processTagsAll(qwExternalContact, qwExternalContact.getCorpId(),
+                                    tagIdsList, currentDate, localTime));
 
                             // 添加到批量更新列表
                             batchUpdateList.add(qwExternal);
@@ -685,7 +688,7 @@ public class OpenQwApiServiceImpl implements OpenQwApiService {
     }
 
     @Override
-    public R delTag(QwExternalContactAddTagParam param) {
+    public R delTag(QwExternalContactAddTagParam param, Long tenantId) {
         // 获取当前日期和时间
         LocalDate currentDate = LocalDate.now();
         LocalTime localTime = LocalTime.now();
@@ -746,7 +749,7 @@ public class OpenQwApiServiceImpl implements OpenQwApiService {
                                 log.info("客户移除标签delUserTag:"+qwExternalContact.getName()+"|公司"+qwExternalContact.getCorpId()+"|员工"+qwExternalContact.getUserId()+"|总标签"+ids);
 
                                 //检查sop
-                                processTagsAll(qwExternalContact,param.getCorpId(),ids,currentDate,localTime);
+                                tenantDataSourceUtil.execute(tenantId, () -> processTagsAll(qwExternalContact,param.getCorpId(),ids,currentDate,localTime));
 
                                 // 添加到批量更新列表
                                 batchUpdateList.add(qwExternal);

+ 4 - 0
fs-service/src/main/java/com/fs/qw/domain/QwUser.java

@@ -1,7 +1,9 @@
 package com.fs.qw.domain;
 
 
+import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
 import com.fs.common.annotation.Excel;
 import com.fs.common.core.domain.BaseEntity;
 import lombok.Data;
@@ -18,6 +20,8 @@ public class QwUser extends BaseEntity
     private static final long serialVersionUID = 1L;
 
     /** id */
+    /** id(数据库自增;勿依赖应用侧雪花填充) */
+    @TableId(type = IdType.AUTO)
     private Long id;
 
     /** 企微用户id */

+ 2 - 2
fs-service/src/main/java/com/fs/qw/mapper/QwGroupChatMapper.java

@@ -117,8 +117,8 @@ public interface QwGroupChatMapper
     @Select("select chat_id,name from qw_group_chat where  corp_id=#{corpId}")
     List<QwGroupChatOptionsVO> selectGroupChatOptionsVOList(String corpId);
 
-    @Select("select chat_id,name from qw_group_chat where corp_id = #{corpId} and find_in_set(owner,#{qwUserIds})")
-    List<QwGroupChatOptionsVO> listAllByQwUserList(@Param("qwUserIds") String qwUserIds, @Param("corpId") String corpId);
+    @Select("select chat_id,name from qw_group_chat where corp_id = #{corpId} and find_in_set(owner,#{qwOpenUserIds})")
+    List<QwGroupChatOptionsVO> listAllByQwUserList(@Param("qwOpenUserIds") String qwOpenUserIds, @Param("corpId") String corpId);
 
     List<QwGroupChat> selectQwGroupChatByChatIds(@Param("ids") String[] ids);
 

+ 5 - 2
fs-service/src/main/java/com/fs/qw/mapper/QwUserMapper.java

@@ -50,7 +50,7 @@ public interface QwUserMapper extends BaseMapper<QwUser>
     @Select("select company_user_id,company_id,welcome_text,qw_user_name,send_msg_type from qw_user where id = #{id}")
     public QwUser selectQwUserByIdByWeComeText(@Param("id") Long id);
 
-    @Select("select * from qw_user where qw_user_id = #{qwUserId} and corp_id = #{corpId} ")
+    @Select("select * from qw_user where qw_open_user_id = #{qwUserId} and corp_id = #{corpId} ")
     public QwUser selectQwUserByIdByWeComeText2(@Param("qwUserId") String qwUserId, @Param("corpId") String corpId);
     /**
      * 根据companyUserId查询企微用户
@@ -508,7 +508,7 @@ public interface QwUserMapper extends BaseMapper<QwUser>
     @Select("select * from qw_user where qw_user_id=#{qwUserId} and corp_id =#{corpId} limit 1")
     QwUser selectQwUserEntityByQwUserIdAndCorId(@Param("qwUserId")String qwUserId,@Param("corpId") String corpId);
 
-    @Select("select * from qw_user where ipad_status = 1 and corp_id=#{corpId} and qw_user_id=#{qwUserId} limit 1 ")
+    @Select("select * from qw_user where ipad_status = 1 and corp_id=#{corpId} and qw_open_user_id=#{qwUserId} limit 1 ")
     QwUser selectQwUserAppKeyAndIdByCorpIdAndUserIdAndIpad(@Param("corpId")String corpId,@Param("qwUserId") String qwUserId);
 
     // 批量查询
@@ -521,4 +521,7 @@ public interface QwUserMapper extends BaseMapper<QwUser>
     // 批量更新
     int batchUpdateQwUser(@Param("list") List<QwUser> users);
 
+    @Select("select group_concat(qw_open_user_id) from qw_user where corp_id = #{corpId} and find_in_set(qw_user_id, #{qwUserIds})")
+    String selectQwOpenUserIdByQwUserIdAndCorpId(@Param("qwUserIds") String qwUserIds, @Param("corpId") String corpId);
+
 }

+ 1 - 1
fs-service/src/main/java/com/fs/qw/service/IQwUserService.java

@@ -97,7 +97,7 @@ public interface IQwUserService
     */
     List<QwUserVO> selectQwUserListBindVO(QwUserParam qwUser);
 
-    R syncQwUser(String corpId);
+    R syncQwUser(String corpId,Long tenantId);
 
     R unlockQwUserLoginCodeUrlTask();
 

+ 1 - 1
fs-service/src/main/java/com/fs/qw/service/IQwUserServiceAsyncHelper.java

@@ -17,7 +17,7 @@ public interface IQwUserServiceAsyncHelper {
      * @param corpId
      * @param company
      */
-    void syncQwUserAsync(String corpId, Company company);
+//    void syncQwUserAsync(String corpId, Company company);
 
     /**
      * 同步企微用户名称

+ 5 - 1
fs-service/src/main/java/com/fs/qw/service/impl/QwGroupChatServiceImpl.java

@@ -413,7 +413,11 @@ public class QwGroupChatServiceImpl implements IQwGroupChatService
 
     @Override
     public List<QwGroupChatOptionsVO> listAllByQwUserList(String qwUserIds, String corpId, String sopId) {
-        List<QwGroupChatOptionsVO> list = qwGroupChatMapper.listAllByQwUserList(qwUserIds, corpId);
+
+        // qwUserIds 转换为  qwOpenUserIds
+        String qwOpenUserIds = qwUserMapper.selectQwOpenUserIdByQwUserIdAndCorpId(qwUserIds, corpId);
+
+        List<QwGroupChatOptionsVO> list = qwGroupChatMapper.listAllByQwUserList(qwOpenUserIds, corpId);
         if(StringUtils.isNotEmpty(sopId)){
             QwSop qwSop = sopMapper.selectQwSopById(sopId);
             List<String> chatIds;

+ 27 - 27
fs-service/src/main/java/com/fs/qw/service/impl/QwUserServiceAsyncHelperImpl.java

@@ -104,33 +104,33 @@ public class QwUserServiceAsyncHelperImpl implements IQwUserServiceAsyncHelper {
 
     org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
 
-    /**
-     * 同步企微用户
-     *
-     * @param corpId
-     * @param company
-     */
-    @Async
-    @Override
-    public void syncQwUserAsync(String corpId, Company company) {
-        try {
-            log.info("同步企微用户Async");
-            List<String> strings = qwCompanyMapper.selectQwCompanyCorpIdListByCompanyId(company.getCompanyId());
-            log.info("strings:{}", strings);
-            log.info("corpId:{}", corpId);
-            for (String string : strings) {
-                if (string.equals(corpId)) {
-                    log.info("瞒住条件");
-                    qwUserService.syncQwUser(string);
-                    qwDeptService.insertOrUpdateQwDept(string);
-                }
-            }
-            log.info("同步完成");
-        } catch (Exception e) {
-            log.error("异步任务执行异常", e);
-            log.info("同步企微员工和部门,同步失败");
-        }
-    }
+//    /**
+//     * 同步企微用户
+//     *
+//     * @param corpId
+//     * @param company
+//     */
+//    @Async
+//    @Override
+//    public void syncQwUserAsync(String corpId, Company company) {
+//        try {
+//            log.info("同步企微用户Async");
+//            List<String> strings = qwCompanyMapper.selectQwCompanyCorpIdListByCompanyId(company.getCompanyId());
+//            log.info("strings:{}", strings);
+//            log.info("corpId:{}", corpId);
+//            for (String string : strings) {
+//                if (string.equals(corpId)) {
+//                    log.info("瞒住条件");
+//                    qwUserService.syncQwUser(string);
+//                    qwDeptService.insertOrUpdateQwDept(string);
+//                }
+//            }
+//            log.info("同步完成");
+//        } catch (Exception e) {
+//            log.error("异步任务执行异常", e);
+//            log.info("同步企微员工和部门,同步失败");
+//        }
+//    }
 
     /**
      * 同步企微用户名称

+ 60 - 18
fs-service/src/main/java/com/fs/qw/service/impl/QwUserServiceImpl.java

@@ -3,6 +3,7 @@ package com.fs.qw.service.impl;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpUtil;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -44,6 +45,7 @@ import com.fs.qw.utils.RSAUtils;
 import com.fs.qw.vo.*;
 import com.fs.qwApi.Result.QwOpenidResult;
 import com.fs.qwApi.Result.QwUploadImgResult;
+import com.fs.qwApi.config.OpenQwConfig;
 import com.fs.qwApi.domain.QwUserIdResult;
 import com.fs.qwApi.domain.inner.DeptUser;
 import com.fs.qwApi.param.QwOpenidByUserParams;
@@ -65,6 +67,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.io.*;
+import java.net.SocketTimeoutException;
 import java.net.URL;
 import java.security.KeyFactory;
 import java.security.PrivateKey;
@@ -935,30 +938,69 @@ public class QwUserServiceImpl implements IQwUserService
     }
 
     @Override
-    public R syncQwUser(String corpId) {
+    public R syncQwUser(String corpId,Long tenantId) {
         QwUserIdResult userList = qwApiService.getUserList(corpId);
         List<DeptUser> deptUser = userList.getDept_user();
         log.info("返回数据:{}", JSON.toJSONString(userList));
         log.info("同步用户数量:{}", deptUser.size());
         QwCompany qwCompany = iQwCompanyService.selectQwCompanyByCorpId(corpId);
         for (DeptUser user : deptUser) {
-            QwUser qw=qwUserMapper.selectQwUserByCorpIdAndUserId(corpId,qwApiService.getOpenUserid(qwApiService.getToken(corpId,qwCompany.getPermanentCode()),user.getUserid(),corpId));
+            String userid = user.getUserid();
+            String openUserIdRedisKey = "corpId:" + userid;
+            String  redisResult= redisCache.getCacheObject(openUserIdRedisKey);
+            String openUserId = "";
+            if (StringUtils.isNotBlank(redisResult)){
+                openUserId = redisResult;
+            } else {
+                if (userid != null && tenantId != null && qwCompany.getPermanentCode() != null) {
+                    // 远程调用 fs-qw-api 同步企微用户
+                    String url = OpenQwConfig.baseApi + "/getOpenUserid?userId=" + userid + "&corpId=" + corpId + "&permanentCode=" + qwCompany.getPermanentCode() + "&tenantId=" + tenantId;
+                    try {
+                        String result = HttpUtil.createPost(url)
+                                .execute()
+                                .body();
+                        if (StringUtils.isNotBlank(result)) {
+                            R r = JSON.parseObject(result, R.class);
+                            if (!"200".equals(r.get("code").toString())) {
+                                log.error("企微用户获取加密userId,HTTP状态码: {}", r.get("code").toString());
+                                return R.error("企微用户获取加密userId,服务返回状态码: " + r.get("code").toString());
+                            } else {
+                                openUserId = r.get("userId").toString();
+                            }
+                        }
+
+                    } catch (Exception e) {
+                        log.error("企微用户获取加密userId异常, url={}", url, e);
+                        if (e.getCause() instanceof SocketTimeoutException) {
+                            return R.error("企微用户获取加密userId超时,请稍后重试");
+                        }
+                        return R.error("企微用户获取加密userId失败: " + e.getMessage());
+                    }
+                }
+            }
+
+            if (StringUtils.isNotBlank(openUserId)) {
+                QwUser qw=qwUserMapper.selectQwUserByCorpIdAndUserId(corpId, openUserId);
 //            String serverQwUserName = qwApiService.getServerQwUserName(corpId, qwCompany.getOpenSecret(), user.getUserid(),qwCompany.getPermanentCode());
 //            log.info("同步用户名称:{}", serverQwUserName);
-            QwUser qwUser = new QwUser();
-            qwUser.setQwUserId(user.getUserid());
-            qwUser.setDepartment(user.getDepartment().toString());
+                QwUser qwUser = new QwUser();
+                qwUser.setQwUserId(userid);
+                qwUser.setDepartment(user.getDepartment().toString());
 //            qwUser.setQwUserName(serverQwUserName);
-            qwUser.setCorpId(corpId);
-            QwOpenidByUserParams param=new QwOpenidByUserParams();
-            param.setUserid(user.getUserid());
-            QwOpenidResult qwOpenidResult = qwApiService.useridToOpenid(param, corpId);
-            qwUser.setOpenid(qwOpenidResult.getOpenid());
-             if (qw!=null){
-                 qwUser.setId(qw.getId());
-                 qwUser.setIsDel(0);
-                 qwUserMapper.updateQwUser(qwUser);
-             }
+                qwUser.setCorpId(corpId);
+//            QwOpenidByUserParams param=new QwOpenidByUserParams();
+//            param.setUserid(user.getUserid());
+//            QwOpenidResult qwOpenidResult = qwApiService.useridToOpenid(param, corpId);
+//            qwUser.setOpenid(qwOpenidResult.getOpenid());
+                if (qw!=null){
+                    qwUser.setId(qw.getId());
+                    qwUser.setIsDel(0);
+                    qwUserMapper.updateQwUser(qwUser);
+                }
+            } else {
+                log.error("企微用户获取加密userId为空, userid={}", userid);
+            }
+
         }
         return R.ok();
     }
@@ -1316,9 +1358,9 @@ public class QwUserServiceImpl implements IQwUserService
         }
         WxWorkSetCallbackUrlDTO wxWorkSetCallbackUrlDTO = new WxWorkSetCallbackUrlDTO();
 
-        System.out.println("回调地址"+"http://saasqwapimsg.ylrzcloud.com/msg/callback/"+serverId + "/"+loginParam.getTenantId());
-        wxWorkSetCallbackUrlDTO.setUrl("http://saasqwapimsg.ylrzcloud.com/msg/callback/"+serverId+ "/"+loginParam.getTenantId());
-        //wxWorkSetCallbackUrlDTO.setUrl("http://cn-hk-bgp-4.ofalias.net:55081/msg/callback/"+serverId+ "/"+loginParam.getTenantId());
+        System.out.println("回调地址"+"http://newsaasqwapimsg.ylrzcloud.com/msg/callback/"+serverId + "/"+loginParam.getTenantId());
+        wxWorkSetCallbackUrlDTO.setUrl("http://newsaasqwapimsg.ylrzcloud.com/msg/callback/"+serverId+ "/"+loginParam.getTenantId());
+//        wxWorkSetCallbackUrlDTO.setUrl("http://t66e9dea.natappfree.cc/msg/callback/"+serverId+ "/"+loginParam.getTenantId());
         wxWorkSetCallbackUrlDTO.setUuid(data.getUuid());
         wxWorkService.SetCallbackUrl(wxWorkSetCallbackUrlDTO,serverId);
 

+ 2 - 1
fs-service/src/main/java/com/fs/qwApi/config/OpenQwConfig.java

@@ -6,5 +6,6 @@ public interface OpenQwConfig {
     String api ="http://newsaasqwapi.ylrzcloud.com";
 //    String api ="http://127.0.0.1:8007";
 //    String taskApi ="192.168.0.64:7006";
-    String taskApi ="127.0.0.1:7006";
+    String taskApi ="http://172.27.0.7:7006";
+//    String taskApi ="http://129.28.41.190:7006";
 }

+ 0 - 1
fs-service/src/main/java/com/fs/system/mapper/SysDictDataMapper.java

@@ -30,7 +30,6 @@ public interface SysDictDataMapper
      * @param dictType 字典类型
      * @return 字典数据集合信息
      */
-    @DataSource(DataSourceType.MASTER)
     public List<SysDictData> selectDictDataByType(String dictType);
 
     /**

+ 3 - 0
fs-service/src/main/resources/application-common.yml

@@ -159,4 +159,7 @@ comm:
     internal-secret: CommGatewayInternal2026!@#
     enabled: true
     fallback-local: true
+baidu:
+  token: 12313231232
+  back-domain: https://www.xxxx.com
 

+ 2 - 2
fs-service/src/main/resources/application-dev.yml

@@ -3,8 +3,8 @@ spring:
     # redis 配置
     redis:
         # 地址
-        #host: localhost
-        host: 172.27.0.7
+        host: localhost
+#        host: 172.27.0.7
         # 端口,默认为6379
         port: 6379
         # 数据库索引

File diff suppressed because it is too large
+ 112 - 112
fs-service/src/main/resources/db/tenant-initTable.sql


+ 1 - 1
fs-task/src/main/java/com/fs/task/controller/TaskManualController.java

@@ -191,7 +191,7 @@ public class TaskManualController {
             log.info("开始同步企微用户,租户={}, corpId={}", tenantInfo.getId(), qwCompany.getCorpId());
 
             // 执行同步操作
-            qwUserService.syncQwUser(qwCompany.getCorpId());
+            qwUserService.syncQwUser(qwCompany.getCorpId(),tenantInfo.getId());
 
             log.info("同步完成,租户={}", tenantInfo.getId());
 

+ 1 - 1
fs-task/src/main/java/com/fs/task/jobs/QwUserAsyncTask.java

@@ -62,7 +62,7 @@ public class QwUserAsyncTask {
                 log.info("开始同步企微用户,租户={}, corpId={}", tenantInfo.getId(), qwCompany.getCorpId());
 
                 // 执行同步操作
-                qwUserService.syncQwUser(qwCompany.getCorpId());
+                qwUserService.syncQwUser(qwCompany.getCorpId(),tenantInfo.getId());
 //                qwDeptService.insertOrUpdateQwDept(qwCompany.getCorpId());
 
                 log.info("同步完成,租户={}", tenantInfo.getId());

+ 1 - 1
fs-task/src/main/resources/application-dev.yml

@@ -2,7 +2,7 @@
 spring:
     # redis 配置
     redis:
-        #host: localhost
+#        host: localhost
         host: 172.27.0.7
         port: 6379
         database: 0

Some files were not shown because too many files changed in this diff