feat: remove old data import scripts and JSON files
- Deleted `import-data.ts` and `import-life.ts` scripts for importing short-link and life JSON data into the database. - Removed `ncode-list.json` containing short-link data. - Added new script `mv-resources.ts` for migrating resources from username-based paths to userId-based paths in the database and object storage. - Introduced `UserId` module for fetching user IDs and usernames from the database with caching. - Updated `UserApp` class to use user IDs instead of usernames for resource paths. - Modified routes to include a new endpoint for retrieving user IDs based on usernames.
This commit is contained in:
@@ -29,7 +29,7 @@ export class Asr {
|
||||
this.url = AsrBaseURL
|
||||
}
|
||||
if (!this.appid || !this.token) {
|
||||
throw new Error("VOLCENGINE_Asr_APPID or VOLCENGINE_Asr_TOKEN is not set")
|
||||
console.error("VOLCENGINE_ASR_APPID or VOLCENGINE_ASR_TOKEN is not set")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { getAppLoadStatus, setAppLoadStatus } from './get-app-status.ts';
|
||||
import { minioResources } from '../s3.ts';
|
||||
import { downloadFileFromMinio, fetchApp, fetchDomain, fetchTest } from '@/modules/fm-manager/index.ts';
|
||||
import { logger } from '../logger.ts';
|
||||
import { UserId } from '@/routes/user/modules/user-id.ts';
|
||||
export * from './get-app-status.ts';
|
||||
export * from './user-home.ts';
|
||||
|
||||
@@ -20,7 +21,7 @@ const wrapperResources = (resources: string, urlpath: string) => {
|
||||
if (urlpath.startsWith('http')) {
|
||||
return urlpath;
|
||||
}
|
||||
return `${resources}/${urlpath}`;
|
||||
return `${resources}/data/${urlpath}`;
|
||||
};
|
||||
const demoData = {
|
||||
user: 'root',
|
||||
@@ -221,17 +222,19 @@ export class UserApp {
|
||||
const value = fetchData;
|
||||
await redis.set(key, JSON.stringify(value));
|
||||
const version = value.version;
|
||||
let indexHtml = resources + '/' + user + '/' + app + '/' + version + '/index.html';
|
||||
const uid = await UserId.getUserIdByName(user);
|
||||
let indexHtml = resources + 'data/' + uid + '/' + app + '/' + version + '/index.html';
|
||||
const files = value?.data?.files || [];
|
||||
const permission = value?.data?.permission || { share: 'private' };
|
||||
const data = {};
|
||||
|
||||
// 将文件名和路径添加到 `data` 对象中
|
||||
files.forEach((file) => {
|
||||
const noUserPath = file.path.startsWith(`${user}/`) ? file.path.replace(`${user}/`, '') : file.path;
|
||||
if (file.name === 'index.html') {
|
||||
indexHtml = wrapperResources(resources, file.path);
|
||||
indexHtml = wrapperResources(resources, noUserPath);
|
||||
}
|
||||
data[file.name] = wrapperResources(resources, file.path);
|
||||
data[file.name] = wrapperResources(resources, noUserPath);
|
||||
});
|
||||
await redis.set('user:app:exist:' + app + ':' + user, indexHtml + '||etag||true', 'EX', 60 * 60 * 24 * 7); // 7天
|
||||
await redis.set('user:app:permission:' + app + ':' + user, JSON.stringify(permission), 'EX', 60 * 60 * 24 * 7); // 7天
|
||||
|
||||
@@ -464,7 +464,7 @@ app
|
||||
data: z.object({
|
||||
id: z.string().optional(),
|
||||
key: z.string().optional(),
|
||||
version: z.string().optional(),
|
||||
user: z.string().optional().describe('用户名,默认为当前用户'),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import { CustomError } from '@kevisual/router';
|
||||
import { checkUsername } from './admin/user.ts';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { sql } from 'drizzle-orm';
|
||||
import z from 'zod';
|
||||
import { UserId } from './modules/user-id.ts';
|
||||
|
||||
app
|
||||
.route({
|
||||
@@ -91,3 +93,27 @@ app
|
||||
};
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app.route({
|
||||
path: 'user',
|
||||
key: 'uid',
|
||||
description: '根据用户名获取用户ID',
|
||||
middleware: ['auth'],
|
||||
metadata: {
|
||||
args: {
|
||||
username: z.string().describe('username is required'),
|
||||
}
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
const { username } = ctx.query || {};
|
||||
if (!username) {
|
||||
ctx.throw(400, { message: 'username is required' });
|
||||
}
|
||||
const userId = await UserId.getUserIdByName(username);
|
||||
if (!userId) {
|
||||
ctx.throw(404, { message: 'user not found' });
|
||||
}
|
||||
ctx.body = {
|
||||
id: userId,
|
||||
};
|
||||
}).addTo(app);
|
||||
41
src/routes/user/modules/user-id.ts
Normal file
41
src/routes/user/modules/user-id.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { db, redis, schema } from '@/app.ts';
|
||||
|
||||
export class UserId {
|
||||
static async getUserIdByName(username: string): Promise<string | null> {
|
||||
const cacheKey = `user:id:${username}`;
|
||||
let userId = await redis.get(cacheKey);
|
||||
if (!userId) {
|
||||
const user = await db
|
||||
.select({ id: schema.cfUser.id })
|
||||
.from(schema.cfUser)
|
||||
.where(eq(schema.cfUser.username, username))
|
||||
.limit(1);
|
||||
if (user.length > 0) {
|
||||
userId = user[0].id;
|
||||
await redis.set(cacheKey, userId, 'EX', 3600); // 缓存1小时
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return userId;
|
||||
}
|
||||
static async getUserNameById(userId: string): Promise<string | null> {
|
||||
const cacheKey = `user:name:${userId}`;
|
||||
let username = await redis.get(cacheKey);
|
||||
if (!username) {
|
||||
const user = await db
|
||||
.select({ username: schema.cfUser.username })
|
||||
.from(schema.cfUser)
|
||||
.where(eq(schema.cfUser.id, userId))
|
||||
.limit(1);
|
||||
if (user.length > 0) {
|
||||
username = user[0].username;
|
||||
await redis.set(cacheKey, username, 'EX', 3600); // 缓存1小时
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return username;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user