@misstalor17/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 (84) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc +56 -0
  3. package/README.md +6 -0
  4. package/app/controller/base.js +43 -0
  5. package/app/controller/business.js +121 -0
  6. package/app/controller/project.js +75 -0
  7. package/app/controller/view.js +24 -0
  8. package/app/extend/logger.js +37 -0
  9. package/app/middleware/api-params-verify.js +70 -0
  10. package/app/middleware/api-sign-verify.js +31 -0
  11. package/app/middleware/error-handler.js +32 -0
  12. package/app/middleware/project-handler.js +28 -0
  13. package/app/middleware.js +44 -0
  14. package/app/pages/asserts/custom.css +12 -0
  15. package/app/pages/boot.js +45 -0
  16. package/app/pages/common/curl.js +96 -0
  17. package/app/pages/common/utils.js +2 -0
  18. package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu.vue +22 -0
  19. package/app/pages/dashboard/complex-view/header-view/header-view.vue +106 -0
  20. package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +45 -0
  21. package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue +33 -0
  22. package/app/pages/dashboard/complex-view/schema-view/complex-view/table-panel/table-panel.vue +105 -0
  23. package/app/pages/dashboard/complex-view/schema-view/components/component-config.js +23 -0
  24. package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +85 -0
  25. package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +90 -0
  26. package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +113 -0
  27. package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +109 -0
  28. package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +66 -0
  29. package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +17 -0
  30. package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +116 -0
  31. package/app/pages/dashboard/dashboard.vue +96 -0
  32. package/app/pages/dashboard/entry.dashboard.js +45 -0
  33. package/app/pages/store/index.js +3 -0
  34. package/app/pages/store/menu.js +60 -0
  35. package/app/pages/store/project.js +17 -0
  36. package/app/pages/widgets/header-container/asserts/logo.png +0 -0
  37. package/app/pages/widgets/header-container/asserts/user.png +0 -0
  38. package/app/pages/widgets/header-container/header-container.vue +105 -0
  39. package/app/pages/widgets/schema-form/complex-view/input/input.vue +120 -0
  40. package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +121 -0
  41. package/app/pages/widgets/schema-form/complex-view/select/select.vue +106 -0
  42. package/app/pages/widgets/schema-form/form-item-config.js +20 -0
  43. package/app/pages/widgets/schema-form/schema-form.vue +122 -0
  44. package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +42 -0
  45. package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +55 -0
  46. package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +37 -0
  47. package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +41 -0
  48. package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +109 -0
  49. package/app/pages/widgets/schema-search-bar/search-item-config.js +23 -0
  50. package/app/pages/widgets/schema-table/schema.table.vue +191 -0
  51. package/app/pages/widgets/sider-container/sider-container.vue +34 -0
  52. package/app/public/static/logo.png +0 -0
  53. package/app/public/static/normalize.css +240 -0
  54. package/app/router/business.js +9 -0
  55. package/app/router/project.js +6 -0
  56. package/app/router/view.js +13 -0
  57. package/app/router-schema/business.js +82 -0
  58. package/app/router-schema/project.js +31 -0
  59. package/app/service/base.js +13 -0
  60. package/app/service/project.js +40 -0
  61. package/app/view/entry.tpl +25 -0
  62. package/app/webpack/config/webpack.base.js +204 -0
  63. package/app/webpack/config/webpack.dev.js +56 -0
  64. package/app/webpack/config/webpack.prod.js +116 -0
  65. package/app/webpack/dev.js +52 -0
  66. package/app/webpack/libs/blank.js +1 -0
  67. package/app/webpack/prod.js +17 -0
  68. package/config/config.default.js +3 -0
  69. package/docs/dashboard-model.js +143 -0
  70. package/elpis-core/env.js +23 -0
  71. package/elpis-core/index.js +93 -0
  72. package/elpis-core/loader/config.js +52 -0
  73. package/elpis-core/loader/controller.js +61 -0
  74. package/elpis-core/loader/extend.js +52 -0
  75. package/elpis-core/loader/middleware.js +61 -0
  76. package/elpis-core/loader/router-schema.js +46 -0
  77. package/elpis-core/loader/router.js +43 -0
  78. package/elpis-core/loader/service.js +61 -0
  79. package/index.js +38 -0
  80. package/model/buiness/model.js +200 -0
  81. package/model/index.js +93 -0
  82. package/npminstall-debug.log +218 -0
  83. package/package.json +92 -0
  84. package/test/controller/project.test.js +194 -0
