web修改

This commit is contained in:
2025-12-19 17:34:30 +08:00
parent cc372bc7ea
commit 9c4f73ac9c
22 changed files with 1660 additions and 822 deletions

View File

@@ -0,0 +1,68 @@
import { api } from '@/api/index'
import type { ResultDomain, PageRequest } from '@/types'
import type { TbAgent } from '@/types/ai'
/**
* @description 智能体管理接口
* @filename agent.ts
* @author yslg
* @copyright xyzh
* @since 2025-12-19
*/
export const agentAPI = {
baseUrl: '/urban-lifeline/ai/agent',
/**
* 创建智能体
* @param agent 智能体信息
*/
async createAgent(agent: TbAgent): Promise<ResultDomain<TbAgent>> {
const response = await api.post<TbAgent>(`${this.baseUrl}`, agent)
return response.data
},
/**
* 更新智能体
* @param agent 智能体信息
*/
async updateAgent(agent: TbAgent): Promise<ResultDomain<TbAgent>> {
const response = await api.put<TbAgent>(`${this.baseUrl}`, agent)
return response.data
},
/**
* 删除智能体
* @param agentId 智能体ID
*/
async deleteAgent(agentId: string): Promise<ResultDomain<TbAgent>> {
const response = await api.delete<TbAgent>(`${this.baseUrl}/${agentId}`)
return response.data
},
/**
* 获取智能体详情
* @param agentId 智能体ID
*/
async getAgent(agentId: string): Promise<ResultDomain<TbAgent>> {
const response = await api.get<TbAgent>(`${this.baseUrl}/${agentId}`)
return response.data
},
/**
* 分页查询智能体
* @param pageRequest 分页请求参数
*/
async getAgentPage(pageRequest: PageRequest<TbAgent>): Promise<ResultDomain<TbAgent>> {
const response = await api.post<TbAgent>(`${this.baseUrl}/page`, pageRequest)
return response.data
},
/**
* 获取智能体列表
* @param filter 筛选条件
*/
async getAgentList(filter?: TbAgent): Promise<ResultDomain<TbAgent>> {
const response = await api.get<TbAgent>(`${this.baseUrl}/list`, { params: filter })
return response.data
}
}

View File

