chore: 渲染端通过 api 获取数据

This commit is contained in:
wangxuefeng
2025-03-01 13:54:58 +08:00
parent 50fed4a7dc
commit 5c4aa42ecf
11 changed files with 176 additions and 324 deletions

View File

@@ -1,21 +1,44 @@
import instance from './instance'; import instance from './instance';
import { type HistorySchema } from '@vtj/core';
export const getMaterialsList = async () => { export type LowCodeHistorySchema = {
project_id: string;
id: string;
page_id?: string;
block_id?: string;
dsl?: HistorySchema;
};
function transformHistoryData(data: LowCodeHistorySchema) {
return {
...data,
dsl: JSON.stringify(data.dsl || {})
};
}
export const getHistories = async () => {
const response = await instance.get('/api/v1/histories'); const response = await instance.get('/api/v1/histories');
return response.data; return response.data;
}; };
export const createMaterials = async (data: any) => { export const getHistory = async (id: string) => {
const response = await instance.post('/api/v1/histories', data); const response = await instance.get(`/api/v1/histories/${id}`);
return response.data; return response.data;
}; };
export const updateMaterials = async (id: string, data: any) => { export const createHistory = async (data: LowCodeHistorySchema) => {
const response = await instance.post(
'/api/v1/histories',
transformHistoryData(data)
);
return response.data;
};
export const updateHistory = async (id: string, data: any) => {
const response = await instance.put(`/api/v1/histories/${id}`, data); const response = await instance.put(`/api/v1/histories/${id}`, data);
return response.data; return response.data;
}; };
export const deleteMaterials = async (id: string) => { export const deleteHistory = async (id: string) => {
const response = await instance.delete(`/api/v1/histories/${id}`); const response = await instance.delete(`/api/v1/histories/${id}`);
return response.data; return response.data;
}; };

View File

@@ -4,3 +4,4 @@ export * from './file';
export * from './materials'; export * from './materials';
export * from './project'; export * from './project';
export * from './application'; export * from './application';
export * from './history';

View File

