feat: 接入聊天历史界面与外链会话恢复
- 新增管理端与用户端聊天历史接口和页面 - 外链聊天支持访问令牌登录、身份保活与当前会话恢复 - 聊天执行链路切到统一 runtime 与 chatlog 查询接口
This commit is contained in:
@@ -3,6 +3,8 @@ package tech.easyflow.auth.service;
|
||||
import tech.easyflow.auth.entity.LoginDTO;
|
||||
import tech.easyflow.auth.entity.LoginVO;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
public interface AuthService {
|
||||
/**
|
||||
* 登录
|
||||
@@ -13,4 +15,14 @@ public interface AuthService {
|
||||
* 开发模式免登录
|
||||
*/
|
||||
LoginVO devLogin(String account);
|
||||
|
||||
/**
|
||||
* 通过访问令牌登录
|
||||
*/
|
||||
LoginVO loginByApiKey(String apiKey);
|
||||
|
||||
/**
|
||||
* 通过账号ID登录
|
||||
*/
|
||||
LoginVO loginByAccountId(BigInteger accountId, Long timeoutSeconds);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
package tech.easyflow.auth.service.impl;
|
||||
|
||||
import cn.dev33.satoken.stp.SaLoginModel;
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.core.tenant.TenantManager;
|
||||
import org.springframework.stereotype.Service;
|
||||
import tech.easyflow.auth.entity.LoginDTO;
|
||||
import tech.easyflow.auth.entity.LoginVO;
|
||||
import tech.easyflow.auth.service.AuthService;
|
||||
@@ -7,22 +14,19 @@ import tech.easyflow.common.constant.Constants;
|
||||
import tech.easyflow.common.constant.enums.EnumDataStatus;
|
||||
import tech.easyflow.common.entity.LoginAccount;
|
||||
import tech.easyflow.common.web.exceptions.BusinessException;
|
||||
import tech.easyflow.system.entity.SysApiKey;
|
||||
import tech.easyflow.system.entity.SysAccount;
|
||||
import tech.easyflow.system.entity.SysMenu;
|
||||
import tech.easyflow.system.entity.SysRole;
|
||||
import tech.easyflow.system.service.SysApiKeyService;
|
||||
import tech.easyflow.system.service.SysAccountService;
|
||||
import tech.easyflow.system.service.SysMenuService;
|
||||
import tech.easyflow.system.service.SysRoleService;
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.crypto.digest.BCrypt;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.core.tenant.TenantManager;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -35,6 +39,8 @@ public class AuthServiceImpl implements AuthService, StpInterface {
|
||||
private SysRoleService sysRoleService;
|
||||
@Resource
|
||||
private SysMenuService sysMenuService;
|
||||
@Resource
|
||||
private SysApiKeyService sysApiKeyService;
|
||||
|
||||
@Override
|
||||
public LoginVO login(LoginDTO loginDTO) {
|
||||
@@ -63,6 +69,29 @@ public class AuthServiceImpl implements AuthService, StpInterface {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginVO loginByApiKey(String apiKey) {
|
||||
try {
|
||||
TenantManager.ignoreTenantCondition();
|
||||
sysApiKeyService.checkApikeyPermission(apiKey, "/public-api/bot/chat");
|
||||
SysApiKey sysApiKey = sysApiKeyService.getSysApiKey(apiKey);
|
||||
BigInteger accountId = sysApiKey.getCreatedBy();
|
||||
if (accountId == null) {
|
||||
throw new BusinessException("访问令牌未绑定创建用户");
|
||||
}
|
||||
Long timeoutSeconds = resolveApiKeyLoginTimeoutSeconds(sysApiKey);
|
||||
return loginByAccountId(accountId, timeoutSeconds);
|
||||
} finally {
|
||||
TenantManager.restoreTenantCondition();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginVO loginByAccountId(BigInteger accountId, Long timeoutSeconds) {
|
||||
SysAccount record = getAvailableAccount(accountId, "账号不存在或不可用");
|
||||
return createLoginVO(record, timeoutSeconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getPermissionList(Object loginId, String loginType) {
|
||||
List<SysMenu> menus = sysMenuService.getMenusByAccountId(new SysMenu(), BigInteger.valueOf(Long.parseLong(loginId.toString())));
|
||||
@@ -79,7 +108,17 @@ public class AuthServiceImpl implements AuthService, StpInterface {
|
||||
}
|
||||
|
||||
private LoginVO createLoginVO(SysAccount record) {
|
||||
StpUtil.login(record.getId());
|
||||
return createLoginVO(record, null);
|
||||
}
|
||||
|
||||
private LoginVO createLoginVO(SysAccount record, Long timeoutSeconds) {
|
||||
if (timeoutSeconds != null) {
|
||||
SaLoginModel loginModel = new SaLoginModel();
|
||||
loginModel.setTimeout(timeoutSeconds);
|
||||
StpUtil.login(record.getId(), loginModel);
|
||||
} else {
|
||||
StpUtil.login(record.getId());
|
||||
}
|
||||
LoginAccount loginAccount = new LoginAccount();
|
||||
BeanUtil.copyProperties(record, loginAccount);
|
||||
StpUtil.getSession().set(Constants.LOGIN_USER_KEY, loginAccount);
|
||||
@@ -92,10 +131,32 @@ public class AuthServiceImpl implements AuthService, StpInterface {
|
||||
return res;
|
||||
}
|
||||
|
||||
private Long resolveApiKeyLoginTimeoutSeconds(SysApiKey sysApiKey) {
|
||||
Date expiredAt = sysApiKey.getExpiredAt();
|
||||
if (expiredAt == null) {
|
||||
return null;
|
||||
}
|
||||
long remainingMs = expiredAt.getTime() - System.currentTimeMillis();
|
||||
if (remainingMs <= 0) {
|
||||
throw new BusinessException("apiKey 已过期");
|
||||
}
|
||||
long timeoutSeconds = (remainingMs + 999) / 1000;
|
||||
return Math.max(timeoutSeconds, 1L);
|
||||
}
|
||||
|
||||
private SysAccount getAvailableAccount(String account, String accountNotFoundMessage) {
|
||||
QueryWrapper w = QueryWrapper.create();
|
||||
w.eq(SysAccount::getLoginName, account);
|
||||
SysAccount record = sysAccountService.getOne(w);
|
||||
return validateAvailableAccount(record, accountNotFoundMessage);
|
||||
}
|
||||
|
||||
private SysAccount getAvailableAccount(BigInteger accountId, String accountNotFoundMessage) {
|
||||
SysAccount record = sysAccountService.getById(accountId);
|
||||
return validateAvailableAccount(record, accountNotFoundMessage);
|
||||
}
|
||||
|
||||
private SysAccount validateAvailableAccount(SysAccount record, String accountNotFoundMessage) {
|
||||
if (record == null) {
|
||||
throw new BusinessException(accountNotFoundMessage);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user