@@ -0,0 +1,262 @@
import { api } from '@/api/index'
import type { ResultDomain, PageRequest } from '@/types'
import type { TbKnowledge, TbKnowledgeFile, SegmentRequestBody, DocumentStatusRequestBody } from '@/types/ai'
/**
* @description AI知识库相关接口
* @filename aiKnowledge.ts
* @author yslg
* @copyright xyzh
* @since 2025-12-19
*/
export const aiKnowledgeAPI = {
baseUrl: '/urban-lifeline/ai/knowledge',
// ====================== 知识库管理 ======================
/**
* 创建知识库
* @param knowledge 知识库信息
*/
async createKnowledge(knowledge: TbKnowledge): Promise<ResultDomain<TbKnowledge>> {
const response = await api.post<TbKnowledge>(`${this.baseUrl}`, knowledge)
return response.data
},
/**
* 更新知识库
* @param knowledge 知识库信息
*/
async updateKnowledge(knowledge: TbKnowledge): Promise<ResultDomain<TbKnowledge>> {
const response = await api.put<TbKnowledge>(`${this.baseUrl}`, knowledge)
return response.data
},
/**
* 删除知识库
* @param knowledgeId 知识库ID
*/
async deleteKnowledge(knowledgeId: string): Promise<ResultDomain<boolean>> {
const response = await api.delete<boolean>(`${this.baseUrl}/${knowledgeId}`)
return response.data
},
/**
* 获取知识库详情
* @param knowledgeId 知识库ID
*/
async getKnowledge(knowledgeId: string): Promise<ResultDomain<TbKnowledge>> {
const response = await api.get<TbKnowledge>(`${this.baseUrl}/${knowledgeId}`)
return response.data
},
/**
* 查询知识库列表
* @param filter 筛选条件
*/
async listKnowledges(filter?: TbKnowledge): Promise<ResultDomain<TbKnowledge>> {
const response = await api.post<TbKnowledge>(`${this.baseUrl}/list`, filter || {})
return response.data
},
/**
* 分页查询知识库
* @param pageRequest 分页请求
*/
async pageKnowledges(pageRequest: PageRequest<TbKnowledge>): Promise<ResultDomain<TbKnowledge>> {
const response = await api.post<TbKnowledge>(`${this.baseUrl}/page`, pageRequest)
return response.data
},
/**
* 获取知识库统计信息
* @param knowledgeId 知识库ID
*/
async getKnowledgeStats(knowledgeId: string): Promise<ResultDomain<TbKnowledge>> {
const response = await api.get<TbKnowledge>(`${this.baseUrl}/${knowledgeId}/stats`)
return response.data
},
// ====================== 文件管理 ======================
/**
* 获取知识库文档列表
* @param knowledgeId 知识库ID
* @param page 页码
* @param limit 每页条数
*/
async getDocumentList(knowledgeId: string, page = 1, limit = 20): Promise<ResultDomain<Record<string, any>>> {
const response = await api.get<Record<string, any>>(`${this.baseUrl}/${knowledgeId}/documents`, {
params: { page, limit }
})
return response.data
},
/**
* 上传文件到知识库
* @param file 文件
* @param knowledgeId 知识库ID
* @param indexingTechnique 索引方式
*/
async uploadToKnowledge(
file: File,
knowledgeId: string,
indexingTechnique?: string
): Promise<ResultDomain<TbKnowledgeFile>> {
const formData = new FormData()
formData.append('file', file)
formData.append('knowledgeId', knowledgeId)
if (indexingTechnique) {
formData.append('indexingTechnique', indexingTechnique)
}
const response = await api.upload<TbKnowledgeFile>(`${this.baseUrl}/file/upload`, formData)
return response.data
},
/**
* 批量上传文件到知识库
* @param files 文件数组
* @param knowledgeId 知识库ID
* @param indexingTechnique 索引方式
*/
async batchUploadToKnowledge(
files: File[],
knowledgeId: string,
indexingTechnique?: string
): Promise<ResultDomain<TbKnowledgeFile>> {
const formData = new FormData()
files.forEach(file => formData.append('files', file))
formData.append('knowledgeId', knowledgeId)
if (indexingTechnique) {
formData.append('indexingTechnique', indexingTechnique)
}
const response = await api.upload<TbKnowledgeFile>(`${this.baseUrl}/file/batch-upload`, formData)
return response.data
},
/**
* 更新知识库文件(上传新版本)
* @param file 文件
* @param knowledgeId 知识库ID
* @param fileRootId 文件根ID
*/
async updateFile(
file: File,
knowledgeId: string,
fileRootId: string
): Promise<ResultDomain<TbKnowledgeFile>> {
const formData = new FormData()
formData.append('file', file)
formData.append('knowledgeId', knowledgeId)
formData.append('fileRootId', fileRootId)
const response = await api.uploadPut<TbKnowledgeFile>(`${this.baseUrl}/file/upload`, formData)
return response.data
},
/**
* 删除知识库文件
* @param fileId 文件ID
*/
async deleteFile(fileId: string): Promise<ResultDomain<boolean>> {
const response = await api.delete<boolean>(`${this.baseUrl}/file/${fileId}`)
return response.data
},
/**
* 获取文件历史版本
* @param fileRootId 文件根ID
*/
async getFileHistory(fileRootId: string): Promise<ResultDomain<TbKnowledgeFile>> {
const response = await api.get<TbKnowledgeFile>(`${this.baseUrl}/file/${fileRootId}/history`)
return response.data
},
// ====================== 文档分段管理 ======================
/**
* 获取文档分段列表
* @param datasetId Dify数据集ID
* @param documentId Dify文档ID
*/
async getDocumentSegments(datasetId: string, documentId: string): Promise<ResultDomain<Record<string, any>>> {
const response = await api.get<Record<string, any>>(
`${this.baseUrl}/datasets/${datasetId}/documents/${documentId}/segments`
)
return response.data
},
/**
* 创建文档分段
* @param datasetId Dify数据集ID
* @param documentId Dify文档ID
* @param requestBody 分段内容
*/
async createSegment(
datasetId: string,
documentId: string,
requestBody: SegmentRequestBody
): Promise<ResultDomain<string>> {
const response = await api.post<string>(
`${this.baseUrl}/datasets/${datasetId}/documents/${documentId}/segments`,
requestBody
)
return response.data
},
/**
* 更新文档分段
* @param datasetId Dify数据集ID
* @param documentId Dify文档ID
* @param segmentId 分段ID
* @param requestBody 分段内容
*/
async updateSegment(
datasetId: string,
documentId: string,
segmentId: string,
requestBody: SegmentRequestBody
): Promise<ResultDomain<string>> {
const response = await api.patch<string>(
`${this.baseUrl}/datasets/${datasetId}/documents/${documentId}/segments/${segmentId}`,
requestBody
)
return response.data
},
/**
* 删除文档分段
* @param datasetId Dify数据集ID
* @param documentId Dify文档ID
* @param segmentId 分段ID
*/
async deleteSegment(
datasetId: string,
documentId: string,
segmentId: string
): Promise<ResultDomain<string>> {
const response = await api.delete<string>(
`${this.baseUrl}/datasets/${datasetId}/documents/${documentId}/segments/${segmentId}`
)
return response.data
},
// ====================== 文档状态管理 ======================
/**
* 更新文档状态(启用/禁用/归档)
* @param datasetId Dify数据集ID
* @param action 操作类型: enable/disable/archive/un_archive
* @param requestBody 请求体
*/
async updateDocumentStatus(
datasetId: string,
action: 'enable' | 'disable' | 'archive' | 'un_archive',
requestBody: DocumentStatusRequestBody
): Promise<ResultDomain<string>> {
const response = await api.patch<string>(
`${this.baseUrl}/datasets/${datasetId}/documents/${action}/status`,
requestBody
)
return response.data
}
}

View File