@@ -0,0 +1,96 @@
1
+ const md5 = require('md5')
2
+ import { ElMessage } from 'element-plus'
3
+ import axios from 'axios';
4
+ /**
5
+ * 前端封装的curl方法
6
+ * @param {Object} options - 请求配置项
7
+ * @param {string} options.url - 请求地址
8
+ * @param {string} [options.method='post'] - 请求方法(get/post/put/delete 等)
9
+ * @param {Object} [options.headers={}] - 请求头
10
+ * @param {Object} [options.query={}] - URL 查询参数(拼接在 url 后)
11
+ * @param {Object} [options.data={}] - 请求体数据(post/put 等方法使用)
12
+ * @param {string} [options.responseType='json'] - 响应数据类型
13
+ * @param {number} [options.timeout=60000] - 请求超时时间(毫秒)
14
+ * @param {string} [options.errorMessage='网络异常,请稍后重试'] - 默认错误提示语
15
+ * @returns {Promise<Object>} 响应数据
16
+ */
17
+
18
+ const curl = ({
19
+ url,//请求地址
20
+ method = 'post',//请求方法
21
+ headers = {},//请求头
22
+ query = {},//url query
23
+ data = {},//post data
24
+ responseType = 'json',//response data type
25
+ timeout = 60000,
26
+ errorMessage = '网络异常'
27
+ }) => {
28
+ //接口签名处理(让接口变动态)
29
+ const signKey = 'AShdahsdoahdsoanjsdoaiuhd13'
30
+ const st = Date.now()
31
+ const dtoHeaders = {
32
+ ...headers,
33
+ s_t: st,
34
+ s_sign: md5(`${signKey}_${st}`)
35
+ }
36
+ if(url.indexOf('/api/proj/') > -1 && window.projKey){
37
+ dtoHeaders.proj_key = window.projKey
38
+ }
39
+ //构造请求参数(把参数转换为 axios 参数)
40
+ const ajaxSetting = {
41
+ url,
42
+ method,
43
+ params: query,
44
+ data,
45
+ responseType,
46
+ timeout,
47
+ headers: dtoHeaders
48
+ }
49
+
50
+ return axios.request(ajaxSetting).then((response) => {
51
+ const resData = response.data || {}
52
+ //后端Api放回格式
53
+ const { success } = resData
54
+ //失败
55
+ if (!success) {
56
+ const { message, code } = resData
57
+ // if (code === 442) {
58
+ // ElMessage.error('请求参数异常')
59
+ // } else if (code === 445) {
60
+ // ElMessage.error('请求不合法')
61
+ // } else if (code === 50000) {
62
+ // ElMessage.error(message)
63
+ // } else {
64
+ // ElMessage.error(errorMessage)
65
+ // }
66
+ // 根据错误码展示对应提示
67
+ const errorTips = {
68
+ 442: '请求参数异常',
69
+ 445: '请求不合法',
70
+ 446:'缺少项目必要参数',
71
+ 50000: message,
72
+ default: errorMessage
73
+ };
74
+ ElMessage.error(errorTips[code] || errorTips.default);
75
+ console.log(message);
76
+ return Promise.resolve({ success, message, code })
77
+ }
78
+ //成功
79
+ const { data, metadata } = resData
80
+ return Promise.resolve({ success, data, metadata })
81
+
82
+
83
+ }).catch((error) => {
84
+ const { message } = error
85
+
86
+ if (message.match(/timeout/)) {
87
+ return Promise.resolve({
88
+ message: 'REQUEST TIMEOUT',
89
+ code: 504
90
+ })
91
+ }
92
+ return Promise.resolve(error)
93
+ })
94
+ }
95
+
96
+ export default curl;
@@ -0,0 +1,2 @@
1
+ const utils = {};
2
+ export default utils;
@@ -0,0 +1,22 @@
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" :menu-item="item"></sub-menu>
6
+ <el-menu-item v-else :index="item.key">{{ item.name }}</el-menu-item>
7
+ </div>
8
+ </el-sub-menu>
9
+ </template>
10
+
11
+ <script setup>
12
+ // import { ref } from 'vue'
13
+ defineOptions({
14
+ name: 'SubMenu'
15
+ })
16
+ const { menuItem } = defineProps(['menuItem'])
17
+
18
+
19
+ </script>
20
+
21
+ <style lang='less' scoped></style>
22
+
@@ -0,0 +1,106 @@
1
+ <template>
2
+ <header-container :title="projName">
3
+ <template #menu-content>
4
+ <!--根据 menuStore.menuList 渲染-->
5
+ <el-menu :default-active="activeKey" :ellipsis="false" mode="horizontal" @select="onMenuSelect">
6
+ <template v-for="item in menuStore.menuList">
7
+ <sub-menu v-if="item.subMenu && item.subMenu.length > 0" :menu-item="item"></sub-menu>
8
+ <el-menu-item v-else :index="item.key">
9
+ {{ item.name }}
10
+ </el-menu-item>
11
+ </template>
12
+ </el-menu>
13
+ </template>
14
+ <template #setting-content>
15
+ <!--根据 projStore.projectList 渲染-->
16
+ <el-dropdown @command="handleProjectCommadn">
17
+ <span class="project-list">
18
+ {{ projName }}
19
+ <el-icon v-if="projectStore.projectList.length > 1" class="el-icon--right">
20
+ <ArrowDown />
21
+ </el-icon>
22
+ </span>
23
+ <template v-if="projectStore.projectList.length > 1" #dropdown>
24
+ <el-dropdown-item v-for="item in projectStore.projectList" :key="item.key" :command="item.key"
25
+ :disabled="item.name === projName">
26
+ {{ item.name }}
27
+ </el-dropdown-item>
28
+ </template>
29
+
30
+ </el-dropdown>
31
+ </template>
32
+ <template #main-content>
33
+ <!---->
34
+ <slot name="main-content"></slot>
35
+ </template>
36
+ </header-container>
37
+ </template>
38
+
39
+ <script setup>
40
+ import { ref, watch, onMounted } from 'vue'
41
+ import { useRoute } from 'vue-router'
42
+ import { ArrowDown } from '@element-plus/icons-vue'
43
+ import SubMenu from './complex-view/sub-menu.vue'
44
+ import HeaderContainer from '$elpisWidgets/header-container/header-container.vue'
45
+ import { useMenuStore } from '$elpisStore/menu.js'
46
+ import { useProjectStore } from '$elpisStore/project.js'
47
+ // import { emit } from 'cluster'
48
+
49
+ const route = useRoute()
50
+ const menuStore = useMenuStore()
51
+ const projectStore = useProjectStore()
52
+ const activeKey = ref('')
53
+ defineProps({
54
+ projName: String
55
+ })
56
+ const emit = defineEmits(['menu-select'])
57
+
58
+ watch(() => route.query.key, () => {
59
+ setActiveKey();
60
+ })
61
+ watch(() => menuStore.menuList, () => {
62
+ setActiveKey();
63
+ }, { deep: true })
64
+
65
+ onMounted(() => {
66
+ setActiveKey();
67
+ })
68
+ const setActiveKey = function () {
69
+ const menuItem = menuStore.findMenuItem({
70
+ key: 'key',
71
+ value: route.query.key
72
+ })
73
+ activeKey.value = menuItem?.key
74
+ }
75
+
76
+ const onMenuSelect = function (menuKey) {
77
+ console.log(menuKey, 'menuKey');
78
+ const menuItem = menuStore.findMenuItem({
79
+ key: 'key',
80
+ value: menuKey
81
+ })
82
+ emit('menu-select', menuItem)
83
+ }
84
+ const handleProjectCommadn = function (event) {
85
+ const projectItem = projectStore.projectList.find(item => item.key === event)
86
+ if (!projectItem || !projectItem.homePage) { return; }
87
+ const { host } = window.location;
88
+ window.location.replace(`http://${host}/view/dashboard${projectItem.homePage}`)
89
+ }
90
+ </script>
91
+
92
+ <style lang='less' scoped>
93
+ .project-list {
94
+ margin-right: 20px;
95
+ cursor: pointer;
96
+ color: var(--el-color-primary);
97
+ display: flex;
98
+ align-items: center;
99
+ outline: none;
100
+ }
101
+
102
+ :deep(.el-menu--horizontal.el-menu) {
103
+ border-bottom: 1px solid;
104
+ }
105
+ </style>
106
+
@@ -0,0 +1,45 @@
1
+ <template>
2
+ <iframe :src="path" class="iframe"></iframe>
3
+ </template>
4
+
5
+ <script setup>
6
+ import { ref, watch, onMounted } from 'vue'
7
+ import { useRoute } from 'vue-router'
8
+ import { useMenuStore } from '$elpisStore/menu.js'
9
+
10
+ const route = useRoute()
11
+ const menuStore = useMenuStore()
12
+ const path = ref('')
13
+
14
+ const setPath = function () {
15
+ const { key, sider_key: siderKey } = route.query
16
+
17
+ const menuItem = menuStore.findMenuItem({
18
+ key: 'key',
19
+ value: siderKey ?? key
20
+ })
21
+
22
+ path.value = menuItem?.iframeConfig?.path ?? ''
23
+ }
24
+
25
+ watch([
26
+ () => route.query.key,
27
+ () => route.query.sider_key,
28
+ () => menuStore.menuList
29
+ ], () => {
30
+ setPath()
31
+ }, { deep: true })
32
+ onMounted(() => {
33
+ setPath()
34
+ })
35
+
36
+ </script>
37
+
38
+ <style lang='less' scoped>
39
+ .iframe {
40
+ border: 0;
41
+ width: 100%;
42
+ height: 100%;
43
+ }
44
+ </style>
45
+
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <el-card class="search-panel">
3
+ <schema-search-bar :schema="searchSchema" @load="onLoad" @search="onSearch" @reset="onReset"></schema-search-bar>
4
+ </el-card>
5
+ </template>
6
+
7
+ <script setup>
8
+ import { inject } from 'vue'
9
+ import SchemaSearchBar from '$elpisWidgets/schema-search-bar/schema-search-bar.vue'
10
+ const { searchSchema } = inject('schemaViewData')
11
+ const emit = defineEmits(['search'])
12
+
13
+ const onLoad = (searhValhObj) => {
14
+ emit('search', searhValhObj)
15
+ }
16
+ const onSearch = (searhValhObj) => {
17
+ emit('search', searhValhObj)
18
+ }
19
+ const onReset = () => {
20
+ emit('search', {})
21
+ }
22
+ </script>
23
+
24
+ <style lang='less' scoped>
25
+ .search-panel {
26
+ margin: 10px 10px 0 10px;
27
+ }
28
+
29
+ :deep(.el-card__body) {
30
+ padding-bottom: 2px;
31
+ }
32
+ </style>
33
+
@@ -0,0 +1,105 @@
1
+ <template>
2
+ <el-card class="table-panel">
3
+ <!-- operation-panel -->
4
+ <el-row v-if="tableConfig?.headerButtons?.length > 0" justify="end" class="operation-panel">
5
+ <el-button v-for="item in tableConfig?.headerButtons" v-bind="item"
6
+ @click="operationHandler({ btnConfig: item })">{{ item.label }}</el-button>
7
+ </el-row>
8
+ <!-- schema-table(组件 widget) -->
9
+ <schema-table ref="schemaTableRef" :apiParams="apiParams" :schema="tableSchema" :api="api"
10
+ :buttons="tableConfig?.rowButtons ?? []" @operate="operationHandler"></schema-table>
11
+ </el-card>
12
+ </template>
13
+
14
+ <script setup>
15
+ import { ref, inject } from 'vue'
16
+ import $curl from '$elpisCommon/curl.js'
17
+ import { ElMessageBox, ElNotification } from 'element-plus'
18
+ import SchemaTable from '$elpisWidgets/schema-table/schema.table.vue'
19
+
20
+ const emit = defineEmits(['operate'])
21
+ const { api, tableSchema, tableConfig, apiParams } = inject('schemaViewData')
22
+ const schemaTableRef = ref(null)
23
+ const EventHandlerMap = {
24
+ remove: removeData
25
+ }
26
+ const operationHandler = ({ btnConfig, rowData }) => {
27
+ const { eventKey } = btnConfig;
28
+ if (EventHandlerMap[eventKey]) {
29
+ EventHandlerMap[eventKey]({ btnConfig, rowData })
30
+ } else {
31
+ emit('operate', { btnConfig, rowData })
32
+ }
33
+ }
34
+ function removeData({ btnConfig, rowData }) {
35
+ const { eventOption } = btnConfig
36
+ if (!eventOption?.params) { return; }
37
+ const { params } = eventOption
38
+ const removeKey = Object.keys(params)[0]
39
+ let removeValue;
40
+ const removeValueList = params[removeKey].split('::')
41
+ if (removeValueList[0] === 'schema' && removeValueList[1]) {
42
+ removeValue = rowData[removeValueList[1]]
43
+ }
44
+ ElMessageBox.confirm(
45
+ `确认删除${removeKey} 为: ${removeValue} 数据?`,
46
+ 'Warning',
47
+ {
48
+ confirmButtonText: '确认',
49
+ cancelButtonText: '取消',
50
+ type: 'warning',
51
+ }
52
+ )
53
+ .then(async () => {
54
+ schemaTableRef.value.showLoading()
55
+ const res = await $curl({
56
+ method: 'delete',
57
+ url: api.value,
58
+ data: {
59
+ [removeKey]: removeValue
60
+ },
61
+ errorMessage: '删除失败'
62
+ })
63
+ schemaTableRef.value.hideLoading()
64
+
65
+ if (!res || !res.success || !res.data) {
66
+ return;
67
+ }
68
+
69
+ ElNotification({
70
+ title: '删除成功',
71
+ message: '删除成功',
72
+ type: 'success'
73
+ })
74
+ await initTableData()
75
+ })
76
+ }
77
+
78
+ const initTableData = async () => {
79
+ await schemaTableRef.value.initData()
80
+ }
81
+ const loadTableData = async () => {
82
+ await schemaTableRef.value.loadTableData()
83
+ }
84
+
85
+ defineExpose({
86
+ loadTableData
87
+ })
88
+ </script>
89
+
90
+ <style lang='less' scoped>
91
+ .table-panel {
92
+ flex: 1;
93
+ margin: 10px;
94
+
95
+ .operation-panel {
96
+ margin-bottom: 10px;
97
+ }
98
+ }
99
+
100
+ :deep(.el-card__body) {
101
+ height: 98%;
102
+ display: flex;
103
+ flex-direction: column;
104
+ }
105
+ </style>
@@ -0,0 +1,23 @@
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
+ //业务扩展 component 配置
6
+ import BusinessComponentConfig from '$businessComponentConfig'
7
+
8
+ const ComponentConfig = {
9
+ createForm:{
10
+ component:createForm
11
+ },
12
+ editForm:{
13
+ component:editForm
14
+ },
15
+ detailPanel:{
16
+ component:detailPanel
17
+ }
18
+ }
19
+
20
+ export default {
21
+ ...BusinessComponentConfig,
22
+ ...ComponentConfig
23
+ };
@@ -0,0 +1,85 @@
1
+ <template>
2
+ <el-drawer v-model="isShow" direction="rtl" :destroy-on-close="true" :size="550">
3
+ <template #header>
4
+ <h3>{{ title }}</h3>
5
+ </template>
6
+ <template #default>
7
+ <schema-form v-loading="loading" ref="schemaFormRef" :schema="components[name]?.schema"></schema-form>
8
+ </template>
9
+ <template #footer>
10
+ <el-button type="primary" @click="save">{{ saveBtnText }}</el-button>
11
+ </template>
12
+ </el-drawer>
13
+ </template>
14
+
15
+ <script setup>
16
+ import { ref, inject } from 'vue'
17
+ import { ElNotification } from 'element-plus';
18
+ import $curl from '$elpisCommon/curl'
19
+ import SchemaForm from '$elpisWidgets/schema-form/schema-form.vue';
20
+
21
+ const { api, components } = inject('schemaViewData')
22
+
23
+ const emit = defineEmits(['command'])
24
+
25
+ const name = ref('createForm')
26
+
27
+ const schemaFormRef = ref(null)
28
+ const isShow = ref(false)
29
+ const loading = ref(false)
30
+ const title = ref('')
31
+ const saveBtnText = ref('')
32
+
33
+ const show = () => {
34
+ const { config } = components.value[name.value]
35
+ title.value = config.title
36
+ saveBtnText.value = config.saveBtnText
37
+ isShow.value = true
38
+ }
39
+
40
+ const close = () => {
41
+ isShow.value = false
42
+ }
43
+
44
+ const save = async () => {
45
+ if (loading.value) { return; }
46
+ //校验表单
47
+ if (!schemaFormRef.value.validate()) { return; }
48
+
49
+ loading.value = true
50
+
51
+ const res = await $curl({
52
+ method: 'post',
53
+ url: api.value,
54
+ data: {
55
+ ...schemaFormRef.value.getValue()
56
+ }
57
+ })
58
+ loading.value = false
59
+
60
+ if (!res || !res.success) {
61
+ return;
62
+ }
63
+
64
+ ElNotification({
65
+ title: '创建成功',
66
+ message: '创建成功',
67
+ type: 'success'
68
+ })
69
+
70
+ close()
71
+
72
+ emit('command', {
73
+ event: 'loadTableData'
74
+ })
75
+ }
76
+ // const { components } = inject('schemaViewData')
77
+
78
+ defineExpose({
79
+ name, show
80
+ })
81
+
82
+ </script>
83
+
84
+ <style lang='less' scoped></style>
85
+
@@ -0,0 +1,90 @@
1
+ <template>
2
+ <el-drawer v-model="isShow" direction="rtl" :destroy-on-close="true" :size="550">
3
+ <template #header>
4
+ <h3>{{ title }}</h3>
5
+ </template>
6
+ <template #default>
7
+ <el-card v-loading="loading" shadow="always" class="detail-panel">
8
+ <el-row v-for="(item, key) in components[name]?.schema?.properties" :key="key" type="flex" align="middle"
9
+ class="row-item">
10
+ <el-row class="item-label">{{ item.label }}:</el-row>
11
+ <el-row class="item-value">{{ dtoModel[key] }}</el-row>
12
+ </el-row>
13
+ </el-card>
14
+ </template>
15
+
16
+ </el-drawer>
17
+ </template>
18
+
19
+ <script setup>
20
+ import { ref, inject } from 'vue'
21
+ import $curl from '$elpisCommon/curl'
22
+ const { api, components } = inject('schemaViewData')
23
+
24
+ const isShow = ref(false)
25
+ const name = ref('detailPanel')
26
+ const loading = ref(false)
27
+ const mainKey = ref('')
28
+ const mainValue = ref()
29
+ const dtoModel = ref({})
30
+ const title = ref('')
31
+ const show = (rowData) => {
32
+ const { config } = components.value[name.value]
33
+ title.value = config.title
34
+ mainKey.value = config.mainKey //表单主键
35
+ mainValue.value = rowData[config.mainKey] //表单主键值
36
+ dtoModel.value = {}
37
+
38
+ isShow.value = true
39
+
40
+ fetchFormData()
41
+ }
42
+
43
+ const fetchFormData = async () => {
44
+ if (loading.value) { return; }
45
+ loading.value = true
46
+
47
+ const res = await $curl({
48
+ method: 'get',
49
+ url: api.value,
50
+ query: {
51
+ [mainKey.value]: mainValue.value
52
+ }
53
+ })
54
+ loading.value = false
55
+
56
+ if (!res || !res.success || !res.data) {
57
+ return;
58
+ }
59
+ dtoModel.value = res.data
60
+ }
61
+
62
+ defineExpose({
63
+ name, show
64
+ })
65
+
66
+ </script>
67
+
68
+ <style lang='less' scoped>
69
+ .detail-panel {
70
+ border: 1px solid #a6a6a6;
71
+ padding: 30px;
72
+
73
+ .row-item {
74
+ height: 40px;
75
+ line-height: 40px;
76
+ font-size: 20px;
77
+
78
+ .item-label {
79
+ margin-right: 20px;
80
+ width: 120px;
81
+ color: #ffffff;
82
+ }
83
+
84
+ .item-value {
85
+ color: #d2dae4
86
+ }
87
+ }
88
+ }
89
+ </style>
90
+