This commit is contained in:
parent
92ea90ec81
commit
e346e1a16a
@ -99,11 +99,12 @@ definitions:
|
||||
file:
|
||||
$ref: '#/definitions/entity.File'
|
||||
file_id:
|
||||
description: |-
|
||||
FileId
|
||||
虽然有了 UserFileId, 但是 File Id 还是应该保留,因为这个是针对访客用户的
|
||||
description: FileId
|
||||
type: integer
|
||||
hidden:
|
||||
description: |-
|
||||
UserFileId *schema.EntityId `json:"user_file_id"`
|
||||
UserFile *UserFile `json:"user_file"`
|
||||
type: boolean
|
||||
id:
|
||||
description: Id schema.EntityId `gorm:"primarykey" json:"id,string"`
|
||||
@ -116,10 +117,6 @@ definitions:
|
||||
type: integer
|
||||
updated_at:
|
||||
type: string
|
||||
user_file:
|
||||
$ref: '#/definitions/entity.UserFile'
|
||||
user_file_id:
|
||||
type: integer
|
||||
type: object
|
||||
entity.ChatMessageList:
|
||||
properties:
|
||||
@ -145,6 +142,9 @@ definitions:
|
||||
file_id:
|
||||
type: integer
|
||||
hidden:
|
||||
description: |-
|
||||
UserFileId *schema.EntityId `json:"user_file_id"`
|
||||
UserFile *UserFile `json:"user_file"`
|
||||
type: boolean
|
||||
id:
|
||||
type: integer
|
||||
@ -156,10 +156,6 @@ definitions:
|
||||
type: integer
|
||||
updated_at:
|
||||
type: string
|
||||
user_file:
|
||||
$ref: '#/definitions/entity.UserFile'
|
||||
user_file_id:
|
||||
type: integer
|
||||
type: object
|
||||
entity.Document:
|
||||
properties:
|
||||
@ -185,6 +181,7 @@ definitions:
|
||||
type: string
|
||||
expired_at:
|
||||
description: |-
|
||||
Public bool `json:"public"` // 是否公开,访客上传的文件应始终公开,或归属于所有者
|
||||
TODO: 移除 file 的到期时间,如果当 file 没有任何引用的时候再删除
|
||||
因为有外键,所以直接删除是删不掉的,必须删除消息
|
||||
type: string
|
||||
@ -195,11 +192,6 @@ definitions:
|
||||
type: integer
|
||||
mime_type:
|
||||
type: string
|
||||
path:
|
||||
type: string
|
||||
public:
|
||||
description: 是否公开,访客上传的文件应始终公开,或归属于所有者
|
||||
type: boolean
|
||||
size:
|
||||
type: integer
|
||||
updated_at:
|
||||
@ -267,22 +259,6 @@ definitions:
|
||||
user_id:
|
||||
type: string
|
||||
type: object
|
||||
entity.UserFile:
|
||||
properties:
|
||||
created_at:
|
||||
type: string
|
||||
file:
|
||||
$ref: '#/definitions/entity.File'
|
||||
file_id:
|
||||
type: integer
|
||||
id:
|
||||
description: Id schema.EntityId `gorm:"primarykey" json:"id,string"`
|
||||
type: integer
|
||||
updated_at:
|
||||
type: string
|
||||
user_id:
|
||||
type: string
|
||||
type: object
|
||||
schema.AddPublicChatMessageRequest:
|
||||
properties:
|
||||
assistant_key:
|
||||
@ -1738,38 +1714,16 @@ paths:
|
||||
summary: 添加聊天记录
|
||||
tags:
|
||||
- chat_message
|
||||
/api/v1/files/{id}/download:
|
||||
/api/v1/files/download/{hash}:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 根据 File ID 下载文件。如果文件是私有的,将无法下载
|
||||
description: 根据文件 Hash 下载文件。仅支持图片下载,且图片具有有效期
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
- description: FileId uint64 `uri:"id" binding:"required"`
|
||||
in: path
|
||||
name: hash
|
||||
required: true
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
type: file
|
||||
summary: 下载公开文件
|
||||
tags:
|
||||
- file
|
||||
/api/v1/files/user/{id}/download:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 根据 File ID 下载文件。如果文件是私有的,将无法下载
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
type: integer
|
||||
- in: query
|
||||
name: id_token
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
@ -1778,7 +1732,7 @@ paths:
|
||||
description: OK
|
||||
schema:
|
||||
type: file
|
||||
summary: 下载用户开文件
|
||||
summary: 下载图片
|
||||
tags:
|
||||
- file
|
||||
/api/v1/libraries:
|
||||
|
212
src/api/api.ts
212
src/api/api.ts
@ -906,13 +906,13 @@ export interface EntityChatMessage {
|
||||
*/
|
||||
'file'?: EntityFile;
|
||||
/**
|
||||
* FileId 虽然有了 UserFileId, 但是 File Id 还是应该保留,因为这个是针对访客用户的
|
||||
* FileId
|
||||
* @type {number}
|
||||
* @memberof EntityChatMessage
|
||||
*/
|
||||
'file_id'?: number;
|
||||
/**
|
||||
*
|
||||
* UserFileId *schema.EntityId `json:\"user_file_id\"` UserFile *UserFile `json:\"user_file\"`
|
||||
* @type {boolean}
|
||||
* @memberof EntityChatMessage
|
||||
*/
|
||||
@ -947,18 +947,6 @@ export interface EntityChatMessage {
|
||||
* @memberof EntityChatMessage
|
||||
*/
|
||||
'updated_at'?: string;
|
||||
/**
|
||||
*
|
||||
* @type {EntityUserFile}
|
||||
* @memberof EntityChatMessage
|
||||
*/
|
||||
'user_file'?: EntityUserFile;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof EntityChatMessage
|
||||
*/
|
||||
'user_file_id'?: number;
|
||||
}
|
||||
/**
|
||||
*
|
||||
@ -1015,7 +1003,7 @@ export interface EntityChatMessageList {
|
||||
*/
|
||||
'file_id'?: number;
|
||||
/**
|
||||
*
|
||||
* UserFileId *schema.EntityId `json:\"user_file_id\"` UserFile *UserFile `json:\"user_file\"`
|
||||
* @type {boolean}
|
||||
* @memberof EntityChatMessageList
|
||||
*/
|
||||
@ -1050,18 +1038,6 @@ export interface EntityChatMessageList {
|
||||
* @memberof EntityChatMessageList
|
||||
*/
|
||||
'updated_at'?: string;
|
||||
/**
|
||||
*
|
||||
* @type {EntityUserFile}
|
||||
* @memberof EntityChatMessageList
|
||||
*/
|
||||
'user_file'?: EntityUserFile;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof EntityChatMessageList
|
||||
*/
|
||||
'user_file_id'?: number;
|
||||
}
|
||||
/**
|
||||
*
|
||||
@ -1144,7 +1120,7 @@ export interface EntityFile {
|
||||
*/
|
||||
'created_at'?: string;
|
||||
/**
|
||||
* TODO: 移除 file 的到期时间,如果当 file 没有任何引用的时候再删除 因为有外键,所以直接删除是删不掉的,必须删除消息
|
||||
* Public bool `json:\"public\"` // 是否公开,访客上传的文件应始终公开,或归属于所有者 TODO: 移除 file 的到期时间,如果当 file 没有任何引用的时候再删除 因为有外键,所以直接删除是删不掉的,必须删除消息
|
||||
* @type {string}
|
||||
* @memberof EntityFile
|
||||
*/
|
||||
@ -1167,18 +1143,6 @@ export interface EntityFile {
|
||||
* @memberof EntityFile
|
||||
*/
|
||||
'mime_type'?: string;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof EntityFile
|
||||
*/
|
||||
'path'?: string;
|
||||
/**
|
||||
* 是否公开,访客上传的文件应始终公开,或归属于所有者
|
||||
* @type {boolean}
|
||||
* @memberof EntityFile
|
||||
*/
|
||||
'public'?: boolean;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
@ -1357,49 +1321,6 @@ export interface EntityTool {
|
||||
*/
|
||||
'user_id'?: string;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
* @interface EntityUserFile
|
||||
*/
|
||||
export interface EntityUserFile {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof EntityUserFile
|
||||
*/
|
||||
'created_at'?: string;
|
||||
/**
|
||||
*
|
||||
* @type {EntityFile}
|
||||
* @memberof EntityUserFile
|
||||
*/
|
||||
'file'?: EntityFile;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof EntityUserFile
|
||||
*/
|
||||
'file_id'?: number;
|
||||
/**
|
||||
* Id schema.EntityId `gorm:\"primarykey\" json:\"id,string\"`
|
||||
* @type {number}
|
||||
* @memberof EntityUserFile
|
||||
*/
|
||||
'id'?: number;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof EntityUserFile
|
||||
*/
|
||||
'updated_at'?: string;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof EntityUserFile
|
||||
*/
|
||||
'user_id'?: string;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
@ -4663,17 +4584,17 @@ export class ChatPublicApi extends BaseAPI {
|
||||
export const FileApiAxiosParamCreator = function (configuration?: Configuration) {
|
||||
return {
|
||||
/**
|
||||
* 根据 File ID 下载文件。如果文件是私有的,将无法下载
|
||||
* @summary 下载公开文件
|
||||
* @param {number} id
|
||||
* 根据文件 Hash 下载文件。仅支持图片下载,且图片具有有效期
|
||||
* @summary 下载图片
|
||||
* @param {string} hash FileId uint64 `uri:\"id\" binding:\"required\"`
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
apiV1FilesIdDownloadGet: async (id: number, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('apiV1FilesIdDownloadGet', 'id', id)
|
||||
const localVarPath = `/api/v1/files/{id}/download`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
|
||||
apiV1FilesDownloadHashGet: async (hash: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'hash' is not null or undefined
|
||||
assertParamExists('apiV1FilesDownloadHashGet', 'hash', hash)
|
||||
const localVarPath = `/api/v1/files/download/{hash}`
|
||||
.replace(`{${"hash"}}`, encodeURIComponent(String(hash)));
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
let baseOptions;
|
||||
@ -4687,45 +4608,6 @@ export const FileApiAxiosParamCreator = function (configuration?: Configuration)
|
||||
|
||||
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
|
||||
return {
|
||||
url: toPathString(localVarUrlObj),
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* 根据 File ID 下载文件。如果文件是私有的,将无法下载
|
||||
* @summary 下载用户开文件
|
||||
* @param {number} id
|
||||
* @param {string} [idToken]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
apiV1FilesUserIdDownloadGet: async (id: number, idToken?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'id' is not null or undefined
|
||||
assertParamExists('apiV1FilesUserIdDownloadGet', 'id', id)
|
||||
const localVarPath = `/api/v1/files/user/{id}/download`
|
||||
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||
let baseOptions;
|
||||
if (configuration) {
|
||||
baseOptions = configuration.baseOptions;
|
||||
}
|
||||
|
||||
const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
if (idToken !== undefined) {
|
||||
localVarQueryParameter['id_token'] = idToken;
|
||||
}
|
||||
|
||||
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
@ -4746,30 +4628,16 @@ export const FileApiFp = function(configuration?: Configuration) {
|
||||
const localVarAxiosParamCreator = FileApiAxiosParamCreator(configuration)
|
||||
return {
|
||||
/**
|
||||
* 根据 File ID 下载文件。如果文件是私有的,将无法下载
|
||||
* @summary 下载公开文件
|
||||
* @param {number} id
|
||||
* 根据文件 Hash 下载文件。仅支持图片下载,且图片具有有效期
|
||||
* @summary 下载图片
|
||||
* @param {string} hash FileId uint64 `uri:\"id\" binding:\"required\"`
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiV1FilesIdDownloadGet(id: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<File>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.apiV1FilesIdDownloadGet(id, options);
|
||||
async apiV1FilesDownloadHashGet(hash: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<File>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.apiV1FilesDownloadHashGet(hash, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['FileApi.apiV1FilesIdDownloadGet']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* 根据 File ID 下载文件。如果文件是私有的,将无法下载
|
||||
* @summary 下载用户开文件
|
||||
* @param {number} id
|
||||
* @param {string} [idToken]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiV1FilesUserIdDownloadGet(id: number, idToken?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<File>> {
|
||||
const localVarAxiosArgs = await localVarAxiosParamCreator.apiV1FilesUserIdDownloadGet(id, idToken, options);
|
||||
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
||||
const localVarOperationServerBasePath = operationServerMap['FileApi.apiV1FilesUserIdDownloadGet']?.[localVarOperationServerIndex]?.url;
|
||||
const localVarOperationServerBasePath = operationServerMap['FileApi.apiV1FilesDownloadHashGet']?.[localVarOperationServerIndex]?.url;
|
||||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
}
|
||||
@ -4783,25 +4651,14 @@ export const FileApiFactory = function (configuration?: Configuration, basePath?
|
||||
const localVarFp = FileApiFp(configuration)
|
||||
return {
|
||||
/**
|
||||
* 根据 File ID 下载文件。如果文件是私有的,将无法下载
|
||||
* @summary 下载公开文件
|
||||
* @param {number} id
|
||||
* 根据文件 Hash 下载文件。仅支持图片下载,且图片具有有效期
|
||||
* @summary 下载图片
|
||||
* @param {string} hash FileId uint64 `uri:\"id\" binding:\"required\"`
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
apiV1FilesIdDownloadGet(id: number, options?: RawAxiosRequestConfig): AxiosPromise<File> {
|
||||
return localVarFp.apiV1FilesIdDownloadGet(id, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* 根据 File ID 下载文件。如果文件是私有的,将无法下载
|
||||
* @summary 下载用户开文件
|
||||
* @param {number} id
|
||||
* @param {string} [idToken]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
apiV1FilesUserIdDownloadGet(id: number, idToken?: string, options?: RawAxiosRequestConfig): AxiosPromise<File> {
|
||||
return localVarFp.apiV1FilesUserIdDownloadGet(id, idToken, options).then((request) => request(axios, basePath));
|
||||
apiV1FilesDownloadHashGet(hash: string, options?: RawAxiosRequestConfig): AxiosPromise<File> {
|
||||
return localVarFp.apiV1FilesDownloadHashGet(hash, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
};
|
||||
};
|
||||
@ -4814,28 +4671,15 @@ export const FileApiFactory = function (configuration?: Configuration, basePath?
|
||||
*/
|
||||
export class FileApi extends BaseAPI {
|
||||
/**
|
||||
* 根据 File ID 下载文件。如果文件是私有的,将无法下载
|
||||
* @summary 下载公开文件
|
||||
* @param {number} id
|
||||
* 根据文件 Hash 下载文件。仅支持图片下载,且图片具有有效期
|
||||
* @summary 下载图片
|
||||
* @param {string} hash FileId uint64 `uri:\"id\" binding:\"required\"`
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof FileApi
|
||||
*/
|
||||
public apiV1FilesIdDownloadGet(id: number, options?: RawAxiosRequestConfig) {
|
||||
return FileApiFp(this.configuration).apiV1FilesIdDownloadGet(id, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 File ID 下载文件。如果文件是私有的,将无法下载
|
||||
* @summary 下载用户开文件
|
||||
* @param {number} id
|
||||
* @param {string} [idToken]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof FileApi
|
||||
*/
|
||||
public apiV1FilesUserIdDownloadGet(id: number, idToken?: string, options?: RawAxiosRequestConfig) {
|
||||
return FileApiFp(this.configuration).apiV1FilesUserIdDownloadGet(id, idToken, options).then((request) => request(this.axios, this.basePath));
|
||||
public apiV1FilesDownloadHashGet(hash: string, options?: RawAxiosRequestConfig) {
|
||||
return FileApiFp(this.configuration).apiV1FilesDownloadHashGet(hash, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,12 @@
|
||||
v-if="chatId !== null && chatData.assistant_id !== null"
|
||||
>
|
||||
<template #trigger>
|
||||
<n-button tertiary circle size="large">
|
||||
<n-button
|
||||
tertiary
|
||||
circle
|
||||
size="large"
|
||||
@click="showUploadModal = true"
|
||||
>
|
||||
<template #icon>
|
||||
<n-icon><DocumentAttachOutline /></n-icon>
|
||||
</template>
|
||||
@ -148,6 +153,34 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<n-modal
|
||||
v-model:show="showUploadModal"
|
||||
:bordered="false"
|
||||
class="w-0"
|
||||
preset="card"
|
||||
title="上传"
|
||||
size="huge"
|
||||
:style="{
|
||||
width: '80%',
|
||||
}"
|
||||
>
|
||||
<n-upload directory-dnd :custom-request="uploadFile" :max="5">
|
||||
<n-upload-dragger>
|
||||
<div style="margin-bottom: 12px">
|
||||
<n-icon size="48" :depth="3">
|
||||
<ArchiveOutline />
|
||||
</n-icon>
|
||||
</div>
|
||||
<n-text style="font-size: 16px">
|
||||
点击或者拖动文件到该区域来上传
|
||||
</n-text>
|
||||
<n-p depth="3" style="margin: 8px 0 0 0">
|
||||
请不要上传敏感数据,比如你的银行卡号和密码,信用卡号有效期和安全码
|
||||
</n-p>
|
||||
</n-upload-dragger>
|
||||
</n-upload>
|
||||
</n-modal>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useUserStore } from "../../stores/user";
|
||||
@ -157,6 +190,7 @@ import {
|
||||
MicOutline,
|
||||
DocumentAttachOutline,
|
||||
TrashBinOutline,
|
||||
ArchiveOutline,
|
||||
} from "@vicons/ionicons5";
|
||||
import {
|
||||
EntityChatMessage,
|
||||
@ -171,7 +205,7 @@ import router from "@/router";
|
||||
import element from "@/config/element";
|
||||
import { useIsMobile } from "@/utils/composables";
|
||||
import { useAppStore } from "@/stores/app";
|
||||
import { useDialog, useMessage } from "naive-ui";
|
||||
import { UploadCustomRequestOptions, useDialog, useMessage } from "naive-ui";
|
||||
import { useAssistantStore } from "@/stores/assistants";
|
||||
|
||||
// 获取组件传入的 chatId
|
||||
@ -211,6 +245,18 @@ const appStore = useAppStore();
|
||||
const dialog = useDialog();
|
||||
const assistantStore = useAssistantStore();
|
||||
const message = useMessage();
|
||||
const showUploadModal = ref(false);
|
||||
const pasteUpload = (event: ClipboardEvent) => {
|
||||
// const items = event.clipboardData && event.clipboardData.items;
|
||||
// if (items && items.length) {
|
||||
// for (let i = 0; i < items.length; i++) {
|
||||
// if (items[i].type.indexOf("image") !== -1) {
|
||||
// fileUpload.value = items[i].getAsFile();
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
};
|
||||
|
||||
function onKeydown(e: KeyboardEvent) {
|
||||
// 如果是 Esc
|
||||
@ -378,7 +424,7 @@ async function sendMessage(
|
||||
}
|
||||
|
||||
let chatVariables = {
|
||||
"now": new Date().toLocaleString(),
|
||||
now: new Date().toLocaleString(),
|
||||
};
|
||||
|
||||
// 合并
|
||||
@ -650,12 +696,16 @@ onMounted(() => {
|
||||
if (chatId.value) {
|
||||
getChat();
|
||||
}
|
||||
|
||||
document.addEventListener("paste", pasteUpload);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
chatStore.currentChat = {
|
||||
id: 0,
|
||||
};
|
||||
|
||||
document.removeEventListener("paste", pasteUpload);
|
||||
});
|
||||
|
||||
const assistantMenuOptions: any = ref([]);
|
||||
@ -679,17 +729,28 @@ const showAssistantSelect = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const uploadFile = () => {
|
||||
if (!fileUpload.value || !chatId.value) {
|
||||
return;
|
||||
}
|
||||
const uploadFile = ({
|
||||
file,
|
||||
data,
|
||||
headers,
|
||||
withCredentials,
|
||||
action,
|
||||
onFinish,
|
||||
onError,
|
||||
onProgress,
|
||||
}: UploadCustomRequestOptions) => {
|
||||
// const formData = new FormData();
|
||||
|
||||
// formData.append(file.name, file.file as File);
|
||||
|
||||
// uploading.value = true;
|
||||
|
||||
|
||||
uploading.value = true;
|
||||
getApi()
|
||||
.ChatMessage.apiV1ChatsIdFilesPost(
|
||||
Number(chatId.value),
|
||||
{
|
||||
file: fileUpload.value,
|
||||
file: file.file as File,
|
||||
url: "",
|
||||
},
|
||||
{
|
||||
@ -701,12 +762,14 @@ const uploadFile = () => {
|
||||
.then((r) => {
|
||||
// 如果成功
|
||||
if (r.status === 200 || r.status === 201) {
|
||||
fileUpload.value = null;
|
||||
getChatMessages();
|
||||
|
||||
onFinish();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
alert(err.response.data.message);
|
||||
message.error("上传失败: " + err.response.data.message);
|
||||
onError();
|
||||
})
|
||||
.finally(() => {
|
||||
uploading.value = false;
|
||||
|
@ -8,18 +8,31 @@
|
||||
<!-- 文件类型 -->
|
||||
<n-flex justify="end">
|
||||
<div class="flex items-center flex-nowrap">
|
||||
<!-- 如果是 user file -->
|
||||
<div class="flex items-end flex-col">
|
||||
<div>
|
||||
<n-divider class="!p-0 !m-0" title-placement="right">
|
||||
{{ userStore.user.name }}
|
||||
</n-divider>
|
||||
</div>
|
||||
<n-image
|
||||
v-if="message.user_file"
|
||||
v-if="message.file && message.file.mime_type?.startsWith('image/')"
|
||||
width="100"
|
||||
:src="fileBaseUrl + '/user/' + message.user_file.id + '/download'"
|
||||
:src="fileBaseUrl + '/download/' + message.file.file_hash"
|
||||
/>
|
||||
<n-image
|
||||
v-else-if="message.file"
|
||||
width="100"
|
||||
:src="fileBaseUrl + '/' + message.file.id + '/download'"
|
||||
<n-text italic depth="3" v-else>
|
||||
你上传了一个文件
|
||||
</n-text>
|
||||
</div>
|
||||
|
||||
<div class="relative h-full">
|
||||
<n-avatar
|
||||
round
|
||||
size="large"
|
||||
:src="userStore.user.avatar"
|
||||
class="ml-3 min-w-10 absolute top-0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</n-flex>
|
||||
</div>
|
||||
<div v-else-if="message.role === 'user' && message.content">
|
||||
@ -40,7 +53,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="mdInited"
|
||||
class="markdown-body"
|
||||
class="break-all break-words markdown-body"
|
||||
v-html="mdIt.render(message.content)"
|
||||
></div>
|
||||
</div>
|
||||
@ -80,7 +93,11 @@
|
||||
<!-- 当 message.content 变化时,重新渲染 -->
|
||||
<div>
|
||||
<div
|
||||
v-if="message.assistant_id && message.assistant !== null && message.assistant?.name !== ''"
|
||||
v-if="
|
||||
message.assistant_id &&
|
||||
message.assistant !== null &&
|
||||
message.assistant?.name !== ''
|
||||
"
|
||||
>
|
||||
<n-divider class="!p-0 !m-0" title-placement="left">
|
||||
{{ message.assistant?.name }}
|
||||
|
Loading…
Reference in New Issue
Block a user