@@ -0,0 +1,124 @@
import { api } from '@/api/index'
import type { ResultDomain } from '@/types'
import type { TbChat, TbChatMessage, ChatPrepareData, StopChatParams, CommentMessageParams, DifyFileInfo } from '@/types/ai'
/**
* @description AI对话相关接口
* @filename aichat.ts
* @author yslg
* @copyright xyzh
* @since 2025-12-19
*/
export const aiChatAPI = {
baseUrl: '/urban-lifeline/ai/chat',
// ====================== 会话管理 ======================
/**
* 创建会话
* @param chat 会话信息
*/
async createChat(chat: TbChat): Promise<ResultDomain<TbChat>> {
const response = await api.post<TbChat>(`${this.baseUrl}/conversation`, chat)
return response.data
},
/**
* 更新会话
* @param chat 会话信息
*/
async updateChat(chat: TbChat): Promise<ResultDomain<TbChat>> {
const response = await api.put<TbChat>(`${this.baseUrl}/conversation`, chat)
return response.data
},
/**
* 删除会话
* @param chat 会话信息
*/
async deleteChat(chat: TbChat): Promise<ResultDomain<TbChat>> {
const response = await api.delete<TbChat>(`${this.baseUrl}/conversation`, { data: chat })
return response.data
},
/**
* 获取会话列表
* @param filter 筛选条件
*/
async getChatList(filter: TbChat): Promise<ResultDomain<TbChat>> {
const response = await api.get<TbChat>(`${this.baseUrl}/conversations`, { data: filter })
return response.data
},
// ====================== 消息管理 ======================
/**
* 获取对话消息列表
* @param filter 筛选条件
*/
async getMessageList(filter: TbChat): Promise<ResultDomain<TbChatMessage>> {
const response = await api.post<TbChatMessage>(`${this.baseUrl}/messages`, filter)
return response.data
},
// ====================== 流式对话 ======================
/**
* 准备流式对话会话数据
* @param chatPrepareData 对话预处理数据
*/
async prepareStreamChat(chatPrepareData: ChatPrepareData): Promise<ResultDomain<string>> {
const response = await api.post<string>(`${this.baseUrl}/stream/prepare`, chatPrepareData)
return response.data
},
/**
* 获取流式对话SSE URL
* @param sessionId 会话ID
*/
getStreamChatUrl(sessionId: string): string {
return `${this.baseUrl}/stream?sessionId=${sessionId}`
},
/**
* 创建流式对话 EventSource
* @param sessionId 会话ID
*/
createStreamChat(sessionId: string): EventSource {
const url = this.getStreamChatUrl(sessionId)
return new EventSource(url)
},
/**
* 停止对话
* @param params 停止参数
*/
async stopChat(params: StopChatParams): Promise<ResultDomain<boolean>> {
const response = await api.post<boolean>(`${this.baseUrl}/stop`, params)
return response.data
},
/**
* 评价消息
* @param params 评价参数
*/
async commentMessage(params: CommentMessageParams): Promise<ResultDomain<boolean>> {
const response = await api.post<boolean>(`${this.baseUrl}/comment`, params)
return response.data
},
// ====================== 文件上传 ======================
/**
* 上传文件用于对话(图文多模态)
* @param file 文件
* @param agentId 智能体ID
*/
async uploadFileForChat(file: File, agentId: string): Promise<ResultDomain<DifyFileInfo>> {
const formData = new FormData()
formData.append('file', file)
formData.append('agentId', agentId)
const response = await api.uploadPut<DifyFileInfo>(`${this.baseUrl}/file/upload`, formData)
return response.data
}
}

View File

@@ -0,0 +1,3 @@
export * from './agent'
export * from './aichat'
export * from './aiKnowledge'

View File

