Parcourir la source

总后台干销售管理

三七 il y a 1 mois
Parent
commit
a2fbdac91f

+ 48 - 0
fs-admin/src/main/java/com/fs/company/controller/CompanyConfigController.java

@@ -0,0 +1,48 @@
+package com.fs.company.controller;
+
+
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.company.service.ICompanyConfigService;
+import com.fs.system.domain.SysConfig;
+import com.fs.system.service.ISysConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 系统配置
+ *
+
+ */
+@RestController
+@RequestMapping("/company/companyConfig")
+public class CompanyConfigController extends BaseController
+{
+
+    @Autowired
+    private ICompanyConfigService companyConfigService;
+
+
+    @Autowired
+    private ISysConfigService configService;
+
+
+
+    /**
+     * 根据参数键名查询总后台参数值
+     * @param configKey
+     * @return
+     */
+    @GetMapping(value = "/getConfigByKey/{configKey}")
+    public AjaxResult getConfigByKey(@PathVariable String configKey)
+    {
+        SysConfig config=configService.selectConfigByConfigKey(configKey);
+        return AjaxResult.success(config);
+    }
+
+
+
+}

+ 572 - 0
fs-admin/src/main/java/com/fs/company/controller/CompanyUserAllController.java

@@ -0,0 +1,572 @@
+package com.fs.company.controller;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.json.JSONUtil;
+import com.baidu.dev2.thirdparty.jackson.databind.ObjectMapper;
+import com.fs.common.annotation.Log;
+import com.fs.common.constant.UserConstants;
+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.domain.model.LoginUser;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.core.redis.RedisCache;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.PatternUtils;
+import com.fs.common.utils.SecurityUtils;
+import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.company.domain.*;
+import com.fs.company.param.CompanyUserAreaParam;
+import com.fs.company.param.CompanyUserCodeParam;
+import com.fs.company.param.CompanyUserQwParam;
+import com.fs.company.service.*;
+import com.fs.company.vo.BatchUserRolesVO;
+import com.fs.company.vo.CompanyUserImportVO;
+import com.fs.company.vo.CompanyUserQwListVO;
+import com.fs.company.vo.CompanyUserVO;
+import com.fs.course.config.CourseConfig;
+import com.fs.framework.web.service.TokenService;
+import com.fs.his.utils.qrcode.QRCodeUtils;
+import com.fs.his.vo.OptionsVO;
+import com.fs.hisStore.vo.FsStoreProductExportVO;
+import com.fs.im.config.IMConfig;
+import com.fs.im.dto.OpenImResponseDTO;
+import com.fs.im.service.OpenIMService;
+import com.fs.qw.domain.QwCompany;
+import com.fs.qw.service.IQwCompanyService;
+import com.fs.qw.service.IQwUserService;
+import com.fs.qw.vo.CompanyUserQwVO;
+import com.fs.qw.vo.QwUserVO;
+import com.fs.system.service.ISysConfigService;
+import com.fs.utils.DomainUtil;
+import com.fs.utils.QwStatusEnum;
+import com.fs.voice.utils.StringUtil;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import io.swagger.annotations.ApiOperation;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.util.Assert;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+
+/**
+ * 用户信息
+ */
+@RestController
+@RequestMapping("/company/CompanyUserAll")
+public class CompanyUserAllController extends BaseController {
+
+    @Autowired
+    private ICompanyRoleService roleService;
+
+    @Autowired
+    private ICompanyPostService postService;
+
+    @Autowired
+    private ICompanyUserService companyUserService;
+
+    @Autowired
+    private ICompanyService companyService;
+
+    @Autowired
+    private ICompanyUserDelayTimeService companyUserDelayTimeService;
+
+    @Autowired
+    private ISysConfigService configService;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    @Autowired
+    private OpenIMService openIMService;
+
+    @Autowired
+    IQwCompanyService iQwCompanyService;
+
+    @Autowired
+    private IQwUserService qwUserService;
+
+    @Autowired
+    private TokenService tokenService;
+
+    private static final String appLink = "https://jump.ylrztop.com/jumpapp/pages/index/index?link=";
+
+
+    @GetMapping("/getList")
+    public TableDataInfo getList(CompanyUser user)
+    {
+        startPage();
+        List<CompanyUser> list = companyUserService.selectCompanyUserList(user);
+        return getDataTable(list);
+    }
+    @GetMapping("/qwList")
+    public TableDataInfo qwList(CompanyUserQwParam user) {
+        List<CompanyUserQwListVO> list = companyUserService.selectCompanyUserQwListVO(user);
+        if (!list.isEmpty()){
+            String json = configService.selectConfigByKey("course.config");
+            CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+            Long sendDelayTime = config.getSendDelayTime();
+            List<CompletableFuture<Void>> futures = new ArrayList<>();
+            for (CompanyUserQwListVO companyUserQwListVO : list) {
+                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
+                    CompanyUserDelayTime companyUserDelayTime = companyUserDelayTimeService.selectCompanyUserDelayTimeByCompanyUser(companyUserQwListVO.getCompanyId(), companyUserQwListVO.getUserId());
+                    if (ObjectUtil.isEmpty(companyUserDelayTime)) {
+                        companyUserQwListVO.setSendDelayTime(sendDelayTime);
+                    } else {
+                        companyUserQwListVO.setSendDelayTime(companyUserDelayTime.getSendDelayTime());
+                    }
+                    //是否绑定
+                    if(QwStatusEnum.BOUND.getCode() == companyUserQwListVO.getQwStatus()){
+                        if(!companyUserQwListVO.getQwUserId().isEmpty()){
+                            Long[] ids = Arrays.stream(companyUserQwListVO.getQwUserId().split(","))
+                                    .map(Long::parseLong)
+                                    .toArray(Long[]::new);
+                            List<QwUserVO> qwUserVOS = qwUserService.selectQwUserVOByIds(ids);
+                            companyUserQwListVO.setQwUsers(qwUserVOS);
+                        }
+                    }
+                });
+                futures.add(future);
+            }
+            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
+        }
+        return getDataTable(list);
+    }
+
+    @Log(title = "用户管理导出", businessType = BusinessType.EXPORT)
+    @PreAuthorize("@ss.hasPermi('company:user:export')")
+    @GetMapping("/export")
+    public AjaxResult export(CompanyUser user)
+    {
+        List<CompanyUser> list = companyUserService.selectCompanyUserList(user);
+        ExcelUtil<CompanyUser> util = new ExcelUtil<CompanyUser>(CompanyUser.class);
+        return util.exportExcel(list, "用户数据");
+    }
+
+
+    @Log(title = "销售信息导入", businessType = BusinessType.IMPORT,isStoreLog = true,logParam = {"销售","信息导入"})
+    @PreAuthorize("@ss.hasPermi('company:user:import')")
+    @PostMapping("/importCompanyUser")
+    public AjaxResult importData(@RequestParam("file") MultipartFile file, boolean updateSupport) throws Exception
+    {
+        ExcelUtil<CompanyUserImportVO> util = new ExcelUtil<>(CompanyUserImportVO.class);
+        List<CompanyUserImportVO> list = util.importExcel(file.getInputStream());
+        String message = companyUserService.importCompanyUser(list, updateSupport);
+        return AjaxResult.success(message);
+    }
+
+
+    @GetMapping("/importTemplate")
+    public AjaxResult importTemplate()
+    {
+        ExcelUtil<CompanyUserImportVO> util = new ExcelUtil<>(CompanyUserImportVO.class);
+        return util.importTemplateExcel("销售数据");
+    }
+
+
+
+    /**
+     * 根据用户编号获取详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('company:user:query')")
+    @GetMapping(value = { "/", "/{userId}" })
+    public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId)
+    {
+        AjaxResult ajax = AjaxResult.success();
+        CompanyRole companyRoleMap=new CompanyRole();
+
+        CompanyUser userById = companyUserService.selectCompanyUserById(userId);
+        companyRoleMap.setCompanyId(userById.getCompanyId());
+        List<CompanyRole> roles = roleService.selectCompanyRoleList(companyRoleMap);
+
+        ajax.put("roles", CompanyUser.isAdmin(userById.getUserType()) ? roles : roles.stream().filter(r -> r.getRoleKey()!="admin").collect(Collectors.toList()));
+
+        CompanyPost postMap=new CompanyPost();
+        postMap.setCompanyId(userById.getCompanyId());
+        ajax.put("posts", postService.selectCompanyPostList(postMap));
+        if (StringUtils.isNotNull(userId))
+        {
+            CompanyUser companyUser=companyUserService.selectCompanyUserById(userId);
+            ajax.put(AjaxResult.DATA_TAG, companyUser);
+            ajax.put("postIds", postService.selectPostListByUserId(userId));
+            ajax.put("roleIds", roleService.selectRoleListByUserId(userId));
+
+
+        }
+        return ajax;
+    }
+
+    /**
+     * 根据用户编号获取详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('company:user:query')")
+    @GetMapping("/addInfo/{companyId}")
+    public AjaxResult addInfo(@PathVariable(value = "companyId", required = true) Long companyId)
+    {
+        AjaxResult ajax = AjaxResult.success();
+
+        CompanyRole companyRoleMap=new CompanyRole();
+        companyRoleMap.setCompanyId(companyId);
+        List<CompanyRole> roles = roleService.selectCompanyRoleList(companyRoleMap);
+
+        ajax.put("roles", CompanyUser.isAdmin("01") ? roles : roles.stream().filter(r -> r.getRoleKey()!="admin").collect(Collectors.toList()));
+
+        CompanyPost postMap=new CompanyPost();
+        postMap.setCompanyId(companyId);
+        ajax.put("posts", postService.selectCompanyPostList(postMap));
+
+        return ajax;
+    }
+
+    /**
+     * 新增用户
+     */
+    @PreAuthorize("@ss.hasPermi('company:user:add')")
+    @Log(title = "用户管理", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@Validated @RequestBody CompanyUser user)
+    {
+        if (!PatternUtils.checkPassword(user.getPassword())) {
+            return AjaxResult.error("密码格式不正确,需包含字母、数字和特殊字符,长度为 8-20 位");
+        }
+
+        //判断用户数量是否已达到上线
+
+        Integer count=companyUserService.selectCompanyUserCountByCompanyId(user.getCompanyId());
+        Company company=companyService.selectCompanyById(user.getCompanyId());
+
+        if(count>company.getLimitUserCount()){
+            return AjaxResult.error("用户数量已达到上限");
+        }
+        user.setCompanyId(user.getCompanyId());
+        if (UserConstants.NOT_UNIQUE.equals(String.valueOf(companyUserService.checkUserName(user.getUserName()))))
+        {
+            return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
+        }
+        if (!StringUtil.strIsNullOrEmpty(user.getDomain())){
+            user.setDomain(user.getDomain().replaceAll("^[\\s\\u2005]+", ""));
+        }
+
+        user.setCreateBy(SecurityUtils.getUsername());
+        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
+        user.setCreateTime(new Date());
+        user.setUserType("01");//一般用户
+        user.setIsAudit(1);
+        return toAjax(companyUserService.insertUser(user));
+    }
+
+    /**
+     * 生成创建销售的二维码
+     */
+
+    @PreAuthorize("@ss.hasPermi('company:user:addCodeUrl')")
+    @Log(title = "生成创建销售的二维码", businessType = BusinessType.INSERT)
+    @PostMapping("/addCodeUrl")
+    public R addCodeUrl( @RequestBody CompanyUserCodeParam user) throws Exception {
+
+        QwCompany qwCompany = iQwCompanyService.getQwCompanyByRedis(user.getCorpId());
+        if (qwCompany == null || qwCompany.getCorpId() == null){
+            return R.error("企业信息不存在");
+        }
+
+        //部门
+        Long deptId = user.getDeptId();
+
+        //角色组
+        Long[] roleIds = user.getRoleIds();
+
+        //区域
+        String addressId = user.getAddressId();
+
+
+        Map<String, Object> stateMap = new HashMap<>();
+        stateMap.put("companyId", user.getCompanyId());
+        stateMap.put("deptId", deptId);
+        stateMap.put("roleIds", roleIds); // 数组可以直接存放
+        stateMap.put("addressId", addressId);
+
+        // 使用JSON库将Map转换为字符串
+        ObjectMapper objectMapper = new ObjectMapper();
+        String status = objectMapper.writeValueAsString(stateMap);
+
+        // 如果要将status作为URL参数传递,记得进行URL编码!
+        String encodedStatus = URLEncoder.encode(status, StandardCharsets.UTF_8.toString());
+
+        String url="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+user.getCorpId()+"&redirect_uri=" +
+                "http://"+qwCompany.getRealmNameUrl()+"/loginqw/pages/companyLogin/index?corpId="+user.getCorpId() +
+                "&response_type=code&scope=snsapi_base&state="+encodedStatus+"&agentid="+qwCompany.getServerAgentId()+"#wechat_redirect";
+
+        R andUpload = QRCodeUtils.createAndUpload(url);
+        return  R.ok().put("data",andUpload);
+    }
+    /**
+     * 修改用户
+     */
+    @PreAuthorize("@ss.hasPermi('company:user:edit')")
+    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@Validated @RequestBody CompanyUser user)
+    {
+
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        user.setUpdateBy(SecurityUtils.getUsername());
+
+        if (!StringUtil.strIsNullOrEmpty(user.getDomain())){
+            user.setDomain(user.getDomain().replaceAll("^[\\s\\u2005]+", ""));
+        }
+
+        CompanyUser companyUser = companyUserService.selectCompanyUserById(user.getUserId());
+
+        if (!companyUser.getUserName().equals(user.getUserName())){
+            if (UserConstants.NOT_UNIQUE.equals(String.valueOf(companyUserService.checkUserName(user.getUserName()))))
+            {
+                return AjaxResult.error("修改员工账号'" + user.getUserName() + "'失败,员工账号已存在");
+            }
+        }
+
+
+        logger.info("用户管理-修改用户:"+user.getUserName()+"/登陆人:"+loginUser.getUser().getUserId()+"/名字:"+loginUser.getUser().getUserName()+"/修改的角色:"+ Arrays.toString(user.getRoleIds()));
+        return toAjax(companyUserService.updateUser(user));
+    }
+
+    /**
+     * 删除用户
+     */
+    @PreAuthorize("@ss.hasPermi('company:user:remove')")
+    @Log(title = "用户管理", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{userIds}")
+    public AjaxResult remove(@PathVariable Long[] userIds)
+    {
+        for (Long userId : userIds) {
+            CompanyUser companyUser = companyUserService.selectCompanyUserById(userId);
+            CompanyUserDelayTime companyUserDelayTime = companyUserDelayTimeService.selectCompanyUserDelayTimeByCompanyUser(companyUser.getCompanyId(),userId);
+            if (ObjectUtil.isNotEmpty(companyUserDelayTime)){
+                companyUserDelayTimeService.deleteCompanyUserDelayTimeById(companyUserDelayTime.getId());
+            }
+        }
+        return toAjax(companyUserService.deleteCompanyUserByIds(userIds));
+    }
+
+    /**
+     * 重置密码
+     */
+    @PreAuthorize("@ss.hasPermi('company:user:edit')")
+    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
+    @PutMapping("/resetPwd")
+    public AjaxResult resetPwd(@RequestBody CompanyUser user)
+    {
+        if (!PatternUtils.checkPassword(user.getPassword())) {
+            return AjaxResult.error("密码格式不正确,需包含字母、数字和特殊字符,长度为 8-20 位");
+        }
+
+        String newPassword = SecurityUtils.encryptPassword(user.getPassword());
+        int i = companyUserService.resetUserPwdByUserId(user.getUserId(), newPassword);
+
+        if (i > 0) {
+            // 更新缓存用户密码
+            redisCache.deleteObject("newCompanyUser:" + user.getCompanyId() + ":" + user.getUserName());
+        }
+
+        return toAjax(i);
+    }
+
+    /**
+     * 状态修改
+     */
+    @PreAuthorize("@ss.hasPermi('company:user:edit')")
+    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public AjaxResult changeStatus(@RequestBody CompanyUser user)
+    {
+        //管理员的状态不能修改
+        CompanyUser companyUser=companyUserService.selectCompanyUserById(user.getUserId());
+        if(companyUser.isAdmin()){
+            return AjaxResult.error("不能修改管理员状态");
+        }
+        user.setUpdateBy(SecurityUtils.getUsername());
+        return toAjax(companyUserService.updateCompanyUser(user));
+    }
+
+
+
+
+    /**
+     * 获取区域
+     */
+    @GetMapping("/getCitysAreaList")
+    public R getCitysAreaList(){
+        return R.ok().put("data",companyUserService.getCitysAreaList());
+    }
+
+    /**
+     * 批量修改 销售的所属区域(临时的)
+     */
+    @PostMapping("/updateCompanyUserAreaList")
+    public R updateCompanyUserAreaList(@RequestBody CompanyUserAreaParam param)
+    {
+        return companyUserService.updateCompanyUserAreaList(param);
+    }
+
+
+    @GetMapping("/generateSubDomain")
+    public R generateSubDomain(CompanyUser user){
+        //获取后台配置
+        String json= configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+        // 生成二级域名
+        String subDomain = "http://" + DomainUtil.generateSubDomain(config.getCourseDomainName(), 6, String.valueOf(SecurityUtils.getLoginUser().getUser().getUserId()));
+        return  R.ok().put("data",subDomain);
+    }
+
+    @Log(title = "设置是否需要单独注册会员", businessType = BusinessType.UPDATE)
+    @PutMapping("/setRegister")
+    public AjaxResult setIsRegisterMember(@RequestParam Boolean status, @RequestBody List<Long> userIds) {
+        Boolean r = companyUserService.setIsRegisterMember(status, userIds);
+        if (r) {
+            return AjaxResult.success();
+        } else {
+            return AjaxResult.error("操作失败");
+        }
+    }
+
+    @Log(title = "是否允许所有方式注册会员", businessType = BusinessType.UPDATE)
+    @PutMapping("/allowedAllRegister")
+    public AjaxResult isAllowedAllRegister(@RequestParam Boolean status, @RequestBody List<Long> userIds) {
+        Boolean r = companyUserService.isAllowedAllRegister(status, userIds);
+        if (r) {
+            return AjaxResult.success();
+        } else {
+            return AjaxResult.error("操作失败");
+        }
+    }
+    @PostMapping("/common/uploadOSS")
+    public R uploadOSS(@RequestParam("file") MultipartFile file,
+                       @RequestParam("userId") String userId) throws Exception {
+        String url = companyUserService.uploadQrCode(file, userId);
+        return R.ok().put("url", url);
+    }
+
+
+    /**
+     * 销售解除绑定医生
+     */
+    @PreAuthorize("@ss.hasPermi('qw:companyUser:unBindDoctorId')")
+    @Log(title = "销售解除绑定医生", businessType = BusinessType.UPDATE)
+    @GetMapping("/unBindDoctorId/{userId}")
+    public R bindDoctorId(@PathVariable("userId") Long userId){
+        return companyUserService.unBindDoctor(userId);
+    }
+
+    /**
+     * 销售绑定医生
+     */
+    @PreAuthorize("@ss.hasPermi('qw:companyUser:bindDoctorId')")
+    @Log(title = "销售绑定医生", businessType = BusinessType.UPDATE)
+    @PostMapping("/bindDoctorId")
+    public R unBindDoctorId(@RequestBody CompanyUser companyUser){
+        return companyUserService.bindDoctor(companyUser);
+    }
+
+    /**
+     * 批量修改角色
+     * @param batchUserRolesVO
+     */
+    @PreAuthorize("@ss.hasPermi('company:user:edit')")
+    @Log(title = "批量修改角色", businessType = BusinessType.UPDATE)
+    @PostMapping("/updateBatchUserRoles")
+    public R updateBatchUserRoles(@RequestBody BatchUserRolesVO batchUserRolesVO){
+        Assert.notEmpty(batchUserRolesVO.getRoleIds(), "角色不能为空");
+        Assert.notEmpty(batchUserRolesVO.getUserIds(), "用户不能为空");
+        return companyUserService.updateBatchUserRoles(batchUserRolesVO);
+    }
+
+
+    @ApiOperation("校验客服是否注册新的im")
+    @PostMapping("/accountCheck")
+    public R accountCheck(@RequestBody Map<String, String> userIdMap){
+        //获取管理员token
+        String userId = userIdMap.get("userId");
+        String adminToken = openIMService.getAdminToken();
+        JSONObject requestBody = new JSONObject();
+        // 解析响应
+        if (StringUtils.isNotEmpty(adminToken)) {
+            //查询用户是否注册
+            ArrayList<String> userIds = new ArrayList<>();
+            requestBody = new JSONObject();
+            userIds.add(userId);
+            requestBody.put("checkUserIDs", userIds);
+            String body = HttpRequest.post(IMConfig.URL+"/user/account_check")
+                    .header("operationID", String.valueOf(System.currentTimeMillis()))
+                    .header("token", adminToken)
+                    .body(requestBody.toString())
+                    .execute()
+                    .body();
+            JSONObject jsonObject = new JSONObject(body);
+            JSONArray results = jsonObject.getJSONObject("data").getJSONArray("results");
+            if (results != null && results.length() > 0) {
+                JSONObject resultObj = results.getJSONObject(0);
+                int accountStatus = resultObj.getInt("accountStatus");
+                //未注册自动注册
+                if (accountStatus==0){
+                    String s = userId.replaceFirst("^C", "");
+                    CompanyUser companyUser = companyUserService.selectCompanyUserById(Long.parseLong(s));
+                    if (null==companyUser){
+                        return R.error("用户不存在");
+                    }
+                    ArrayList<Object> users = new ArrayList<>();
+                    HashMap<String, String> map = new HashMap<>();
+                    map.put("userID",userId);
+                    map.put("nickname",companyUser.getNickName());
+                    map.put("faceURL",companyUser.getAvatar());
+                    users.add(map);
+                    requestBody = new JSONObject();
+                    //userIds.add(userId);
+                    requestBody.put("users", users);
+                    String registerBody = HttpRequest.post(IMConfig.URL+"/user/user_register")
+                            .header("operationID", String.valueOf(System.currentTimeMillis()))
+                            .header("token", adminToken).body(requestBody.toString()).execute().body();
+                }
+            } else {
+                return R.error("返回结果为空");
+            }
+           /* HashMap<String, String> tokenMap = new HashMap<>();
+            tokenMap.put("platformID","1");
+            tokenMap.put("userID",userId);*/
+            requestBody = new JSONObject();
+            requestBody.put("platformID",5);
+            requestBody.put("userID",userId);
+            String body1 = HttpRequest.post(IMConfig.URL+"/auth/get_user_token")
+                    .header("operationID", String.valueOf(System.currentTimeMillis()))
+                    .header("token", adminToken)
+                    .body(requestBody.toString()).execute().body();
+            JSONObject userJson = new JSONObject(body1);
+            JSONObject userData = userJson.getJSONObject("data");
+            String userToken = userData.getString("token");
+            return R.ok().put("token", userToken);
+        } else {
+            return R.error("获取管理员token失败");
+        }
+    }
+    @ApiOperation("添加好友")
+    @PostMapping("/importFriend")
+    public R importFriend(@RequestBody HashMap<String,Object> map){
+        String ownerUserID = (String) map.get("ownerUserID");
+        List<String> friendUserIDs = (List<String>)map.get("friendUserIDs");
+        OpenImResponseDTO openImResponseDTO = openIMService.importFriend(ownerUserID, friendUserIDs);
+        return R.ok().put("data",openImResponseDTO);
+    }
+}

