feat: save single html and update redis

This commit is contained in:
xion 2024-10-27 17:46:59 +08:00
parent c6539439e9
commit e032c092d9
5 changed files with 97 additions and 23 deletions

View File

@ -66,6 +66,7 @@ app
const newData = { ...app.data, ...data };
const newApp = await app.update({ data: newData, ...rest });
ctx.body = newApp;
setExpire(newApp.id, tokenUser.username);
} else {
throw new CustomError('app not found');
}
@ -177,7 +178,7 @@ app
const dataFiles = app.data.files || [];
const newFiles = _.uniqBy([...dataFiles, ...files], 'name');
const res = await app.update({ data: { ...app.data, files: newFiles } });
setExpire(app.id, 'test');
ctx.body = prefixFix(res, tokenUser.username);
} catch (e) {
console.log('update error', e);

View File

@ -5,7 +5,7 @@ import { AppData, AppType, AppStatus } from './app.ts';
export type AppList = Partial<InstanceType<typeof AppListModel>>;
/**
* APP List
* APP List
*/
export class AppListModel extends Model {
declare id: string;

View File

@ -46,29 +46,29 @@ const add = app.route({
add.run = async (ctx) => {
const tokenUser = ctx.state.tokenUser;
const data = ctx.query.data;
const _data: Container = {
title: '',
description: '',
code: '',
type: '',
};
const container = {
..._data,
...data,
};
let containerModel: any = null;
if (container.id) {
containerModel = await ContainerModel.findByPk(container.id);
if (containerModel) {
containerModel.update(container);
containerModel.update({
...container,
publish: {
...containerModel.publish,
...container.publish,
},
});
await containerModel.save();
if (containerModel.code || containerModel.source || containerModel.sourceType) {
ctx.emit?.('pageEdit', {
source: 'container',
data: containerModel.toJSON(),
operation: 'edit',
});
}
}
} else {
try {
containerModel = await ContainerModel.create({
@ -123,7 +123,7 @@ app
}
container.publish = publish;
await container.save();
const { title, description, key, version, fileName } = publish;
const { title, description, key, version, fileName, saveHTML } = publish;
ctx.body = container;
if (!key || !version || !fileName) {
return;
@ -134,6 +134,7 @@ app
version: version,
code: container.code,
filePath: fileName,
saveHTML
});
await ctx.call({
path: 'app',
@ -143,7 +144,7 @@ app
data: {
appKey: key,
version,
files: [uploadResult],
files: uploadResult,
},
},
});

View File

@ -5,7 +5,7 @@ import { Op } from 'sequelize';
import { getContainerData } from './get-container.ts';
import path from 'path';
import fs from 'fs';
import { getHTML, getDataJs } from './file-template.ts';
import { getHTML, getDataJs, getOneHTML } from './file-template.ts';
import { minioClient } from '@/app.ts';
import { bucketName } from '@/modules/minio.ts';
import { getContentType } from '@/utils/get-content-type.ts';
@ -65,24 +65,43 @@ export const cachePage = async (page: PageModel, opts: { tokenUser: any; key; ve
},
];
};
export const uploadMinioContainer = async ({ tokenUser, key, version, code, filePath }) => {
export const uploadMinioContainer = async ({ tokenUser, key, version, code, filePath, saveHTML }) => {
if ((filePath as string).includes('..')) {
throw new CustomError('file path is invalid');
}
const uploadFiles = [];
const minioKeyVersion = `${tokenUser.username}/${key}/${version}`;
const minioPath = path.join(minioKeyVersion, filePath);
const minioFileName = path.basename(minioPath);
if (!minioFileName.endsWith('.js')) {
saveHTML = false;
}
console.log('minioPath', minioPath);
// const isHTML = filePath.endsWith('.html');
const name = minioPath.replace(minioKeyVersion + '/', '');
await minioClient.putObject(bucketName, minioPath, code, code.length, {
'Content-Type': getContentType(filePath),
'app-source': 'user-app',
'Cache-Control': 'no-cache', // 缓存一年
'Cache-Control': 'no-cache', // no-cache
});
return {
uploadFiles.push({
name,
path: minioPath,
};
});
if (saveHTML) {
const htmlPath = minioPath.replace('.js', '.html');
const code = getOneHTML({ title: 'Kevisual', file: minioFileName.replace('.js', '') });
await minioClient.putObject(bucketName, htmlPath, code, code.length, {
'Content-Type': 'text/html',
'app-source': 'user-app',
'Cache-Control': 'max-age=31536000, immutable',
});
uploadFiles.push({
name: 'index.html',
path: htmlPath,
});
}
return uploadFiles;
};
export const uploadMinio = async ({ tokenUser, key, version, path, filePath }) => {
const minioPath = `${tokenUser.username}/${key}/${version}/${path}`;

View File

@ -3,6 +3,11 @@ type HTMLOptions = {
rootId: string;
dataKey?: string;
};
/**
* data list
* @param opts
* @returns
*/
export const getHTML = (opts: HTMLOptions) => {
return `<!DOCTYPE html>
<html lang="zh-CN">
@ -45,3 +50,51 @@ export const getHTML = (opts: HTMLOptions) => {
export const getDataJs = (result: any) => {
return 'export const data=' + JSON.stringify(result);
};
type OneHTMLOptions = {
title?: string;
file: string;
}
/**
* one data
* @param opts
* @returns
*/
export const getOneHTML = (opts: OneHTMLOptions) => {
return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="https://envision.xiongxiao.me/resources/root/avatar.png"/>
<title>${opts.title || 'Kevisual'}</title>
<style>
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
body {
font-size: 16px;
}
</style>
</head>
<body>
<div id="root"></div>
<script type="module">
import { ContainerOne } from 'https://kevisual.xiongxiao.me/system/lib/container.js'
import { render, unmount } from './${opts.file}.js'
const container = new ContainerOne({
root: '#root',
});
container.renderOne({
code: {render, unmount}
});
</script>
</body>
</html>`;
};