Compare commits
10 Commits
4f920b0ac2
...
99015ecbd2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
99015ecbd2 | ||
![]() |
db10bb6a6c | ||
![]() |
8d0c890061 | ||
![]() |
9d25cddcb3 | ||
![]() |
0852dd98f0 | ||
![]() |
9b2c728d4c | ||
![]() |
eecc2b1893 | ||
![]() |
261dd5bb67 | ||
![]() |
47c9ec1aba | ||
![]() |
dd69823a00 |
@ -9,3 +9,9 @@ VITE_PORT = 10011
|
|||||||
# VITE_BASE_API_URL = 'https://custom-chart-pre-api.shiyue.com/'
|
# VITE_BASE_API_URL = 'https://custom-chart-pre-api.shiyue.com/'
|
||||||
VITE_BASE_API_URL = 'https://custom-chart-api.shiyuegame.com/'
|
VITE_BASE_API_URL = 'https://custom-chart-api.shiyuegame.com/'
|
||||||
VITE_DEBUG_MODE = true
|
VITE_DEBUG_MODE = true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Y_CODE_PLATFORM_URL = 'https://localhost:10010/'
|
||||||
|
Y_CODE_DESIGNER_URL = 'https://localhost:10011/'
|
||||||
|
Y_CODE_RENDERER_URL = 'https://localhost:10012/'
|
@ -5,3 +5,8 @@ VITE_NODE_ENV = 'production'
|
|||||||
VITE_BASE_URL = /
|
VITE_BASE_URL = /
|
||||||
|
|
||||||
VITE_BASE_API_URL = 'https://custom-chart-api.shiyuegame.com/'
|
VITE_BASE_API_URL = 'https://custom-chart-api.shiyuegame.com/'
|
||||||
|
|
||||||
|
|
||||||
|
Y_CODE_PLATFORM_URL = 'https://y-code-platform.shiyuegame.com/'
|
||||||
|
Y_CODE_DESIGNER_URL = 'https://y-code-designer.shiyuegame.com/'
|
||||||
|
Y_CODE_RENDERER_URL = 'https://y-code-renderer.shiyuegame.com/'
|
||||||
|
@ -6,3 +6,7 @@ VITE_BASE_URL = /
|
|||||||
|
|
||||||
# base api url
|
# base api url
|
||||||
VITE_BASE_API_URL = 'https://custom-chart-pre-api.shiyue.com/'
|
VITE_BASE_API_URL = 'https://custom-chart-pre-api.shiyue.com/'
|
||||||
|
|
||||||
|
Y_CODE_PLATFORM_URL = 'https://y-code-platform-pre.shiyue.com/'
|
||||||
|
Y_CODE_DESIGNER_URL = 'https://y-code-designer-pre.shiyue.com/'
|
||||||
|
Y_CODE_RENDERER_URL = 'https://y-code-renderer-pre.shiyue.com/'
|
||||||
|
@ -13,22 +13,23 @@
|
|||||||
"clean": "rimraf node_modules"
|
"clean": "rimraf node_modules"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vtj/core": "^0.10.9",
|
"@vtj/core": "^0.10.10",
|
||||||
"@vtj/designer": "0.10.9",
|
"@vtj/designer": "0.10.10",
|
||||||
"@vtj/icons": "0.10.9",
|
"@vtj/icons": "0.10.10",
|
||||||
"@vtj/local": "^0.10.9",
|
"@vtj/local": "^0.10.10",
|
||||||
"@vtj/materials": "^0.10.9",
|
"@vtj/materials": "^0.10.10",
|
||||||
"@vtj/node": "0.10.2",
|
"@vtj/node": "0.10.2",
|
||||||
"@vtj/pro": "^0.10.9",
|
"@vtj/pro": "^0.10.10",
|
||||||
"@vtj/renderer": "^0.10.9",
|
"@vtj/renderer": "^0.10.10",
|
||||||
"@vtj/ui": "^0.10.9",
|
"@vtj/ui": "^0.10.10",
|
||||||
"@vtj/utils": "0.10.9",
|
"@vtj/utils": "0.10.10",
|
||||||
"@vtj/web": "^0.10.9",
|
"@vtj/web": "^0.10.10",
|
||||||
"axios": "^1.8.1",
|
"axios": "^1.8.1",
|
||||||
"element-plus": "^2.9.4",
|
"element-plus": "^2.9.4",
|
||||||
"licia-es": "^1.46.0",
|
"licia-es": "^1.46.0",
|
||||||
"pinia": "^3.0.1",
|
"pinia": "^3.0.1",
|
||||||
"pinia-plugin-persistedstate": "^4.2.0",
|
"pinia-plugin-persistedstate": "^4.2.0",
|
||||||
|
"postmate": "^1.5.2",
|
||||||
"unplugin-auto-import": "^19.1.1",
|
"unplugin-auto-import": "^19.1.1",
|
||||||
"vue": "~3.5.13",
|
"vue": "~3.5.13",
|
||||||
"vue-router": "~4.5.0"
|
"vue-router": "~4.5.0"
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
defineProps<{ msg: string }>()
|
|
||||||
|
|
||||||
const count = ref(0)
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<h1>{{ msg }}</h1>
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<button type="button" @click="count++">count is {{ count }}</button>
|
|
||||||
<p>
|
|
||||||
Edit
|
|
||||||
<code>components/HelloWorld.vue</code> to test HMR
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Check out
|
|
||||||
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
|
|
||||||
>create-vue</a
|
|
||||||
>, the official Vue + Vite starter
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Install
|
|
||||||
<a href="https://github.com/vuejs/language-tools" target="_blank">Volar</a>
|
|
||||||
in your IDE for a better DX
|
|
||||||
</p>
|
|
||||||
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.read-the-docs {
|
|
||||||
color: #888;
|
|
||||||
}
|
|
||||||
</style>
|
|
2
apps/designer/src/constants/env.ts
Normal file
2
apps/designer/src/constants/env.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
// @ts-ignore
|
||||||
|
export const currentEnv = __APP_ENV__;
|
1
apps/designer/src/constants/index.ts
Normal file
1
apps/designer/src/constants/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './env';
|
@ -1,7 +1,6 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
const apiBase = import.meta.env.VITE_BASE_API_URL;
|
const apiBase = import.meta.env.VITE_BASE_API_URL;
|
||||||
console.log('apiBase', apiBase);
|
|
||||||
|
|
||||||
// 创建独立实例
|
// 创建独立实例
|
||||||
const instance = axios.create({
|
const instance = axios.create({
|
||||||
|
@ -8,7 +8,7 @@ export const pinia = createPinia();
|
|||||||
// 用户模块 store
|
// 用户模块 store
|
||||||
export const useUserStore = defineStore('user', () => {
|
export const useUserStore = defineStore('user', () => {
|
||||||
// 状态定义
|
// 状态定义
|
||||||
const token = ref<string>(localStorage.getItem('token') || '');
|
const token = ref<string>(localStorage.getItem('y-code-access-token') || '');
|
||||||
const userProfile = ref<null>(null);
|
const userProfile = ref<null>(null);
|
||||||
|
|
||||||
// getter 计算属性
|
// getter 计算属性
|
||||||
@ -17,20 +17,14 @@ export const useUserStore = defineStore('user', () => {
|
|||||||
// 同步 action
|
// 同步 action
|
||||||
const setToken = (newToken: string) => {
|
const setToken = (newToken: string) => {
|
||||||
token.value = newToken;
|
token.value = newToken;
|
||||||
localStorage.setItem('token', newToken);
|
localStorage.setItem('y-code-access-token', newToken);
|
||||||
};
|
|
||||||
|
|
||||||
// 异步 action
|
|
||||||
const fetchProfile = async () => {
|
|
||||||
const { data } = await axios.get('/api/user/profile');
|
|
||||||
userProfile.value = data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 清理方法
|
// 清理方法
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
token.value = '';
|
token.value = '';
|
||||||
userProfile.value = null;
|
userProfile.value = null;
|
||||||
localStorage.removeItem('token');
|
localStorage.removeItem('y-code-access-token');
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -38,7 +32,6 @@ export const useUserStore = defineStore('user', () => {
|
|||||||
userProfile,
|
userProfile,
|
||||||
isLoggedIn,
|
isLoggedIn,
|
||||||
setToken,
|
setToken,
|
||||||
fetchProfile,
|
|
||||||
logout
|
logout
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -1,40 +1,71 @@
|
|||||||
<template>
|
|
||||||
<div class="designer-container" ref="container"></div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import {
|
import Postmate from 'postmate';
|
||||||
Engine,
|
import { Engine, widgetManager } from '@vtj/pro';
|
||||||
widgetManager
|
import { request, jsonp } from '@vtj/utils';
|
||||||
// type ProjectModel
|
import { useUserStore } from '@/store';
|
||||||
} from '@vtj/pro';
|
|
||||||
|
|
||||||
import { LowCodeService } from '@/service';
|
import { LowCodeService } from '@/service';
|
||||||
|
|
||||||
const container = ref();
|
const container = ref();
|
||||||
const service = new LowCodeService();
|
const service = new LowCodeService();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
const engine = new Engine({
|
onMounted(async () => {
|
||||||
|
// 数据模型
|
||||||
|
const model = {
|
||||||
|
name: '',
|
||||||
|
url: '',
|
||||||
|
applicationId: -1,
|
||||||
|
projectId: -1,
|
||||||
|
accessToken: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
const handshake = new Postmate.Model({});
|
||||||
|
await handshake.then((parent) => {
|
||||||
|
parent.emit('sync-context', 'y-code-designer is ready');
|
||||||
|
Object.assign(model, parent.model);
|
||||||
|
// console.log('get parent model', model);
|
||||||
|
userStore.setToken(model.accessToken);
|
||||||
|
request.useRequest((req) => {
|
||||||
|
req.headers.set('Authorization', `Bearer ${model.accessToken}`);
|
||||||
|
return req;
|
||||||
|
});
|
||||||
|
const engine = new Engine({
|
||||||
container,
|
container,
|
||||||
service,
|
service,
|
||||||
project: {
|
project: {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
id: 4,
|
id: model.projectId,
|
||||||
name: '低代码平台'
|
name: model.name
|
||||||
|
},
|
||||||
|
adapter: {
|
||||||
|
request,
|
||||||
|
jsonp
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
widgetManager.set('Previewer', {
|
||||||
widgetManager.set('Previewer', {
|
|
||||||
props: {
|
props: {
|
||||||
path: (block: any) => {
|
path: (block: any) => {
|
||||||
const pathname = location.pathname;
|
const pathname = location.pathname;
|
||||||
return `${pathname}#/preview/${block.id}`;
|
return `${pathname}#/preview/${block.id}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
widgetManager.set('Templates', {
|
||||||
|
invisible: true
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="designer-container"
|
||||||
|
ref="container"
|
||||||
|
:token="userStore.token"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.designer-container {
|
.designer-container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -1,12 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<component v-if="renderer" :is="renderer"></component>
|
<component v-if="renderer" :is="renderer" v-bind="$attrs"></component>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, getCurrentInstance } from 'vue';
|
import { ref, getCurrentInstance } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { createProvider, ContextMode } from '@vtj/pro';
|
import { createProvider, ContextMode } from '@vtj/pro';
|
||||||
import { LowCodeService } from '@/service';
|
import { LowCodeService } from '@/service';
|
||||||
|
import { request, jsonp } from '@vtj/utils';
|
||||||
|
import { useUserStore } from '@/store';
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
const service = new LowCodeService();
|
const service = new LowCodeService();
|
||||||
|
request.useRequest((req) => {
|
||||||
|
req.headers.set('Authorization', `Bearer ${userStore.token}`);
|
||||||
|
return req;
|
||||||
|
});
|
||||||
const { provider, onReady } = createProvider({
|
const { provider, onReady } = createProvider({
|
||||||
mode: ContextMode.Runtime,
|
mode: ContextMode.Runtime,
|
||||||
service,
|
service,
|
||||||
@ -14,6 +22,10 @@ const { provider, onReady } = createProvider({
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
id: 4
|
id: 4
|
||||||
},
|
},
|
||||||
|
adapter: {
|
||||||
|
request,
|
||||||
|
jsonp
|
||||||
|
},
|
||||||
dependencies: {
|
dependencies: {
|
||||||
Vue: () => import('vue'),
|
Vue: () => import('vue'),
|
||||||
VueRouter: () => import('vue-router'),
|
VueRouter: () => import('vue-router'),
|
||||||
|
@ -35,7 +35,7 @@ const config = createViteConfig({
|
|||||||
export default defineConfig(({ mode }) => {
|
export default defineConfig(({ mode }) => {
|
||||||
console.log('mode', mode);
|
console.log('mode', mode);
|
||||||
// 加载环境变量(支持 .env.development/.env.production)
|
// 加载环境变量(支持 .env.development/.env.production)
|
||||||
const env = loadEnv(mode, process.cwd(), ['VITE_', 'VTJ_', 'SY_']);
|
const env = loadEnv(mode, process.cwd(), ['VITE_', 'VTJ_', 'SY_', 'Y_CODE_']);
|
||||||
return {
|
return {
|
||||||
...config,
|
...config,
|
||||||
server: {
|
server: {
|
||||||
|
@ -6,6 +6,13 @@ VITE_BASE_URL = /
|
|||||||
|
|
||||||
# 前端可见变量(必须以 VITE_ 开头)
|
# 前端可见变量(必须以 VITE_ 开头)
|
||||||
VITE_PORT = 10010
|
VITE_PORT = 10010
|
||||||
# VITE_BASE_API_URL = 'https://custom-chart-pre-api.shiyue.com/'
|
VITE_BASE_API_URL = 'https://custom-chart-pre-api.shiyue.com/'
|
||||||
VITE_BASE_API_URL = 'https://custom-chart-api.shiyuegame.com/'
|
# VITE_BASE_API_URL = 'https://custom-chart-api.shiyuegame.com/'
|
||||||
|
|
||||||
VITE_DEBUG_MODE = true
|
VITE_DEBUG_MODE = true
|
||||||
|
|
||||||
|
|
||||||
|
Y_CODE_PLATFORM_URL = 'https://localhost:10010/'
|
||||||
|
Y_CODE_DESIGNER_URL = 'https://localhost:10011/'
|
||||||
|
Y_CODE_RENDERER_URL = 'https://localhost:10012/'
|
||||||
|
Y_CODE_V1_URL = 'https://localhost:10013/'
|
@ -5,3 +5,8 @@ VITE_NODE_ENV = 'production'
|
|||||||
VITE_BASE_URL = /
|
VITE_BASE_URL = /
|
||||||
|
|
||||||
VITE_BASE_API_URL = 'https://custom-chart-api.shiyuegame.com/'
|
VITE_BASE_API_URL = 'https://custom-chart-api.shiyuegame.com/'
|
||||||
|
|
||||||
|
Y_CODE_PLATFORM_URL = 'https://y-code-platform.shiyuegame.com/'
|
||||||
|
Y_CODE_DESIGNER_URL = 'https://y-code-designer.shiyuegame.com/'
|
||||||
|
Y_CODE_RENDERER_URL = 'https://y-code-renderer.shiyuegame.com/'
|
||||||
|
Y_CODE_V1_URL = 'https://custom-chart.shiyuegame.com/'
|
@ -6,3 +6,8 @@ VITE_BASE_URL = /
|
|||||||
|
|
||||||
# base api url
|
# base api url
|
||||||
VITE_BASE_API_URL = 'https://custom-chart-pre-api.shiyue.com/'
|
VITE_BASE_API_URL = 'https://custom-chart-pre-api.shiyue.com/'
|
||||||
|
|
||||||
|
Y_CODE_PLATFORM_URL = 'https://y-code-platform-pre.shiyue.com/'
|
||||||
|
Y_CODE_DESIGNER_URL = 'https://y-code-designer-pre.shiyue.com/'
|
||||||
|
Y_CODE_RENDERER_URL = 'https://y-code-renderer-pre.shiyue.com/'
|
||||||
|
Y_CODE_V1_URL = 'https://custom-chart.shiyue.com/'
|
@ -1,42 +1,3 @@
|
|||||||
## 安装使用
|
# 因为项目接入了天梯登陆,使用前需要申请天梯的悦码权限
|
||||||
|
|
||||||
- 安装依赖
|
天梯地址 https://auth-pro.shiyue.com/
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm install
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
- 运行
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm dev
|
|
||||||
```
|
|
||||||
|
|
||||||
- 打包
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm build
|
|
||||||
```
|
|
||||||
|
|
||||||
## vscode 配置
|
|
||||||
|
|
||||||
安装项目根目录 `.vscode` 推荐的插件,再安装 `Volar`,并禁用 `Vetur`,重启 vscode 即可。
|
|
||||||
|
|
||||||
## Git 贡献提交规范
|
|
||||||
|
|
||||||
- 参考 [vue](https://github.com/vuejs/vue/blob/dev/.github/COMMIT_CONVENTION.md) 规范 ([Angular](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular))
|
|
||||||
|
|
||||||
- `feat` 增加新功能
|
|
||||||
- `fix` 修复问题/BUG
|
|
||||||
- `style` 代码风格相关无影响运行结果的
|
|
||||||
- `perf` 优化/性能提升
|
|
||||||
- `refactor` 重构
|
|
||||||
- `revert` 撤销修改
|
|
||||||
- `test` 测试相关
|
|
||||||
- `docs` 文档/注释
|
|
||||||
- `chore` 依赖更新/脚手架配置修改等
|
|
||||||
- `workflow` 工作流改进
|
|
||||||
- `ci` 持续集成
|
|
||||||
- `types` 类型定义文件更改
|
|
||||||
- `wip` 开发中
|
|
||||||
|
@ -29,9 +29,11 @@
|
|||||||
"@ant-design/icons-vue": "~7.0.1",
|
"@ant-design/icons-vue": "~7.0.1",
|
||||||
"@iconify/vue": "^4.3.0",
|
"@iconify/vue": "^4.3.0",
|
||||||
"@iframe-resizer/parent": "^5.3.3",
|
"@iframe-resizer/parent": "^5.3.3",
|
||||||
|
"@sy/unified-login": "1.0.29",
|
||||||
"@sy/y-code-renderer-adapter": "workspace:*",
|
"@sy/y-code-renderer-adapter": "workspace:*",
|
||||||
"@tanstack/query-core": "^5.66.4",
|
"@tanstack/query-core": "^5.66.4",
|
||||||
"@tanstack/vue-query": "^5.66.9",
|
"@tanstack/vue-query": "^5.66.9",
|
||||||
|
"@vue/runtime-core": "^3.5.13",
|
||||||
"@vueuse/core": "~11.1.0",
|
"@vueuse/core": "~11.1.0",
|
||||||
"ant-design-vue": "~4.2.6",
|
"ant-design-vue": "~4.2.6",
|
||||||
"axios": "~1.8.1",
|
"axios": "~1.8.1",
|
||||||
@ -51,9 +53,9 @@
|
|||||||
"vue": "~3.5.13",
|
"vue": "~3.5.13",
|
||||||
"vue-i18n": "^11.1.1",
|
"vue-i18n": "^11.1.1",
|
||||||
"vue-router": "~4.4.5",
|
"vue-router": "~4.4.5",
|
||||||
"vue-types": "~5.1.3",
|
"vue-types": "~6.0.0",
|
||||||
"vue-virtual-scroller": "2.0.0-beta.8",
|
"vue-virtual-scroller": "2.0.0-beta.8",
|
||||||
"wujie": "^1.0.25",
|
"wujie-vue3": "^1.0.25",
|
||||||
"xlsx": "~0.18.5"
|
"xlsx": "~0.18.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -62,9 +64,9 @@
|
|||||||
"@iconify-json/ant-design": "^1.2.5",
|
"@iconify-json/ant-design": "^1.2.5",
|
||||||
"@iconify-json/ep": "^1.2.2",
|
"@iconify-json/ep": "^1.2.2",
|
||||||
"@iconify/json": "^2.2.307",
|
"@iconify/json": "^2.2.307",
|
||||||
"@sy/y-code-designer": "workspace:*",
|
|
||||||
"@sy/low-code-shared": "workspace:*",
|
"@sy/low-code-shared": "workspace:*",
|
||||||
"@sy/vite-plugin-http2-proxy": "workspace:*",
|
"@sy/vite-plugin-http2-proxy": "workspace:*",
|
||||||
|
"@sy/y-code-designer": "workspace:*",
|
||||||
"@types/crypto-js": "^4.2.2",
|
"@types/crypto-js": "^4.2.2",
|
||||||
"@types/lodash-es": "~4.17.12",
|
"@types/lodash-es": "~4.17.12",
|
||||||
"@types/node": "~22.7.9",
|
"@types/node": "~22.7.9",
|
||||||
@ -74,8 +76,8 @@
|
|||||||
"@typescript-eslint/parser": "~8.11.0",
|
"@typescript-eslint/parser": "~8.11.0",
|
||||||
"@umijs/openapi": "^1.13.0",
|
"@umijs/openapi": "^1.13.0",
|
||||||
"@vitejs/plugin-vue": "~5.1.5",
|
"@vitejs/plugin-vue": "~5.1.5",
|
||||||
"@vitejs/plugin-vue-jsx": "~4.0.1",
|
"@vitejs/plugin-vue-jsx": "~4.1.1",
|
||||||
"@vue/tsconfig": "^0.5.1",
|
"@vue/tsconfig": "^0.7.0",
|
||||||
"commitizen": "~4.3.1",
|
"commitizen": "~4.3.1",
|
||||||
"conventional-changelog-cli": "~4.1.0",
|
"conventional-changelog-cli": "~4.1.0",
|
||||||
"cross-env": "~7.0.3",
|
"cross-env": "~7.0.3",
|
||||||
@ -90,9 +92,9 @@
|
|||||||
"lint-staged": "~15.2.11",
|
"lint-staged": "~15.2.11",
|
||||||
"msw": "^2.7.0",
|
"msw": "^2.7.0",
|
||||||
"postcss": "~8.4.49",
|
"postcss": "~8.4.49",
|
||||||
"postcss-html": "~1.7.0",
|
"postcss-html": "~1.8.0",
|
||||||
"postcss-less": "~6.0.0",
|
"postcss-less": "~6.0.0",
|
||||||
"prettier": "~3.3.3",
|
"prettier": "~3.5.3",
|
||||||
"rimraf": "~6.0.1",
|
"rimraf": "~6.0.1",
|
||||||
"stylelint": "~16.10.0",
|
"stylelint": "~16.10.0",
|
||||||
"stylelint-config-property-sort-order-smacss": "^10.0.0",
|
"stylelint-config-property-sort-order-smacss": "^10.0.0",
|
||||||
@ -101,7 +103,7 @@
|
|||||||
"stylelint-config-standard": "~36.0.1",
|
"stylelint-config-standard": "~36.0.1",
|
||||||
"stylelint-order": "~6.0.4",
|
"stylelint-order": "~6.0.4",
|
||||||
"stylelint-prettier": "^5.0.3",
|
"stylelint-prettier": "^5.0.3",
|
||||||
"typescript": "~5.6.3",
|
"typescript": "~5.8.2",
|
||||||
"unocss": "^65.5.0",
|
"unocss": "^65.5.0",
|
||||||
"unplugin-vue-components": "~0.27.5",
|
"unplugin-vue-components": "~0.27.5",
|
||||||
"vite": "~6.2.0",
|
"vite": "~6.2.0",
|
||||||
@ -110,8 +112,8 @@
|
|||||||
"vite-plugin-mkcert": "^1.17.6",
|
"vite-plugin-mkcert": "^1.17.6",
|
||||||
"vite-plugin-svg-icons": "~2.0.1",
|
"vite-plugin-svg-icons": "~2.0.1",
|
||||||
"vite-plugin-vue-inspector": "^5.3.1",
|
"vite-plugin-vue-inspector": "^5.3.1",
|
||||||
"vue-eslint-parser": "~9.4.3",
|
"vue-eslint-parser": "~10.1.1",
|
||||||
"vue-tsc": "~2.1.10"
|
"vue-tsc": "~2.2.8"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"vue",
|
"vue",
|
||||||
|
@ -19,12 +19,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
import { theme } from 'ant-design-vue';
|
import { theme } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { useUserStore } from '@/store/modules/user';
|
||||||
|
|
||||||
import { LockScreen } from '@/components/basic/lockscreen';
|
import { LockScreen } from '@/components/basic/lockscreen';
|
||||||
import { useRoute } from 'vue-router';
|
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
userStore.login();
|
||||||
|
|
||||||
const { compactAlgorithm } = theme;
|
const { compactAlgorithm } = theme;
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,21 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- <div id="container" /> -->
|
<!-- <div id="container" /> -->
|
||||||
<iframe
|
<!-- <iframe
|
||||||
ref="iframeRef"
|
ref="iframeRef"
|
||||||
width="100%"
|
width="100%"
|
||||||
style="border: none"
|
style="border: none"
|
||||||
height="100%"
|
height="100%"
|
||||||
:src="route.meta?.app?.url"
|
:src="route.meta?.app?.url"
|
||||||
/>
|
/> -->
|
||||||
<!-- <component :is="WujieVue" v-bind="route.meta?.app" /> -->
|
<WujieVue width="100%" height="100%" v-bind="route.meta?.app" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted } from 'vue';
|
import { onMounted } from 'vue';
|
||||||
import { setupApp, startApp } from 'wujie';
|
// import { setupApp, startApp } from 'wujie';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
|
import WujieVue from 'wujie-vue3';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
console.log(route.meta?.app);
|
// console.log(route.meta?.app);
|
||||||
// onMounted(() => {
|
// onMounted(() => {
|
||||||
// setupApp({
|
// setupApp({
|
||||||
// el: '#container',
|
// el: '#container',
|
||||||
|
@ -2,32 +2,37 @@
|
|||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import Postmate from 'postmate';
|
import Postmate from 'postmate';
|
||||||
import { Spin, Alert, Button } from 'ant-design-vue';
|
import { useUserStore } from '@/store/modules/user';
|
||||||
|
// import { Spin, Alert, Button } from 'ant-design-vue';
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
|
console.log('userStore', userStore);
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const MAX_RETRIES = 3;
|
// const MAX_RETRIES = 3;
|
||||||
|
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const errorMessage = ref('');
|
const errorMessage = ref('');
|
||||||
const retryCount = ref(0);
|
// const retryCount = ref(0);
|
||||||
|
|
||||||
const initPostmate = async () => {
|
const initPostmate = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
errorMessage.value = '';
|
errorMessage.value = '';
|
||||||
const container = document.getElementById('low-code-adapter');
|
const container = document.getElementById('low-code-adapter');
|
||||||
console.log('container', container);
|
|
||||||
if (!container) {
|
if (!container) {
|
||||||
errorMessage.value = '容器元素未找到';
|
errorMessage.value = '容器元素未找到';
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const handle = new Postmate({
|
const connection = new Postmate({
|
||||||
container,
|
container,
|
||||||
url: route.meta?.app?.url,
|
url: route.meta?.app?.url,
|
||||||
name: 'y-code-renderer',
|
name: 'y-code-renderer',
|
||||||
classListArray: ['responsive-iframe'],
|
classListArray: ['responsive-iframe'],
|
||||||
model: {
|
model: {
|
||||||
|
accessToken: userStore.token,
|
||||||
name: route.meta?.app?.name,
|
name: route.meta?.app?.name,
|
||||||
applicationId: route.meta?.app?.applicationId,
|
applicationId: route.meta?.app?.applicationId,
|
||||||
projectId: route.meta?.app?.projectId,
|
projectId: route.meta?.app?.projectId,
|
||||||
@ -36,23 +41,27 @@
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
handle
|
connection.then((child) => {
|
||||||
.then((instance) => {
|
console.log('Postmate 连接成功', child);
|
||||||
console.log('Postmate连接成功', instance);
|
child.on('some-event', (data) => console.log(data)); // Logs "Hello, World!"
|
||||||
retryCount.value = 0; // 重置重试计数器
|
child.call('sayHi', {
|
||||||
})
|
name: route.meta?.app?.name,
|
||||||
.catch((err) => {
|
|
||||||
retryCount.value++;
|
|
||||||
errorMessage.value = `连接失败: ${err.message}`;
|
|
||||||
if (retryCount.value < MAX_RETRIES) {
|
|
||||||
initPostmate(); // 自动重试
|
|
||||||
} else {
|
|
||||||
errorMessage.value = '已达到最大重试次数,请检查网络连接';
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
loading.value = false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// retryCount.value = 0; // 重置重试计数器
|
||||||
|
});
|
||||||
|
// .catch((err) => {
|
||||||
|
// retryCount.value++;
|
||||||
|
// errorMessage.value = `连接失败: ${err.message}`;
|
||||||
|
// if (retryCount.value < MAX_RETRIES) {
|
||||||
|
// initPostmate(); // 自动重试
|
||||||
|
// } else {
|
||||||
|
// errorMessage.value = '已达到最大重试次数,请检查网络连接';
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// .finally(() => {
|
||||||
|
// loading.value = false;
|
||||||
|
// });
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@ -61,18 +70,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="iframe-container">
|
|
||||||
<div id="low-code-adapter" />
|
<div id="low-code-adapter" />
|
||||||
|
|
||||||
<!-- <div v-if="loading" class="loading-overlay">
|
|
||||||
<Spin :tip="`正在连接应用(${retryCount + 1}/${MAX_RETRIES})`" />
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
<!-- <div v-if="errorMessage" class="error-overlay">
|
|
||||||
<Alert type="error" :message="errorMessage" show-icon />
|
|
||||||
<Button v-if="retryCount < MAX_RETRIES" @click="initPostmate">重新连接</Button>
|
|
||||||
</div> -->
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@ -85,39 +83,8 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.iframe-container {
|
|
||||||
position: relative;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#low-code-adapter {
|
#low-code-adapter {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 99%;
|
||||||
}
|
|
||||||
|
|
||||||
.loading-overlay {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background: rgba(255, 255, 255, 0.8);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error-overlay {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background: rgba(255, 255, 255, 0.8);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
z-index: 1001;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -2,6 +2,16 @@ export const devMode = 'development';
|
|||||||
|
|
||||||
export const prodMode = 'production';
|
export const prodMode = 'production';
|
||||||
|
|
||||||
export const isDevMode = import.meta.env.DEV;
|
export const stagingMode = 'staging';
|
||||||
|
|
||||||
export const isProdMode = import.meta.env.PROD;
|
// @ts-ignore
|
||||||
|
export const currentEnv = __APP_ENV__;
|
||||||
|
|
||||||
|
export const isDevMode = import.meta.env.MODE === devMode;
|
||||||
|
export const isProdMode = import.meta.env.MODE === prodMode;
|
||||||
|
export const isStagingMode = import.meta.env.MODE === stagingMode;
|
||||||
|
|
||||||
|
export const Y_CODE_RENDERER_URL = currentEnv.Y_CODE_RENDERER_URL;
|
||||||
|
export const Y_CODE_DESIGNER_URL = currentEnv.Y_CODE_DESIGNER_URL;
|
||||||
|
export const Y_CODE_PLATFORM_URL = currentEnv.Y_CODE_PLATFORM_URL;
|
||||||
|
export const Y_CODE_V1_URL = currentEnv.Y_CODE_V1_URL;
|
||||||
|
@ -1 +1,3 @@
|
|||||||
export * from '@sy/low-code-shared/constants';
|
// export * from '@sy/low-code-shared/constants';
|
||||||
|
export * from './env';
|
||||||
|
export * from './low-code';
|
||||||
|
2
apps/platform/src/constants/low-code.ts
Normal file
2
apps/platform/src/constants/low-code.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export const LOW_CODE_APPLICATION_ID = 0;
|
||||||
|
export const LOW_CODE_PROJECT_ID = 4;
|
16
apps/platform/src/io/file.ts
Normal file
16
apps/platform/src/io/file.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import instance from './instance';
|
||||||
|
|
||||||
|
export const uploadFile = async (data: FormData) => {
|
||||||
|
const response = await instance.post('/api/v1/files/upload', data);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteFile = async (id: string) => {
|
||||||
|
const response = await instance.delete(`/api/v1/files/upload/${id}`);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getFileList = async () => {
|
||||||
|
const response = await instance.get('/api/v1/files/upload');
|
||||||
|
return response.data;
|
||||||
|
};
|
@ -1,41 +1,41 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
// import { useUserStore } from '@/store/modules/user';
|
||||||
|
// import router from '@/router';
|
||||||
|
import appClient from '@/io/tianti';
|
||||||
import { useUserStore } from '@/store/modules/user';
|
import { useUserStore } from '@/store/modules/user';
|
||||||
import router from '@/router';
|
|
||||||
|
// axios拦截器
|
||||||
|
const { reqInterceptor, resInterceptor } = appClient.getInterceptor();
|
||||||
|
|
||||||
const baseApiUrl = import.meta.env.VITE_BASE_API_URL;
|
const baseApiUrl = import.meta.env.VITE_BASE_API_URL;
|
||||||
|
|
||||||
// 创建独立实例
|
// 创建独立实例
|
||||||
const instance = axios.create({
|
const instance = axios.create({
|
||||||
baseURL: baseApiUrl, // 基础URL直接放在实例配置中
|
baseURL: baseApiUrl,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 请求拦截器改为使用实例
|
|
||||||
instance.interceptors.request.use(
|
instance.interceptors.request.use(
|
||||||
(config) => {
|
(config) => config,
|
||||||
// 可在此处添加统一请求头等配置
|
(error) => Promise.reject(error),
|
||||||
return config;
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
return Promise.reject(error);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
instance.interceptors.request.use(reqInterceptor.fulfilled, reqInterceptor.rejected);
|
||||||
|
|
||||||
// 响应拦截器改为使用实例
|
// 响应拦截器
|
||||||
instance.interceptors.response.use(
|
instance.interceptors.response.use(
|
||||||
(response) => {
|
(response) => {
|
||||||
// 如果响应数据中 code 为 -1,清空登录状态并跳转到登录页
|
// 检查是否为401未授权错误
|
||||||
if (response?.data?.code === -1) {
|
if (response.data.code === 401) {
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
userStore.clearLoginStatus(); // 清空用户信息
|
console.log('用户未授权或登录已过期,即将跳转...');
|
||||||
router.push('/login'); // 直接使用路由实例
|
// userStore.logout();
|
||||||
console.error('请求失败:', response.data.msg);
|
// 返回一个永远不会resolve的Promise,防止后续代码执行
|
||||||
|
return new Promise(() => {});
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => Promise.reject(error),
|
||||||
return Promise.reject(error);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
instance.interceptors.response.use(resInterceptor.fulfilled, resInterceptor.rejected);
|
||||||
|
|
||||||
// 导出实例
|
// 导出实例
|
||||||
export default instance;
|
export default instance;
|
||||||
|
12
apps/platform/src/io/tianti.ts
Normal file
12
apps/platform/src/io/tianti.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// @ts-ignore
|
||||||
|
import AxiosAppClient from '@sy/unified-login/es/app-client/axios';
|
||||||
|
|
||||||
|
export type Env = 'dev' | 'test' | 'pre' | 'prod';
|
||||||
|
|
||||||
|
const appClient = new AxiosAppClient({
|
||||||
|
appKey: 'y-code', // 应用标识,不同项目不能一样
|
||||||
|
env: 'prod', // dev:本地开发;test:测试;pre:预发布;prod:正式
|
||||||
|
devBaseUrl: `https://localhost:${import.meta.env.VITE_PORT}`, // 应用开发环境地址
|
||||||
|
});
|
||||||
|
|
||||||
|
export default appClient;
|
@ -9,3 +9,102 @@ export const logout = async () => {
|
|||||||
const response = await instance.post('/logout');
|
const response = await instance.post('/logout');
|
||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息接口
|
||||||
|
*/
|
||||||
|
export interface UserInfo {
|
||||||
|
/** 用户ID */
|
||||||
|
UserID: number;
|
||||||
|
/** 用户名 */
|
||||||
|
Username: string;
|
||||||
|
/** 头像URL */
|
||||||
|
Avatar: string;
|
||||||
|
/** 用户别名/真实姓名 */
|
||||||
|
Alias: string;
|
||||||
|
/** 创建时间 */
|
||||||
|
CreatedAt: string;
|
||||||
|
/** 更新时间 */
|
||||||
|
UpdatedAt: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前登录用户信息
|
||||||
|
*
|
||||||
|
* @returns {Promise<{code: number, data: UserInfo, message: string}>} 返回包含用户信息的响应对象
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* const userInfo = await getCurrentUser();
|
||||||
|
* console.log(userInfo.data.Username); // 输出当前用户名
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export const getCurrentUser = async () => {
|
||||||
|
const response = await instance.get('/api/v1/users/current');
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定用户信息
|
||||||
|
*
|
||||||
|
* @param {number|string} id 用户ID
|
||||||
|
* @returns {Promise<{code: number, data: UserInfo, message: string}>} 返回包含用户信息的响应对象
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* // 获取ID为2594的用户信息
|
||||||
|
* const userInfo = await getUserById(2594);
|
||||||
|
* console.log(userInfo.data.Username); // 输出用户名
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export const getUserById = async (id: number | string) => {
|
||||||
|
const response = await instance.get(`/api/v1/users/${id}`);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户列表项接口
|
||||||
|
*/
|
||||||
|
export interface UserListItem {
|
||||||
|
/** 用户ID */
|
||||||
|
user_id: number;
|
||||||
|
/** 用户名 */
|
||||||
|
username: string;
|
||||||
|
/** 头像URL */
|
||||||
|
avatar: string;
|
||||||
|
/** 用户别名/真实姓名 */
|
||||||
|
alias: string;
|
||||||
|
/** 创建时间 */
|
||||||
|
created_at: string;
|
||||||
|
/** 更新时间 */
|
||||||
|
updated_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户列表查询参数
|
||||||
|
*/
|
||||||
|
export interface UserListParams {
|
||||||
|
/** 页码,默认1 */
|
||||||
|
page?: number | string;
|
||||||
|
/** 每页数量,默认20 */
|
||||||
|
per_page?: number | string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户列表
|
||||||
|
*
|
||||||
|
* @param {UserListParams} params 查询参数,包含页码和每页数量
|
||||||
|
* @returns {Promise<{code: number, data: {list: UserListItem[], total: number}, message: string}>} 返回包含用户列表的响应对象
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* // 获取第1页,每页20条记录
|
||||||
|
* const result = await getUserList({ page: 1, per_page: 20 });
|
||||||
|
* console.log(`总用户数: ${result.data.total}`);
|
||||||
|
* console.log(`第一个用户: ${result.data.list[0].username}`);
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export const getUserList = async (params: UserListParams = {}) => {
|
||||||
|
const response = await instance.get('/api/v1/users', { params });
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
@ -33,10 +33,15 @@
|
|||||||
</Menu.Item> -->
|
</Menu.Item> -->
|
||||||
<Menu.Divider />
|
<Menu.Divider />
|
||||||
<Menu.Item>
|
<Menu.Item>
|
||||||
<div @click.prevent="doLogout">
|
<div @click.prevent="tianti.logout">
|
||||||
<poweroff-outlined /> {{ $t('layout.header.dropdownItemLoginOut') }}
|
<poweroff-outlined /> {{ $t('layout.header.dropdownItemLoginOut') }}
|
||||||
</div>
|
</div>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
|
<Menu.Item v-if="isDevEnv">
|
||||||
|
<div @click.prevent="tianti.openDev">
|
||||||
|
{{ $t('layout.header.openDev') }}
|
||||||
|
</div>
|
||||||
|
</Menu.Item>
|
||||||
</Menu>
|
</Menu>
|
||||||
</template>
|
</template>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
@ -49,6 +54,8 @@
|
|||||||
<script lang="tsx" setup>
|
<script lang="tsx" setup>
|
||||||
import { computed, type CSSProperties } from 'vue';
|
import { computed, type CSSProperties } from 'vue';
|
||||||
import { useRouter, useRoute } from 'vue-router';
|
import { useRouter, useRoute } from 'vue-router';
|
||||||
|
import tianti from '@/io/tianti';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
QuestionCircleOutlined,
|
QuestionCircleOutlined,
|
||||||
MenuFoldOutlined,
|
MenuFoldOutlined,
|
||||||
@ -71,6 +78,8 @@
|
|||||||
import { LOGIN_NAME } from '@/router/constant';
|
import { LOGIN_NAME } from '@/router/constant';
|
||||||
import { useLayoutSettingStore } from '@/store/modules/layoutSetting';
|
import { useLayoutSettingStore } from '@/store/modules/layoutSetting';
|
||||||
|
|
||||||
|
const isDevEnv = import.meta.env.VITE_NODE_ENV === 'development';
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
collapsed: {
|
collapsed: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"footer": { "onlinePreview": "在线预览", "onlineDocument": "在线文档" },
|
"footer": {
|
||||||
|
"onlinePreview": "在线预览",
|
||||||
|
"onlineDocument": "在线文档"
|
||||||
|
},
|
||||||
"header": {
|
"header": {
|
||||||
"dropdownItemDoc": "文档",
|
"dropdownItemDoc": "文档",
|
||||||
"dropdownItemLoginOut": "退出系统",
|
"dropdownItemLoginOut": "退出系统",
|
||||||
|
"openDev": "打开开发环境",
|
||||||
"tooltipErrorLog": "错误日志",
|
"tooltipErrorLog": "错误日志",
|
||||||
"tooltipLock": "锁定屏幕",
|
"tooltipLock": "锁定屏幕",
|
||||||
"tooltipNotify": "消息通知",
|
"tooltipNotify": "消息通知",
|
||||||
|
|
||||||
"tooltipEntryFull": "全屏",
|
"tooltipEntryFull": "全屏",
|
||||||
"tooltipExitFull": "退出全屏",
|
"tooltipExitFull": "退出全屏",
|
||||||
|
|
||||||
"lockScreenPassword": "锁屏密码",
|
"lockScreenPassword": "锁屏密码",
|
||||||
"lockScreen": "锁定屏幕",
|
"lockScreen": "锁定屏幕",
|
||||||
"lockScreenBtn": "锁定",
|
"lockScreenBtn": "锁定",
|
||||||
|
|
||||||
"home": "首页"
|
"home": "首页"
|
||||||
},
|
},
|
||||||
"multipleTab": {
|
"multipleTab": {
|
||||||
@ -38,20 +38,15 @@
|
|||||||
"menuTypeMixSidebar": "左侧菜单混合模式",
|
"menuTypeMixSidebar": "左侧菜单混合模式",
|
||||||
"menuTypeMix": "顶部菜单混合模式",
|
"menuTypeMix": "顶部菜单混合模式",
|
||||||
"menuTypeTopMenu": "顶部菜单模式",
|
"menuTypeTopMenu": "顶部菜单模式",
|
||||||
|
|
||||||
"on": "开",
|
"on": "开",
|
||||||
"off": "关",
|
"off": "关",
|
||||||
"minute": "分钟",
|
"minute": "分钟",
|
||||||
|
|
||||||
"operatingTitle": "操作成功",
|
"operatingTitle": "操作成功",
|
||||||
"operatingContent": "复制成功,请到 src/settings/projectSetting.ts 中修改配置!",
|
"operatingContent": "复制成功,请到 src/settings/projectSetting.ts 中修改配置!",
|
||||||
"resetSuccess": "重置成功!",
|
"resetSuccess": "重置成功!",
|
||||||
|
|
||||||
"copyBtn": "拷贝",
|
"copyBtn": "拷贝",
|
||||||
"clearBtn": "清空缓存并返回登录页",
|
"clearBtn": "清空缓存并返回登录页",
|
||||||
|
|
||||||
"drawerTitle": "项目配置",
|
"drawerTitle": "项目配置",
|
||||||
|
|
||||||
"darkMode": "主题",
|
"darkMode": "主题",
|
||||||
"navMode": "导航栏模式",
|
"navMode": "导航栏模式",
|
||||||
"interfaceFunction": "界面功能",
|
"interfaceFunction": "界面功能",
|
||||||
@ -59,11 +54,9 @@
|
|||||||
"animation": "动画",
|
"animation": "动画",
|
||||||
"splitMenu": "分割菜单",
|
"splitMenu": "分割菜单",
|
||||||
"closeMixSidebarOnChange": "切换页面关闭菜单",
|
"closeMixSidebarOnChange": "切换页面关闭菜单",
|
||||||
|
|
||||||
"sysTheme": "系统主题",
|
"sysTheme": "系统主题",
|
||||||
"headerTheme": "顶栏主题",
|
"headerTheme": "顶栏主题",
|
||||||
"sidebarTheme": "菜单主题",
|
"sidebarTheme": "菜单主题",
|
||||||
|
|
||||||
"menuDrag": "侧边菜单拖拽",
|
"menuDrag": "侧边菜单拖拽",
|
||||||
"menuSearch": "菜单搜索",
|
"menuSearch": "菜单搜索",
|
||||||
"menuAccordion": "侧边菜单手风琴模式",
|
"menuAccordion": "侧边菜单手风琴模式",
|
||||||
@ -73,7 +66,6 @@
|
|||||||
"menuCollapseButton": "菜单折叠按钮",
|
"menuCollapseButton": "菜单折叠按钮",
|
||||||
"contentMode": "内容区域宽度",
|
"contentMode": "内容区域宽度",
|
||||||
"expandedMenuWidth": "菜单展开宽度",
|
"expandedMenuWidth": "菜单展开宽度",
|
||||||
|
|
||||||
"breadcrumb": "面包屑",
|
"breadcrumb": "面包屑",
|
||||||
"breadcrumbIcon": "面包屑图标",
|
"breadcrumbIcon": "面包屑图标",
|
||||||
"tabs": "标签页",
|
"tabs": "标签页",
|
||||||
@ -87,22 +79,17 @@
|
|||||||
"fullContent": "全屏内容",
|
"fullContent": "全屏内容",
|
||||||
"grayMode": "灰色模式",
|
"grayMode": "灰色模式",
|
||||||
"colorWeak": "色弱模式",
|
"colorWeak": "色弱模式",
|
||||||
|
|
||||||
"progress": "顶部进度条",
|
"progress": "顶部进度条",
|
||||||
"switchLoading": "切换loading",
|
"switchLoading": "切换loading",
|
||||||
"switchAnimation": "切换动画",
|
"switchAnimation": "切换动画",
|
||||||
"animationType": "动画类型",
|
"animationType": "动画类型",
|
||||||
|
|
||||||
"autoScreenLock": "自动锁屏",
|
"autoScreenLock": "自动锁屏",
|
||||||
"notAutoScreenLock": "不自动锁屏",
|
"notAutoScreenLock": "不自动锁屏",
|
||||||
|
|
||||||
"fixedHeader": "固定header",
|
"fixedHeader": "固定header",
|
||||||
"fixedSideBar": "固定Sidebar",
|
"fixedSideBar": "固定Sidebar",
|
||||||
|
|
||||||
"mixSidebarTrigger": "混合菜单触发方式",
|
"mixSidebarTrigger": "混合菜单触发方式",
|
||||||
"triggerHover": "悬停",
|
"triggerHover": "悬停",
|
||||||
"triggerClick": "点击",
|
"triggerClick": "点击",
|
||||||
|
|
||||||
"mixSidebarFixed": "固定展开菜单"
|
"mixSidebarFixed": "固定展开菜单"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,6 +20,7 @@ dayjs.extend(timezone);
|
|||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
|
|
||||||
app.use(VueQueryPlugin);
|
app.use(VueQueryPlugin);
|
||||||
|
|
||||||
function setupPlugins() {
|
function setupPlugins() {
|
||||||
// 安装图标
|
// 安装图标
|
||||||
setupIcons();
|
setupIcons();
|
||||||
|
41
apps/platform/src/router/routes/modules/acl.ts
Normal file
41
apps/platform/src/router/routes/modules/acl.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import type { RouteRecordRaw } from 'vue-router';
|
||||||
|
import { Y_CODE_RENDERER_URL } from '@/constants';
|
||||||
|
import { LOW_CODE_APPLICATION_ID, LOW_CODE_PROJECT_ID } from '@/constants/low-code';
|
||||||
|
|
||||||
|
const moduleName = 'acl';
|
||||||
|
|
||||||
|
const routes: Array<RouteRecordRaw> = [
|
||||||
|
{
|
||||||
|
path: '/acl',
|
||||||
|
name: moduleName,
|
||||||
|
redirect: '/acl/list',
|
||||||
|
meta: {
|
||||||
|
title: '权限管理',
|
||||||
|
icon: 'ant-design:user-outlined',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'list',
|
||||||
|
name: `${moduleName}-list`,
|
||||||
|
meta: {
|
||||||
|
title: '权限列表',
|
||||||
|
keepAlive: true,
|
||||||
|
icon: 'ant-design:list',
|
||||||
|
app: {
|
||||||
|
url: Y_CODE_RENDERER_URL,
|
||||||
|
name: 'y-code-platform-project-list',
|
||||||
|
// sync: true,
|
||||||
|
// alive: true,
|
||||||
|
// degrade: true,
|
||||||
|
applicationId: LOW_CODE_APPLICATION_ID,
|
||||||
|
projectId: LOW_CODE_PROJECT_ID,
|
||||||
|
fileId: '1hsd0407hf',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
component: () => import('@/components/renderer-adapter/index.vue'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default routes;
|
@ -1,4 +1,5 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router';
|
import type { RouteRecordRaw } from 'vue-router';
|
||||||
|
import { Y_CODE_RENDERER_URL } from '@/constants';
|
||||||
|
|
||||||
// 微前端路由
|
// 微前端路由
|
||||||
const moduleName = 'application';
|
const moduleName = 'application';
|
||||||
@ -20,11 +21,11 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
icon: 'ant-design:list',
|
icon: 'ant-design:list',
|
||||||
app: {
|
app: {
|
||||||
url: 'https://localhost:10010',
|
url: Y_CODE_RENDERER_URL,
|
||||||
name: 'y-code-platform-application-list',
|
name: 'y-code-platform-application-list',
|
||||||
sync: true,
|
// sync: true,
|
||||||
alive: true,
|
// alive: true,
|
||||||
degrade: true,
|
// degrade: true,
|
||||||
applicationId: 0,
|
applicationId: 0,
|
||||||
projectId: 4,
|
projectId: 4,
|
||||||
fileId: 'b91n1y9yr',
|
fileId: 'b91n1y9yr',
|
||||||
|
@ -4,4 +4,5 @@ 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';
|
import staticFile from './static-file';
|
||||||
export default [...dashboard, ...user, ...micro, ...application, ...project, ...staticFile];
|
import acl from './acl';
|
||||||
|
export default [...dashboard, ...user, ...micro, ...application, ...project, ...staticFile, ...acl];
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router';
|
import type { RouteRecordRaw } from 'vue-router';
|
||||||
|
import { Y_CODE_DESIGNER_URL, Y_CODE_V1_URL } from '@/constants';
|
||||||
|
|
||||||
// 微前端路由
|
|
||||||
const moduleName = 'micro';
|
const moduleName = 'micro';
|
||||||
|
|
||||||
const routes: Array<RouteRecordRaw> = [
|
const routes: Array<RouteRecordRaw> = [
|
||||||
@ -17,52 +17,36 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
name: `${moduleName}-designer`,
|
name: `${moduleName}-designer`,
|
||||||
meta: {
|
meta: {
|
||||||
title: '低代码编辑器',
|
title: '低代码编辑器',
|
||||||
|
keepAlive: true,
|
||||||
icon: 'ant-design:edit-outlined',
|
icon: 'ant-design:edit-outlined',
|
||||||
app: {
|
app: {
|
||||||
url: 'https://localhost:10011',
|
url: Y_CODE_DESIGNER_URL,
|
||||||
name: 'y-code-designer',
|
name: 'y-code-designer',
|
||||||
// sync: true,
|
projectId: 4,
|
||||||
// alive: true,
|
sync: true,
|
||||||
// degrade: true,
|
alive: true,
|
||||||
},
|
|
||||||
},
|
|
||||||
component: () => import('@/components/micro-container/index.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'renderer',
|
|
||||||
name: `${moduleName}-renderer`,
|
|
||||||
meta: {
|
|
||||||
title: '低代码渲染器',
|
|
||||||
keepAlive: true,
|
|
||||||
// hideInMenu: true,
|
|
||||||
icon: 'ant-design:eye-outlined',
|
|
||||||
app: {
|
|
||||||
url: 'https://localhost:10010',
|
|
||||||
name: 'y-code-renderer',
|
|
||||||
// sync: true,
|
|
||||||
// alive: true,
|
|
||||||
degrade: true,
|
degrade: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
component: () => import('@/components/micro-container/index.vue'),
|
component: () => import('@/components/renderer-adapter/index.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'y-code-v1',
|
path: 'y-code-v1',
|
||||||
name: `${moduleName}-y-code-v1`,
|
name: `${moduleName}-y-code-v1`,
|
||||||
meta: {
|
meta: {
|
||||||
title: '悦码 1.0',
|
title: '悦码 1.0',
|
||||||
// keepAlive: true,
|
keepAlive: true,
|
||||||
// hideInMenu: true,
|
// hideInMenu: true,
|
||||||
icon: 'ant-design:delete-outlined',
|
icon: 'ant-design:delete-outlined',
|
||||||
app: {
|
app: {
|
||||||
url: 'http://localhost:10012',
|
url: Y_CODE_V1_URL,
|
||||||
name: 'y-code-v1',
|
name: 'y-code-v1',
|
||||||
// sync: true,
|
// sync: true,
|
||||||
// alive: true,
|
// alive: true,
|
||||||
degrade: true,
|
degrade: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
component: () => import('@/components/micro-container/index.vue'),
|
component: () => import('@/components/renderer-adapter/index.vue'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router';
|
import type { RouteRecordRaw } from 'vue-router';
|
||||||
|
import { Y_CODE_RENDERER_URL } from '@/constants';
|
||||||
|
import { LOW_CODE_APPLICATION_ID, LOW_CODE_PROJECT_ID } from '@/constants/low-code';
|
||||||
|
|
||||||
// 微前端路由
|
// 微前端路由
|
||||||
const moduleName = 'project';
|
const moduleName = 'project';
|
||||||
@ -20,18 +22,38 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
icon: 'ant-design:list',
|
icon: 'ant-design:list',
|
||||||
app: {
|
app: {
|
||||||
url: 'https://localhost:10010',
|
url: Y_CODE_RENDERER_URL,
|
||||||
name: 'y-code-platform-project-list',
|
name: 'y-code-platform-project-list',
|
||||||
// sync: true,
|
// sync: true,
|
||||||
// alive: true,
|
// alive: true,
|
||||||
// degrade: true,
|
// degrade: true,
|
||||||
applicationId: 0,
|
applicationId: LOW_CODE_APPLICATION_ID,
|
||||||
projectId: 4,
|
projectId: LOW_CODE_PROJECT_ID,
|
||||||
fileId: '4g4mz6qi8u',
|
fileId: '4g4mz6qi8u',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
component: () => import('@/components/renderer-adapter/index.vue'),
|
component: () => import('@/components/renderer-adapter/index.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'file',
|
||||||
|
name: `${moduleName}-file`,
|
||||||
|
meta: {
|
||||||
|
title: 'dsl 文件列表',
|
||||||
|
keepAlive: true,
|
||||||
|
icon: 'ant-design:file',
|
||||||
|
app: {
|
||||||
|
url: Y_CODE_RENDERER_URL,
|
||||||
|
name: 'y-code-platform-project-file',
|
||||||
|
// sync: true,
|
||||||
|
// alive: true,
|
||||||
|
// degrade: true,
|
||||||
|
applicationId: LOW_CODE_APPLICATION_ID,
|
||||||
|
projectId: LOW_CODE_PROJECT_ID,
|
||||||
|
fileId: '7pftwojzu',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
component: () => import('@/components/renderer-adapter/index.vue'),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router';
|
import type { RouteRecordRaw } from 'vue-router';
|
||||||
|
import { Y_CODE_RENDERER_URL } from '@/constants';
|
||||||
|
import { LOW_CODE_APPLICATION_ID, LOW_CODE_PROJECT_ID } from '@/constants/low-code';
|
||||||
|
|
||||||
// 微前端路由
|
// 微前端路由
|
||||||
const moduleName = 'static-file';
|
const moduleName = 'static-file';
|
||||||
@ -9,7 +11,7 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
name: moduleName,
|
name: moduleName,
|
||||||
meta: {
|
meta: {
|
||||||
title: '静态文件管理',
|
title: '静态文件管理',
|
||||||
icon: 'ant-design:file-outlined',
|
icon: 'ant-design:file',
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
@ -18,13 +20,13 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
meta: {
|
meta: {
|
||||||
title: '静态文件列表',
|
title: '静态文件列表',
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
icon: 'ant-design:list',
|
icon: 'ant-design:file',
|
||||||
app: {
|
app: {
|
||||||
url: 'https://localhost:10010',
|
url: Y_CODE_RENDERER_URL,
|
||||||
name: 'y-code-platform-application-list',
|
name: 'y-code-platform-application-list',
|
||||||
sync: true,
|
applicationId: LOW_CODE_APPLICATION_ID,
|
||||||
alive: true,
|
projectId: LOW_CODE_PROJECT_ID,
|
||||||
degrade: true,
|
fileId: '7pfr394d6',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
component: () => import('@/components/renderer-adapter/index.vue'),
|
component: () => import('@/components/renderer-adapter/index.vue'),
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router';
|
import type { RouteRecordRaw } from 'vue-router';
|
||||||
|
import { Y_CODE_RENDERER_URL } from '@/constants';
|
||||||
|
import { LOW_CODE_APPLICATION_ID, LOW_CODE_PROJECT_ID } from '@/constants/low-code';
|
||||||
|
|
||||||
const moduleName = 'user';
|
const moduleName = 'user';
|
||||||
|
|
||||||
@ -17,55 +19,20 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
name: `${moduleName}-list`,
|
name: `${moduleName}-list`,
|
||||||
meta: {
|
meta: {
|
||||||
title: '用户列表',
|
title: '用户列表',
|
||||||
icon: 'ant-design:unordered-list-outlined',
|
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
hideInMenu: false,
|
icon: 'ant-design:list',
|
||||||
|
app: {
|
||||||
|
url: Y_CODE_RENDERER_URL,
|
||||||
|
name: 'y-code-platform-project-list',
|
||||||
|
// sync: true,
|
||||||
|
// alive: true,
|
||||||
|
// degrade: true,
|
||||||
|
applicationId: LOW_CODE_APPLICATION_ID,
|
||||||
|
projectId: LOW_CODE_PROJECT_ID,
|
||||||
|
fileId: 'b91ra0ej4',
|
||||||
},
|
},
|
||||||
component: () => import('@/views/user/list.vue'),
|
|
||||||
},
|
},
|
||||||
{
|
component: () => import('@/components/renderer-adapter/index.vue'),
|
||||||
path: 'add',
|
|
||||||
name: `${moduleName}-add`,
|
|
||||||
meta: {
|
|
||||||
title: '新增用户',
|
|
||||||
icon: 'ant-design:user-add-outlined',
|
|
||||||
hideInMenu: true,
|
|
||||||
activeMenu: `${moduleName}-list`,
|
|
||||||
},
|
|
||||||
component: () => import('@/views/user/add.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'edit/:id',
|
|
||||||
name: `${moduleName}-edit`,
|
|
||||||
meta: {
|
|
||||||
title: '编辑用户',
|
|
||||||
icon: 'ant-design:edit-outlined',
|
|
||||||
hideInMenu: true,
|
|
||||||
activeMenu: `${moduleName}-list`,
|
|
||||||
},
|
|
||||||
component: () => import('@/views/user/edit.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'detail/:id',
|
|
||||||
name: `${moduleName}-detail`,
|
|
||||||
meta: {
|
|
||||||
title: '用户详情',
|
|
||||||
icon: 'ant-design:profile-outlined',
|
|
||||||
hideInMenu: true,
|
|
||||||
activeMenu: `${moduleName}-list`,
|
|
||||||
},
|
|
||||||
component: () => import('@/views/user/detail.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'change-password/:id',
|
|
||||||
name: `${moduleName}-change-password`,
|
|
||||||
meta: {
|
|
||||||
title: '修改密码',
|
|
||||||
icon: 'ant-design:lock-outlined',
|
|
||||||
hideInMenu: true,
|
|
||||||
activeMenu: `${moduleName}-list`,
|
|
||||||
},
|
|
||||||
component: () => import('@/views/user/change-password.vue'),
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router';
|
// import type { RouteRecordRaw } from 'vue-router';
|
||||||
import { LOGIN_NAME } from '@/router/constant';
|
// import { LOGIN_NAME } from '@/router/constant';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* layout布局之外的路由
|
* layout布局之外的路由
|
||||||
*/
|
*/
|
||||||
export const LoginRoute: RouteRecordRaw = {
|
// export const LoginRoute: RouteRecordRaw = {
|
||||||
path: '/login',
|
// path: '/login',
|
||||||
name: LOGIN_NAME,
|
// name: LOGIN_NAME,
|
||||||
component: () => import('@/views/login/index.vue'),
|
// component: () => import('@/views/login/index.vue'),
|
||||||
meta: {
|
// meta: {
|
||||||
title: '登录',
|
// title: '登录',
|
||||||
},
|
// },
|
||||||
};
|
// };
|
||||||
|
|
||||||
export default [LoginRoute];
|
export default [];
|
||||||
|
0
apps/platform/src/store/modules/application.ts
Normal file
0
apps/platform/src/store/modules/application.ts
Normal file
@ -5,8 +5,7 @@ interface KeepAliveState {
|
|||||||
list: string[];
|
list: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useKeepAliveStore = defineStore({
|
export const useKeepAliveStore = defineStore('keep-alive', {
|
||||||
id: 'keep-alive',
|
|
||||||
state: (): KeepAliveState => ({
|
state: (): KeepAliveState => ({
|
||||||
list: [],
|
list: [],
|
||||||
}),
|
}),
|
||||||
|
0
apps/platform/src/store/modules/project.ts
Normal file
0
apps/platform/src/store/modules/project.ts
Normal file
@ -3,7 +3,8 @@ import { defineStore } from 'pinia';
|
|||||||
import { useSSEStore } from './sse';
|
import { useSSEStore } from './sse';
|
||||||
import { store } from '@/store';
|
import { store } from '@/store';
|
||||||
import { resetRouter } from '@/router';
|
import { resetRouter } from '@/router';
|
||||||
import { login, logout } from '@/io';
|
import tianti from '@/io/tianti';
|
||||||
|
import { getCurrentUser } from '@/io/user';
|
||||||
|
|
||||||
export const useUserStore = defineStore(
|
export const useUserStore = defineStore(
|
||||||
'user',
|
'user',
|
||||||
@ -13,6 +14,10 @@ export const useUserStore = defineStore(
|
|||||||
const perms = ref<string[]>([]);
|
const perms = ref<string[]>([]);
|
||||||
const userInfo = ref<Partial<API.UserEntity>>({});
|
const userInfo = ref<Partial<API.UserEntity>>({});
|
||||||
|
|
||||||
|
const setToken = (_token: string) => {
|
||||||
|
token.value = _token;
|
||||||
|
};
|
||||||
|
|
||||||
/** 清空登录态(token、userInfo...) */
|
/** 清空登录态(token、userInfo...) */
|
||||||
const clearLoginStatus = () => {
|
const clearLoginStatus = () => {
|
||||||
token.value = '';
|
token.value = '';
|
||||||
@ -23,21 +28,24 @@ export const useUserStore = defineStore(
|
|||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
/** 登录成功保存token */
|
|
||||||
const setToken = (_token: string) => {
|
|
||||||
token.value = _token;
|
|
||||||
};
|
|
||||||
/** 登录 */
|
/** 登录 */
|
||||||
const login = async (params: any) => {
|
const login = async () => {
|
||||||
const data = await login(params);
|
tianti.checkQuery();
|
||||||
console.log('data', data);
|
const token = localStorage.getItem('y-code-access-token');
|
||||||
// @ts-ignore
|
if (token) {
|
||||||
setToken(data.msg);
|
setToken(token);
|
||||||
|
setTimeout(() => {
|
||||||
|
getCurrentUser().then((res) => {
|
||||||
|
userInfo.value = res.data.data;
|
||||||
|
console.log('userInfo', userInfo.value);
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
/** 登出 */
|
/** 登出 */
|
||||||
const logout = async () => {
|
const logout = async () => {
|
||||||
sseStore.closeEventSource();
|
sseStore.closeEventSource();
|
||||||
await logout();
|
await tianti.logout();
|
||||||
clearLoginStatus();
|
clearLoginStatus();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
28
apps/platform/src/views/error/403.vue
Normal file
28
apps/platform/src/views/error/403.vue
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<script lang="jsx">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import OneClickAuth from '@sy/unified-login/one-click-auth.vue';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'ForbiddenPage',
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
return () => {
|
||||||
|
return (
|
||||||
|
<div class="forbidden-page">
|
||||||
|
<OneClickAuth env="dev" appMark={30} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.forbidden-page {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,44 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>1</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts"></script>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.login-box {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
width: 100vw;
|
|
||||||
height: 100vh;
|
|
||||||
padding-top: 240px;
|
|
||||||
background: url('@/assets/login.svg');
|
|
||||||
background-size: 100%;
|
|
||||||
|
|
||||||
.login-logo {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
|
|
||||||
.svg-icon {
|
|
||||||
font-size: 48px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.ant-form) {
|
|
||||||
width: 400px;
|
|
||||||
|
|
||||||
.ant-col {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-form-item-label {
|
|
||||||
padding-right: 6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-type-switch {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,60 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="add-user">
|
|
||||||
<a-card :bordered="false">
|
|
||||||
<a-form layout="vertical" :model="userForm" @submit="handleAddUser">
|
|
||||||
<a-form-item label="用户名">
|
|
||||||
<a-input
|
|
||||||
v-model:value="userForm.username"
|
|
||||||
placeholder="请输入用户名"
|
|
||||||
allow-clear
|
|
||||||
style="max-width: 400px"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="密码">
|
|
||||||
<a-input
|
|
||||||
v-model:value="userForm.password"
|
|
||||||
placeholder="请输入密码"
|
|
||||||
type="password"
|
|
||||||
allow-clear
|
|
||||||
style="max-width: 400px"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item>
|
|
||||||
<a-space>
|
|
||||||
<a-button type="primary" html-type="submit">新增用户</a-button>
|
|
||||||
<a-button @click="goBack">取消</a-button>
|
|
||||||
</a-space>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
</a-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
|
||||||
import { message } from 'ant-design-vue';
|
|
||||||
import { useTabsViewStore } from '@/store/modules/tabsView';
|
|
||||||
const { closeCurrentTab } = useTabsViewStore();
|
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const route = useRoute();
|
|
||||||
|
|
||||||
// 用户表单数据
|
|
||||||
const userForm = reactive({
|
|
||||||
username: '',
|
|
||||||
password: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 新增用户
|
|
||||||
const handleAddUser = async () => {
|
|
||||||
// TODO: 调用新增用户接口
|
|
||||||
message.success('用户新增成功');
|
|
||||||
goBack();
|
|
||||||
};
|
|
||||||
|
|
||||||
const goBack = () => {
|
|
||||||
router.back();
|
|
||||||
closeCurrentTab(route);
|
|
||||||
};
|
|
||||||
</script>
|
|
@ -1,66 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="change-password">
|
|
||||||
<a-card :bordered="false">
|
|
||||||
<a-form layout="vertical" :model="passwordForm" @submit="handleChangePassword">
|
|
||||||
<a-form-item label="新密码">
|
|
||||||
<a-input
|
|
||||||
v-model:value="passwordForm.newPassword"
|
|
||||||
placeholder="请输入新密码"
|
|
||||||
type="password"
|
|
||||||
allow-clear
|
|
||||||
style="max-width: 400px"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="确认密码">
|
|
||||||
<a-input
|
|
||||||
v-model:value="passwordForm.confirmPassword"
|
|
||||||
placeholder="请确认新密码"
|
|
||||||
type="password"
|
|
||||||
allow-clear
|
|
||||||
style="max-width: 400px"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item>
|
|
||||||
<a-space>
|
|
||||||
<a-button type="primary" html-type="submit">修改密码</a-button>
|
|
||||||
<a-button type="default" @click="goBack">取消</a-button>
|
|
||||||
</a-space>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
</a-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
|
||||||
import { message } from 'ant-design-vue';
|
|
||||||
import { useTabsViewStore } from '@/store/modules/tabsView';
|
|
||||||
const { closeCurrentTab } = useTabsViewStore();
|
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
console.log('router', router);
|
|
||||||
const route = useRoute();
|
|
||||||
|
|
||||||
// 密码表单数据
|
|
||||||
const passwordForm = reactive({
|
|
||||||
newPassword: '',
|
|
||||||
confirmPassword: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 修改密码
|
|
||||||
const handleChangePassword = async () => {
|
|
||||||
if (passwordForm.newPassword !== passwordForm.confirmPassword) {
|
|
||||||
message.error('两次输入的密码不一致');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// TODO: 调用修改密码接口
|
|
||||||
message.success('密码修改成功');
|
|
||||||
goBack();
|
|
||||||
};
|
|
||||||
|
|
||||||
const goBack = () => {
|
|
||||||
router.back();
|
|
||||||
closeCurrentTab(route);
|
|
||||||
};
|
|
||||||
</script>
|
|
@ -1,94 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="user-detail">
|
|
||||||
<a-card title="用户详情" :bordered="false">
|
|
||||||
<!-- 基本信息 -->
|
|
||||||
<a-descriptions bordered>
|
|
||||||
<a-descriptions-item label="用户名">
|
|
||||||
{{ userInfo.username }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="昵称">
|
|
||||||
{{ userInfo.nickname }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="手机号">
|
|
||||||
{{ userInfo.phone }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="邮箱">
|
|
||||||
{{ userInfo.email }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="状态">
|
|
||||||
<a-tag :color="userInfo.status === 1 ? 'green' : 'red'">
|
|
||||||
{{ userInfo.status === 1 ? '启用' : '禁用' }}
|
|
||||||
</a-tag>
|
|
||||||
</a-descriptions-item>
|
|
||||||
<a-descriptions-item label="创建时间">
|
|
||||||
{{ userInfo.createTime }}
|
|
||||||
</a-descriptions-item>
|
|
||||||
</a-descriptions>
|
|
||||||
|
|
||||||
<!-- 操作按钮 -->
|
|
||||||
<div class="operation-buttons" style="margin-top: 24px">
|
|
||||||
<a-button type="primary" @click="handleEdit">编辑</a-button>
|
|
||||||
<a-button style="margin-left: 8px" @click="goBack">返回</a-button>
|
|
||||||
</div>
|
|
||||||
</a-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted } from 'vue';
|
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
|
||||||
import { useTabsViewStore } from '@/store/modules/tabsView';
|
|
||||||
const { closeCurrentTab } = useTabsViewStore();
|
|
||||||
|
|
||||||
const userInfo = ref({
|
|
||||||
username: 'mockUser',
|
|
||||||
nickname: 'mockNickname',
|
|
||||||
phone: '1234567890',
|
|
||||||
email: 'mock@example.com',
|
|
||||||
status: 1,
|
|
||||||
createTime: '2023-01-01 12:00:00',
|
|
||||||
});
|
|
||||||
|
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
getUserDetail();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取用户详情
|
|
||||||
async function getUserDetail() {
|
|
||||||
try {
|
|
||||||
const userId = route.params.id;
|
|
||||||
// 这里替换成实际的 API 调用
|
|
||||||
const response = await $api.user.getDetail(userId);
|
|
||||||
userInfo.value = response.data;
|
|
||||||
} catch (err) {
|
|
||||||
console.error('err', err);
|
|
||||||
$message.error('获取用户详情失败');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 编辑用户
|
|
||||||
function handleEdit() {
|
|
||||||
const userId = route.params.id;
|
|
||||||
router.push(`/user/edit/${userId}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回上一页并关闭当前标签
|
|
||||||
function goBack() {
|
|
||||||
router.back();
|
|
||||||
closeCurrentTab(route);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.user-detail {
|
|
||||||
padding: 24px;
|
|
||||||
background: #fff;
|
|
||||||
|
|
||||||
.operation-buttons {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,106 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="user-edit">
|
|
||||||
<a-card :bordered="false">
|
|
||||||
<a-form layout="vertical" :model="userForm" @submit="handleSave">
|
|
||||||
<a-form-item label="用户名">
|
|
||||||
<a-input
|
|
||||||
v-model:value="userForm.username"
|
|
||||||
placeholder="请输入用户名"
|
|
||||||
allow-clear
|
|
||||||
style="max-width: 400px"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="昵称">
|
|
||||||
<a-input
|
|
||||||
v-model:value="userForm.nickname"
|
|
||||||
placeholder="请输入昵称"
|
|
||||||
allow-clear
|
|
||||||
style="max-width: 400px"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="手机号">
|
|
||||||
<a-input
|
|
||||||
v-model:value="userForm.phone"
|
|
||||||
placeholder="请输入手机号"
|
|
||||||
allow-clear
|
|
||||||
style="max-width: 400px"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="邮箱">
|
|
||||||
<a-input
|
|
||||||
v-model:value="userForm.email"
|
|
||||||
placeholder="请输入邮箱"
|
|
||||||
allow-clear
|
|
||||||
style="max-width: 400px"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="状态">
|
|
||||||
<a-select v-model:value="userForm.status" style="max-width: 400px">
|
|
||||||
<a-select-option :value="1">启用</a-select-option>
|
|
||||||
<a-select-option :value="0">禁用</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item>
|
|
||||||
<a-space>
|
|
||||||
<a-button type="primary" html-type="submit">保存</a-button>
|
|
||||||
<a-button @click="goBack">取消</a-button>
|
|
||||||
</a-space>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
</a-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import { useRouter, useRoute } from 'vue-router';
|
|
||||||
import { message } from 'ant-design-vue';
|
|
||||||
import { useTabsViewStore } from '@/store/modules/tabsView';
|
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const route = useRoute();
|
|
||||||
const { closeCurrentTab } = useTabsViewStore();
|
|
||||||
|
|
||||||
// 用户信息表单数据
|
|
||||||
const userForm = ref({
|
|
||||||
username: '',
|
|
||||||
nickname: '',
|
|
||||||
phone: '',
|
|
||||||
email: '',
|
|
||||||
status: 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 保存用户信息
|
|
||||||
const handleSave = async () => {
|
|
||||||
// TODO: 调用保存接口
|
|
||||||
message.success('保存成功');
|
|
||||||
goBack();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 取消编辑
|
|
||||||
const goBack = () => {
|
|
||||||
router.back(); // 假设返回用户列表页面
|
|
||||||
closeCurrentTab(route); // 关闭当前标签页
|
|
||||||
};
|
|
||||||
|
|
||||||
// 初始化用户信息(可以通过接口获取)
|
|
||||||
const initUserData = async (userId: string) => {
|
|
||||||
// TODO: 调用接口获取用户信息
|
|
||||||
// const res = await getUserInfo(userId);
|
|
||||||
|
|
||||||
// 添加 mock 数据
|
|
||||||
userForm.value = {
|
|
||||||
username: 'mockUser',
|
|
||||||
nickname: 'mockNickname',
|
|
||||||
phone: '1234567890',
|
|
||||||
email: 'mock@example.com',
|
|
||||||
status: 1,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取用户ID并初始化数据
|
|
||||||
const userId = route.params.id; // 假设路由中有用户ID
|
|
||||||
if (userId) {
|
|
||||||
initUserData(userId);
|
|
||||||
}
|
|
||||||
</script>
|
|
@ -1,219 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="user-list">
|
|
||||||
<a-card :bordered="false">
|
|
||||||
<!-- 搜索区域 -->
|
|
||||||
<a-form layout="inline" :model="searchForm" @submit="handleSearch">
|
|
||||||
<a-form-item label="用户名" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
|
|
||||||
<a-input v-model:value="searchForm.username" placeholder="请输入用户名" allow-clear />
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item label="手机号" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
|
|
||||||
<a-input v-model:value="searchForm.phone" placeholder="请输入手机号" allow-clear />
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item>
|
|
||||||
<a-space>
|
|
||||||
<a-button type="primary" html-type="submit">查询</a-button>
|
|
||||||
<a-button @click="resetSearch">重置</a-button>
|
|
||||||
</a-space>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
|
|
||||||
<!-- 操作按钮区域 -->
|
|
||||||
<div class="table-operations">
|
|
||||||
<a-space>
|
|
||||||
<a-button type="primary" @click="handleAdd">
|
|
||||||
<template #icon>
|
|
||||||
<plus-outlined />
|
|
||||||
</template>
|
|
||||||
新增用户
|
|
||||||
</a-button>
|
|
||||||
</a-space>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 表格区域 -->
|
|
||||||
<a-table
|
|
||||||
:columns="columns"
|
|
||||||
:data-source="tableData"
|
|
||||||
:loading="loading"
|
|
||||||
:pagination="pagination"
|
|
||||||
:row-selection="{ selectedRowKeys, onChange: onSelectChange }"
|
|
||||||
row-key="id"
|
|
||||||
@change="handleTableChange"
|
|
||||||
>
|
|
||||||
<!-- 状态列 -->
|
|
||||||
<template #status="{ text }">
|
|
||||||
<a-tag :color="text ? 'success' : 'error'">
|
|
||||||
{{ text ? '启用' : '禁用' }}
|
|
||||||
</a-tag>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- 操作列 -->
|
|
||||||
<template #action="{ record }">
|
|
||||||
<a-space>
|
|
||||||
<a-button type="link" @click="handleEdit(record)">编辑</a-button>
|
|
||||||
<a-button type="link" @click="handleDetail(record)">详情</a-button>
|
|
||||||
<a-button type="link" @click="handleChangePassword(record)">修改密码</a-button>
|
|
||||||
<a-popconfirm title="确定要删除这条记录吗?" @confirm="handleDelete(record)">
|
|
||||||
<a-button type="link" danger>删除</a-button>
|
|
||||||
</a-popconfirm>
|
|
||||||
</a-space>
|
|
||||||
</template>
|
|
||||||
</a-table>
|
|
||||||
</a-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref, reactive } from 'vue';
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
import { PlusOutlined } from '@ant-design/icons-vue';
|
|
||||||
import { message } from 'ant-design-vue';
|
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
// 搜索表单数据
|
|
||||||
const searchForm = reactive({
|
|
||||||
username: '',
|
|
||||||
phone: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 表格列配置
|
|
||||||
const columns = [
|
|
||||||
{
|
|
||||||
title: '用户名',
|
|
||||||
dataIndex: 'username',
|
|
||||||
width: 120,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '昵称',
|
|
||||||
dataIndex: 'nickname',
|
|
||||||
width: 120,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '手机号',
|
|
||||||
dataIndex: 'phone',
|
|
||||||
width: 120,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '状态',
|
|
||||||
dataIndex: 'status',
|
|
||||||
width: 100,
|
|
||||||
slots: { customRender: 'status' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '创建时间',
|
|
||||||
dataIndex: 'createTime',
|
|
||||||
width: 180,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作',
|
|
||||||
key: 'action',
|
|
||||||
fixed: 'right',
|
|
||||||
width: 280,
|
|
||||||
slots: { customRender: 'action' },
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// 表格数据
|
|
||||||
const loading = ref(false);
|
|
||||||
const tableData = ref<any[]>([]);
|
|
||||||
const selectedRowKeys = ref<string[]>([]);
|
|
||||||
const pagination = reactive({
|
|
||||||
current: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
total: 0,
|
|
||||||
showSizeChanger: true,
|
|
||||||
showQuickJumper: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取表格数据
|
|
||||||
const getTableData = async () => {
|
|
||||||
loading.value = true;
|
|
||||||
try {
|
|
||||||
// TODO: 调用接口获取数据
|
|
||||||
// const res = await getUserList({
|
|
||||||
// ...searchForm,
|
|
||||||
// page: pagination.current,
|
|
||||||
// pageSize: pagination.pageSize,
|
|
||||||
// });
|
|
||||||
// tableData.value = res.data.list;
|
|
||||||
// pagination.total = res.data.total;
|
|
||||||
|
|
||||||
// 模拟数据
|
|
||||||
tableData.value = Array.from({ length: 10 }).map((_, index) => ({
|
|
||||||
id: index + 1,
|
|
||||||
username: `user${index + 1}`,
|
|
||||||
nickname: `用户${index + 1}`,
|
|
||||||
phone: '13800138000',
|
|
||||||
email: `user${index + 1}@example.com`,
|
|
||||||
status: index % 2,
|
|
||||||
createTime: '2024-03-20 12:00:00',
|
|
||||||
}));
|
|
||||||
pagination.total = 100;
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 表格选择改变
|
|
||||||
const onSelectChange = (keys: string[]) => {
|
|
||||||
selectedRowKeys.value = keys;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 表格分页、排序、筛选变化
|
|
||||||
const handleTableChange = (pag: any) => {
|
|
||||||
pagination.current = pag.current;
|
|
||||||
pagination.pageSize = pag.pageSize;
|
|
||||||
getTableData();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 搜索
|
|
||||||
const handleSearch = () => {
|
|
||||||
pagination.current = 1;
|
|
||||||
getTableData();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 重置搜索
|
|
||||||
const resetSearch = () => {
|
|
||||||
searchForm.username = '';
|
|
||||||
searchForm.phone = '';
|
|
||||||
handleSearch();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 新增用户
|
|
||||||
const handleAdd = () => {
|
|
||||||
router.push('/user/add');
|
|
||||||
};
|
|
||||||
|
|
||||||
// 编辑用户
|
|
||||||
const handleEdit = (record: any) => {
|
|
||||||
router.push(`/user/edit/${record.id}`);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 查看详情
|
|
||||||
const handleDetail = (record: any) => {
|
|
||||||
router.push(`/user/detail/${record.id}`);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 修改密码
|
|
||||||
const handleChangePassword = (record: any) => {
|
|
||||||
router.push(`/user/change-password/${record.id}`);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 删除用户
|
|
||||||
const handleDelete = async (record: any) => {
|
|
||||||
// TODO: 调用删除接口
|
|
||||||
message.success('删除成功');
|
|
||||||
getTableData();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 初始化
|
|
||||||
getTableData();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.user-list {
|
|
||||||
.table-operations {
|
|
||||||
margin: 16px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -32,7 +32,7 @@
|
|||||||
"strictFunctionTypes": false,
|
"strictFunctionTypes": false,
|
||||||
"noImplicitAny": false,
|
"noImplicitAny": false,
|
||||||
"lib": ["dom", "esnext", "DOM.Iterable"],
|
"lib": ["dom", "esnext", "DOM.Iterable"],
|
||||||
"types": ["node", "vite/client"],
|
"types": ["node", "vite/client", "vue"],
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["src/*"]
|
"@/*": ["src/*"]
|
||||||
}
|
}
|
||||||
|
1
apps/platform/types/shims/shims-vue.d.ts
vendored
1
apps/platform/types/shims/shims-vue.d.ts
vendored
@ -14,6 +14,7 @@ declare module 'vue' {
|
|||||||
Reflect: Reflect;
|
Reflect: Reflect;
|
||||||
suspenseStatus: '' | 'pending' | 'resolve' | 'fallback';
|
suspenseStatus: '' | 'pending' | 'resolve' | 'fallback';
|
||||||
}
|
}
|
||||||
|
export * from '@vue/runtime-core';
|
||||||
}
|
}
|
||||||
|
|
||||||
declare type Nullable<T> = T | null;
|
declare type Nullable<T> = T | null;
|
||||||
|
@ -26,7 +26,8 @@ const __APP_INFO__ = {
|
|||||||
export default ({ command, mode }: ConfigEnv): UserConfig => {
|
export default ({ command, mode }: ConfigEnv): UserConfig => {
|
||||||
console.log('mode', mode);
|
console.log('mode', mode);
|
||||||
// 环境变量
|
// 环境变量
|
||||||
const env = loadEnv(mode, process.cwd(), ['VITE_', 'VTJ_', 'SY_']);
|
const env = loadEnv(mode, process.cwd(), ['VITE_', 'VTJ_', 'SY_', 'Y_CODE_']);
|
||||||
|
console.log('env', env);
|
||||||
const isDev = command === 'serve';
|
const isDev = command === 'serve';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -46,6 +47,8 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
|
|||||||
server: {
|
server: {
|
||||||
open: true,
|
open: true,
|
||||||
host: true,
|
host: true,
|
||||||
|
cors: true,
|
||||||
|
port: Number(env.VITE_PORT),
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'https://custom-chart-pre-api.shiyue.com',
|
target: 'https://custom-chart-pre-api.shiyue.com',
|
||||||
|
@ -5,9 +5,13 @@ VITE_NODE_ENV = 'development'
|
|||||||
VITE_BASE_URL = /
|
VITE_BASE_URL = /
|
||||||
|
|
||||||
# 前端可见变量(必须以 VITE_ 开头)
|
# 前端可见变量(必须以 VITE_ 开头)
|
||||||
VITE_PORT = 10010
|
VITE_PORT = 10012
|
||||||
# VITE_BASE_API_URL = 'https://custom-chart-pre-api.shiyue.com/'
|
# VITE_BASE_API_URL = 'https://custom-chart-pre-api.shiyue.com/'
|
||||||
VITE_BASE_API_URL = 'https://custom-chart-api.shiyuegame.com/'
|
VITE_BASE_API_URL = 'https://custom-chart-api.shiyuegame.com/'
|
||||||
|
|
||||||
|
|
||||||
VITE_DEBUG_MODE = true
|
VITE_DEBUG_MODE = true
|
||||||
|
|
||||||
|
Y_CODE_PLATFORM_URL = 'https://localhost:10010/'
|
||||||
|
Y_CODE_DESIGNER_URL = 'https://localhost:10011/'
|
||||||
|
Y_CODE_RENDERER_URL = 'https://localhost:10012/'
|
@ -5,3 +5,7 @@ VITE_NODE_ENV = 'production'
|
|||||||
VITE_BASE_URL = /
|
VITE_BASE_URL = /
|
||||||
|
|
||||||
VITE_BASE_API_URL = 'https://custom-chart-api.shiyuegame.com/'
|
VITE_BASE_API_URL = 'https://custom-chart-api.shiyuegame.com/'
|
||||||
|
|
||||||
|
Y_CODE_PLATFORM_URL = 'https://y-code-platform.shiyuegame.com/'
|
||||||
|
Y_CODE_DESIGNER_URL = 'https://y-code-designer.shiyuegame.com/'
|
||||||
|
Y_CODE_RENDERER_URL = 'https://y-code-renderer.shiyuegame.com/'
|
||||||
|
@ -9,3 +9,7 @@ VITE_PORT = 10010
|
|||||||
|
|
||||||
# base api url
|
# base api url
|
||||||
VITE_BASE_API_URL = 'https://custom-chart-pre-api.shiyue.com/'
|
VITE_BASE_API_URL = 'https://custom-chart-pre-api.shiyue.com/'
|
||||||
|
|
||||||
|
Y_CODE_PLATFORM_URL = 'https://y-code-platform-pre.shiyue.com/'
|
||||||
|
Y_CODE_DESIGNER_URL = 'https://y-code-designer-pre.shiyue.com/'
|
||||||
|
Y_CODE_RENDERER_URL = 'https://y-code-renderer-pre.shiyue.com/'
|
@ -7,7 +7,7 @@ import path from "path";
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
export default defineConfig(({ mode }) => {
|
export default defineConfig(({ mode }) => {
|
||||||
console.log("mode", mode);
|
console.log("mode", mode);
|
||||||
const env = loadEnv(mode, process.cwd(), ["VITE_"]);
|
const env = loadEnv(mode, process.cwd(), ["VITE_", "Y_CODE_"]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
server: {
|
server: {
|
||||||
|
@ -18,13 +18,14 @@
|
|||||||
"@sy/low-code-shared": "workspace:*",
|
"@sy/low-code-shared": "workspace:*",
|
||||||
"@sy/web-vitals": "workspace:*",
|
"@sy/web-vitals": "workspace:*",
|
||||||
"@tanstack/vue-query": "^5.66.9",
|
"@tanstack/vue-query": "^5.66.9",
|
||||||
"@vtj/core": "^0.10.9",
|
"@vtj/core": "^0.10.10",
|
||||||
"@vtj/icons": "0.10.9",
|
"@vtj/icons": "0.10.10",
|
||||||
"@vtj/materials": "^0.10.9",
|
"@vtj/materials": "^0.10.10",
|
||||||
"@vtj/pro": "^0.10.9",
|
"@vtj/pro": "^0.10.10",
|
||||||
"@vtj/renderer": "^0.10.9",
|
"@vtj/renderer": "^0.10.10",
|
||||||
"@vtj/ui": "^0.10.9",
|
"@vtj/ui": "^0.10.10",
|
||||||
"@vtj/web": "^0.10.9",
|
"@vtj/utils": "^0.10.10",
|
||||||
|
"@vtj/web": "^0.10.10",
|
||||||
"axios": "^1.8.1",
|
"axios": "^1.8.1",
|
||||||
"core-js": "^3.40.0",
|
"core-js": "^3.40.0",
|
||||||
"element-plus": "^2.9.4",
|
"element-plus": "^2.9.4",
|
||||||
@ -35,10 +36,10 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@farmfe/cli": "^1.0.4",
|
"@farmfe/cli": "^1.0.4",
|
||||||
"@vtj/cli": "^0.10.2",
|
|
||||||
"@farmfe/core": "^1.6.6",
|
"@farmfe/core": "^1.6.6",
|
||||||
"@sy/vite-plugin-http2-proxy": "workspace:*",
|
"@sy/vite-plugin-http2-proxy": "workspace:*",
|
||||||
"@vitejs/plugin-vue": "^5.2.1",
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
|
"@vtj/cli": "^0.10.2",
|
||||||
"vite-plugin-mkcert": "^1.17.6"
|
"vite-plugin-mkcert": "^1.17.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,6 +6,7 @@ import { createProvider } from '@vtj/web'
|
|||||||
import { useQuery } from '@tanstack/vue-query'
|
import { useQuery } from '@tanstack/vue-query'
|
||||||
import { LowCodeService } from './service'
|
import { LowCodeService } from './service'
|
||||||
import { getFile } from './io'
|
import { getFile } from './io'
|
||||||
|
import { request, jsonp } from '@vtj/utils'
|
||||||
// import * as VtjUI from '@vtj/ui'
|
// import * as VtjUI from '@vtj/ui'
|
||||||
|
|
||||||
// 响应式状态
|
// 响应式状态
|
||||||
@ -13,7 +14,11 @@ const renderer = ref()
|
|||||||
const lowCodeService = new LowCodeService()
|
const lowCodeService = new LowCodeService()
|
||||||
|
|
||||||
// Postmate 握手协议
|
// Postmate 握手协议
|
||||||
const handshake = new Postmate.Model({})
|
const postmate = new Postmate.Model({
|
||||||
|
sayHi: (data: any) => {
|
||||||
|
console.log('sayHi',data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// 数据模型
|
// 数据模型
|
||||||
const model = {
|
const model = {
|
||||||
@ -21,28 +26,33 @@ const model = {
|
|||||||
applicationId: -1,
|
applicationId: -1,
|
||||||
projectId: -1,
|
projectId: -1,
|
||||||
fileId: '',
|
fileId: '',
|
||||||
url: ''
|
url: '',
|
||||||
|
accessToken: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数据查询
|
// 数据查询
|
||||||
const { data: file, isFetching } = useQuery({
|
const { data: file, isFetching } = useQuery({
|
||||||
queryKey: ['getFile'],
|
queryKey: ['getFile'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
await handshake.then((parent) => {
|
await postmate.then((parent) => {
|
||||||
// parent.emit('sync-context', 'Hello, World!')
|
parent.emit('some-event', 'y-code-renderer is ready')
|
||||||
Object.assign(model, parent.model)
|
Object.assign(model, parent.model)
|
||||||
|
localStorage.setItem('y-code-access-token', model.accessToken || '')
|
||||||
// console.log('model', model)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return getFile(model.fileId).then(() => {
|
return getFile(model.fileId).then(() => {
|
||||||
|
request.useRequest((req) => {
|
||||||
|
req.headers.set('Authorization', `Bearer ${model.accessToken}`)
|
||||||
|
return req
|
||||||
|
})
|
||||||
const { provider, onReady } = createProvider({
|
const { provider, onReady } = createProvider({
|
||||||
nodeEnv: import.meta.env.NODE_ENV,
|
nodeEnv: import.meta.env.NODE_ENV,
|
||||||
service: lowCodeService,
|
service: lowCodeService,
|
||||||
project: { id: model.projectId },
|
project: { id: model.projectId },
|
||||||
// components: {
|
adapter: {
|
||||||
// ...VtjUI,
|
request,
|
||||||
// }
|
jsonp
|
||||||
|
}
|
||||||
})
|
})
|
||||||
onReady(async () => {
|
onReady(async () => {
|
||||||
const instance = getCurrentInstance()
|
const instance = getCurrentInstance()
|
||||||
|
2
apps/renderer/src/constants/env.ts
Normal file
2
apps/renderer/src/constants/env.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
// @ts-ignore
|
||||||
|
export const currentEnv = __APP_ENV__;
|
1
apps/renderer/src/constants/index.ts
Normal file
1
apps/renderer/src/constants/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from "./env";
|
@ -12,7 +12,6 @@ const app = createApp(App);
|
|||||||
|
|
||||||
// 批量注册组件
|
// 批量注册组件
|
||||||
Object.entries(VtjUI).forEach(([name, component]) => {
|
Object.entries(VtjUI).forEach(([name, component]) => {
|
||||||
console.log("name", name, component);
|
|
||||||
app.component(name, component);
|
app.component(name, component);
|
||||||
});
|
});
|
||||||
app
|
app
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# .env.development
|
# .env.development
|
||||||
VITE_NODE_ENV = development
|
VITE_NODE_ENV = development
|
||||||
|
|
||||||
VITE_PORT = 10012
|
VITE_PORT = 10013
|
||||||
|
|
||||||
VITE_OA_BASEURL = https://oa-pre.shiyue.com
|
VITE_OA_BASEURL = https://oa-pre.shiyue.com
|
||||||
|
|
||||||
|
@ -43,11 +43,11 @@
|
|||||||
"eslint-plugin-vue": "^9.32.0",
|
"eslint-plugin-vue": "^9.32.0",
|
||||||
"less": "^4.2.2",
|
"less": "^4.2.2",
|
||||||
"semantic-release": "^24.2.2",
|
"semantic-release": "^24.2.2",
|
||||||
"typescript": "~5.3.3",
|
"typescript": "~5.8.2",
|
||||||
"unplugin-vue-components": "^0.26.0",
|
"unplugin-vue-components": "^0.26.0",
|
||||||
"vite": "^6.2.0",
|
"vite": "^6.2.0",
|
||||||
"vite-plugin-qiankun": "^1.0.15",
|
"vite-plugin-qiankun": "^1.0.15",
|
||||||
"vue-tsc": "^2.2.0",
|
"vue-tsc": "^2.2.8",
|
||||||
"yargs-parser": "^21.1.1"
|
"yargs-parser": "^21.1.1"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.4.1"
|
"packageManager": "pnpm@10.4.1"
|
||||||
|
15
package.json
15
package.json
@ -13,7 +13,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"low-code:help": "node ./scripts/index.mjs",
|
"low-code:help": "node ./scripts/index.mjs",
|
||||||
"preinstall": "npx only-allow pnpm && pnpm i -g turbo rimraf",
|
"preinstall": "npx only-allow pnpm && pnpm i -g turbo rimraf cross-env",
|
||||||
"dev": "turbo run dev",
|
"dev": "turbo run dev",
|
||||||
"build": "turbo run build",
|
"build": "turbo run build",
|
||||||
"preview": "turbo run preview",
|
"preview": "turbo run preview",
|
||||||
@ -38,7 +38,9 @@
|
|||||||
"eslint-plugin-prettier": "~5.2.3",
|
"eslint-plugin-prettier": "~5.2.3",
|
||||||
"eslint-plugin-unused-imports": "^4.1.4",
|
"eslint-plugin-unused-imports": "^4.1.4",
|
||||||
"husky": "~9.1.7",
|
"husky": "~9.1.7",
|
||||||
|
"inquirer": "^12.4.2",
|
||||||
"lint-staged": "~15.2.11",
|
"lint-staged": "~15.2.11",
|
||||||
|
"ora": "^8.2.0",
|
||||||
"postcss-html": "~1.7.0",
|
"postcss-html": "~1.7.0",
|
||||||
"prettier": "~3.3.3",
|
"prettier": "~3.3.3",
|
||||||
"stylelint": "~16.10.0",
|
"stylelint": "~16.10.0",
|
||||||
@ -48,11 +50,8 @@
|
|||||||
"stylelint-config-standard": "~36.0.1",
|
"stylelint-config-standard": "~36.0.1",
|
||||||
"stylelint-order": "~6.0.4",
|
"stylelint-order": "~6.0.4",
|
||||||
"stylelint-prettier": "^5.0.3",
|
"stylelint-prettier": "^5.0.3",
|
||||||
"typescript": "~5.6.3",
|
"typescript": "~5.8.2",
|
||||||
"vue-eslint-parser": "~9.4.3",
|
"vue-eslint-parser": "~10.1.1",
|
||||||
"vue-tsc": "~2.1.10",
|
"vue-tsc": "~2.2.8"
|
||||||
"inquirer": "^12.4.2",
|
}
|
||||||
"ora": "^8.2.0"
|
|
||||||
},
|
|
||||||
"dependencies": {}
|
|
||||||
}
|
}
|
@ -16,6 +16,6 @@
|
|||||||
"clean": "rimraf node_modules"
|
"clean": "rimraf node_modules"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^5.7.3"
|
"typescript": "^5.8.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
1644
pnpm-lock.yaml
generated
1644
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user