package com.fs.qw; import com.alibaba.fastjson.JSON; import com.fs.common.annotation.Log; import com.fs.common.annotation.RepeatSubmit; import com.fs.common.constant.Constants; 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.exception.ServiceException; import com.fs.common.exception.user.UserPasswordNotMatchException; import com.fs.common.utils.MessageUtils; import com.fs.common.utils.ServletUtils; import com.fs.common.utils.poi.ExcelUtil; 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.core.manager.AsyncManager; import com.fs.core.manager.factory.AsyncFactory; import com.fs.fastGpt.domain.FastGptRole; import com.fs.fastGpt.mapper.FastGptRoleMapper; import com.fs.core.security.LoginUser; import com.fs.core.web.service.TokenService; import com.fs.qw.domain.QwExternalContact; import com.fs.qw.domain.QwUser; import com.fs.qw.mapper.QwCompanyMapper; import com.fs.qw.mapper.QwExternalContactMapper; import com.fs.qw.param.*; import com.fs.qw.service.IQwDeptService; import com.fs.qw.service.IQwExternalContactService; 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.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; /** * 企微用户Controller * * @author fs * @date 2024-06-20 */ @RestController @RequestMapping("/qw/user") public class QwUserController extends BaseController { private static final org.slf4j.Logger logger = LoggerFactory.getLogger(QwUserController.class); @Autowired private IQwUserService qwUserService; @Autowired private TokenService tokenService; @Autowired private ICompanyUserService companyUserService; @Autowired private IQwExternalContactService qwExternalContactService; @Autowired private QwCompanyMapper qwCompanyMapper; @Autowired private QwExternalContactMapper qwExternalContactMapper; @Autowired private FastGptRoleMapper fastGptRoleMapper; @Autowired private IQwDeptService qwDeptService; @Autowired private CompanyUserMapper companyUserMapper; @Autowired private QwApiService qwApiService; @Resource private AuthenticationManager authenticationManager; /** * 查询企微员工列表 */ @PreAuthorize("@ss.hasPermi('qw:user:staffList')") @GetMapping("/staffList") public TableDataInfo staffList(QwUserListParam qwUser) { startPage(); LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); qwUser.setCompanyId(loginUser.getCompany().getCompanyId()); List list = qwUserService.selectQwUserListStaffVO(qwUser); return getDataTable(list); } /** * 直接授权key */ @PreAuthorize("@ss.hasPermi('qw:user:authAppKey')") @PostMapping("/authAppKey") public R authAppKey(@RequestBody QwUser param){ return qwUserService.authAppKey(param); } /** * 输入授权key */ @PreAuthorize("@ss.hasPermi('qw:user:authAppKey')") @PostMapping("/handleInputAuthAppKey") public R handleInputAuthAppKey(@RequestBody QwUser param){ return qwUserService.handleInputAuthAppKey(param); } /** * 登录企业微信(发起登录) */ @PreAuthorize("@ss.hasPermi('qw:user:login')") @PostMapping("/loginQwCode") public R loginQwCode(@RequestBody QwLoginParam loginParam){ return qwUserService.loginQwCode(loginParam); } /** * 登录请求-刷新获取二维码 */ @PreAuthorize("@ss.hasPermi('qw:user:login')") @PostMapping("/loginQwCodeUrl") public R loginQwCodeUrl(@RequestBody QwLoginParam loginParam){ return qwUserService.loginQwCodeUrl(loginParam); } /** * 取redis里的登录二维码 */ @PreAuthorize("@ss.hasPermi('qw:user:login')") @PostMapping("/getQwCodeUrl") public R getQwCodeUrl(@RequestBody QwLoginParam loginParam) throws InterruptedException { return qwUserService.getQwCodeUrl(loginParam); } /** * 登录企业微信(传输验证信息) */ @PreAuthorize("@ss.hasPermi('qw:user:login')") @PostMapping("/loginQwCodeMsg") public R loginQwCodeMsg(@RequestBody QwLoginParam loginParam){ return qwUserService.loginQwCodeMsg(loginParam); } /** * 退出企业微信(退出插件) */ @PreAuthorize("@ss.hasPermi('qw:user:login')") @PostMapping("/logoutQwLogout") public R logoutQwLogout(@RequestBody QwLoginParam loginParam){ return qwUserService.logoutQwLogout(loginParam); } // /** // * 企业微信(修改登录状态) // */ // @PreAuthorize("@ss.hasPermi('qw:user:login')") // @PostMapping("/modifyLoginQwStatus") // public R modifyLoginQwStatus(@RequestBody QwLoginParam loginParam){ // return qwUserService.modifyLoginQwStatus(loginParam); // } // /** * 查询企业微信登录状态 */ @PreAuthorize("@ss.hasPermi('qw:user:login')") @PostMapping("/getLoginQwStatus") public R getLoginQwStatus(@RequestBody QwLoginParam loginParam){ return qwUserService.getLoginQwStatus(loginParam); } @PutMapping public AjaxResult updateUser(@RequestBody QwUser qwUser){ return toAjax(qwUserService.updateQwUser(qwUser)); } /** * 企业微信员工账号 绑定 云主机 */ @PreAuthorize("@ss.hasPermi('qw:user:loginIp')") @Log(title = "绑定 云主机", businessType = BusinessType.INSERT) @GetMapping("/qwBindCloudHost/{appKey}") public R qwBindCloudHost(@PathVariable("appKey") String appKey){ return qwUserService.qwBindCloudHost(appKey); } /** * 获取云主机的账密 * */ @PreAuthorize("@ss.hasPermi('qw:user:cloudAP')") @PostMapping("/selectCloudAP") public R selectCloudAP(@RequestBody QwCloudAPParam param) throws Exception { return qwUserService.selectCloudAP(param); } /** * 根据销售账号密码 获取 他的所有企业微信账号以及云主机和账号密码 */ @PostMapping("/selectCloudByCompany") public R selectCloudByCompany(@RequestBody QwCloudIPByCompanyParam param) throws Exception { // 用户验证 Authentication authentication = null; try { // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername authentication = authenticationManager .authenticate(new UsernamePasswordAuthenticationToken(param.getCompanyAdmin(), param.getCompanyPassWord())); } catch (Exception e) { if (e instanceof BadCredentialsException) { AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,param.getCompanyAdmin(), Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); throw new UserPasswordNotMatchException(); } else { AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,param.getCompanyAdmin(), Constants.LOGIN_FAIL, e.getMessage())); throw new ServiceException(e.getMessage()); } } LoginUser loginUser=(LoginUser) authentication.getPrincipal(); return qwUserService.selectCloudByCompany(loginUser.getUser().getCompanyId(),loginUser.getUser().getUserId()); } /** * 企业微信员工账号 绑定 云主机 */ @PreAuthorize("@ss.hasPermi('qw:user:bindIp')") @GetMapping("/qwBindCloudHostByIp/{appKey}/{IP}") public R qwBindCloudHostByIp(@PathVariable("appKey") String appKey,@PathVariable("IP") String IP){ return qwUserService.qwBindCloudHostByIp(appKey,IP); } /** * 企业微信员工账号 解除绑定 云主机 */ @PreAuthorize("@ss.hasPermi('qw:user:loginIpOut')") @Log(title = "解除绑定 云主机", businessType = BusinessType.UPDATE) @GetMapping("/qwUnbindCloudHost/{appKey}") public R qwUnbindCloudHost(@PathVariable("appKey") String appKey){ return qwUserService.qwUnbindCloudHost(appKey); } /** * 查询企微用户列表 */ // @PreAuthorize("@ss.hasPermi('qw:user:list')") @GetMapping("/list") public TableDataInfo list(QwUserListParam qwUser) { startPage(); LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); qwUser.setCompanyId(loginUser.getCompany().getCompanyId()); List list = qwUserService.selectQwUserListVO(qwUser); return getDataTable(list); } /** * 查询企微用户列表 */ @GetMapping("/userList") public TableDataInfo userList(QwUserListParam qwUser) { startPage(); // LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); // qwUser.setCompanyId(loginUser.getCompany().getCompanyId()); List list = qwUserService.selectAllQwUserListVO(qwUser); return getDataTable(list); } // /** // * 查询我的企微用户列表 // */ // @PreAuthorize("@ss.hasPermi('qw:user:myList')") // @GetMapping("/myList") // public TableDataInfo myList(QwUserParam qwUser) // { // startPage(); // LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); // qwUser.setCompanyId(loginUser.getCompany().getCompanyId()); // qwUser.setCompanyUserId(loginUser.getCompany().getUserId()); // List list = qwUserService.selectQwUserListVO(qwUser); // return getDataTable(list); // } /** * 导出企微用户列表 */ @PreAuthorize("@ss.hasPermi('qw:user:export')") @Log(title = "企微用户", businessType = BusinessType.EXPORT) @GetMapping("/export") public AjaxResult export(QwUser qwUser) { LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); qwUser.setCompanyId(loginUser.getCompany().getCompanyId()); List list = qwUserService.selectQwUserList(qwUser); ExcelUtil util = new ExcelUtil(QwUser.class); return util.exportExcel(list, "企微用户数据"); } /** * 查询企微员工列表-用于员工管理绑定 */ @GetMapping("/getQwUserList") public R getQwUserList() { LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); QwUserParam qwUser = new QwUserParam(); List strings = qwCompanyMapper.selectQwCompanyCorpIdListByCompanyId(loginUser.getCompany().getCompanyId()); qwUser.setCorpId(strings); if (strings==null||strings.size()==0){ return R.ok().put("data",null); } qwUser.setIsDel(0); List list = qwUserService.selectQwUserListBindVO(qwUser); return R.ok().put("data",list); } @GetMapping("/getMyQwUserList") public R getMyQwUserList() { LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); List list = qwUserService.selectQwUserListOptionsVOByCompanyUserId(loginUser.getUser().getUserId()); return R.ok().put("data",list); } @GetMapping("/getMyQwCompanyList") public R getMyQwCompanyList() { LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); List list = qwUserService.selectQwCompanyListOptionsVOByCompanyId(loginUser.getCompany().getCompanyId()); return R.ok().put("data",list); } /** * 获取企微用户详细信息 */ @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)); } // /** // * 新增企微用户 // */ // @PreAuthorize("@ss.hasPermi('qw:user:add')") // @Log(title = "企微用户", businessType = BusinessType.INSERT) // @PostMapping // public R add() // { // LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); // // return R.ok(qwUserService.syncQwUser(loginUser.getCompany().getCompanyId())); // } /** * 同步企微用户 */ @RepeatSubmit @PreAuthorize("@ss.hasPermi('qw:user:sync')") @Log(title = "企微用户", businessType = BusinessType.INSERT) @PostMapping("sync/{corpId}") public R sync(@PathVariable String corpId) { LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); Company company = loginUser.getCompany(); List strings = qwCompanyMapper.selectQwCompanyCorpIdListByCompanyId(company.getCompanyId()); for (String string : strings) { if (string.equals(corpId)){ qwUserService.syncQwUser(string); qwDeptService.insertOrUpdateQwDept(string); System.out.println("同步完成"); } } return R.ok(); } @RepeatSubmit @PreAuthorize("@ss.hasPermi('qw:user:sync')") @Log(title = "企微用户", businessType = BusinessType.INSERT) @PostMapping("syncName/{corpId}") public R syncName(@PathVariable String corpId) { LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); Company company = loginUser.getCompany(); List strings = qwCompanyMapper.selectQwCompanyCorpIdListByCompanyId(company.getCompanyId()); for (String string : strings) { if (string.equals(corpId)){ qwUserService.syncQwUserName(string); } } return R.ok(); } /** * 绑定AI客服 */ // @PreAuthorize("@ss.hasPermi('qw:user:bindAi')") @Log(title = "企微用户", businessType = BusinessType.UPDATE) @PutMapping("/bindAi") @RepeatSubmit public R edit(@RequestBody QwUserBindAi param) { QwUser qwUser=new QwUser(); qwUser.setId(param.getId()); qwUser.setFastGptRoleId(param.getFastGptRoleId()); FastGptRole role = fastGptRoleMapper.selectFastGptRoleByRoleId(param.getFastGptRoleId()); if (role.getBindCorpId()!=null){ if (role.getBindCorpId().equals(param.getCorpId())){ qwUserService.updateQwUser(qwUser); }else { return R.error("该角色已绑定其他企业"); } }else { int i = qwUserService.updateQwUser(qwUser); FastGptRole fastGptRole=new FastGptRole(); fastGptRole.setRoleId(param.getFastGptRoleId()); fastGptRole.setBindCorpId(param.getCorpId()); fastGptRoleMapper.updateFastGptRole(fastGptRole); if (i>0){ return R.ok(); }else { return R.error("绑定失败"); } } return R.ok(); } /** * 解除应用绑定 */ // @PreAuthorize("@ss.hasPermi('fastGpt:fastGptRole:relieve')") @Log(title = "解除应用", businessType = BusinessType.UPDATE) @GetMapping("/relieveFastGptRoleById/{id}") public R relieveFastGptRoleById(@PathVariable("id") Long id) { return qwUserService.relieveFastGptRoleById(id); } /** * 绑定企微用户 */ @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 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 splitParamSet = Arrays.stream(splitParam) .filter(s -> !s.isEmpty()) .collect(Collectors.toSet()); // 找出在 qwUserIdCompanySet 中存在但在 splitParamSet 中不存在的元素 Set 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); QwUser qw = new QwUser(); qw.setCompanyUserId(qwUserParam.getCompanyUserId()); qw.setId(Long.parseLong(paramId)); qw.setStatus(1); qw.setCompanyId(companyUser.getCompanyId()); qwUserService.updateQwUser(qw); } //同步最后单独跑/先不异步了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); } /** 修改企微用户的欢迎语 */ @PostMapping("/weclomeQwUser") public R weclomeQwUser(@RequestBody QwUser qwUser) throws Exception { return qwUserService.weclomeQwUser(qwUser); } /** * 删除企微用户 */ @PreAuthorize("@ss.hasPermi('qw:user:remove')") @Log(title = "企微用户", businessType = BusinessType.DELETE) @DeleteMapping("/{ids}") public AjaxResult remove(@PathVariable Long[] ids) { return toAjax(qwUserService.deleteQwUserByIds(ids)); } /** * 获取企业微信用户列表 */ @GetMapping("/qwUserList/{corpId}") public TableDataInfo qwUserList(@PathVariable String corpId) { // LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); // Long companyId = loginUser.getCompany().getCompanyId(); List list = qwUserService.selectQwUserListOptionsVO(corpId); return getDataTable(list); } @GetMapping("/getQwUserAll") public AjaxResult getQwUserAll(){ return AjaxResult.success(qwUserService.getQwUserAll()); } 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 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(); } }