fix: 页面优化,工具栏显示
This commit is contained in:
parent
fc1ecf7bc9
commit
8436c3515c
|
|
@ -4,7 +4,7 @@
|
|||
.gradle
|
||||
/build/
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
*.sql
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ public class AiManagerApiController extends BaseController {
|
|||
@Anonymous
|
||||
public AjaxResult selectInfo(String aiType) {
|
||||
AiManager aiManager = aiManagerService.selectAiManagerByType(aiType);
|
||||
if (aiManager == null) {
|
||||
return AjaxResult.error("该功能未配置或已停用");
|
||||
}
|
||||
aiManager.setPrompt(null);
|
||||
return AjaxResult.success(aiManager);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,17 @@ public class PortalVideoController extends BaseController {
|
|||
return byteDeptApiKeyService.resolveVolcApiKey(SecurityUtils.getAiUserId());
|
||||
}
|
||||
|
||||
/** 与 ai_manager.type、portal.video.function-type 对齐,用于扣费 */
|
||||
private String resolveFunctionType(PortalVideoGenRequest req) {
|
||||
if (StringUtils.isNotEmpty(req.getFunctionType())) {
|
||||
return req.getFunctionType();
|
||||
}
|
||||
if (StringUtils.isNotEmpty(portalVideoProperties.getFunctionType())) {
|
||||
return portalVideoProperties.getFunctionType();
|
||||
}
|
||||
return "21";
|
||||
}
|
||||
|
||||
private void applyOptionalParams(ByteBodyReq body, PortalVideoGenRequest req) {
|
||||
PortalVideoProperties.Defaults d = portalVideoProperties.getDefaults();
|
||||
body.setDuration(req.getDuration() != null ? req.getDuration() : d.getDuration());
|
||||
|
|
@ -97,7 +108,7 @@ public class PortalVideoController extends BaseController {
|
|||
/**
|
||||
* 写入订单:提示词、生成模式、图床 URL,以及模型/时长/分辨率/比例与完整 JSON 参数(便于对账与审计)。
|
||||
*/
|
||||
private void fillVideoOrderRecord(AiOrder aiOrder, PortalVideoGenRequest req, String mode, ByteBodyReq body) {
|
||||
private void fillVideoOrderRecord(AiOrder aiOrder, PortalVideoGenRequest req, String mode, ByteBodyReq body, String functionTypeResolved) {
|
||||
aiOrder.setText(req.getText());
|
||||
aiOrder.setMode(mode);
|
||||
applyOrderImages(aiOrder, req);
|
||||
|
|
@ -119,7 +130,7 @@ public class PortalVideoController extends BaseController {
|
|||
Map<String, Object> snap = new LinkedHashMap<>();
|
||||
snap.put("generationMode", mode);
|
||||
snap.put("prompt", req.getText());
|
||||
snap.put("functionType", StringUtils.isNotEmpty(req.getFunctionType()) ? req.getFunctionType() : "21");
|
||||
snap.put("functionType", functionTypeResolved);
|
||||
snap.put("model", body.getModel());
|
||||
snap.put("duration", body.getDuration());
|
||||
snap.put("resolution", body.getResolution());
|
||||
|
|
@ -143,13 +154,13 @@ public class PortalVideoController extends BaseController {
|
|||
}
|
||||
|
||||
private AjaxResult submitOrderAndCreate(PortalVideoGenRequest req, String mode, ByteBodyReq byteBodyReq) {
|
||||
AiOrder aiOrder = aiOrderService.getAiOrder(
|
||||
StringUtils.isNotEmpty(req.getFunctionType()) ? req.getFunctionType() : "21");
|
||||
String functionType = resolveFunctionType(req);
|
||||
AiOrder aiOrder = aiOrderService.getAiOrder(functionType);
|
||||
if (aiOrder == null) {
|
||||
return AjaxResult.error(-1, "You have a low balance, please recharge");
|
||||
}
|
||||
try {
|
||||
fillVideoOrderRecord(aiOrder, req, mode, byteBodyReq);
|
||||
fillVideoOrderRecord(aiOrder, req, mode, byteBodyReq, functionType);
|
||||
aiOrderService.updateAiOrder(aiOrder);
|
||||
|
||||
String key = apiKey();
|
||||
|
|
|
|||
|
|
@ -23,6 +23,19 @@ public class PortalVideoProperties {
|
|||
|
||||
private List<String> resolutions = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 与 ai_manager.type 一致,用于扣费与订单;库中需存在对应记录且 status=0、del_flag=0
|
||||
*/
|
||||
private String functionType = "21";
|
||||
|
||||
public String getFunctionType() {
|
||||
return functionType;
|
||||
}
|
||||
|
||||
public void setFunctionType(String functionType) {
|
||||
this.functionType = functionType != null ? functionType : "21";
|
||||
}
|
||||
|
||||
public Defaults getDefaults() {
|
||||
return defaults;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -238,6 +238,8 @@ volcengine:
|
|||
# 门户视频生成页:模型 / 比例 / 时长 / 分辨率均由此处维护,前后端不写死业务枚举
|
||||
portal:
|
||||
video:
|
||||
# 与库表 ai_manager.type 一致(用于扣费);若报错 functionType does not exist,请插入对应 type 或改此处与库一致
|
||||
function-type: "21"
|
||||
defaults:
|
||||
model: ep-20260326165811-dlkth
|
||||
duration: 4
|
||||
|
|
|
|||
|
|
@ -124,6 +124,8 @@ public class AiManagerServiceImpl implements IAiManagerService {
|
|||
public AiManager selectAiManagerByType(String aiType) {
|
||||
QueryWrapper<AiManager> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("type", aiType);
|
||||
queryWrapper.eq("del_flag", "0");
|
||||
queryWrapper.eq("status", 0);
|
||||
return aiManagerMapper.selectOne(queryWrapper);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,7 +147,9 @@ public class AiOrderServiceImpl implements IAiOrderService {
|
|||
public AiOrder getAiOrder(String aiType) {
|
||||
AiManager aiManager = aiManagerService.selectAiManagerByType(aiType);
|
||||
if (aiManager == null) {
|
||||
throw new ServiceException("Corresponding functionType does not exist", HttpStatus.BAD_REQUEST);
|
||||
throw new ServiceException(
|
||||
"未找到可用的功能类型:请在「AI管理」中新增 type=" + aiType + " 且状态为正常的记录,或执行 sql/seed_ai_manager_type_21.sql 初始化",
|
||||
HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
// 判断用户余额是否足够
|
||||
AiUser aiUser = aiUserService.selectAiUserById(SecurityUtils.getAiUserId());
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ import java.util.concurrent.TimeUnit;
|
|||
@Service
|
||||
public class ByteDeptApiKeyServiceImpl implements IByteDeptApiKeyService {
|
||||
|
||||
private static final String NO_PERM_MSG = "用户没有权限,请联系管理员分配部门";
|
||||
private static final String NO_DEPT_MSG = "用户未分配部门:请在后台为门户用户设置 ai_user.dept_id(关联 sys_dept.dept_id)";
|
||||
private static final String NO_DEPT_ROW_MSG = "用户所属部门不存在或已删除,请核对 ai_user.dept_id";
|
||||
private static final String NO_API_KEY_MSG = "部门未配置火山 API Key:请在 sys_dept 为用户所在部门(或其上级二级部门)配置 byte_api_key";
|
||||
private static final int CACHE_HOURS = 1;
|
||||
|
||||
@Autowired
|
||||
|
|
@ -31,7 +33,7 @@ public class ByteDeptApiKeyServiceImpl implements IByteDeptApiKeyService {
|
|||
@Override
|
||||
public String resolveVolcApiKey(Long aiUserId) {
|
||||
if (aiUserId == null) {
|
||||
throw new ServiceException(NO_PERM_MSG);
|
||||
throw new ServiceException(NO_DEPT_MSG);
|
||||
}
|
||||
String cacheKey = aiUserId + "_byte_api_key";
|
||||
String cached = redisCache.getCacheObject(cacheKey);
|
||||
|
|
@ -40,22 +42,34 @@ public class ByteDeptApiKeyServiceImpl implements IByteDeptApiKeyService {
|
|||
}
|
||||
AiUser aiUser = aiUserService.selectAiUserById(aiUserId);
|
||||
if (aiUser == null || aiUser.getDeptId() == null) {
|
||||
throw new ServiceException(NO_PERM_MSG);
|
||||
throw new ServiceException(NO_DEPT_MSG);
|
||||
}
|
||||
SysDept userDept = sysDeptService.selectDeptById(aiUser.getDeptId());
|
||||
if (userDept == null) {
|
||||
throw new ServiceException(NO_PERM_MSG);
|
||||
throw new ServiceException(NO_DEPT_ROW_MSG);
|
||||
}
|
||||
Long secondLevelDeptId = resolveSecondLevelDeptId(userDept);
|
||||
SysDept keyDept = sysDeptService.selectDeptById(secondLevelDeptId);
|
||||
if (keyDept == null || StringUtils.isEmpty(keyDept.getByteApiKey())) {
|
||||
throw new ServiceException(NO_PERM_MSG);
|
||||
// 优先使用用户直接归属部门的 Key;多数业务把用户挂在分公司(如 101)并在该节点配 byte_api_key
|
||||
String apiKey = trimKey(userDept.getByteApiKey());
|
||||
if (StringUtils.isEmpty(apiKey)) {
|
||||
Long fallbackDeptId = resolveSecondLevelDeptId(userDept);
|
||||
if (!fallbackDeptId.equals(userDept.getDeptId())) {
|
||||
SysDept keyDept = sysDeptService.selectDeptById(fallbackDeptId);
|
||||
if (keyDept != null) {
|
||||
apiKey = trimKey(keyDept.getByteApiKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StringUtils.isEmpty(apiKey)) {
|
||||
throw new ServiceException(NO_API_KEY_MSG);
|
||||
}
|
||||
String apiKey = keyDept.getByteApiKey().trim();
|
||||
redisCache.setCacheObject(cacheKey, apiKey, CACHE_HOURS, TimeUnit.HOURS);
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
private static String trimKey(String raw) {
|
||||
return raw == null ? null : raw.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 二级部门:祖级路径中,紧接在「一级」(ancestors 第二段)之下的部门节点;
|
||||
* 深度不足时退回用户当前部门。
|
||||
|
|
|
|||
Loading…
Reference in New Issue