@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.
Files changed (81) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc +59 -0
  3. package/.vscode/settings.json +15 -0
  4. package/README.md +198 -0
  5. package/app/controller/base.js +41 -0
  6. package/app/controller/project.js +98 -0
  7. package/app/controller/view.js +24 -0
  8. package/app/extend/logger.js +43 -0
  9. package/app/middleware/api-params-verify.js +89 -0
  10. package/app/middleware/api-sign-verify.js +47 -0
  11. package/app/middleware/error-handler.js +41 -0
  12. package/app/middleware/project-handler.js +27 -0
  13. package/app/middleware.js +40 -0
  14. package/app/pages/asserts/custom.css +12 -0
  15. package/app/pages/boot.js +59 -0
  16. package/app/pages/common/curl.js +88 -0
  17. package/app/pages/common/util.js +3 -0
  18. package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +40 -0
  19. package/app/pages/dashboard/complex-view/header-view/header-view.vue +141 -0
  20. package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +43 -0
  21. package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue +39 -0
  22. package/app/pages/dashboard/complex-view/schema-view/complex-view/table-panel/table-panel.vue +146 -0
  23. package/app/pages/dashboard/complex-view/schema-view/components/component-config.js +24 -0
  24. package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +118 -0
  25. package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +177 -0
  26. package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +157 -0
  27. package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +150 -0
  28. package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +113 -0
  29. package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +35 -0
  30. package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +134 -0
  31. package/app/pages/dashboard/dashboard.vue +127 -0
  32. package/app/pages/dashboard/entry.dashboard.js +46 -0
  33. package/app/pages/store/index.js +5 -0
  34. package/app/pages/store/menu.js +61 -0
  35. package/app/pages/store/project.js +13 -0
  36. package/app/pages/widgets/header-container/asserts/avatar.png +0 -0
  37. package/app/pages/widgets/header-container/asserts/logo.png +0 -0
  38. package/app/pages/widgets/header-container/header-container.vue +144 -0
  39. package/app/pages/widgets/schema-form/complex-view/input/input.vue +165 -0
  40. package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +166 -0
  41. package/app/pages/widgets/schema-form/complex-view/select/select.vue +144 -0
  42. package/app/pages/widgets/schema-form/form-item.config.js +24 -0
  43. package/app/pages/widgets/schema-form/schema-form.vue +144 -0
  44. package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +57 -0
  45. package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +77 -0
  46. package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +51 -0
  47. package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +58 -0
  48. package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +138 -0
  49. package/app/pages/widgets/schema-search-bar/search-item-config.js +27 -0
  50. package/app/pages/widgets/schema-table/schema-table.vue +254 -0
  51. package/app/pages/widgets/sider-container/sider-container.vue +32 -0
  52. package/app/router/business.js +15 -0
  53. package/app/router/project.js +10 -0
  54. package/app/router/view.js +11 -0
  55. package/app/router-schema/business.js +82 -0
  56. package/app/router-schema/project.js +40 -0
  57. package/app/service/base.js +13 -0
  58. package/app/service/project.js +55 -0
  59. package/app/view/entry.tpl +27 -0
  60. package/app/webpack/config/blank.js +3 -0
  61. package/app/webpack/config/webpack.base.js +269 -0
  62. package/app/webpack/config/webpack.dev.js +61 -0
  63. package/app/webpack/config/webpack.prod.js +149 -0
  64. package/app/webpack/dev.js +58 -0
  65. package/app/webpack/prod.js +21 -0
  66. package/config/config.default.js +3 -0
  67. package/elpis-core/env.js +22 -0
  68. package/elpis-core/index.js +99 -0
  69. package/elpis-core/loader/config.js +51 -0
  70. package/elpis-core/loader/controller.js +75 -0
  71. package/elpis-core/loader/extend.js +54 -0
  72. package/elpis-core/loader/middleware.js +69 -0
  73. package/elpis-core/loader/router-schema.js +50 -0
  74. package/elpis-core/loader/router.js +52 -0
  75. package/elpis-core/loader/service.js +74 -0
  76. package/index.js +29 -0
  77. package/jsconfig.json +16 -0
  78. package/logs/applocation.log +3 -0
  79. package/model/index.js +119 -0
  80. package/package.json +93 -0
  81. 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,12 @@
1
+ html, body{
2
+ height: 100%;
3
+ }
4
+
5
+ #root{
6
+ height: 100%;
7
+ }
8
+
9
+ input:-webkit-autofill {
10
+ /* 覆盖自动填充背景颜色 */
11
+ -webkit-box-shadow: 0 0 0px 1000px white inset ;
12
+ }
@@ -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,3 @@
1
+ const utils = {}
2
+
3
+ export default utils
@@ -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>
@@ -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
+ }