+ 23 - 0
fs-admin/src/main/java/com/fs/his/controller/FsDoctorController.java

@@ -26,6 +26,9 @@ import com.fs.his.service.IFsDoctorService;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.common.core.page.TableDataInfo;
 
+import static com.fs.his.utils.PhoneUtil.decryptAutoPhoneMk;
+import static com.fs.his.utils.PhoneUtil.encryptPhone;
+
 /**
  * 医生管理Controller
  *
@@ -291,4 +294,24 @@ public class FsDoctorController extends BaseController
         return R.ok().put("data", new PageInfo<>(list));
     }
 
+
+    @GetMapping("/getDocVoList")
+    public TableDataInfo getDocVoList(FsDoctorParam param) {
+        startPage();
+        List<FsDoctorVO> list = fsDoctorService.selectDocVOByNameAndPhone(param);
+        if (list == null || list.isEmpty()) {
+            param.setMobile(encryptPhone(param.getMobile()));
+            list = fsDoctorService.selectDocVOByNameAndPhone(param);
+        }
+
+        if (list != null) {
+            list.forEach( item -> {
+                if (item.getMobile() != null)
+                    item.setMobile(decryptAutoPhoneMk(item.getMobile()));
+            });
+        }
+        return getDataTable(list);
+    }
+
+
 }

+ 138 - 0
fs-admin/src/main/java/com/fs/qw/controller/QwDeptController.java

@@ -0,0 +1,138 @@
+package com.fs.qw.controller;
+
+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.domain.model.LoginUser;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.qw.domain.QwDept;
+import com.fs.qw.mapper.QwCompanyMapper;
+import com.fs.qw.service.IQwDeptService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 企业微信部门Controller
+ *
+ * @author fs
+ * @date 2024-08-27
+ */
+@RestController
+@RequestMapping("/qw/qwDept")
+public class QwDeptController extends BaseController
+{
+    @Autowired
+    private IQwDeptService qwDeptService;
+
+
+    /**
+     * 查询企业微信部门列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwDept:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(QwDept qwDept)
+    {
+        startPage();
+        List<QwDept> list = qwDeptService.selectQwDeptList(qwDept);
+        return getDataTable(list);
+    }
+    @Autowired
+    QwCompanyMapper qwCompanyMapper;
+
+    /**
+     * 同步企业微信 部门信息
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwDept:list')")
+    @GetMapping("/syncDept/{companyId}")
+    public R syncDept(@PathVariable("companyId") Long companyId){
+
+        List<String> strings = qwCompanyMapper.selectQwCompanyCorpIdListByCompanyId(companyId);
+        for (String string : strings) {
+            qwDeptService.insertOrUpdateQwDept(string);
+        }
+
+        return  R.ok();
+    }
+
+    /**
+     * 导出企业微信部门列表
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwDept:export')")
+    @Log(title = "企业微信部门", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(QwDept qwDept)
+    {
+        List<QwDept> list = qwDeptService.selectQwDeptList(qwDept);
+        ExcelUtil<QwDept> util = new ExcelUtil<QwDept>(QwDept.class);
+        return util.exportExcel(list, "企业微信部门数据");
+    }
+
+    /**
+     * 获取企业微信部门详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwDept:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(qwDeptService.selectQwDeptById(id));
+    }
+
+    /**
+     * 新增企业微信部门
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwDept:add')")
+    @Log(title = "企业微信部门", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody QwDept qwDept)
+    {
+        return toAjax(qwDeptService.insertQwDept(qwDept));
+    }
+
+    /**
+     * 修改企业微信部门
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwDept:edit')")
+    @Log(title = "企业微信部门", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody QwDept qwDept)
+    {
+        return toAjax(qwDeptService.updateQwDept(qwDept));
+    }
+
+    /**
+     * 删除企业微信部门
+     */
+    @PreAuthorize("@ss.hasPermi('qw:qwDept:remove')")
+    @Log(title = "企业微信部门", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(qwDeptService.deleteQwDeptByIds(ids));
+    }
+
+    /**
+     * @Description: 获取企微部门 按Treeselect返回 每一个企微主体有自己的部门,按企微主体查询
+     * @Param:
+     * @Return:
+     * @Author xgb
+     * @Date 2025/10/30 9:33
+     */
+    @GetMapping("/treeselect")
+    public AjaxResult treeselect(QwDept qwDept)
+    {
+        if(StringUtils.isEmpty(qwDept.getCorpId())){
+            return AjaxResult.error("请选择企微主体");
+        }
+        List<QwDept> depts = qwDeptService.selectQwDeptList(qwDept);
+        return AjaxResult.success(qwDeptService.buildDeptTreeSelect(depts));
+    }
+
+}

