@dmqweb/elpis 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +3 -0
- package/.eslintrc +59 -0
- package/.vscode/settings.json +15 -0
- package/README.md +198 -0
- package/app/controller/base.js +41 -0
- package/app/controller/project.js +98 -0
- package/app/controller/view.js +24 -0
- package/app/extend/logger.js +43 -0
- package/app/middleware/api-params-verify.js +89 -0
- package/app/middleware/api-sign-verify.js +47 -0
- package/app/middleware/error-handler.js +41 -0
- package/app/middleware/project-handler.js +27 -0
- package/app/middleware.js +40 -0
- package/app/pages/asserts/custom.css +12 -0
- package/app/pages/boot.js +59 -0
- package/app/pages/common/curl.js +88 -0
- package/app/pages/common/util.js +3 -0
- package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +40 -0
- package/app/pages/dashboard/complex-view/header-view/header-view.vue +141 -0
- package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +43 -0
- package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue +39 -0
- package/app/pages/dashboard/complex-view/schema-view/complex-view/table-panel/table-panel.vue +146 -0
- package/app/pages/dashboard/complex-view/schema-view/components/component-config.js +24 -0
- package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +118 -0
- package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +177 -0
- package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +157 -0
- package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +150 -0
- package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +113 -0
- package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +35 -0
- package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +134 -0
- package/app/pages/dashboard/dashboard.vue +127 -0
- package/app/pages/dashboard/entry.dashboard.js +46 -0
- package/app/pages/store/index.js +5 -0
- package/app/pages/store/menu.js +61 -0
- package/app/pages/store/project.js +13 -0
- package/app/pages/widgets/header-container/asserts/avatar.png +0 -0
- package/app/pages/widgets/header-container/asserts/logo.png +0 -0
- package/app/pages/widgets/header-container/header-container.vue +144 -0
- package/app/pages/widgets/schema-form/complex-view/input/input.vue +165 -0
- package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +166 -0
- package/app/pages/widgets/schema-form/complex-view/select/select.vue +144 -0
- package/app/pages/widgets/schema-form/form-item.config.js +24 -0
- package/app/pages/widgets/schema-form/schema-form.vue +144 -0
- package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +57 -0
- package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +77 -0
- package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +51 -0
- package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +58 -0
- package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +138 -0
- package/app/pages/widgets/schema-search-bar/search-item-config.js +27 -0
- package/app/pages/widgets/schema-table/schema-table.vue +254 -0
- package/app/pages/widgets/sider-container/sider-container.vue +32 -0
- package/app/router/business.js +15 -0
- package/app/router/project.js +10 -0
- package/app/router/view.js +11 -0
- package/app/router-schema/business.js +82 -0
- package/app/router-schema/project.js +40 -0
- package/app/service/base.js +13 -0
- package/app/service/project.js +55 -0
- package/app/view/entry.tpl +27 -0
- package/app/webpack/config/blank.js +3 -0
- package/app/webpack/config/webpack.base.js +269 -0
- package/app/webpack/config/webpack.dev.js +61 -0
- package/app/webpack/config/webpack.prod.js +149 -0
- package/app/webpack/dev.js +58 -0
- package/app/webpack/prod.js +21 -0
- package/config/config.default.js +3 -0
- package/elpis-core/env.js +22 -0
- package/elpis-core/index.js +99 -0
- package/elpis-core/loader/config.js +51 -0
- package/elpis-core/loader/controller.js +75 -0
- package/elpis-core/loader/extend.js +54 -0
- package/elpis-core/loader/middleware.js +69 -0
- package/elpis-core/loader/router-schema.js +50 -0
- package/elpis-core/loader/router.js +52 -0
- package/elpis-core/loader/service.js +74 -0
- package/index.js +29 -0
- package/jsconfig.json +16 -0
- package/logs/applocation.log +3 -0
- package/model/index.js +119 -0
- package/package.json +93 -0
- package/test/controller/project.test.js +216 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* projectHandler 相关项目处理内容
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
module.exports = (app) => {
|
|
6
|
+
return async (ctx, next) => {
|
|
7
|
+
|
|
8
|
+
if (ctx.path.indexOf('/api/proj/') < 0) {
|
|
9
|
+
return await next()
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const { proj_key : projKey} = ctx.request.headers
|
|
13
|
+
|
|
14
|
+
if (!projKey) {
|
|
15
|
+
ctx.status = 200;
|
|
16
|
+
ctx.body = {
|
|
17
|
+
success: false,
|
|
18
|
+
message: 'no project key',
|
|
19
|
+
code: 446
|
|
20
|
+
};
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
ctx.projKey = projKey
|
|
24
|
+
|
|
25
|
+
await next()
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
// 模板渲染引擎中间件
|
|
3
|
+
module.exports = (app) => {
|
|
4
|
+
// 引入koa-static中间件,用于提供静态文件服务
|
|
5
|
+
const KoaStatic = require('koa-static');
|
|
6
|
+
// 将app/public目录设置为静态文件服务目录
|
|
7
|
+
// 这样可以直接通过URL访问该目录下的文件,如CSS、JS、图片等
|
|
8
|
+
// path.resolve(process.cwd(), './app/public')将相对路径解析为绝对路径
|
|
9
|
+
app.use(KoaStatic(path.resolve(process.cwd(), './app/public')))
|
|
10
|
+
|
|
11
|
+
// 引入koa-nunjucks-2中间件
|
|
12
|
+
const koaNunjucks = require('koa-nunjucks-2');
|
|
13
|
+
app.use(koaNunjucks({
|
|
14
|
+
ext: 'tpl', // 配置模板文件的扩展名
|
|
15
|
+
path: path.resolve(process.cwd(), './app/public'), // 配置模板文件的查找路径
|
|
16
|
+
nunjucksConfig: {
|
|
17
|
+
nocache: true, // 开发时禁用缓存
|
|
18
|
+
trimBlocks: true // trimBlocks设置为true,表示自动去除块级标签后的空白字符
|
|
19
|
+
}
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
// 引入koa-bodyparser中间件,用于解析HTTP请求体
|
|
23
|
+
const bodyParser = require('koa-bodyparser');
|
|
24
|
+
app.use(bodyParser({
|
|
25
|
+
formLimit: '1000mb', // 设置表单数据大小限制为1000MB
|
|
26
|
+
enableTypes:['json', 'form', 'text'] // 启用解析的请求体类型:JSON、表单、文本
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
// 引入 自定义的错误处理中间件
|
|
30
|
+
app.use(app.middlewares.errorHandler)
|
|
31
|
+
|
|
32
|
+
// 引入 签名合法校验
|
|
33
|
+
app.use(app.middlewares.apiSignVerify)
|
|
34
|
+
|
|
35
|
+
// 引入 API参数校验
|
|
36
|
+
app.use(app.middlewares.apiParamsVerify)
|
|
37
|
+
|
|
38
|
+
// 引入 项目处理中间件
|
|
39
|
+
app.use(app.middlewares.projectHandler)
|
|
40
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { createApp } from "vue";
|
|
2
|
+
|
|
3
|
+
// 引入 elementUI
|
|
4
|
+
import ElementPlus from "element-plus";
|
|
5
|
+
import "element-plus/theme-chalk/index.css";
|
|
6
|
+
import 'element-plus/theme-chalk/dark/css-vars.css'
|
|
7
|
+
import './asserts/custom.css'
|
|
8
|
+
import pinia from '$elpisStore/index.js'
|
|
9
|
+
import { createWebHistory, createRouter } from 'vue-router'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* vue 页面主入口, 用于启动 vue
|
|
13
|
+
* @param pageComponent vue 入口组件
|
|
14
|
+
* @param routes 路由列表
|
|
15
|
+
* @param libs 页面依赖的第三方包
|
|
16
|
+
*/
|
|
17
|
+
export default (pageComponent, { routes, libs } = {}) => {
|
|
18
|
+
// 添加passive事件监听器支持,解决Chrome中关于非被动事件监听器的警告
|
|
19
|
+
(function() {
|
|
20
|
+
if (typeof EventTarget !== "undefined") {
|
|
21
|
+
let func = EventTarget.prototype.addEventListener;
|
|
22
|
+
EventTarget.prototype.addEventListener = function(type, fn, capture) {
|
|
23
|
+
capture = capture || {};
|
|
24
|
+
if (type === "touchstart" || type === "touchmove" || type === "wheel" || type === "mousewheel") {
|
|
25
|
+
capture.passive = capture.passive || !capture.once;
|
|
26
|
+
}
|
|
27
|
+
func.call(this, type, fn, capture);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
})();
|
|
31
|
+
|
|
32
|
+
const app = createApp(pageComponent);
|
|
33
|
+
|
|
34
|
+
// 挂载 elementUI
|
|
35
|
+
app.use(ElementPlus);
|
|
36
|
+
// 挂载 pinia
|
|
37
|
+
app.use(pinia);
|
|
38
|
+
|
|
39
|
+
// 挂载 第三方库
|
|
40
|
+
if ( libs && libs.length ) {
|
|
41
|
+
for (let i = 0; i < libs.length; i++) {
|
|
42
|
+
app.use(libs[i]);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 挂载路由
|
|
47
|
+
if ( routes && routes.length ) {
|
|
48
|
+
const router = createRouter ({
|
|
49
|
+
history: createWebHistory(), // 采用 history 路由模式
|
|
50
|
+
routes,
|
|
51
|
+
});
|
|
52
|
+
app.use(router);
|
|
53
|
+
router.isReady().then(() => {
|
|
54
|
+
app.mount("#root");
|
|
55
|
+
})
|
|
56
|
+
} else {
|
|
57
|
+
app.mount("#root");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { ElMessage } from "element-plus";
|
|
2
|
+
|
|
3
|
+
const md5 = require("md5");
|
|
4
|
+
/**
|
|
5
|
+
* 前端封装的 curl 方法
|
|
6
|
+
* @param {Object} options 请求参数
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const curl = ({
|
|
10
|
+
url, // 请求地址
|
|
11
|
+
method = 'post', // 请求方法
|
|
12
|
+
headers = {}, // 请求头
|
|
13
|
+
params = {}, // 请求参数
|
|
14
|
+
data = {}, // 请求体
|
|
15
|
+
responseType = 'json', // 响应数据类型
|
|
16
|
+
timeout = 60000, // 请求超时时间
|
|
17
|
+
errorMsg = '请求超时', // 请求超时错误信息
|
|
18
|
+
}) => {
|
|
19
|
+
|
|
20
|
+
// 接口签名处理(让接口变动态)
|
|
21
|
+
const signKey = 'elpis-sign-key'
|
|
22
|
+
const st = Date.now()
|
|
23
|
+
const signature = md5(`${signKey}_${st}`)
|
|
24
|
+
|
|
25
|
+
const dotHeaders = {
|
|
26
|
+
...headers,
|
|
27
|
+
s_t: st,
|
|
28
|
+
s_sign: signature,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if(url.indexOf('/api/proj/') > -1 && window.projKey && window.projKey !== 'undefined') {
|
|
32
|
+
|
|
33
|
+
dotHeaders.proj_key = window.projKey
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// 构造请求参数 把参数转换为 axios 参数
|
|
37
|
+
const ajaxSetting = {
|
|
38
|
+
method,
|
|
39
|
+
url,
|
|
40
|
+
params,
|
|
41
|
+
data,
|
|
42
|
+
responseType,
|
|
43
|
+
timeout,
|
|
44
|
+
headers: dotHeaders
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return axios.request(ajaxSetting).then((response) => {
|
|
48
|
+
const resData = response.data
|
|
49
|
+
|
|
50
|
+
// 后端API返回格式
|
|
51
|
+
const { success } = resData;
|
|
52
|
+
|
|
53
|
+
// 失败
|
|
54
|
+
if(!success){
|
|
55
|
+
const { message, code } = resData;
|
|
56
|
+
if ( code === 402){
|
|
57
|
+
ElMessage.error('请求参数异常')
|
|
58
|
+
} else if ( code === 445){
|
|
59
|
+
ElMessage.error('请求不合法')
|
|
60
|
+
}else if ( code === 446){
|
|
61
|
+
ElMessage.error('缺少项目必要参数 ')
|
|
62
|
+
} else if ( code === 50000){
|
|
63
|
+
ElMessage.error(message)
|
|
64
|
+
}else {
|
|
65
|
+
ElMessage.error(errorMsg)
|
|
66
|
+
}
|
|
67
|
+
console.error(message)
|
|
68
|
+
return Promise.resolve({ success, code, message})
|
|
69
|
+
}
|
|
70
|
+
// 成功
|
|
71
|
+
const { data, metadata} = resData;
|
|
72
|
+
return Promise.resolve({ success, data, metadata})
|
|
73
|
+
|
|
74
|
+
}).catch((e) => {
|
|
75
|
+
const { message } = e
|
|
76
|
+
|
|
77
|
+
if (message.match(/timeout/)){
|
|
78
|
+
return Promise.resolve({
|
|
79
|
+
message: '请求超时',
|
|
80
|
+
code: 504
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return Promise.resolve(e)
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export default curl;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- 下拉菜单 -->
|
|
3
|
+
<el-sub-menu
|
|
4
|
+
:index="menuItem.key"
|
|
5
|
+
>
|
|
6
|
+
<template #title>
|
|
7
|
+
{{ menuItem.name }}
|
|
8
|
+
</template>
|
|
9
|
+
<div
|
|
10
|
+
v-for="item in menuItem.subMenu"
|
|
11
|
+
:key="item.key"
|
|
12
|
+
>
|
|
13
|
+
<sub-menu
|
|
14
|
+
v-if="item.subMenu && item.subMenu.length > 0"
|
|
15
|
+
:menu-item="item"
|
|
16
|
+
>
|
|
17
|
+
<!-- -->
|
|
18
|
+
</sub-menu>
|
|
19
|
+
<el-menu-item
|
|
20
|
+
v-else
|
|
21
|
+
:index="item.key"
|
|
22
|
+
>
|
|
23
|
+
{{ item.name }}
|
|
24
|
+
</el-menu-item>
|
|
25
|
+
</div>
|
|
26
|
+
</el-sub-menu>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<script setup>
|
|
30
|
+
const { menuItem } = defineProps({
|
|
31
|
+
menuItem: {
|
|
32
|
+
type: Object,
|
|
33
|
+
required: true
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<style scoped lang="less">
|
|
39
|
+
|
|
40
|
+
</style>
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- 引用布局模板、 增加插槽部分 -->
|
|
3
|
+
<header-container :title="projName">
|
|
4
|
+
<!-- 中间菜单区域 -->
|
|
5
|
+
<template #menu-content>
|
|
6
|
+
<!-- 根据 menuStore.menuList 渲染 -->
|
|
7
|
+
<el-menu
|
|
8
|
+
:default-active="activeKey"
|
|
9
|
+
:ellipsis="false"
|
|
10
|
+
mode="horizontal"
|
|
11
|
+
@select="onMenuSelect"
|
|
12
|
+
>
|
|
13
|
+
<template
|
|
14
|
+
v-for="item in menuStore.menuList"
|
|
15
|
+
>
|
|
16
|
+
<sub-menu
|
|
17
|
+
v-if="item.subMenu && item.subMenu.length > 0"
|
|
18
|
+
:menu-item="item"
|
|
19
|
+
/>
|
|
20
|
+
<el-menu-item
|
|
21
|
+
v-else
|
|
22
|
+
:index="item.key"
|
|
23
|
+
>
|
|
24
|
+
{{ item.name }}
|
|
25
|
+
</el-menu-item>
|
|
26
|
+
</template>
|
|
27
|
+
</el-menu>
|
|
28
|
+
</template>
|
|
29
|
+
<!-- 右侧上方设置区域 -->
|
|
30
|
+
<template #setting-content>
|
|
31
|
+
<!-- 根据 projStore.projList 渲染 -->
|
|
32
|
+
<el-dropdown @command="handleProjectCommand">
|
|
33
|
+
<span class="project-list">
|
|
34
|
+
{{ projName }}
|
|
35
|
+
<el-icon
|
|
36
|
+
v-if="projectStore.projectList.length > 1"
|
|
37
|
+
class="el-icon--right"
|
|
38
|
+
>
|
|
39
|
+
<arrow-down />
|
|
40
|
+
</el-icon>
|
|
41
|
+
</span>
|
|
42
|
+
<template
|
|
43
|
+
v-if="projectStore.projectList.length > 1"
|
|
44
|
+
#dropdown
|
|
45
|
+
>
|
|
46
|
+
<el-dropdown-menu>
|
|
47
|
+
<el-dropdown-item
|
|
48
|
+
v-for="item in projectStore.projectList"
|
|
49
|
+
:key="item.key"
|
|
50
|
+
:command="item.key"
|
|
51
|
+
:disabled="item.key === route.query.proj_key"
|
|
52
|
+
>
|
|
53
|
+
{{ item. name }}
|
|
54
|
+
</el-dropdown-item>
|
|
55
|
+
</el-dropdown-menu>
|
|
56
|
+
</template>
|
|
57
|
+
</el-dropdown>
|
|
58
|
+
</template>
|
|
59
|
+
<!-- 主内容区域 -->
|
|
60
|
+
<template #main-content>
|
|
61
|
+
<slot name="main-content" />
|
|
62
|
+
</template>
|
|
63
|
+
</header-container>
|
|
64
|
+
</template>
|
|
65
|
+
|
|
66
|
+
<script setup>
|
|
67
|
+
import { ArrowDown } from '@element-plus/icons-vue'
|
|
68
|
+
import { ref, watch, onMounted } from 'vue'
|
|
69
|
+
import { useRoute } from 'vue-router'
|
|
70
|
+
import HeaderContainer from '$elpisWidgets/header-container/header-container.vue'
|
|
71
|
+
import SubMenu from './complex-view/sub-menu/sub-menu.vue'
|
|
72
|
+
import { useProjectStore } from '$elpisStore/project.js'
|
|
73
|
+
import { useMenuStore } from '$elpisStore/menu.js'
|
|
74
|
+
|
|
75
|
+
const route = useRoute()
|
|
76
|
+
const projectStore = useProjectStore()
|
|
77
|
+
const menuStore = useMenuStore()
|
|
78
|
+
|
|
79
|
+
defineProps({
|
|
80
|
+
// eslint-disable-next-line vue/require-default-prop
|
|
81
|
+
projName: {
|
|
82
|
+
type: String,
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
// 传给父组件 menu-select 事件
|
|
86
|
+
const emit = defineEmits(['menu-select'])
|
|
87
|
+
|
|
88
|
+
const activeKey = ref('')
|
|
89
|
+
|
|
90
|
+
// 设置 activeKey
|
|
91
|
+
const setActiveKey = function() {
|
|
92
|
+
const menuItem = menuStore.findMenuItem({
|
|
93
|
+
key: 'key',
|
|
94
|
+
value: route.query.key
|
|
95
|
+
})
|
|
96
|
+
activeKey.value = menuItem?.key
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 监听路由变化,设置 activeKey
|
|
100
|
+
watch( [
|
|
101
|
+
() => route.query.key,
|
|
102
|
+
() => menuStore.menuList
|
|
103
|
+
], () => {
|
|
104
|
+
setActiveKey()
|
|
105
|
+
}, { deep: true, immediate: true})
|
|
106
|
+
// 当页面加载完成并且该组件被挂载到DOM上时
|
|
107
|
+
onMounted(() => {
|
|
108
|
+
setActiveKey()
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
// 监听菜单选择
|
|
113
|
+
const onMenuSelect = function(menuKey) {
|
|
114
|
+
const menuItem = menuStore.findMenuItem({
|
|
115
|
+
key: 'key',
|
|
116
|
+
value: menuKey
|
|
117
|
+
})
|
|
118
|
+
emit('menu-select', menuItem)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// 下拉菜单处理项目切换
|
|
122
|
+
const handleProjectCommand = function(event) {
|
|
123
|
+
const projectItem = projectStore.projectList.find(item => item.key === event)
|
|
124
|
+
if (!projectItem || !projectItem.homePage) {
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
const { origin} = window.location
|
|
128
|
+
window.location.href = `${origin}/view/dashboard${projectItem.homePage}`
|
|
129
|
+
}
|
|
130
|
+
</script>
|
|
131
|
+
|
|
132
|
+
<style scoped lang="less">
|
|
133
|
+
.project-list {
|
|
134
|
+
margin-right: 20px;
|
|
135
|
+
cursor: pointer;
|
|
136
|
+
color: var(--el-color-primary);
|
|
137
|
+
display: flex;
|
|
138
|
+
align-items: center;
|
|
139
|
+
outline: none;
|
|
140
|
+
}
|
|
141
|
+
</style>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<iframe
|
|
3
|
+
:src="path"
|
|
4
|
+
class="iframe"
|
|
5
|
+
/>
|
|
6
|
+
</template>
|
|
7
|
+
|
|
8
|
+
<script setup>
|
|
9
|
+
import { useRoute } from 'vue-router'
|
|
10
|
+
import { useMenuStore } from '$elpisStore/menu'
|
|
11
|
+
import { ref, watch, onMounted } from 'vue'
|
|
12
|
+
|
|
13
|
+
const route = useRoute()
|
|
14
|
+
const menuStore = useMenuStore()
|
|
15
|
+
const path = ref('')
|
|
16
|
+
const setPath = function () {
|
|
17
|
+
const { sider_key, key } = route.query;
|
|
18
|
+
const menuItem = menuStore.findMenuItem({
|
|
19
|
+
key: 'key',
|
|
20
|
+
value: sider_key ?? key
|
|
21
|
+
})
|
|
22
|
+
path.value = menuItem?.iframeConfig?.path ?? ''
|
|
23
|
+
}
|
|
24
|
+
watch([
|
|
25
|
+
() => route.query.sider_key,
|
|
26
|
+
() => route.query.proj_key,
|
|
27
|
+
() => menuStore.getMenuList
|
|
28
|
+
], () => {
|
|
29
|
+
setPath()
|
|
30
|
+
},{ deep: true})
|
|
31
|
+
onMounted(() => {
|
|
32
|
+
setPath()
|
|
33
|
+
})
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
<style lang="less" scoped>
|
|
38
|
+
.iframe {
|
|
39
|
+
width: 100%;
|
|
40
|
+
height: 100%;
|
|
41
|
+
border: none;
|
|
42
|
+
}
|
|
43
|
+
</style>
|
package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-card class="search-panel">
|
|
3
|
+
<schema-search-bar
|
|
4
|
+
:schema="searchSchema"
|
|
5
|
+
@reset="onReset"
|
|
6
|
+
@load="onLoad"
|
|
7
|
+
@search="onSearch"
|
|
8
|
+
/>
|
|
9
|
+
</el-card>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script setup>
|
|
13
|
+
import { inject} from 'vue'
|
|
14
|
+
import schemaSearchBar from '$elpisWidgets/schema-search-bar/schema-search-bar.vue'
|
|
15
|
+
const {
|
|
16
|
+
searchSchema
|
|
17
|
+
} = inject('schemaViewData')
|
|
18
|
+
|
|
19
|
+
const emit = defineEmits(['search'])
|
|
20
|
+
|
|
21
|
+
const onLoad = (searchValObj) => {
|
|
22
|
+
emit('search', searchValObj)
|
|
23
|
+
}
|
|
24
|
+
const onSearch = (searchValObj) => {
|
|
25
|
+
emit('search', searchValObj)
|
|
26
|
+
}
|
|
27
|
+
const onReset = () => {
|
|
28
|
+
emit('search', {})
|
|
29
|
+
}
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<style lang="less" scoped>
|
|
33
|
+
.search-panel {
|
|
34
|
+
margin: 10px 10px 0 10px;
|
|
35
|
+
}
|
|
36
|
+
:deep(.el-card__body) {
|
|
37
|
+
padding-bottom: 2px;
|
|
38
|
+
}
|
|
39
|
+
</style>
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-card class="table-panel">
|
|
3
|
+
<!-- operation-panel -->
|
|
4
|
+
<el-row
|
|
5
|
+
v-if="tableConfig?.headerButtons?.length > 0"
|
|
6
|
+
justify="end"
|
|
7
|
+
class="operation-panel"
|
|
8
|
+
>
|
|
9
|
+
<el-button
|
|
10
|
+
v-for="item in tableConfig?.headerButtons"
|
|
11
|
+
v-bind="item"
|
|
12
|
+
@click="operationHandler({ btnConfig : item})"
|
|
13
|
+
>
|
|
14
|
+
{{ item.label }}
|
|
15
|
+
</el-button>
|
|
16
|
+
</el-row>
|
|
17
|
+
<!-- schema-table(组件 ) -->
|
|
18
|
+
<schema-table
|
|
19
|
+
ref="schemaTableRef"
|
|
20
|
+
:api="api"
|
|
21
|
+
:schema="tableSchema"
|
|
22
|
+
:api-params="apiParams"
|
|
23
|
+
:buttons="tableConfig?.rowButtons ?? []"
|
|
24
|
+
@operate="operationHandler"
|
|
25
|
+
>
|
|
26
|
+
<!-- -->
|
|
27
|
+
</schema-table>
|
|
28
|
+
</el-card>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<script setup>
|
|
32
|
+
import { ref, inject } from 'vue'
|
|
33
|
+
import $curl from '$elpisCommon/curl.js'
|
|
34
|
+
import { ElMessageBox, ElNotification } from 'element-plus'
|
|
35
|
+
import SchemaTable from '$elpisWidgets/schema-table/schema-table.vue'
|
|
36
|
+
|
|
37
|
+
const {
|
|
38
|
+
api,
|
|
39
|
+
apiParams,
|
|
40
|
+
tableSchema,
|
|
41
|
+
tableConfig,
|
|
42
|
+
} = inject('schemaViewData')
|
|
43
|
+
|
|
44
|
+
const schemaTableRef = ref(null)
|
|
45
|
+
const emit = defineEmits(['operate'])
|
|
46
|
+
|
|
47
|
+
const eventHandlerMap = {
|
|
48
|
+
remove: removeData
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 获取按钮事件名
|
|
52
|
+
const operationHandler = ({ btnConfig, rowData }) => {
|
|
53
|
+
|
|
54
|
+
const { eventKey } = btnConfig
|
|
55
|
+
|
|
56
|
+
if (eventHandlerMap[eventKey]){
|
|
57
|
+
eventHandlerMap[eventKey]({ btnConfig, rowData })
|
|
58
|
+
} else {
|
|
59
|
+
emit('operate', { btnConfig, rowData })
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 删除数据
|
|
64
|
+
function removeData({ btnConfig, rowData }) {
|
|
65
|
+
const { eventOption } = btnConfig
|
|
66
|
+
if (!eventOption?.params) return;
|
|
67
|
+
|
|
68
|
+
const { params } = eventOption
|
|
69
|
+
|
|
70
|
+
const removeKey = Object.keys(params)[0]
|
|
71
|
+
let removeValue = params[removeKey];
|
|
72
|
+
|
|
73
|
+
const removeValueList = removeValue.split('::')
|
|
74
|
+
if (removeValueList[0] === 'schema' && removeValueList[1]) {
|
|
75
|
+
removeValue = rowData[removeValueList[1]]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
ElMessageBox.confirm(
|
|
79
|
+
`确认删除 ${rowData['product_name']} 数据吗?`,
|
|
80
|
+
'warning',
|
|
81
|
+
{
|
|
82
|
+
confirmButtonText: '确定',
|
|
83
|
+
cancelButtonText: '取消',
|
|
84
|
+
type: 'warning'
|
|
85
|
+
}
|
|
86
|
+
).then( async () => {
|
|
87
|
+
schemaTableRef.value.showLoading()
|
|
88
|
+
const res = await $curl({
|
|
89
|
+
method: 'delete',
|
|
90
|
+
url: api.value,
|
|
91
|
+
data: {
|
|
92
|
+
[removeKey] : removeValue
|
|
93
|
+
},
|
|
94
|
+
errorMessage: '删除失败'
|
|
95
|
+
})
|
|
96
|
+
schemaTableRef.value.hideLoading()
|
|
97
|
+
|
|
98
|
+
if (!res || !res.success || !res.data) {
|
|
99
|
+
return
|
|
100
|
+
}
|
|
101
|
+
ElNotification.success({
|
|
102
|
+
title: '删除成功',
|
|
103
|
+
message: `${removeKey}: ${removeValue} 删除成功`,
|
|
104
|
+
type: 'success'
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
await initTableData()
|
|
108
|
+
})
|
|
109
|
+
.catch(() => {
|
|
110
|
+
ElNotification.info({
|
|
111
|
+
title: '取消删除',
|
|
112
|
+
message: '已取消删除操作',
|
|
113
|
+
type: 'info'
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
const initTableData = async () => {
|
|
118
|
+
await schemaTableRef.value.initData()
|
|
119
|
+
}
|
|
120
|
+
const loadTableData = async () => {
|
|
121
|
+
await schemaTableRef.value.loadTableData()
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
defineExpose({
|
|
125
|
+
loadTableData,
|
|
126
|
+
initTableData
|
|
127
|
+
})
|
|
128
|
+
</script>
|
|
129
|
+
|
|
130
|
+
<style lang="less" scoped>
|
|
131
|
+
.table-panel {
|
|
132
|
+
flex: 1;
|
|
133
|
+
margin: 10px;
|
|
134
|
+
width: 100%;
|
|
135
|
+
height: 100%;
|
|
136
|
+
|
|
137
|
+
.operation-panel {
|
|
138
|
+
margin-bottom: 10px;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
:deep(.el-card__body) {
|
|
142
|
+
height: 98%;
|
|
143
|
+
display: flex;
|
|
144
|
+
flex-direction: column;
|
|
145
|
+
}
|
|
146
|
+
</style>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import createForm from "./create-form/create-form.vue"
|
|
2
|
+
import editForm from "./edit-form/edit-form.vue"
|
|
3
|
+
import detailPanel from "./detail-panel/detail-panel.vue";
|
|
4
|
+
|
|
5
|
+
// 业务自定义组件注册
|
|
6
|
+
import BusinessComponentConfig from "$businessComponentConfig";
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
const ComponentConfig = {
|
|
10
|
+
createForm: {
|
|
11
|
+
component: createForm
|
|
12
|
+
},
|
|
13
|
+
editForm: {
|
|
14
|
+
component: editForm
|
|
15
|
+
},
|
|
16
|
+
detailPanel: {
|
|
17
|
+
component: detailPanel
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default {
|
|
22
|
+
...ComponentConfig,
|
|
23
|
+
...BusinessComponentConfig
|
|
24
|
+
}
|