@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.
Files changed (86) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc +55 -0
  3. package/.idea/dictionaries/project.xml +8 -0
  4. package/.idea/elpis.iml +8 -0
  5. package/.idea/git_toolbox_prj.xml +15 -0
  6. package/.idea/inspectionProfiles/Project_Default.xml +329 -0
  7. package/.idea/modules.xml +8 -0
  8. package/.idea/vcs.xml +6 -0
  9. package/README.md +201 -0
  10. package/app/controller/base.js +77 -0
  11. package/app/controller/project.js +69 -0
  12. package/app/controller/view.js +20 -0
  13. package/app/extend/logger.js +35 -0
  14. package/app/middleware/api-params-verify.js +74 -0
  15. package/app/middleware/api-sign-verify.js +33 -0
  16. package/app/middleware/error-hander.js +32 -0
  17. package/app/middleware/project-handler.js +25 -0
  18. package/app/middleware.js +37 -0
  19. package/app/pages/asserts/custom.css +11 -0
  20. package/app/pages/boot.js +43 -0
  21. package/app/pages/common/curl.js +83 -0
  22. package/app/pages/common/index.js +2 -0
  23. package/app/pages/common/utils.js +0 -0
  24. package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +23 -0
  25. package/app/pages/dashboard/complex-view/header-view/header-view.vue +117 -0
  26. package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +40 -0
  27. package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue +45 -0
  28. package/app/pages/dashboard/complex-view/schema-view/complex-view/tabel-panel/tabel-panel.vue +134 -0
  29. package/app/pages/dashboard/complex-view/schema-view/components/component-config.js +20 -0
  30. package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +89 -0
  31. package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +101 -0
  32. package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +128 -0
  33. package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +119 -0
  34. package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +96 -0
  35. package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +21 -0
  36. package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +117 -0
  37. package/app/pages/dashboard/dashboard.vue +88 -0
  38. package/app/pages/dashboard/entry.dashboard.js +41 -0
  39. package/app/pages/router/index.js +11 -0
  40. package/app/pages/store/index.js +4 -0
  41. package/app/pages/store/menu.js +65 -0
  42. package/app/pages/store/project.js +16 -0
  43. package/app/pages/widgets/header-container/asserts/avatar.png +0 -0
  44. package/app/pages/widgets/header-container/asserts/logo.png +0 -0
  45. package/app/pages/widgets/header-container/header-container.vue +103 -0
  46. package/app/pages/widgets/schema-form/complex-view/input/input.vue +142 -0
  47. package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +143 -0
  48. package/app/pages/widgets/schema-form/complex-view/select/select.vue +130 -0
  49. package/app/pages/widgets/schema-form/form-item-config.js +20 -0
  50. package/app/pages/widgets/schema-form/schema-form.vue +132 -0
  51. package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +48 -0
  52. package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +67 -0
  53. package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +40 -0
  54. package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +50 -0
  55. package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +142 -0
  56. package/app/pages/widgets/schema-search-bar/search-item-config.js +24 -0
  57. package/app/pages/widgets/schema-table/schema-table.vue +238 -0
  58. package/app/pages/widgets/sider-container/sider-container.vue +31 -0
  59. package/app/public/static/logo.png +0 -0
  60. package/app/public/static/normalize.css +239 -0
  61. package/app/router/project.js +9 -0
  62. package/app/router/view.js +7 -0
  63. package/app/router-schema/project.js +32 -0
  64. package/app/service/base.js +12 -0
  65. package/app/service/project.js +42 -0
  66. package/app/view/entry.tpl +26 -0
  67. package/app/webpack/config/webpack.base.js +219 -0
  68. package/app/webpack/config/webpack.dev.js +55 -0
  69. package/app/webpack/config/webpack.prod.js +118 -0
  70. package/app/webpack/dev.js +52 -0
  71. package/app/webpack/libs/blank.js +2 -0
  72. package/app/webpack/prod.js +18 -0
  73. package/config/config.default.js +3 -0
  74. package/elpis-core/env.js +20 -0
  75. package/elpis-core/index.js +92 -0
  76. package/elpis-core/loader/config.js +54 -0
  77. package/elpis-core/loader/controller.js +61 -0
  78. package/elpis-core/loader/extend.js +55 -0
  79. package/elpis-core/loader/middleware.js +61 -0
  80. package/elpis-core/loader/router-schema.js +39 -0
  81. package/elpis-core/loader/router.js +42 -0
  82. package/elpis-core/loader/service.js +64 -0
  83. package/index.js +41 -0
  84. package/model/index.js +105 -0
  85. package/package.json +94 -0
  86. 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;
@@ -0,0 +1,2 @@
1
+ const test ={}
2
+ export default test
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>
@@ -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>