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

View File

@ -3,5 +3,5 @@ import user from './user';
import micro from './micro';
import application from './application';
import project from './project';
export default [...dashboard, ...user, ...micro, ...application, ...project];
import staticFile from './static-file';
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>
<div class="login-box">
<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>
<div>1</div>
</template>
<script setup lang="ts">
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>
<script setup lang="ts"></script>
<style lang="less" scoped>
.login-box {

View File

@ -4,17 +4,22 @@ import Postmate from 'postmate';
import { createRenderer } from '@vtj/renderer'
import { type BlockSchema } from '@vtj/core'
const dsl: BlockSchema = {
"name": "ProjectList",
const dsl: BlockSchema ={
"name": "List",
"locked": false,
"inject": [],
"state": {
"editModalVisible": {
"applicationList": {
"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": {},
"computed": {},
"watch": [],
@ -22,10 +27,28 @@ const dsl: BlockSchema = {
"props": [],
"emits": [],
"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,
"__VERSION__": "1740469448492",
"id": "cmc7fwbj7e",
"__VERSION__": "1740735328808",
"id": "ic98nyzx7",
"nodes": [
{
"id": "lvv6dsl62",
@ -43,7 +66,7 @@ const dsl: BlockSchema = {
"children": "",
"props": {
"prop": "id",
"label": "项目 id",
"label": "应用 id",
"fixed": "left",
"index": 1
},
@ -59,7 +82,49 @@ const dsl: BlockSchema = {
"children": [],
"props": {
"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": [],
"events": {}
@ -85,7 +150,7 @@ const dsl: BlockSchema = {
"$index"
]
},
"children": "编辑",
"children": "进入项目",
"props": {
"type": "primary",
"size": "small",
@ -93,7 +158,7 @@ const dsl: BlockSchema = {
"text": true,
"bg": false,
"loadingIcon": "Loading",
"icon": "Edit"
"icon": "VtjIconProject"
},
"directives": [],
"events": {
@ -101,11 +166,72 @@ const dsl: BlockSchema = {
"name": "click",
"handler": {
"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": {}
}
}
},
{
"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": {
@ -118,29 +244,10 @@ const dsl: BlockSchema = {
}
],
"props": {
"data": [
{
"id": "1",
"name": "miniapp",
"actions": {
"edit": true
}
"data": {
"type": "JSExpression",
"value": "this.state.applicationList"
},
{
"id": "2",
"name": "mobile",
"actions": {
"edit": true
}
},
{
"id": "3",
"name": "web",
"actions": {
"edit": true
}
}
],
"size": "small",
"highlightCurrentRow": true,
"show-summary": false,
@ -152,80 +259,6 @@ const dsl: BlockSchema = {
},
"directives": [],
"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": {}
}
}
}
]
};