+ 309 - 5
fs-admin/src/main/java/com/fs/qw/controller/QwUserController.java

@@ -1,22 +1,48 @@
 package com.fs.qw.controller;
 
+import com.alibaba.fastjson.JSON;
+import com.fs.common.annotation.Log;
+import com.fs.common.annotation.RepeatSubmit;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.model.LoginUser;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.ServletUtils;
+import com.fs.company.domain.Company;
+import com.fs.company.domain.CompanyUser;
+import com.fs.company.mapper.CompanyUserMapper;
+import com.fs.company.service.ICompanyUserService;
+import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.domain.QwExternalContactTransferCompanyAudit;
+import com.fs.qw.domain.QwUser;
+import com.fs.qw.mapper.QwCompanyMapper;
+import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.param.QwFsUserParam;
+import com.fs.qw.param.QwUserBingParam;
+import com.fs.qw.param.QwUserListParam;
+import com.fs.qw.service.IQwDeptService;
 import com.fs.qw.service.IQwExternalContactTransferCompanyAuditService;
 import com.fs.qw.service.IQwUserService;
 import com.fs.qw.vo.QwOptionsVO;
+import com.fs.qw.vo.QwUserVO;
+import com.fs.qwApi.domain.QwExternalContactAllListResult;
+import com.fs.qwApi.domain.inner.ExternalContact;
+import com.fs.qwApi.domain.inner.ExternalContactInfo;
+import com.fs.qwApi.domain.inner.FollowInfo;
+import com.fs.qwApi.param.QwExternalListParam;
+import com.fs.qwApi.service.QwApiService;
+import com.fs.voice.utils.StringUtil;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
 
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * 企微用户Controller
@@ -29,8 +55,28 @@ import java.util.List;
 public class QwUserController extends BaseController {
     @Autowired
     private IQwUserService qwUserService;
+
     @Autowired
     private IQwExternalContactTransferCompanyAuditService auditService;
+
+    @Autowired
+    private ICompanyUserService companyUserService;
+
+    @Autowired
+    private CompanyUserMapper companyUserMapper;
+
+    @Autowired
+    private QwApiService qwApiService;
+
+    @Autowired
+    private QwCompanyMapper qwCompanyMapper;
+
+    @Autowired
+    private IQwDeptService qwDeptService;
+
+    @Autowired
+    private QwExternalContactMapper qwExternalContactMapper;
+
     @GetMapping("/getQwUserAll")
     public AjaxResult getQwUserAll(){
         return AjaxResult.success(qwUserService.getQwUserAll());
@@ -47,7 +93,265 @@ public class QwUserController extends BaseController {
    @GetMapping("/getMyQwCompanyList")
     public R getMyQwCompanyList()
     {
-        List<QwOptionsVO> list = qwUserService.selectQwCompanyListOptionsVOBySys();
+        List<QwOptionsVO> list = qwUserService.selectQwCompanyListOptionsVOAll();
         return  R.ok().put("data",list);
     }
+
+    /**
+     * 绑定企微用户
+     */
+    @PreAuthorize("@ss.hasPermi('qw:user:bind')")
+    @Log(title = "企微用户", businessType = BusinessType.UPDATE)
+    @PutMapping("/bindQwUser")
+    @RepeatSubmit
+    public R bindQwUser(@RequestBody QwUserBingParam qwUserParam)
+    {
+        CompanyUser companyUser = companyUserService.selectCompanyUserById(qwUserParam.getCompanyUserId());
+
+        String qwUserIdCompanyStr = companyUser.getQwUserId();
+        Set<String> qwUserIdCompanySet = new HashSet<>();
+        if (!StringUtil.strIsNullOrEmpty(qwUserIdCompanyStr)) {
+            String[] qwUserId = qwUserIdCompanyStr.split(",");
+            qwUserIdCompanySet = Arrays.stream(qwUserId)
+                    .filter(id -> !id.isEmpty())
+                    .collect(Collectors.toSet());
+        }
+
+        if (companyUser!=null){
+
+            //选择的企业微信账号为“”
+            if (StringUtil.strIsNullOrEmpty(qwUserParam.getId())&&qwUserParam.getCompanyUserId()!=null){
+                //制空企业微信的绑定
+                qwUserService.updateUserByUserId(qwUserParam.getCompanyUserId());
+
+                //制空销售的绑定
+                companyUserMapper.updateCompanyUserByNullQwUserID(companyUser.getUserId());
+
+            }else {
+                String idParam = qwUserParam.getId();
+                String[] splitParam = idParam.split(",");
+                Set<String> splitParamSet = Arrays.stream(splitParam)
+                        .filter(s -> !s.isEmpty())
+                        .collect(Collectors.toSet());
+
+                // 找出在 qwUserIdCompanySet 中存在但在 splitParamSet 中不存在的元素
+                Set<String> difference = new HashSet<>(qwUserIdCompanySet);
+                difference.removeAll(splitParamSet);
+
+                //制空绑定
+                if (!difference.isEmpty()){
+                    difference.forEach(id->{
+                        qwUserService.updateUnBindUserById(id);
+                    });
+
+                }
+
+
+                for (String paramId : splitParamSet) {
+                    QwUser qu= qwUserService.selectQwUserById(Long.parseLong(paramId));
+                    if (qu.getCompanyUserId()!=null&&!qu.getCompanyUserId().equals(qwUserParam.getCompanyUserId())){
+                        return R.error( qu.getQwUserName()+"已经被其他人绑定,请先解绑");
+                    }
+
+
+                    CompanyUser user = new CompanyUser();
+                    user.setQwUserId(qwUserParam.getId());
+                    user.setUserId(companyUser.getUserId());
+                    user.setQwStatus(1);
+                    companyUserMapper.updateCompanyUser(user);
+
+
+
+                    qu.setCompanyUserId(qwUserParam.getCompanyUserId());
+                    qu.setStatus(1);
+                    qu.setCompanyId(companyUser.getCompanyId());
+                    qwUserService.updateQwUser(qu);
+
+                }
+
+                //同步最后单独跑/先不异步了pp
+                for (String paramId : splitParamSet){
+
+                    //如果销售没绑定过,全刷,否则只同步新的增加的
+                    if (StringUtil.strIsNullOrEmpty(qwUserIdCompanyStr)){
+                        updateAndSyncQwUser(paramId, companyUser);
+
+                    }
+                    else if (!StringUtil.strIsNullOrEmpty(qwUserIdCompanyStr) && !qwUserIdCompanySet.contains(paramId)){
+                        updateAndSyncQwUser(paramId, companyUser);
+                    }
+                }
+            }
+
+
+            return R.ok();
+        }
+        return R.error("绑定失败");
+
+    }
+
+
+    private void updateAndSyncQwUser(String paramId, CompanyUser companyUser) {
+
+        QwUser qu= qwUserService.selectQwUserById(Long.parseLong(paramId));
+
+        qwExternalContactMapper.updateBindUserByQwUser(qu.getCorpId(),qu.getQwUserId(),companyUser.getCompanyId(),companyUser.getUserId());
+
+        //根据企微账号和公司id 同步企业微信账号(游标初始为空)
+        syncMyQwExternalContact(qu,null);
+    }
+
+    public R  syncMyQwExternalContact(QwUser qwUser,String getNextCursor )  {
+
+        String qwUserId = qwUser.getQwUserId();
+        String corpId = qwUser.getCorpId();
+        Long companyId = qwUser.getCompanyId();
+
+        QwExternalListParam param = new QwExternalListParam();
+        param.setLimit(100);
+        param.setUserid_list(Arrays.asList(qwUserId));
+        param.setCursor(getNextCursor);
+
+        QwExternalContactAllListResult list = qwApiService.getAllExternalcontactList(param, corpId);
+
+        logger.info("批量获取客户详情" + list);
+
+        if (list.getErrcode() == 0) {
+            List<ExternalContactInfo> externalContactList = list.getExternal_contact_list();
+            for (ExternalContactInfo externalContactInfo : externalContactList) {
+
+                ExternalContact externalContact = externalContactInfo.getExternal_contact();
+                FollowInfo followInfo = externalContactInfo.getFollow_info();
+                QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalContactUserIdAndExternalIdAndCompanyId(externalContact.getExternal_userid(), qwUserId, corpId);
+                logger.info("客户详情" + qwExternalContact);
+
+                if (qwExternalContact == null) {
+                    qwExternalContact = new QwExternalContact();
+                    qwExternalContact.setUserId(qwUserId); // 设置属于用户ID
+                    qwExternalContact.setExternalUserId(externalContact.getExternal_userid()); // 设置外部联系人ID
+
+
+                    qwExternalContact.setCorpId(corpId); // 设置企业ID
+                    qwExternalContact.setCompanyId(companyId); // 设置公司ID
+                }
+
+
+                // 设置公共属性
+                qwExternalContact.setCompanyUserId(qwUser.getCompanyUserId());
+                qwExternalContact.setQwUserId(qwUser.getId());
+                qwExternalContact.setName(externalContact.getName()); // 设置名称
+                qwExternalContact.setAvatar(externalContact.getAvatar()); // 设置头像
+                qwExternalContact.setType(externalContact.getType()); // 设置外部联系人类型(1微信用户,2企业微信用户)
+                qwExternalContact.setGender(externalContact.getGender()); // 设置性别 (0-未知, 1-男性, 2-女性)
+                qwExternalContact.setDescription(followInfo.getDescription()); // 设置描述信息
+                qwExternalContact.setRemark(followInfo.getRemark());
+
+//                        if (followInfo.getTag_id() != null && !followInfo.getTag_id().isEmpty()) {
+                qwExternalContact.setTagIds(JSON.toJSONString(followInfo.getTag_id())); // 设置标签ID
+//                        }
+
+//                        if (followInfo.getRemark_mobiles() != null && !followInfo.getRemark_mobiles().isEmpty()) {
+                qwExternalContact.setRemarkMobiles(JSON.toJSONString(followInfo.getRemark_mobiles())); // 设置备注电话号码
+//                        }
+
+                qwExternalContact.setState(followInfo.getState());
+
+                if (followInfo.getState() != null && !followInfo.getState().isEmpty()) {
+                    String s = "way:" + corpId + ":";
+                    if (followInfo.getState().contains(s)) {
+                        String wayId = followInfo.getState().substring(followInfo.getState().indexOf(s) + s.length());
+                        qwExternalContact.setWayId(Long.parseLong(wayId));
+                    }
+                }
+
+                qwExternalContact.setRemarkCorpName(followInfo.getRemark_corp_name()); // 设置备注企业名称
+                qwExternalContact.setAddWay(followInfo.getAdd_way()); // 设置来源
+                qwExternalContact.setOperUserid(followInfo.getOper_userid()); // 设置oper用户ID
+
+                // 根据是否存在记录进行更新或插入
+                if (qwExternalContact.getId() != null) {
+                    qwExternalContactMapper.updateQwExternalContact(qwExternalContact);
+                } else {
+                    qwExternalContactMapper.insertQwExternalContact(qwExternalContact);
+                }
+            }
+
+        }else {
+            return R.error("同步失败:"+list.getErrmsg());
+        }
+
+        if (!StringUtil.strIsNullOrEmpty(list.getNext_cursor())){
+            syncMyQwExternalContact(qwUser,list.getNext_cursor());
+        }
+        return R.ok();
+    }
+
+
+    /**
+     * 同步企微用户
+     */
+    @RepeatSubmit
+    @PreAuthorize("@ss.hasPermi('qw:user:sync')")
+    @Log(title = "企微用户", businessType = BusinessType.INSERT)
+    @PostMapping("sync/{corpId}/{companyId}")
+    public R sync(@PathVariable("corpId") String corpId,@PathVariable("companyId") Long companyId)
+    {
+
+        List<String> strings = qwCompanyMapper.selectQwCompanyCorpIdListByCompanyId(companyId);
+        for (String string : strings) {
+
+            if (string.equals(corpId)){
+                qwUserService.syncQwUser(string);
+                qwDeptService.insertOrUpdateQwDept(string);
+                logger.info("同步完成");
+            }
+        }
+        return R.ok();
+    }
+
+    /**
+     * 获取企微用户详细信息
+     */
+
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(qwUserService.selectQwUserVOById(id));
+    }
+    /**
+     * 批量查询 企微用户详细信息
+     */
+    @GetMapping(value = "/getInfo/{ids}")
+    public AjaxResult getInfoByIds(@PathVariable("ids") Long[] ids)
+    {
+        return AjaxResult.success(qwUserService.selectQwUserVOByIds(ids));
+    }
+
+    @RepeatSubmit
+    @PreAuthorize("@ss.hasPermi('qw:user:sync')")
+    @Log(title = "同步企微用户名称", businessType = BusinessType.INSERT)
+    @PostMapping("syncName/{corpId}/{companyId}")
+    public R syncName(@PathVariable("corpId") String corpId,@PathVariable("companyId") Long companyId)
+    {
+        List<String> strings = qwCompanyMapper.selectQwCompanyCorpIdListByCompanyId(companyId);
+        for (String string : strings) {
+            if (string.equals(corpId)){
+                qwUserService.syncQwUserName(string);
+            }
+        }
+        return R.ok();
+    }
+
+
+    /**
+     * 查询企微用户列表
+     */
+
+    @GetMapping("/userList")
+    public TableDataInfo userList(QwUserListParam qwUser)
+    {
+        startPage();
+        List<QwUserVO> list = qwUserService.selectAllQwUserListVO(qwUser);
+        return getDataTable(list);
+    }
 }

+ 1 - 1
fs-company/src/main/java/com/fs/company/controller/qw/QwUserController.java

@@ -621,7 +621,7 @@ public class QwUserController extends BaseController
     }
     @RepeatSubmit
     @PreAuthorize("@ss.hasPermi('qw:user:sync')")
