Files
code-center/src/routes/user/list.ts
xiongxiao 55378f4c94 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.
2026-03-25 00:57:18 +08:00

119 lines
3.0 KiB
TypeScript

import { app, db, schema } from '@/app.ts';
import { User } from '@/models/user.ts';
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({
path: 'user',
key: 'list',
middleware: ['auth'],
})
.define(async (ctx) => {
const users = await db
.select({
id: schema.cfUser.id,
username: schema.cfUser.username,
description: schema.cfUser.description,
needChangePassword: schema.cfUser.needChangePassword,
})
.from(schema.cfUser)
.orderBy(sql`${schema.cfUser.updatedAt} DESC`);
ctx.body = users;
})
.addTo(app);
app
.route({
path: 'user',
key: 'update',
middleware: ['auth'],
})
.define(async (ctx) => {
const tokenUser = ctx.state.tokenUser;
const { id, username, password, description } = ctx.query.data || {};
if (!id) {
throw new CustomError(400, { message: 'id is required' });
}
const user = await User.findByPk(id);
if (user.id !== tokenUser.id) {
throw new CustomError(403, { message: 'Permission denied' });
}
if (!user) {
throw new CustomError(500, { message: 'user not found' });
}
if (username) {
user.username = username;
}
if (password) {
user.createPassword(password);
}
if (description) {
user.description = description;
}
await user.save();
ctx.body = {
id: user.id,
username: user.username,
description: user.description,
needChangePassword: user.needChangePassword,
};
})
.addTo(app);
app
.route({
path: 'user',
key: 'add',
middleware: ['auth-admin'],
})
.define(async (ctx) => {
const { username, password, description } = ctx.query.data || {};
if (!username) {
throw new CustomError(400, { message: 'username is required' });
}
checkUsername(username);
const findUserByUsername = await User.findOne({ username });
if (findUserByUsername) {
throw new CustomError(400, { message: 'username already exists' });
}
const pwd = password || nanoid(6);
const user = await User.createUser(username, pwd, description);
ctx.body = {
id: user.id,
username: user.username,
description: user.description,
needChangePassword: user.needChangePassword,
password: pwd,
};
})
.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);