Merge remote-tracking branch 'yudao/dev' into dev-new
commit
7844a6f292
Binary file not shown.
After Width: | Height: | Size: 108 KiB |
Binary file not shown.
After Width: | Height: | Size: 87 KiB |
Binary file not shown.
After Width: | Height: | Size: 86 KiB |
Binary file not shown.
After Width: | Height: | Size: 121 KiB |
|
@ -12,6 +12,7 @@ import {
|
|||
} from '@vben/plugins/vxe-table';
|
||||
import {
|
||||
erpNumberFormatter,
|
||||
formatPast2,
|
||||
formatToFractionDigit,
|
||||
isFunction,
|
||||
isString,
|
||||
|
@ -296,32 +297,7 @@ setupVbenVxeTable({
|
|||
|
||||
vxeUI.formats.add('formatPast2', {
|
||||
tableCellFormatMethod({ cellValue }) {
|
||||
if (cellValue === null || cellValue === undefined) {
|
||||
return '';
|
||||
}
|
||||
// 定义时间单位常量,便于维护
|
||||
const SECOND = 1000;
|
||||
const MINUTE = 60 * SECOND;
|
||||
const HOUR = 60 * MINUTE;
|
||||
const DAY = 24 * HOUR;
|
||||
|
||||
// 计算各时间单位
|
||||
const day = Math.floor(cellValue / DAY);
|
||||
const hour = Math.floor((cellValue % DAY) / HOUR);
|
||||
const minute = Math.floor((cellValue % HOUR) / MINUTE);
|
||||
const second = Math.floor((cellValue % MINUTE) / SECOND);
|
||||
|
||||
// 根据时间长短返回不同格式
|
||||
if (day > 0) {
|
||||
return `${day} 天${hour} 小时 ${minute} 分钟`;
|
||||
}
|
||||
if (hour > 0) {
|
||||
return `${hour} 小时 ${minute} 分钟`;
|
||||
}
|
||||
if (minute > 0) {
|
||||
return `${minute} 分钟`;
|
||||
}
|
||||
return second > 0 ? `${second} 秒` : `${0} 秒`;
|
||||
return formatPast2(cellValue);
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
import type { PageResult } from '@vben/request';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace AiChatConversationApi {
|
||||
export interface ChatConversationVO {
|
||||
id: number; // ID 编号
|
||||
userId: number; // 用户编号
|
||||
title: string; // 对话标题
|
||||
pinned: boolean; // 是否置顶
|
||||
roleId: number; // 角色编号
|
||||
modelId: number; // 模型编号
|
||||
model: string; // 模型标志
|
||||
temperature: number; // 温度参数
|
||||
maxTokens: number; // 单条回复的最大 Token 数量
|
||||
maxContexts: number; // 上下文的最大 Message 数量
|
||||
createTime?: Date; // 创建时间
|
||||
// 额外字段
|
||||
systemMessage?: string; // 角色设定
|
||||
modelName?: string; // 模型名字
|
||||
roleAvatar?: string; // 角色头像
|
||||
modelMaxTokens?: string; // 模型的单条回复的最大 Token 数量
|
||||
modelMaxContexts?: string; // 模型的上下文的最大 Message 数量
|
||||
}
|
||||
}
|
||||
|
||||
// 获得【我的】聊天对话
|
||||
export function getChatConversationMy(id: number) {
|
||||
return requestClient.get<AiChatConversationApi.ChatConversationVO>(
|
||||
`/ai/chat/conversation/get-my?id=${id}`,
|
||||
);
|
||||
}
|
||||
|
||||
// 新增【我的】聊天对话
|
||||
export function createChatConversationMy(
|
||||
data: AiChatConversationApi.ChatConversationVO,
|
||||
) {
|
||||
return requestClient.post('/ai/chat/conversation/create-my', data);
|
||||
}
|
||||
|
||||
// 更新【我的】聊天对话
|
||||
export function updateChatConversationMy(
|
||||
data: AiChatConversationApi.ChatConversationVO,
|
||||
) {
|
||||
return requestClient.put(`/ai/chat/conversation/update-my`, data);
|
||||
}
|
||||
|
||||
// 删除【我的】聊天对话
|
||||
export function deleteChatConversationMy(id: number) {
|
||||
return requestClient.delete(`/ai/chat/conversation/delete-my?id=${id}`);
|
||||
}
|
||||
|
||||
// 删除【我的】所有对话,置顶除外
|
||||
export function deleteChatConversationMyByUnpinned() {
|
||||
return requestClient.delete(`/ai/chat/conversation/delete-by-unpinned`);
|
||||
}
|
||||
|
||||
// 获得【我的】聊天对话列表
|
||||
export function getChatConversationMyList() {
|
||||
return requestClient.get<AiChatConversationApi.ChatConversationVO[]>(
|
||||
`/ai/chat/conversation/my-list`,
|
||||
);
|
||||
}
|
||||
|
||||
// 获得【我的】聊天对话列表
|
||||
export function getChatConversationPage(params: any) {
|
||||
return requestClient.get<
|
||||
PageResult<AiChatConversationApi.ChatConversationVO[]>
|
||||
>(`/ai/chat/conversation/page`, { params });
|
||||
}
|
||||
|
||||
// 管理员删除消息
|
||||
export function deleteChatConversationByAdmin(id: number) {
|
||||
return requestClient.delete(`/ai/chat/conversation/delete-by-admin?id=${id}`);
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
import type { PageResult } from '@vben/request';
|
||||
|
||||
import { useAppConfig } from '@vben/hooks';
|
||||
import { fetchEventSource } from '@vben/request';
|
||||
import { useAccessStore } from '@vben/stores';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
|
||||
const accessStore = useAccessStore();
|
||||
export namespace AiChatMessageApi {
|
||||
export interface ChatMessageVO {
|
||||
id: number; // 编号
|
||||
conversationId: number; // 对话编号
|
||||
type: string; // 消息类型
|
||||
userId: string; // 用户编号
|
||||
roleId: string; // 角色编号
|
||||
model: number; // 模型标志
|
||||
modelId: number; // 模型编号
|
||||
content: string; // 聊天内容
|
||||
tokens: number; // 消耗 Token 数量
|
||||
segmentIds?: number[]; // 段落编号
|
||||
segments?: {
|
||||
content: string; // 段落内容
|
||||
documentId: number; // 文档编号
|
||||
documentName: string; // 文档名称
|
||||
id: number; // 段落编号
|
||||
}[];
|
||||
createTime: Date; // 创建时间
|
||||
roleAvatar: string; // 角色头像
|
||||
userAvatar: string; // 用户头像
|
||||
}
|
||||
}
|
||||
|
||||
// 消息列表
|
||||
export function getChatMessageListByConversationId(
|
||||
conversationId: null | number,
|
||||
) {
|
||||
return requestClient.get<AiChatMessageApi.ChatMessageVO[]>(
|
||||
`/ai/chat/message/list-by-conversation-id?conversationId=${conversationId}`,
|
||||
);
|
||||
}
|
||||
|
||||
// 发送 Stream 消息
|
||||
export function sendChatMessageStream(
|
||||
conversationId: number,
|
||||
content: string,
|
||||
ctrl: any,
|
||||
enableContext: boolean,
|
||||
onMessage: any,
|
||||
onError: any,
|
||||
onClose: any,
|
||||
) {
|
||||
const token = accessStore.accessToken;
|
||||
return fetchEventSource(`${apiURL}/ai/chat/message/send-stream`, {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
openWhenHidden: true,
|
||||
body: JSON.stringify({
|
||||
conversationId,
|
||||
content,
|
||||
useContext: enableContext,
|
||||
}),
|
||||
onmessage: onMessage,
|
||||
onerror: onError,
|
||||
onclose: onClose,
|
||||
signal: ctrl.signal,
|
||||
});
|
||||
}
|
||||
|
||||
// 删除消息
|
||||
export function deleteChatMessage(id: number) {
|
||||
return requestClient.delete(`/ai/chat/message/delete?id=${id}`);
|
||||
}
|
||||
|
||||
// 删除指定对话的消息
|
||||
export function deleteByConversationId(conversationId: number) {
|
||||
return requestClient.delete(
|
||||
`/ai/chat/message/delete-by-conversation-id?conversationId=${conversationId}`,
|
||||
);
|
||||
}
|
||||
// 获得消息分页
|
||||
export function getChatMessagePage(params: any) {
|
||||
return requestClient.get<PageResult<AiChatMessageApi.ChatMessageVO>>(
|
||||
'/ai/chat/message/page',
|
||||
{ params },
|
||||
);
|
||||
}
|
||||
// 管理员删除消息
|
||||
export function deleteChatMessageByAdmin(id: number) {
|
||||
return requestClient.delete(`/ai/chat/message/delete-by-admin?id=${id}`);
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace AiImageApi {
|
||||
export interface ImageMidjourneyButtonsVO {
|
||||
customId: string; // MJ::JOB::upsample::1::85a4b4c1-8835-46c5-a15c-aea34fad1862 动作标识
|
||||
emoji: string; // 图标 emoji
|
||||
label: string; // Make Variations 文本
|
||||
style: number; // 样式: 2(Primary)、3(Green)
|
||||
}
|
||||
// AI 绘图 VO
|
||||
export interface ImageVO {
|
||||
id: number; // 编号
|
||||
platform: string; // 平台
|
||||
model: string; // 模型
|
||||
prompt: string; // 提示词
|
||||
width: number; // 图片宽度
|
||||
height: number; // 图片高度
|
||||
status: number; // 状态
|
||||
publicStatus: boolean; // 公开状态
|
||||
picUrl: string; // 任务地址
|
||||
errorMessage: string; // 错误信息
|
||||
options: any; // 配置 Map<string, string>
|
||||
taskId: number; // 任务编号
|
||||
buttons: ImageMidjourneyButtonsVO[]; // mj 操作按钮
|
||||
createTime: Date; // 创建时间
|
||||
finishTime: Date; // 完成时间
|
||||
}
|
||||
|
||||
export interface ImageDrawReqVO {
|
||||
prompt: string; // 提示词
|
||||
modelId: number; // 模型
|
||||
style: string; // 图像生成的风格
|
||||
width: string; // 图片宽度
|
||||
height: string; // 图片高度
|
||||
options: object; // 绘制参数,Map<String, String>
|
||||
}
|
||||
|
||||
export interface ImageMidjourneyImagineReqVO {
|
||||
prompt: string; // 提示词
|
||||
modelId: number; // 模型
|
||||
base64Array?: string[]; // size不能为空
|
||||
width: string; // 图片宽度
|
||||
height: string; // 图片高度
|
||||
version: string; // 版本
|
||||
}
|
||||
|
||||
export interface ImageMidjourneyActionVO {
|
||||
id: number; // 图片编号
|
||||
customId: string; // MJ::JOB::upsample::1::85a4b4c1-8835-46c5-a15c-aea34fad1862 动作标识
|
||||
}
|
||||
}
|
||||
|
||||
// 获取【我的】绘图分页
|
||||
export function getImagePageMy(params: PageParam) {
|
||||
return requestClient.get<PageResult<AiImageApi.ImageVO>>(
|
||||
'/ai/image/my-page',
|
||||
{ params },
|
||||
);
|
||||
}
|
||||
|
||||
// 获取【我的】绘图记录
|
||||
export function getImageMy(id: number) {
|
||||
return requestClient.get<AiImageApi.ImageVO>(`/ai/image/get-my?id=${id}`);
|
||||
}
|
||||
|
||||
// 获取【我的】绘图记录列表
|
||||
export function getImageListMyByIds(ids: number[]) {
|
||||
return requestClient.get<AiImageApi.ImageVO[]>(`/ai/image/my-list-by-ids`, {
|
||||
params: { ids: ids.join(',') },
|
||||
});
|
||||
}
|
||||
|
||||
// 生成图片
|
||||
export function drawImage(data: AiImageApi.ImageDrawReqVO) {
|
||||
return requestClient.post(`/ai/image/draw`, data);
|
||||
}
|
||||
|
||||
// 删除【我的】绘画记录
|
||||
export function deleteImageMy(id: number) {
|
||||
return requestClient.delete(`/ai/image/delete-my?id=${id}`);
|
||||
}
|
||||
|
||||
// ================ midjourney 专属 ================
|
||||
// 【Midjourney】生成图片
|
||||
export function midjourneyImagine(
|
||||
data: AiImageApi.ImageMidjourneyImagineReqVO,
|
||||
) {
|
||||
return requestClient.post(`/ai/image/midjourney/imagine`, data);
|
||||
}
|
||||
|
||||
// 【Midjourney】Action 操作(二次生成图片)
|
||||
export function midjourneyAction(data: AiImageApi.ImageMidjourneyActionVO) {
|
||||
return requestClient.post(`/ai/image/midjourney/action`, data);
|
||||
}
|
||||
|
||||
// ================ 绘图管理 ================
|
||||
// 查询绘画分页
|
||||
export function getImagePage(params: any) {
|
||||
return requestClient.get<AiImageApi.ImageVO[]>(`/ai/image/page`, { params });
|
||||
}
|
||||
|
||||
// 更新绘画发布状态
|
||||
export function updateImage(data: any) {
|
||||
return requestClient.put(`/ai/image/update`, data);
|
||||
}
|
||||
|
||||
// 删除绘画
|
||||
export function deleteImage(id: number) {
|
||||
return requestClient.delete(`/ai/image/delete?id=${id}`);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace AiKnowledgeDocumentApi {
|
||||
export interface KnowledgeDocumentVO {
|
||||
id: number; // 编号
|
||||
knowledgeId: number; // 知识库编号
|
||||
name: string; // 文档名称
|
||||
contentLength: number; // 字符数
|
||||
tokens: number; // token 数
|
||||
segmentMaxTokens: number; // 分片最大 token 数
|
||||
retrievalCount: number; // 召回次数
|
||||
status: number; // 是否启用
|
||||
}
|
||||
}
|
||||
|
||||
// 查询知识库文档分页
|
||||
export function getKnowledgeDocumentPage(params: PageParam) {
|
||||
return requestClient.get<
|
||||
PageResult<AiKnowledgeDocumentApi.KnowledgeDocumentVO>
|
||||
>('/ai/knowledge/document/page', { params });
|
||||
}
|
||||
|
||||
// 查询知识库文档详情
|
||||
export function getKnowledgeDocument(id: number) {
|
||||
return requestClient.get(`/ai/knowledge/document/get?id=${id}`);
|
||||
}
|
||||
// 新增知识库文档(单个)
|
||||
export function createKnowledge(data: any) {
|
||||
return requestClient.post('/ai/knowledge/document/create', data);
|
||||
}
|
||||
// 新增知识库文档(多个)
|
||||
export function createKnowledgeDocumentList(data: any) {
|
||||
return requestClient.post('/ai/knowledge/document/create-list', data);
|
||||
}
|
||||
|
||||
// 修改知识库文档
|
||||
export function updateKnowledgeDocument(data: any) {
|
||||
return requestClient.put('/ai/knowledge/document/update', data);
|
||||
}
|
||||
|
||||
// 修改知识库文档状态
|
||||
export function updateKnowledgeDocumentStatus(data: any) {
|
||||
return requestClient.put('/ai/knowledge/document/update-status', data);
|
||||
}
|
||||
// 删除知识库文档
|
||||
export function deleteKnowledgeDocument(id: number) {
|
||||
return requestClient.delete(`/ai/knowledge/document/delete?id=${id}`);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace AiKnowledgeKnowledgeApi {
|
||||
export interface KnowledgeVO {
|
||||
id: number; // 编号
|
||||
name: string; // 知识库名称
|
||||
description: string; // 知识库描述
|
||||
embeddingModelId: number; // 嵌入模型编号,高质量模式时维护
|
||||
topK: number; // topK
|
||||
similarityThreshold: number; // 相似度阈值
|
||||
}
|
||||
}
|
||||
|
||||
// 查询知识库分页
|
||||
export function getKnowledgePage(params: PageParam) {
|
||||
return requestClient.get<PageResult<AiKnowledgeKnowledgeApi.KnowledgeVO>>(
|
||||
'/ai/knowledge/page',
|
||||
{ params },
|
||||
);
|
||||
}
|
||||
|
||||
// 查询知识库详情
|
||||
export function getKnowledge(id: number) {
|
||||
return requestClient.get<AiKnowledgeKnowledgeApi.KnowledgeVO>(
|
||||
`/ai/knowledge/get?id=${id}`,
|
||||
);
|
||||
}
|
||||
// 新增知识库
|
||||
export function createKnowledge(data: AiKnowledgeKnowledgeApi.KnowledgeVO) {
|
||||
return requestClient.post('/ai/knowledge/create', data);
|
||||
}
|
||||
|
||||
// 修改知识库
|
||||
export function updateKnowledge(data: AiKnowledgeKnowledgeApi.KnowledgeVO) {
|
||||
return requestClient.put('/ai/knowledge/update', data);
|
||||
}
|
||||
|
||||
// 删除知识库
|
||||
export function deleteKnowledge(id: number) {
|
||||
return requestClient.delete(`/ai/knowledge/delete?id=${id}`);
|
||||
}
|
||||
|
||||
// 获取知识库简单列表
|
||||
export function getSimpleKnowledgeList() {
|
||||
return requestClient.get<AiKnowledgeKnowledgeApi.KnowledgeVO[]>(
|
||||
'/ai/knowledge/simple-list',
|
||||
);
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace AiKnowledgeSegmentApi {
|
||||
// AI 知识库分段 VO
|
||||
export interface KnowledgeSegmentVO {
|
||||
id: number; // 编号
|
||||
documentId: number; // 文档编号
|
||||
knowledgeId: number; // 知识库编号
|
||||
vectorId: string; // 向量库编号
|
||||
content: string; // 切片内容
|
||||
contentLength: number; // 切片内容长度
|
||||
tokens: number; // token 数量
|
||||
retrievalCount: number; // 召回次数
|
||||
status: number; // 文档状态
|
||||
createTime: number; // 创建时间
|
||||
}
|
||||
}
|
||||
|
||||
// 查询知识库分段分页
|
||||
export function getKnowledgeSegmentPage(params: PageParam) {
|
||||
return requestClient.get<
|
||||
PageResult<AiKnowledgeSegmentApi.KnowledgeSegmentVO>
|
||||
>('/ai/knowledge/segment/page', { params });
|
||||
}
|
||||
|
||||
// 查询知识库分段详情
|
||||
export function getKnowledgeSegment(id: number) {
|
||||
return requestClient.get<AiKnowledgeSegmentApi.KnowledgeSegmentVO>(
|
||||
`/ai/knowledge/segment/get?id=${id}`,
|
||||
);
|
||||
}
|
||||
// 新增知识库分段
|
||||
export function createKnowledgeSegment(
|
||||
data: AiKnowledgeSegmentApi.KnowledgeSegmentVO,
|
||||
) {
|
||||
return requestClient.post('/ai/knowledge/segment/create', data);
|
||||
}
|
||||
|
||||
// 修改知识库分段
|
||||
export function updateKnowledgeSegment(
|
||||
data: AiKnowledgeSegmentApi.KnowledgeSegmentVO,
|
||||
) {
|
||||
return requestClient.put('/ai/knowledge/segment/update', data);
|
||||
}
|
||||
|
||||
// 修改知识库分段状态
|
||||
export function updateKnowledgeSegmentStatus(data: any) {
|
||||
return requestClient.put('/ai/knowledge/segment/update-status', data);
|
||||
}
|
||||
// 删除知识库分段
|
||||
export function deleteKnowledgeSegment(id: number) {
|
||||
return requestClient.delete(`/ai/knowledge/segment/delete?id=${id}`);
|
||||
}
|
||||
|
||||
// 切片内容
|
||||
export function splitContent(url: string, segmentMaxTokens: number) {
|
||||
return requestClient.get('/ai/knowledge/segment/split', {
|
||||
params: { url, segmentMaxTokens },
|
||||
});
|
||||
}
|
||||
|
||||
// 获取文档处理列表
|
||||
export function getKnowledgeSegmentProcessList(documentIds: number[]) {
|
||||
return requestClient.get('/ai/knowledge/segment/get-process-list', {
|
||||
params: { documentIds: documentIds.join(',') },
|
||||
});
|
||||
}
|
||||
|
||||
// 搜索知识库分段
|
||||
export function searchKnowledgeSegment(params: any) {
|
||||
return requestClient.get('/ai/knowledge/segment/search', {
|
||||
params,
|
||||
});
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
import { useAppConfig } from '@vben/hooks';
|
||||
import { fetchEventSource } from '@vben/request';
|
||||
import { useAccessStore } from '@vben/stores';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
|
||||
const accessStore = useAccessStore();
|
||||
export namespace AiMindmapApi {
|
||||
// AI 思维导图 VO
|
||||
export interface MindMapVO {
|
||||
id: number; // 编号
|
||||
userId: number; // 用户编号
|
||||
prompt: string; // 生成内容提示
|
||||
generatedContent: string; // 生成的思维导图内容
|
||||
platform: string; // 平台
|
||||
model: string; // 模型
|
||||
errorMessage: string; // 错误信息
|
||||
}
|
||||
|
||||
// AI 思维导图生成 VO
|
||||
export interface AiMindMapGenerateReqVO {
|
||||
prompt: string;
|
||||
}
|
||||
}
|
||||
|
||||
export function generateMindMap({
|
||||
data,
|
||||
onClose,
|
||||
onMessage,
|
||||
onError,
|
||||
ctrl,
|
||||
}: {
|
||||
ctrl: AbortController;
|
||||
data: AiMindmapApi.AiMindMapGenerateReqVO;
|
||||
onClose?: (...args: any[]) => void;
|
||||
onError?: (...args: any[]) => void;
|
||||
onMessage?: (res: any) => void;
|
||||
}) {
|
||||
const token = accessStore.accessToken;
|
||||
return fetchEventSource(`${apiURL}/ai/mind-map/generate-stream`, {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
openWhenHidden: true,
|
||||
body: JSON.stringify(data),
|
||||
onmessage: onMessage,
|
||||
onerror: onError,
|
||||
onclose: onClose,
|
||||
signal: ctrl.signal,
|
||||
});
|
||||
}
|
||||
|
||||
// 查询思维导图分页
|
||||
export function getMindMapPage(params: any) {
|
||||
return requestClient.get(`/ai/mind-map/page`, { params });
|
||||
}
|
||||
|
||||
// 删除思维导图
|
||||
export function deleteMindMap(id: number) {
|
||||
return requestClient.delete(`/ai/mind-map/delete?id=${id}`);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace AiModelApiKeyApi {
|
||||
export interface ApiKeyVO {
|
||||
id: number; // 编号
|
||||
name: string; // 名称
|
||||
apiKey: string; // 密钥
|
||||
platform: string; // 平台
|
||||
url: string; // 自定义 API 地址
|
||||
status: number; // 状态
|
||||
}
|
||||
}
|
||||
|
||||
// 查询 API 密钥分页
|
||||
export function getApiKeyPage(params: PageParam) {
|
||||
return requestClient.get<PageResult<AiModelApiKeyApi.ApiKeyVO>>(
|
||||
'/ai/api-key/page',
|
||||
{ params },
|
||||
);
|
||||
}
|
||||
|
||||
// 获得 API 密钥列表
|
||||
export function getApiKeySimpleList() {
|
||||
return requestClient.get<AiModelApiKeyApi.ApiKeyVO[]>(
|
||||
'/ai/api-key/simple-list',
|
||||
);
|
||||
}
|
||||
|
||||
// 查询 API 密钥详情
|
||||
export function getApiKey(id: number) {
|
||||
return requestClient.get<AiModelApiKeyApi.ApiKeyVO>(
|
||||
`/ai/api-key/get?id=${id}`,
|
||||
);
|
||||
}
|
||||
// 新增 API 密钥
|
||||
export function createApiKey(data: AiModelApiKeyApi.ApiKeyVO) {
|
||||
return requestClient.post('/ai/api-key/create', data);
|
||||
}
|
||||
|
||||
// 修改 API 密钥
|
||||
export function updateApiKey(data: AiModelApiKeyApi.ApiKeyVO) {
|
||||
return requestClient.put('/ai/api-key/update', data);
|
||||
}
|
||||
|
||||
// 删除 API 密钥
|
||||
export function deleteApiKey(id: number) {
|
||||
return requestClient.delete(`/ai/api-key/delete?id=${id}`);
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace AiModelChatRoleApi {
|
||||
export interface ChatRoleVO {
|
||||
id: number; // 角色编号
|
||||
modelId: number; // 模型编号
|
||||
name: string; // 角色名称
|
||||
avatar: string; // 角色头像
|
||||
category: string; // 角色类别
|
||||
sort: number; // 角色排序
|
||||
description: string; // 角色描述
|
||||
systemMessage: string; // 角色设定
|
||||
welcomeMessage: string; // 角色设定
|
||||
publicStatus: boolean; // 是否公开
|
||||
status: number; // 状态
|
||||
knowledgeIds?: number[]; // 引用的知识库 ID 列表
|
||||
toolIds?: number[]; // 引用的工具 ID 列表
|
||||
}
|
||||
|
||||
// AI 聊天角色 分页请求 vo
|
||||
export interface ChatRolePageReqVO {
|
||||
name?: string; // 角色名称
|
||||
category?: string; // 角色类别
|
||||
publicStatus: boolean; // 是否公开
|
||||
pageNo: number; // 是否公开
|
||||
pageSize: number; // 是否公开
|
||||
}
|
||||
}
|
||||
|
||||
// 查询聊天角色分页
|
||||
export function getChatRolePage(params: PageParam) {
|
||||
return requestClient.get<PageResult<AiModelChatRoleApi.ChatRoleVO>>(
|
||||
'/ai/chat-role/page',
|
||||
{ params },
|
||||
);
|
||||
}
|
||||
|
||||
// 查询聊天角色详情
|
||||
export function getChatRole(id: number) {
|
||||
return requestClient.get<AiModelChatRoleApi.ChatRoleVO>(
|
||||
`/ai/chat-role/get?id=${id}`,
|
||||
);
|
||||
}
|
||||
// 新增聊天角色
|
||||
export function createChatRole(data: AiModelChatRoleApi.ChatRoleVO) {
|
||||
return requestClient.post('/ai/chat-role/create', data);
|
||||
}
|
||||
|
||||
// 修改聊天角色
|
||||
export function updateChatRole(data: AiModelChatRoleApi.ChatRoleVO) {
|
||||
return requestClient.put('/ai/chat-role/update', data);
|
||||
}
|
||||
|
||||
// 删除聊天角色
|
||||
export function deleteChatRole(id: number) {
|
||||
return requestClient.delete(`/ai/chat-role/delete?id=${id}`);
|
||||
}
|
||||
|
||||
// ======= chat 聊天
|
||||
// 获取 my role
|
||||
export function getMyPage(params: AiModelChatRoleApi.ChatRolePageReqVO) {
|
||||
return requestClient.get('/ai/chat-role/my-page', { params });
|
||||
}
|
||||
|
||||
// 获取角色分类
|
||||
export function getCategoryList() {
|
||||
return requestClient.get('/ai/chat-role/category-list');
|
||||
}
|
||||
|
||||
// 创建角色
|
||||
export function createMy(data: AiModelChatRoleApi.ChatRoleVO) {
|
||||
return requestClient.post('/ai/chat-role/create-my', data);
|
||||
}
|
||||
|
||||
// 更新角色
|
||||
export function updateMy(data: AiModelChatRoleApi.ChatRoleVO) {
|
||||
return requestClient.put('/ai/chat-role/update', data);
|
||||
}
|
||||
|
||||
// 删除角色 my
|
||||
export function deleteMy(id: number) {
|
||||
return requestClient.delete(`/ai/chat-role/delete-my?id=${id}`);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace AiModelModelApi {
|
||||
export interface ModelVO {
|
||||
id: number; // 编号
|
||||
keyId: number; // API 秘钥编号
|
||||
name: string; // 模型名字
|
||||
model: string; // 模型标识
|
||||
platform: string; // 模型平台
|
||||
type: number; // 模型类型
|
||||
sort: number; // 排序
|
||||
status: number; // 状态
|
||||
temperature?: number; // 温度参数
|
||||
maxTokens?: number; // 单条回复的最大 Token 数量
|
||||
maxContexts?: number; // 上下文的最大 Message 数量
|
||||
}
|
||||
}
|
||||
|
||||
// 查询模型分页
|
||||
export function getModelPage(params: PageParam) {
|
||||
return requestClient.get<PageResult<AiModelModelApi.ModelVO>>(
|
||||
'/ai/model/page',
|
||||
{ params },
|
||||
);
|
||||
}
|
||||
|
||||
// 获得模型列表
|
||||
export function getModelSimpleList(type?: number) {
|
||||
return requestClient.get<AiModelModelApi.ModelVO[]>('/ai/model/simple-list', {
|
||||
params: {
|
||||
type,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 查询模型详情
|
||||
export function getModel(id: number) {
|
||||
return requestClient.get<AiModelModelApi.ModelVO>(`/ai/model/get?id=${id}`);
|
||||
}
|
||||
// 新增模型
|
||||
export function createModel(data: AiModelModelApi.ModelVO) {
|
||||
return requestClient.post('/ai/model/create', data);
|
||||
}
|
||||
|
||||
// 修改模型
|
||||
export function updateModel(data: AiModelModelApi.ModelVO) {
|
||||
return requestClient.put('/ai/model/update', data);
|
||||
}
|
||||
|
||||
// 删除模型
|
||||
export function deleteModel(id: number) {
|
||||
return requestClient.delete(`/ai/model/delete?id=${id}`);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace AiModelToolApi {
|
||||
export interface ToolVO {
|
||||
id: number; // 工具编号
|
||||
name: string; // 工具名称
|
||||
description: string; // 工具描述
|
||||
status: number; // 状态
|
||||
}
|
||||
}
|
||||
|
||||
// 查询工具分页
|
||||
export function getToolPage(params: PageParam) {
|
||||
return requestClient.get<PageResult<AiModelToolApi.ToolVO>>('/ai/tool/page', {
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 查询工具详情
|
||||
export function getTool(id: number) {
|
||||
return requestClient.get<AiModelToolApi.ToolVO>(`/ai/tool/get?id=${id}`);
|
||||
}
|
||||
// 新增工具
|
||||
export function createTool(data: AiModelToolApi.ToolVO) {
|
||||
return requestClient.post('/ai/tool/create', data);
|
||||
}
|
||||
|
||||
// 修改工具
|
||||
export function updateTool(data: AiModelToolApi.ToolVO) {
|
||||
return requestClient.put('/ai/tool/update', data);
|
||||
}
|
||||
|
||||
// 删除工具
|
||||
export function deleteTool(id: number) {
|
||||
return requestClient.delete(`/ai/tool/delete?id=${id}`);
|
||||
}
|
||||
|
||||
// 获取工具简单列表
|
||||
export function getToolSimpleList() {
|
||||
return requestClient.get<AiModelToolApi.ToolVO[]>('/ai/tool/simple-list');
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace AiMusicApi {
|
||||
// AI 音乐 VO
|
||||
export interface MusicVO {
|
||||
id: number; // 编号
|
||||
userId: number; // 用户编号
|
||||
title: string; // 音乐名称
|
||||
lyric: string; // 歌词
|
||||
imageUrl: string; // 图片地址
|
||||
audioUrl: string; // 音频地址
|
||||
videoUrl: string; // 视频地址
|
||||
status: number; // 音乐状态
|
||||
gptDescriptionPrompt: string; // 描述词
|
||||
prompt: string; // 提示词
|
||||
platform: string; // 模型平台
|
||||
model: string; // 模型
|
||||
generateMode: number; // 生成模式
|
||||
tags: string; // 音乐风格标签
|
||||
duration: number; // 音乐时长
|
||||
publicStatus: boolean; // 是否发布
|
||||
taskId: string; // 任务id
|
||||
errorMessage: string; // 错误信息
|
||||
}
|
||||
}
|
||||
|
||||
// 查询音乐分页
|
||||
export function getMusicPage(params: PageParam) {
|
||||
return requestClient.get<PageResult<AiMusicApi.MusicVO>>(`/ai/music/page`, {
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 更新音乐
|
||||
export function updateMusic(data: any) {
|
||||
return requestClient.put('/ai/music/update', data);
|
||||
}
|
||||
|
||||
// 删除音乐
|
||||
export function deleteMusic(id: number) {
|
||||
return requestClient.delete(`/ai/music/delete?id=${id}`);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export function getWorkflowPage(params: PageParam) {
|
||||
return requestClient.get<PageResult<any>>('/ai/workflow/page', {
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
export const getWorkflow = (id: number | string) => {
|
||||
return requestClient.get(`/ai/workflow/get?id=${id}`);
|
||||
};
|
||||
|
||||
export const createWorkflow = (data: any) => {
|
||||
return requestClient.post('/ai/workflow/create', data);
|
||||
};
|
||||
|
||||
export const updateWorkflow = (data: any) => {
|
||||
return requestClient.put('/ai/workflow/update', data);
|
||||
};
|
||||
|
||||
export const deleteWorkflow = (id: number | string) => {
|
||||
return requestClient.delete(`/ai/workflow/delete?id=${id}`);
|
||||
};
|
||||
|
||||
export const testWorkflow = (data: any) => {
|
||||
return requestClient.post('/ai/workflow/test', data);
|
||||
};
|
|
@ -0,0 +1,95 @@
|
|||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import type { AiWriteTypeEnum } from '#/utils';
|
||||
|
||||
import { useAppConfig } from '@vben/hooks';
|
||||
import { fetchEventSource } from '@vben/request';
|
||||
import { useAccessStore } from '@vben/stores';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
|
||||
const accessStore = useAccessStore();
|
||||
export namespace AiWriteApi {
|
||||
export interface WriteVO {
|
||||
type: AiWriteTypeEnum.REPLY | AiWriteTypeEnum.WRITING; // 1:撰写 2:回复
|
||||
prompt: string; // 写作内容提示 1。撰写 2回复
|
||||
originalContent: string; // 原文
|
||||
length: number; // 长度
|
||||
format: number; // 格式
|
||||
tone: number; // 语气
|
||||
language: number; // 语言
|
||||
userId?: number; // 用户编号
|
||||
platform?: string; // 平台
|
||||
model?: string; // 模型
|
||||
generatedContent?: string; // 生成的内容
|
||||
errorMessage?: string; // 错误信息
|
||||
createTime?: Date; // 创建时间
|
||||
}
|
||||
|
||||
export interface AiWritePageReqVO extends PageParam {
|
||||
userId?: number; // 用户编号
|
||||
type?: AiWriteTypeEnum; // 写作类型
|
||||
platform?: string; // 平台
|
||||
createTime?: [string, string]; // 创建时间
|
||||
}
|
||||
|
||||
export interface AiWriteRespVo {
|
||||
id: number;
|
||||
userId: number;
|
||||
type: number;
|
||||
platform: string;
|
||||
model: string;
|
||||
prompt: string;
|
||||
generatedContent: string;
|
||||
originalContent: string;
|
||||
length: number;
|
||||
format: number;
|
||||
tone: number;
|
||||
language: number;
|
||||
errorMessage: string;
|
||||
createTime: string;
|
||||
}
|
||||
}
|
||||
|
||||
export function writeStream({
|
||||
data,
|
||||
onClose,
|
||||
onMessage,
|
||||
onError,
|
||||
ctrl,
|
||||
}: {
|
||||
ctrl: AbortController;
|
||||
data: Partial<AiWriteApi.WriteVO>;
|
||||
onClose?: (...args: any[]) => void;
|
||||
onError?: (...args: any[]) => void;
|
||||
onMessage?: (res: any) => void;
|
||||
}) {
|
||||
const token = accessStore.accessToken;
|
||||
return fetchEventSource(`${apiURL}/ai/write/generate-stream`, {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
openWhenHidden: true,
|
||||
body: JSON.stringify(data),
|
||||
onmessage: onMessage,
|
||||
onerror: onError,
|
||||
onclose: onClose,
|
||||
signal: ctrl.signal,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取写作列表
|
||||
export function getWritePage(params: any) {
|
||||
return requestClient.get<PageResult<AiWriteApi.AiWritePageReqVO>>(
|
||||
`/ai/write/page`,
|
||||
{ params },
|
||||
);
|
||||
}
|
||||
|
||||
// 删除音乐
|
||||
export function deleteWrite(id: number) {
|
||||
return requestClient.delete(`/ai/write/delete`, { params: { id } });
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace ProductUnitApi {
|
||||
/** 产品单位信息 */
|
||||
export interface ProductUnit {
|
||||
id: number; // 编号
|
||||
groupId?: number; // 分组编号
|
||||
name?: string; // 单位名称
|
||||
basic?: number; // 基础单位
|
||||
number?: number; // 单位数量/相对于基础单位
|
||||
usageType: number; // 用途
|
||||
}
|
||||
}
|
||||
|
||||
/** 查询产品单位分页 */
|
||||
export function getProductUnitPage(params: PageParam) {
|
||||
return requestClient.get<PageResult<ProductUnitApi.ProductUnit>>(
|
||||
'/basic/product-unit/page',
|
||||
{ params },
|
||||
);
|
||||
}
|
||||
|
||||
/** 查询产品单位详情 */
|
||||
export function getProductUnit(id: number) {
|
||||
return requestClient.get<ProductUnitApi.ProductUnit>(
|
||||
`/basic/product-unit/get?id=${id}`,
|
||||
);
|
||||
}
|
||||
|
||||
/** 新增产品单位 */
|
||||
export function createProductUnit(data: ProductUnitApi.ProductUnit) {
|
||||
return requestClient.post('/basic/product-unit/create', data);
|
||||
}
|
||||
|
||||
/** 修改产品单位 */
|
||||
export function updateProductUnit(data: ProductUnitApi.ProductUnit) {
|
||||
return requestClient.put('/basic/product-unit/update', data);
|
||||
}
|
||||
|
||||
/** 删除产品单位 */
|
||||
export function deleteProductUnit(id: number) {
|
||||
return requestClient.delete(`/basic/product-unit/delete?id=${id}`);
|
||||
}
|
||||
|
||||
/** 批量删除产品单位 */
|
||||
export function deleteProductUnitListByIds(ids: number[]) {
|
||||
return requestClient.delete(
|
||||
`/basic/product-unit/delete-list?ids=${ids.join(',')}`,
|
||||
);
|
||||
}
|
||||
|
||||
/** 导出产品单位 */
|
||||
export function exportProductUnit(params: any) {
|
||||
return requestClient.download('/basic/product-unit/export-excel', params);
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace ProductUnitGroupApi {
|
||||
/** 产品单位组信息 */
|
||||
export interface ProductUnitGroup {
|
||||
id: number; // 编号
|
||||
name?: string; // 产品单位组名称
|
||||
status?: number; // 开启状态
|
||||
}
|
||||
}
|
||||
|
||||
/** 查询产品单位组分页 */
|
||||
export function getProductUnitGroupPage(params: PageParam) {
|
||||
return requestClient.get<PageResult<ProductUnitGroupApi.ProductUnitGroup>>(
|
||||
'/basic/product-unit-group/page',
|
||||
{ params },
|
||||
);
|
||||
}
|
||||
|
||||
/** 查询产品单位组详情 */
|
||||
export function getProductUnitGroup(id: number) {
|
||||
return requestClient.get<ProductUnitGroupApi.ProductUnitGroup>(
|
||||
`/basic/product-unit-group/get?id=${id}`,
|
||||
);
|
||||
}
|
||||
|
||||
/** 新增产品单位组 */
|
||||
export function createProductUnitGroup(
|
||||
data: ProductUnitGroupApi.ProductUnitGroup,
|
||||
) {
|
||||
return requestClient.post('/basic/product-unit-group/create', data);
|
||||
}
|
||||
|
||||
/** 修改产品单位组 */
|
||||
export function updateProductUnitGroup(
|
||||
data: ProductUnitGroupApi.ProductUnitGroup,
|
||||
) {
|
||||
return requestClient.put('/basic/product-unit-group/update', data);
|
||||
}
|
||||
|
||||
/** 删除产品单位组 */
|
||||
export function deleteProductUnitGroup(id: number) {
|
||||
return requestClient.delete(`/basic/product-unit-group/delete?id=${id}`);
|
||||
}
|
||||
|
||||
/** 批量删除产品单位组 */
|
||||
export function deleteProductUnitGroupListByIds(ids: number[]) {
|
||||
return requestClient.delete(
|
||||
`/basic/product-unit-group/delete-list?ids=${ids.join(',')}`,
|
||||
);
|
||||
}
|
||||
|
||||
/** 导出产品单位组 */
|
||||
export function exportProductUnitGroup(params: any) {
|
||||
return requestClient.download(
|
||||
'/basic/product-unit-group/export-excel',
|
||||
params,
|
||||
);
|
||||
}
|
|
@ -4,8 +4,7 @@ import { requestClient } from '#/api/request';
|
|||
|
||||
export namespace BpmProcessDefinitionApi {
|
||||
/** 流程定义 */
|
||||
// TODO @ziye:不用 VO 后缀哈
|
||||
export interface ProcessDefinitionVO {
|
||||
export interface ProcessDefinition {
|
||||
id: string;
|
||||
version: number;
|
||||
deploymentTime: number;
|
||||
|
@ -21,7 +20,7 @@ export namespace BpmProcessDefinitionApi {
|
|||
|
||||
/** 查询流程定义 */
|
||||
export async function getProcessDefinition(id?: string, key?: string) {
|
||||
return requestClient.get<BpmProcessDefinitionApi.ProcessDefinitionVO>(
|
||||
return requestClient.get<BpmProcessDefinitionApi.ProcessDefinition>(
|
||||
'/bpm/process-definition/get',
|
||||
{
|
||||
params: { id, key },
|
||||
|
@ -32,13 +31,13 @@ export async function getProcessDefinition(id?: string, key?: string) {
|
|||
/** 分页查询流程定义 */
|
||||
export async function getProcessDefinitionPage(params: PageParam) {
|
||||
return requestClient.get<
|
||||
PageResult<BpmProcessDefinitionApi.ProcessDefinitionVO>
|
||||
PageResult<BpmProcessDefinitionApi.ProcessDefinition>
|
||||
>('/bpm/process-definition/page', { params });
|
||||
}
|
||||
|
||||
/** 查询流程定义列表 */
|
||||
export async function getProcessDefinitionList(params: any) {
|
||||
return requestClient.get<BpmProcessDefinitionApi.ProcessDefinitionVO[]>(
|
||||
return requestClient.get<BpmProcessDefinitionApi.ProcessDefinition[]>(
|
||||
'/bpm/process-definition/list',
|
||||
{
|
||||
params,
|
||||
|
@ -49,6 +48,6 @@ export async function getProcessDefinitionList(params: any) {
|
|||
/** 查询流程定义列表(简单列表) */
|
||||
export async function getSimpleProcessDefinitionList() {
|
||||
return requestClient.get<
|
||||
PageResult<BpmProcessDefinitionApi.ProcessDefinitionVO>
|
||||
PageResult<BpmProcessDefinitionApi.ProcessDefinition>
|
||||
>('/bpm/process-definition/simple-list');
|
||||
}
|
||||
|
|
|
@ -4,8 +4,7 @@ import { requestClient } from '#/api/request';
|
|||
|
||||
export namespace BpmFormApi {
|
||||
/** 流程表单 */
|
||||
// TODO @ziye:不用 VO 后缀哈
|
||||
export interface FormVO {
|
||||
export interface Form {
|
||||
id?: number | undefined;
|
||||
name: string;
|
||||
conf: string;
|
||||
|
@ -18,24 +17,23 @@ export namespace BpmFormApi {
|
|||
|
||||
/** 获取表单分页列表 */
|
||||
export async function getFormPage(params: PageParam) {
|
||||
return requestClient.get<PageResult<BpmFormApi.FormVO>>('/bpm/form/page', {
|
||||
return requestClient.get<PageResult<BpmFormApi.Form>>('/bpm/form/page', {
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取表单详情 */
|
||||
// TODO @ziye:应该不会 string 的情况呢。
|
||||
export async function getFormDetail(id: number | string) {
|
||||
return requestClient.get<BpmFormApi.FormVO>(`/bpm/form/get?id=${id}`);
|
||||
export async function getFormDetail(id: number) {
|
||||
return requestClient.get<BpmFormApi.Form>(`/bpm/form/get?id=${id}`);
|
||||
}
|
||||
|
||||
/** 创建表单 */
|
||||
export async function createForm(data: BpmFormApi.FormVO) {
|
||||
export async function createForm(data: BpmFormApi.Form) {
|
||||
return requestClient.post('/bpm/form/create', data);
|
||||
}
|
||||
|
||||
/** 更新表单 */
|
||||
export async function updateForm(data: BpmFormApi.FormVO) {
|
||||
export async function updateForm(data: BpmFormApi.Form) {
|
||||
return requestClient.put('/bpm/form/update', data);
|
||||
}
|
||||
|
||||
|
@ -46,5 +44,5 @@ export async function deleteForm(id: number) {
|
|||
|
||||
/** 获取表单简单列表 */
|
||||
export async function getFormSimpleList() {
|
||||
return requestClient.get<BpmFormApi.FormVO[]>('/bpm/form/simple-list');
|
||||
return requestClient.get<BpmFormApi.Form[]>('/bpm/form/simple-list');
|
||||
}
|
||||
|
|
|
@ -3,8 +3,7 @@ import type { PageParam, PageResult } from '@vben/request';
|
|||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace BpmOALeaveApi {
|
||||
// TODO @ziye:不用 VO 后缀
|
||||
export interface LeaveVO {
|
||||
export interface Leave {
|
||||
id: number;
|
||||
status: number;
|
||||
type: number;
|
||||
|
@ -18,23 +17,23 @@ export namespace BpmOALeaveApi {
|
|||
}
|
||||
|
||||
/** 创建请假申请 */
|
||||
export async function createLeave(data: BpmOALeaveApi.LeaveVO) {
|
||||
export async function createLeave(data: BpmOALeaveApi.Leave) {
|
||||
return requestClient.post('/bpm/oa/leave/create', data);
|
||||
}
|
||||
|
||||
/** 更新请假申请 */
|
||||
export async function updateLeave(data: BpmOALeaveApi.LeaveVO) {
|
||||
export async function updateLeave(data: BpmOALeaveApi.Leave) {
|
||||
return requestClient.post('/bpm/oa/leave/update', data);
|
||||
}
|
||||
|
||||
/** 获得请假申请 */
|
||||
export async function getLeave(id: number) {
|
||||
return requestClient.get<BpmOALeaveApi.LeaveVO>(`/bpm/oa/leave/get?id=${id}`);
|
||||
return requestClient.get<BpmOALeaveApi.Leave>(`/bpm/oa/leave/get?id=${id}`);
|
||||
}
|
||||
|
||||
/** 获得请假申请分页 */
|
||||
export async function getLeavePage(params: PageParam) {
|
||||
return requestClient.get<PageResult<BpmOALeaveApi.LeaveVO>>(
|
||||
return requestClient.get<PageResult<BpmOALeaveApi.Leave>>(
|
||||
'/bpm/oa/leave/page',
|
||||
{ params },
|
||||
);
|
||||
|
|
|
@ -3,9 +3,8 @@ import type { PageParam, PageResult } from '@vben/request';
|
|||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace BpmProcessExpressionApi {
|
||||
// TODO @ziye:不用 VO 后缀
|
||||
/** 流程表达式 VO */
|
||||
export interface ProcessExpressionVO {
|
||||
/** 流程表达式 */
|
||||
export interface ProcessExpression {
|
||||
id: number; // 编号
|
||||
name: string; // 表达式名字
|
||||
status: number; // 表达式状态
|
||||
|
@ -16,27 +15,27 @@ export namespace BpmProcessExpressionApi {
|
|||
/** 查询流程表达式分页 */
|
||||
export async function getProcessExpressionPage(params: PageParam) {
|
||||
return requestClient.get<
|
||||
PageResult<BpmProcessExpressionApi.ProcessExpressionVO>
|
||||
PageResult<BpmProcessExpressionApi.ProcessExpression>
|
||||
>('/bpm/process-expression/page', { params });
|
||||
}
|
||||
|
||||
/** 查询流程表达式详情 */
|
||||
export async function getProcessExpression(id: number) {
|
||||
return requestClient.get<BpmProcessExpressionApi.ProcessExpressionVO>(
|
||||
return requestClient.get<BpmProcessExpressionApi.ProcessExpression>(
|
||||
`/bpm/process-expression/get?id=${id}`,
|
||||
);
|
||||
}
|
||||
|
||||
/** 新增流程表达式 */
|
||||
export async function createProcessExpression(
|
||||
data: BpmProcessExpressionApi.ProcessExpressionVO,
|
||||
data: BpmProcessExpressionApi.ProcessExpression,
|
||||
) {
|
||||
return requestClient.post<number>('/bpm/process-expression/create', data);
|
||||
}
|
||||
|
||||
/** 修改流程表达式 */
|
||||
export async function updateProcessExpression(
|
||||
data: BpmProcessExpressionApi.ProcessExpressionVO,
|
||||
data: BpmProcessExpressionApi.ProcessExpression,
|
||||
) {
|
||||
return requestClient.put<boolean>('/bpm/process-expression/update', data);
|
||||
}
|
||||
|
|
|
@ -9,29 +9,29 @@ import { requestClient } from '#/api/request';
|
|||
|
||||
export namespace BpmProcessInstanceApi {
|
||||
// TODO @芋艿:一些注释缺少或者不对;
|
||||
export type Task = {
|
||||
export interface Task {
|
||||
id: number;
|
||||
name: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type User = {
|
||||
export interface User {
|
||||
avatar: string;
|
||||
id: number;
|
||||
nickname: string;
|
||||
};
|
||||
}
|
||||
|
||||
// 审批任务信息
|
||||
export type ApprovalTaskInfo = {
|
||||
export interface ApprovalTaskInfo {
|
||||
assigneeUser: User;
|
||||
id: number;
|
||||
ownerUser: User;
|
||||
reason: string;
|
||||
signPicUrl: string;
|
||||
status: number;
|
||||
};
|
||||
}
|
||||
|
||||
// 审批节点信息
|
||||
export type ApprovalNodeInfo = {
|
||||
export interface ApprovalNodeInfo {
|
||||
candidateStrategy?: BpmCandidateStrategyEnum;
|
||||
candidateUsers?: User[];
|
||||
endTime?: Date;
|
||||
|
@ -41,10 +41,10 @@ export namespace BpmProcessInstanceApi {
|
|||
startTime?: Date;
|
||||
status: number;
|
||||
tasks: ApprovalTaskInfo[];
|
||||
};
|
||||
}
|
||||
|
||||
/** 流程实例 */
|
||||
export type ProcessInstanceVO = {
|
||||
export interface ProcessInstance {
|
||||
businessKey: string;
|
||||
category: string;
|
||||
createTime: string;
|
||||
|
@ -61,20 +61,20 @@ export namespace BpmProcessInstanceApi {
|
|||
startUser?: User;
|
||||
status: number;
|
||||
tasks?: BpmProcessInstanceApi.Task[];
|
||||
};
|
||||
}
|
||||
|
||||
// 审批详情
|
||||
export type ApprovalDetail = {
|
||||
export interface ApprovalDetail {
|
||||
activityNodes: BpmProcessInstanceApi.ApprovalNodeInfo[];
|
||||
formFieldsPermission: any;
|
||||
processDefinition: BpmModelApi.ProcessDefinition;
|
||||
processInstance: BpmProcessInstanceApi.ProcessInstanceVO;
|
||||
processInstance: BpmProcessInstanceApi.ProcessInstance;
|
||||
status: number;
|
||||
todoTask: BpmTaskApi.TaskVO;
|
||||
};
|
||||
todoTask: BpmTaskApi.Task;
|
||||
}
|
||||
|
||||
// 抄送流程实例 VO
|
||||
export type CopyVO = {
|
||||
// 抄送流程实例
|
||||
export interface Copy {
|
||||
activityId: string;
|
||||
activityName: string;
|
||||
createTime: number;
|
||||
|
@ -90,12 +90,12 @@ export namespace BpmProcessInstanceApi {
|
|||
value: string;
|
||||
}[];
|
||||
taskId: string;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/** 查询我的流程实例分页 */
|
||||
export async function getProcessInstanceMyPage(params: PageParam) {
|
||||
return requestClient.get<PageResult<BpmProcessInstanceApi.ProcessInstanceVO>>(
|
||||
return requestClient.get<PageResult<BpmProcessInstanceApi.ProcessInstance>>(
|
||||
'/bpm/process-instance/my-page',
|
||||
{ params },
|
||||
);
|
||||
|
@ -103,7 +103,7 @@ export async function getProcessInstanceMyPage(params: PageParam) {
|
|||
|
||||
/** 查询管理员流程实例分页 */
|
||||
export async function getProcessInstanceManagerPage(params: PageParam) {
|
||||
return requestClient.get<PageResult<BpmProcessInstanceApi.ProcessInstanceVO>>(
|
||||
return requestClient.get<PageResult<BpmProcessInstanceApi.ProcessInstance>>(
|
||||
'/bpm/process-instance/manager-page',
|
||||
{ params },
|
||||
);
|
||||
|
@ -111,7 +111,7 @@ export async function getProcessInstanceManagerPage(params: PageParam) {
|
|||
|
||||
/** 新增流程实例 */
|
||||
export async function createProcessInstance(data: any) {
|
||||
return requestClient.post<BpmProcessInstanceApi.ProcessInstanceVO>(
|
||||
return requestClient.post<BpmProcessInstanceApi.ProcessInstance>(
|
||||
'/bpm/process-instance/create',
|
||||
data,
|
||||
);
|
||||
|
@ -142,14 +142,14 @@ export async function cancelProcessInstanceByAdmin(id: number, reason: string) {
|
|||
|
||||
/** 查询流程实例详情 */
|
||||
export async function getProcessInstance(id: number) {
|
||||
return requestClient.get<BpmProcessInstanceApi.ProcessInstanceVO>(
|
||||
return requestClient.get<BpmProcessInstanceApi.ProcessInstance>(
|
||||
`/bpm/process-instance/get?id=${id}`,
|
||||
);
|
||||
}
|
||||
|
||||
/** 查询复制流程实例分页 */
|
||||
export async function getProcessInstanceCopyPage(params: PageParam) {
|
||||
return requestClient.get<PageResult<BpmProcessInstanceApi.ProcessInstanceVO>>(
|
||||
return requestClient.get<PageResult<BpmProcessInstanceApi.ProcessInstance>>(
|
||||
'/bpm/process-instance/copy/page',
|
||||
{ params },
|
||||
);
|
||||
|
@ -157,9 +157,9 @@ export async function getProcessInstanceCopyPage(params: PageParam) {
|
|||
|
||||
/** 更新流程实例 */
|
||||
export async function updateProcessInstance(
|
||||
data: BpmProcessInstanceApi.ProcessInstanceVO,
|
||||
data: BpmProcessInstanceApi.ProcessInstance,
|
||||
) {
|
||||
return requestClient.put<BpmProcessInstanceApi.ProcessInstanceVO>(
|
||||
return requestClient.put<BpmProcessInstanceApi.ProcessInstance>(
|
||||
'/bpm/process-instance/update',
|
||||
data,
|
||||
);
|
||||
|
@ -183,7 +183,7 @@ export async function getNextApprovalNodes(params: any) {
|
|||
|
||||
/** 获取表单字段权限 */
|
||||
export async function getFormFieldsPermission(params: any) {
|
||||
return requestClient.get<BpmProcessInstanceApi.ProcessInstanceVO>(
|
||||
return requestClient.get<BpmProcessInstanceApi.ProcessInstance>(
|
||||
`/bpm/process-instance/get-form-fields-permission`,
|
||||
{ params },
|
||||
);
|
||||
|
@ -191,7 +191,7 @@ export async function getFormFieldsPermission(params: any) {
|
|||
|
||||
/** 获取流程实例 BPMN 模型视图 */
|
||||
export async function getProcessInstanceBpmnModelView(id: string) {
|
||||
return requestClient.get<BpmProcessInstanceApi.ProcessInstanceVO>(
|
||||
return requestClient.get<BpmProcessInstanceApi.ProcessInstance>(
|
||||
`/bpm/process-instance/get-bpmn-model-view?id=${id}`,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,9 +3,8 @@ import type { PageParam, PageResult } from '@vben/request';
|
|||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace BpmProcessListenerApi {
|
||||
// TODO @ziye:不用 VO 后缀
|
||||
/** BPM 流程监听器 VO */
|
||||
export interface ProcessListenerVO {
|
||||
/** BPM 流程监听器 */
|
||||
export interface ProcessListener {
|
||||
id: number; // 编号
|
||||
name: string; // 监听器名字
|
||||
type: string; // 监听器类型
|
||||
|
@ -18,7 +17,7 @@ export namespace BpmProcessListenerApi {
|
|||
|
||||
/** 查询流程监听器分页 */
|
||||
export async function getProcessListenerPage(params: PageParam) {
|
||||
return requestClient.get<PageResult<BpmProcessListenerApi.ProcessListenerVO>>(
|
||||
return requestClient.get<PageResult<BpmProcessListenerApi.ProcessListener>>(
|
||||
'/bpm/process-listener/page',
|
||||
{ params },
|
||||
);
|
||||
|
@ -26,21 +25,21 @@ export async function getProcessListenerPage(params: PageParam) {
|
|||
|
||||
/** 查询流程监听器详情 */
|
||||
export async function getProcessListener(id: number) {
|
||||
return requestClient.get<BpmProcessListenerApi.ProcessListenerVO>(
|
||||
return requestClient.get<BpmProcessListenerApi.ProcessListener>(
|
||||
`/bpm/process-listener/get?id=${id}`,
|
||||
);
|
||||
}
|
||||
|
||||
/** 新增流程监听器 */
|
||||
export async function createProcessListener(
|
||||
data: BpmProcessListenerApi.ProcessListenerVO,
|
||||
data: BpmProcessListenerApi.ProcessListener,
|
||||
) {
|
||||
return requestClient.post<number>('/bpm/process-listener/create', data);
|
||||
}
|
||||
|
||||
/** 修改流程监听器 */
|
||||
export async function updateProcessListener(
|
||||
data: BpmProcessListenerApi.ProcessListenerVO,
|
||||
data: BpmProcessListenerApi.ProcessListener,
|
||||
) {
|
||||
return requestClient.put<boolean>('/bpm/process-listener/update', data);
|
||||
}
|
||||
|
|
|
@ -5,9 +5,8 @@ import type { BpmProcessInstanceApi } from '../processInstance';
|
|||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace BpmTaskApi {
|
||||
// TODO @ziye:不用 VO 后缀;注释使用 /** */ 风格;
|
||||
/** BPM 流程监听器 VO */
|
||||
export interface TaskVO {
|
||||
/** BPM 流程监听器 */
|
||||
export interface Task {
|
||||
id: number; // 编号
|
||||
name: string; // 监听器名字
|
||||
type: string; // 监听器类型
|
||||
|
@ -16,8 +15,8 @@ export namespace BpmTaskApi {
|
|||
valueType: string; // 监听器值类型
|
||||
}
|
||||
|
||||
// 流程任务 VO
|
||||
export interface TaskManagerVO {
|
||||
// 流程任务
|
||||
export interface TaskManager {
|
||||
id: string; // 编号
|
||||
name: string; // 任务名称
|
||||
createTime: number; // 创建时间
|
||||
|
@ -29,7 +28,7 @@ export namespace BpmTaskApi {
|
|||
assigneeUser: any; // 处理人
|
||||
taskDefinitionKey: string; // 任务定义key
|
||||
processInstanceId: string; // 流程实例id
|
||||
processInstance: BpmProcessInstanceApi.ProcessInstanceVO; // 流程实例
|
||||
processInstance: BpmProcessInstanceApi.ProcessInstance; // 流程实例
|
||||
parentTaskId: any; // 父任务id
|
||||
children: any; // 子任务
|
||||
formId: any; // 表单id
|
||||
|
@ -46,27 +45,21 @@ export namespace BpmTaskApi {
|
|||
|
||||
/** 查询待办任务分页 */
|
||||
export async function getTaskTodoPage(params: PageParam) {
|
||||
return requestClient.get<PageResult<BpmTaskApi.TaskVO>>(
|
||||
'/bpm/task/todo-page',
|
||||
{
|
||||
params,
|
||||
},
|
||||
);
|
||||
return requestClient.get<PageResult<BpmTaskApi.Task>>('/bpm/task/todo-page', {
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/** 查询已办任务分页 */
|
||||
export async function getTaskDonePage(params: PageParam) {
|
||||
return requestClient.get<PageResult<BpmTaskApi.TaskVO>>(
|
||||
'/bpm/task/done-page',
|
||||
{
|
||||
params,
|
||||
},
|
||||
);
|
||||
return requestClient.get<PageResult<BpmTaskApi.Task>>('/bpm/task/done-page', {
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/** 查询任务管理分页 */
|
||||
export async function getTaskManagerPage(params: PageParam) {
|
||||
return requestClient.get<PageResult<BpmTaskApi.TaskVO>>(
|
||||
return requestClient.get<PageResult<BpmTaskApi.Task>>(
|
||||
'/bpm/task/manager-page',
|
||||
{ params },
|
||||
);
|
||||
|
|
|
@ -3,9 +3,8 @@ import type { PageParam, PageResult } from '@vben/request';
|
|||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace BpmUserGroupApi {
|
||||
// TODO @ziye:不用 VO 后缀
|
||||
/** BPM 用户组 VO */
|
||||
export interface UserGroupVO {
|
||||
/** BPM 用户组 */
|
||||
export interface UserGroup {
|
||||
id: number;
|
||||
name: string;
|
||||
description: string;
|
||||
|
@ -18,7 +17,7 @@ export namespace BpmUserGroupApi {
|
|||
|
||||
/** 查询用户组分页 */
|
||||
export async function getUserGroupPage(params: PageParam) {
|
||||
return requestClient.get<PageResult<BpmUserGroupApi.UserGroupVO>>(
|
||||
return requestClient.get<PageResult<BpmUserGroupApi.UserGroup>>(
|
||||
'/bpm/user-group/page',
|
||||
{ params },
|
||||
);
|
||||
|
@ -26,18 +25,18 @@ export async function getUserGroupPage(params: PageParam) {
|
|||
|
||||
/** 查询用户组详情 */
|
||||
export async function getUserGroup(id: number) {
|
||||
return requestClient.get<BpmUserGroupApi.UserGroupVO>(
|
||||
return requestClient.get<BpmUserGroupApi.UserGroup>(
|
||||
`/bpm/user-group/get?id=${id}`,
|
||||
);
|
||||
}
|
||||
|
||||
/** 新增用户组 */
|
||||
export async function createUserGroup(data: BpmUserGroupApi.UserGroupVO) {
|
||||
export async function createUserGroup(data: BpmUserGroupApi.UserGroup) {
|
||||
return requestClient.post<number>('/bpm/user-group/create', data);
|
||||
}
|
||||
|
||||
/** 修改用户组 */
|
||||
export async function updateUserGroup(data: BpmUserGroupApi.UserGroupVO) {
|
||||
export async function updateUserGroup(data: BpmUserGroupApi.UserGroup) {
|
||||
return requestClient.put<boolean>('/bpm/user-group/update', data);
|
||||
}
|
||||
|
||||
|
@ -48,7 +47,7 @@ export async function deleteUserGroup(id: number) {
|
|||
|
||||
/** 查询用户组列表 */
|
||||
export async function getUserGroupSimpleList() {
|
||||
return requestClient.get<BpmUserGroupApi.UserGroupVO[]>(
|
||||
return requestClient.get<BpmUserGroupApi.UserGroup[]>(
|
||||
`/bpm/user-group/simple-list`,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -65,13 +65,13 @@ export namespace InfraCodegenApi {
|
|||
}
|
||||
|
||||
/** 更新代码生成请求 */
|
||||
export interface CodegenUpdateReqVO {
|
||||
export interface CodegenUpdateReq {
|
||||
table: any | CodegenTable;
|
||||
columns: CodegenColumn[];
|
||||
}
|
||||
|
||||
/** 创建代码生成请求 */
|
||||
export interface CodegenCreateListReqVO {
|
||||
export interface CodegenCreateListReq {
|
||||
dataSourceConfigId?: number;
|
||||
tableNames: string[];
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ export function getCodegenTable(tableId: number) {
|
|||
}
|
||||
|
||||
/** 修改代码生成表定义 */
|
||||
export function updateCodegenTable(data: InfraCodegenApi.CodegenUpdateReqVO) {
|
||||
export function updateCodegenTable(data: InfraCodegenApi.CodegenUpdateReq) {
|
||||
return requestClient.put('/infra/codegen/update', data);
|
||||
}
|
||||
|
||||
|
@ -136,9 +136,7 @@ export function getSchemaTableList(params: any) {
|
|||
}
|
||||
|
||||
/** 基于数据库的表结构,创建代码生成器的表定义 */
|
||||
export function createCodegenList(
|
||||
data: InfraCodegenApi.CodegenCreateListReqVO,
|
||||
) {
|
||||
export function createCodegenList(data: InfraCodegenApi.CodegenCreateListReq) {
|
||||
return requestClient.post('/infra/codegen/create-list', data);
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ export function deleteConfigList(ids: number[]) {
|
|||
|
||||
/** 导出参数 */
|
||||
export function exportConfig(params: any) {
|
||||
return requestClient.download('/infra/config/export', {
|
||||
return requestClient.download('/infra/config/export-excel', {
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ export namespace InfraFileApi {
|
|||
}
|
||||
|
||||
/** 文件预签名地址 */
|
||||
export interface FilePresignedUrlRespVO {
|
||||
export interface FilePresignedUrlResp {
|
||||
configId: number; // 文件配置编号
|
||||
uploadUrl: string; // 文件上传 URL
|
||||
url: string; // 文件 URL
|
||||
|
@ -27,7 +27,7 @@ export namespace InfraFileApi {
|
|||
}
|
||||
|
||||
/** 上传文件 */
|
||||
export interface FileUploadReqVO {
|
||||
export interface FileUploadReq {
|
||||
file: globalThis.File;
|
||||
directory?: string;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ export function deleteFileList(ids: number[]) {
|
|||
|
||||
/** 获取文件预签名地址 */
|
||||
export function getFilePresignedUrl(name: string, directory?: string) {
|
||||
return requestClient.get<InfraFileApi.FilePresignedUrlRespVO>(
|
||||
return requestClient.get<InfraFileApi.FilePresignedUrlResp>(
|
||||
'/infra/file/presigned-url',
|
||||
{
|
||||
params: { name, directory },
|
||||
|
@ -67,7 +67,7 @@ export function createFile(data: InfraFileApi.File) {
|
|||
|
||||
/** 上传文件 */
|
||||
export function uploadFile(
|
||||
data: InfraFileApi.FileUploadReqVO,
|
||||
data: InfraFileApi.FileUploadReq,
|
||||
onUploadProgress?: AxiosProgressEvent,
|
||||
) {
|
||||
// 特殊:由于 upload 内部封装,即使 directory 为 undefined,也会传递给后端
|
||||
|
|
|
@ -168,7 +168,7 @@ export function deleteSpu(id: number) {
|
|||
|
||||
/** 导出商品 SPU Excel */
|
||||
export function exportSpu(params: PageParam) {
|
||||
return requestClient.download('/product/spu/export', { params });
|
||||
return requestClient.download('/product/spu/export-excel', { params });
|
||||
}
|
||||
|
||||
/** 获得商品 SPU 精简列表 */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/** 数据对照 Response VO */
|
||||
export interface MallDataComparisonRespVO<T> {
|
||||
/** 数据对照 Response */
|
||||
export interface MallDataComparisonResp<T> {
|
||||
value: T;
|
||||
reference: T;
|
||||
}
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
import type { MallDataComparisonRespVO } from './common';
|
||||
import type { MallDataComparisonResp } from './common';
|
||||
|
||||
import { formatDate } from '@vben/utils';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace MallMemberStatisticsApi {
|
||||
/** 会员分析 Request VO */
|
||||
/** 会员分析 Request */
|
||||
export interface AnalyseReq {
|
||||
times: Date[];
|
||||
}
|
||||
|
||||
/** 会员分析对照数据 Response VO */
|
||||
/** 会员分析对照数据 Response */
|
||||
export interface AnalyseComparison {
|
||||
registerUserCount: number;
|
||||
visitUserCount: number;
|
||||
rechargeUserCount: number;
|
||||
}
|
||||
|
||||
/** 会员分析 Response VO */
|
||||
/** 会员分析 Response */
|
||||
export interface Analyse {
|
||||
visitUserCount: number;
|
||||
orderUserCount: number;
|
||||
payUserCount: number;
|
||||
atv: number;
|
||||
comparison: MallDataComparisonRespVO<AnalyseComparison>;
|
||||
comparison: MallDataComparisonResp<AnalyseComparison>;
|
||||
}
|
||||
|
||||
/** 会员地区统计 Response VO */
|
||||
/** 会员地区统计 Response */
|
||||
export interface AreaStatistics {
|
||||
areaId: number;
|
||||
areaName: string;
|
||||
|
@ -36,13 +36,13 @@ export namespace MallMemberStatisticsApi {
|
|||
orderPayPrice: number;
|
||||
}
|
||||
|
||||
/** 会员性别统计 Response VO */
|
||||
/** 会员性别统计 Response */
|
||||
export interface SexStatistics {
|
||||
sex: number;
|
||||
userCount: number;
|
||||
}
|
||||
|
||||
/** 会员统计 Response VO */
|
||||
/** 会员统计 Response */
|
||||
export interface Summary {
|
||||
userCount: number;
|
||||
rechargeUserCount: number;
|
||||
|
@ -50,13 +50,13 @@ export namespace MallMemberStatisticsApi {
|
|||
expensePrice: number;
|
||||
}
|
||||
|
||||
/** 会员终端统计 Response VO */
|
||||
/** 会员终端统计 Response */
|
||||
export interface TerminalStatistics {
|
||||
terminal: number;
|
||||
userCount: number;
|
||||
}
|
||||
|
||||
/** 会员数量统计 Response VO */
|
||||
/** 会员数量统计 Response */
|
||||
export interface Count {
|
||||
/** 用户访问量 */
|
||||
visitUserCount: string;
|
||||
|
@ -64,7 +64,7 @@ export namespace MallMemberStatisticsApi {
|
|||
registerUserCount: number;
|
||||
}
|
||||
|
||||
/** 会员注册数量 Response VO */
|
||||
/** 会员注册数量 Response */
|
||||
export interface RegisterCount {
|
||||
date: string;
|
||||
count: number;
|
||||
|
@ -114,7 +114,7 @@ export function getMemberTerminalStatisticsList() {
|
|||
/** 获得用户数量量对照 */
|
||||
export function getUserCountComparison() {
|
||||
return requestClient.get<
|
||||
MallDataComparisonRespVO<MallMemberStatisticsApi.Count>
|
||||
MallDataComparisonResp<MallMemberStatisticsApi.Count>
|
||||
>('/statistics/member/user-count-comparison');
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import { requestClient } from '#/api/request';
|
|||
|
||||
export namespace MallPayStatisticsApi {
|
||||
/** 支付统计 */
|
||||
export interface PaySummaryRespVO {
|
||||
export interface PaySummaryResp {
|
||||
/** 充值金额,单位分 */
|
||||
rechargePrice: number;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ export namespace MallPayStatisticsApi {
|
|||
|
||||
/** 获取钱包充值金额 */
|
||||
export function getWalletRechargePrice() {
|
||||
return requestClient.get<MallPayStatisticsApi.PaySummaryRespVO>(
|
||||
return requestClient.get<MallPayStatisticsApi.PaySummaryResp>(
|
||||
'/statistics/pay/summary',
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import type { PageParam, PageResult } from '@vben/request';
|
||||
|
||||
import type { MallDataComparisonRespVO } from './common';
|
||||
import type { MallDataComparisonResp } from './common';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
|
@ -43,7 +43,7 @@ export namespace MallProductStatisticsApi {
|
|||
/** 获得商品统计分析 */
|
||||
export function getProductStatisticsAnalyse(params: PageParam) {
|
||||
return requestClient.get<
|
||||
MallDataComparisonRespVO<MallProductStatisticsApi.ProductStatistics>
|
||||
MallDataComparisonResp<MallProductStatisticsApi.ProductStatistics>
|
||||
>('/statistics/product/analyse', { params });
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import type { MallDataComparisonRespVO } from './common';
|
||||
import type { MallDataComparisonResp } from './common';
|
||||
|
||||
import { formatDate } from '@vben/utils';
|
||||
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export namespace MallTradeStatisticsApi {
|
||||
/** 交易统计 Response VO */
|
||||
/** 交易统计 Response */
|
||||
export interface TradeSummary {
|
||||
yesterdayOrderCount: number;
|
||||
monthOrderCount: number;
|
||||
|
@ -13,12 +13,12 @@ export namespace MallTradeStatisticsApi {
|
|||
monthPayPrice: number;
|
||||
}
|
||||
|
||||
/** 交易状况 Request VO */
|
||||
/** 交易状况 Request */
|
||||
export interface TradeTrendReq {
|
||||
times: [Date, Date];
|
||||
}
|
||||
|
||||
/** 交易状况统计 Response VO */
|
||||
/** 交易状况统计 Response */
|
||||
export interface TradeTrendSummary {
|
||||
time: string;
|
||||
turnoverPrice: number;
|
||||
|
@ -30,7 +30,7 @@ export namespace MallTradeStatisticsApi {
|
|||
afterSaleRefundPrice: number;
|
||||
}
|
||||
|
||||
/** 交易订单数量 Response VO */
|
||||
/** 交易订单数量 Response */
|
||||
export interface TradeOrderCount {
|
||||
/** 待发货 */
|
||||
undelivered?: number;
|
||||
|
@ -42,7 +42,7 @@ export namespace MallTradeStatisticsApi {
|
|||
auditingWithdraw?: number;
|
||||
}
|
||||
|
||||
/** 交易订单统计 Response VO */
|
||||
/** 交易订单统计 Response */
|
||||
export interface TradeOrderSummary {
|
||||
/** 支付订单商品数 */
|
||||
orderPayCount?: number;
|
||||
|
@ -50,7 +50,7 @@ export namespace MallTradeStatisticsApi {
|
|||
orderPayPrice?: number;
|
||||
}
|
||||
|
||||
/** 订单量趋势统计 Response VO */
|
||||
/** 订单量趋势统计 Response */
|
||||
export interface TradeOrderTrend {
|
||||
/** 日期 */
|
||||
date: string;
|
||||
|
@ -71,7 +71,7 @@ const formatDateParam = (params: MallTradeStatisticsApi.TradeTrendReq) => {
|
|||
/** 查询交易统计 */
|
||||
export function getTradeStatisticsSummary() {
|
||||
return requestClient.get<
|
||||
MallDataComparisonRespVO<MallTradeStatisticsApi.TradeSummary>
|
||||
MallDataComparisonResp<MallTradeStatisticsApi.TradeSummary>
|
||||
>('/statistics/trade/summary');
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ export function getTradeStatisticsAnalyse(
|
|||
params: MallTradeStatisticsApi.TradeTrendReq,
|
||||
) {
|
||||
return requestClient.get<
|
||||
MallDataComparisonRespVO<MallTradeStatisticsApi.TradeTrendSummary>
|
||||
MallDataComparisonResp<MallTradeStatisticsApi.TradeTrendSummary>
|
||||
>('/statistics/trade/analyse', { params: formatDateParam(params) });
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ export function getOrderCount() {
|
|||
/** 获得交易订单数量对照 */
|
||||
export function getOrderComparison() {
|
||||
return requestClient.get<
|
||||
MallDataComparisonRespVO<MallTradeStatisticsApi.TradeOrderSummary>
|
||||
MallDataComparisonResp<MallTradeStatisticsApi.TradeOrderSummary>
|
||||
>('/statistics/trade/order-comparison');
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ export function getOrderCountTrendComparison(
|
|||
endTime: Date,
|
||||
) {
|
||||
return requestClient.get<
|
||||
MallDataComparisonRespVO<MallTradeStatisticsApi.TradeOrderTrend>[]
|
||||
MallDataComparisonResp<MallTradeStatisticsApi.TradeOrderTrend>[]
|
||||
>('/statistics/trade/order-count-trend', {
|
||||
params: {
|
||||
type,
|
||||
|
|
|
@ -24,7 +24,7 @@ export namespace PayAppApi {
|
|||
status: number;
|
||||
}
|
||||
|
||||
export interface AppPageReqVO extends PageParam {
|
||||
export interface AppPageReq extends PageParam {
|
||||
name?: string;
|
||||
status?: number;
|
||||
remark?: string;
|
||||
|
@ -37,7 +37,7 @@ export namespace PayAppApi {
|
|||
}
|
||||
|
||||
/** 查询支付应用列表 */
|
||||
export function getAppPage(params: PayAppApi.AppPageReqVO) {
|
||||
export function getAppPage(params: PayAppApi.AppPageReq) {
|
||||
return requestClient.get<PageResult<PayAppApi.App>>('/pay/app/page', {
|
||||
params,
|
||||
});
|
||||
|
|
|
@ -20,7 +20,7 @@ export namespace DemoOrderApi {
|
|||
createTime?: Date;
|
||||
}
|
||||
|
||||
export interface OrderPageReqVO extends PageParam {
|
||||
export interface OrderPageReq extends PageParam {
|
||||
spuId?: number;
|
||||
createTime?: Date[];
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ export function createDemoOrder(data: DemoOrderApi.Order) {
|
|||
}
|
||||
|
||||
/** 获得示例订单分页 */
|
||||
export function getDemoOrderPage(params: DemoOrderApi.OrderPageReqVO) {
|
||||
export function getDemoOrderPage(params: DemoOrderApi.OrderPageReq) {
|
||||
return requestClient.get<PageResult<DemoOrderApi.Order>>(
|
||||
'/pay/demo-order/page',
|
||||
{
|
||||
|
|
|
@ -40,7 +40,7 @@ export namespace PayOrderApi {
|
|||
}
|
||||
|
||||
/** 支付订单分页请求 */
|
||||
export interface OrderPageReqVO extends PageParam {
|
||||
export interface OrderPageReq extends PageParam {
|
||||
merchantId?: number;
|
||||
appId?: number;
|
||||
channelId?: number;
|
||||
|
@ -66,7 +66,7 @@ export namespace PayOrderApi {
|
|||
}
|
||||
|
||||
/** 支付订单导出请求 */
|
||||
export interface OrderExportReqVO {
|
||||
export interface OrderExportReq {
|
||||
merchantId?: number;
|
||||
appId?: number;
|
||||
channelId?: number;
|
||||
|
@ -93,7 +93,7 @@ export namespace PayOrderApi {
|
|||
}
|
||||
|
||||
/** 查询支付订单列表 */
|
||||
export function getOrderPage(params: PayOrderApi.OrderPageReqVO) {
|
||||
export function getOrderPage(params: PayOrderApi.OrderPageReq) {
|
||||
return requestClient.get<PageResult<PayOrderApi.Order>>('/pay/order/page', {
|
||||
params,
|
||||
});
|
||||
|
@ -120,6 +120,6 @@ export function submitOrder(data: any) {
|
|||
}
|
||||
|
||||
/** 导出支付订单 */
|
||||
export function exportOrder(params: PayOrderApi.OrderExportReqVO) {
|
||||
export function exportOrder(params: PayOrderApi.OrderExportReq) {
|
||||
return requestClient.download('/pay/order/export-excel', { params });
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ export namespace PayRefundApi {
|
|||
}
|
||||
|
||||
/** 退款订单分页请求 */
|
||||
export interface RefundPageReqVO extends PageParam {
|
||||
export interface RefundPageReq extends PageParam {
|
||||
merchantId?: number;
|
||||
appId?: number;
|
||||
channelId?: number;
|
||||
|
@ -64,7 +64,7 @@ export namespace PayRefundApi {
|
|||
}
|
||||
|
||||
/** 退款订单导出请求 */
|
||||
export interface RefundExportReqVO {
|
||||
export interface RefundExportReq {
|
||||
merchantId?: number;
|
||||
appId?: number;
|
||||
channelId?: number;
|
||||
|
@ -94,7 +94,7 @@ export namespace PayRefundApi {
|
|||
}
|
||||
|
||||
/** 查询退款订单列表 */
|
||||
export function getRefundPage(params: PayRefundApi.RefundPageReqVO) {
|
||||
export function getRefundPage(params: PayRefundApi.RefundPageReq) {
|
||||
return requestClient.get<PageResult<PayRefundApi.Refund>>(
|
||||
'/pay/refund/page',
|
||||
{
|
||||
|
@ -124,6 +124,6 @@ export function deleteRefund(id: number) {
|
|||
}
|
||||
|
||||
/** 导出退款订单 */
|
||||
export function exportRefund(params: PayRefundApi.RefundExportReqVO) {
|
||||
export function exportRefund(params: PayRefundApi.RefundExportReq) {
|
||||
return requestClient.download('/pay/refund/export-excel', { params });
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ export namespace PayTransferApi {
|
|||
}
|
||||
|
||||
/** 转账单分页请求 */
|
||||
export interface TransferPageReqVO extends PageParam {
|
||||
export interface TransferPageReq extends PageParam {
|
||||
appId?: number;
|
||||
channelId?: number;
|
||||
channelCode?: string;
|
||||
|
@ -36,7 +36,7 @@ export namespace PayTransferApi {
|
|||
}
|
||||
|
||||
/** 查询转账单列表 */
|
||||
export function getTransferPage(params: PayTransferApi.TransferPageReqVO) {
|
||||
export function getTransferPage(params: PayTransferApi.TransferPageReq) {
|
||||
return requestClient.get<PageResult<PayTransferApi.Transfer>>(
|
||||
'/pay/transfer/page',
|
||||
{
|
||||
|
|
|
@ -4,12 +4,12 @@ import { requestClient } from '#/api/request';
|
|||
|
||||
export namespace PayWalletApi {
|
||||
/** 用户钱包查询参数 */
|
||||
export interface PayWalletUserReqVO {
|
||||
export interface PayWalletUserReq {
|
||||
userId: number;
|
||||
}
|
||||
|
||||
/** 钱包信息 */
|
||||
export interface WalletVO {
|
||||
export interface Wallet {
|
||||
id: number;
|
||||
userId: number;
|
||||
userType: number;
|
||||
|
@ -20,7 +20,7 @@ export namespace PayWalletApi {
|
|||
}
|
||||
|
||||
/** 钱包分页请求 */
|
||||
export interface WalletPageReqVO extends PageParam {
|
||||
export interface WalletPageReq extends PageParam {
|
||||
userId?: number;
|
||||
userType?: number;
|
||||
balance?: number;
|
||||
|
@ -31,15 +31,15 @@ export namespace PayWalletApi {
|
|||
}
|
||||
|
||||
/** 查询用户钱包详情 */
|
||||
export function getWallet(params: PayWalletApi.PayWalletUserReqVO) {
|
||||
return requestClient.get<PayWalletApi.WalletVO>('/pay/wallet/get', {
|
||||
export function getWallet(params: PayWalletApi.PayWalletUserReq) {
|
||||
return requestClient.get<PayWalletApi.Wallet>('/pay/wallet/get', {
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/** 查询会员钱包列表 */
|
||||
export function getWalletPage(params: PayWalletApi.WalletPageReqVO) {
|
||||
return requestClient.get<PageResult<PayWalletApi.WalletVO>>(
|
||||
export function getWalletPage(params: PayWalletApi.WalletPageReq) {
|
||||
return requestClient.get<PageResult<PayWalletApi.Wallet>>(
|
||||
'/pay/wallet/page',
|
||||
{
|
||||
params,
|
||||
|
@ -48,6 +48,6 @@ export function getWalletPage(params: PayWalletApi.WalletPageReqVO) {
|
|||
}
|
||||
|
||||
/** 修改会员钱包余额 */
|
||||
export function updateWalletBalance(data: PayWalletApi.WalletVO) {
|
||||
export function updateWalletBalance(data: PayWalletApi.Wallet) {
|
||||
return requestClient.put('/pay/wallet/update-balance', data);
|
||||
}
|
||||
|
|
|
@ -57,5 +57,5 @@ export function deleteDictDataList(ids: number[]) {
|
|||
|
||||
// 导出字典类型数据
|
||||
export function exportDictData(params: any) {
|
||||
return requestClient.download('/system/dict-data/export', { params });
|
||||
return requestClient.download('/system/dict-data/export-excel', { params });
|
||||
}
|
||||
|
|
|
@ -51,5 +51,5 @@ export function deleteDictTypeList(ids: number[]) {
|
|||
|
||||
// 导出字典类型
|
||||
export function exportDictType(params: any) {
|
||||
return requestClient.download('/system/dict-type/export', { params });
|
||||
return requestClient.download('/system/dict-type/export-excel', { params });
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ export namespace SystemMailTemplateApi {
|
|||
}
|
||||
|
||||
/** 邮件发送信息 */
|
||||
export interface MailSendReqVO {
|
||||
export interface MailSendReq {
|
||||
mail: string;
|
||||
templateCode: string;
|
||||
templateParams: Record<string, any>;
|
||||
|
@ -64,6 +64,6 @@ export function deleteMailTemplateList(ids: number[]) {
|
|||
}
|
||||
|
||||
/** 发送邮件 */
|
||||
export function sendMail(data: SystemMailTemplateApi.MailSendReqVO) {
|
||||
export function sendMail(data: SystemMailTemplateApi.MailSendReq) {
|
||||
return requestClient.post('/system/mail-template/send-mail', data);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ export namespace SystemNotifyTemplateApi {
|
|||
}
|
||||
|
||||
/** 发送站内信请求 */
|
||||
export interface NotifySendReqVO {
|
||||
export interface NotifySendReq {
|
||||
userId: number;
|
||||
userType: number;
|
||||
templateCode: string;
|
||||
|
@ -74,6 +74,6 @@ export function exportNotifyTemplate(params: any) {
|
|||
}
|
||||
|
||||
/** 发送站内信 */
|
||||
export function sendNotify(data: SystemNotifyTemplateApi.NotifySendReqVO) {
|
||||
export function sendNotify(data: SystemNotifyTemplateApi.NotifySendReq) {
|
||||
return requestClient.post('/system/notify-template/send-notify', data);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { requestClient } from '#/api/request';
|
|||
/** OAuth2.0 授权信息响应 */
|
||||
export namespace SystemOAuth2ClientApi {
|
||||
/** 授权信息 */
|
||||
export interface AuthorizeInfoRespVO {
|
||||
export interface AuthorizeInfoResp {
|
||||
client: {
|
||||
logo: string;
|
||||
name: string;
|
||||
|
@ -17,7 +17,7 @@ export namespace SystemOAuth2ClientApi {
|
|||
|
||||
/** 获得授权信息 */
|
||||
export function getAuthorize(clientId: string) {
|
||||
return requestClient.get<SystemOAuth2ClientApi.AuthorizeInfoRespVO>(
|
||||
return requestClient.get<SystemOAuth2ClientApi.AuthorizeInfoResp>(
|
||||
`/system/oauth2/authorize?clientId=${clientId}`,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,19 +2,19 @@ import { requestClient } from '#/api/request';
|
|||
|
||||
export namespace SystemPermissionApi {
|
||||
/** 分配用户角色请求 */
|
||||
export interface AssignUserRoleReqVO {
|
||||
export interface AssignUserRoleReq {
|
||||
userId: number;
|
||||
roleIds: number[];
|
||||
}
|
||||
|
||||
/** 分配角色菜单请求 */
|
||||
export interface AssignRoleMenuReqVO {
|
||||
export interface AssignRoleMenuReq {
|
||||
roleId: number;
|
||||
menuIds: number[];
|
||||
}
|
||||
|
||||
/** 分配角色数据权限请求 */
|
||||
export interface AssignRoleDataScopeReqVO {
|
||||
export interface AssignRoleDataScopeReq {
|
||||
roleId: number;
|
||||
dataScope: number;
|
||||
dataScopeDeptIds: number[];
|
||||
|
@ -30,14 +30,14 @@ export async function getRoleMenuList(roleId: number) {
|
|||
|
||||
/** 赋予角色菜单权限 */
|
||||
export async function assignRoleMenu(
|
||||
data: SystemPermissionApi.AssignRoleMenuReqVO,
|
||||
data: SystemPermissionApi.AssignRoleMenuReq,
|
||||
) {
|
||||
return requestClient.post('/system/permission/assign-role-menu', data);
|
||||
}
|
||||
|
||||
/** 赋予角色数据权限 */
|
||||
export async function assignRoleDataScope(
|
||||
data: SystemPermissionApi.AssignRoleDataScopeReqVO,
|
||||
data: SystemPermissionApi.AssignRoleDataScopeReq,
|
||||
) {
|
||||
return requestClient.post('/system/permission/assign-role-data-scope', data);
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ export async function getUserRoleList(userId: number) {
|
|||
|
||||
/** 赋予用户角色 */
|
||||
export async function assignUserRole(
|
||||
data: SystemPermissionApi.AssignUserRoleReqVO,
|
||||
data: SystemPermissionApi.AssignUserRoleReq,
|
||||
) {
|
||||
return requestClient.post('/system/permission/assign-user-role', data);
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ export function deletePostList(ids: number[]) {
|
|||
|
||||
/** 导出岗位 */
|
||||
export function exportPost(params: any) {
|
||||
return requestClient.download('/system/post/export', {
|
||||
return requestClient.download('/system/post/export-excel', {
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -63,5 +63,5 @@ export function deleteSmsChannelList(ids: number[]) {
|
|||
|
||||
/** 导出短信渠道 */
|
||||
export function exportSmsChannel(params: any) {
|
||||
return requestClient.download('/system/sms-channel/export', { params });
|
||||
return requestClient.download('/system/sms-channel/export-excel', { params });
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ export namespace SystemSmsTemplateApi {
|
|||
}
|
||||
|
||||
/** 发送短信请求 */
|
||||
export interface SmsSendReqVO {
|
||||
export interface SmsSendReq {
|
||||
mobile: string;
|
||||
templateCode: string;
|
||||
templateParams: Record<string, any>;
|
||||
|
@ -72,6 +72,6 @@ export function exportSmsTemplate(params: any) {
|
|||
}
|
||||
|
||||
/** 发送短信 */
|
||||
export function sendSms(data: SystemSmsTemplateApi.SmsSendReqVO) {
|
||||
export function sendSms(data: SystemSmsTemplateApi.SmsSendReq) {
|
||||
return requestClient.post('/system/sms-template/send-sms', data);
|
||||
}
|
||||
|
|
|
@ -20,14 +20,14 @@ export namespace SystemSocialUserApi {
|
|||
}
|
||||
|
||||
/** 社交绑定请求 */
|
||||
export interface SocialUserBindReqVO {
|
||||
export interface SocialUserBindReq {
|
||||
type: number;
|
||||
code: string;
|
||||
state: string;
|
||||
}
|
||||
|
||||
/** 取消社交绑定请求 */
|
||||
export interface SocialUserUnbindReqVO {
|
||||
export interface SocialUserUnbindReq {
|
||||
type: number;
|
||||
openid: string;
|
||||
}
|
||||
|
@ -49,12 +49,12 @@ export function getSocialUser(id: number) {
|
|||
}
|
||||
|
||||
/** 社交绑定,使用 code 授权码 */
|
||||
export function socialBind(data: SystemSocialUserApi.SocialUserBindReqVO) {
|
||||
export function socialBind(data: SystemSocialUserApi.SocialUserBindReq) {
|
||||
return requestClient.post<boolean>('/system/social-user/bind', data);
|
||||
}
|
||||
|
||||
/** 取消社交绑定 */
|
||||
export function socialUnbind(data: SystemSocialUserApi.SocialUserUnbindReqVO) {
|
||||
export function socialUnbind(data: SystemSocialUserApi.SocialUserUnbindReq) {
|
||||
return requestClient.delete<boolean>('/system/social-user/unbind', { data });
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ export function deleteUserList(ids: number[]) {
|
|||
|
||||
/** 导出用户 */
|
||||
export function exportUser(params: any) {
|
||||
return requestClient.download('/system/user/export', params);
|
||||
return requestClient.download('/system/user/export-excel', params);
|
||||
}
|
||||
|
||||
/** 下载用户导入模板 */
|
||||
|
|
|
@ -2,7 +2,7 @@ import { requestClient } from '#/api/request';
|
|||
|
||||
export namespace SystemUserProfileApi {
|
||||
/** 用户个人中心信息 */
|
||||
export interface UserProfileRespVO {
|
||||
export interface UserProfileResp {
|
||||
id: number;
|
||||
username: string;
|
||||
nickname: string;
|
||||
|
@ -19,13 +19,13 @@ export namespace SystemUserProfileApi {
|
|||
}
|
||||
|
||||
/** 更新密码请求 */
|
||||
export interface UpdatePasswordReqVO {
|
||||
export interface UpdatePasswordReq {
|
||||
oldPassword: string;
|
||||
newPassword: string;
|
||||
}
|
||||
|
||||
/** 更新个人信息请求 */
|
||||
export interface UpdateProfileReqVO {
|
||||
export interface UpdateProfileReq {
|
||||
nickname?: string;
|
||||
email?: string;
|
||||
mobile?: string;
|
||||
|
@ -36,21 +36,19 @@ export namespace SystemUserProfileApi {
|
|||
|
||||
/** 获取登录用户信息 */
|
||||
export function getUserProfile() {
|
||||
return requestClient.get<SystemUserProfileApi.UserProfileRespVO>(
|
||||
return requestClient.get<SystemUserProfileApi.UserProfileResp>(
|
||||
'/system/user/profile/get',
|
||||
);
|
||||
}
|
||||
|
||||
/** 修改用户个人信息 */
|
||||
export function updateUserProfile(
|
||||
data: SystemUserProfileApi.UpdateProfileReqVO,
|
||||
) {
|
||||
export function updateUserProfile(data: SystemUserProfileApi.UpdateProfileReq) {
|
||||
return requestClient.put('/system/user/profile/update', data);
|
||||
}
|
||||
|
||||
/** 修改用户个人密码 */
|
||||
export function updateUserPassword(
|
||||
data: SystemUserProfileApi.UpdatePasswordReqVO,
|
||||
data: SystemUserProfileApi.UpdatePasswordReq,
|
||||
) {
|
||||
return requestClient.put('/system/user/profile/update-password', data);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
<script setup lang="ts">
|
||||
import type { Item } from './ui/typing';
|
||||
|
||||
import { onMounted, onUnmounted, ref } from 'vue';
|
||||
|
||||
import { Tinyflow as TinyflowNative } from './ui/index';
|
||||
|
||||
import './ui/index.css';
|
||||
|
||||
const props = defineProps<{
|
||||
className?: string;
|
||||
data?: Record<string, any>;
|
||||
provider?: {
|
||||
internal?: () => Item[] | Promise<Item[]>;
|
||||
knowledge?: () => Item[] | Promise<Item[]>;
|
||||
llm?: () => Item[] | Promise<Item[]>;
|
||||
};
|
||||
style?: Record<string, string>;
|
||||
}>();
|
||||
|
||||
const divRef = ref<HTMLDivElement | null>(null);
|
||||
let tinyflow: null | TinyflowNative = null;
|
||||
// 定义默认的 provider 方法
|
||||
const defaultProvider = {
|
||||
llm: () => [] as Item[],
|
||||
knowledge: () => [] as Item[],
|
||||
internal: () => [] as Item[],
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if (divRef.value) {
|
||||
// 合并默认 provider 和传入的 props.provider
|
||||
const mergedProvider = {
|
||||
...defaultProvider,
|
||||
...props.provider,
|
||||
};
|
||||
tinyflow = new TinyflowNative({
|
||||
element: divRef.value as Element,
|
||||
data: props.data || {},
|
||||
provider: mergedProvider,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (tinyflow) {
|
||||
tinyflow.destroy();
|
||||
tinyflow = null;
|
||||
}
|
||||
});
|
||||
|
||||
const getData = () => {
|
||||
if (tinyflow) {
|
||||
return tinyflow.getData();
|
||||
}
|
||||
console.warn('Tinyflow instance is not initialized');
|
||||
return null;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
getData,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
ref="divRef"
|
||||
class="tinyflow"
|
||||
:class="[className]"
|
||||
:style="style"
|
||||
style="height: 100%"
|
||||
></div>
|
||||
</template>
|
|
@ -0,0 +1,2 @@
|
|||
export { default as Tinyflow } from './tinyflow.vue';
|
||||
export * from './ui/typing';
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,68 @@
|
|||
export interface Item {
|
||||
children?: Item[];
|
||||
label: string;
|
||||
value: number | string;
|
||||
}
|
||||
|
||||
export interface Position {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
export interface Viewport {
|
||||
x: number;
|
||||
y: number;
|
||||
zoom: number;
|
||||
}
|
||||
|
||||
export interface Node {
|
||||
data?: Record<string, any>;
|
||||
draggable?: boolean;
|
||||
height?: number;
|
||||
id: string;
|
||||
position: Position;
|
||||
selected?: boolean;
|
||||
type?: string;
|
||||
width?: number;
|
||||
}
|
||||
|
||||
export interface Edge {
|
||||
animated?: boolean;
|
||||
id: string;
|
||||
label?: string;
|
||||
source: string;
|
||||
target: string;
|
||||
type?: string;
|
||||
}
|
||||
export type TinyflowData = Partial<{
|
||||
edges: Edge[];
|
||||
nodes: Node[];
|
||||
viewport: Viewport;
|
||||
}>;
|
||||
|
||||
export interface TinyflowOptions {
|
||||
data?: TinyflowData;
|
||||
element: Element | string;
|
||||
provider?: {
|
||||
internal?: () => Item[] | Promise<Item[]>;
|
||||
knowledge?: () => Item[] | Promise<Item[]>;
|
||||
llm?: () => Item[] | Promise<Item[]>;
|
||||
};
|
||||
}
|
||||
|
||||
export declare class Tinyflow {
|
||||
private _init;
|
||||
private _setOptions;
|
||||
private options;
|
||||
private rootEl;
|
||||
private svelteFlowInstance;
|
||||
constructor(options: TinyflowOptions);
|
||||
destroy(): void;
|
||||
getData(): {
|
||||
edges: Edge[];
|
||||
nodes: Node[];
|
||||
viewport: Viewport;
|
||||
};
|
||||
getOptions(): TinyflowOptions;
|
||||
setData(data: TinyflowData): void;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export { default as MarkdownView } from './markdown-view.vue';
|
||||
|
||||
export * from './typing';
|
|
@ -0,0 +1,206 @@
|
|||
<script setup lang="ts">
|
||||
import type { MarkdownViewProps } from './typing';
|
||||
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
|
||||
import { MarkdownIt } from '@vben/plugins/markmap';
|
||||
|
||||
import { useClipboard } from '@vueuse/core';
|
||||
import { message } from 'ant-design-vue';
|
||||
import hljs from 'highlight.js';
|
||||
|
||||
import 'highlight.js/styles/vs2015.min.css';
|
||||
|
||||
// 定义组件属性
|
||||
const props = defineProps<MarkdownViewProps>();
|
||||
|
||||
const { copy } = useClipboard(); // 初始化 copy 到粘贴板
|
||||
const contentRef = ref<HTMLElement | null>(null);
|
||||
|
||||
const md = new MarkdownIt({
|
||||
highlight(str, lang) {
|
||||
if (lang && hljs.getLanguage(lang)) {
|
||||
try {
|
||||
const copyHtml = `<div id="copy" data-copy='${str}' style="position: absolute; right: 10px; top: 5px; color: #fff;cursor: pointer;">复制</div>`;
|
||||
return `<pre style="position: relative;">${copyHtml}<code class="hljs">${hljs.highlight(lang, str, true).value}</code></pre>`;
|
||||
} catch {}
|
||||
}
|
||||
return ``;
|
||||
},
|
||||
});
|
||||
|
||||
/** 渲染 markdown */
|
||||
const renderedMarkdown = computed(() => {
|
||||
return md.render(props.content);
|
||||
});
|
||||
|
||||
/** 初始化 */
|
||||
onMounted(async () => {
|
||||
// 添加 copy 监听
|
||||
contentRef.value?.addEventListener('click', (e: any) => {
|
||||
if (e.target.id === 'copy') {
|
||||
copy(e.target?.dataset?.copy);
|
||||
message.success('复制成功!');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="contentRef" class="markdown-view" v-html="renderedMarkdown"></div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.markdown-view {
|
||||
max-width: 100%;
|
||||
font-family: 'PingFang SC';
|
||||
font-size: 0.95rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.6rem;
|
||||
color: #3b3e55;
|
||||
text-align: left;
|
||||
letter-spacing: 0;
|
||||
|
||||
pre {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
pre code.hljs {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
code.hljs {
|
||||
width: auto;
|
||||
padding-top: 20px;
|
||||
border-radius: 6px;
|
||||
|
||||
@media screen and (min-width: 1536px) {
|
||||
width: 960px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1536px) and (min-width: 1024px) {
|
||||
width: calc(100vw - 400px - 64px - 32px * 2);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) and (min-width: 768px) {
|
||||
width: calc(100vw - 32px * 2);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
width: calc(100vw - 16px * 2);
|
||||
}
|
||||
}
|
||||
|
||||
p,
|
||||
code.hljs {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
p {
|
||||
//margin-bottom: 1rem !important;
|
||||
margin: 0;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
/* 标题通用格式 */
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin: 24px 0 8px;
|
||||
font-weight: 600;
|
||||
color: #3b3e55;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 22px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 20px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
/* 列表(有序,无序) */
|
||||
ul,
|
||||
ol {
|
||||
padding: 0;
|
||||
margin: 0 0 8px;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
color: #3b3e55; // var(--color-CG600);
|
||||
}
|
||||
|
||||
li {
|
||||
margin: 4px 0 0 20px;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol > li {
|
||||
margin-bottom: 1rem;
|
||||
list-style-type: decimal;
|
||||
// 表达式,修复有序列表序号展示不全的问题
|
||||
// &:nth-child(n + 10) {
|
||||
// margin-left: 30px;
|
||||
// }
|
||||
|
||||
// &:nth-child(n + 100) {
|
||||
// margin-left: 30px;
|
||||
// }
|
||||
}
|
||||
|
||||
ul > li {
|
||||
margin-right: 11px;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
color: #3b3e55; // var(--color-G900);
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
ol ul,
|
||||
ol ul > li,
|
||||
ul ul,
|
||||
ul ul li {
|
||||
margin-bottom: 1rem;
|
||||
margin-left: 6px;
|
||||
// list-style: circle;
|
||||
font-size: 16px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
ul ul ul,
|
||||
ul ul ul li,
|
||||
ol ol,
|
||||
ol ol > li,
|
||||
ol ul ul,
|
||||
ol ul ul > li,
|
||||
ul ol,
|
||||
ul ol > li {
|
||||
list-style: square;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,3 @@
|
|||
export type MarkdownViewProps = {
|
||||
content: string;
|
||||
};
|
|
@ -177,7 +177,7 @@ defineExpose({ open }); // 提供 open 方法,用于打开弹窗
|
|||
@click="clickIcon()"
|
||||
>
|
||||
{{ currentNode.name }}
|
||||
<IconifyIcon class="ml-1" icon="ep:edit-pen" />
|
||||
<IconifyIcon class="ml-1" icon="lucide:edit-3" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -222,7 +222,7 @@ defineExpose({ showCopyTaskNodeConfig }); // 暴露方法给父组件
|
|||
/>
|
||||
<div v-else class="node-name">
|
||||
{{ nodeName }}
|
||||
<IconifyIcon class="ml-1" icon="ep:edit-pen" @click="clickIcon()" />
|
||||
<IconifyIcon class="ml-1" icon="lucide:edit-3" @click="clickIcon()" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -171,7 +171,7 @@ defineExpose({ openDrawer }); // 暴露方法给父组件
|
|||
@click="clickIcon()"
|
||||
>
|
||||
{{ nodeName }}
|
||||
<IconifyIcon class="ml-1" icon="ep:edit-pen" :size="16" />
|
||||
<IconifyIcon class="ml-1" icon="lucide:edit-3" :size="16" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -188,7 +188,7 @@ defineExpose({ validate });
|
|||
>
|
||||
<IconifyIcon
|
||||
color="#0089ff"
|
||||
icon="ep:circle-close-filled"
|
||||
icon="lucide:circle-x"
|
||||
class="size-4"
|
||||
@click="
|
||||
deleteConditionGroup(condition.conditionGroups.conditions, cIdx)
|
||||
|
|
|
@ -219,7 +219,7 @@ defineExpose({ openDrawer }); // 暴露方法给父组件
|
|||
@click="clickIcon()"
|
||||
>
|
||||
{{ nodeName }}
|
||||
<IconifyIcon class="ml-1" icon="ep:edit-pen" />
|
||||
<IconifyIcon class="ml-1" icon="lucide:edit-3" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -266,7 +266,7 @@ defineExpose({ openDrawer }); // 暴露方法给父组件
|
|||
@click="deleteRouterGroup(index)"
|
||||
>
|
||||
<template #icon>
|
||||
<IconifyIcon icon="ep:close" />
|
||||
<IconifyIcon icon="lucide:x" />
|
||||
</template>
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -287,7 +287,7 @@ defineExpose({ openDrawer }); // 暴露方法给父组件
|
|||
@click="addRouterGroup"
|
||||
>
|
||||
<template #icon>
|
||||
<IconifyIcon icon="ep:setting" />
|
||||
<IconifyIcon icon="lucide:settings" />
|
||||
</template>
|
||||
新增路由分支
|
||||
</Button>
|
||||
|
|
|
@ -158,7 +158,7 @@ defineExpose({ showStartUserNodeConfig });
|
|||
{{ nodeName }}
|
||||
<IconifyIcon
|
||||
class="ml-1"
|
||||
icon="ep:edit-pen"
|
||||
icon="lucide:edit-3"
|
||||
:size="16"
|
||||
@click="clickIcon()"
|
||||
/>
|
||||
|
|
|
@ -399,7 +399,7 @@ onMounted(() => {
|
|||
/>
|
||||
<div v-else class="node-name">
|
||||
{{ nodeName }}
|
||||
<IconifyIcon class="ml-1" icon="ep:edit-pen" @click="clickIcon()" />
|
||||
<IconifyIcon class="ml-1" icon="lucide:edit-3" @click="clickIcon()" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -456,7 +456,7 @@ onMounted(() => {
|
|||
@click="deleteFormSetting(index)"
|
||||
>
|
||||
<template #icon>
|
||||
<IconifyIcon icon="ep:close" />
|
||||
<IconifyIcon icon="lucide:x" />
|
||||
</template>
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -486,7 +486,7 @@ onMounted(() => {
|
|||
@click="addFormSettingCondition(index, formSetting)"
|
||||
>
|
||||
<template #icon>
|
||||
<IconifyIcon icon="ep:link" />
|
||||
<IconifyIcon icon="lucide:link" />
|
||||
</template>
|
||||
添加条件
|
||||
</Button>
|
||||
|
@ -561,7 +561,7 @@ onMounted(() => {
|
|||
@click="addFormFieldSetting(formSetting)"
|
||||
>
|
||||
<template #icon>
|
||||
<IconifyIcon icon="ep:memo" />
|
||||
<IconifyIcon icon="lucide:file-cog" />
|
||||
</template>
|
||||
添加修改字段
|
||||
</Button>
|
||||
|
@ -579,7 +579,7 @@ onMounted(() => {
|
|||
@click="addFormSetting"
|
||||
>
|
||||
<template #icon>
|
||||
<IconifyIcon icon="ep:setting" />
|
||||
<IconifyIcon icon="lucide:settings" />
|
||||
</template>
|
||||
添加设置
|
||||
</Button>
|
||||
|
@ -604,7 +604,7 @@ onMounted(() => {
|
|||
@click="deleteFormSetting(index)"
|
||||
>
|
||||
<template #icon>
|
||||
<IconifyIcon icon="ep:close" />
|
||||
<IconifyIcon icon="lucide:x" />
|
||||
</template>
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -635,7 +635,7 @@ onMounted(() => {
|
|||
@click="addFormSettingCondition(index, formSetting)"
|
||||
>
|
||||
<template #icon>
|
||||
<IconifyIcon icon="ep:link" />
|
||||
<IconifyIcon icon="lucide:link" />
|
||||
</template>
|
||||
添加条件
|
||||
</Button>
|
||||
|
@ -673,7 +673,7 @@ onMounted(() => {
|
|||
@click="addFormSetting"
|
||||
>
|
||||
<template #icon>
|
||||
<IconifyIcon icon="ep:setting" />
|
||||
<IconifyIcon icon="lucide:settings" />
|
||||
</template>
|
||||
添加设置
|
||||
</Button>
|
||||
|
|
|
@ -595,7 +595,7 @@ onMounted(() => {
|
|||
/>
|
||||
<div v-else class="node-name">
|
||||
{{ nodeName }}
|
||||
<IconifyIcon class="ml-1" icon="ep:edit-pen" @click="clickIcon()" />
|
||||
<IconifyIcon class="ml-1" icon="lucide:edit-3" @click="clickIcon()" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -1135,7 +1135,7 @@ onMounted(() => {
|
|||
<Button v-else text @click="changeBtnDisplayName(index)">
|
||||
<div class="flex items-center">
|
||||
{{ item.displayName }}
|
||||
<IconifyIcon icon="ep:edit" class="ml-2" />
|
||||
<IconifyIcon icon="lucide:edit" class="ml-2" />
|
||||
</div>
|
||||
</Button>
|
||||
</Col>
|
||||
|
|
|
@ -91,13 +91,13 @@ function deleteNode() {
|
|||
<div class="node-text" v-else>
|
||||
{{ NODE_DEFAULT_TEXT.get(BpmNodeTypeEnum.COPY_TASK_NODE) }}
|
||||
</div>
|
||||
<IconifyIcon v-if="!readonly" icon="ep:arrow-right-bold" />
|
||||
<IconifyIcon v-if="!readonly" icon="lucide:chevron-right" />
|
||||
</div>
|
||||
<div v-if="!readonly" class="node-toolbar">
|
||||
<div class="toolbar-icon">
|
||||
<IconifyIcon
|
||||
color="#0089ff"
|
||||
icon="ep:circle-close-filled"
|
||||
icon="lucide:circle-x"
|
||||
:size="18"
|
||||
@click="deleteNode"
|
||||
/>
|
||||
|
|
|
@ -88,13 +88,13 @@ function deleteNode() {
|
|||
<div class="node-text" v-else>
|
||||
{{ NODE_DEFAULT_TEXT.get(BpmNodeTypeEnum.DELAY_TIMER_NODE) }}
|
||||
</div>
|
||||
<IconifyIcon v-if="!readonly" icon="ep:arrow-right-bold" />
|
||||
<IconifyIcon v-if="!readonly" icon="lucide:chevron-right" />
|
||||
</div>
|
||||
<div v-if="!readonly" class="node-toolbar">
|
||||
<div class="toolbar-icon">
|
||||
<IconifyIcon
|
||||
color="#0089ff"
|
||||
icon="ep:circle-close-filled"
|
||||
icon="lucide:circle-x"
|
||||
:size="18"
|
||||
@click="deleteNode"
|
||||
/>
|
||||
|
|
|
@ -248,7 +248,7 @@ function recursiveFindParentNode(
|
|||
<div class="toolbar-icon">
|
||||
<IconifyIcon
|
||||
color="#0089ff"
|
||||
icon="ep:circle-close-filled"
|
||||
icon="lucide:circle-x"
|
||||
:size="18"
|
||||
@click="deleteCondition(index)"
|
||||
/>
|
||||
|
@ -263,7 +263,7 @@ function recursiveFindParentNode(
|
|||
"
|
||||
@click="moveNode(index, -1)"
|
||||
>
|
||||
<IconifyIcon icon="ep:arrow-left" />
|
||||
<IconifyIcon icon="lucide:chevron-left" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
|
@ -275,7 +275,7 @@ function recursiveFindParentNode(
|
|||
"
|
||||
@click="moveNode(index, 1)"
|
||||
>
|
||||
<IconifyIcon icon="ep:arrow-right" />
|
||||
<IconifyIcon icon="lucide:chevron-right" />
|
||||
</div>
|
||||
</div>
|
||||
<NodeHandler
|
||||
|
|
|
@ -250,7 +250,7 @@ function recursiveFindParentNode(
|
|||
<div class="toolbar-icon">
|
||||
<IconifyIcon
|
||||
color="#0089ff"
|
||||
icon="ep:circle-close-filled"
|
||||
icon="lucide:circle-x"
|
||||
:size="18"
|
||||
@click="deleteCondition(index)"
|
||||
/>
|
||||
|
@ -265,7 +265,7 @@ function recursiveFindParentNode(
|
|||
"
|
||||
@click="moveNode(index, -1)"
|
||||
>
|
||||
<IconifyIcon icon="ep:arrow-left" />
|
||||
<IconifyIcon icon="lucide:chevron-left" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
|
@ -277,7 +277,7 @@ function recursiveFindParentNode(
|
|||
"
|
||||
@click="moveNode(index, 1)"
|
||||
>
|
||||
<IconifyIcon icon="ep:arrow-right" />
|
||||
<IconifyIcon icon="lucide:chevron-right" />
|
||||
</div>
|
||||
</div>
|
||||
<NodeHandler
|
||||
|
|
|
@ -344,7 +344,7 @@ function addNode(type: number) {
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="add-icon"><IconifyIcon icon="ep:plus" /></div>
|
||||
<div class="add-icon"><IconifyIcon icon="lucide:plus" /></div>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -201,7 +201,7 @@ function recursiveFindParentNode(
|
|||
<div class="toolbar-icon">
|
||||
<IconifyIcon
|
||||
color="#0089ff"
|
||||
icon="ep:circle-close-filled"
|
||||
icon="lucide:circle-x"
|
||||
@click="deleteCondition(index)"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -91,13 +91,13 @@ function deleteNode() {
|
|||
<div class="node-text" v-else>
|
||||
{{ NODE_DEFAULT_TEXT.get(BpmNodeTypeEnum.ROUTER_BRANCH_NODE) }}
|
||||
</div>
|
||||
<IconifyIcon v-if="!readonly" icon="ep:arrow-right-bold" />
|
||||
<IconifyIcon v-if="!readonly" icon="lucide:chevron-right" />
|
||||
</div>
|
||||
<div v-if="!readonly" class="node-toolbar">
|
||||
<div class="toolbar-icon">
|
||||
<IconifyIcon
|
||||
color="#0089ff"
|
||||
icon="ep:circle-close-filled"
|
||||
icon="lucide:circle-x"
|
||||
@click="deleteNode"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -105,7 +105,7 @@ function nodeClick() {
|
|||
<div class="node-text" v-else>
|
||||
{{ NODE_DEFAULT_TEXT.get(BpmNodeTypeEnum.START_USER_NODE) }}
|
||||
</div>
|
||||
<IconifyIcon icon="ep:arrow-right-bold" v-if="!readonly" />
|
||||
<IconifyIcon icon="lucide:chevron-right" v-if="!readonly" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 传递子节点给添加节点组件。会在子节点前面添加节点 -->
|
||||
|
|
|
@ -93,13 +93,13 @@ function deleteNode() {
|
|||
<div class="node-text" v-else>
|
||||
{{ NODE_DEFAULT_TEXT.get(BpmNodeTypeEnum.TRIGGER_NODE) }}
|
||||
</div>
|
||||
<IconifyIcon v-if="!readonly" icon="ep:arrow-right-bold" />
|
||||
<IconifyIcon v-if="!readonly" icon="lucide:chevron-right" />
|
||||
</div>
|
||||
<div v-if="!readonly" class="node-toolbar">
|
||||
<div class="toolbar-icon">
|
||||
<IconifyIcon
|
||||
color="#0089ff"
|
||||
icon="ep:circle-close-filled"
|
||||
icon="lucide:circle-x"
|
||||
:size="18"
|
||||
@click="deleteNode"
|
||||
/>
|
||||
|
|
|
@ -111,13 +111,13 @@ function findReturnTaskNodes(
|
|||
<div class="node-text" v-else>
|
||||
{{ NODE_DEFAULT_TEXT.get(currentNode.type) }}
|
||||
</div>
|
||||
<IconifyIcon icon="ep:arrow-right-bold" v-if="!readonly" />
|
||||
<IconifyIcon icon="lucide:chevron-right" v-if="!readonly" />
|
||||
</div>
|
||||
<div v-if="!readonly" class="node-toolbar">
|
||||
<div class="toolbar-icon">
|
||||
<IconifyIcon
|
||||
color="#0089ff"
|
||||
icon="ep:circle-close-filled"
|
||||
icon="lucide:circle-x"
|
||||
:size="18"
|
||||
@click="deleteNode"
|
||||
/>
|
||||
|
|
|
@ -97,7 +97,7 @@ const postOptions = ref<SystemPostApi.Post[]>([]); // 岗位列表
|
|||
const userOptions = ref<SystemUserApi.User[]>([]); // 用户列表
|
||||
const deptOptions = ref<SystemDeptApi.Dept[]>([]); // 部门列表
|
||||
const deptTreeOptions = ref();
|
||||
const userGroupOptions = ref<BpmUserGroupApi.UserGroupVO[]>([]); // 用户组列表
|
||||
const userGroupOptions = ref<BpmUserGroupApi.UserGroup[]>([]); // 用户组列表
|
||||
|
||||
provide('formFields', formFields);
|
||||
provide('formType', formType);
|
||||
|
|
|
@ -205,10 +205,10 @@ onMounted(() => {
|
|||
<Row type="flex" justify="end">
|
||||
<ButtonGroup key="scale-control">
|
||||
<Button v-if="!readonly" @click="exportJson">
|
||||
<IconifyIcon icon="ep:download" /> 导出
|
||||
<IconifyIcon icon="lucide:download" /> 导出
|
||||
</Button>
|
||||
<Button v-if="!readonly" @click="importJson">
|
||||
<IconifyIcon icon="ep:upload" />导入
|
||||
<IconifyIcon icon="lucide:upload" />导入
|
||||
</Button>
|
||||
<!-- 用于打开本地文件-->
|
||||
<input
|
||||
|
@ -221,14 +221,14 @@ onMounted(() => {
|
|||
@change="importLocalFile"
|
||||
/>
|
||||
<Button @click="processReZoom()">
|
||||
<IconifyIcon icon="tabler:relation-one-to-one" />
|
||||
<IconifyIcon icon="lucide:table-columns-split" />
|
||||
</Button>
|
||||
<Button :plain="true" @click="zoomOut()">
|
||||
<IconifyIcon icon="tabler:zoom-out" />
|
||||
<IconifyIcon icon="lucide:zoom-out" />
|
||||
</Button>
|
||||
<Button class="w-80px"> {{ scaleValue }}% </Button>
|
||||
<Button :plain="true" @click="zoomIn()">
|
||||
<IconifyIcon icon="tabler:zoom-in" />
|
||||
<IconifyIcon icon="lucide:zoom-in" />
|
||||
</Button>
|
||||
<Button @click="resetPosition">重置</Button>
|
||||
</ButtonGroup>
|
||||
|
|
|
@ -260,7 +260,7 @@ export function useNodeForm(nodeType: BpmNodeTypeEnum) {
|
|||
const postOptions = inject<Ref<SystemPostApi.Post[]>>('postList', ref([])); // 岗位列表
|
||||
const userOptions = inject<Ref<SystemUserApi.User[]>>('userList', ref([])); // 用户列表
|
||||
const deptOptions = inject<Ref<SystemDeptApi.Dept[]>>('deptList', ref([])); // 部门列表
|
||||
const userGroupOptions = inject<Ref<BpmUserGroupApi.UserGroupVO[]>>(
|
||||
const userGroupOptions = inject<Ref<BpmUserGroupApi.UserGroup[]>>(
|
||||
'userGroupList',
|
||||
ref([]),
|
||||
); // 用户组列表
|
||||
|
|
|
@ -25,7 +25,10 @@ defineProps<SummaryCardProps>();
|
|||
<div class="flex items-center gap-1">
|
||||
<span class="text-3.5">{{ title }}</span>
|
||||
<Tooltip :content="tooltip" placement="topLeft" v-if="tooltip">
|
||||
<IconifyIcon icon="ep:warning" class="item-center !text-3 flex" />
|
||||
<IconifyIcon
|
||||
icon="lucide:circle-alert"
|
||||
class="item-center !text-3 flex"
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div class="flex flex-row items-baseline gap-2">
|
||||
|
@ -42,7 +45,9 @@ defineProps<SummaryCardProps>();
|
|||
>
|
||||
<span class="text-sm">{{ Math.abs(Number(percent)) }}%</span>
|
||||
<IconifyIcon
|
||||
:icon="Number(percent) > 0 ? 'ep:caret-top' : 'ep:caret-bottom'"
|
||||
:icon="
|
||||
Number(percent) > 0 ? 'lucide:chevron-up' : 'lucide:chevron-down'
|
||||
"
|
||||
class="!text-3 ml-0.5"
|
||||
/>
|
||||
</span>
|
||||
|
|
|
@ -136,7 +136,7 @@ export function getUploadUrl(): string {
|
|||
* @param file 文件
|
||||
*/
|
||||
function createFile0(
|
||||
vo: InfraFileApi.FilePresignedUrlRespVO,
|
||||
vo: InfraFileApi.FilePresignedUrlResp,
|
||||
file: File,
|
||||
): InfraFileApi.File {
|
||||
const fileVO = {
|
||||
|
|
|
@ -21,10 +21,11 @@ const accessStore = useAccessStore();
|
|||
|
||||
const tenantEnable = isTenantEnable();
|
||||
|
||||
const value = ref<number>(accessStore.visitTenantId ?? undefined); // 当前访问的租户 ID
|
||||
const tenants = ref<SystemTenantApi.Tenant[]>([]); // 租户列表
|
||||
// 当前访问的租户 ID
|
||||
const value = ref<number | undefined>(accessStore.visitTenantId ?? undefined);
|
||||
// 租户列表
|
||||
const tenants = ref<SystemTenantApi.Tenant[]>([]);
|
||||
|
||||
// TODO @xingyu:这个有可能 3 端复用么?
|
||||
async function handleChange(id: SelectValue) {
|
||||
// 设置访问租户 ID
|
||||
accessStore.setVisitTenantId(id as number);
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
import type { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: '/ai',
|
||||
name: 'Ai',
|
||||
meta: {
|
||||
title: 'Ai',
|
||||
hideInMenu: true,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'image/square',
|
||||
component: () => import('#/views/ai/image/square/index.vue'),
|
||||
name: 'AiImageSquare',
|
||||
meta: {
|
||||
noCache: true,
|
||||
hidden: true,
|
||||
canTo: true,
|
||||
title: '绘图作品',
|
||||
activePath: '/ai/image',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'knowledge/document',
|
||||
component: () => import('#/views/ai/knowledge/document/index.vue'),
|
||||
name: 'AiKnowledgeDocument',
|
||||
meta: {
|
||||
noCache: true,
|
||||
hidden: true,
|
||||
canTo: true,
|
||||
title: '知识库文档',
|
||||
activePath: '/ai/knowledge',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'knowledge/document/create',
|
||||
component: () => import('#/views/ai/knowledge/document/form/index.vue'),
|
||||
name: 'AiKnowledgeDocumentCreate',
|
||||
meta: {
|
||||
noCache: true,
|
||||
hidden: true,
|
||||
canTo: true,
|
||||
title: '创建文档',
|
||||
activePath: '/ai/knowledge',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'knowledge/document/update',
|
||||
component: () => import('#/views/ai/knowledge/document/form/index.vue'),
|
||||
name: 'AiKnowledgeDocumentUpdate',
|
||||
meta: {
|
||||
noCache: true,
|
||||
hidden: true,
|
||||
canTo: true,
|
||||
title: '修改文档',
|
||||
activePath: '/ai/knowledge',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'knowledge/retrieval',
|
||||
component: () =>
|
||||
import('#/views/ai/knowledge/knowledge/retrieval/index.vue'),
|
||||
name: 'AiKnowledgeRetrieval',
|
||||
meta: {
|
||||
noCache: true,
|
||||
hidden: true,
|
||||
canTo: true,
|
||||
title: '文档召回测试',
|
||||
activePath: '/ai/knowledge',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'knowledge/segment',
|
||||
component: () => import('#/views/ai/knowledge/segment/index.vue'),
|
||||
name: 'AiKnowledgeSegment',
|
||||
meta: {
|
||||
noCache: true,
|
||||
hidden: true,
|
||||
canTo: true,
|
||||
title: '知识库分段',
|
||||
activePath: '/ai/knowledge',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'console/workflow/create',
|
||||
component: () => import('#/views/ai/workflow/form/index.vue'),
|
||||
name: 'AiWorkflowCreate',
|
||||
meta: {
|
||||
noCache: true,
|
||||
hidden: true,
|
||||
canTo: true,
|
||||
title: '设计 AI 工作流',
|
||||
activePath: '/ai/workflow',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'console/workflow/:type/:id',
|
||||
component: () => import('#/views/ai/workflow/form/index.vue'),
|
||||
name: 'AiWorkflowUpdate',
|
||||
meta: {
|
||||
noCache: true,
|
||||
hidden: true,
|
||||
canTo: true,
|
||||
title: '设计 AI 工作流',
|
||||
activePath: '/ai/workflow',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default routes;
|
|
@ -5,6 +5,244 @@
|
|||
* 枚举类
|
||||
*/
|
||||
|
||||
/**
|
||||
* AI 平台的枚举
|
||||
*/
|
||||
export const AiPlatformEnum = {
|
||||
TONG_YI: 'TongYi', // 阿里
|
||||
YI_YAN: 'YiYan', // 百度
|
||||
DEEP_SEEK: 'DeepSeek', // DeepSeek
|
||||
ZHI_PU: 'ZhiPu', // 智谱 AI
|
||||
XING_HUO: 'XingHuo', // 讯飞
|
||||
SiliconFlow: 'SiliconFlow', // 硅基流动
|
||||
OPENAI: 'OpenAI',
|
||||
Ollama: 'Ollama',
|
||||
STABLE_DIFFUSION: 'StableDiffusion', // Stability AI
|
||||
MIDJOURNEY: 'Midjourney', // Midjourney
|
||||
SUNO: 'Suno', // Suno AI
|
||||
};
|
||||
|
||||
export const AiModelTypeEnum = {
|
||||
CHAT: 1, // 聊天
|
||||
IMAGE: 2, // 图像
|
||||
VOICE: 3, // 音频
|
||||
VIDEO: 4, // 视频
|
||||
EMBEDDING: 5, // 向量
|
||||
RERANK: 6, // 重排
|
||||
};
|
||||
export interface ImageModelVO {
|
||||
key: string;
|
||||
name: string;
|
||||
image?: string;
|
||||
}
|
||||
export const OtherPlatformEnum: ImageModelVO[] = [
|
||||
{
|
||||
key: AiPlatformEnum.TONG_YI,
|
||||
name: '通义万相',
|
||||
},
|
||||
{
|
||||
key: AiPlatformEnum.YI_YAN,
|
||||
name: '百度千帆',
|
||||
},
|
||||
{
|
||||
key: AiPlatformEnum.ZHI_PU,
|
||||
name: '智谱 AI',
|
||||
},
|
||||
{
|
||||
key: AiPlatformEnum.SiliconFlow,
|
||||
name: '硅基流动',
|
||||
},
|
||||
];
|
||||
/**
|
||||
* AI 图像生成状态的枚举
|
||||
*/
|
||||
export const AiImageStatusEnum = {
|
||||
IN_PROGRESS: 10, // 进行中
|
||||
SUCCESS: 20, // 已完成
|
||||
FAIL: 30, // 已失败
|
||||
};
|
||||
/**
|
||||
* AI 音乐生成状态的枚举
|
||||
*/
|
||||
export const AiMusicStatusEnum = {
|
||||
IN_PROGRESS: 10, // 进行中
|
||||
SUCCESS: 20, // 已完成
|
||||
FAIL: 30, // 已失败
|
||||
};
|
||||
|
||||
/**
|
||||
* AI 写作类型的枚举
|
||||
*/
|
||||
export enum AiWriteTypeEnum {
|
||||
WRITING = 1, // 撰写
|
||||
REPLY, // 回复
|
||||
}
|
||||
|
||||
// ========== 【图片 UI】相关的枚举 ==========
|
||||
|
||||
export const ImageHotWords = [
|
||||
'中国旗袍',
|
||||
'古装美女',
|
||||
'卡通头像',
|
||||
'机甲战士',
|
||||
'童话小屋',
|
||||
'中国长城',
|
||||
]; // 图片热词
|
||||
|
||||
export const ImageHotEnglishWords = [
|
||||
'Chinese Cheongsam',
|
||||
'Ancient Beauty',
|
||||
'Cartoon Avatar',
|
||||
'Mech Warrior',
|
||||
'Fairy Tale Cottage',
|
||||
'The Great Wall of China',
|
||||
]; // 图片热词(英文)
|
||||
|
||||
export const StableDiffusionSamplers: ImageModelVO[] = [
|
||||
{
|
||||
key: 'DDIM',
|
||||
name: 'DDIM',
|
||||
},
|
||||
{
|
||||
key: 'DDPM',
|
||||
name: 'DDPM',
|
||||
},
|
||||
{
|
||||
key: 'K_DPMPP_2M',
|
||||
name: 'K_DPMPP_2M',
|
||||
},
|
||||
{
|
||||
key: 'K_DPMPP_2S_ANCESTRAL',
|
||||
name: 'K_DPMPP_2S_ANCESTRAL',
|
||||
},
|
||||
{
|
||||
key: 'K_DPM_2',
|
||||
name: 'K_DPM_2',
|
||||
},
|
||||
{
|
||||
key: 'K_DPM_2_ANCESTRAL',
|
||||
name: 'K_DPM_2_ANCESTRAL',
|
||||
},
|
||||
{
|
||||
key: 'K_EULER',
|
||||
name: 'K_EULER',
|
||||
},
|
||||
{
|
||||
key: 'K_EULER_ANCESTRAL',
|
||||
name: 'K_EULER_ANCESTRAL',
|
||||
},
|
||||
{
|
||||
key: 'K_HEUN',
|
||||
name: 'K_HEUN',
|
||||
},
|
||||
{
|
||||
key: 'K_LMS',
|
||||
name: 'K_LMS',
|
||||
},
|
||||
];
|
||||
|
||||
export const StableDiffusionStylePresets: ImageModelVO[] = [
|
||||
{
|
||||
key: '3d-model',
|
||||
name: '3d-model',
|
||||
},
|
||||
{
|
||||
key: 'analog-film',
|
||||
name: 'analog-film',
|
||||
},
|
||||
{
|
||||
key: 'anime',
|
||||
name: 'anime',
|
||||
},
|
||||
{
|
||||
key: 'cinematic',
|
||||
name: 'cinematic',
|
||||
},
|
||||
{
|
||||
key: 'comic-book',
|
||||
name: 'comic-book',
|
||||
},
|
||||
{
|
||||
key: 'digital-art',
|
||||
name: 'digital-art',
|
||||
},
|
||||
{
|
||||
key: 'enhance',
|
||||
name: 'enhance',
|
||||
},
|
||||
{
|
||||
key: 'fantasy-art',
|
||||
name: 'fantasy-art',
|
||||
},
|
||||
{
|
||||
key: 'isometric',
|
||||
name: 'isometric',
|
||||
},
|
||||
{
|
||||
key: 'line-art',
|
||||
name: 'line-art',
|
||||
},
|
||||
{
|
||||
key: 'low-poly',
|
||||
name: 'low-poly',
|
||||
},
|
||||
{
|
||||
key: 'modeling-compound',
|
||||
name: 'modeling-compound',
|
||||
},
|
||||
// neon-punk origami photographic pixel-art tile-texture
|
||||
{
|
||||
key: 'neon-punk',
|
||||
name: 'neon-punk',
|
||||
},
|
||||
{
|
||||
key: 'origami',
|
||||
name: 'origami',
|
||||
},
|
||||
{
|
||||
key: 'photographic',
|
||||
name: 'photographic',
|
||||
},
|
||||
{
|
||||
key: 'pixel-art',
|
||||
name: 'pixel-art',
|
||||
},
|
||||
{
|
||||
key: 'tile-texture',
|
||||
name: 'tile-texture',
|
||||
},
|
||||
];
|
||||
|
||||
export const StableDiffusionClipGuidancePresets: ImageModelVO[] = [
|
||||
{
|
||||
key: 'NONE',
|
||||
name: 'NONE',
|
||||
},
|
||||
{
|
||||
key: 'FAST_BLUE',
|
||||
name: 'FAST_BLUE',
|
||||
},
|
||||
{
|
||||
key: 'FAST_GREEN',
|
||||
name: 'FAST_GREEN',
|
||||
},
|
||||
{
|
||||
key: 'SIMPLE',
|
||||
name: 'SIMPLE',
|
||||
},
|
||||
{
|
||||
key: 'SLOW',
|
||||
name: 'SLOW',
|
||||
},
|
||||
{
|
||||
key: 'SLOWER',
|
||||
name: 'SLOWER',
|
||||
},
|
||||
{
|
||||
key: 'SLOWEST',
|
||||
name: 'SLOWEST',
|
||||
},
|
||||
];
|
||||
// ========== COMMON 模块 ==========
|
||||
// 全局通用状态枚举
|
||||
export const CommonStatusEnum = {
|
||||
|
@ -92,7 +330,136 @@ export const InfraApiErrorLogProcessStatusEnum = {
|
|||
DONE: 1, // 已处理
|
||||
IGNORE: 2, // 已忽略
|
||||
};
|
||||
export interface ImageSizeVO {
|
||||
key: string;
|
||||
name?: string;
|
||||
style: string;
|
||||
width: string;
|
||||
height: string;
|
||||
}
|
||||
export const Dall3SizeList: ImageSizeVO[] = [
|
||||
{
|
||||
key: '1024x1024',
|
||||
name: '1:1',
|
||||
width: '1024',
|
||||
height: '1024',
|
||||
style: 'width: 30px; height: 30px;background-color: #dcdcdc;',
|
||||
},
|
||||
{
|
||||
key: '1024x1792',
|
||||
name: '3:5',
|
||||
width: '1024',
|
||||
height: '1792',
|
||||
style: 'width: 30px; height: 50px;background-color: #dcdcdc;',
|
||||
},
|
||||
{
|
||||
key: '1792x1024',
|
||||
name: '5:3',
|
||||
width: '1792',
|
||||
height: '1024',
|
||||
style: 'width: 50px; height: 30px;background-color: #dcdcdc;',
|
||||
},
|
||||
];
|
||||
|
||||
export const Dall3Models: ImageModelVO[] = [
|
||||
{
|
||||
key: 'dall-e-3',
|
||||
name: 'DALL·E 3',
|
||||
image: `/static/imgs/ai/dall2.jpg`,
|
||||
},
|
||||
{
|
||||
key: 'dall-e-2',
|
||||
name: 'DALL·E 2',
|
||||
image: `/static/imgs/ai/dall3.jpg`,
|
||||
},
|
||||
];
|
||||
|
||||
export const Dall3StyleList: ImageModelVO[] = [
|
||||
{
|
||||
key: 'vivid',
|
||||
name: '清晰',
|
||||
image: `/static/imgs/ai/qingxi.jpg`,
|
||||
},
|
||||
{
|
||||
key: 'natural',
|
||||
name: '自然',
|
||||
image: `/static/imgs/ai/ziran.jpg`,
|
||||
},
|
||||
];
|
||||
export const MidjourneyModels: ImageModelVO[] = [
|
||||
{
|
||||
key: 'midjourney',
|
||||
name: 'MJ',
|
||||
image: 'https://bigpt8.com/pc/_nuxt/mj.34a61377.png',
|
||||
},
|
||||
{
|
||||
key: 'niji',
|
||||
name: 'NIJI',
|
||||
image: 'https://bigpt8.com/pc/_nuxt/nj.ca79b143.png',
|
||||
},
|
||||
];
|
||||
export const MidjourneyVersions = [
|
||||
{
|
||||
value: '6.0',
|
||||
label: 'v6.0',
|
||||
},
|
||||
{
|
||||
value: '5.2',
|
||||
label: 'v5.2',
|
||||
},
|
||||
{
|
||||
value: '5.1',
|
||||
label: 'v5.1',
|
||||
},
|
||||
{
|
||||
value: '5.0',
|
||||
label: 'v5.0',
|
||||
},
|
||||
{
|
||||
value: '4.0',
|
||||
label: 'v4.0',
|
||||
},
|
||||
];
|
||||
|
||||
export const NijiVersionList = [
|
||||
{
|
||||
value: '5',
|
||||
label: 'v5',
|
||||
},
|
||||
];
|
||||
|
||||
export const MidjourneySizeList: ImageSizeVO[] = [
|
||||
{
|
||||
key: '1:1',
|
||||
width: '1',
|
||||
height: '1',
|
||||
style: 'width: 30px; height: 30px;background-color: #dcdcdc;',
|
||||
},
|
||||
{
|
||||
key: '3:4',
|
||||
width: '3',
|
||||
height: '4',
|
||||
style: 'width: 30px; height: 40px;background-color: #dcdcdc;',
|
||||
},
|
||||
{
|
||||
key: '4:3',
|
||||
width: '4',
|
||||
height: '3',
|
||||
style: 'width: 40px; height: 30px;background-color: #dcdcdc;',
|
||||
},
|
||||
{
|
||||
key: '9:16',
|
||||
width: '9',
|
||||
height: '16',
|
||||
style: 'width: 30px; height: 50px;background-color: #dcdcdc;',
|
||||
},
|
||||
{
|
||||
key: '16:9',
|
||||
width: '16',
|
||||
height: '9',
|
||||
style: 'width: 50px; height: 30px;background-color: #dcdcdc;',
|
||||
},
|
||||
];
|
||||
// ========== PAY 模块 ==========
|
||||
/**
|
||||
* 支付渠道枚举
|
||||
|
@ -743,3 +1110,81 @@ export enum ProcessVariableEnum {
|
|||
*/
|
||||
START_USER_ID = 'PROCESS_START_USER_ID',
|
||||
}
|
||||
// ========== 【写作 UI】相关的枚举 ==========
|
||||
|
||||
/** 写作点击示例时的数据 */
|
||||
export const WriteExample = {
|
||||
write: {
|
||||
prompt: 'vue',
|
||||
data: 'Vue.js 是一种用于构建用户界面的渐进式 JavaScript 框架。它的核心库只关注视图层,易于上手,同时也便于与其他库或已有项目整合。\n\nVue.js 的特点包括:\n- 响应式的数据绑定:Vue.js 会自动将数据与 DOM 同步,使得状态管理变得更加简单。\n- 组件化:Vue.js 允许开发者通过小型、独立和通常可复用的组件构建大型应用。\n- 虚拟 DOM:Vue.js 使用虚拟 DOM 实现快速渲染,提高了性能。\n\n在 Vue.js 中,一个典型的应用结构可能包括:\n1. 根实例:每个 Vue 应用都需要一个根实例作为入口点。\n2. 组件系统:可以创建自定义的可复用组件。\n3. 指令:特殊的带有前缀 v- 的属性,为 DOM 元素提供特殊的行为。\n4. 插值:用于文本内容,将数据动态地插入到 HTML。\n5. 计算属性和侦听器:用于处理数据的复杂逻辑和响应数据变化。\n6. 条件渲染:根据条件决定元素的渲染。\n7. 列表渲染:用于显示列表数据。\n8. 事件处理:响应用户交互。\n9. 表单输入绑定:处理表单输入和验证。\n10. 组件生命周期钩子:在组件的不同阶段执行特定的函数。\n\nVue.js 还提供了官方的路由器 Vue Router 和状态管理库 Vuex,以支持构建复杂的单页应用(SPA)。\n\n在开发过程中,开发者通常会使用 Vue CLI,这是一个强大的命令行工具,用于快速生成 Vue 项目脚手架,集成了诸如 Babel、Webpack 等现代前端工具,以及热重载、代码检测等开发体验优化功能。\n\nVue.js 的生态系统还包括大量的第三方库和插件,如 Vuetify(UI 组件库)、Vue Test Utils(测试工具)等,这些都极大地丰富了 Vue.js 的开发生态。\n\n总的来说,Vue.js 是一个灵活、高效的前端框架,适合从小型项目到大型企业级应用的开发。它的易用性、灵活性和强大的社区支持使其成为许多开发者的首选框架之一。',
|
||||
},
|
||||
reply: {
|
||||
originalContent: '领导,我想请假',
|
||||
prompt: '不批',
|
||||
data: '您的请假申请已收悉,经核实和考虑,暂时无法批准您的请假申请。\n\n如有特殊情况或紧急事务,请及时与我联系。\n\n祝工作顺利。\n\n谢谢。',
|
||||
},
|
||||
};
|
||||
|
||||
// ========== 【思维导图 UI】相关的枚举 ==========
|
||||
|
||||
/** 思维导图已有内容生成示例 */
|
||||
export const MindMapContentExample = `# Java 技术栈
|
||||
|
||||
## 核心技术
|
||||
### Java SE
|
||||
### Java EE
|
||||
|
||||
## 框架
|
||||
### Spring
|
||||
#### Spring Boot
|
||||
#### Spring MVC
|
||||
#### Spring Data
|
||||
### Hibernate
|
||||
### MyBatis
|
||||
|
||||
## 构建工具
|
||||
### Maven
|
||||
### Gradle
|
||||
|
||||
## 版本控制
|
||||
### Git
|
||||
### SVN
|
||||
|
||||
## 测试工具
|
||||
### JUnit
|
||||
### Mockito
|
||||
### Selenium
|
||||
|
||||
## 应用服务器
|
||||
### Tomcat
|
||||
### Jetty
|
||||
### WildFly
|
||||
|
||||
## 数据库
|
||||
### MySQL
|
||||
### PostgreSQL
|
||||
### Oracle
|
||||
### MongoDB
|
||||
|
||||
## 消息队列
|
||||
### Kafka
|
||||
### RabbitMQ
|
||||
### ActiveMQ
|
||||
|
||||
## 微服务
|
||||
### Spring Cloud
|
||||
### Dubbo
|
||||
|
||||
## 容器化
|
||||
### Docker
|
||||
### Kubernetes
|
||||
|
||||
## 云服务
|
||||
### AWS
|
||||
### Azure
|
||||
### Google Cloud
|
||||
|
||||
## 开发工具
|
||||
### IntelliJ IDEA
|
||||
### Eclipse
|
||||
### Visual Studio Code`;
|
||||
|
|
|
@ -143,10 +143,10 @@ export const getBoolDictOptions = (dictType: string) => {
|
|||
enum DICT_TYPE {
|
||||
AI_GENERATE_MODE = 'ai_generate_mode', // AI 生成模式
|
||||
AI_IMAGE_STATUS = 'ai_image_status', // AI 图片状态
|
||||
AI_MODEL_TYPE = 'ai_model_type', // AI 模型类型
|
||||
AI_MUSIC_STATUS = 'ai_music_status', // AI 音乐状态
|
||||
// ========== AI - 人工智能模块 ==========
|
||||
AI_PLATFORM = 'ai_platform', // AI 平台
|
||||
|
||||
AI_WRITE_FORMAT = 'ai_write_format', // AI 写作格式
|
||||
AI_WRITE_LANGUAGE = 'ai_write_language', // AI 写作语言
|
||||
AI_WRITE_LENGTH = 'ai_write_length', // AI 写作长度
|
||||
|
|
|
@ -1,215 +0,0 @@
|
|||
/**
|
||||
* 下载工具模块
|
||||
* 提供多种文件格式的下载功能
|
||||
*/
|
||||
// TODO @ziye:请使用 @vben/utils/download 代替 packages/@core/base/shared/src/utils/download.ts
|
||||
|
||||
/**
|
||||
* 图片下载配置接口
|
||||
*/
|
||||
interface ImageDownloadOptions {
|
||||
/** 图片 URL */
|
||||
url: string;
|
||||
/** 指定画布宽度 */
|
||||
canvasWidth?: number;
|
||||
/** 指定画布高度 */
|
||||
canvasHeight?: number;
|
||||
/** 将图片绘制在画布上时带上图片的宽高值,默认为 true */
|
||||
drawWithImageSize?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 基础文件下载函数
|
||||
* @param data - 文件数据 Blob
|
||||
* @param fileName - 文件名
|
||||
* @param mimeType - MIME 类型
|
||||
*/
|
||||
export const download0 = (data: Blob, fileName: string, mimeType: string) => {
|
||||
try {
|
||||
// 创建 blob
|
||||
const blob = new Blob([data], { type: mimeType });
|
||||
// 创建 href 超链接,点击进行下载
|
||||
window.URL = window.URL || window.webkitURL;
|
||||
const href = URL.createObjectURL(blob);
|
||||
const downA = document.createElement('a');
|
||||
downA.href = href;
|
||||
downA.download = fileName;
|
||||
downA.click();
|
||||
// 销毁超链接
|
||||
window.URL.revokeObjectURL(href);
|
||||
} catch (error) {
|
||||
console.error('文件下载失败:', error);
|
||||
throw new Error(
|
||||
`文件下载失败: ${error instanceof Error ? error.message : '未知错误'}`,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 触发文件下载的通用方法
|
||||
* @param url - 下载链接
|
||||
* @param fileName - 文件名
|
||||
*/
|
||||
const triggerDownload = (url: string, fileName: string) => {
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = fileName;
|
||||
a.click();
|
||||
};
|
||||
|
||||
export const download = {
|
||||
/**
|
||||
* 下载 Excel 文件
|
||||
* @param data - 文件数据 Blob
|
||||
* @param fileName - 文件名
|
||||
*/
|
||||
excel: (data: Blob, fileName: string) => {
|
||||
download0(data, fileName, 'application/vnd.ms-excel');
|
||||
},
|
||||
|
||||
/**
|
||||
* 下载 Word 文件
|
||||
* @param data - 文件数据 Blob
|
||||
* @param fileName - 文件名
|
||||
*/
|
||||
word: (data: Blob, fileName: string) => {
|
||||
download0(data, fileName, 'application/msword');
|
||||
},
|
||||
|
||||
/**
|
||||
* 下载 Zip 文件
|
||||
* @param data - 文件数据 Blob
|
||||
* @param fileName - 文件名
|
||||
*/
|
||||
zip: (data: Blob, fileName: string) => {
|
||||
download0(data, fileName, 'application/zip');
|
||||
},
|
||||
|
||||
/**
|
||||
* 下载 HTML 文件
|
||||
* @param data - 文件数据 Blob
|
||||
* @param fileName - 文件名
|
||||
*/
|
||||
html: (data: Blob, fileName: string) => {
|
||||
download0(data, fileName, 'text/html');
|
||||
},
|
||||
|
||||
/**
|
||||
* 下载 Markdown 文件
|
||||
* @param data - 文件数据 Blob
|
||||
* @param fileName - 文件名
|
||||
*/
|
||||
markdown: (data: Blob, fileName: string) => {
|
||||
download0(data, fileName, 'text/markdown');
|
||||
},
|
||||
|
||||
/**
|
||||
* 下载 JSON 文件
|
||||
* @param data - 文件数据 Blob
|
||||
* @param fileName - 文件名
|
||||
*/
|
||||
json: (data: Blob, fileName: string) => {
|
||||
download0(data, fileName, 'application/json');
|
||||
},
|
||||
|
||||
/**
|
||||
* 下载图片(允许跨域)
|
||||
* @param options - 图片下载配置
|
||||
*/
|
||||
image: (options: ImageDownloadOptions) => {
|
||||
const {
|
||||
url,
|
||||
canvasWidth,
|
||||
canvasHeight,
|
||||
drawWithImageSize = true,
|
||||
} = options;
|
||||
|
||||
const image = new Image();
|
||||
// image.setAttribute('crossOrigin', 'anonymous')
|
||||
image.src = url;
|
||||
image.addEventListener('load', () => {
|
||||
try {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = canvasWidth || image.width;
|
||||
canvas.height = canvasHeight || image.height;
|
||||
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
|
||||
ctx?.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
if (drawWithImageSize) {
|
||||
ctx.drawImage(image, 0, 0, image.width, image.height);
|
||||
} else {
|
||||
ctx.drawImage(image, 0, 0);
|
||||
}
|
||||
|
||||
const dataUrl = canvas.toDataURL('image/png');
|
||||
triggerDownload(dataUrl, 'image.png');
|
||||
} catch (error) {
|
||||
console.error('图片下载失败:', error);
|
||||
throw new Error(
|
||||
`图片下载失败: ${error instanceof Error ? error.message : '未知错误'}`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
image.addEventListener('error', () => {
|
||||
throw new Error('图片加载失败');
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 将 Base64 字符串转换为文件对象
|
||||
* @param base64 - Base64 字符串
|
||||
* @param fileName - 文件名
|
||||
* @returns File 对象
|
||||
*/
|
||||
base64ToFile: (base64: string, fileName: string): File => {
|
||||
// 输入验证
|
||||
if (!base64 || typeof base64 !== 'string') {
|
||||
throw new Error('base64 参数必须是非空字符串');
|
||||
}
|
||||
|
||||
// 将 base64 按照逗号进行分割,将前缀与后续内容分隔开
|
||||
const data = base64.split(',');
|
||||
if (data.length !== 2 || !data[0] || !data[1]) {
|
||||
throw new Error('无效的 base64 格式');
|
||||
}
|
||||
|
||||
// 利用正则表达式从前缀中获取类型信息(image/png、image/jpeg、image/webp等)
|
||||
const typeMatch = data[0].match(/:(.*?);/);
|
||||
if (!typeMatch || !typeMatch[1]) {
|
||||
throw new Error('无法解析 base64 类型信息');
|
||||
}
|
||||
const type = typeMatch[1];
|
||||
|
||||
// 从类型信息中获取具体的文件格式后缀(png、jpeg、webp)
|
||||
const typeParts = type.split('/');
|
||||
if (typeParts.length !== 2 || !typeParts[1]) {
|
||||
throw new Error('无效的 MIME 类型格式');
|
||||
}
|
||||
const suffix = typeParts[1];
|
||||
|
||||
try {
|
||||
// 使用 atob() 对 base64 数据进行解码,结果是一个文件数据流以字符串的格式输出
|
||||
const bstr = window.atob(data[1]);
|
||||
|
||||
// 获取解码结果字符串的长度
|
||||
const n = bstr.length;
|
||||
// 根据解码结果字符串的长度创建一个等长的整型数字数组
|
||||
const u8arr = new Uint8Array(n);
|
||||
|
||||
// 优化的 Uint8Array 填充逻辑
|
||||
for (let i = 0; i < n; i++) {
|
||||
// 使用 charCodeAt() 获取字符对应的字节值(Base64 解码后的字符串是字节级别的)
|
||||
// eslint-disable-next-line unicorn/prefer-code-point
|
||||
u8arr[i] = bstr.charCodeAt(i);
|
||||
}
|
||||
|
||||
// 返回 File 文件对象
|
||||
return new File([u8arr], `${fileName}.${suffix}`, { type });
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Base64 解码失败: ${error instanceof Error ? error.message : '未知错误'}`,
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
|
@ -1,6 +1,5 @@
|
|||
export * from './constants';
|
||||
export * from './dict';
|
||||
export * from './download';
|
||||
export * from './formCreate';
|
||||
export * from './rangePickerProps';
|
||||
export * from './routerHelper';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { defineAsyncComponent } from 'vue';
|
||||
|
||||
const modules = import.meta.glob('../views/**/*.{vue,tsx}');
|
||||
// TODO @xingyu:这个要不要融合到哪个 router util 里? utils 里面没有引入 vue 使用不了 defineAsyncComponent
|
||||
|
||||
/**
|
||||
* 注册一个异步组件
|
||||
* @param componentPath 例:/bpm/oa/leave/detail
|
||||
|
|
|
@ -19,7 +19,7 @@ const authStore = useAuthStore();
|
|||
const activeName = ref('basicInfo');
|
||||
|
||||
/** 加载个人信息 */
|
||||
const profile = ref<SystemUserProfileApi.UserProfileRespVO>();
|
||||
const profile = ref<SystemUserProfileApi.UserProfileResp>();
|
||||
async function loadProfile() {
|
||||
profile.value = await getUserProfile();
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import { updateUserProfile } from '#/api/system/user/profile';
|
|||
import { DICT_TYPE, getDictOptions } from '#/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
profile?: SystemUserProfileApi.UserProfileRespVO;
|
||||
profile?: SystemUserProfileApi.UserProfileResp;
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: 'success'): void;
|
||||
|
@ -77,7 +77,7 @@ async function handleSubmit(values: Recordable<any>) {
|
|||
try {
|
||||
formApi.setLoading(true);
|
||||
// 提交表单
|
||||
await updateUserProfile(values as SystemUserProfileApi.UpdateProfileReqVO);
|
||||
await updateUserProfile(values as SystemUserProfileApi.UpdateProfileReq);
|
||||
// 关闭并提示
|
||||
emit('success');
|
||||
message.success($t('ui.actionMessage.operationSuccess'));
|
||||
|
|
|
@ -14,7 +14,7 @@ import { CropperAvatar } from '#/components/cropper';
|
|||
import { useUpload } from '#/components/upload/use-upload';
|
||||
|
||||
const props = defineProps<{
|
||||
profile?: SystemUserProfileApi.UserProfileRespVO;
|
||||
profile?: SystemUserProfileApi.UserProfileResp;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
|
|
@ -0,0 +1,445 @@
|
|||
<script setup lang="ts">
|
||||
import type { PropType } from 'vue';
|
||||
|
||||
import type { AiChatConversationApi } from '#/api/ai/chat/conversation';
|
||||
|
||||
import { h, onMounted, ref, toRefs, watch } from 'vue';
|
||||
|
||||
import { confirm, prompt, useVbenDrawer } from '@vben/common-ui';
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import { Button, Empty, Input, Layout, message } from 'ant-design-vue';
|
||||
|
||||
import {
|
||||
createChatConversationMy,
|
||||
deleteChatConversationMy,
|
||||
deleteChatConversationMyByUnpinned,
|
||||
getChatConversationMyList,
|
||||
updateChatConversationMy,
|
||||
} from '#/api/ai/chat/conversation';
|
||||
|
||||
import RoleRepository from '../role/RoleRepository.vue';
|
||||
|
||||
// 加载中定时器
|
||||
// 定义组件 props
|
||||
const props = defineProps({
|
||||
activeId: {
|
||||
type: [Number, null] as PropType<null | number>,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
// 定义钩子
|
||||
const emits = defineEmits([
|
||||
'onConversationCreate',
|
||||
'onConversationClick',
|
||||
'onConversationClear',
|
||||
'onConversationDelete',
|
||||
]);
|
||||
|
||||
const [Drawer, drawerApi] = useVbenDrawer({
|
||||
connectedComponent: RoleRepository,
|
||||
});
|
||||
|
||||
// 定义属性
|
||||
const searchName = ref<string>(''); // 对话搜索
|
||||
const activeConversationId = ref<null | number>(null); // 选中的对话,默认为 null
|
||||
const hoverConversationId = ref<null | number>(null); // 悬浮上去的对话
|
||||
const conversationList = ref([] as AiChatConversationApi.ChatConversationVO[]); // 对话列表
|
||||
const conversationMap = ref<any>({}); // 对话分组 (置顶、今天、三天前、一星期前、一个月前)
|
||||
const loading = ref<boolean>(false); // 加载中
|
||||
const loadingTime = ref<any>();
|
||||
|
||||
/** 搜索对话 */
|
||||
async function searchConversation() {
|
||||
// 恢复数据
|
||||
if (searchName.value.trim().length === 0) {
|
||||
conversationMap.value = await getConversationGroupByCreateTime(
|
||||
conversationList.value,
|
||||
);
|
||||
} else {
|
||||
// 过滤
|
||||
const filterValues = conversationList.value.filter((item) => {
|
||||
return item.title.includes(searchName.value.trim());
|
||||
});
|
||||
conversationMap.value =
|
||||
await getConversationGroupByCreateTime(filterValues);
|
||||
}
|
||||
}
|
||||
|
||||
/** 点击对话 */
|
||||
async function handleConversationClick(id: number) {
|
||||
// 过滤出选中的对话
|
||||
const filterConversation = conversationList.value.find((item) => {
|
||||
return item.id === id;
|
||||
});
|
||||
// 回调 onConversationClick
|
||||
// noinspection JSVoidFunctionReturnValueUsed
|
||||
const success = emits('onConversationClick', filterConversation) as any;
|
||||
// 切换对话
|
||||
if (success) {
|
||||
activeConversationId.value = id;
|
||||
}
|
||||
}
|
||||
|
||||
/** 获取对话列表 */
|
||||
async function getChatConversationList() {
|
||||
try {
|
||||
// 加载中
|
||||
loadingTime.value = setTimeout(() => {
|
||||
loading.value = true;
|
||||
}, 50);
|
||||
|
||||
// 1.1 获取 对话数据
|
||||
conversationList.value = await getChatConversationMyList();
|
||||
// 1.2 排序
|
||||
conversationList.value.sort((a, b) => {
|
||||
return Number(b.createTime) - Number(a.createTime);
|
||||
});
|
||||
// 1.3 没有任何对话情况
|
||||
if (conversationList.value.length === 0) {
|
||||
activeConversationId.value = null;
|
||||
conversationMap.value = {};
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 对话根据时间分组(置顶、今天、一天前、三天前、七天前、30 天前)
|
||||
conversationMap.value = await getConversationGroupByCreateTime(
|
||||
conversationList.value,
|
||||
);
|
||||
} finally {
|
||||
// 清理定时器
|
||||
if (loadingTime.value) {
|
||||
clearTimeout(loadingTime.value);
|
||||
}
|
||||
// 加载完成
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/** 按照 creteTime 创建时间,进行分组 */
|
||||
async function getConversationGroupByCreateTime(
|
||||
list: AiChatConversationApi.ChatConversationVO[],
|
||||
) {
|
||||
// 排序、指定、时间分组(今天、一天前、三天前、七天前、30天前)
|
||||
// noinspection NonAsciiCharacters
|
||||
const groupMap: any = {
|
||||
置顶: [],
|
||||
今天: [],
|
||||
一天前: [],
|
||||
三天前: [],
|
||||
七天前: [],
|
||||
三十天前: [],
|
||||
};
|
||||
// 当前时间的时间戳
|
||||
const now = Date.now();
|
||||
// 定义时间间隔常量(单位:毫秒)
|
||||
const oneDay = 24 * 60 * 60 * 1000;
|
||||
const threeDays = 3 * oneDay;
|
||||
const sevenDays = 7 * oneDay;
|
||||
const thirtyDays = 30 * oneDay;
|
||||
for (const conversation of list) {
|
||||
// 置顶
|
||||
if (conversation.pinned) {
|
||||
groupMap['置顶'].push(conversation);
|
||||
continue;
|
||||
}
|
||||
// 计算时间差(单位:毫秒)
|
||||
const diff = now - Number(conversation.createTime);
|
||||
// 根据时间间隔判断
|
||||
if (diff < oneDay) {
|
||||
groupMap['今天'].push(conversation);
|
||||
} else if (diff < threeDays) {
|
||||
groupMap['一天前'].push(conversation);
|
||||
} else if (diff < sevenDays) {
|
||||
groupMap['三天前'].push(conversation);
|
||||
} else if (diff < thirtyDays) {
|
||||
groupMap['七天前'].push(conversation);
|
||||
} else {
|
||||
groupMap['三十天前'].push(conversation);
|
||||
}
|
||||
}
|
||||
return groupMap;
|
||||
}
|
||||
|
||||
async function createConversation() {
|
||||
// 1. 新建对话
|
||||
const conversationId = await createChatConversationMy(
|
||||
{} as unknown as AiChatConversationApi.ChatConversationVO,
|
||||
);
|
||||
// 2. 获取对话内容
|
||||
await getChatConversationList();
|
||||
// 3. 选中对话
|
||||
await handleConversationClick(conversationId);
|
||||
// 4. 回调
|
||||
emits('onConversationCreate');
|
||||
}
|
||||
|
||||
/** 修改对话的标题 */
|
||||
async function updateConversationTitle(
|
||||
conversation: AiChatConversationApi.ChatConversationVO,
|
||||
) {
|
||||
// 1. 二次确认
|
||||
prompt({
|
||||
async beforeClose(scope) {
|
||||
if (scope.isConfirm) {
|
||||
if (scope.value) {
|
||||
try {
|
||||
// 2. 发起修改
|
||||
await updateChatConversationMy({
|
||||
id: conversation.id,
|
||||
title: scope.value,
|
||||
} as AiChatConversationApi.ChatConversationVO);
|
||||
message.success('重命名成功');
|
||||
// 3. 刷新列表
|
||||
await getChatConversationList();
|
||||
// 4. 过滤当前切换的
|
||||
const filterConversationList = conversationList.value.filter(
|
||||
(item) => {
|
||||
return item.id === conversation.id;
|
||||
},
|
||||
);
|
||||
if (
|
||||
filterConversationList.length > 0 &&
|
||||
filterConversationList[0] && // tip:避免切换对话
|
||||
activeConversationId.value === filterConversationList[0].id
|
||||
) {
|
||||
emits('onConversationClick', filterConversationList[0]);
|
||||
}
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
message.error('请输入标题');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
component: () => {
|
||||
return h(Input, {
|
||||
placeholder: '请输入标题',
|
||||
allowClear: true,
|
||||
defaultValue: conversation.title,
|
||||
rules: [{ required: true, message: '请输入标题' }],
|
||||
});
|
||||
},
|
||||
content: '请输入标题',
|
||||
title: '修改标题',
|
||||
modelPropName: 'value',
|
||||
});
|
||||
}
|
||||
|
||||
/** 删除聊天对话 */
|
||||
async function deleteChatConversation(
|
||||
conversation: AiChatConversationApi.ChatConversationVO,
|
||||
) {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await confirm(`是否确认删除对话 - ${conversation.title}?`);
|
||||
// 发起删除
|
||||
await deleteChatConversationMy(conversation.id);
|
||||
message.success('对话已删除');
|
||||
// 刷新列表
|
||||
await getChatConversationList();
|
||||
// 回调
|
||||
emits('onConversationDelete', conversation);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
async function handleClearConversation() {
|
||||
try {
|
||||
await confirm('确认后对话会全部清空,置顶的对话除外。');
|
||||
await deleteChatConversationMyByUnpinned();
|
||||
message.success('操作成功!');
|
||||
// 清空 对话 和 对话内容
|
||||
activeConversationId.value = null;
|
||||
// 获取 对话列表
|
||||
await getChatConversationList();
|
||||
// 回调 方法
|
||||
emits('onConversationClear');
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 对话置顶 */
|
||||
async function handleTop(
|
||||
conversation: AiChatConversationApi.ChatConversationVO,
|
||||
) {
|
||||
// 更新对话置顶
|
||||
conversation.pinned = !conversation.pinned;
|
||||
await updateChatConversationMy(conversation);
|
||||
// 刷新对话
|
||||
await getChatConversationList();
|
||||
}
|
||||
|
||||
// ============ 角色仓库 ============
|
||||
|
||||
/** 角色仓库抽屉 */
|
||||
const handleRoleRepository = async () => {
|
||||
drawerApi.open();
|
||||
};
|
||||
|
||||
/** 监听选中的对话 */
|
||||
const { activeId } = toRefs(props);
|
||||
watch(activeId, async (newValue) => {
|
||||
activeConversationId.value = newValue;
|
||||
});
|
||||
|
||||
// 定义 public 方法
|
||||
defineExpose({ createConversation });
|
||||
|
||||
/** 初始化 */
|
||||
onMounted(async () => {
|
||||
// 获取 对话列表
|
||||
await getChatConversationList();
|
||||
// 默认选中
|
||||
if (props.activeId) {
|
||||
activeConversationId.value = props.activeId;
|
||||
} else {
|
||||
// 首次默认选中第一个
|
||||
if (conversationList.value.length > 0 && conversationList.value[0]) {
|
||||
activeConversationId.value = conversationList.value[0].id;
|
||||
// 回调 onConversationClick
|
||||
await emits('onConversationClick', conversationList.value[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Layout.Sider
|
||||
width="260px"
|
||||
class="conversation-container relative flex h-full flex-col justify-between overflow-hidden bg-[hsl(var(--primary-foreground))!important] p-[10px_10px_0]"
|
||||
>
|
||||
<Drawer />
|
||||
<!-- 左顶部:对话 -->
|
||||
<div class="flex h-full flex-col">
|
||||
<Button
|
||||
class="btn-new-conversation h-[38px] w-full"
|
||||
type="primary"
|
||||
@click="createConversation"
|
||||
>
|
||||
<IconifyIcon icon="lucide:plus" class="mr-[5px]" />
|
||||
新建对话
|
||||
</Button>
|
||||
|
||||
<Input
|
||||
v-model:value="searchName"
|
||||
size="large"
|
||||
class="search-input mt-[20px]"
|
||||
placeholder="搜索历史记录"
|
||||
@keyup="searchConversation"
|
||||
>
|
||||
<template #prefix>
|
||||
<IconifyIcon icon="lucide:search" />
|
||||
</template>
|
||||
</Input>
|
||||
|
||||
<!-- 左中间:对话列表 -->
|
||||
<div class="conversation-list mt-[10px] flex-1 overflow-auto">
|
||||
<!-- 情况一:加载中 -->
|
||||
<Empty v-if="loading" description="." v-loading="loading" />
|
||||
|
||||
<!-- 情况二:按照 group 分组 -->
|
||||
<div
|
||||
v-for="conversationKey in Object.keys(conversationMap)"
|
||||
:key="conversationKey"
|
||||
class=""
|
||||
>
|
||||
<div
|
||||
v-if="conversationMap[conversationKey].length > 0"
|
||||
class="conversation-item classify-title pt-[10px]"
|
||||
>
|
||||
<b class="mx-[4px]">
|
||||
{{ conversationKey }}
|
||||
</b>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="conversation in conversationMap[conversationKey]"
|
||||
:key="conversation.id"
|
||||
@click="handleConversationClick(conversation.id)"
|
||||
@mouseover="hoverConversationId = conversation.id"
|
||||
@mouseout="hoverConversationId = null"
|
||||
class="conversation-item mt-[5px]"
|
||||
>
|
||||
<div
|
||||
class="conversation flex cursor-pointer flex-row items-center justify-between rounded-[5px] px-[5px] leading-[30px]"
|
||||
:class="[
|
||||
conversation.id === activeConversationId ? 'bg-[#e6e6e6]' : '',
|
||||
]"
|
||||
>
|
||||
<div class="title-wrapper flex items-center">
|
||||
<img
|
||||
class="avatar h-[25px] w-[25px] rounded-[5px]"
|
||||
:src="conversation.roleAvatar ?? '/static/gpt.svg'"
|
||||
/>
|
||||
<span
|
||||
class="title text-black/77 max-w-[150px] overflow-hidden text-ellipsis whitespace-nowrap px-[10px] py-[2px] text-[14px] font-normal"
|
||||
>
|
||||
{{ conversation.title }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="hoverConversationId === conversation.id"
|
||||
class="button-wrapper relative right-[2px] flex items-center text-[#606266]"
|
||||
>
|
||||
<Button
|
||||
class="btn mr-0 px-[5px]"
|
||||
type="link"
|
||||
@click.stop="handleTop(conversation)"
|
||||
>
|
||||
<IconifyIcon
|
||||
v-if="!conversation.pinned"
|
||||
icon="lucide:arrow-up"
|
||||
/>
|
||||
<IconifyIcon
|
||||
v-if="conversation.pinned"
|
||||
icon="lucide:arrow-down"
|
||||
/>
|
||||
</Button>
|
||||
<Button
|
||||
class="btn mr-0 px-[5px]"
|
||||
type="link"
|
||||
@click.stop="updateConversationTitle(conversation)"
|
||||
>
|
||||
<IconifyIcon icon="lucide:edit" />
|
||||
</Button>
|
||||
<Button
|
||||
class="btn mr-0 px-[5px]"
|
||||
type="link"
|
||||
@click.stop="deleteChatConversation(conversation)"
|
||||
>
|
||||
<IconifyIcon icon="lucide:trash" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部占位 -->
|
||||
<div class="h-[50px] w-full"></div>
|
||||
</div>
|
||||
|
||||
<!-- 左底部:工具栏 -->
|
||||
<div
|
||||
class="tool-box absolute bottom-0 left-0 right-0 flex items-center justify-between bg-[#f4f4f4] px-[20px] leading-[35px] text-[var(--el-text-color)] shadow-[0_0_1px_1px_rgba(228,228,228,0.8)]"
|
||||
>
|
||||
<div
|
||||
class="flex cursor-pointer items-center text-[#606266]"
|
||||
@click="handleRoleRepository"
|
||||
>
|
||||
<IconifyIcon icon="lucide:user" />
|
||||
<span class="ml-[5px]">角色仓库</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex cursor-pointer items-center text-[#606266]"
|
||||
@click="handleClearConversation"
|
||||
>
|
||||
<IconifyIcon icon="lucide:trash" />
|
||||
<span class="ml-[5px]">清空未置顶对话</span>
|
||||
</div>
|
||||
</div>
|
||||
</Layout.Sider>
|
||||
</template>
|
|
@ -0,0 +1,82 @@
|
|||
<script lang="ts" setup>
|
||||
import type { AiChatConversationApi } from '#/api/ai/chat/conversation';
|
||||
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import {
|
||||
getChatConversationMy,
|
||||
updateChatConversationMy,
|
||||
} from '#/api/ai/chat/conversation';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
import { useFormSchema } from '../../data';
|
||||
|
||||
const emit = defineEmits(['success']);
|
||||
const formData = ref<AiChatConversationApi.ChatConversationVO>();
|
||||
|
||||
const [Form, formApi] = useVbenForm({
|
||||
commonConfig: {
|
||||
componentProps: {
|
||||
class: 'w-full',
|
||||
},
|
||||
formItemClass: 'col-span-2',
|
||||
labelWidth: 140,
|
||||
},
|
||||
layout: 'horizontal',
|
||||
schema: useFormSchema(),
|
||||
showDefaultActions: false,
|
||||
});
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
async onConfirm() {
|
||||
const { valid } = await formApi.validate();
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
modalApi.lock();
|
||||
// 提交表单
|
||||
const data =
|
||||
(await formApi.getValues()) as AiChatConversationApi.ChatConversationVO;
|
||||
try {
|
||||
await updateChatConversationMy(data);
|
||||
|
||||
// 关闭并提示
|
||||
await modalApi.close();
|
||||
emit('success');
|
||||
message.success($t('ui.actionMessage.operationSuccess'));
|
||||
} finally {
|
||||
modalApi.unlock();
|
||||
}
|
||||
},
|
||||
async onOpenChange(isOpen: boolean) {
|
||||
if (!isOpen) {
|
||||
formData.value = undefined;
|
||||
return;
|
||||
}
|
||||
// 加载数据
|
||||
const data = modalApi.getData<AiChatConversationApi.ChatConversationVO>();
|
||||
if (!data || !data.id) {
|
||||
return;
|
||||
}
|
||||
modalApi.lock();
|
||||
try {
|
||||
formData.value = await getChatConversationMy(data.id as number);
|
||||
// 设置到 values
|
||||
await formApi.setValues(formData.value);
|
||||
} finally {
|
||||
modalApi.unlock();
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[600px]" title="设定">
|
||||
<Form class="mx-4" />
|
||||
</Modal>
|
||||
</template>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue