Files
code-center/src/routes/app-manager/module/app.ts
2025-12-28 16:16:23 +08:00

161 lines
4.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { sequelize } from '../../../modules/sequelize.ts';
import { DataTypes, Model } from 'sequelize';
type AppPermissionType = 'public' | 'private' | 'protected';
/**
* 共享设置
* 1. 设置公共可以直接访问
* 2. 设置受保护需要登录后访问
* 3. 设置私有只有自己可以访问。\n
* 受保护可以设置密码,设置访问的用户名。切换共享状态后,需要重新设置密码和用户名。
*/
export interface AppData {
files: { name: string; path: string }[];
permission?: {
// 访问权限, 字段和minio的权限配置一致
share: AppPermissionType; // public, private(Only Self), protected(protected, 通过配置访问)
usernames?: string; // 受保护的访问用户名,多个用逗号分隔
password?: string; // 受保护的访问密码
'expiration-time'?: string; // 受保护的访问过期时间
};
// 运行环境browser, node, 或者其他,是数组
runtime?: string[];
}
export enum AppStatus {
running = 'running',
stop = 'stop',
}
export type App = Partial<InstanceType<typeof AppModel>>;
/**
* APP 管理
*/
export class AppModel extends Model {
declare id: string;
declare data: AppData;
declare title: string;
declare description: string;
declare version: string;
declare key: string;
declare uid: string;
declare pid: string;
// 是否是history路由代理模式。静态的直接转minio而不需要缓存下来。
declare proxy: boolean;
declare user: string;
declare status: string;
static async moveToNewUser(oldUserName: string, newUserName: string) {
const appIds = await AppModel.findAll({
where: {
user: oldUserName,
},
attributes: ['id'],
});
for (const app of appIds) {
const appData = await AppModel.findByPk(app.id);
appData.user = newUserName;
const data = appData.data;
data.files = await AppModel.getNewFiles(data.files, {
oldUser: oldUserName,
newUser: newUserName,
});
appData.data = { ...data };
await appData.save({ fields: ['data', 'user'] });
}
}
static async getNewFiles(files: { name: string; path: string }[] = [], opts: { oldUser: string; newUser: string } = { oldUser: '', newUser: '' }) {
const { oldUser, newUser } = opts;
const _ = files.map((item) => {
if (item.path.startsWith('http')) {
return item;
}
if (oldUser && item.path.startsWith(oldUser)) {
return item;
}
const paths = item.path.split('/');
return {
...item,
path: newUser + '/' + paths.slice(1).join('/'),
};
});
return _;
}
async getPublic() {
const value = this.toJSON();
// 删除不需要的字段
const data = value.data;
if (data && data.permission) {
delete data.permission.usernames;
delete data.permission.password;
delete data.permission['expiration-time'];
}
value.data = data;
return value;
}
}
AppModel.init(
{
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
comment: 'id',
},
title: {
type: DataTypes.STRING,
defaultValue: '',
},
description: {
type: DataTypes.STRING,
defaultValue: '',
},
data: {
type: DataTypes.JSONB,
defaultValue: {},
},
version: {
type: DataTypes.STRING,
defaultValue: '',
},
key: {
type: DataTypes.STRING,
// 和 uid 组合唯一
},
uid: {
type: DataTypes.UUID,
allowNull: true,
},
pid: {
type: DataTypes.UUID,
allowNull: true,
},
proxy: {
type: DataTypes.BOOLEAN,
defaultValue: false,
},
user: {
type: DataTypes.STRING,
allowNull: true,
},
status: {
type: DataTypes.STRING,
defaultValue: 'running', // stop, running
},
},
{
sequelize,
tableName: 'kv_app',
paranoid: true,
indexes: [
{
unique: true,
fields: ['key', 'uid'],
},
],
},
);
// AppModel.sync({ alter: true, logging: false }).catch((e) => {
// console.error('AppModel sync', e);
// });