@@ -265,16 +265,17 @@ export const api = {
},
/**
* 文件上传
* 文件上传 (POST) - 使用 axios postForm
*/
upload<T = any>(url: string, formData: FormData, config?: CustomAxiosRequestConfig): Promise<AxiosResponse<ResultDomain<T>>> {
return request.post<ResultDomain<T>>(url, formData, {
...config,
headers: {
'Content-Type': 'multipart/form-data',
...(config?.headers as Record<string, string>)
}
});
return request.postForm<ResultDomain<T>>(url, formData, config);
},
/**
* 文件上传 (PUT) - 使用 axios putForm
*/
uploadPut<T = any>(url: string, formData: FormData, config?: CustomAxiosRequestConfig): Promise<AxiosResponse<ResultDomain<T>>> {
return request.putForm<ResultDomain<T>>(url, formData, config);
},
/**

View File

@@ -0,0 +1 @@
export * from './workcase'

View File

@@ -0,0 +1,185 @@
import { api } from '@/api/index'
import type { ResultDomain, PageRequest } from '@/types'
import type { TbWorkcaseDTO, TbWorkcaseProcessDTO, TbWorkcaseDeviceDTO } from '@/types/workcase'
/**
* @description 工单管理接口
* @filename workcase.ts
* @author yslg
* @copyright xyzh
* @since 2025-12-19
*/
export const workcaseAPI = {
baseUrl: '/urban-lifeline/workcase',
// ========================= 工单管理 =========================
/**
* 创建工单
* @param workcase 工单信息
*/
async createWorkcase(workcase: TbWorkcaseDTO): Promise<ResultDomain<TbWorkcaseDTO>> {
const response = await api.post<TbWorkcaseDTO>(`${this.baseUrl}`, workcase)
return response.data
},
/**
* 更新工单
* @param workcase 工单信息
*/
async updateWorkcase(workcase: TbWorkcaseDTO): Promise<ResultDomain<TbWorkcaseDTO>> {
const response = await api.put<TbWorkcaseDTO>(`${this.baseUrl}`, workcase)
return response.data
},
/**
* 删除工单
* @param workcaseId 工单ID
*/
async deleteWorkcase(workcaseId: string): Promise<ResultDomain<TbWorkcaseDTO>> {
const response = await api.delete<TbWorkcaseDTO>(`${this.baseUrl}/${workcaseId}`)
return response.data
},
/**
* 获取工单详情
* @param workcaseId 工单ID
*/
async getWorkcaseById(workcaseId: string): Promise<ResultDomain<TbWorkcaseDTO>> {
const response = await api.get<TbWorkcaseDTO>(`${this.baseUrl}/${workcaseId}`)
return response.data
},
/**
* 查询工单列表
* @param filter 筛选条件
*/
async getWorkcaseList(filter?: TbWorkcaseDTO): Promise<ResultDomain<TbWorkcaseDTO>> {
const response = await api.post<TbWorkcaseDTO>(`${this.baseUrl}/list`, filter || {})
return response.data
},
/**
* 分页查询工单
* @param pageRequest 分页请求
*/
async getWorkcasePage(pageRequest: PageRequest<TbWorkcaseDTO>): Promise<ResultDomain<TbWorkcaseDTO>> {
const response = await api.post<TbWorkcaseDTO>(`${this.baseUrl}/page`, pageRequest)
return response.data
},
// ========================= CRM同步接口 =========================
/**
* 同步工单到CRM
* @param workcase 工单信息
*/
async syncWorkcaseToCrm(workcase: TbWorkcaseDTO): Promise<ResultDomain<void>> {
const response = await api.post<void>(`${this.baseUrl}/sync/crm`, workcase)
return response.data
},
/**
* 接收CRM工单更新CRM回调
* @param jsonBody JSON字符串
*/
async receiveWorkcaseFromCrm(jsonBody: string): Promise<ResultDomain<void>> {
const response = await api.post<void>(`${this.baseUrl}/receive/crm`, jsonBody)
return response.data
},
// ========================= 工单处理过程 =========================
/**
* 创建工单处理过程
* @param process 处理过程信息
*/
async createWorkcaseProcess(process: TbWorkcaseProcessDTO): Promise<ResultDomain<TbWorkcaseProcessDTO>> {
const response = await api.post<TbWorkcaseProcessDTO>(`${this.baseUrl}/process`, process)
return response.data
},
/**
* 更新工单处理过程
* @param process 处理过程信息
*/
async updateWorkcaseProcess(process: TbWorkcaseProcessDTO): Promise<ResultDomain<TbWorkcaseProcessDTO>> {
const response = await api.put<TbWorkcaseProcessDTO>(`${this.baseUrl}/process`, process)
return response.data
},
/**
* 删除工单处理过程
* @param processId 处理过程ID
*/
async deleteWorkcaseProcess(processId: string): Promise<ResultDomain<TbWorkcaseProcessDTO>> {
const response = await api.delete<TbWorkcaseProcessDTO>(`${this.baseUrl}/process/${processId}`)
return response.data
},
/**
* 查询工单处理过程列表
* @param filter 筛选条件
*/
async getWorkcaseProcessList(filter?: TbWorkcaseProcessDTO): Promise<ResultDomain<TbWorkcaseProcessDTO>> {
const response = await api.post<TbWorkcaseProcessDTO>(`${this.baseUrl}/process/list`, filter || {})
return response.data
},
/**
* 分页查询工单处理过程
* @param pageRequest 分页请求
*/
async getWorkcaseProcessPage(pageRequest: PageRequest<TbWorkcaseProcessDTO>): Promise<ResultDomain<TbWorkcaseProcessDTO>> {
const response = await api.post<TbWorkcaseProcessDTO>(`${this.baseUrl}/process/page`, pageRequest)
return response.data
},
// ========================= 工单设备管理 =========================
/**
* 创建工单设备
* @param device 设备信息
*/
async createWorkcaseDevice(device: TbWorkcaseDeviceDTO): Promise<ResultDomain<TbWorkcaseDeviceDTO>> {
const response = await api.post<TbWorkcaseDeviceDTO>(`${this.baseUrl}/device`, device)
return response.data
},
/**
* 更新工单设备
* @param device 设备信息
*/
async updateWorkcaseDevice(device: TbWorkcaseDeviceDTO): Promise<ResultDomain<TbWorkcaseDeviceDTO>> {
const response = await api.put<TbWorkcaseDeviceDTO>(`${this.baseUrl}/device`, device)
return response.data
},
/**
* 删除工单设备
* @param workcaseId 工单ID
* @param device 设备名称
*/
async deleteWorkcaseDevice(workcaseId: string, device: string): Promise<ResultDomain<TbWorkcaseDeviceDTO>> {
const response = await api.delete<TbWorkcaseDeviceDTO>(`${this.baseUrl}/device/${workcaseId}/${device}`)
return response.data
},
/**
* 查询工单设备列表
* @param filter 筛选条件
*/
async getWorkcaseDeviceList(filter?: TbWorkcaseDeviceDTO): Promise<ResultDomain<TbWorkcaseDeviceDTO>> {
const response = await api.post<TbWorkcaseDeviceDTO>(`${this.baseUrl}/device/list`, filter || {})
return response.data
},
/**
* 分页查询工单设备
* @param pageRequest 分页请求
*/
async getWorkcaseDevicePage(pageRequest: PageRequest<TbWorkcaseDeviceDTO>): Promise<ResultDomain<TbWorkcaseDeviceDTO>> {
const response = await api.post<TbWorkcaseDeviceDTO>(`${this.baseUrl}/device/page`, pageRequest)
return response.data
}
}

