Compare commits
No commits in common. "15f5a20f7ccb6314ba600be9642ece989adf5a6f" and "8a4c0f73c6f8ca7abbc31a799de2dcdd90154007" have entirely different histories.
15f5a20f7c
...
8a4c0f73c6
|
|
@ -4,7 +4,7 @@
|
|||
.gradle
|
||||
/build/
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
*.sql
|
||||
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
|
|
|
|||
|
|
@ -51,9 +51,6 @@ 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,12 @@ public class ByteApiController extends BaseController {
|
|||
return AjaxResult.error(-1, "You have a low balance, please recharge");
|
||||
}
|
||||
aiOrder.setText(text);
|
||||
aiOrder.setMode(mode); // 记录生成模式
|
||||
aiOrder.setFunctionType(mode); // 记录生成模式
|
||||
|
||||
// 文生视频模式下不设置图片
|
||||
if ("image-to-video".equals(mode) && firstUrl != null) {
|
||||
aiOrder.setImg1(firstUrl.toString());
|
||||
}
|
||||
|
||||
ByteBodyReq byteBodyReq = new ByteBodyReq();
|
||||
// model由前端传入,默认为Seedance 2.0
|
||||
|
|
|
|||
|
|
@ -1,38 +0,0 @@
|
|||
package com.ruoyi.api;
|
||||
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.utils.TencentCosUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* COS 上传兼容接口
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/cos")
|
||||
@Api(tags = "COS文件上传")
|
||||
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
||||
public class CosController {
|
||||
|
||||
private final TencentCosUtil tencentCosUtil;
|
||||
|
||||
@ApiOperation("COS上传接口")
|
||||
@PostMapping("/upload")
|
||||
public AjaxResult upload(
|
||||
@ApiParam(name = "file", value = "文件", required = true)
|
||||
@RequestParam("file") MultipartFile file) throws Exception {
|
||||
String uploadUrl = tencentCosUtil.uploadMultipartFile(file, true);
|
||||
AjaxResult ajax = AjaxResult.success(uploadUrl);
|
||||
ajax.put("url", uploadUrl);
|
||||
ajax.put("oldName", file.getOriginalFilename());
|
||||
return ajax;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,455 +0,0 @@
|
|||
package com.ruoyi.api;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.ruoyi.ai.domain.AiOrder;
|
||||
import com.ruoyi.ai.domain.ByteBodyReq;
|
||||
import com.ruoyi.ai.domain.ByteBodyRes;
|
||||
import com.ruoyi.ai.domain.ContentItem;
|
||||
import com.ruoyi.ai.domain.ImageUrl;
|
||||
import com.ruoyi.ai.domain.content;
|
||||
import com.ruoyi.ai.service.IAiOrderService;
|
||||
import com.ruoyi.ai.service.IByteDeptApiKeyService;
|
||||
import com.ruoyi.ai.service.IByteService;
|
||||
import com.ruoyi.api.request.PortalVideoGenRequest;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.TencentCosUtil;
|
||||
import com.ruoyi.config.PortalVideoProperties;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 门户视频生成:按用户二级部门 byte_api_key 调用火山;任务列表含库表与火山过滤列表。
|
||||
*/
|
||||
@Api(tags = "门户-视频生成")
|
||||
@RestController
|
||||
@RequestMapping("/api/portal/video")
|
||||
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
||||
public class PortalVideoController extends BaseController {
|
||||
|
||||
private final IByteService byteService;
|
||||
private final IByteDeptApiKeyService byteDeptApiKeyService;
|
||||
private final IAiOrderService aiOrderService;
|
||||
private final TencentCosUtil tencentCosUtil;
|
||||
private final PortalVideoProperties portalVideoProperties;
|
||||
|
||||
@Value("${volcengine.ark.callbackUrl:}")
|
||||
private String volcCallbackUrl;
|
||||
|
||||
private static final ObjectMapper OM = new ObjectMapper();
|
||||
|
||||
private String apiKey() {
|
||||
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());
|
||||
body.setResolution(StringUtils.isNotEmpty(req.getResolution()) ? req.getResolution() : d.getResolution());
|
||||
body.setRatio(StringUtils.isNotEmpty(req.getRatio()) ? req.getRatio() : d.getRatio());
|
||||
if (StringUtils.isNotEmpty(volcCallbackUrl)) {
|
||||
body.setCallback_url(volcCallbackUrl);
|
||||
}
|
||||
}
|
||||
|
||||
private ByteBodyReq newVideoBody(PortalVideoGenRequest req, List<ContentItem> content) {
|
||||
String modelId = StringUtils.isNotEmpty(req.getModel()) ? req.getModel() : portalVideoProperties.resolveDefaultModelId();
|
||||
if (StringUtils.isEmpty(modelId)) {
|
||||
throw new ServiceException("未配置门户视频模型,请在 application.yml 的 portal.video 中配置 models 与 defaults.model");
|
||||
}
|
||||
ByteBodyReq body = new ByteBodyReq();
|
||||
body.setModel(modelId);
|
||||
body.setContent(content);
|
||||
applyOptionalParams(body, req);
|
||||
return body;
|
||||
}
|
||||
|
||||
private void applyOrderImages(AiOrder aiOrder, PortalVideoGenRequest req) {
|
||||
if (StringUtils.isNotEmpty(req.getFirstUrl())) {
|
||||
aiOrder.setImg1(req.getFirstUrl());
|
||||
}
|
||||
if (StringUtils.isNotEmpty(req.getLastUrl())) {
|
||||
aiOrder.setImg2(req.getLastUrl());
|
||||
}
|
||||
if (StringUtils.isNotEmpty(req.getReferenceUrl())) {
|
||||
aiOrder.setImg1(req.getReferenceUrl());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入订单:提示词、生成模式、图床 URL,以及模型/时长/分辨率/比例与完整 JSON 参数(便于对账与审计)。
|
||||
*/
|
||||
private void fillVideoOrderRecord(AiOrder aiOrder, PortalVideoGenRequest req, String mode, ByteBodyReq body, String functionTypeResolved) {
|
||||
aiOrder.setText(req.getText());
|
||||
aiOrder.setMode(mode);
|
||||
applyOrderImages(aiOrder, req);
|
||||
if (req.getDuration() != null) {
|
||||
aiOrder.setDuration(req.getDuration());
|
||||
} else if (body.getDuration() != null) {
|
||||
aiOrder.setDuration(body.getDuration());
|
||||
}
|
||||
if (StringUtils.isNotEmpty(body.getResolution())) {
|
||||
aiOrder.setResolution(body.getResolution());
|
||||
}
|
||||
if (StringUtils.isNotEmpty(body.getRatio())) {
|
||||
aiOrder.setRatio(body.getRatio());
|
||||
}
|
||||
if (StringUtils.isNotEmpty(body.getModel())) {
|
||||
aiOrder.setModel(body.getModel());
|
||||
}
|
||||
try {
|
||||
Map<String, Object> snap = new LinkedHashMap<>();
|
||||
snap.put("generationMode", mode);
|
||||
snap.put("prompt", req.getText());
|
||||
snap.put("functionType", functionTypeResolved);
|
||||
snap.put("model", body.getModel());
|
||||
snap.put("duration", body.getDuration());
|
||||
snap.put("resolution", body.getResolution());
|
||||
snap.put("ratio", body.getRatio());
|
||||
if (StringUtils.isNotEmpty(req.getFirstUrl())) {
|
||||
snap.put("firstUrl", req.getFirstUrl());
|
||||
}
|
||||
if (StringUtils.isNotEmpty(req.getLastUrl())) {
|
||||
snap.put("lastUrl", req.getLastUrl());
|
||||
}
|
||||
if (StringUtils.isNotEmpty(req.getReferenceUrl())) {
|
||||
snap.put("referenceUrl", req.getReferenceUrl());
|
||||
}
|
||||
if (req.getContent() != null && !req.getContent().isEmpty()) {
|
||||
snap.put("content", req.getContent());
|
||||
}
|
||||
aiOrder.setVideoParams(OM.writeValueAsString(snap));
|
||||
} catch (Exception e) {
|
||||
aiOrder.setVideoParams("{\"error\":\"video_params_serialize_failed\"}");
|
||||
}
|
||||
}
|
||||
|
||||
/** 写入 video_params.volcTaskId,任务成功后 result 会改为成品 URL,仍应用此 id 校验归属与轮询 */
|
||||
private void mergeVolcTaskIdIntoVideoParams(AiOrder aiOrder, String volcTaskId) {
|
||||
if (StringUtils.isEmpty(volcTaskId)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ObjectNode node;
|
||||
if (StringUtils.isNotEmpty(aiOrder.getVideoParams())) {
|
||||
JsonNode existing = OM.readTree(aiOrder.getVideoParams());
|
||||
if (existing instanceof ObjectNode) {
|
||||
node = (ObjectNode) existing;
|
||||
} else {
|
||||
node = OM.createObjectNode();
|
||||
node.set("snapshotBeforeVolcId", existing);
|
||||
}
|
||||
} else {
|
||||
node = OM.createObjectNode();
|
||||
}
|
||||
node.put("volcTaskId", volcTaskId);
|
||||
aiOrder.setVideoParams(OM.writeValueAsString(node));
|
||||
} catch (Exception e) {
|
||||
aiOrder.setVideoParams("{\"volcTaskId\":\"" + volcTaskId.replace("\"", "") + "\"}");
|
||||
}
|
||||
}
|
||||
|
||||
private AjaxResult submitOrderAndCreate(PortalVideoGenRequest req, String mode, ByteBodyReq byteBodyReq) {
|
||||
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, functionType);
|
||||
aiOrderService.updateAiOrder(aiOrder);
|
||||
|
||||
String key = apiKey();
|
||||
ByteBodyRes byteBodyRes = byteService.imgToVideo(byteBodyReq, key);
|
||||
String id = byteBodyRes.getId();
|
||||
if (id == null) {
|
||||
aiOrderService.orderFailure(aiOrder);
|
||||
return AjaxResult.error(-2, "generation failed, balance has been refunded");
|
||||
}
|
||||
mergeVolcTaskIdIntoVideoParams(aiOrder, id);
|
||||
aiOrder.setResult(id);
|
||||
aiOrderService.orderSuccess(aiOrder);
|
||||
return AjaxResult.success(byteBodyRes);
|
||||
} catch (Exception e) {
|
||||
aiOrderService.orderFailure(aiOrder);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/text-to-video")
|
||||
@ApiOperation("文生视频")
|
||||
public AjaxResult textToVideo(@RequestBody PortalVideoGenRequest request) {
|
||||
List<ContentItem> contentList;
|
||||
if (request.getContent() != null && !request.getContent().isEmpty()) {
|
||||
contentList = request.getContent();
|
||||
} else {
|
||||
if (StringUtils.isEmpty(request.getText())) {
|
||||
return AjaxResult.error("请输入视频描述文本");
|
||||
}
|
||||
contentList = new ArrayList<>();
|
||||
ContentItem textItem = new ContentItem();
|
||||
textItem.setType("text");
|
||||
textItem.setText(request.getText());
|
||||
contentList.add(textItem);
|
||||
}
|
||||
|
||||
ByteBodyReq body = newVideoBody(request, contentList);
|
||||
return submitOrderAndCreate(request, "text-to-video", body);
|
||||
}
|
||||
|
||||
@PostMapping("/image-first-frame")
|
||||
@ApiOperation("图生视频-基于首帧")
|
||||
public AjaxResult imageFirstFrame(@RequestBody PortalVideoGenRequest request) {
|
||||
if (StringUtils.isEmpty(request.getFirstUrl())) {
|
||||
return AjaxResult.error("请上传首帧图片");
|
||||
}
|
||||
if (StringUtils.isEmpty(request.getText())) {
|
||||
return AjaxResult.error("请输入视频描述文本");
|
||||
}
|
||||
List<ContentItem> contentList = buildTextAndFirstFrame(request.getText(), request.getFirstUrl());
|
||||
ByteBodyReq body = newVideoBody(request, contentList);
|
||||
return submitOrderAndCreate(request, "image-first-frame", body);
|
||||
}
|
||||
|
||||
@PostMapping("/image-first-last-frame")
|
||||
@ApiOperation("图生视频-基于首尾帧")
|
||||
public AjaxResult imageFirstLastFrame(@RequestBody PortalVideoGenRequest request) {
|
||||
if (StringUtils.isEmpty(request.getFirstUrl()) || StringUtils.isEmpty(request.getLastUrl())) {
|
||||
return AjaxResult.error("请同时上传首帧与尾帧图片");
|
||||
}
|
||||
if (StringUtils.isEmpty(request.getText())) {
|
||||
return AjaxResult.error("请输入视频描述文本");
|
||||
}
|
||||
List<ContentItem> contentList = buildTextAndFirstFrame(request.getText(), request.getFirstUrl());
|
||||
ContentItem lastFrameItem = new ContentItem();
|
||||
lastFrameItem.setType("image_url");
|
||||
lastFrameItem.setRole("last_frame");
|
||||
ImageUrl lastImageUrl = new ImageUrl();
|
||||
lastImageUrl.setUrl(request.getLastUrl());
|
||||
lastFrameItem.setImageUrl(lastImageUrl);
|
||||
contentList.add(lastFrameItem);
|
||||
|
||||
ByteBodyReq body = newVideoBody(request, contentList);
|
||||
return submitOrderAndCreate(request, "image-first-last-frame", body);
|
||||
}
|
||||
|
||||
@PostMapping("/image-reference")
|
||||
@ApiOperation("图生视频-基于参考图")
|
||||
public AjaxResult imageReference(@RequestBody PortalVideoGenRequest request) {
|
||||
List<ContentItem> contentList;
|
||||
if (request.getContent() != null && !request.getContent().isEmpty()) {
|
||||
contentList = request.getContent();
|
||||
ContentItem head = contentList.get(0);
|
||||
if (head == null || !"text".equals(head.getType()) || StringUtils.isEmpty(head.getText())) {
|
||||
return AjaxResult.error("请输入视频描述文本(首条须为 type=text,可含 [图n] 占位)");
|
||||
}
|
||||
String firstRef = contentList.stream()
|
||||
.filter(PortalVideoController::isReferenceImageContentItem)
|
||||
.map(it -> it.getImageUrl().getUrl())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (StringUtils.isEmpty(firstRef)) {
|
||||
return AjaxResult.error("请上传参考图(content 中须含 image_url + role=reference_image)");
|
||||
}
|
||||
if (StringUtils.isEmpty(request.getReferenceUrl())) {
|
||||
request.setReferenceUrl(firstRef);
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.isEmpty(request.getReferenceUrl())) {
|
||||
return AjaxResult.error("请上传参考图");
|
||||
}
|
||||
if (StringUtils.isEmpty(request.getText())) {
|
||||
return AjaxResult.error("请输入视频描述文本");
|
||||
}
|
||||
contentList = new ArrayList<>();
|
||||
ContentItem textItem = new ContentItem();
|
||||
textItem.setType("text");
|
||||
textItem.setText(request.getText());
|
||||
contentList.add(textItem);
|
||||
|
||||
ContentItem refItem = new ContentItem();
|
||||
refItem.setType("image_url");
|
||||
refItem.setRole("reference_image");
|
||||
ImageUrl refUrl = new ImageUrl();
|
||||
refUrl.setUrl(request.getReferenceUrl());
|
||||
refItem.setImageUrl(refUrl);
|
||||
contentList.add(refItem);
|
||||
}
|
||||
|
||||
ByteBodyReq body = newVideoBody(request, contentList);
|
||||
return submitOrderAndCreate(request, "image-reference", body);
|
||||
}
|
||||
|
||||
private static boolean isReferenceImageContentItem(ContentItem item) {
|
||||
if (item == null || !"image_url".equals(item.getType())) {
|
||||
return false;
|
||||
}
|
||||
if (!"reference_image".equals(item.getRole())) {
|
||||
return false;
|
||||
}
|
||||
ImageUrl iu = item.getImageUrl();
|
||||
return iu != null && StringUtils.isNotEmpty(iu.getUrl());
|
||||
}
|
||||
|
||||
private List<ContentItem> buildTextAndFirstFrame(String text, String firstUrl) {
|
||||
List<ContentItem> contentList = new ArrayList<>();
|
||||
ContentItem textItem = new ContentItem();
|
||||
textItem.setType("text");
|
||||
textItem.setText(text);
|
||||
contentList.add(textItem);
|
||||
|
||||
ContentItem firstFrameItem = new ContentItem();
|
||||
firstFrameItem.setType("image_url");
|
||||
firstFrameItem.setRole("first_frame");
|
||||
ImageUrl firstImageUrl = new ImageUrl();
|
||||
firstImageUrl.setUrl(firstUrl);
|
||||
firstFrameItem.setImageUrl(firstImageUrl);
|
||||
contentList.add(firstFrameItem);
|
||||
return contentList;
|
||||
}
|
||||
|
||||
@GetMapping("/options")
|
||||
@ApiOperation("门户视频生成可选参数(模型/比例/时长等,来自配置)")
|
||||
public AjaxResult videoParamOptions() {
|
||||
Map<String, Object> data = new LinkedHashMap<>();
|
||||
data.put("defaults", portalVideoProperties.getDefaults());
|
||||
data.put("models", portalVideoProperties.getModels());
|
||||
data.put("ratios", portalVideoProperties.getRatios());
|
||||
data.put("durations", portalVideoProperties.getDurations());
|
||||
data.put("resolutions", portalVideoProperties.getResolutions());
|
||||
return AjaxResult.success(data);
|
||||
}
|
||||
|
||||
@GetMapping("/tasks")
|
||||
@ApiOperation("查询视频生成任务列表(本用户库表分页)")
|
||||
public TableDataInfo listMyVideoTasks(AiOrder aiOrder) {
|
||||
aiOrder.setUserId(SecurityUtils.getAiUserId());
|
||||
aiOrder.setType("21");
|
||||
startPage();
|
||||
List<AiOrder> list = aiOrderService.selectAiOrderList(aiOrder);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@GetMapping("/volc-tasks")
|
||||
@ApiOperation("查询视频生成任务列表(火山平台,按本用户在库中的任务 id 过滤)")
|
||||
public AjaxResult listVolcTasks(
|
||||
@RequestParam(defaultValue = "1") int pageNum,
|
||||
@RequestParam(defaultValue = "20") int pageSize) throws Exception {
|
||||
Long uid = SecurityUtils.getAiUserId();
|
||||
String key = apiKey();
|
||||
String raw = byteService.listVideoGenerationTasks(pageNum, pageSize, key);
|
||||
String filtered = filterVolcTasksJsonForUser(raw, uid);
|
||||
return AjaxResult.success(OM.readTree(filtered));
|
||||
}
|
||||
|
||||
private String filterVolcTasksJsonForUser(String raw, Long userId) throws Exception {
|
||||
AiOrder query = new AiOrder();
|
||||
query.setUserId(userId);
|
||||
query.setType("21");
|
||||
List<AiOrder> mine = aiOrderService.selectAiOrderList(query);
|
||||
Set<String> allowed = mine.stream()
|
||||
.map(AiOrder::getResult)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
JsonNode root = OM.readTree(raw);
|
||||
if (!(root instanceof ObjectNode)) {
|
||||
return raw;
|
||||
}
|
||||
ArrayNode arr = null;
|
||||
String arrayKey = null;
|
||||
if (root.has("items") && root.get("items").isArray()) {
|
||||
arr = (ArrayNode) root.get("items");
|
||||
arrayKey = "items";
|
||||
} else if (root.has("data") && root.get("data").isArray()) {
|
||||
arr = (ArrayNode) root.get("data");
|
||||
arrayKey = "data";
|
||||
}
|
||||
if (arr == null) {
|
||||
return raw;
|
||||
}
|
||||
ArrayNode out = OM.createArrayNode();
|
||||
for (JsonNode n : arr) {
|
||||
String tid = n.has("id") ? n.get("id").asText() : null;
|
||||
if (tid != null && allowed.contains(tid)) {
|
||||
out.add(n);
|
||||
}
|
||||
}
|
||||
ObjectNode result = ((ObjectNode) root).deepCopy();
|
||||
result.set(arrayKey, out);
|
||||
result.put("filtered_total", out.size());
|
||||
return OM.writeValueAsString(result);
|
||||
}
|
||||
|
||||
@GetMapping("/tasks/{taskId}")
|
||||
@ApiOperation("查询单个视频生成任务(火山)")
|
||||
public AjaxResult getVolcTask(@PathVariable String taskId) throws Exception {
|
||||
Long uid = SecurityUtils.getAiUserId();
|
||||
AiOrder owned = aiOrderService.getAiOrderByPortalVideoTask(taskId);
|
||||
if (owned == null || !uid.equals(owned.getUserId())) {
|
||||
return AjaxResult.error("无权查看该任务");
|
||||
}
|
||||
String key = apiKey();
|
||||
ByteBodyRes byteBodyRes = byteService.uploadVideo(taskId, key);
|
||||
if ("succeeded".equals(byteBodyRes.getStatus())) {
|
||||
content contentObj = byteBodyRes.getContent();
|
||||
if (contentObj != null && StringUtils.isNotEmpty(contentObj.getVideo_url())) {
|
||||
String videoUrl = tencentCosUtil.uploadFileByUrl(contentObj.getVideo_url());
|
||||
if (videoUrl != null) {
|
||||
contentObj.setVideo_url(videoUrl);
|
||||
AiOrder aiOrder = new AiOrder();
|
||||
aiOrder.setId(owned.getId());
|
||||
aiOrder.setResult(videoUrl);
|
||||
aiOrderService.updateAiOrder(aiOrder);
|
||||
}
|
||||
}
|
||||
}
|
||||
return AjaxResult.success(byteBodyRes);
|
||||
}
|
||||
|
||||
@DeleteMapping("/tasks/{taskId}")
|
||||
@ApiOperation("删除或取消视频生成任务")
|
||||
public AjaxResult deleteOrCancelTask(@PathVariable String taskId) throws Exception {
|
||||
Long uid = SecurityUtils.getAiUserId();
|
||||
AiOrder owned = aiOrderService.getAiOrderByPortalVideoTask(taskId);
|
||||
if (owned == null || !uid.equals(owned.getUserId())) {
|
||||
return AjaxResult.error("无权操作该任务");
|
||||
}
|
||||
String key = apiKey();
|
||||
AjaxResult cancelRes = byteService.cancelVideoTask(taskId, key);
|
||||
if (cancelRes.isSuccess() && owned.getStatus() != null && owned.getStatus() == 0) {
|
||||
aiOrderService.orderFailure(owned);
|
||||
}
|
||||
return cancelRes;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
package com.ruoyi.api.request;
|
||||
|
||||
import com.ruoyi.ai.domain.ContentItem;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 门户视频生成(火山 Seedance)请求体
|
||||
*/
|
||||
@Data
|
||||
public class PortalVideoGenRequest {
|
||||
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* 文生视频时可选:多段文本 + 参考图(与火山 content 一致);不传则仅使用 text 单行
|
||||
*/
|
||||
private List<ContentItem> content;
|
||||
|
||||
/** 默认与后台配置的视频计费类型一致 */
|
||||
private String functionType = "21";
|
||||
|
||||
private String model;
|
||||
|
||||
private Integer duration;
|
||||
|
||||
private String resolution;
|
||||
|
||||
private String ratio;
|
||||
|
||||
private String firstUrl;
|
||||
|
||||
private String lastUrl;
|
||||
|
||||
/** 图生视频-参考图模式 */
|
||||
private String referenceUrl;
|
||||
}
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
package com.ruoyi.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 门户视频生成参数(模型、比例、时长、分辨率等从配置读取,不在代码中写死业务默认值)。
|
||||
*/
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "portal.video")
|
||||
public class PortalVideoProperties {
|
||||
|
||||
private Defaults defaults = new Defaults();
|
||||
|
||||
private List<ModelOption> models = new ArrayList<>();
|
||||
|
||||
private List<String> ratios = new ArrayList<>();
|
||||
|
||||
private List<Integer> durations = new ArrayList<>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public void setDefaults(Defaults defaults) {
|
||||
if (defaults != null) {
|
||||
this.defaults = defaults;
|
||||
}
|
||||
}
|
||||
|
||||
public List<ModelOption> getModels() {
|
||||
return models;
|
||||
}
|
||||
|
||||
public void setModels(List<ModelOption> models) {
|
||||
this.models = models != null ? models : new ArrayList<>();
|
||||
}
|
||||
|
||||
public List<String> getRatios() {
|
||||
return ratios;
|
||||
}
|
||||
|
||||
public void setRatios(List<String> ratios) {
|
||||
this.ratios = ratios != null ? ratios : new ArrayList<>();
|
||||
}
|
||||
|
||||
public List<Integer> getDurations() {
|
||||
return durations;
|
||||
}
|
||||
|
||||
public void setDurations(List<Integer> durations) {
|
||||
this.durations = durations != null ? durations : new ArrayList<>();
|
||||
}
|
||||
|
||||
public List<String> getResolutions() {
|
||||
return resolutions;
|
||||
}
|
||||
|
||||
public void setResolutions(List<String> resolutions) {
|
||||
this.resolutions = resolutions != null ? resolutions : new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* defaults.model 为空时,取 models 第一项的 value。
|
||||
*/
|
||||
public String resolveDefaultModelId() {
|
||||
if (defaults.getModel() != null && !defaults.getModel().isEmpty()) {
|
||||
return defaults.getModel();
|
||||
}
|
||||
if (!models.isEmpty() && models.get(0).getValue() != null) {
|
||||
return models.get(0).getValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class Defaults {
|
||||
private String model;
|
||||
private Integer duration;
|
||||
private String resolution;
|
||||
private String ratio;
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public void setModel(String model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public Integer getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public void setDuration(Integer duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public String getResolution() {
|
||||
return resolution;
|
||||
}
|
||||
|
||||
public void setResolution(String resolution) {
|
||||
this.resolution = resolution;
|
||||
}
|
||||
|
||||
public String getRatio() {
|
||||
return ratio;
|
||||
}
|
||||
|
||||
public void setRatio(String ratio) {
|
||||
this.ratio = ratio;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ModelOption {
|
||||
private String label;
|
||||
private String value;
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
package com.ruoyi.web.controller.ai;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.ai.service.IAiUserService;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.constant.UserConstants;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.system.service.ISysDeptService;
|
||||
|
||||
/**
|
||||
* AI 业务侧部门管理(数据源与系统部门 sys_dept 一致,权限独立)
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/ai/dept")
|
||||
public class AiDeptController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ISysDeptService deptService;
|
||||
|
||||
@Autowired
|
||||
private IAiUserService aiUserService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('ai:dept:list')")
|
||||
@GetMapping("/list")
|
||||
public AjaxResult list(SysDept dept)
|
||||
{
|
||||
List<SysDept> depts = deptService.selectDeptList(dept);
|
||||
return success(depts);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('ai:dept:list')")
|
||||
@GetMapping("/list/exclude/{deptId}")
|
||||
public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId)
|
||||
{
|
||||
List<SysDept> depts = deptService.selectDeptList(new SysDept());
|
||||
depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + ""));
|
||||
return success(depts);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('ai:dept:query')")
|
||||
@GetMapping(value = "/{deptId}")
|
||||
public AjaxResult getInfo(@PathVariable Long deptId)
|
||||
{
|
||||
deptService.checkDeptDataScope(deptId);
|
||||
return success(deptService.selectDeptById(deptId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('ai:dept:add')")
|
||||
@Log(title = "AI部门管理", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@Validated @RequestBody SysDept dept)
|
||||
{
|
||||
if (!deptService.checkDeptNameUnique(dept))
|
||||
{
|
||||
return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
|
||||
}
|
||||
dept.setCreateBy(getUsername());
|
||||
return toAjax(deptService.insertDept(dept));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('ai:dept:edit')")
|
||||
@Log(title = "AI部门管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@Validated @RequestBody SysDept dept)
|
||||
{
|
||||
Long deptId = dept.getDeptId();
|
||||
deptService.checkDeptDataScope(deptId);
|
||||
if (!deptService.checkDeptNameUnique(dept))
|
||||
{
|
||||
return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
|
||||
}
|
||||
else if (dept.getParentId().equals(deptId))
|
||||
{
|
||||
return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
|
||||
}
|
||||
else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0)
|
||||
{
|
||||
return error("该部门包含未停用的子部门!");
|
||||
}
|
||||
dept.setUpdateBy(getUsername());
|
||||
return toAjax(deptService.updateDept(dept));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('ai:dept:remove')")
|
||||
@Log(title = "AI部门管理", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{deptId}")
|
||||
public AjaxResult remove(@PathVariable Long deptId)
|
||||
{
|
||||
if (deptService.hasChildByDeptId(deptId))
|
||||
{
|
||||
return warn("存在下级部门,不允许删除");
|
||||
}
|
||||
if (deptService.checkDeptExistUser(deptId))
|
||||
{
|
||||
return warn("部门存在系统用户,不允许删除");
|
||||
}
|
||||
if (aiUserService.countAiUserByDeptId(deptId) > 0)
|
||||
{
|
||||
return warn("部门存在 AI 用户,不允许删除");
|
||||
}
|
||||
deptService.checkDeptDataScope(deptId);
|
||||
return toAjax(deptService.deleteDeptById(deptId));
|
||||
}
|
||||
}
|
||||
|
|
@ -93,20 +93,6 @@ public class AiUserController extends BaseController {
|
|||
return toAjax(aiUserService.updateAiUser(aiUser));
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配归属部门(deptId 为空表示不归属任何部门)
|
||||
*/
|
||||
@ApiOperation("分配AI用户归属部门")
|
||||
@PreAuthorize("@ss.hasPermi('ai:user:edit')")
|
||||
@Log(title = "ai-用户信息", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/dept")
|
||||
public AjaxResult assignDept(@RequestBody AiUser aiUser) {
|
||||
if (aiUser.getId() == null) {
|
||||
return error("用户主键不能为空");
|
||||
}
|
||||
return toAjax(aiUserService.updateAiUserDept(aiUser.getId(), aiUser.getDeptId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态修改
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -235,42 +235,6 @@ volcengine:
|
|||
apiKey: 3e33e034-7e25-4228-8864-b51b2a7a8f97
|
||||
callbackUrl: https://undressing.top/api/ai/volcCallback
|
||||
|
||||
# 门户视频生成页:模型 / 比例 / 时长 / 分辨率均由此处维护,前后端不写死业务枚举
|
||||
portal:
|
||||
video:
|
||||
# 与库表 ai_manager.type 一致(用于扣费);若报错 functionType does not exist,请插入对应 type 或改此处与库一致
|
||||
function-type: "21"
|
||||
defaults:
|
||||
model: ep-20260326165811-dlkth
|
||||
duration: 4
|
||||
resolution: 720p
|
||||
ratio: "3:4"
|
||||
models:
|
||||
- label: Seedance 2.0
|
||||
value: ep-20260326165811-dlkth
|
||||
- label: Seedance 2.0 Fast
|
||||
value: ep-20260326170056-dkj9m
|
||||
ratios:
|
||||
- "16:9"
|
||||
- "9:16"
|
||||
- "3:4"
|
||||
- "1:1"
|
||||
- "4:3"
|
||||
durations:
|
||||
- 4
|
||||
- 5
|
||||
- 6
|
||||
- 8
|
||||
- 10
|
||||
- 11
|
||||
- 12
|
||||
- 13
|
||||
- 14
|
||||
- 15
|
||||
resolutions:
|
||||
- "720p"
|
||||
- "1080p"
|
||||
|
||||
jinsha:
|
||||
url: https://api.jinshapay.xyz
|
||||
appId: 1763617360
|
||||
|
|
|
|||
|
|
@ -117,19 +117,12 @@ public class AiUser extends BaseEntity {
|
|||
*/
|
||||
private String country;
|
||||
|
||||
/** 归属部门ID(sys_dept.dept_id) */
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 上级用户昵称
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String superiorName;
|
||||
|
||||
/** 归属部门名称 */
|
||||
@TableField(exist = false)
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 上级用户ID
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -52,9 +52,6 @@ public class SysDept extends BaseEntity
|
|||
/** 父部门名称 */
|
||||
private String parentName;
|
||||
|
||||
/** Byte API Key */
|
||||
private String byteApiKey;
|
||||
|
||||
/** 子部门 */
|
||||
private List<SysDept> children = new ArrayList<SysDept>();
|
||||
|
||||
|
|
@ -174,16 +171,6 @@ public class SysDept extends BaseEntity
|
|||
this.parentName = parentName;
|
||||
}
|
||||
|
||||
public String getByteApiKey()
|
||||
{
|
||||
return byteApiKey;
|
||||
}
|
||||
|
||||
public void setByteApiKey(String byteApiKey)
|
||||
{
|
||||
this.byteApiKey = byteApiKey;
|
||||
}
|
||||
|
||||
public List<SysDept> getChildren()
|
||||
{
|
||||
return children;
|
||||
|
|
@ -205,7 +192,6 @@ public class SysDept extends BaseEntity
|
|||
.append("leader", getLeader())
|
||||
.append("phone", getPhone())
|
||||
.append("email", getEmail())
|
||||
.append("byteApiKey", getByteApiKey())
|
||||
.append("status", getStatus())
|
||||
.append("delFlag", getDelFlag())
|
||||
.append("createBy", getCreateBy())
|
||||
|
|
|
|||
|
|
@ -84,12 +84,6 @@ public class AiOrder extends BaseEntity {
|
|||
@Excel(name = "宽高比")
|
||||
private String ratio;
|
||||
|
||||
/** 火山/方舟模型 endpoint */
|
||||
private String model;
|
||||
|
||||
/** 视频类订单:本次提交的完整参数 JSON(提示词、模型、时长等) */
|
||||
private String videoParams;
|
||||
|
||||
/** 首帧图片 */
|
||||
private String img1;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,5 @@ public interface AiOrderMapper extends BaseMapper<AiOrder> {
|
|||
|
||||
AiOrder getAiOrderByResult(@Param("result") String result);
|
||||
|
||||
/** 门户视频:按火山任务 id 查单(result 可能已被替换为成品 URL,故兼查 video_params.volcTaskId) */
|
||||
AiOrder getAiOrderByPortalVideoTask(@Param("taskId") String taskId);
|
||||
|
||||
BigDecimal getSumAmountByUserId(@Param("userId") String userId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import java.util.List;
|
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.ruoyi.common.core.domain.entity.AiUser;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
/**
|
||||
* ai-用户信息Mapper接口
|
||||
|
|
@ -23,9 +22,4 @@ public interface AiUserMapper extends BaseMapper<AiUser> {
|
|||
|
||||
AiUser selectAiUserById(Long id);
|
||||
AiUser getUserInfo(Long id);
|
||||
|
||||
int countAiUserByDeptId(@Param("deptId") Long deptId);
|
||||
|
||||
@Update("update ai_user set dept_id = #{deptId}, update_time = sysdate() where id = #{userId}")
|
||||
int updateAiUserDeptId(@Param("userId") Long userId, @Param("deptId") Long deptId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,5 @@ public interface IAiOrderService {
|
|||
|
||||
AiOrder getAiOrderByResult(String result);
|
||||
|
||||
AiOrder getAiOrderByPortalVideoTask(String taskId);
|
||||
|
||||
BigDecimal getSumAmountByUserId(String userId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,16 +99,6 @@ public interface IAiUserService {
|
|||
|
||||
int updatePassword(AiUser aiUser);
|
||||
|
||||
/**
|
||||
* 部门下 AI 用户数量(用于删除部门前校验)
|
||||
*/
|
||||
int countAiUserByDeptId(Long deptId);
|
||||
|
||||
/**
|
||||
* 分配 AI 用户归属部门,deptId 为空则清空
|
||||
*/
|
||||
int updateAiUserDept(Long userId, Long deptId);
|
||||
|
||||
public void deductSampleAmount(String userId);
|
||||
|
||||
void handleRebate(String orderNo, Long userId, BigDecimal rechargeAmount);
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
package com.ruoyi.ai.service;
|
||||
|
||||
/**
|
||||
* 门户用户火山方舟 API Key:取自所属二级部门 {@code sys_dept.byte_api_key},带 Redis 缓存。
|
||||
*/
|
||||
public interface IByteDeptApiKeyService {
|
||||
|
||||
/**
|
||||
* Redis 键:{userId}_byte_api_key,优先读缓存,再读库;均无有效 key 则抛出业务异常。
|
||||
*/
|
||||
String resolveVolcApiKey(Long aiUserId);
|
||||
}
|
||||
|
|
@ -17,31 +17,17 @@ public interface IByteService {
|
|||
ByteBodyRes imgToImg(ByteBodyReq req) throws Exception;
|
||||
|
||||
/**
|
||||
* 首尾帧图生视频(使用全局配置的 Ark API Key)
|
||||
* 首尾帧图生视频
|
||||
*/
|
||||
ByteBodyRes imgToVideo(ByteBodyReq req) throws Exception;
|
||||
|
||||
/**
|
||||
* 视频生成任务创建(指定 Ark API Key,门户按部门密钥调用)
|
||||
*/
|
||||
ByteBodyRes imgToVideo(ByteBodyReq req, String arkApiKey) throws Exception;
|
||||
|
||||
/**
|
||||
* 下载视频
|
||||
*/
|
||||
ByteBodyRes uploadVideo(String id) throws Exception;
|
||||
|
||||
ByteBodyRes uploadVideo(String id, String arkApiKey) throws Exception;
|
||||
|
||||
/**
|
||||
* 取消视频生成任务
|
||||
*/
|
||||
AjaxResult cancelVideoTask(String id) throws Exception;
|
||||
|
||||
AjaxResult cancelVideoTask(String id, String arkApiKey) throws Exception;
|
||||
|
||||
/**
|
||||
* GET 查询视频生成任务列表(火山 list 文档),返回原始 JSON 字符串
|
||||
*/
|
||||
String listVideoGenerationTasks(int pageNum, int pageSize, String arkApiKey) throws Exception;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,8 +124,6 @@ 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,9 +147,7 @@ public class AiOrderServiceImpl implements IAiOrderService {
|
|||
public AiOrder getAiOrder(String aiType) {
|
||||
AiManager aiManager = aiManagerService.selectAiManagerByType(aiType);
|
||||
if (aiManager == null) {
|
||||
throw new ServiceException(
|
||||
"未找到可用的功能类型:请在「AI管理」中新增 type=" + aiType + " 且状态为正常的记录,或执行 sql/seed_ai_manager_type_21.sql 初始化",
|
||||
HttpStatus.BAD_REQUEST);
|
||||
throw new ServiceException("Corresponding functionType does not exist", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
// 判断用户余额是否足够
|
||||
AiUser aiUser = aiUserService.selectAiUserById(SecurityUtils.getAiUserId());
|
||||
|
|
@ -203,11 +201,6 @@ public class AiOrderServiceImpl implements IAiOrderService {
|
|||
return aiOrderMapper.selectOne(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AiOrder getAiOrderByPortalVideoTask(String taskId) {
|
||||
return aiOrderMapper.getAiOrderByPortalVideoTask(taskId);
|
||||
}
|
||||
|
||||
public int getChangerType(String aiType) {
|
||||
switch (aiType) {
|
||||
case "11":
|
||||
|
|
|
|||
|
|
@ -132,19 +132,6 @@ public class AiUserServiceImpl implements IAiUserService {
|
|||
return aiUserMapper.updateById(aiUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countAiUserByDeptId(Long deptId) {
|
||||
if (deptId == null) {
|
||||
return 0;
|
||||
}
|
||||
return aiUserMapper.countAiUserByDeptId(deptId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateAiUserDept(Long userId, Long deptId) {
|
||||
return aiUserMapper.updateAiUserDeptId(userId, deptId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除ai-用户信息
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,99 +0,0 @@
|
|||
package com.ruoyi.ai.service.impl;
|
||||
|
||||
import com.ruoyi.ai.service.IByteDeptApiKeyService;
|
||||
import com.ruoyi.ai.service.IAiUserService;
|
||||
import com.ruoyi.common.core.domain.entity.AiUser;
|
||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
||||
import com.ruoyi.common.core.redis.RedisCache;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.system.service.ISysDeptService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Service
|
||||
public class ByteDeptApiKeyServiceImpl implements IByteDeptApiKeyService {
|
||||
|
||||
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
|
||||
private RedisCache redisCache;
|
||||
|
||||
@Autowired
|
||||
private IAiUserService aiUserService;
|
||||
|
||||
@Autowired
|
||||
private ISysDeptService sysDeptService;
|
||||
|
||||
@Override
|
||||
public String resolveVolcApiKey(Long aiUserId) {
|
||||
if (aiUserId == null) {
|
||||
throw new ServiceException(NO_DEPT_MSG);
|
||||
}
|
||||
String cacheKey = aiUserId + "_byte_api_key";
|
||||
String cached = redisCache.getCacheObject(cacheKey);
|
||||
if (StringUtils.isNotEmpty(cached)) {
|
||||
return cached;
|
||||
}
|
||||
AiUser aiUser = aiUserService.selectAiUserById(aiUserId);
|
||||
if (aiUser == null || aiUser.getDeptId() == null) {
|
||||
throw new ServiceException(NO_DEPT_MSG);
|
||||
}
|
||||
SysDept userDept = sysDeptService.selectDeptById(aiUser.getDeptId());
|
||||
if (userDept == null) {
|
||||
throw new ServiceException(NO_DEPT_ROW_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);
|
||||
}
|
||||
redisCache.setCacheObject(cacheKey, apiKey, CACHE_HOURS, TimeUnit.HOURS);
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
private static String trimKey(String raw) {
|
||||
return raw == null ? null : raw.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 二级部门:祖级路径中,紧接在「一级」(ancestors 第二段)之下的部门节点;
|
||||
* 深度不足时退回用户当前部门。
|
||||
*/
|
||||
private Long resolveSecondLevelDeptId(SysDept userDept) {
|
||||
String ancestors = userDept.getAncestors();
|
||||
if (StringUtils.isEmpty(ancestors)) {
|
||||
return userDept.getDeptId();
|
||||
}
|
||||
String[] parts = ancestors.split(",");
|
||||
if (parts.length >= 3) {
|
||||
try {
|
||||
return Long.parseLong(parts[2].trim());
|
||||
} catch (NumberFormatException ignored) {
|
||||
return userDept.getDeptId();
|
||||
}
|
||||
}
|
||||
if (parts.length == 2) {
|
||||
try {
|
||||
return Long.parseLong(parts[1].trim());
|
||||
} catch (NumberFormatException ignored) {
|
||||
return userDept.getDeptId();
|
||||
}
|
||||
}
|
||||
return userDept.getDeptId();
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,6 @@ import com.ruoyi.ai.service.IByteService;
|
|||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.http.OkHttpUtils;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.*;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
|
@ -84,24 +83,17 @@ public class ByteService implements IByteService {
|
|||
|
||||
@Override
|
||||
public ByteBodyRes imgToVideo(ByteBodyReq req) throws Exception {
|
||||
return imgToVideo(req, volcApiKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBodyRes imgToVideo(ByteBodyReq req, String arkApiKey) throws Exception {
|
||||
if (req == null) {
|
||||
throw new Exception("imgToVideo error:req is null");
|
||||
}
|
||||
if (StringUtils.isBlank(arkApiKey)) {
|
||||
throw new Exception("imgToVideo error:apiKey is null");
|
||||
}
|
||||
|
||||
// 使用火山引擎配置
|
||||
String jsonBody = objectMapper.writeValueAsString(req);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(volcBaseUrl + "/api/v3/contents/generations/tasks")
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Authorization", "Bearer " + arkApiKey)
|
||||
.header("Authorization", "Bearer " + volcApiKey)
|
||||
.post(RequestBody.create(
|
||||
MediaType.parse("application/json; charset=utf-8"),
|
||||
jsonBody
|
||||
|
|
@ -125,22 +117,15 @@ public class ByteService implements IByteService {
|
|||
|
||||
@Override
|
||||
public ByteBodyRes uploadVideo(String id) throws Exception {
|
||||
return uploadVideo(id, volcApiKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBodyRes uploadVideo(String id, String arkApiKey) throws Exception {
|
||||
if (StringUtils.isBlank(id)) {
|
||||
throw new Exception("uploadVideo error:id is null");
|
||||
}
|
||||
if (StringUtils.isBlank(arkApiKey)) {
|
||||
throw new Exception("uploadVideo error:apiKey is null");
|
||||
}
|
||||
|
||||
// 使用火山引擎配置查询任务状态
|
||||
Request request = new Request.Builder()
|
||||
.url(volcBaseUrl + "/api/v3/contents/generations/tasks/" + id)
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Authorization", "Bearer " + arkApiKey)
|
||||
.header("Authorization", "Bearer " + volcApiKey)
|
||||
.get()
|
||||
.build();
|
||||
|
||||
|
|
@ -161,23 +146,16 @@ public class ByteService implements IByteService {
|
|||
|
||||
@Override
|
||||
public AjaxResult cancelVideoTask(String id) throws Exception {
|
||||
return cancelVideoTask(id, volcApiKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult cancelVideoTask(String id, String arkApiKey) throws Exception {
|
||||
if (StringUtils.isBlank(id)) {
|
||||
return AjaxResult.error("任务ID不能为空");
|
||||
}
|
||||
if (StringUtils.isBlank(arkApiKey)) {
|
||||
return AjaxResult.error("API Key 无效");
|
||||
}
|
||||
|
||||
try {
|
||||
// 向火山引擎发送 DELETE 请求取消任务
|
||||
Request request = new Request.Builder()
|
||||
.url(volcBaseUrl + "/api/v3/contents/generations/tasks/" + id)
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Authorization", "Bearer " + arkApiKey)
|
||||
.header("Authorization", "Bearer " + volcApiKey)
|
||||
.delete()
|
||||
.build();
|
||||
|
||||
|
|
@ -193,39 +171,4 @@ public class ByteService implements IByteService {
|
|||
return AjaxResult.error("取消任务异常:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String listVideoGenerationTasks(int pageNum, int pageSize, String arkApiKey) throws Exception {
|
||||
if (StringUtils.isBlank(arkApiKey)) {
|
||||
throw new Exception("listVideoGenerationTasks error:apiKey is null");
|
||||
}
|
||||
int pn = pageNum > 0 ? pageNum : 1;
|
||||
int ps = pageSize > 0 ? Math.min(pageSize, 500) : 10;
|
||||
|
||||
HttpUrl parsed = HttpUrl.parse(volcBaseUrl + "/api/v3/contents/generations/tasks");
|
||||
if (parsed == null) {
|
||||
throw new Exception("listVideoGenerationTasks error:invalid base url");
|
||||
}
|
||||
HttpUrl url = parsed.newBuilder()
|
||||
.addQueryParameter("page_num", String.valueOf(pn))
|
||||
.addQueryParameter("page_size", String.valueOf(ps))
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Authorization", "Bearer " + arkApiKey)
|
||||
.get()
|
||||
.build();
|
||||
|
||||
Response response = OkHttpUtils.newCall(request).execute();
|
||||
if (response.body() == null) {
|
||||
throw new Exception("listVideoGenerationTasks response null");
|
||||
}
|
||||
String body = response.body().string();
|
||||
if (!response.isSuccessful()) {
|
||||
throw new Exception("listVideoGenerationTasks error:" + body);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,18 +21,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<result property="source" column="source" />
|
||||
<result property="text" column="text" />
|
||||
<result property="isTop" column="is_top" />
|
||||
<result property="img1" column="img1" />
|
||||
<result property="img2" column="img2" />
|
||||
<result property="mode" column="mode" />
|
||||
<result property="duration" column="duration" />
|
||||
<result property="resolution" column="resolution" />
|
||||
<result property="ratio" column="ratio" />
|
||||
<result property="model" column="model" />
|
||||
<result property="videoParams" column="video_params" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectAiOrderVo">
|
||||
select ao.id, ao.del_flag, ao.create_by, ao.create_time, ao.update_by, ao.update_time, ao.remark, ao.order_num, ao.user_id, ao.type, ao.amount, ao.result, ao.status, ao.source, ao.text, ao.is_top, ao.img1, ao.img2, ao.mode, ao.duration, ao.resolution, ao.ratio, ao.model, ao.video_params, au.user_id uuid from ai_order ao
|
||||
select ao.id, ao.del_flag, ao.create_by, ao.create_time, ao.update_by, ao.update_time, ao.remark, ao.order_num, ao.user_id, ao.type, ao.amount, ao.result, ao.status, ao.source, ao.text, ao.is_top, au.user_id uuid from ai_order ao
|
||||
left join ai_user au on au.id = ao.user_id
|
||||
</sql>
|
||||
|
||||
|
|
@ -69,21 +61,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
where result = #{result}
|
||||
</select>
|
||||
|
||||
<select id="getAiOrderByPortalVideoTask" resultMap="AiOrderResult">
|
||||
<include refid="selectAiOrderVo"/>
|
||||
where ao.del_flag = '0'
|
||||
and ao.type = '21'
|
||||
and (
|
||||
ao.result = #{taskId}
|
||||
or (
|
||||
ao.video_params is not null and ao.video_params != ''
|
||||
and JSON_VALID(ao.video_params)
|
||||
and JSON_UNQUOTE(JSON_EXTRACT(ao.video_params, '$.volcTaskId')) = #{taskId}
|
||||
)
|
||||
)
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
<select id="getSumAmountByUserId" resultType="java.math.BigDecimal">
|
||||
SELECT COALESCE(sum(amount), 0) from ai_order where user_id = #{userId}
|
||||
</select>
|
||||
|
|
@ -141,7 +118,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="amount != null">amount = #{amount},</if>
|
||||
<if test="result != null">result = #{result},</if>
|
||||
<if test="status != null">status = #{status},</if>
|
||||
<if test="source != null">source = #{source},</if>
|
||||
<if test="source != null">status = #{source},</if>
|
||||
<if test="text != null">text = #{text},</if>
|
||||
<if test="isTop != null">is_top = #{isTop},</if>
|
||||
</trim>
|
||||
|
|
|
|||
|
|
@ -33,18 +33,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<result property="source" column="source" />
|
||||
<result property="ip" column="ip" />
|
||||
<result property="country" column="country" />
|
||||
<result property="deptId" column="dept_id" />
|
||||
<result property="deptName" column="dept_name" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectAiUserVo">
|
||||
select id, del_flag, create_by, create_time, update_by, update_time, remark, username, nickname, gender, avatar, phone, password, openid, status, email, birthday, invitation_code, payment_url, login_time, balance, superior_id, user_id, source, ip, country, dept_id from ai_user
|
||||
select id, del_flag, create_by, create_time, update_by, update_time, remark, username, nickname, gender, avatar, phone, password, openid, status, email, birthday, invitation_code, payment_url, login_time, balance, superior_id, user_id, source, ip, country from ai_user
|
||||
</sql>
|
||||
|
||||
<select id="selectAiUserList" parameterType="AiUser" resultMap="AiUserResult">
|
||||
select u.id, u.del_flag, u.create_by, u.create_time, u.update_by, u.update_time, u.remark, u.username, u.nickname, u.gender, u.avatar, u.phone, u.password, u.openid, u.status, u.email, u.birthday, u.invitation_code, u.payment_url, u.login_time, u.balance, u.superior_id, u.user_id, u.source, u.ip, u.country, u.dept_id, d.dept_name, au.user_id superiorUuid, au.username superiorName from ai_user u
|
||||
select u.id, u.del_flag, u.create_by, u.create_time, u.update_by, u.update_time, u.remark, u.username, u.nickname, u.gender, u.avatar, u.phone, u.password, u.openid, u.status, u.email, u.birthday, u.invitation_code, u.payment_url, u.login_time, u.balance, u.superior_id, u.user_id, u.source, u.ip, u.country, au.user_id superiorUuid, au.username superiorName from ai_user u
|
||||
left join ai_user au on au.id = u.superior_id
|
||||
left join sys_dept d on d.dept_id = u.dept_id and d.del_flag = '0'
|
||||
<where>
|
||||
<if test="nickname != null and nickname != ''"> and u.nickname like concat('%', #{nickname}, '%')</if>
|
||||
<if test="username != null and username != ''"> and u.username like concat('%', #{username}, '%')</if>
|
||||
|
|
@ -66,25 +63,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="superiorId != null "> and u.superior_id = #{superiorId}</if>
|
||||
<if test="id != null "> and u.id = #{id}</if>
|
||||
<if test="source != null "> and u.source = #{source}</if>
|
||||
<if test="deptId != null "> and u.dept_id = #{deptId}</if>
|
||||
</where>
|
||||
order by u.id desc
|
||||
</select>
|
||||
|
||||
<select id="selectAiUserById" parameterType="Long" resultMap="AiUserResult">
|
||||
select u.id, u.del_flag, u.create_by, u.create_time, u.update_by, u.update_time, u.remark, u.username, u.nickname, u.gender, u.avatar, u.phone, u.password, u.openid, u.status, u.email, u.birthday, u.invitation_code, u.payment_url, u.login_time, u.balance, u.superior_id, u.user_id, u.source, u.ip, u.country, u.dept_id, d.dept_name
|
||||
from ai_user u
|
||||
left join sys_dept d on d.dept_id = u.dept_id and d.del_flag = '0'
|
||||
where u.id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="getUserInfo" parameterType="Long" resultMap="AiUserResult">
|
||||
select del_flag, create_by, create_time, update_by, update_time, remark, username, nickname, gender, avatar, phone, password, openid, status, email, birthday, invitation_code, payment_url, login_time, balance, superior_id, user_id, source, ip, country, dept_id from ai_user
|
||||
<include refid="selectAiUserVo"/>
|
||||
where id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="countAiUserByDeptId" resultType="int">
|
||||
select count(1) from ai_user where del_flag = '0' and dept_id = #{deptId}
|
||||
<select id="getUserInfo" parameterType="Long" resultMap="AiUserResult">
|
||||
select del_flag, create_by, create_time, update_by, update_time, remark, username, nickname, gender, avatar, phone, password, openid, status, email, birthday, invitation_code, payment_url, login_time, balance, superior_id, user_id, source from ai_user
|
||||
where id = #{id}
|
||||
</select>
|
||||
<select id="selectPasswordById" resultType="java.lang.String">
|
||||
select password from ai_user where id = #{id}
|
||||
|
|
@ -118,7 +108,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="source != null">source,</if>
|
||||
<if test="ip != null">ip,</if>
|
||||
<if test="country != null">country,</if>
|
||||
<if test="deptId != null">dept_id,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="delFlag != null and delFlag != ''">#{delFlag},</if>
|
||||
|
|
@ -145,7 +134,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="userId != null">#{userId},</if>
|
||||
<if test="source != null">#{source},</if>
|
||||
<if test="country != null">#{country},</if>
|
||||
<if test="deptId != null">#{deptId},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
|
|
@ -175,9 +163,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="superiorId != null">superior_id = #{superiorId},</if>
|
||||
<if test="userId != null">user_id = #{userId},</if>
|
||||
<if test="source != null">source = #{source},</if>
|
||||
<if test="ip != null">ip = #{ip},</if>
|
||||
<if test="ip != null">source = #{ip},</if>
|
||||
<if test="country != null">country = #{country},</if>
|
||||
<if test="deptId != null">dept_id = #{deptId},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<result property="leader" column="leader" />
|
||||
<result property="phone" column="phone" />
|
||||
<result property="email" column="email" />
|
||||
<result property="byteApiKey" column="byte_api_key" />
|
||||
<result property="status" column="status" />
|
||||
<result property="delFlag" column="del_flag" />
|
||||
<result property="parentName" column="parent_name" />
|
||||
|
|
@ -24,7 +23,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</resultMap>
|
||||
|
||||
<sql id="selectDeptVo">
|
||||
select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.byte_api_key, d.status, d.del_flag, d.create_by, d.create_time
|
||||
select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time
|
||||
from sys_dept d
|
||||
</sql>
|
||||
|
||||
|
|
@ -60,7 +59,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</select>
|
||||
|
||||
<select id="selectDeptById" parameterType="Long" resultMap="SysDeptResult">
|
||||
select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.byte_api_key, d.status,
|
||||
select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status,
|
||||
(select dept_name from sys_dept where dept_id = d.parent_id) parent_name
|
||||
from sys_dept d
|
||||
where d.dept_id = #{deptId}
|
||||
|
|
@ -102,7 +101,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="leader != null and leader != ''">leader,</if>
|
||||
<if test="phone != null and phone != ''">phone,</if>
|
||||
<if test="email != null and email != ''">email,</if>
|
||||
<if test="byteApiKey != null">byte_api_key,</if>
|
||||
<if test="status != null">status,</if>
|
||||
<if test="createBy != null and createBy != ''">create_by,</if>
|
||||
create_time
|
||||
|
|
@ -115,7 +113,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="leader != null and leader != ''">#{leader},</if>
|
||||
<if test="phone != null and phone != ''">#{phone},</if>
|
||||
<if test="email != null and email != ''">#{email},</if>
|
||||
<if test="byteApiKey != null">#{byteApiKey},</if>
|
||||
<if test="status != null">#{status},</if>
|
||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||
sysdate()
|
||||
|
|
@ -132,7 +129,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="leader != null">leader = #{leader},</if>
|
||||
<if test="phone != null">phone = #{phone},</if>
|
||||
<if test="email != null">email = #{email},</if>
|
||||
<if test="byteApiKey != null">byte_api_key = #{byteApiKey},</if>
|
||||
<if test="status != null and status != ''">status = #{status},</if>
|
||||
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
||||
update_time = sysdate()
|
||||
|
|
|
|||
101
sql/aisql.sql
101
sql/aisql.sql
|
|
@ -1500,8 +1500,6 @@ CREATE TABLE `ai_order` (
|
|||
`duration` int NULL DEFAULT 5 COMMENT '视频时长(秒)',
|
||||
`resolution` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '720p' COMMENT '分辨率',
|
||||
`ratio` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '9:16' COMMENT '宽高比',
|
||||
`model` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '火山模型 endpoint',
|
||||
`video_params` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '视频生成提交参数JSON',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
KEY `idx_order_num` (`order_num`) USING BTREE,
|
||||
KEY `idx_user_id` (`user_id`) USING BTREE
|
||||
|
|
@ -3541,7 +3539,6 @@ CREATE TABLE `ai_user` (
|
|||
`source` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '来源',
|
||||
`ip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户IP',
|
||||
`country` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '隶属国家',
|
||||
`dept_id` bigint NULL DEFAULT NULL COMMENT '归属部门(sys_dept.dept_id)',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uuid`(`user_id` ASC) USING BTREE,
|
||||
UNIQUE INDEX `invitation_code`(`invitation_code` ASC) USING BTREE,
|
||||
|
|
@ -3552,37 +3549,35 @@ CREATE TABLE `ai_user` (
|
|||
-- ----------------------------
|
||||
-- Records of ai_user
|
||||
-- ----------------------------
|
||||
INSERT INTO `ai_user` VALUES (14, '0', '', '2025-11-28 11:42:33', '', '2026-01-06 16:04:21', NULL, 'ww123', NULL, 2, '', '', '$2a$10$bxNPP2cfo9OlJxiOQJJDiu4QOrQet8enUOCiu3QF6qLHaOSLA6G1.', NULL, 0, 'xpchb40121@outlook.com', NULL, 'RM3XZ8z3', NULL, '2026-01-06 16:04:21', 235.00, NULL, 'L8AJXFPT', 'XM001', '2605:52c0:1:446:a425:64ff:fe47:36c6', '美国', NULL);
|
||||
INSERT INTO `ai_user` VALUES (15, '0', '', '2025-12-07 14:52:38', '', '2025-12-08 17:20:37', NULL, 'u30', NULL, 2, '', '', '$2a$10$tXkZP66AWniOcCbhk2LJpOFOSzHEIMLDbGsow4B7maYswco5HShg.', NULL, 0, 'u30@163.com', NULL, 'wHSf4N2v', NULL, '2025-12-08 17:20:37', 10.00, NULL, 'SNLMZXPH', 'XM001', '208.86.32.27', '美国', NULL);
|
||||
INSERT INTO `ai_user` VALUES (16, '0', '', '2025-12-07 17:15:46', '', '2026-01-08 09:08:03', NULL, 'test001', NULL, 2, '', '', '$2a$10$M4ZD5kRehFycoTmgrA1b4.XNnwsvULaQm9ySdSxttRzPVn7ngbE6y', NULL, 0, 'fgerghbrthbrt@gmail.com', NULL, 'XrtN5DDW', NULL, '2026-01-08 09:08:03', 99921.00, NULL, '2LZ9RAC2', '', '15.204.58.244', '美国', NULL);
|
||||
INSERT INTO `ai_user` VALUES (17, '0', '', '2025-12-07 17:28:57', '', '2025-12-07 09:28:57', NULL, 'zz3534217@gmail.com', NULL, 2, '', '', '$2a$10$sxNmfnayqUroy66CgCATf.VkmxsECKv1jTUgFUMN.CQY.3yFBWGO.', NULL, 0, 'zz3534217@gmail.com', NULL, 'qnUwmXYS', NULL, '2025-12-07 21:18:48', 0.00, NULL, '82FR6YTZ', 'XM001', NULL, NULL, NULL);
|
||||
INSERT INTO `ai_user` VALUES (18, '0', '', '2025-12-08 12:53:23', '', '2025-12-08 17:00:57', NULL, '3545486624@qq.com', NULL, 2, '', '', '$2a$10$9siQceU./ZfmW.iDwVf9sehBJWsxzyP10fJvkzStAbyzw4yQEHAUa', NULL, 0, '3545486624@qq.com', NULL, 'ujfTuFNA', NULL, '2025-12-08 17:00:56', 0.00, NULL, 'OEEO8YJQ', 'XM001', '119.246.86.101', '香港', NULL);
|
||||
INSERT INTO `ai_user` VALUES (19, '0', '', '2025-12-08 15:47:59', '', '2025-12-08 15:48:14', NULL, 'walb0501', NULL, 2, '', '', '$2a$10$KnHIeNIOtva0saZVasbfBeJhvCKpU/cjZXEwBJ655jrJcBnCR1s/q', NULL, 0, 'pereadesen2@gmail.com', NULL, 'DqmbQS8q', NULL, '2025-12-08 15:48:14', 8.00, NULL, '9Q889UMZ', 'XM001', '188.253.121.195', '新加坡', NULL);
|
||||
INSERT INTO `ai_user` VALUES (20, '0', '', '2025-12-08 15:50:03', '', '2025-12-08 15:50:23', NULL, 'xu89026719@gmail.com', NULL, 2, '', '', '$2a$10$xdGHiEVaGC7gyXldojpiUO0GOgyu5Pcgtw/WRTuf.TA1e.NbB8Ogu', NULL, 0, 'xu89026719@gmail.com', NULL, 'XnQAfPvA', NULL, '2025-12-08 15:50:23', 0.00, NULL, '209HPBTF', 'XM001', '38.207.136.194', '日本', NULL);
|
||||
INSERT INTO `ai_user` VALUES (21, '0', '', '2025-12-08 17:20:31', '', '2025-12-08 17:22:26', NULL, '1686228', NULL, 2, '', '', '$2a$10$MpUYTeWBI6gVTqjtJBz.3.sMOz6ul.eqLQyrvY3VL2WRbFeK666fW', NULL, 0, '1686228@gmail.com', NULL, 'RyZlK7YG', NULL, '2025-12-08 17:22:26', 10.00, NULL, '9CUIDFW4', 'XM001', '208.86.32.27', '美国', NULL);
|
||||
INSERT INTO `ai_user` VALUES (22, '0', '', '2025-12-08 19:45:16', '', '2025-12-09 03:12:37', NULL, 'a424569211@gmail.com', NULL, 2, '', '', '$2a$10$3TEa4ufju1sMPJdw8K0Ik.ic10m6Ms4LQFxYK2h27/pbI2qR5nJDK', NULL, 0, 'a424569211@gmail.com', NULL, '4JLEc4vd', NULL, '2025-12-09 03:12:37', 0.00, NULL, '0N5NEU38', 'XM001', '205.185.125.114', '美国', NULL);
|
||||
INSERT INTO `ai_user` VALUES (23, '0', '', '2025-12-09 10:33:05', '', '2025-12-09 10:33:21', NULL, 'cc123', NULL, 2, 'https://images.iqyjsnwv.com/2025/12/09/37b754c5_706d42be-ad9a-4f11-a3ec-c0742e97ed64.png', '', '$2a$10$V.SDRP4RgM/qfAmNMSqIdOOM259j064oJCvAbDkhrSZLB99L9nhaK', NULL, 0, 'cherrylux098@gmail.com', NULL, 'rlmhwbhF', NULL, '2025-12-09 10:33:21', 4.00, NULL, 'NU8BE6J2', 'XM001', '2605:52c0:3:1a3:c05b:4bff:fe2c:115a', '美国', NULL);
|
||||
INSERT INTO `ai_user` VALUES (25, '0', '', '2025-12-09 13:46:13', '', '2025-12-09 14:31:51', NULL, 'test1', NULL, 2, '', '', '$2a$10$7v6PPfozY7PHR.ep.GKobePag1aq0ZuS9j.R6lWcKloy9j1R6HgoS', NULL, 0, '123@gmail.com', NULL, 'VBb72Ym3', NULL, '2025-12-09 14:31:50', 8.00, NULL, 'UQ9WZN3V', 'XM001', '2407:cdc0:b00a::19', '香港', NULL);
|
||||
INSERT INTO `ai_user` VALUES (26, '0', '', '2025-12-09 14:13:17', '', '2025-12-09 14:53:48', NULL, 'test2', NULL, 2, '', '', '$2a$10$OirrwiDFruMJQLLnNufEv.BiQzyL.KxCz1x.XVWt5R5e.ggq5m/RS', NULL, 0, '1@gmail.com', NULL, '3WFmGuER', NULL, '2025-12-09 14:53:48', 10.00, NULL, '0NEK09R6', 'XM001', '2407:cdc0:b00a::19', '香港', NULL);
|
||||
INSERT INTO `ai_user` VALUES (27, '0', '', '2025-12-09 14:57:14', '', '2025-12-09 15:01:08', NULL, 'test3', NULL, 2, '', '', '$2a$10$aCcA6Mq/.xOfs6FCJwPot.ttBFv7YjULPQsF3axMz3Gm98MzMafrO', NULL, 0, '2@gmail.com', NULL, 'pqU7mW5R', NULL, '2025-12-09 15:01:08', 10000.00, NULL, '4R80E3NI', 'XM001', '2407:cdc0:b00a::19', '香港', NULL);
|
||||
INSERT INTO `ai_user` VALUES (29, '0', '', '2025-12-11 10:48:59', '', '2025-12-11 10:49:08', NULL, 'test4', NULL, 2, '', '', '$2a$10$he3GMBisX7UeEHFRQYVxU.vcavkDxWWNyCSuz2QvfPKBAEZd17Xuu', NULL, 0, '3@gmail.com', NULL, 'FWzJWjjQ', NULL, '2025-12-11 10:49:08', 0.00, NULL, 'KLSC4HK0', 'ALL', '2407:cdc0:b00a::19', '香港', NULL);
|
||||
INSERT INTO `ai_user` VALUES (30, '0', '', '2025-12-11 10:50:31', '', '2025-12-11 11:00:47', NULL, 'test5', NULL, 2, '', '', '$2a$10$QVUfOv2FbwhRwj35ETn0we.k76tfHNqxXZPKy0vvzxfz1jgh2cB7m', NULL, 0, '4@gmail.com', NULL, 'Rdp7l3db', NULL, '2025-12-11 11:00:47', 28.22, NULL, '1S8WYOXT', 'ALL', '2407:cdc0:b00a::19', '香港', NULL);
|
||||
INSERT INTO `ai_user` VALUES (31, '0', '', '2025-12-14 01:35:44', '', '2025-12-13 17:35:44', NULL, 'whsksmhxud', NULL, 2, '', '', '$2a$10$sJ1pA9uBfgzv8O5X5Ui5G.7uVKRoZDqDqQ9BG848y7njgFtlgzWpq', NULL, 0, 'w809277959@outlook.com', NULL, 'bZEVdu4b', NULL, NULL, 0.00, NULL, '7I7TJC30', 'XM001', '103.82.93.21', '印尼', NULL);
|
||||
INSERT INTO `ai_user` VALUES (32, '0', '', '2025-12-14 01:58:22', '', '2025-12-14 01:58:47', NULL, 'devin', NULL, 2, '', '', '$2a$10$NUNiFbS6WEXznA0LzlW10eH5FjX437NxO05VSnMFII4FIsPQOuoxe', NULL, 0, 'devinhe46@gmail.com', NULL, 'BZNhTE5M', NULL, '2025-12-14 01:58:47', 0.00, NULL, 'BN7FJCGI', 'XM001', '134.122.184.12', '日本', NULL);
|
||||
INSERT INTO `ai_user` VALUES (33, '0', '', '2025-12-14 10:22:49', '', '2025-12-14 10:23:08', NULL, 'djwnx1123', NULL, 2, '', '', '$2a$10$z5dYmkZzGdi9G2nVSPZqJutN2Z/8FN0.cPRilsZdjzgVZKc2QCydi', NULL, 0, '2451855921@qq.com', NULL, 'nc3yv7WQ', NULL, '2025-12-14 10:23:08', 0.00, NULL, '4HF1953W', 'XM001', '103.147.45.37', '香港', NULL);
|
||||
INSERT INTO `ai_user` VALUES (34, '0', '', '2025-12-14 14:52:58', '', '2025-12-14 14:54:08', NULL, 'djwnx', NULL, 2, '', '', '$2a$10$YwtgWJOnElfAn4vuvYRprO5zXrTBZx8fvx/lVIyopVdph7RkeSisS', NULL, 0, 'tianyangyu1123@gmail.com', NULL, 'pFpHVX2y', NULL, '2025-12-14 14:54:08', 0.00, NULL, 'BH9DLPCJ', 'XM001', '43.228.227.211', '香港', NULL);
|
||||
INSERT INTO `ai_user` VALUES (35, '0', '', '2025-12-15 18:05:01', '', '2025-12-24 15:08:10', NULL, 'test6', NULL, 2, '', '', '$2a$10$AOJg.25lz16afHa3OfPMhuxu8oorFGeL4MqMgcxpRKjd4iY0LsmAG', NULL, 0, '5@gmail.com', NULL, 'heNUTHUX', NULL, '2025-12-24 15:08:09', 323.00, 30, 'PJCZNE1M', 'ALL', '2602:fbf1:b001::36', '美国', NULL);
|
||||
INSERT INTO `ai_user` VALUES (36, '0', '', '2025-12-15 18:07:56', '', '2026-01-08 14:53:02', NULL, 'test7', NULL, 2, '', '', '$2a$10$xXtOsMjz5Zd9dsJvUBz5be.6ZphexWOedfe.TLW9bdDtzFBYESzIG', NULL, 0, '6@gmail.com', NULL, 'RXQLfyjy', NULL, '2026-01-08 14:53:01', 100419.00, 35, '24SRSLFG', 'ALL', '2407:cdc0:d002::195', '新加坡', NULL);
|
||||
INSERT INTO `ai_user` VALUES (37, '0', '', '2025-12-16 14:07:46', '', '2025-12-16 14:08:05', NULL, 'test8', NULL, 2, '', '', '$2a$10$Z967MUQ6I5CCgfVJTV0l2ug2BysZmfRNvpq6c.vBVlVIX7ekM3GJi', NULL, 0, '7@gmail.com', NULL, 'kEZx2eps', NULL, '2025-12-16 14:08:04', 0.00, NULL, 'H4AFA8CH', 'ALL', '37.9.33.202', '美国', NULL);
|
||||
INSERT INTO `ai_user` VALUES (38, '0', '', '2025-12-19 22:04:18', '', '2025-12-24 20:57:53', NULL, 'ghypnus', NULL, 2, '', '', '$2a$10$Cr7AQ7D9Jxk6BRE7cYn1su5B4x4aOxkf9JQMwk06Tyt5X1dn8Qr6K', NULL, 0, '1954579286@qq.com', NULL, '3tMwDlMH', NULL, '2025-12-24 20:57:52', 0.00, NULL, 'JPL28UHV', 'XM001', '85.234.69.52', '英国', NULL);
|
||||
INSERT INTO `ai_user` VALUES (39, '0', '', '2025-12-27 16:48:23', '', '2026-01-06 16:32:09', NULL, 'xiaxiaxia', NULL, 2, '', '', '$2a$10$aci4cfcpANfKt1EPdVY1cORUACqXJHGx49gjD72Cc2p62K5TKT6bG', NULL, 0, 'pianochen606@gmail.com', NULL, 'yWQK4jBC', NULL, '2026-01-06 16:32:09', 9829.00, NULL, 'K0G1NBAI', 'XM001', '216.167.64.103', '美国', NULL);
|
||||
INSERT INTO `ai_user` VALUES (40, '0', '', '2025-12-30 11:28:25', '', '2025-12-30 11:28:35', NULL, 'test9', NULL, 2, '', '', '$2a$10$RrqVCQk2eKBrk4LqVlVLg.MCSmKlIJidSpw/aH3jlA4oGf8AEvbYi', NULL, 0, '8@gmail.com', NULL, 'wSsxXKeH', NULL, '2025-12-30 11:28:35', 336.00, 35, 'Z6UI3X6S', 'ALL', '2602:fbf1:b001::36', '美国', NULL);
|
||||
INSERT INTO `ai_user` VALUES (41, '0', '', '2025-12-30 11:58:13', '', '2025-12-30 11:58:20', NULL, 'test10', NULL, 2, '', '', '$2a$10$iyc.quT3QzzzROdjLN1S8.GLE.epyFAo4FvBDOlokDbu4JMODrr3S', NULL, 0, '9@gmail.com', NULL, 'lRbwts88', NULL, '2025-12-30 11:58:20', 110.00, 40, 'LJSSMAQO', 'ALL', '2602:fbf1:b001::36', '美国', NULL);
|
||||
INSERT INTO `ai_user` VALUES (42, '0', '', '2025-12-30 13:42:02', '', '2025-12-30 13:42:09', NULL, 'test11', NULL, 2, '', '', '$2a$10$ke66b3aOZ67NaUT2WQepyO2EmVYkSEBYLB/NFSRID.S3ejHaU5Og.', NULL, 0, '10@gmail.com', NULL, 'BrEg6XmM', NULL, '2025-12-30 13:42:09', 225.00, NULL, 'IHOF63N5', 'ALL', '2602:fbf1:b001::36', '美国', NULL);
|
||||
INSERT INTO `ai_user` VALUES (43, '0', '', '2025-12-31 14:20:06', '', '2025-12-31 14:20:12', NULL, 'a001', NULL, 2, '', '', '$2a$10$Z02VVJ5/LaiTzTp22b2zXOTV8YE/6BMNVrboTj5cuEthXuPpP97Mi', NULL, 0, '11@gmail.com', NULL, 'Xf38CXD6', NULL, '2025-12-31 14:20:12', 1089.00, NULL, 'LXNFP1VS', 'ALL', '2602:fbf1:b001::36', '美国', NULL);
|
||||
INSERT INTO `ai_user` VALUES (44, '0', '', '2025-12-31 14:26:20', '', '2025-12-31 14:26:25', NULL, 'a002', NULL, 2, '', '', '$2a$10$4ZnF/zh3q3E07GBpthtL.ufsxQOt2u/eu8YzcFnmPO5dUa1RJ6mkG', NULL, 0, 'c46258724hk@gmail.com', NULL, 'knt2yT2r', NULL, '2025-12-31 14:26:25', 230.00, 43, 'JW07BAHC', 'ALL', '2602:fbf1:b001::36', '美国', NULL);
|
||||
|
||||
-- 已有库升级:ALTER TABLE ai_user ADD COLUMN dept_id bigint NULL DEFAULT NULL COMMENT '归属部门(sys_dept.dept_id)' AFTER country;
|
||||
INSERT INTO `ai_user` VALUES (14, '0', '', '2025-11-28 11:42:33', '', '2026-01-06 16:04:21', NULL, 'ww123', NULL, 2, '', '', '$2a$10$bxNPP2cfo9OlJxiOQJJDiu4QOrQet8enUOCiu3QF6qLHaOSLA6G1.', NULL, 0, 'xpchb40121@outlook.com', NULL, 'RM3XZ8z3', NULL, '2026-01-06 16:04:21', 235.00, NULL, 'L8AJXFPT', 'XM001', '2605:52c0:1:446:a425:64ff:fe47:36c6', '美国');
|
||||
INSERT INTO `ai_user` VALUES (15, '0', '', '2025-12-07 14:52:38', '', '2025-12-08 17:20:37', NULL, 'u30', NULL, 2, '', '', '$2a$10$tXkZP66AWniOcCbhk2LJpOFOSzHEIMLDbGsow4B7maYswco5HShg.', NULL, 0, 'u30@163.com', NULL, 'wHSf4N2v', NULL, '2025-12-08 17:20:37', 10.00, NULL, 'SNLMZXPH', 'XM001', '208.86.32.27', '美国');
|
||||
INSERT INTO `ai_user` VALUES (16, '0', '', '2025-12-07 17:15:46', '', '2026-01-08 09:08:03', NULL, 'test001', NULL, 2, '', '', '$2a$10$M4ZD5kRehFycoTmgrA1b4.XNnwsvULaQm9ySdSxttRzPVn7ngbE6y', NULL, 0, 'fgerghbrthbrt@gmail.com', NULL, 'XrtN5DDW', NULL, '2026-01-08 09:08:03', 99921.00, NULL, '2LZ9RAC2', '', '15.204.58.244', '美国');
|
||||
INSERT INTO `ai_user` VALUES (17, '0', '', '2025-12-07 17:28:57', '', '2025-12-07 09:28:57', NULL, 'zz3534217@gmail.com', NULL, 2, '', '', '$2a$10$sxNmfnayqUroy66CgCATf.VkmxsECKv1jTUgFUMN.CQY.3yFBWGO.', NULL, 0, 'zz3534217@gmail.com', NULL, 'qnUwmXYS', NULL, '2025-12-07 21:18:48', 0.00, NULL, '82FR6YTZ', 'XM001', NULL, NULL);
|
||||
INSERT INTO `ai_user` VALUES (18, '0', '', '2025-12-08 12:53:23', '', '2025-12-08 17:00:57', NULL, '3545486624@qq.com', NULL, 2, '', '', '$2a$10$9siQceU./ZfmW.iDwVf9sehBJWsxzyP10fJvkzStAbyzw4yQEHAUa', NULL, 0, '3545486624@qq.com', NULL, 'ujfTuFNA', NULL, '2025-12-08 17:00:56', 0.00, NULL, 'OEEO8YJQ', 'XM001', '119.246.86.101', '香港');
|
||||
INSERT INTO `ai_user` VALUES (19, '0', '', '2025-12-08 15:47:59', '', '2025-12-08 15:48:14', NULL, 'walb0501', NULL, 2, '', '', '$2a$10$KnHIeNIOtva0saZVasbfBeJhvCKpU/cjZXEwBJ655jrJcBnCR1s/q', NULL, 0, 'pereadesen2@gmail.com', NULL, 'DqmbQS8q', NULL, '2025-12-08 15:48:14', 8.00, NULL, '9Q889UMZ', 'XM001', '188.253.121.195', '新加坡');
|
||||
INSERT INTO `ai_user` VALUES (20, '0', '', '2025-12-08 15:50:03', '', '2025-12-08 15:50:23', NULL, 'xu89026719@gmail.com', NULL, 2, '', '', '$2a$10$xdGHiEVaGC7gyXldojpiUO0GOgyu5Pcgtw/WRTuf.TA1e.NbB8Ogu', NULL, 0, 'xu89026719@gmail.com', NULL, 'XnQAfPvA', NULL, '2025-12-08 15:50:23', 0.00, NULL, '209HPBTF', 'XM001', '38.207.136.194', '日本');
|
||||
INSERT INTO `ai_user` VALUES (21, '0', '', '2025-12-08 17:20:31', '', '2025-12-08 17:22:26', NULL, '1686228', NULL, 2, '', '', '$2a$10$MpUYTeWBI6gVTqjtJBz.3.sMOz6ul.eqLQyrvY3VL2WRbFeK666fW', NULL, 0, '1686228@gmail.com', NULL, 'RyZlK7YG', NULL, '2025-12-08 17:22:26', 10.00, NULL, '9CUIDFW4', 'XM001', '208.86.32.27', '美国');
|
||||
INSERT INTO `ai_user` VALUES (22, '0', '', '2025-12-08 19:45:16', '', '2025-12-09 03:12:37', NULL, 'a424569211@gmail.com', NULL, 2, '', '', '$2a$10$3TEa4ufju1sMPJdw8K0Ik.ic10m6Ms4LQFxYK2h27/pbI2qR5nJDK', NULL, 0, 'a424569211@gmail.com', NULL, '4JLEc4vd', NULL, '2025-12-09 03:12:37', 0.00, NULL, '0N5NEU38', 'XM001', '205.185.125.114', '美国');
|
||||
INSERT INTO `ai_user` VALUES (23, '0', '', '2025-12-09 10:33:05', '', '2025-12-09 10:33:21', NULL, 'cc123', NULL, 2, 'https://images.iqyjsnwv.com/2025/12/09/37b754c5_706d42be-ad9a-4f11-a3ec-c0742e97ed64.png', '', '$2a$10$V.SDRP4RgM/qfAmNMSqIdOOM259j064oJCvAbDkhrSZLB99L9nhaK', NULL, 0, 'cherrylux098@gmail.com', NULL, 'rlmhwbhF', NULL, '2025-12-09 10:33:21', 4.00, NULL, 'NU8BE6J2', 'XM001', '2605:52c0:3:1a3:c05b:4bff:fe2c:115a', '美国');
|
||||
INSERT INTO `ai_user` VALUES (25, '0', '', '2025-12-09 13:46:13', '', '2025-12-09 14:31:51', NULL, 'test1', NULL, 2, '', '', '$2a$10$7v6PPfozY7PHR.ep.GKobePag1aq0ZuS9j.R6lWcKloy9j1R6HgoS', NULL, 0, '123@gmail.com', NULL, 'VBb72Ym3', NULL, '2025-12-09 14:31:50', 8.00, NULL, 'UQ9WZN3V', 'XM001', '2407:cdc0:b00a::19', '香港');
|
||||
INSERT INTO `ai_user` VALUES (26, '0', '', '2025-12-09 14:13:17', '', '2025-12-09 14:53:48', NULL, 'test2', NULL, 2, '', '', '$2a$10$OirrwiDFruMJQLLnNufEv.BiQzyL.KxCz1x.XVWt5R5e.ggq5m/RS', NULL, 0, '1@gmail.com', NULL, '3WFmGuER', NULL, '2025-12-09 14:53:48', 10.00, NULL, '0NEK09R6', 'XM001', '2407:cdc0:b00a::19', '香港');
|
||||
INSERT INTO `ai_user` VALUES (27, '0', '', '2025-12-09 14:57:14', '', '2025-12-09 15:01:08', NULL, 'test3', NULL, 2, '', '', '$2a$10$aCcA6Mq/.xOfs6FCJwPot.ttBFv7YjULPQsF3axMz3Gm98MzMafrO', NULL, 0, '2@gmail.com', NULL, 'pqU7mW5R', NULL, '2025-12-09 15:01:08', 10000.00, NULL, '4R80E3NI', 'XM001', '2407:cdc0:b00a::19', '香港');
|
||||
INSERT INTO `ai_user` VALUES (29, '0', '', '2025-12-11 10:48:59', '', '2025-12-11 10:49:08', NULL, 'test4', NULL, 2, '', '', '$2a$10$he3GMBisX7UeEHFRQYVxU.vcavkDxWWNyCSuz2QvfPKBAEZd17Xuu', NULL, 0, '3@gmail.com', NULL, 'FWzJWjjQ', NULL, '2025-12-11 10:49:08', 0.00, NULL, 'KLSC4HK0', 'ALL', '2407:cdc0:b00a::19', '香港');
|
||||
INSERT INTO `ai_user` VALUES (30, '0', '', '2025-12-11 10:50:31', '', '2025-12-11 11:00:47', NULL, 'test5', NULL, 2, '', '', '$2a$10$QVUfOv2FbwhRwj35ETn0we.k76tfHNqxXZPKy0vvzxfz1jgh2cB7m', NULL, 0, '4@gmail.com', NULL, 'Rdp7l3db', NULL, '2025-12-11 11:00:47', 28.22, NULL, '1S8WYOXT', 'ALL', '2407:cdc0:b00a::19', '香港');
|
||||
INSERT INTO `ai_user` VALUES (31, '0', '', '2025-12-14 01:35:44', '', '2025-12-13 17:35:44', NULL, 'whsksmhxud', NULL, 2, '', '', '$2a$10$sJ1pA9uBfgzv8O5X5Ui5G.7uVKRoZDqDqQ9BG848y7njgFtlgzWpq', NULL, 0, 'w809277959@outlook.com', NULL, 'bZEVdu4b', NULL, NULL, 0.00, NULL, '7I7TJC30', 'XM001', '103.82.93.21', '印尼');
|
||||
INSERT INTO `ai_user` VALUES (32, '0', '', '2025-12-14 01:58:22', '', '2025-12-14 01:58:47', NULL, 'devin', NULL, 2, '', '', '$2a$10$NUNiFbS6WEXznA0LzlW10eH5FjX437NxO05VSnMFII4FIsPQOuoxe', NULL, 0, 'devinhe46@gmail.com', NULL, 'BZNhTE5M', NULL, '2025-12-14 01:58:47', 0.00, NULL, 'BN7FJCGI', 'XM001', '134.122.184.12', '日本');
|
||||
INSERT INTO `ai_user` VALUES (33, '0', '', '2025-12-14 10:22:49', '', '2025-12-14 10:23:08', NULL, 'djwnx1123', NULL, 2, '', '', '$2a$10$z5dYmkZzGdi9G2nVSPZqJutN2Z/8FN0.cPRilsZdjzgVZKc2QCydi', NULL, 0, '2451855921@qq.com', NULL, 'nc3yv7WQ', NULL, '2025-12-14 10:23:08', 0.00, NULL, '4HF1953W', 'XM001', '103.147.45.37', '香港');
|
||||
INSERT INTO `ai_user` VALUES (34, '0', '', '2025-12-14 14:52:58', '', '2025-12-14 14:54:08', NULL, 'djwnx', NULL, 2, '', '', '$2a$10$YwtgWJOnElfAn4vuvYRprO5zXrTBZx8fvx/lVIyopVdph7RkeSisS', NULL, 0, 'tianyangyu1123@gmail.com', NULL, 'pFpHVX2y', NULL, '2025-12-14 14:54:08', 0.00, NULL, 'BH9DLPCJ', 'XM001', '43.228.227.211', '香港');
|
||||
INSERT INTO `ai_user` VALUES (35, '0', '', '2025-12-15 18:05:01', '', '2025-12-24 15:08:10', NULL, 'test6', NULL, 2, '', '', '$2a$10$AOJg.25lz16afHa3OfPMhuxu8oorFGeL4MqMgcxpRKjd4iY0LsmAG', NULL, 0, '5@gmail.com', NULL, 'heNUTHUX', NULL, '2025-12-24 15:08:09', 323.00, 30, 'PJCZNE1M', 'ALL', '2602:fbf1:b001::36', '美国');
|
||||
INSERT INTO `ai_user` VALUES (36, '0', '', '2025-12-15 18:07:56', '', '2026-01-08 14:53:02', NULL, 'test7', NULL, 2, '', '', '$2a$10$xXtOsMjz5Zd9dsJvUBz5be.6ZphexWOedfe.TLW9bdDtzFBYESzIG', NULL, 0, '6@gmail.com', NULL, 'RXQLfyjy', NULL, '2026-01-08 14:53:01', 100419.00, 35, '24SRSLFG', 'ALL', '2407:cdc0:d002::195', '新加坡');
|
||||
INSERT INTO `ai_user` VALUES (37, '0', '', '2025-12-16 14:07:46', '', '2025-12-16 14:08:05', NULL, 'test8', NULL, 2, '', '', '$2a$10$Z967MUQ6I5CCgfVJTV0l2ug2BysZmfRNvpq6c.vBVlVIX7ekM3GJi', NULL, 0, '7@gmail.com', NULL, 'kEZx2eps', NULL, '2025-12-16 14:08:04', 0.00, NULL, 'H4AFA8CH', 'ALL', '37.9.33.202', '美国');
|
||||
INSERT INTO `ai_user` VALUES (38, '0', '', '2025-12-19 22:04:18', '', '2025-12-24 20:57:53', NULL, 'ghypnus', NULL, 2, '', '', '$2a$10$Cr7AQ7D9Jxk6BRE7cYn1su5B4x4aOxkf9JQMwk06Tyt5X1dn8Qr6K', NULL, 0, '1954579286@qq.com', NULL, '3tMwDlMH', NULL, '2025-12-24 20:57:52', 0.00, NULL, 'JPL28UHV', 'XM001', '85.234.69.52', '英国');
|
||||
INSERT INTO `ai_user` VALUES (39, '0', '', '2025-12-27 16:48:23', '', '2026-01-06 16:32:09', NULL, 'xiaxiaxia', NULL, 2, '', '', '$2a$10$aci4cfcpANfKt1EPdVY1cORUACqXJHGx49gjD72Cc2p62K5TKT6bG', NULL, 0, 'pianochen606@gmail.com', NULL, 'yWQK4jBC', NULL, '2026-01-06 16:32:09', 9829.00, NULL, 'K0G1NBAI', 'XM001', '216.167.64.103', '美国');
|
||||
INSERT INTO `ai_user` VALUES (40, '0', '', '2025-12-30 11:28:25', '', '2025-12-30 11:28:35', NULL, 'test9', NULL, 2, '', '', '$2a$10$RrqVCQk2eKBrk4LqVlVLg.MCSmKlIJidSpw/aH3jlA4oGf8AEvbYi', NULL, 0, '8@gmail.com', NULL, 'wSsxXKeH', NULL, '2025-12-30 11:28:35', 336.00, 35, 'Z6UI3X6S', 'ALL', '2602:fbf1:b001::36', '美国');
|
||||
INSERT INTO `ai_user` VALUES (41, '0', '', '2025-12-30 11:58:13', '', '2025-12-30 11:58:20', NULL, 'test10', NULL, 2, '', '', '$2a$10$iyc.quT3QzzzROdjLN1S8.GLE.epyFAo4FvBDOlokDbu4JMODrr3S', NULL, 0, '9@gmail.com', NULL, 'lRbwts88', NULL, '2025-12-30 11:58:20', 110.00, 40, 'LJSSMAQO', 'ALL', '2602:fbf1:b001::36', '美国');
|
||||
INSERT INTO `ai_user` VALUES (42, '0', '', '2025-12-30 13:42:02', '', '2025-12-30 13:42:09', NULL, 'test11', NULL, 2, '', '', '$2a$10$ke66b3aOZ67NaUT2WQepyO2EmVYkSEBYLB/NFSRID.S3ejHaU5Og.', NULL, 0, '10@gmail.com', NULL, 'BrEg6XmM', NULL, '2025-12-30 13:42:09', 225.00, NULL, 'IHOF63N5', 'ALL', '2602:fbf1:b001::36', '美国');
|
||||
INSERT INTO `ai_user` VALUES (43, '0', '', '2025-12-31 14:20:06', '', '2025-12-31 14:20:12', NULL, 'a001', NULL, 2, '', '', '$2a$10$Z02VVJ5/LaiTzTp22b2zXOTV8YE/6BMNVrboTj5cuEthXuPpP97Mi', NULL, 0, '11@gmail.com', NULL, 'Xf38CXD6', NULL, '2025-12-31 14:20:12', 1089.00, NULL, 'LXNFP1VS', 'ALL', '2602:fbf1:b001::36', '美国');
|
||||
INSERT INTO `ai_user` VALUES (44, '0', '', '2025-12-31 14:26:20', '', '2025-12-31 14:26:25', NULL, 'a002', NULL, 2, '', '', '$2a$10$4ZnF/zh3q3E07GBpthtL.ufsxQOt2u/eu8YzcFnmPO5dUa1RJ6mkG', NULL, 0, 'c46258724hk@gmail.com', NULL, 'knt2yT2r', NULL, '2025-12-31 14:26:25', 230.00, 43, 'JW07BAHC', 'ALL', '2602:fbf1:b001::36', '美国');
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for ai_user_message
|
||||
|
|
@ -4195,7 +4190,6 @@ CREATE TABLE `sys_dept` (
|
|||
`leader` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '负责人',
|
||||
`phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '联系电话',
|
||||
`email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '邮箱',
|
||||
`byte_api_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Byte API Key',
|
||||
`status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '部门状态(0正常 1停用)',
|
||||
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
|
||||
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者',
|
||||
|
|
@ -4208,23 +4202,21 @@ CREATE TABLE `sys_dept` (
|
|||
-- ----------------------------
|
||||
-- Records of sys_dept
|
||||
-- ----------------------------
|
||||
INSERT INTO `sys_dept` VALUES (100, 0, '0', '若依科技', 0, '若依', '15888888888', 'ry@qq.com', NULL, '0', '0', 'admin', '2025-11-09 01:56:46', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (101, 100, '0,100', '深圳总公司', 1, '若依', '15888888888', 'ry@qq.com', NULL, '0', '0', 'admin', '2025-11-09 01:56:47', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (102, 100, '0,100', '长沙分公司', 2, '若依', '15888888888', 'ry@qq.com', NULL, '0', '0', 'admin', '2025-11-09 01:56:47', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (103, 101, '0,100,101', '研发部门', 1, '若依', '15888888888', 'ry@qq.com', NULL, '0', '0', 'admin', '2025-11-09 01:56:47', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (104, 101, '0,100,101', '市场部门', 2, '若依', '15888888888', 'ry@qq.com', NULL, '0', '0', 'admin', '2025-11-09 01:56:47', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (105, 101, '0,100,101', '测试部门', 3, '若依', '15888888888', 'ry@qq.com', NULL, '0', '0', 'admin', '2025-11-09 01:56:48', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (106, 101, '0,100,101', '财务部门', 4, '若依', '15888888888', 'ry@qq.com', NULL, '0', '0', 'admin', '2025-11-09 01:56:48', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (107, 101, '0,100,101', '运维部门', 5, '若依', '15888888888', 'ry@qq.com', NULL, '0', '0', 'admin', '2025-11-09 01:56:49', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (108, 102, '0,100,102', '市场部门', 1, '若依', '15888888888', 'ry@qq.com', NULL, '0', '0', 'admin', '2025-11-09 01:56:49', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (109, 102, '0,100,102', '财务部门', 2, '若依', '15888888888', 'ry@qq.com', NULL, '0', '0', 'admin', '2025-11-09 01:56:49', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (200, 100, '0,100', '胸部', 3, NULL, NULL, NULL, NULL, '0', '2', 'admin', '2025-11-25 13:07:38', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (201, 200, '0,100,200', '大奶', 1, NULL, NULL, NULL, NULL, '0', '2', 'admin', '2025-11-25 13:07:48', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (202, 201, '0,100,200,201', '水滴型', 1, NULL, NULL, NULL, NULL, '0', '2', 'admin', '2025-11-25 13:08:04', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (203, 200, '0,100,200', '小奶', 2, NULL, NULL, NULL, NULL, '0', '2', 'admin', '2025-11-25 13:08:13', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (204, 201, '0,100,200,201', '粉色', 2, NULL, NULL, NULL, NULL, '0', '2', 'admin', '2025-11-25 13:08:25', '', NULL);
|
||||
|
||||
-- 已有数据库升级可执行:ALTER TABLE sys_dept ADD COLUMN byte_api_key varchar(255) NULL DEFAULT NULL COMMENT 'Byte API Key' AFTER email;
|
||||
INSERT INTO `sys_dept` VALUES (100, 0, '0', '若依科技', 0, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-11-09 01:56:46', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (101, 100, '0,100', '深圳总公司', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-11-09 01:56:47', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (102, 100, '0,100', '长沙分公司', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-11-09 01:56:47', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (103, 101, '0,100,101', '研发部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-11-09 01:56:47', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (104, 101, '0,100,101', '市场部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-11-09 01:56:47', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (105, 101, '0,100,101', '测试部门', 3, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-11-09 01:56:48', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (106, 101, '0,100,101', '财务部门', 4, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-11-09 01:56:48', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (107, 101, '0,100,101', '运维部门', 5, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-11-09 01:56:49', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (108, 102, '0,100,102', '市场部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-11-09 01:56:49', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (109, 102, '0,100,102', '财务部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-11-09 01:56:49', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (200, 100, '0,100', '胸部', 3, NULL, NULL, NULL, '0', '2', 'admin', '2025-11-25 13:07:38', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (201, 200, '0,100,200', '大奶', 1, NULL, NULL, NULL, '0', '2', 'admin', '2025-11-25 13:07:48', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (202, 201, '0,100,200,201', '水滴型', 1, NULL, NULL, NULL, '0', '2', 'admin', '2025-11-25 13:08:04', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (203, 200, '0,100,200', '小奶', 2, NULL, NULL, NULL, '0', '2', 'admin', '2025-11-25 13:08:13', '', NULL);
|
||||
INSERT INTO `sys_dept` VALUES (204, 201, '0,100,200,201', '粉色', 2, NULL, NULL, NULL, '0', '2', 'admin', '2025-11-25 13:08:25', '', NULL);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sys_dict_data
|
||||
|
|
@ -4692,11 +4684,6 @@ INSERT INTO `sys_menu` VALUES (1058, '导入代码', 116, 4, '#', '', '', '', 1,
|
|||
INSERT INTO `sys_menu` VALUES (1059, '预览代码', 116, 5, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', '2025-11-09 01:57:14', '', NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (1060, '生成代码', 116, 6, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', '2025-11-09 01:57:14', '', NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2000, '综合管理', 0, 4, 'ai-manager', NULL, NULL, '', 1, 0, 'M', '0', '0', '', 'redis-list', 'admin', '2025-11-12 20:19:15', 'admin', '2025-11-20 20:06:49', '');
|
||||
INSERT INTO `sys_menu` VALUES (2100, 'AI部门管理', 2003, 0, 'aiDept', 'ai/dept/index', NULL, '', 1, 0, 'C', '0', '0', 'ai:dept:list', 'tree', 'admin', '2026-03-30 10:00:00', '', NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2101, 'AI部门查询', 2100, 1, '', '', NULL, '', 1, 0, 'F', '0', '0', 'ai:dept:query', '#', 'admin', '2026-03-30 10:00:00', '', NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2102, 'AI部门新增', 2100, 2, '', '', NULL, '', 1, 0, 'F', '0', '0', 'ai:dept:add', '#', 'admin', '2026-03-30 10:00:00', '', NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2103, 'AI部门修改', 2100, 3, '', '', NULL, '', 1, 0, 'F', '0', '0', 'ai:dept:edit', '#', 'admin', '2026-03-30 10:00:00', '', NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2104, 'AI部门删除', 2100, 4, '', '', NULL, '', 1, 0, 'F', '0', '0', 'ai:dept:remove', '#', 'admin', '2026-03-30 10:00:00', '', NULL, '');
|
||||
INSERT INTO `sys_menu` VALUES (2001, 'AI用户管理', 2003, 1, 'aiUser', 'ai/user/index', NULL, '', 1, 0, 'C', '0', '0', 'ai:user:list', 'user', 'admin', '2025-11-12 20:45:34', 'admin', '2025-11-13 22:19:09', '');
|
||||
INSERT INTO `sys_menu` VALUES (2002, 'AI管理', 2000, 4, 'aiManager', 'ai/manager/index', NULL, '', 1, 0, 'C', '0', '0', 'ai:manager:list', 'online', 'admin', '2025-11-13 19:18:54', 'admin', '2025-11-13 22:49:28', '');
|
||||
INSERT INTO `sys_menu` VALUES (2003, '用户管理', 2000, 1, 'aiUserManger', NULL, NULL, '', 1, 0, 'M', '0', '0', NULL, 'peoples', 'admin', '2025-11-13 22:18:42', '', NULL, '');
|
||||
|
|
|
|||
Loading…
Reference in New Issue