@lixianwei/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 +2 -0
- package/.eslintrc +55 -0
- package/.idea/dictionaries/project.xml +8 -0
- package/.idea/elpis.iml +8 -0
- package/.idea/git_toolbox_prj.xml +15 -0
- package/.idea/inspectionProfiles/Project_Default.xml +329 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/README.md +201 -0
- package/app/controller/base.js +77 -0
- package/app/controller/project.js +69 -0
- package/app/controller/view.js +20 -0
- package/app/extend/logger.js +35 -0
- package/app/middleware/api-params-verify.js +74 -0
- package/app/middleware/api-sign-verify.js +33 -0
- package/app/middleware/error-hander.js +32 -0
- package/app/middleware/project-handler.js +25 -0
- package/app/middleware.js +37 -0
- package/app/pages/asserts/custom.css +11 -0
- package/app/pages/boot.js +43 -0
- package/app/pages/common/curl.js +83 -0
- package/app/pages/common/index.js +2 -0
- package/app/pages/common/utils.js +0 -0
- package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +23 -0
- package/app/pages/dashboard/complex-view/header-view/header-view.vue +117 -0
- package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +40 -0
- package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue +45 -0
- package/app/pages/dashboard/complex-view/schema-view/complex-view/tabel-panel/tabel-panel.vue +134 -0
- package/app/pages/dashboard/complex-view/schema-view/components/component-config.js +20 -0
- package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +89 -0
- package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +101 -0
- package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +128 -0
- package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +119 -0
- package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +96 -0
- package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +21 -0
- package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +117 -0
- package/app/pages/dashboard/dashboard.vue +88 -0
- package/app/pages/dashboard/entry.dashboard.js +41 -0
- package/app/pages/router/index.js +11 -0
- package/app/pages/store/index.js +4 -0
- package/app/pages/store/menu.js +65 -0
- package/app/pages/store/project.js +16 -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 +103 -0
- package/app/pages/widgets/schema-form/complex-view/input/input.vue +142 -0
- package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +143 -0
- package/app/pages/widgets/schema-form/complex-view/select/select.vue +130 -0
- package/app/pages/widgets/schema-form/form-item-config.js +20 -0
- package/app/pages/widgets/schema-form/schema-form.vue +132 -0
- package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +48 -0
- package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +67 -0
- package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +40 -0
- package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +50 -0
- package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +142 -0
- package/app/pages/widgets/schema-search-bar/search-item-config.js +24 -0
- package/app/pages/widgets/schema-table/schema-table.vue +238 -0
- package/app/pages/widgets/sider-container/sider-container.vue +31 -0
- package/app/public/static/logo.png +0 -0
- package/app/public/static/normalize.css +239 -0
- package/app/router/project.js +9 -0
- package/app/router/view.js +7 -0
- package/app/router-schema/project.js +32 -0
- package/app/service/base.js +12 -0
- package/app/service/project.js +42 -0
- package/app/view/entry.tpl +26 -0
- package/app/webpack/config/webpack.base.js +219 -0
- package/app/webpack/config/webpack.dev.js +55 -0
- package/app/webpack/config/webpack.prod.js +118 -0
- package/app/webpack/dev.js +52 -0
- package/app/webpack/libs/blank.js +2 -0
- package/app/webpack/prod.js +18 -0
- package/config/config.default.js +3 -0
- package/elpis-core/env.js +20 -0
- package/elpis-core/index.js +92 -0
- package/elpis-core/loader/config.js +54 -0
- package/elpis-core/loader/controller.js +61 -0
- package/elpis-core/loader/extend.js +55 -0
- package/elpis-core/loader/middleware.js +61 -0
- package/elpis-core/loader/router-schema.js +39 -0
- package/elpis-core/loader/router.js +42 -0
- package/elpis-core/loader/service.js +64 -0
- package/index.js +41 -0
- package/model/index.js +105 -0
- package/package.json +94 -0
- package/test/controller/project.test.js +194 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
const md5 = require('md5')
|
|
2
|
+
const axios = require('axios');
|
|
3
|
+
import { ElMessage } from 'element-plus'
|
|
4
|
+
/*
|
|
5
|
+
* 前端封装的curl 方法
|
|
6
|
+
* @params options 请求参数
|
|
7
|
+
* */
|
|
8
|
+
|
|
9
|
+
const curl = ({
|
|
10
|
+
url, //请求地址
|
|
11
|
+
method = "post", //请求方法
|
|
12
|
+
headers = {}, //请求头
|
|
13
|
+
query = {}, // url query
|
|
14
|
+
data ={}, // post body
|
|
15
|
+
responseType = "json", //response data type
|
|
16
|
+
timeOut=60000, //timeOut
|
|
17
|
+
errorMessage="网络异常"
|
|
18
|
+
})=>{
|
|
19
|
+
|
|
20
|
+
// 接口签名处理(让接口变动态)
|
|
21
|
+
const signKey = 'klx05hb3n1c9ujp8uhxbs2ikkiowp212'
|
|
22
|
+
const st = Date.now()
|
|
23
|
+
|
|
24
|
+
const dtoHeaders ={
|
|
25
|
+
...headers,
|
|
26
|
+
s_t:st,
|
|
27
|
+
s_sign:md5(`${signKey}_${st}`)
|
|
28
|
+
}
|
|
29
|
+
if(url.indexOf('/api/proj/')>-1 && window.projKey){
|
|
30
|
+
dtoHeaders.proj_Key = window.projKey
|
|
31
|
+
}
|
|
32
|
+
// 构造请求参数 把参数转换为axios 参数
|
|
33
|
+
const ajaxStting={
|
|
34
|
+
url, //请求地址
|
|
35
|
+
method, //请求方法
|
|
36
|
+
params:query, // url query
|
|
37
|
+
data, // post body
|
|
38
|
+
responseType, //response data type
|
|
39
|
+
timeOut, //timeOut
|
|
40
|
+
headers: dtoHeaders
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
return axios.request(ajaxStting).then(response=>{
|
|
44
|
+
// 后端返回格式
|
|
45
|
+
const resData = response?.data || {};
|
|
46
|
+
|
|
47
|
+
const {success} = resData;
|
|
48
|
+
// 失败
|
|
49
|
+
if(!success){
|
|
50
|
+
const {code, message} = resData;
|
|
51
|
+
if(code === 442){
|
|
52
|
+
ElMessage.error('请求参数异常')
|
|
53
|
+
}else if(code === 445){
|
|
54
|
+
ElMessage.error('请求不合法')
|
|
55
|
+
}else if(code === 446){
|
|
56
|
+
ElMessage.error('缺少项目必要参数')
|
|
57
|
+
}else if(code === 50000){
|
|
58
|
+
ElMessage.error(errorMessage)
|
|
59
|
+
}
|
|
60
|
+
console.error(message)
|
|
61
|
+
|
|
62
|
+
return Promise.resolve({success,code,message})
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
// 成功
|
|
67
|
+
const {data,metadata} = resData;
|
|
68
|
+
return Promise.resolve({success,data,metadata})
|
|
69
|
+
|
|
70
|
+
}).catch(error=>{
|
|
71
|
+
const {message} = error;
|
|
72
|
+
if(message.match(/timeout/)){
|
|
73
|
+
return Promise.resolve({
|
|
74
|
+
message:'Request Timeout',
|
|
75
|
+
code:504
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return Promise.resolve(error)
|
|
79
|
+
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export default curl;
|
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-sub-menu :index="menuItem.key">
|
|
3
|
+
<template #title>{{menuItem.name}}</template>
|
|
4
|
+
<div :key="item.key" v-for="item in menuItem.subMenu">
|
|
5
|
+
<sub-menu v-if="item.subMenu&& item.subMenu.length>0">
|
|
6
|
+
:menu-item="item
|
|
7
|
+
</sub-menu>
|
|
8
|
+
<el-menu-item v-else :index="item.key">
|
|
9
|
+
{{item.name}}
|
|
10
|
+
</el-menu-item>
|
|
11
|
+
</div>
|
|
12
|
+
</el-sub-menu>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script setup>
|
|
16
|
+
const { menuItem } = defineProps(['menuItem']);
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
<style scoped lang="less">
|
|
22
|
+
|
|
23
|
+
</style>
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
<template>
|
|
4
|
+
<header-container :title="projName">
|
|
5
|
+
<template #menu-content>
|
|
6
|
+
<!-- 根据menuStore.menuList 渲染-->
|
|
7
|
+
<el-menu
|
|
8
|
+
:default-active="activeKey"
|
|
9
|
+
:ellipsis="false"
|
|
10
|
+
mode="horizontal"
|
|
11
|
+
@select="onMenuSelect">
|
|
12
|
+
<template v-for="item in menuStore.menuList" :key="item.key">
|
|
13
|
+
<sub-menu v-if="item.subMenu &&item.subMenu.length>0" :menu-item="item">
|
|
14
|
+
</sub-menu>
|
|
15
|
+
<el-menu-item v-else :index="item.key">
|
|
16
|
+
{{ item.name }}
|
|
17
|
+
</el-menu-item>
|
|
18
|
+
</template>
|
|
19
|
+
</el-menu>
|
|
20
|
+
</template>
|
|
21
|
+
<template #setting-content>
|
|
22
|
+
<!-- 根据projectStore.projectList 渲染-->
|
|
23
|
+
<el-dropdown @command="handleProjectCommand">
|
|
24
|
+
<span class="project-list">
|
|
25
|
+
{{projName}}
|
|
26
|
+
<el-icon v-if="projectStore.projectList.length>1" class="el-icon--right">
|
|
27
|
+
<ArrowDown></ArrowDown>
|
|
28
|
+
</el-icon>
|
|
29
|
+
</span>
|
|
30
|
+
<template v-if="projectStore.projectList.length>1" #dropdown>
|
|
31
|
+
<el-dropdown-item
|
|
32
|
+
v-for="item in projectStore.projectList"
|
|
33
|
+
:key="item.key"
|
|
34
|
+
:command="item.key"
|
|
35
|
+
:disabled="item.name === projName"
|
|
36
|
+
>
|
|
37
|
+
{{item.name}}
|
|
38
|
+
</el-dropdown-item>
|
|
39
|
+
</template>
|
|
40
|
+
</el-dropdown>
|
|
41
|
+
</template>
|
|
42
|
+
<template #main-content>
|
|
43
|
+
<slot name="main-content"></slot>
|
|
44
|
+
</template>
|
|
45
|
+
</header-container>
|
|
46
|
+
</template>
|
|
47
|
+
<script setup >
|
|
48
|
+
import {ref,watch,onMounted} from "vue";
|
|
49
|
+
import {useRoute} from "vue-router";
|
|
50
|
+
import {ArrowDown} from '@element-plus/icons-vue'
|
|
51
|
+
import HeaderContainer from '$elpisWidgets/header-container/header-container.vue'
|
|
52
|
+
import SubMenu from './complex-view/sub-menu/sub-menu.vue'
|
|
53
|
+
import {userMenuStore} from '$elpisStore/menu.js'
|
|
54
|
+
import {userProjectStore} from '$elpisStore/project.js'
|
|
55
|
+
|
|
56
|
+
const route = useRoute()
|
|
57
|
+
const menuStore = userMenuStore()
|
|
58
|
+
const projectStore = userProjectStore()
|
|
59
|
+
defineProps({
|
|
60
|
+
projName: {
|
|
61
|
+
type: String,
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
const emit = defineEmits(['menu-select'])
|
|
65
|
+
|
|
66
|
+
const activeKey = ref('')
|
|
67
|
+
|
|
68
|
+
watch(()=> route.query.key, () => {
|
|
69
|
+
setActiveKey()
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
watch(() => menuStore.menuList, () => {
|
|
73
|
+
setActiveKey()
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
onMounted(() => {
|
|
77
|
+
setActiveKey()
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
const setActiveKey = () => {
|
|
81
|
+
const menuItem = menuStore.findMenuItem({
|
|
82
|
+
key:'key',
|
|
83
|
+
value:route.query.key
|
|
84
|
+
})
|
|
85
|
+
activeKey.value = menuItem?.key
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const onMenuSelect =(menuKey)=>{
|
|
89
|
+
const menuItem = menuStore.findMenuItem({key:'key',value:menuKey})
|
|
90
|
+
emit('menu-select',menuItem)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const handleProjectCommand =(event)=>{
|
|
94
|
+
const projectItem = projectStore.projectList.find(item => item.key === event)
|
|
95
|
+
|
|
96
|
+
if(!projectItem || !projectItem.homePage) {return }
|
|
97
|
+
const {origin} = window.location
|
|
98
|
+
// window.location.replace(`${origin}${pathname}${projectItem.homePage}`)
|
|
99
|
+
window.location.replace(`${origin}/view/dashboard${projectItem.homePage}`)
|
|
100
|
+
// window.location.reload()
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
</script>
|
|
104
|
+
<style scoped lang="less">
|
|
105
|
+
.project-list{
|
|
106
|
+
margin-right: 20px;
|
|
107
|
+
cursor: pointer;
|
|
108
|
+
color:var(--el-color-primary);
|
|
109
|
+
display: flex;
|
|
110
|
+
align-items: center;
|
|
111
|
+
outline: none;
|
|
112
|
+
}
|
|
113
|
+
:deep(.el-menu--horizontal.el-menu){
|
|
114
|
+
border-bottom: 0;
|
|
115
|
+
background: none;
|
|
116
|
+
}
|
|
117
|
+
</style>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<iframe :src="path" class="iframe"></iframe>
|
|
3
|
+
</template>
|
|
4
|
+
<script setup>
|
|
5
|
+
import {ref,watch,onMounted} from 'vue'
|
|
6
|
+
import {useRoute} from 'vue-router'
|
|
7
|
+
import {userMenuStore} from "$elpisStore/menu";
|
|
8
|
+
const menuStore = userMenuStore()
|
|
9
|
+
const route = useRoute()
|
|
10
|
+
const path = ref('')
|
|
11
|
+
|
|
12
|
+
const setPath =()=>{
|
|
13
|
+
const {key,sider_key:siderKey} = route.query
|
|
14
|
+
const menuItem = menuStore.findMenuItem({
|
|
15
|
+
key:'key',
|
|
16
|
+
value:siderKey ?? key
|
|
17
|
+
})
|
|
18
|
+
path.value = menuItem?.iframeConfig?.path ?? ''
|
|
19
|
+
}
|
|
20
|
+
watch([
|
|
21
|
+
()=> route.query.key,
|
|
22
|
+
()=>route.query.sider_key,
|
|
23
|
+
()=>menuStore.menuList
|
|
24
|
+
],()=>{
|
|
25
|
+
setPath()
|
|
26
|
+
},{deep:true})
|
|
27
|
+
|
|
28
|
+
onMounted(() => {
|
|
29
|
+
setPath()
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<style scoped lang="less">
|
|
35
|
+
.iframe{
|
|
36
|
+
margin:0;
|
|
37
|
+
width: 100%;
|
|
38
|
+
height: 100%;
|
|
39
|
+
}
|
|
40
|
+
</style>
|
package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-card class="search-panel">
|
|
3
|
+
<schema-search-bar
|
|
4
|
+
:schema="searchSchema"
|
|
5
|
+
@load="onLoad"
|
|
6
|
+
@search="onSearch"
|
|
7
|
+
@reset="onReset"
|
|
8
|
+
></schema-search-bar>
|
|
9
|
+
</el-card>
|
|
10
|
+
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script setup>
|
|
14
|
+
import { inject } from "vue";
|
|
15
|
+
import SchemaSearchBar from '$elpisWidgets/schema-search-bar/schema-search-bar.vue'
|
|
16
|
+
const {searchSchema} = inject('schemaViewData')
|
|
17
|
+
const emit = defineEmits(['search'])
|
|
18
|
+
|
|
19
|
+
// 加载
|
|
20
|
+
const onLoad =(searchValObj)=>{
|
|
21
|
+
console.log(12456789)
|
|
22
|
+
emit('search', searchValObj)
|
|
23
|
+
}
|
|
24
|
+
// 搜索
|
|
25
|
+
const onSearch =(searchValObj)=>{
|
|
26
|
+
emit('search', searchValObj)
|
|
27
|
+
}
|
|
28
|
+
// 重置
|
|
29
|
+
const onReset = ()=>{
|
|
30
|
+
emit('search', {})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
<style scoped lang="less">
|
|
39
|
+
.search-panel{
|
|
40
|
+
margin: 10px;
|
|
41
|
+
:deep(.el-card__body){
|
|
42
|
+
padding-bottom: 2px;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
</style>
|
|
@@ -0,0 +1,134 @@
|
|
|
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="operationHander({btnConfig: item})"
|
|
13
|
+
>
|
|
14
|
+
{{item.label}}
|
|
15
|
+
</el-button>
|
|
16
|
+
|
|
17
|
+
</el-row>
|
|
18
|
+
<!--schema-tabel (组件widget)-->
|
|
19
|
+
<schema-table
|
|
20
|
+
ref="schemaTableRef"
|
|
21
|
+
:schema="tableSchema"
|
|
22
|
+
:api="api"
|
|
23
|
+
:apiParams="apiParams"
|
|
24
|
+
:buttons="tableConfig?.rowButtons ?? []"
|
|
25
|
+
@operate="operationHander"
|
|
26
|
+
></schema-table>
|
|
27
|
+
</el-card>
|
|
28
|
+
</template>
|
|
29
|
+
<script setup>
|
|
30
|
+
import {ref,inject} from "vue";
|
|
31
|
+
import {ElMessageBox,ElNotification} from "element-plus";
|
|
32
|
+
import $curl from '$elpisCommon/curl.js'
|
|
33
|
+
import SchemaTable from '$elpisWidgets/schema-table/schema-table.vue'
|
|
34
|
+
|
|
35
|
+
const emit = defineEmits(['operate'])
|
|
36
|
+
|
|
37
|
+
const schemaTableRef = ref()
|
|
38
|
+
|
|
39
|
+
const {
|
|
40
|
+
api,
|
|
41
|
+
tableSchema,
|
|
42
|
+
tableConfig,
|
|
43
|
+
apiParams
|
|
44
|
+
} = inject('schemaViewData');
|
|
45
|
+
|
|
46
|
+
// 删除操作
|
|
47
|
+
const removeData = ({btnConfig,rowData})=>{
|
|
48
|
+
const {eventOption} = btnConfig;
|
|
49
|
+
if(!eventOption?.params){return}
|
|
50
|
+
|
|
51
|
+
const { params } = eventOption;
|
|
52
|
+
const removeKey = Object.keys(params)[0]
|
|
53
|
+
let removeValue;
|
|
54
|
+
const removeValueList = params[removeKey].split('::');
|
|
55
|
+
if(removeValueList[0]==='schema'&&removeValueList[1]){
|
|
56
|
+
removeValue = rowData[removeValueList[1]];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
ElMessageBox.confirm(
|
|
60
|
+
`确认删除${removeKey}为${removeValue}的数据?`,
|
|
61
|
+
'Waring',
|
|
62
|
+
{
|
|
63
|
+
confirmButtonText: '确认',
|
|
64
|
+
cancelButtonText:'取消',
|
|
65
|
+
type: 'warning'
|
|
66
|
+
}
|
|
67
|
+
).then(async() => {
|
|
68
|
+
const res = await $curl({
|
|
69
|
+
method:"delete",
|
|
70
|
+
url:api.value,
|
|
71
|
+
data:{
|
|
72
|
+
[removeKey]:removeValue,
|
|
73
|
+
},
|
|
74
|
+
errorMessage:'删除失败'
|
|
75
|
+
});
|
|
76
|
+
schemaTableRef.value.hideLoading();
|
|
77
|
+
if(!res ||!res.success || !res.data){
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
ElNotification({
|
|
81
|
+
title:'删除成功',
|
|
82
|
+
message:'删除成功',
|
|
83
|
+
type: 'success',
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
await initTableData()
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
const EventHandlerMap = {
|
|
92
|
+
remove:removeData
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const operationHander =({btnConfig,rowData})=>{
|
|
96
|
+
const {eventKey} = btnConfig;
|
|
97
|
+
|
|
98
|
+
if(EventHandlerMap[eventKey]){
|
|
99
|
+
EventHandlerMap[eventKey]({btnConfig,rowData})
|
|
100
|
+
}else{
|
|
101
|
+
emit('operate',{btnConfig,rowData})
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const initTableData = async()=>{
|
|
107
|
+
await schemaTableRef.value.initData()
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const loadTableData = async () => {
|
|
111
|
+
await schemaTableRef.value.loadTableData()
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
defineExpose({
|
|
115
|
+
loadTableData
|
|
116
|
+
})
|
|
117
|
+
</script>
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
<style scoped lang="less">
|
|
122
|
+
.table-panel{
|
|
123
|
+
flex: 1;
|
|
124
|
+
margin: 10px;
|
|
125
|
+
.operation-panel{
|
|
126
|
+
margin-bottom: 10px;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
:deep(.el-card__body){
|
|
130
|
+
height: 98%;
|
|
131
|
+
display: flex;
|
|
132
|
+
flex-direction: column;
|
|
133
|
+
}
|
|
134
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import createForm from './create-form/create-form';
|
|
2
|
+
import editForm from './edit-form/edit-form';
|
|
3
|
+
import detailPanel from './detail-panel/detail-panel';
|
|
4
|
+
import BusinessComponentConfig from '$businessComponentConfig'
|
|
5
|
+
|
|
6
|
+
const ComponentConfig ={
|
|
7
|
+
createForm:{
|
|
8
|
+
component:createForm
|
|
9
|
+
},
|
|
10
|
+
editForm:{
|
|
11
|
+
component:editForm
|
|
12
|
+
},
|
|
13
|
+
detailPanel:{
|
|
14
|
+
component:detailPanel
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export default {
|
|
18
|
+
...ComponentConfig,
|
|
19
|
+
...BusinessComponentConfig
|
|
20
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
|
|
2
|
+
<template>
|
|
3
|
+
<el-drawer
|
|
4
|
+
v-model="isShow"
|
|
5
|
+
direction="rtl"
|
|
6
|
+
:destroy-on-close="true"
|
|
7
|
+
:size="550"
|
|
8
|
+
>
|
|
9
|
+
<template #header>
|
|
10
|
+
<h3 class="title">
|
|
11
|
+
{{title}}
|
|
12
|
+
</h3>
|
|
13
|
+
</template>
|
|
14
|
+
<template #default>
|
|
15
|
+
<schema-form v-loading="loading" ref="schemaFormRef" :schema="components[name].schema"></schema-form>
|
|
16
|
+
</template>
|
|
17
|
+
<template #footer>
|
|
18
|
+
<el-button type="primary" @click="save">{{saveBtnText}}</el-button>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
</el-drawer>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<script setup >
|
|
25
|
+
import {inject, ref} from 'vue'
|
|
26
|
+
import {ElNotification} from 'element-plus'
|
|
27
|
+
import $curl from '$elpisCommon/curl.js'
|
|
28
|
+
import SchemaForm from '$elpisWidgets/schema-form/schema-form.vue'
|
|
29
|
+
|
|
30
|
+
const {api,components} = inject('schemaViewData')
|
|
31
|
+
|
|
32
|
+
const emit =defineEmits(['command'])
|
|
33
|
+
const name = ref('createForm')
|
|
34
|
+
|
|
35
|
+
const loading = ref(false)
|
|
36
|
+
const schemaFormRef = ref(null)
|
|
37
|
+
const title = ref()
|
|
38
|
+
const saveBtnText =ref()
|
|
39
|
+
const isShow = ref(false)
|
|
40
|
+
|
|
41
|
+
const show =(rowData)=>{
|
|
42
|
+
const {config} = components.value[name.value]
|
|
43
|
+
title.value = config.title
|
|
44
|
+
saveBtnText.value = config.saveBtnText
|
|
45
|
+
isShow.value = true
|
|
46
|
+
console.log(rowData)
|
|
47
|
+
}
|
|
48
|
+
const close=()=>{
|
|
49
|
+
isShow.value = false
|
|
50
|
+
}
|
|
51
|
+
const save = async ()=>{
|
|
52
|
+
if( loading.value || !schemaFormRef.value.validate() ){
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
loading.value = true
|
|
57
|
+
const res = await $curl({
|
|
58
|
+
method: 'post',
|
|
59
|
+
url: api.value,
|
|
60
|
+
data:{
|
|
61
|
+
...schemaFormRef.value.getValue(),
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
loading.value = false
|
|
65
|
+
if(!res || !res.success){
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
ElNotification({
|
|
69
|
+
title:'创建成功',
|
|
70
|
+
message:'创建成功',
|
|
71
|
+
type: 'success'
|
|
72
|
+
})
|
|
73
|
+
close()
|
|
74
|
+
|
|
75
|
+
emit('command',{
|
|
76
|
+
event:'loadTableData',
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
defineExpose({
|
|
81
|
+
name,
|
|
82
|
+
show
|
|
83
|
+
})
|
|
84
|
+
</script>
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
<style scoped lang="less">
|
|
88
|
+
|
|
89
|
+
</style>
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-drawer
|
|
3
|
+
v-model="isShow"
|
|
4
|
+
direction="rtl"
|
|
5
|
+
:destroy-on-close="true"
|
|
6
|
+
:size="550"
|
|
7
|
+
>
|
|
8
|
+
<template #header>
|
|
9
|
+
<h3>{{ title }}</h3>
|
|
10
|
+
</template>
|
|
11
|
+
<template #default>
|
|
12
|
+
<el-card v-loading="loading" shadow="always" class="detail-panel">
|
|
13
|
+
<el-row
|
|
14
|
+
v-for="(item,key) in components[name]?.schema?.properties"
|
|
15
|
+
:key="key"
|
|
16
|
+
type="flex"
|
|
17
|
+
align="middle"
|
|
18
|
+
class="row-item"
|
|
19
|
+
>
|
|
20
|
+
<el-row class="item-label">
|
|
21
|
+
{{item.label}}
|
|
22
|
+
</el-row>
|
|
23
|
+
<el-row class="item-value">
|
|
24
|
+
{{ dtoModel[key]}}
|
|
25
|
+
</el-row>
|
|
26
|
+
</el-row>
|
|
27
|
+
</el-card>
|
|
28
|
+
</template>
|
|
29
|
+
</el-drawer>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<script setup>
|
|
33
|
+
import {ref,inject} from 'vue'
|
|
34
|
+
import $curl from '$elpisCommon/curl.js'
|
|
35
|
+
|
|
36
|
+
const {api,components}=inject('schemaViewData')
|
|
37
|
+
|
|
38
|
+
const name = ref('detailPanel')
|
|
39
|
+
const isShow = ref(false)
|
|
40
|
+
const loading = ref(false)
|
|
41
|
+
const title = ref('')
|
|
42
|
+
const mainKey = ref() //表单主键
|
|
43
|
+
const mainValue = ref({}) //表单主键值
|
|
44
|
+
const dtoModel = ref({})
|
|
45
|
+
|
|
46
|
+
const show = (rowData)=>{
|
|
47
|
+
const {config} = components.value[name.value]
|
|
48
|
+
title.value = config.title
|
|
49
|
+
mainKey.value = config.mainKey
|
|
50
|
+
mainValue.value = rowData[config.mainKey]
|
|
51
|
+
isShow.value = true
|
|
52
|
+
|
|
53
|
+
fetchFormData()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const fetchFormData = async ()=>{
|
|
57
|
+
if(loading.value){return}
|
|
58
|
+
loading.value = true
|
|
59
|
+
const res = await $curl({
|
|
60
|
+
method: 'get',
|
|
61
|
+
url:api.value,
|
|
62
|
+
query:{
|
|
63
|
+
[mainKey.value]: mainValue.value,
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
loading.value = false
|
|
67
|
+
if(!res || !res.success || !res.data){ return }
|
|
68
|
+
dtoModel.value = res.data
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
defineExpose({
|
|
73
|
+
name,
|
|
74
|
+
show
|
|
75
|
+
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
</script>
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
<style scoped lang="less">
|
|
83
|
+
.detail-panel{
|
|
84
|
+
border: 1px solid #a6a6a6;
|
|
85
|
+
padding: 30px;
|
|
86
|
+
.row-item{
|
|
87
|
+
height: 40px;
|
|
88
|
+
line-height: 40px;
|
|
89
|
+
font-size: 20px;
|
|
90
|
+
.item-label{
|
|
91
|
+
margin-right: 20px;
|
|
92
|
+
width: 120px;
|
|
93
|
+
color: #ffffff;
|
|
94
|
+
}
|
|
95
|
+
.item-value{
|
|
96
|
+
color: #d2dae4;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
}
|
|
101
|
+
</style>
|