This commit is contained in:
熊潇 2025-07-04 00:00:57 +08:00
parent 3fe31039da
commit 30514ceb84
8 changed files with 84 additions and 4 deletions

View File

@ -1,4 +1,5 @@
import { app } from './index.ts'; import { app } from './index.ts';
import '@/modules/dev/add-auth.ts';
app.listen(4000, () => { app.listen(4000, () => {
console.log('Server is running on http://localhost:4000'); console.log('Server is running on http://localhost:4000');

View File

@ -2,6 +2,10 @@ import { app, config, oss } from '../app.ts';
import { dashscopeTTS } from '@/examples/dash-scope/tts.ts'; import { dashscopeTTS } from '@/examples/dash-scope/tts.ts';
import { randomLetter } from '@/utils/random.ts'; import { randomLetter } from '@/utils/random.ts';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
const isAdmin = (tokenUser: any) => {
const username = tokenUser?.username || '';
return username === 'admin' || username === 'root';
};
type DashScopeTTSResponse = { type DashScopeTTSResponse = {
output?: { output?: {
finish_reason?: string; finish_reason?: string;
@ -30,12 +34,27 @@ app
.route({ .route({
path: 'aliyun-ai', path: 'aliyun-ai',
key: 'createVideos', key: 'createVideos',
middleware: ['auth-can'],
}) })
.define(async (ctx) => { .define(async (ctx) => {
const { text, model, save = 'none' } = ctx.query; const { text, model, save = 'none' } = ctx.query;
const tokenUser = ctx.state?.tokenUser;
if (!text) { if (!text) {
ctx.throw(400, 'Text and model are required parameters'); ctx.throw(400, '文字text参数不能为空');
} }
const admin = isAdmin(tokenUser);
if (!tokenUser?.id) {
if (text.length > 300) {
// 大概1分钟
ctx.throw(400, '文字长度超过限制未登录用户最多只能输入300个字符');
}
} else if (!admin) {
if (text.length > 1000) {
// 大概3分钟
ctx.throw(400, '文字长度超过限制登录用户最多只能输入1000个字符');
}
}
const value: DashScopeTTSResponse = await dashscopeTTS({ const value: DashScopeTTSResponse = await dashscopeTTS({
text, text,
voice: model || 'Chelsie', voice: model || 'Chelsie',
@ -43,7 +62,7 @@ app
}); });
const url = value?.output?.audio?.url; const url = value?.output?.audio?.url;
const fileName = `audio-${randomLetter(32)}.wav`; const fileName = `audio-${randomLetter(32)}.wav`;
const username = 'share'; const username = tokenUser?.username || 'share';
const today = dayjs().format('YYYY-MM-DD'); const today = dayjs().format('YYYY-MM-DD');
// 使用用户名和日期作为文件夹路径 // 使用用户名和日期作为文件夹路径
const filePath = `${username}/storage/aliyun-ai/audio/${today}/${fileName}`; const filePath = `${username}/storage/aliyun-ai/audio/${today}/${fileName}`;

View File

@ -38,6 +38,7 @@
"lodash-es": "^4.17.21" "lodash-es": "^4.17.21"
}, },
"devDependencies": { "devDependencies": {
"@kevisual/ai": "^0.0.8",
"@kevisual/context": "^0.0.3", "@kevisual/context": "^0.0.3",
"@kevisual/logger": "^0.0.4", "@kevisual/logger": "^0.0.4",
"@kevisual/oss": "^0.0.12", "@kevisual/oss": "^0.0.12",

10
pnpm-lock.yaml generated
View File

@ -30,6 +30,9 @@ importers:
specifier: ^4.17.21 specifier: ^4.17.21
version: 4.17.21 version: 4.17.21
devDependencies: devDependencies:
'@kevisual/ai':
specifier: ^0.0.8
version: 0.0.8
'@kevisual/context': '@kevisual/context':
specifier: ^0.0.3 specifier: ^0.0.3
version: 0.0.3 version: 0.0.3
@ -116,6 +119,9 @@ packages:
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'} engines: {node: '>=12'}
'@kevisual/ai@0.0.8':
resolution: {integrity: sha512-MvK4U1iWf8hz7lj/+YBQV3qWRRDy42VH8fInKFVxjpEGPGaxfXOMP73C85T4Cf82OGU/fxOayiR0xLi2SyBTLw==}
'@kevisual/auth@1.0.5': '@kevisual/auth@1.0.5':
resolution: {integrity: sha512-GwsLj7unKXi7lmMiIIgdig4LwwLiDJnOy15HHZR5gMbyK6s5/uJiMY5RXPB2+onGzTNDqFo/hXjsD2wkerHPVg==} resolution: {integrity: sha512-GwsLj7unKXi7lmMiIIgdig4LwwLiDJnOy15HHZR5gMbyK6s5/uJiMY5RXPB2+onGzTNDqFo/hXjsD2wkerHPVg==}
@ -1349,6 +1355,10 @@ snapshots:
wrap-ansi: 8.1.0 wrap-ansi: 8.1.0
wrap-ansi-cjs: wrap-ansi@7.0.0 wrap-ansi-cjs: wrap-ansi@7.0.0
'@kevisual/ai@0.0.8':
dependencies:
'@kevisual/logger': 0.0.4
'@kevisual/auth@1.0.5': {} '@kevisual/auth@1.0.5': {}
'@kevisual/code-center-module@0.0.23(dotenv@16.6.1)': '@kevisual/code-center-module@0.0.23(dotenv@16.6.1)':

21
src/modules/ai.ts Normal file
View File

@ -0,0 +1,21 @@
import { useContextKey } from '@kevisual/context';
import { BailianProvider } from '@kevisual/ai';
import { config } from './config.ts';
const createBaiLian = () => {
return new BailianProvider({
baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
model: 'qwen3-235b-a22b',
apiKey: config.BAILIAN_API_KEY,
});
};
export const ai = useContextKey('ai', createBaiLian());
export const bailianModel = useContextKey('bailianModel', () => {
return {
turbo: 'qwen-turbo-2025-04-28',
plus: 'qwen-plus-2025-04-28',
a22b235: 'qwen3-235b-a22b',
};
});

View File

@ -0,0 +1,27 @@
import { useContextKey } from '@kevisual/context';
import { App } from '@kevisual/router';
const app = await useContextKey<App>('app');
app
.route({
path: 'auth',
key: '',
id: 'auth',
description: '验证token不存在拒绝',
})
.define(async (ctx) => {
//
})
.addTo(app);
app
.route({
path: 'auth',
key: 'can',
id: 'auth-can',
description: '如果是登陆的设置tokenUser否者为null',
})
.define(async (ctx) => {
//
})
.addTo(app);

View File

@ -3,4 +3,5 @@ import { useContextKey } from '@kevisual/context';
const init = () => { const init = () => {
return new App(); return new App();
}; };
export const app = useContextKey('app', init); export const app = useContextKey('app', init);

View File

@ -1,6 +1,6 @@
import { sequelize, User, UserInit, Org, OrgInit } from '@kevisual/code-center-module'; import { User, UserInit, Org, OrgInit } from '@kevisual/code-center-module/src/core-models.ts';
export { sequelize, User, UserInit, Org, OrgInit }; export { User, UserInit, Org, OrgInit };
export const init = () => { export const init = () => {
UserInit(); UserInit();