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:
xiongxiao
2026-03-25 00:57:18 +08:00
committed by cnb
parent afa5802ef2
commit 55378f4c94
11 changed files with 294 additions and 383 deletions

View File

@@ -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")
}
}

View File

@@ -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天

View File

@@ -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('用户名,默认为当前用户'),
})
}
}

View File

@@ -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);

View 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;
}
}