View File

@@ -169,6 +169,8 @@ interface Props {
maxCount?: number
title?: string
buttonText?: string
// 自定义上传函数,如果提供则使用外部实现,否则使用默认上传逻辑
customUpload?: (files: File[]) => Promise<TbSysFileDTO[] | void>
}
const props = withDefaults(defineProps<Props>(), {
@@ -178,7 +180,8 @@ const props = withDefaults(defineProps<Props>(), {
maxSize: 10 * 1024 * 1024,
maxCount: 10,
title: '文件上传',
buttonText: '上传文件'
buttonText: '上传文件',
customUpload: undefined
})
const emit = defineEmits<{
@@ -186,6 +189,8 @@ const emit = defineEmits<{
'update:fileList': [value: TbSysFileDTO[]]
'upload-success': [files: TbSysFileDTO[]]
'upload-error': [error: string]
// 文件准备就绪事件,当使用自定义上传时触发,传递文件列表供外部处理
'files-ready': [files: File[]]
}>()
// 响应式数据
@@ -347,6 +352,41 @@ const handleDialogClose = (done: () => void) => {
const uploadFiles = async () => {
if (selectedFiles.value.length === 0) return
// 如果提供了自定义上传函数,则使用外部实现
if (props.customUpload) {
uploading.value = true
try {
// 触发 files-ready 事件,传递文件列表
emit('files-ready', [...selectedFiles.value])
// 调用自定义上传函数
const result = await props.customUpload([...selectedFiles.value])
// 如果自定义函数返回了文件列表,触发上传成功事件
if (result && result.length > 0) {
emit('upload-success', result)
emit('update:fileList', [...props.fileList, ...result])
if (props.mode === 'cover' && result[0]?.url) {
emit('update:coverImg', result[0].url)
}
}
// 清空文件列表
selectedFiles.value = []
if (props.mode === 'dialog') {
closeDialog()
}
} catch (error) {
console.error('自定义上传失败:', error)
emit('upload-error', error instanceof Error ? error.message : '上传失败,请重试')
} finally {
uploading.value = false
}
return
}
// 默认上传逻辑
uploading.value = true
const uploadedFilesList: TbSysFileDTO[] = []
@@ -406,6 +446,29 @@ const uploadFiles = async () => {
}
}
// 暴露方法和状态供外部使用
defineExpose({
// 当前选中的文件列表
selectedFiles,
// 上传状态
uploading,
// 弹窗显示状态
showDialog,
// 手动触发文件选择
triggerFileInput,
// 手动添加文件
addFiles,
// 移除指定文件
removeFile,
// 清空所有文件
clearFiles: () => { selectedFiles.value = [] },
// 手动触发上传
uploadFiles,
// 关闭弹窗
closeDialog,
// 打开弹窗
openDialog: () => { showDialog.value = true }
})
</script>
<style lang="scss" scoped>

View File

@@ -1,139 +0,0 @@
/**
* Agent服务相关 types - 根据后端 VO 和 DTO 转换
*/
import { BaseVO, BaseDTO } from "@/types/base"
// KnowledgeBaseVO - 知识库
export interface KnowledgeBaseVO extends BaseVO {
/** 知识库ID */
knowledgeId?: string
/** 智能体ID */
agentId?: string
/** 智能体名称 */
agentName?: string
/** 知识库名称 */
name?: string
/** 知识库类型 */
kbType?: string
/** 知识库类型名称 */
kbTypeName?: string
/** 访问级别 */
accessLevel?: string
/** 访问级别名称 */
accessLevelName?: string
/** 知识库描述 */
description?: string
/** 存储路径 */
storagePath?: string
/** 当前版本号 */
version?: string
/** 知识库配置 */
config?: Record<string, any>
/** 服务类型 */
serviceType?: string
/** 部门名称 */
deptName?: string
}
// KnowledgeDocumentVO - 知识文档
export interface KnowledgeDocumentVO extends BaseVO {
/** 文档ID */
documentId?: string
/** 知识库ID */
knowledgeId?: string
/** 文档名称 */
name?: string
/** 文档类型 */
docType?: string
/** 文档内容 */
content?: string
/** 文档描述 */
description?: string
/** 文档状态 */
status?: string
/** 文件路径 */
filePath?: string
/** 文件大小 */
fileSize?: number
}
// KnowledgeChunkVO - 知识块(分块存储)
export interface KnowledgeChunkVO extends BaseVO {
/** 块ID */
chunkId?: string
/** 文档ID */
documentId?: string
/** 知识库ID */
knowledgeId?: string
/** 块内容 */
content?: string
/** 块索引 */
chunkIndex?: number
/** 向量嵌入 */
embedding?: number[]
/** 相似度 */
similarity?: number
}
// KnowledgeBaseDTO - 知识库DTO创建和更新
export interface KnowledgeBaseDTO extends BaseDTO {
/** 知识库ID */
knowledgeId?: string
/** 智能体ID */
agentId?: string
/** 知识库名称 */
name?: string
/** 知识库类型 */
kbType?: string
/** 访问级别 */
accessLevel?: string
/** 知识库描述 */
description?: string
/** 存储路径 */
storagePath?: string
/** 当前版本号 */
version?: string
/** 知识库配置 */
config?: Record<string, any>
/** 服务类型 */
serviceType?: string
}
// KnowledgeDocumentDTO - 知识文档DTO创建和更新
export interface KnowledgeDocumentDTO extends BaseDTO {
/** 文档ID */
documentId?: string
/** 知识库ID */
knowledgeId?: string
/** 文档名称 */
name?: string
/** 文档类型 */
docType?: string
/** 文档内容 */
content?: string
/** 文档描述 */
description?: string
/** 文档状态 */
status?: string
/** 文件路径 */
filePath?: string
/** 文件大小 */
fileSize?: number
}
// KnowledgeChunkDTO - 知识块DTO创建和更新
export interface KnowledgeChunkDTO extends BaseDTO {
/** 块ID */
chunkId?: string
/** 文档ID */
documentId?: string
/** 知识库ID */
knowledgeId?: string
/** 块内容 */
content?: string
/** 块索引 */
chunkIndex?: number
/** 向量嵌入 */
embedding?: number[]
}

View File

@@ -1 +0,0 @@
export * from "./agent"

View File

@@ -0,0 +1,35 @@
import type { BaseDTO } from '../base'
/**
* 智能体提示卡
*/
export interface PromptCard {
/** 文件ID */
fileId?: string
/** 提示词 */
prompt?: string
}
/**
* 智能体 DTO
*/
export interface TbAgent extends BaseDTO {
/** 智能体ID */
agentId?: string
/** 智能体名称 */
name?: string
/** 智能体描述 */
description?: string
/** 智能体url */
link?: string
/** 智能体APIKEY */
apiKey?: string
/** 是否是对外智能体,未登录可用 */
isOuter?: boolean
/** 引导词 */
introduce?: string
/** 提示卡片数组 */
promptCards?: PromptCard[]
/** 分类 */
category?: string
}

View File

@@ -0,0 +1,111 @@
import type { BaseDTO } from '../base'
/**
* Dify文件信息用于对话文件上传和请求
*/
export interface DifyFileInfo {
/** 文件IDDify返回 */
id?: string
/** 文件名 */
name?: string
/** 文件大小(字节) */
size?: number
/** 文件扩展名 */
extension?: string
/** 文件MIME类型 */
mimeType?: string
/** 上传人ID */
createdBy?: string
/** 上传时间(时间戳) */
createdAt?: number
/** 预览URL */
previewUrl?: string
/** 源文件URL */
sourceUrl?: string
/** 文件类型image、document、audio、video、file */
type?: string
/** 传输方式remote_url、local_file */
transferMethod?: string
/** 文件URL或ID */
url?: string
/** 本地文件上传ID */
uploadFileId?: string
/** 系统文件ID */
sysFileId?: string
/** 文件路径(从系统文件表获取) */
filePath?: string
}
/**
* AI智能体对话
*/
export interface TbChat extends BaseDTO {
/** 对话ID */
chatId?: string
/** 智能体ID */
agentId?: string
/** 用户ID */
userId?: string
/** 用户类型 true-系统内部人员 false-系统外部人员 */
userType?: boolean
/** 对话标题 */
title?: string
}
/**
* AI智能体对话消息
*/
export interface TbChatMessage extends BaseDTO {
/** 消息ID */
messageId?: string
/** Dify消息ID */
difyMessageId?: string
/** 对话ID */
chatId?: string
/** 角色 */
role?: string
/** 内容 */
content?: string
/** 文件ID数组 */
files?: string[]
/** 评价 */
comment?: string
}
/**
* 对话消息数据预处理对象
*/
export interface ChatPrepareData {
/** 智能体Id */
agentId?: string
/** 对话Id */
chatId?: string
/** 用户问题 */
query?: string
/** 本次对话携带的dify文件对象 */
files?: DifyFileInfo[]
/** 用户ID来客传wechatId员工传userId */
userId?: string
/** 用户类型false=来客true=员工) */
userType?: boolean
}
/**
* 停止对话参数
*/
export interface StopChatParams {
taskId: string
agentId: string
userId: string
}
/**
* 评价消息参数
*/
export interface CommentMessageParams {
agentId: string
chatId: string
messageId: string
comment: string
userId: string
}

View File

@@ -0,0 +1,73 @@
import type { BaseDTO } from '../base'
/**
* 知识库配置
*/
export interface TbKnowledge extends BaseDTO {
/** 知识库ID */
knowledgeId?: string
/** 知识库标题 */
title?: string
/** 知识库头像 */
avatar?: string
/** 知识库描述 */
description?: string
/** Dify知识库IDDataset ID */
difyDatasetId?: string
/** Dify索引方式high_quality/economy */
difyIndexingTechnique?: 'high_quality' | 'economy'
/** 向量模型名称 */
embeddingModel?: string
/** 向量模型提供商 */
embeddingModelProvider?: string
/** Rerank模型名称 */
rerankModel?: string
/** Rerank模型提供商 */
rerankModelProvider?: string
/** 是否启用Rerank0否 1是 */
rerankingEnable?: number
/** 检索Top K返回前K个结果 */
retrievalTopK?: number
/** 检索分数阈值0.00-1.00 */
retrievalScoreThreshold?: number
/** 文档数量 */
documentCount?: number
/** 总分段数 */
totalChunks?: number
/** 所属服务 workcase、bidding */
service?: string
/** bidding所属项目ID */
projectId?: string
/** 所属分类 workcase的内部知识库、外部知识库其他服务default */
category?: string
}
/**
* 知识库文件
*/
export interface TbKnowledgeFile extends BaseDTO {
/** 知识库ID */
knowledgeId?: string
/** 文件ID */
fileId?: string
/** 文件根ID */
fileRootId?: string
/** Dify文件ID */
difyFileId?: string
/** 文件版本 */
version?: number
}
/**
* 文档分段请求体
*/
export interface SegmentRequestBody {
[key: string]: any
}
/**
* 文档状态请求体
*/
export interface DocumentStatusRequestBody {
[key: string]: any
}

View File

@@ -0,0 +1,3 @@
export * from './agent';
export * from './aiKnowledge';
export * from './aiChat';

View File

@@ -9,7 +9,7 @@ export * from "./menu"
export * from "./auth"
export * from "./file"
export * from "./message"
export * from "./agent"
export * from "./ai"
export * from "./crontab"
export * from "./bidding"
export * from "./workcase"

View File

@@ -1,279 +1,65 @@
import type { BaseDTO } from '@/types/base'
/**
* 工单服务相关 types - 根据后端 VO 和 DTO 转换
* 工单表对象
*/
import { BaseVO, BaseDTO } from "@/types/base"
// TicketVO - 工单详情
export interface TicketVO extends BaseVO {
/** 工单ID */
ticketId?: string
/** 工单编号 */
ticketNo?: string
/** 客户ID */
customerId?: string
/** 客户姓名 */
customerName?: string
/** 客户电话 */
customerPhone?: string
/** 关联会话ID */
conversationId?: string
/** 工单类型 */
ticketType?: string
/** 工单类型名称 */
ticketTypeName?: string
/** 工单分类 */
ticketCategory?: string
/** 优先级 */
priority?: string
/** 优先级名称 */
priorityName?: string
/** 优先级颜色 */
priorityColor?: string
/** 工单标题 */
title?: string
/** 问题描述 */
description?: string
/** 附件ID数组 */
attachments?: string[]
/** 附件数量 */
attachmentCount?: number
/** 工单来源 */
ticketSource?: string
/** 工单来源名称 */
ticketSourceName?: string
/** 分配给处理人ID */
assignedTo?: string
/** 处理人姓名 */
assignedToName?: string
/** 分配部门 */
assignedDept?: string
/** 分配部门名称 */
assignedDeptName?: string
/** 工单状态 */
ticketStatus?: string
/** 工单状态名称 */
ticketStatusName?: string
/** 工单状态颜色 */
statusColor?: string
/** 解决方案 */
resolution?: string
/** 解决时间 */
resolutionTime?: string
/** 关闭时间 */
closeTime?: string
/** 首次响应时间 */
responseTime?: string
/** SLA截止时间 */
slaDeadline?: string
/** 是否逾期 */
isOverdue?: boolean
/** 距离SLA截止的剩余时间分钟 */
slaRemainingMinutes?: number
/** 客户评分1-5星 */
customerRating?: number
/** 客户反馈 */
customerFeedback?: string
/** CRM系统工单ID */
crmTicketId?: string
/** 同步状态 */
syncStatus?: string
/** 同步状态名称 */
syncStatusName?: string
/** 工单标签 */
tags?: string[]
/** 工单元数据 */
metadata?: Record<string, any>
/** 处理记录数量 */
logCount?: number
/** 创建者姓名 */
creatorName?: string
/** 更新者姓名 */
updaterName?: string
export interface TbWorkcaseDTO extends BaseDTO {
/** 工单ID */
workcaseId?: string
/** 来客ID */
userId?: string
/** 来客姓名 */
username?: string
/** 来客电话 */
phone?: string
/** 故障类型 */
type?: string
/** 设备名称 */
device?: string
/** 设备代码 */
deviceCode?: string
/** 工单图片列表 */
imgs?: string[]
/** 紧急程度 normal-普通 emergency-紧急 */
emergency?: 'normal' | 'emergency'
/** 状态 pending-待处理 processing-处理中 done-已完成 */
status?: 'pending' | 'processing' | 'done'
/** 处理人ID */
processor?: string
}
// TicketListVO - 工单列表(简化版)
export interface TicketListVO extends BaseVO {
/** 工单ID */
ticketId?: string
/** 工单编号 */
ticketNo?: string
/** 客户姓名 */
customerName?: string
/** 工单标题 */
title?: string
/** 工单类型名称 */
ticketTypeName?: string
/** 优先级 */
priority?: string
/** 优先级名称 */
priorityName?: string
/** 工单状态 */
ticketStatus?: string
/** 工单状态名称 */
ticketStatusName?: string
/** 处理人姓名 */
assignedToName?: string
/** SLA截止时间 */
slaDeadline?: string
/** 是否逾期 */
isOverdue?: boolean
/** 创建者姓名 */
creatorName?: string
/**
* 工单过程表DTO
*/
export interface TbWorkcaseProcessDTO extends BaseDTO {
/** 工单ID */
workcaseId?: string
/** 过程ID */
processId?: string
/** 动作 info记录assign指派redeploy转派repeal撤销finish完成 */
action?: 'info' | 'assign' | 'redeploy' | 'repeal' | 'finish'
/** 消息 */
message?: string
/** 携带文件列表 */
files?: string[]
/** 处理人(指派、转派专属) */
processor?: string
}
// TbTicketDTO - 工单DTO创建和更新
export interface TbTicketDTO extends BaseDTO {
/** 工单ID更新时需要 */
ticketId?: string
/** 工单编号 */
ticketNo?: string
/** 客户ID */
customerId?: string
/** 关联会话ID */
conversationId?: string
/** 工单类型 */
ticketType?: string
/** 工单分类 */
ticketCategory?: string
/** 优先级 */
priority?: string
/** 工单标题 */
title?: string
/** 问题描述 */
description?: string
/** 附件ID数组 */
attachments?: string[]
/** 工单来源 */
ticketSource?: string
/** 分配给(处理人) */
assignedTo?: string
/** 分配部门 */
assignedDept?: string
/** 工单状态 */
ticketStatus?: string
/** 解决方案 */
resolution?: string
/** 解决时间 */
resolutionTime?: string
/** 关闭时间 */
closeTime?: string
/** 首次响应时间 */
responseTime?: string
/** SLA截止时间 */
slaDeadline?: string
/** 是否逾期 */
isOverdue?: boolean
/** 客户评分1-5星 */
customerRating?: number
/** 客户反馈 */
customerFeedback?: string
/** CRM系统工单ID */
crmTicketId?: string
/** 同步状态 */
syncStatus?: string
/** 工单标签 */
tags?: string[]
/** 工单元数据 */
metadata?: Record<string, any>
}
// CustomerVO - 客户信息
export interface CustomerVO extends BaseVO {
/** 客户ID */
customerId?: string
/** 客户编号 */
customerNo?: string
/** 客户姓名 */
customerName?: string
/** 客户类型 */
customerType?: string
/** 公司名称 */
companyName?: string
/** 电话 */
phone?: string
/** 邮箱 */
email?: string
/** 微信OpenID */
wechatOpenid?: string
/** 微信UnionID */
wechatUnionid?: string
/** 头像URL */
avatar?: string
/** 性别 */
gender?: number
/** 地址 */
address?: string
/** 客户等级 */
customerLevel?: string
/** 客户来源 */
customerSource?: string
/** 客户标签数组 */
tags?: string[]
/** 备注 */
notes?: string
/** CRM系统客户ID */
crmCustomerId?: string
/** 最后联系时间 */
lastContactTime?: string
/** 咨询总次数 */
totalConsultations?: number
/** 订单总数 */
totalOrders?: number
/** 总消费金额 */
totalAmount?: number
/** 满意度评分1-5 */
satisfactionScore?: number
/** 状态 */
status?: string
}
// TbCustomerDTO - 客户DTO创建和更新
export interface TbCustomerDTO extends BaseDTO {
/** 客户ID更新时需要 */
customerId?: string
/** 客户编号 */
customerNo?: string
/** 客户姓名 */
customerName?: string
/** 客户类型 */
customerType?: string
/** 公司名称 */
companyName?: string
/** 电话 */
phone?: string
/** 邮箱 */
email?: string
/** 微信OpenID */
wechatOpenid?: string
/** 微信UnionID */
wechatUnionid?: string
/** 头像URL */
avatar?: string
/** 性别 */
gender?: number
/** 地址 */
address?: string
/** 客户等级 */
customerLevel?: string
/** 客户来源 */
customerSource?: string
/** 客户标签数组 */
tags?: string[]
/** 备注 */
notes?: string
/** CRM系统客户ID */
crmCustomerId?: string
/** 最后联系时间 */
lastContactTime?: string
/** 咨询总次数 */
totalConsultations?: number
/** 订单总数 */
totalOrders?: number
/** 总消费金额 */
totalAmount?: number
/** 满意度评分1-5 */
satisfactionScore?: number
/** 状态 */
status?: string
/**
* 工单设备涉及的文件DTO
*/
export interface TbWorkcaseDeviceDTO extends BaseDTO {
/** 工单ID */
workcaseId?: string
/** 设备名称 */
device?: string
/** 设备代码 */
deviceCode?: string
/** 文件ID */
fileId?: string
/** 文件名 */
fileName?: string
/** 文件根ID */
fileRootId?: string
}

View File

@@ -42,6 +42,8 @@ export default defineConfig({
'./api': './src/api/index.ts',
'./api/auth': './src/api/auth/auth.ts',
'./api/file': './src/api/file/file.ts',
'./api/workcase': './src/api/workcase/index.ts',
'./api/ai': './src/api/ai/index.ts',
// ========== Utils 工具模块 ==========
'./utils': './src/utils/index.ts',
@@ -56,6 +58,8 @@ export default defineConfig({
'./types/auth': './src/types/auth/index.ts',
'./types/file': './src/types/file/index.ts',
'./types/sys': './src/types/sys/index.ts',
'./types/workcase': './src/types/workcase/index.ts',
'./types/ai': './src/types/ai/index.ts',
// ========== Config 配置模块 ==========
'./config': './src/config/index.ts',