chore: 更新部分接口

This commit is contained in:
wangxuefeng 2025-02-28 20:38:51 +08:00
parent 2fa8ed74e5
commit cc6a1e6bc1
5 changed files with 207 additions and 265 deletions

View File

@ -12,13 +12,22 @@ import {
} from '@vtj/core'; } from '@vtj/core';
import { Storage, mapToObject } from '@vtj/utils'; import { Storage, mapToObject } from '@vtj/utils';
import { BaseService } from '@vtj/renderer'; import { BaseService } from '@vtj/renderer';
import { getProject } from '@/io'; import { getProject, updateProject } from '@/io';
const storage = new Storage({ const storage = new Storage({
type: 'local', type: 'local',
expired: 0 expired: 0
// prefix: '__VTJ_' // prefix: '__VTJ_'
}); });
const stringifyFields = [
'config',
'pages',
'dependencies',
'blocks',
'apis',
'meta'
];
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); // console.log('init-project', project);
@ -29,8 +38,9 @@ export class StorageService extends BaseService {
// const dsl = Object.assign(model.toDsl(), match || {}); // const dsl = Object.assign(model.toDsl(), match || {});
// console.log('init-project-dsl', dsl); // console.log('init-project-dsl', dsl);
// storage.save(`project_${model.id}`, dsl); // storage.save(`project_${model.id}`, dsl);
// return Promise.resolve(dsl);
const remoteProject = await getProject(3); 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); console.log('dsl', dsl);
@ -45,6 +55,17 @@ export class StorageService extends BaseService {
} }
public saveProject(project: ProjectSchema): Promise<boolean> { public saveProject(project: ProjectSchema): Promise<boolean> {
console.log('saveProject', project);
const newProject = {
...project,
...Object.fromEntries(
Object.entries(project)
.filter(([key]) => stringifyFields.includes(key))
.map(([key, value]) => [key, JSON.stringify(value)])
)
};
console.log('newProject', 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());
return Promise.resolve(true); return Promise.resolve(true);

View File

@ -3,5 +3,5 @@ import user from './user';
import micro from './micro'; import micro from './micro';
import application from './application'; import application from './application';
import project from './project'; import project from './project';
import staticFile from './static-file';
export default [...dashboard, ...user, ...micro, ...application, ...project]; export default [...dashboard, ...user, ...micro, ...application, ...project, ...staticFile];

View File

@ -0,0 +1,36 @@
import type { RouteRecordRaw } from 'vue-router';
// 微前端路由
const moduleName = 'static-file';
const routes: Array<RouteRecordRaw> = [
{
path: '/static-file',
name: moduleName,
meta: {
title: '静态文件管理',
icon: 'ant-design:file-outlined',
},
children: [
{
path: 'list',
name: `${moduleName}-list`,
meta: {
title: '静态文件列表',
keepAlive: true,
icon: 'ant-design:list',
app: {
url: 'https://localhost:10010',
name: 'low-code-platform-application-list',
sync: true,
alive: true,
degrade: true,
},
},
component: () => import('@/components/renderer-adapter/index.vue'),
},
],
},
];
export default routes;

View File

@ -1,156 +1,8 @@
<template> <template>
<div class="login-box"> <div>1</div>
<div class="login-logo">
<h1 class="mb-0 ml-2 text-3xl font-bold">登录</h1>
</div>
<div class="login-type-switch mb-4">
<a-radio-group v-model:value="loginType">
<a-radio-button value="password">密码登录</a-radio-button>
<a-radio-button value="code">验证码登录</a-radio-button>
</a-radio-group>
</div>
<a-form layout="horizontal" :model="loginFormModel" @submit="handleSubmit">
<a-form-item>
<a-input v-model:value="loginFormModel.phone" size="large" placeholder="请输入手机号">
<template #prefix> <Icon icon="ant-design:user-outlined" /> </template>
</a-input>
</a-form-item>
<a-form-item v-if="loginType === 'password'">
<a-input
v-model:value="loginFormModel.password"
size="large"
type="password"
placeholder="请输入密码"
autocomplete="new-password"
>
<template #prefix> <Icon icon="ant-design:lock-outlined" /></template>
</a-input>
</a-form-item>
<a-form-item v-else>
<div class="flex">
<a-input v-model:value="loginFormModel.code" size="large" placeholder="请输入验证码">
<template #prefix> <Icon icon="ant-design:safety-outlined" /></template>
</a-input>
<a-button class="ml-2" size="large" :disabled="!!timer" @click="handleSendCode">
{{ timer ? `${countdown}s后重新获取` : '获取验证码' }}
</a-button>
</div>
</a-form-item>
<a-form-item>
<a-button type="primary" html-type="submit" size="large" :loading="loading" block>
登录
</a-button>
</a-form-item>
</a-form>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts"></script>
import { ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { message, Modal } from 'ant-design-vue';
import { Icon } from '@/components/basic/icon';
import { useUserStore } from '@/store/modules/user';
import { to } from '@/utils/awaitTo';
import { sendVerificationCode } from '@/io';
const route = useRoute();
const router = useRouter();
const userStore = useUserStore();
const loading = ref(false);
const loginFormModel = ref({
phone: '13265400503',
// password: 'a123456',
code: '123',
});
const loginTypeMap = {
password: 1,
code: 0,
};
fetch(`https://localhost:8088/?from=1026962h`)
const loginType = ref('password');
const timer = ref(null);
const countdown = ref(60);
const hasRequestedCode = ref(false);
const handleSendCode = async () => {
const { phone } = loginFormModel.value;
if (!phone) {
return message.warning('请输入手机号');
}
await sendVerificationCode({ phone }).then(() => {
message.success('验证码已发送');
hasRequestedCode.value = true;
});
countdown.value = 60;
timer.value = setInterval(() => {
countdown.value--;
if (countdown.value <= 0) {
clearInterval(timer.value);
timer.value = null;
}
}, 1000);
};
const handleSubmit = async () => {
const { phone, password, code } = loginFormModel.value;
if (!phone.trim()) {
return message.warning('手机号不能为空!');
}
if (loginType.value === 'password' && !password.trim()) {
return message.warning('密码不能为空!');
}
if (loginType.value === 'code') {
if (!hasRequestedCode.value) {
return message.warning('请先获取验证码!');
}
if (!code.trim()) {
return message.warning('验证码不能为空!');
}
}
message.loading('登录中...', 0);
loading.value = true;
const [err] = await to(
userStore.login({
...loginFormModel.value,
type: loginTypeMap[loginType.value],
}),
);
console.log('err', err);
if (err) {
Modal.error({
title: () => '提示',
content: () => err.message,
});
} else {
message.success('登录成功!');
setTimeout(() => {
router.replace((route.query.redirect as string) || '/');
window.location.reload();
});
}
loading.value = false;
message.destroy();
};
</script>
<style lang="less" scoped> <style lang="less" scoped>
.login-box { .login-box {

View File

@ -4,17 +4,22 @@ import Postmate from 'postmate';
import { createRenderer } from '@vtj/renderer' import { createRenderer } from '@vtj/renderer'
import { type BlockSchema } from '@vtj/core' import { type BlockSchema } from '@vtj/core'
const dsl: BlockSchema = { const dsl: BlockSchema ={
"name": "ProjectList", "name": "List",
"locked": false, "locked": false,
"inject": [], "inject": [],
"state": { "state": {
"editModalVisible": { "applicationList": {
"type": "JSExpression", "type": "JSExpression",
"value": "false" "value": "[]"
}
},
"lifeCycles": {
"mounted": {
"type": "JSFunction",
"value": "() => {\r\n this.getApplicationList().then(res => {\r\n this.state.applicationList = res.list\r\n })\r\n}"
} }
}, },
"lifeCycles": {},
"methods": {}, "methods": {},
"computed": {}, "computed": {},
"watch": [], "watch": [],
@ -22,10 +27,28 @@ const dsl: BlockSchema = {
"props": [], "props": [],
"emits": [], "emits": [],
"slots": [], "slots": [],
"dataSources": {}, "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, "__VTJ_BLOCK__": true,
"__VERSION__": "1740469448492", "__VERSION__": "1740735328808",
"id": "cmc7fwbj7e", "id": "ic98nyzx7",
"nodes": [ "nodes": [
{ {
"id": "lvv6dsl62", "id": "lvv6dsl62",
@ -43,7 +66,7 @@ const dsl: BlockSchema = {
"children": "", "children": "",
"props": { "props": {
"prop": "id", "prop": "id",
"label": "项目 id", "label": "应用 id",
"fixed": "left", "fixed": "left",
"index": 1 "index": 1
}, },
@ -59,7 +82,49 @@ const dsl: BlockSchema = {
"children": [], "children": [],
"props": { "props": {
"prop": "name", "prop": "name",
"label": "项目名称" "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": [], "directives": [],
"events": {} "events": {}
@ -85,7 +150,7 @@ const dsl: BlockSchema = {
"$index" "$index"
] ]
}, },
"children": "编辑", "children": "进入项目",
"props": { "props": {
"type": "primary", "type": "primary",
"size": "small", "size": "small",
@ -93,7 +158,7 @@ const dsl: BlockSchema = {
"text": true, "text": true,
"bg": false, "bg": false,
"loadingIcon": "Loading", "loadingIcon": "Loading",
"icon": "Edit" "icon": "VtjIconProject"
}, },
"directives": [], "directives": [],
"events": { "events": {
@ -101,11 +166,72 @@ const dsl: BlockSchema = {
"name": "click", "name": "click",
"handler": { "handler": {
"type": "JSFunction", "type": "JSFunction",
"value": "() => {\r\n console.log('window', window)\r\n console.log('this.context.row', this.context.row)\r\n // this.state.editModalVisible = true\r\n const routers = this.$router.getRoutes()\r\n console.log('routers', routers)\r\n console.log('this.$router', this.$router)\r\n}" "value": "() => {\r\n\r\n}"
}, },
"modifiers": {} "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": { "props": {
@ -118,29 +244,10 @@ const dsl: BlockSchema = {
} }
], ],
"props": { "props": {
"data": [ "data": {
{ "type": "JSExpression",
"id": "1", "value": "this.state.applicationList"
"name": "miniapp", },
"actions": {
"edit": true
}
},
{
"id": "2",
"name": "mobile",
"actions": {
"edit": true
}
},
{
"id": "3",
"name": "web",
"actions": {
"edit": true
}
}
],
"size": "small", "size": "small",
"highlightCurrentRow": true, "highlightCurrentRow": true,
"show-summary": false, "show-summary": false,
@ -152,80 +259,6 @@ const dsl: BlockSchema = {
}, },
"directives": [], "directives": [],
"events": {} "events": {}
},
{
"id": "8l081hgwdy",
"name": "AModal",
"from": "ant-design-vue",
"invisible": false,
"locked": false,
"children": [
{
"id": "8ojtz79z3q",
"name": "p",
"from": "",
"invisible": false,
"locked": false,
"children": "Some contents...",
"props": {},
"directives": [],
"events": {}
},
{
"id": "8s3fwx31ti",
"name": "p",
"from": "",
"invisible": false,
"locked": false,
"children": "Some contents...",
"props": {},
"directives": [],
"events": {}
},
{
"id": "8vn1umw4ja",
"name": "p",
"from": "",
"invisible": false,
"locked": false,
"children": "Some contents...",
"props": {},
"directives": [],
"events": {}
}
],
"props": {
"open": true,
"title": "Basic Modal"
},
"directives": [
{
"id": "9v357t0ryi",
"name": "vIf",
"value": {
"type": "JSExpression",
"value": "this.state.editModalVisible"
}
}
],
"events": {
"cancel": {
"name": "cancel",
"handler": {
"type": "JSFunction",
"value": "() => {\r\n this.state.editModalVisible = false\r\n}"
},
"modifiers": {}
},
"ok": {
"name": "ok",
"handler": {
"type": "JSFunction",
"value": "() => {\r\n this.state.editModalVisible = false\r\n}"
},
"modifiers": {}
}
}
} }
] ]
}; };