@@ -9,23 +9,93 @@ import {
99} from '~/server/db/operate/images'
1010import { Hono } from 'hono'
1111import { HTTPException } from 'hono/http-exception'
12+ import { fetchConfigsByKeys } from '~/server/db/query/configs'
13+ import { getClient } from '~/server/lib/s3'
14+ import { getR2Client } from '~/server/lib/r2'
15+ import { uploadSimpleObject } from '~/server/lib/s3api'
16+ import { GetObjectCommand } from '@aws-sdk/client-s3'
17+ import sharp from 'sharp'
1218
1319const app = new Hono ( )
1420
1521app . post ( '/add' , async ( c ) => {
16- const image = await c . req . json ( )
17- if ( ! image . url ) {
22+ const body = await c . req . json ( )
23+ if ( ! body ) {
24+ throw new HTTPException ( 400 , { message : 'Missing body' } )
25+ }
26+
27+ // 验证基本图片信息
28+ if ( ! body . url ) {
1829 throw new HTTPException ( 500 , { message : 'Image link cannot be empty' } )
1930 }
20- if ( ! image . height || image . height <= 0 ) {
31+ if ( ! body . height || body . height <= 0 ) {
2132 throw new HTTPException ( 500 , { message : 'Image height cannot be empty and must be greater than 0' } )
2233 }
23- if ( ! image . width || image . width <= 0 ) {
34+ if ( ! body . width || body . width <= 0 ) {
2435 throw new HTTPException ( 500 , { message : 'Image width cannot be empty and must be greater than 0' } )
2536 }
37+
2638 try {
27- await insertImage ( image )
28- return c . json ( { code : 200 , message : 'Success' } )
39+ // 获取存储配置
40+ const configs = await fetchConfigsByKeys ( [
41+ 's3_cdn' ,
42+ 's3_cdn_url' ,
43+ 's3_direct_upload' ,
44+ 'r2_public_domain' ,
45+ 'r2_direct_upload'
46+ ] )
47+
48+ // 检查是否是直传模式
49+ const s3DirectUpload = configs . find ( ( item : any ) => item . config_key === 's3_direct_upload' ) ?. config_value === 'true'
50+ const r2DirectUpload = configs . find ( ( item : any ) => item . config_key === 'r2_direct_upload' ) ?. config_value === 'true'
51+
52+ // 如果是直传模式,需要处理文件
53+ if ( s3DirectUpload || r2DirectUpload ) {
54+ const url = body . url
55+ const previewUrl = body . preview_url
56+ if ( ! url ) {
57+ throw new HTTPException ( 400 , { message : 'Missing file URL' } )
58+ }
59+
60+ // 确保 URL 是完整的
61+ if ( ! url . startsWith ( 'http://' ) && ! url . startsWith ( 'https://' ) ) {
62+ if ( s3DirectUpload ) {
63+ const s3Cdn = configs . find ( ( item : any ) => item . config_key === 's3_cdn' ) ?. config_value
64+ const s3CdnUrl = configs . find ( ( item : any ) => item . config_key === 's3_cdn_url' ) ?. config_value || ''
65+ if ( s3Cdn && s3Cdn === 'true' ) {
66+ body . url = `https://${ s3CdnUrl . includes ( 'https://' ) ? s3CdnUrl . split ( '//' ) [ 1 ] : s3CdnUrl } /${ url } `
67+ }
68+ } else if ( r2DirectUpload ) {
69+ const publicDomain = configs . find ( ( item : any ) => item . config_key === 'r2_public_domain' ) ?. config_value || ''
70+ if ( publicDomain ) {
71+ body . url = `https://${ publicDomain } /${ url } `
72+ }
73+ }
74+ }
75+
76+ // 处理预览图片 URL
77+ if ( previewUrl && ! previewUrl . startsWith ( 'http://' ) && ! previewUrl . startsWith ( 'https://' ) ) {
78+ if ( s3DirectUpload ) {
79+ const s3Cdn = configs . find ( ( item : any ) => item . config_key === 's3_cdn' ) ?. config_value
80+ const s3CdnUrl = configs . find ( ( item : any ) => item . config_key === 's3_cdn_url' ) ?. config_value || ''
81+ if ( s3Cdn && s3Cdn === 'true' ) {
82+ body . preview_url = `https://${ s3CdnUrl . includes ( 'https://' ) ? s3CdnUrl . split ( '//' ) [ 1 ] : s3CdnUrl } /${ previewUrl } `
83+ }
84+ } else if ( r2DirectUpload ) {
85+ const publicDomain = configs . find ( ( item : any ) => item . config_key === 'r2_public_domain' ) ?. config_value || ''
86+ if ( publicDomain ) {
87+ body . preview_url = `https://${ publicDomain } /${ previewUrl } `
88+ }
89+ }
90+ }
91+ }
92+
93+ // 保存图片信息
94+ const res = await insertImage ( body )
95+ return Response . json ( {
96+ code : 200 ,
97+ data : res
98+ } )
2999 } catch ( e ) {
30100 throw new HTTPException ( 500 , { message : 'Failed' , cause : e } )
31101 }
0 commit comments