@@ -19,7 +19,11 @@ import {
updateFile as updateLowCodeFile, updateFile as updateLowCodeFile,
getFile as getLowCodeFile, getFile as getLowCodeFile,
deleteFile as deleteLowCodeFile, deleteFile as deleteLowCodeFile,
type LowCodeFileSchema getHistory as getLowCodeHistory,
updateHistory as updateLowCodeHistory,
deleteHistory as deleteLowCodeHistory,
getHistories as getLowCodeHistories,
createHistory as createLowCodeHistory
} from '@/io'; } from '@/io';
import { isNumeric } from 'licia-es'; import { isNumeric } from 'licia-es';
const storage = new Storage({ const storage = new Storage({
@@ -39,20 +43,9 @@ const stringifyFields = [
export class StorageService extends BaseService { export class StorageService extends BaseService {
public async init(project: ProjectSchema): Promise<ProjectSchema> { public async init(project: ProjectSchema): Promise<ProjectSchema> {
// console.log('init-project', project);
// const model = new ProjectModel(project);
// // console.log('init-project-model', model);
// const match = storage.get(`project_${model.id}`);
// console.log('init-project-match', match);
// const dsl = Object.assign(model.toDsl(), match || {});
// console.log('init-project-dsl', dsl);
// storage.save(`project_${model.id}`, dsl);
// return Promise.resolve(dsl);
const remoteProject = await getProject('2'); const remoteProject = await getProject('2');
console.log('remoteProject', remoteProject);
const model = new ProjectModel(remoteProject); const model = new ProjectModel(remoteProject);
const dsl = model.toDsl(); const dsl = model.toDsl();
console.log('dsl', dsl);
storage.save(`project_${model.id}`, dsl); storage.save(`project_${model.id}`, dsl);
return Promise.resolve(dsl); return Promise.resolve(dsl);
} }
@@ -64,7 +57,6 @@ export class StorageService extends BaseService {
} }
public saveProject(project: ProjectSchema): Promise<boolean> { public saveProject(project: ProjectSchema): Promise<boolean> {
console.log('saveProject', project);
const newProject = { const newProject = {
...project, ...project,
...Object.fromEntries( ...Object.fromEntries(
@@ -73,7 +65,6 @@ export class StorageService extends BaseService {
.map(([key, value]) => [key, JSON.stringify(value)]) .map(([key, value]) => [key, JSON.stringify(value)])
) )
}; };
console.log('newProject', newProject);
updateProject('2', newProject); updateProject('2', newProject);
const model = new ProjectModel(project); const model = new ProjectModel(project);
storage.save(`project_${model.id}`, model.toDsl()); storage.save(`project_${model.id}`, model.toDsl());
@@ -93,51 +84,60 @@ export class StorageService extends BaseService {
console.log('saveFile', file); console.log('saveFile', file);
if (file.id) { if (file.id) {
const existFile = await getLowCodeFile(file.id); const existFile = await getLowCodeFile(file.id);
console.log('existFile', existFile);
if (existFile.file_id) { if (existFile.file_id) {
console.log('updateFile', file, existFile); return updateLowCodeFile(file.id, {
await updateLowCodeFile(file.id, {
...existFile, ...existFile,
dsl: file dsl: file
}); })
.then(() => {
return Promise.resolve(true);
})
.catch((err) => {
return Promise.reject(err);
});
} else { } else {
console.log('createFile', file); return createFile({
await createFile({
project_id: 2, project_id: 2,
publish: false, publish: false,
active: true, active: true,
dsl: file, dsl: file,
file_id: file.id file_id: file.id
}); })
.then(() => {
return Promise.resolve(true);
})
.catch((err) => {
return Promise.reject(err);
});
} }
} }
return Promise.resolve(true); return Promise.resolve(false);
} }
public async getFile(id: string): Promise<BlockSchema> { public async getFile(id: string): Promise<BlockSchema> {
const dsl = storage.get(`file_${id}`); console.log('getFile', id);
const lowCodeFile = await getLowCodeFile(id); return getLowCodeFile(id).then((lowCodeFile) => {
console.log('getFile', lowCodeFile); if (lowCodeFile.dsl) {
if (lowCodeFile.dsl) { return Promise.resolve(lowCodeFile.dsl as BlockSchema);
return Promise.resolve(lowCodeFile.dsl as BlockSchema); } else {
} else { return Promise.reject(null);
return Promise.reject(null); }
}
}
public async removeFile(id: string): Promise<boolean> {
storage.remove(`file_${id}`);
console.log('removeFile', id);
// return Promise.resolve(true);
return deleteLowCodeFile(id).then((res) => {
console.log('removeFile-res', res);
return Promise.resolve(true);
}); });
} }
public saveHistory(history: HistorySchema): Promise<boolean> { public async removeFile(id: string): Promise<boolean> {
return deleteLowCodeFile(id).then(() => Promise.resolve(true));
}
public async saveHistory(history: HistorySchema): Promise<boolean> {
console.log('saveHistory', history);
// const existHistory = await getLowCodeHistory(history.id);
// if (existHistory.history_id) {
// await updateLowCodeHistory(history.id, history);
// } else {
// await createLowCodeHistory(history);
// }
storage.save(`history_${history.id}`, history); storage.save(`history_${history.id}`, history);
// console.log('saveHistory', history);
return Promise.resolve(true); return Promise.resolve(true);
} }
@@ -152,23 +152,18 @@ export class StorageService extends BaseService {
}; };
public removeHistory(id: string): Promise<boolean> { public removeHistory(id: string): Promise<boolean> {
const history = storage.get(`history_${id}`) as HistorySchema; return deleteLowCodeHistory(id).then((res) => {
if (history) { console.log('removeHistory', res);
const items = history.items || []; return Promise.resolve(true);
const ids = items.map((item) => item.id); });
this.removeHistoryItem(id, ids);
storage.remove(`history_${id}`);
console.log('removeHistory', history);
}
return Promise.resolve(true);
} }
public getHistory(id: string): Promise<HistorySchema> { public async getHistory(id: string): Promise<HistorySchema> {
const dsl = storage.get(`history_${id}`); const dsl = storage.get(`history_${id}`);
console.log('getHistoryDSL', dsl); console.log('getHistoryDSL', dsl);
const history = new HistoryModel(dsl || { id }); const history = new HistoryModel(dsl || { id });
console.log('getHistory', dsl, id, history); console.log('getHistory', dsl, id, history);
// const histories = await getLowCodeHistories(id);
return Promise.resolve(history.toDsl()); return Promise.resolve(history.toDsl());
} }
@@ -178,9 +173,9 @@ export class StorageService extends BaseService {
return Promise.resolve(item); return Promise.resolve(item);
} }
public saveHistoryItem(fId: string, item: HistoryItem): Promise<boolean> { public saveHistoryItem(fileId: string, item: HistoryItem): Promise<boolean> {
console.log('saveHistoryItem', fId, item); console.log('saveHistoryItem', fileId, item);
storage.save(`history_${fId}_${item.id}`, item); storage.save(`history_${fileId}_${item.id}`, item);
return Promise.resolve(true); return Promise.resolve(true);
} }

View File

@@ -16,6 +16,7 @@
"@iframe-resizer/child": "^5.3.3", "@iframe-resizer/child": "^5.3.3",
"@sy/low-code-shared": "workspace:*", "@sy/low-code-shared": "workspace:*",
"@sy/web-vitals": "workspace:*", "@sy/web-vitals": "workspace:*",
"@tanstack/vue-query": "^5.66.9",
"@vtj/core": "^0.10.6", "@vtj/core": "^0.10.6",
"@vtj/icons": "0.10.6", "@vtj/icons": "0.10.6",
"@vtj/materials": "^0.10.6", "@vtj/materials": "^0.10.6",

View File

@@ -1,267 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted } from 'vue'; import { onMounted, computed, watch } from 'vue';
import { ElLoading } from 'element-plus';
import Postmate from 'postmate'; import Postmate from 'postmate';
import { createRenderer } from '@vtj/renderer' import { createRenderer } from '@vtj/renderer'
import { type BlockSchema } from '@vtj/core' import { getFile } from './io';
import { useQuery } from '@tanstack/vue-query';
const dsl: BlockSchema ={
"name": "List",
"locked": false,
"inject": [],
"state": {
"applicationList": {
"type": "JSExpression",
"value": "[]"
}
},
"lifeCycles": {
"mounted": {
"type": "JSFunction",
"value": "() => {\r\n this.getApplicationList().then(res => {\r\n this.state.applicationList = res.list\r\n })\r\n}"
}
},
"methods": {},
"computed": {},
"watch": [],
"css": "",
"props": [],
"emits": [],
"slots": [],
"dataSources": {
"getApplicationList": {
"type": "api",
"ref": "esnarea6u",
"name": "getApplicationList",
"label": "https://custom-chart-pre-api.shiyue.com/",
"transform": {
"type": "JSFunction",
"value": "(res) => {\n return res;\n}"
},
"test": {
"type": "JSFunction",
"value": "() => this.runApi({\n /* 在这里可输入接口参数 */\n})"
},
"mockTemplate": {
"type": "JSFunction"
}
}
},
"__VTJ_BLOCK__": true,
"__VERSION__": "1740735328808",
"id": "ic98nyzx7",
"nodes": [
{
"id": "lvv6dsl62",
"name": "ElTable",
"from": "element-plus",
"invisible": false,
"locked": false,
"children": [
{
"id": "pfh43lnvu",
"name": "ElTableColumn",
"from": "element-plus",
"invisible": false,
"locked": false,
"children": "",
"props": {
"prop": "id",
"label": "应用 id",
"fixed": "left",
"index": 1
},
"directives": [],
"events": {}
},
{
"id": "sz31teqlm",
"name": "ElTableColumn",
"from": "element-plus",
"invisible": false,
"locked": false,
"children": [],
"props": {
"prop": "name",
"label": "应用名称"
},
"directives": [],
"events": {}
},
{
"id": "45tlsubsf",
"name": "ElTableColumn",
"from": "element-plus",
"invisible": false,
"locked": false,
"children": [
{
"id": "esnffq4yb",
"name": "ElTag",
"from": "element-plus",
"invisible": false,
"locked": false,
"slot": {
"name": "default",
"params": [
"row",
"column",
"$index"
]
},
"children": {
"type": "JSExpression",
"value": "this.context.row.active === true ? '运行中' : '已下架'"
},
"props": {
"closable": false,
"disable-transitions": true,
"hit": false,
"size": "small"
},
"directives": [],
"events": {}
}
],
"props": {
"prop": "active",
"label": "状态"
},
"directives": [],
"events": {}
},
{
"id": "wiozj7tbe",
"name": "ElTableColumn",
"from": "element-plus",
"invisible": false,
"locked": false,
"children": [
{
"id": "2320850l3f",
"name": "ElButton",
"from": "element-plus",
"invisible": false,
"locked": false,
"slot": {
"name": "default",
"params": [
"row",
"column",
"$index"
]
},
"children": "进入项目",
"props": {
"type": "primary",
"size": "small",
"plain": false,
"text": true,
"bg": false,
"loadingIcon": "Loading",
"icon": "VtjIconProject"
},
"directives": [],
"events": {
"click": {
"name": "click",
"handler": {
"type": "JSFunction",
"value": "() => {\r\n\r\n}"
},
"modifiers": {}
}
}
},
{
"id": "1e8qs5f6xn",
"name": "ElPopconfirm",
"from": "element-plus",
"invisible": false,
"locked": false,
"slot": {
"name": "default",
"params": [
"row",
"column",
"$index"
]
},
"children": [
{
"id": "1hscpv89nf",
"name": "ElButton",
"from": "element-plus",
"invisible": false,
"locked": false,
"slot": {
"name": "reference",
"params": []
},
"children": "下架",
"props": {
"size": "small",
"plain": false,
"text": true,
"bg": false,
"link": false,
"round": false,
"circle": false,
"loading": false,
"icon": "Delete",
"type": "warning"
},
"directives": [],
"events": {}
}
],
"props": {
"title": "是否删除?",
"confirmButtonText": "删除",
"iconColor": "#FF1100"
},
"directives": [],
"events": {
"confirm": {
"name": "confirm",
"handler": {
"type": "JSFunction",
"value": "() => {\r\n console.log('this.context.row', this.context.row)\r\n console.log(this.context.row.active)\r\n}"
},
"modifiers": {
"once": true
}
}
}
}
],
"props": {
"prop": "address",
"label": "操作",
"fixed": "right"
},
"directives": [],
"events": {}
}
],
"props": {
"data": {
"type": "JSExpression",
"value": "this.state.applicationList"
},
"size": "small",
"highlightCurrentRow": true,
"show-summary": false,
"lazy": true,
"scrollbar-always-on": true,
"flexible": true,
"stripe": true,
"showHeader": true
},
"directives": [],
"events": {}
}
]
};
onMounted(() => { onMounted(() => {
const handshake = new Postmate.Model({}); const handshake = new Postmate.Model({});
@@ -271,11 +15,34 @@ handshake.then(parent => {
}); });
}); });
const { renderer } = createRenderer({ const { data: file, isFetching } = useQuery({
dsl, queryKey: ['file', '45tncm34d'],
queryFn: async () => {
return getFile('45tncm34d');
},
retry: 3,
retryDelay: 2000,
});
watch(isFetching, (newVal) => {
if (newVal) {
ElLoading.service({
text: '低代码文件加载中...',
});
} else {
ElLoading.service().close();
}
});
const renderer = computed(() => {
console.log(file?.value?.dsl.id);
if (file?.value?.dsl) {
return createRenderer({ dsl: file.value.dsl }).renderer;
}
return null;
}); });
</script> </script>
<template> <template>
<component :is="renderer" /> <component :is="renderer" v-if="renderer" />
</template> </template>

View File

@@ -1,10 +1,15 @@
import { createApp } from "vue"; import { createApp } from "vue";
import "@sy/web-vitals"; import "@sy/web-vitals";
import { IconsPlugin } from "@vtj/icons"; import { IconsPlugin } from "@vtj/icons";
import { VueQueryPlugin } from "@tanstack/vue-query";
// import "@sy/low-code-shared/styles/reset.css"; // import "@sy/low-code-shared/styles/reset.css";
import App from "./App.vue"; import App from "./App.vue";
import ElementPlus from "element-plus"; import ElementPlus from "element-plus";
import "element-plus/dist/index.css"; import "element-plus/dist/index.css";
createApp(App).use(ElementPlus).use(IconsPlugin).mount("#low-code-renderer"); createApp(App)
.use(ElementPlus)
.use(IconsPlugin)
.use(VueQueryPlugin)
.mount("#low-code-renderer");

View File

@@ -0,0 +1,16 @@
import { BlockSchema } from "@vtj/core";
import instance from "./instance";
export type LowCodeFileSchema = {
project_id: number;
publish: boolean;
active: boolean;
dsl: BlockSchema;
file_path?: string;
file_id?: string;
};
export const getFile = async (id: string): Promise<LowCodeFileSchema> => {
const response = await instance.get(`/api/v1/files/${id}`);
return response.data;
};

View File

@@ -0,0 +1 @@
export * from "./file";

View File

@@ -0,0 +1,30 @@
import axios from "axios";
const baseApiUrl = "https://custom-chart-pre-api.shiyue.com/";
// 创建独立实例
const instance = axios.create({
baseURL: baseApiUrl, // 基础URL直接放在实例配置中
});
// 请求拦截器改为使用实例
instance.interceptors.request.use(
(config) => {
// 可在此处添加统一请求头等配置
return config;
},
(error) => {
return Promise.reject(error);
}
);
instance.interceptors.response.use(
(response) => {
return response.data;
},
(error) => {
return Promise.reject(error);
}
);
// 导出实例
export default instance;

View File

@@ -1,5 +1,7 @@
{ {
"extends": "./node_modules/@vtj/cli/config/tsconfig.web.json",
"compilerOptions": { "compilerOptions": {
"lib": ["es2015", "dom"],
"noUnusedLocals": false, "noUnusedLocals": false,
"noUnusedParameters": false, "noUnusedParameters": false,
"baseUrl": "./", "baseUrl": "./",

11
pnpm-lock.yaml generated
View File

@@ -433,6 +433,9 @@ importers:
'@sy/web-vitals': '@sy/web-vitals':
specifier: workspace:* specifier: workspace:*
version: link:../../packages/web-vitals version: link:../../packages/web-vitals
'@tanstack/vue-query':
specifier: ^5.66.9
version: 5.66.9(vue@3.5.13(typescript@5.7.3))
'@vtj/core': '@vtj/core':
specifier: ^0.10.6 specifier: ^0.10.6
version: 0.10.6 version: 0.10.6
@@ -13316,6 +13319,14 @@ snapshots:
vue: 3.5.13(typescript@5.6.3) vue: 3.5.13(typescript@5.6.3)
vue-demi: 0.14.10(vue@3.5.13(typescript@5.6.3)) vue-demi: 0.14.10(vue@3.5.13(typescript@5.6.3))
'@tanstack/vue-query@5.66.9(vue@3.5.13(typescript@5.7.3))':
dependencies:
'@tanstack/match-sorter-utils': 8.19.4
'@tanstack/query-core': 5.66.4
'@vue/devtools-api': 6.6.4
vue: 3.5.13(typescript@5.7.3)
vue-demi: 0.14.10(vue@3.5.13(typescript@5.7.3))
'@trysound/sax@0.2.0': {} '@trysound/sax@0.2.0': {}
'@tsconfig/node20@20.1.4': {} '@tsconfig/node20@20.1.4': {}