-    @Log(title = "企微用户", businessType = BusinessType.INSERT)
+    @Log(title = "同步企微用户名称", businessType = BusinessType.INSERT)
     @PostMapping("syncName/{corpId}")
     public R syncName(@PathVariable String corpId)
     {

+ 1 - 0
fs-qw-api/src/main/java/com/fs/app/service/QwDataCallbackService.java

@@ -207,6 +207,7 @@ public class QwDataCallbackService {
                             if(WelcomeCodeList.getLength() > 0) {
                                 WelcomeCode = WelcomeCodeList.item(0).getTextContent();
                             }
+
                             String userId = root.getElementsByTagName("UserID").item(0).getTextContent();
                             String externalUserId = root.getElementsByTagName("ExternalUserID").item(0).getTextContent();
                             String cacheKey = "qwApiExternal:" + userId + ":" + corpId + ":" + externalUserId;

+ 14 - 4
fs-service/src/main/java/com/fs/company/domain/CompanyDeptTreeSelect.java

@@ -14,21 +14,31 @@ public class CompanyDeptTreeSelect {
     /** 节点名称 */
     private String label;
 
+    /**
+    * 销售公司
+    */
+    private Long companyId;
+
     /** 子节点 */
     @JsonInclude(JsonInclude.Include.NON_EMPTY)
     private List<CompanyDeptTreeSelect> children;
 
-    public CompanyDeptTreeSelect()
-    {
-
-    }
     public CompanyDeptTreeSelect(CompanyDept dept) {
         this.id = dept.getDeptId();
         this.label = dept.getDeptName();
+        this.companyId = dept.getCompanyId();
         this.children = dept.getChildren().stream().map(CompanyDeptTreeSelect::new).collect(Collectors.toList());
 
     }
 
+    public Long getCompanyId() {
+        return companyId;
+    }
+
+    public void setCompanyId(Long companyId) {
+        this.companyId = companyId;
+    }
+
     public Long getId()
     {
         return id;

+ 4 - 0
fs-service/src/main/java/com/fs/qw/mapper/QwUserMapper.java

@@ -156,6 +156,7 @@ public interface QwUserMapper extends BaseMapper<QwUser>
             "            <if test=\"nickName != null  and nickName != ''\"> and cu.nick_name like concat( #{nickName}, '%') </if>\n" +
             "            <if test=\"qwUserName != null  and qwUserName != ''\"> and qu.qw_user_name like concat('%', #{qwUserName}, '%') </if> " +
             "            <if test=\"corpId != null \"> and qu.corp_id = #{corpId}</if>\n" +
+            "            <if test=\"companyUserId != null \"> and qu.company_user_id = #{companyUserId}</if>\n" +
             "            <if test=\"companyId != null \"> and qu.company_id = #{companyId}</if>\n " +
             "            <if test=\"isDel != null \"> and qu.is_del = #{isDel}</if>\n "+
             "            <if test=\"cuDeptIdList != null and !cuDeptIdList.isEmpty() and  userType != '00' \">" +
@@ -301,6 +302,9 @@ public interface QwUserMapper extends BaseMapper<QwUser>
     @Select("select corp_id as dictValue,corp_name as dictLabel from qw_company where FIND_IN_SET(#{companyId},company_ids)")
     List<QwOptionsVO> selectQwCompanyListOptionsVOByCompanyId(Long companyId);
 
+    @Select("select corp_id as dictValue,corp_name as dictLabel from qw_company where status=1")
+    List<QwOptionsVO> selectQwCompanyListOptionsVOAll();
+
     @Select("select  *  from qw_user where qw_hook_id=#{qwHookId} ")
     QwUser selectQwUserByQwHookId(String qwHookId);
 

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

@@ -113,6 +113,7 @@ public interface IQwUserService
     void updateUnBindUserById(String id);
 
     List<QwOptionsVO> selectQwUserListOptionsVOByCompanyUserId(Long userId);
+    List<QwOptionsVO> selectQwCompanyListOptionsVOAll();
 
     QwUser selectQwUserByAppKey(String key);
 

+ 5 - 0
fs-service/src/main/java/com/fs/qw/service/impl/QwUserServiceImpl.java

@@ -1057,6 +1057,11 @@ public class QwUserServiceImpl implements IQwUserService
         return qwUserMapper.selectQwUserListOptionsVOByCompanyUserId(userId);
     }
 
+    @Override
+    public List<QwOptionsVO> selectQwCompanyListOptionsVOAll() {
+        return qwUserMapper.selectQwCompanyListOptionsVOAll();
+    }
+
     @Override
     public QwUser selectQwUserByAppKey(String key) {
         return qwUserMapper.selectQwUserByAppKey(key);

+ 28 - 0
fs-service/src/main/java/com/fs/utils/DomainUtil.java

@@ -0,0 +1,28 @@
+package com.fs.utils;
+
+
+import java.util.Random;
+
+public class DomainUtil {
+
+    private static final String LETTER = "abcdefghijklmnopqrstuvwxyz";
+    private static final Random RANDOM = new Random();
+
+    /**
+     * 生成二级域名
+     * @param domain 主域名
+     * @param length 名称长度
+     * @param suffix 后缀
+     * @return  二级域名
+     */
+    public static String generateSubDomain(String domain, int length, String suffix) {
+        if (length < 6) {
+            length = 6;
+        }
+        StringBuilder sub = new StringBuilder(length);
+        for (int i = 0; i < length; i++) {
+            sub.append(LETTER.charAt(RANDOM.nextInt(LETTER.length())));
+        }
+        return sub + "-" + suffix + "." + domain;
+    }
+}

+ 29 - 0
fs-service/src/main/java/com/fs/utils/QwStatusEnum.java

@@ -0,0 +1,29 @@
+package com.fs.utils;
+
+/**
+ * @description:
+ * @author: Guos
+ * @time: 2025/10/16 下午3:00
+ */
+public enum QwStatusEnum {
+
+    BOUND(1, "已绑定"),
+    UNBOUND(0, "未绑定");
+
+    private Integer code;
+
+    private String detail;
+
+    QwStatusEnum(Integer code, String detail) {
+        this.code = code;
+        this.detail = detail;
+    }
+
+    public int getCode(){
+        return this.code;
+    }
+
+    public String getDetail() {
+        return this.detail;
+    }
+}