Skip to content

Commit

Permalink
feat: add file upload in chat usage
Browse files Browse the repository at this point in the history
  • Loading branch information
moonrailgun committed Dec 29, 2024
1 parent e92c28b commit 52f70c8
Show file tree
Hide file tree
Showing 13 changed files with 57 additions and 11 deletions.
2 changes: 1 addition & 1 deletion client/shared/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,6 @@ export {
applyDefaultFallbackGroupPermission,
} from './utils/role-helper';
export { uploadFile } from './utils/upload-helper';
export type { UploadFileResult } from './utils/upload-helper';
export type { UploadFileResult, UploadFileUsage } from './utils/upload-helper';
export { parseUrlStr } from './utils/url-helper';
export { sleep } from './utils/utils';
4 changes: 4 additions & 0 deletions client/shared/utils/upload-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import { getGlobalConfig } from '../model/config';
import { showErrorToasts } from '../manager/ui';
import filesize from 'filesize';

export type UploadFileUsage = 'chat' | 'group' | 'user' | 'unknown';

interface UploadFileOptions {
usage?: UploadFileUsage;
onProgress?: (percent: number, progressEvent: unknown) => void;
}
export interface UploadFileResult {
Expand All @@ -23,6 +26,7 @@ export async function uploadFile(
): Promise<UploadFileResult> {
const form = new FormData();
form.append('file', file);
form.append('usage', options.usage ?? 'unknown');

const uploadFileLimit = getGlobalConfig().uploadFileLimit;
if (file.size > uploadFileLimit) {
Expand Down
8 changes: 6 additions & 2 deletions client/web/src/components/ChatBox/ChatInputBox/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ export function uploadMessageImage(image: File): Promise<{
}%(${originImageSize} -> ${compressedImageSize})`
);
}
const fileInfo = await uploadFile(uploadImage);
const fileInfo = await uploadFile(uploadImage, {
usage: 'chat',
});
const imageRemoteUrl = fileInfo.url;

resolve({
Expand All @@ -62,7 +64,9 @@ export async function uploadMessageFile(file: File): Promise<{
name: string;
url: string;
}> {
const fileInfo = await uploadFile(file);
const fileInfo = await uploadFile(file, {
usage: 'chat',
});

return {
name: file.name || fileInfo.etag,
Expand Down
9 changes: 8 additions & 1 deletion client/web/src/components/ImageUploader.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { blobUrlToFile } from '@/utils/file-helper';
import clsx from 'clsx';
import React, { PropsWithChildren, useState } from 'react';
import { uploadFile, UploadFileResult, useAsyncRequest } from 'tailchat-shared';
import {
uploadFile,
UploadFileResult,
UploadFileUsage,
useAsyncRequest,
} from 'tailchat-shared';
import { ImagePicker } from './ImagePicker';

interface ImageUploaderProps extends PropsWithChildren {
circle?: boolean;
aspect?: number;
className?: string;
usage?: UploadFileUsage;
onUploadSuccess: (fileInfo: UploadFileResult) => void;
}

Expand All @@ -20,6 +26,7 @@ export const ImageUploader: React.FC<ImageUploaderProps> = React.memo(
const file = await blobUrlToFile(blobUrl);

const fileInfo = await uploadFile(file, {
usage: props.usage,
onProgress(percent) {
const uploadProgress = Number((percent * 100).toFixed());
console.log(`进度:${uploadProgress}`);
Expand Down
1 change: 1 addition & 0 deletions client/web/src/components/modals/GroupDetail/Config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export const GroupConfig: React.FC<{
<>
<ImageUploader
aspect={16 / 9}
usage="group"
onUploadSuccess={(fileInfo: UploadFileResult) => {
handleModifyConfig('groupBackgroundImage', fileInfo.url);
}}
Expand Down
1 change: 1 addition & 0 deletions client/web/src/components/modals/GroupDetail/Summary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const GroupSummary: React.FC<{
<div className="w-1/3 mobile:w-full mobile:text-center">
<AvatarUploader
circle={true}
usage="group"
onUploadSuccess={handleGroupAvatarChange}
>
<Avatar size={128} name={groupInfo.name} src={groupInfo.avatar} />
Expand Down
1 change: 1 addition & 0 deletions client/web/src/components/modals/SettingsView/Account.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export const SettingsAccount: React.FC = React.memo(() => {
<div className="w-1/3 mobile:w-full">
<AvatarUploader
circle={true}
usage="user"
onUploadSuccess={handleUserAvatarChange}
>
<Avatar size={128} src={userInfo.avatar} name={userInfo.nickname} />
Expand Down
14 changes: 12 additions & 2 deletions server/admin/src/client/fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,19 +163,29 @@ export const fileFields = [
width: 140,
},
}),
createTextField('usage', {
list: {
width: 100,
},
}),
createFileSizeField('size', {
list: {
width: 120,
sort: true,
},
}),
createTextField('metaData.content-type'),
createTextField('etag'),
createTextField('etag', {
list: {
width: 300,
},
}),
createUserField('userId', {
reference: 'users',
displayField: 'nickname',
list: {
width: 80,
width: 200,
ellipsis: true,
},
}),
createDateTimeField('createdAt', {
Expand Down
1 change: 1 addition & 0 deletions server/admin/src/client/i18n/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export const zhTranslation = {
objectName: '对象存储名',
url: '文件路径',
size: '文件大小',
usage: '使用场景',
'metaData.content-type': '文件类型',
userId: '存储用户',
createdAt: '创建时间',
Expand Down
2 changes: 1 addition & 1 deletion server/admin/src/client/resources/file.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const FileList: React.FC = React.memo(() => {
]}
tableProps={{
scroll: {
x: 1200,
x: 1600,
},
}}
fields={fileFields}
Expand Down
1 change: 1 addition & 0 deletions server/admin/src/client/routes/system/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export const SystemConfig: React.FC = React.memo(() => {
if (file) {
const formdata = new FormData();
formdata.append('file', file);
formdata.append('usage', 'server');

const { data } = await request.put('/file/upload', formdata, {
headers: {
Expand Down
9 changes: 9 additions & 0 deletions server/models/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ export class File extends TimeStamps implements Base {

@prop()
metaData: object;

/**
* 这个文件是用于哪里
* for example: chat, group, user
*/
@prop({
default: 'unknown',
})
usage: string;
}

export type FileDocument = DocumentType<File>;
Expand Down
15 changes: 11 additions & 4 deletions server/services/core/file.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class FileService extends TcService {
ctx: TcContext<
{},
{
$multipart: any;
$params: any;
filename: any;
}
Expand All @@ -129,6 +130,7 @@ class FileService extends TcService {
}

const originFilename = String(ctx.meta.filename);
const usage = _.get(ctx, 'meta.$multipart.usage', 'unknown');

const stream = ctx.params as NodeJS.ReadableStream;
(stream as any).on('error', (err) => {
Expand All @@ -142,7 +144,8 @@ class FileService extends TcService {
const { etag, objectName, url } = await this.saveFileStream(
ctx,
originFilename,
stream
stream,
usage
);

resolve({
Expand Down Expand Up @@ -211,7 +214,8 @@ class FileService extends TcService {
async saveFileStream(
ctx: TcContext,
filename: string,
fileStream: NodeJS.ReadableStream
fileStream: NodeJS.ReadableStream,
usage = 'unknown'
): Promise<{ etag: string; url: string; objectName: string }> {
const span = ctx.startSpan('file.saveFileStream');
const ext = path.extname(filename);
Expand All @@ -234,7 +238,8 @@ class FileService extends TcService {
ctx,
tmpObjectName,
etag,
ext
ext,
usage
);

span.finish();
Expand All @@ -253,7 +258,8 @@ class FileService extends TcService {
ctx: TcContext,
tmpObjectName: string,
etag: string,
ext: string
ext: string,
usage = 'unknown'
): Promise<{
url: string;
objectName: string;
Expand Down Expand Up @@ -299,6 +305,7 @@ class FileService extends TcService {
url,
size: stat.size,
metaData: stat.metaData,
usage,
},
{
upsert: true,
Expand Down

0 comments on commit 52f70c8

Please sign in to comment.