@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,105 @@
1
+ <template>
2
+ <el-container class="header-container">
3
+ <el-header class="header">
4
+ <!-- 左上方title -->
5
+ <el-row type="flex" align="middle" class="header-row">
6
+ <el-row type="flex" align="middle" class="title-panel">
7
+ <img src="./asserts/logo.png" class="logo" />
8
+ <el-row class="text">
9
+ {{ title }}
10
+ </el-row>
11
+ </el-row>
12
+ <!-- 插槽:菜单区域 -->
13
+ <slot name="menu-content"></slot>
14
+ <el-row type="flex" align="middle" justify="end" class="setting-panel">
15
+ <!-- 插槽:设置区域 -->
16
+ <slot name="setting-content"></slot>
17
+ <img src="./asserts/user.png" class="avatar" />
18
+ <el-dropdown @command="handleUserCommand">
19
+ <span class="username">
20
+ {{ userName }}<i class="el-icon-arrow-down el-icon--right"></i>
21
+ </span>
22
+ <template #dropdown>
23
+ <el-dropdown-item command="logout">推出登陆</el-dropdown-item>
24
+ </template>
25
+ </el-dropdown>
26
+ </el-row>
27
+ </el-row>
28
+ </el-header>
29
+ <el-main class="main-container">
30
+ <!-- 插槽:核心内容填充区域 -->
31
+ <slot name="main-content"></slot>
32
+ </el-main>
33
+ </el-container>
34
+ </template>
35
+ <script setup>
36
+ import { ref } from 'vue'
37
+ defineProps({
38
+ title: String
39
+ })
40
+
41
+ const userName = ref('Talor')
42
+ const handleUserCommand = function () { }
43
+ </script>
44
+ <style lang="less" scoped>
45
+ .header-container {
46
+ height: 100%;
47
+ min-width: 100px;
48
+ overflow: hidden;
49
+
50
+ .header {
51
+ max-height: 120px;
52
+ border-bottom: 1px solid #E8E8E8;
53
+
54
+ .header-row {
55
+ height: 60px;
56
+ padding: 0 20px;
57
+
58
+ .title-panel {
59
+ width: 180px;
60
+ min-width: 180px;
61
+
62
+ .logo {
63
+ margin-right: 10px;
64
+ width: 25px;
65
+ height: 25px;
66
+ border-radius: 50%;
67
+ }
68
+
69
+ .text {
70
+ font-size: 15px;
71
+ font-weight: 500;
72
+ }
73
+ }
74
+
75
+ .setting-panel {
76
+ margin-left: auto !important;
77
+ min-width: 180px;
78
+
79
+ .avatar {
80
+ margin-right: 12px;
81
+ width: 30px;
82
+ height: 30px;
83
+ border-radius: 50%;
84
+ }
85
+
86
+ .username {
87
+ font-size: 16px;
88
+ font-weight: 500;
89
+ cursor: pointer;
90
+ height: 60px;
91
+ line-height: 60px;
92
+ outline: none;
93
+ }
94
+ }
95
+ }
96
+
97
+ }
98
+
99
+ .main-container {}
100
+
101
+ :deep(.el-header) {
102
+ padding: 0;
103
+ }
104
+ }
105
+ </style>
@@ -0,0 +1,120 @@
1
+ <template>
2
+ <el-row type="flex" algin="middle" class="form-item">
3
+ <!--label-->
4
+ <el-row class="item-label" justify="end">
5
+ <el-row v-if="schema.option?.required" type="flex" class="required">*</el-row>
6
+ {{ schema.label }}
7
+ </el-row>
8
+ <!--value-->
9
+ <el-row class="item-value">
10
+ <el-input :placeholder="placeholder" v-model="dtoValue" v-bind="schema.option" class="component"
11
+ :class="validTips ? 'valid-border' : ''" @focus="onFocus" @blur="onBlur"></el-input>
12
+ </el-row>
13
+ <!--错误信息-->
14
+ <el-row v-if="validTips" class="valid-tips">{{ validTips }}</el-row>
15
+ </el-row>
16
+ </template>
17
+
18
+ <script setup>
19
+ import { ref, toRefs, watch, inject, onMounted } from 'vue'
20
+
21
+ const ajv = inject('ajv')
22
+
23
+ const props = defineProps({
24
+ schemaKey: String,
25
+ schema: Object,
26
+ model: String
27
+ })
28
+
29
+ const { schemaKey, schema } = props
30
+ const { model } = toRefs(props)
31
+ const name = ref('input')
32
+ const dtoValue = ref()
33
+ const validTips = ref('')
34
+ const placeholder = ref(null)
35
+ const initData = () => {
36
+ dtoValue.value = model.value ?? schema.option?.default
37
+ validTips.value = null
38
+
39
+ const { maxLength, minLength, pattern } = schema
40
+
41
+ const ruleList = []
42
+ if (schema.option?.placeholder) {
43
+ ruleList.push(schema.option.placeholder)
44
+ }
45
+
46
+ if (maxLength) {
47
+ ruleList.push(`最大长度:${maxLength}`)
48
+ }
49
+ if (minLength) {
50
+ ruleList.push(`最小长度:${minLength}`)
51
+ }
52
+ if (pattern) {
53
+ ruleList.push(`格式:${pattern}`)
54
+ }
55
+
56
+ placeholder.value = ruleList.join('|')
57
+ }
58
+
59
+ onMounted(() => {
60
+ initData()
61
+ })
62
+
63
+ watch([model, schema], () => {
64
+ initData()
65
+ }, { deep: true })
66
+
67
+
68
+ const validate = () => {
69
+ validTips.value = null
70
+ const { type } = schema
71
+
72
+ //校验是否必填
73
+ if (schema.option?.required && !dtoValue.value) {
74
+ validTips.value = '不能为空'
75
+ return false;
76
+ }
77
+
78
+ //校验schema
79
+ if (dtoValue.value) {
80
+ const validate = ajv.compile(schema)
81
+ const valid = validate(dtoValue.value)
82
+ if (!valid && validate.errors && validate.errors[0]) {
83
+ const { keyword, params } = validate.errors[0]
84
+ if (keyword === 'type') {
85
+ validTips.value = `类型必须为${type}`
86
+ } else if (keyword === 'maxLength') {
87
+ validTips.value = `最大长度应为${params.limit}`
88
+ } else if (keyword === 'minLength') {
89
+ validTips.value = `最小长度应为${params.limit}`
90
+ } else if (keyword === 'pattern') {
91
+ validTips.value = '格式不正确'
92
+ } else {
93
+ validTips.value = '不符合要求'
94
+ }
95
+ return false;
96
+ }
97
+ }
98
+ return true;
99
+ }
100
+ const getValue = () => {
101
+ return dtoValue.value !== undefined ? {
102
+ [schemaKey]: dtoValue.value
103
+ } : {}
104
+ }
105
+ const onFocus = () => {
106
+ validTips.value = null
107
+ }
108
+
109
+ const onBlur = () => {
110
+ validate()
111
+ }
112
+ defineExpose({
113
+ validate,
114
+ getValue,
115
+ name
116
+ })
117
+ </script>
118
+
119
+ <style lang='less' scoped></style>
120
+
@@ -0,0 +1,121 @@
1
+ <template>
2
+ <el-row type="flex" algin="middle" class="form-item">
3
+ <!--label-->
4
+ <el-row class="item-label" justify="end">
5
+ <el-row v-if="schema.option?.required" type="flex" class="required">*</el-row>
6
+ {{ schema.label }}
7
+ </el-row>
8
+ <!--value-->
9
+ <el-row class="item-value">
10
+ <el-input-number :controls="false" :placeholder="placeholder" v-model="dtoValue" v-bind="schema.option"
11
+ class="component" :class="validTips ? 'valid-border' : ''" @focus="onFocus"
12
+ @blur="onBlur"></el-input-number>
13
+ </el-row>
14
+ <!--错误信息-->
15
+ <el-row v-if="validTips" class="valid-tips">{{ validTips }}</el-row>
16
+ </el-row>
17
+ </template>
18
+
19
+ <script setup>
20
+ import { ref, toRefs, watch, inject, onMounted } from 'vue'
21
+
22
+ const ajv = inject('ajv')
23
+
24
+ const props = defineProps({
25
+ schemaKey: String,
26
+ schema: Object,
27
+ model: Number
28
+ })
29
+
30
+ const { schemaKey, schema } = props
31
+ const { model } = toRefs(props)
32
+ const name = ref('inputNumber')
33
+ const dtoValue = ref()
34
+ const validTips = ref('')
35
+ const placeholder = ref(null)
36
+ const initData = () => {
37
+ dtoValue.value = model.value ?? schema.option?.default
38
+ validTips.value = null
39
+
40
+ const { minimum, maximum } = schema
41
+
42
+ const ruleList = []
43
+ if (schema.option?.placeholder) {
44
+ ruleList.push(schema.option.placeholder)
45
+ }
46
+
47
+ if (minimum !== undefined) {
48
+ ruleList.push(`最小值:${minimum}`)
49
+ }
50
+ if (maximum !== undefined) {
51
+ ruleList.push(`最大值:${maximum}`)
52
+ }
53
+
54
+ placeholder.value = ruleList.join('|')
55
+ }
56
+
57
+ onMounted(() => {
58
+ initData()
59
+ })
60
+
61
+ watch([model, schema], () => {
62
+ initData()
63
+ }, { deep: true })
64
+
65
+
66
+ const validate = () => {
67
+ validTips.value = null
68
+ const { type } = schema
69
+
70
+ //校验是否必填
71
+ if (schema.option?.required && !dtoValue.value) {
72
+ validTips.value = '不能为空'
73
+ return false;
74
+ }
75
+
76
+ //校验schema
77
+ if (dtoValue.value) {
78
+ const validate = ajv.compile(schema)
79
+ const valid = validate(dtoValue.value)
80
+ if (!valid && validate.errors && validate.errors[0]) {
81
+ const { keyword, params } = validate.errors[0]
82
+ if (keyword === 'type') {
83
+ validTips.value = `类型必须为${type}`
84
+ } else if (keyword === 'minimum') {
85
+ validTips.value = `最小值为${params.limit}`
86
+ } else if (keyword === 'maximum') {
87
+ validTips.value = `最大值为${params.limit}`
88
+ }
89
+ else {
90
+ validTips.value = '不符合要求'
91
+ }
92
+ return false;
93
+ }
94
+ }
95
+ return true;
96
+ }
97
+ const getValue = () => {
98
+ return dtoValue.value !== undefined ? {
99
+ [schemaKey]: dtoValue.value
100
+ } : {}
101
+ }
102
+ const onFocus = () => {
103
+ validTips.value = null
104
+ }
105
+
106
+ const onBlur = () => {
107
+ validate()
108
+ }
109
+ defineExpose({
110
+ validate,
111
+ getValue,
112
+ name
113
+ })
114
+ </script>
115
+
116
+ <style lang='less' scoped>
117
+ :deep(.el-input-number .el-input__inner) {
118
+ text-align: left;
119
+ }
120
+ </style>
121
+
@@ -0,0 +1,106 @@
1
+ <template>
2
+ <el-row type="flex" algin="middle" class="form-item">
3
+ <!--label-->
4
+ <el-row class="item-label" justify="end">
5
+ <el-row v-if="schema.option?.required" type="flex" class="required">*</el-row>
6
+ {{ schema.label }}
7
+ </el-row>
8
+ <!--value-->
9
+ <el-row class="item-value">
10
+ <el-select v-model="dtoValue" v-bind="schema.option" class="component" :class="validTips ? 'valid-border' : ''"
11
+ @change="onChange">
12
+ <el-option v-for="item in schema.option?.enumList" :key="item.value" :label="item.label"
13
+ :value="item.value">
14
+
15
+ </el-option>
16
+ </el-select>
17
+ </el-row>
18
+ <!--错误信息-->
19
+ <el-row v-if="validTips" class="valid-tips">{{ validTips }}</el-row>
20
+ </el-row>
21
+ </template>
22
+
23
+ <script setup>
24
+ import { ref, toRefs, watch, inject, onMounted } from 'vue'
25
+
26
+ const ajv = inject('ajv')
27
+
28
+ const props = defineProps({
29
+ schemaKey: String,
30
+ schema: Object,
31
+ model: null
32
+ })
33
+
34
+ const { schemaKey, schema } = props
35
+ const { model } = toRefs(props)
36
+ const name = ref('select')
37
+ const dtoValue = ref()
38
+ const validTips = ref('')
39
+ const initData = () => {
40
+ dtoValue.value = model.value ?? schema.option?.default
41
+ validTips.value = null
42
+ }
43
+
44
+ onMounted(() => {
45
+ initData()
46
+ })
47
+
48
+ watch([model, schema], () => {
49
+ initData()
50
+ }, { deep: true })
51
+
52
+
53
+ const validate = () => {
54
+ validTips.value = null
55
+
56
+ //校验是否必填
57
+ if (schema.option?.required && !dtoValue.value) {
58
+ validTips.value = '不能为空'
59
+ return false;
60
+ }
61
+
62
+ //校验schema
63
+ if (dtoValue.value) {
64
+ let dtoEnum = []
65
+ if (schema.option?.enumList) {
66
+ dtoEnum = schema.option?.enumList.map(item => item.value)
67
+ }
68
+ const validate = ajv.compile({
69
+ schema,
70
+ ...{ enum: dtoEnum }
71
+ })
72
+
73
+ const valid = validate(dtoValue.value)
74
+ if (!valid && validate.erros && validate.erros[0]) {
75
+ if (validate.erros[0].keyword == 'enum') {
76
+ validTips.value('取值超过枚举范围')
77
+ } else {
78
+ validTips.value = '不符合要求'
79
+ }
80
+ return false;
81
+ }
82
+ }
83
+ return true;
84
+ }
85
+ const getValue = () => {
86
+ return dtoValue.value !== undefined ? {
87
+ [schemaKey]: dtoValue.value
88
+ } : {}
89
+ }
90
+ const onChange = () => {
91
+ validate()
92
+ }
93
+
94
+ defineExpose({
95
+ validate,
96
+ getValue,
97
+ name
98
+ })
99
+ </script>
100
+
101
+ <style lang='less' scoped>
102
+ :deep(.el-input-number .el-input__inner) {
103
+ text-align: left;
104
+ }
105
+ </style>
106
+
@@ -0,0 +1,20 @@
1
+ import input from './complex-view/input/input.vue'
2
+ import inputNumber from './complex-view/input-number/input-number.vue'
3
+ import select from './complex-view/select/select.vue'
4
+
5
+ //业务扩展 form-item 配置
6
+ import BusinessFormItemConfig from '$businessFormItemConfig'
7
+
8
+ const FormItemConfig = {
9
+ input:{
10
+ component:input
11
+ },
12
+ inputNumber:{
13
+ component:inputNumber
14
+ },
15
+ select:{
16
+ component:select
17
+ }
18
+ }
19
+
20
+ export default {...BusinessFormItemConfig,...FormItemConfig};
@@ -0,0 +1,122 @@
1
+ <template>
2
+ <el-row v-if="schema && schema.properties" class="schema-form">
3
+ <template v-for="(itemSchema, key) in schema.properties">
4
+ <component ref="formComList" v-show="itemSchema.option.visible !== false"
5
+ :is="FormItemConfig[itemSchema.option?.comType]?.component" :schemaKey="key" :schema="itemSchema"
6
+ :model="model ? model[key] : undefined"></component>
7
+ </template>
8
+ </el-row>
9
+ </template>
10
+
11
+ <script setup>
12
+ import { ref, toRefs, provide } from 'vue'
13
+ import FormItemConfig from './form-item-config';
14
+
15
+
16
+ const Ajv = require('ajv')
17
+ const ajv = new Ajv()
18
+
19
+ provide('ajv', ajv)
20
+
21
+ const props = defineProps({
22
+ /**
23
+ * schema 配置,结构如下:
24
+ * properties: {
25
+ key: {
26
+ ...schema,//标准 scheam 配置
27
+ type: '',//字段类型
28
+ label: '',//字段中文名
29
+ option: {
30
+ ...elTableColumnConfig,//标准 el-component 配置
31
+ comType: '',//控件类型 input/select
32
+ required:false,//表单是否必填
33
+ visible: true,//是否展示
34
+ disabled: false,//是否禁用
35
+ default: '',//默认值
36
+
37
+ //comType === 'select'
38
+ enumList: [],
39
+ }
40
+ }
41
+ },
42
+ },
43
+ */
44
+ schema: Object,
45
+ /**表单数据 */
46
+ model: Object
47
+ });
48
+ const { schema } = toRefs(props)
49
+
50
+ const formComList = ref([])
51
+ //表单校验
52
+ const validate = () => {
53
+ return formComList.value.every(component => component.validate())
54
+ }
55
+ //获取表单值
56
+ const getValue = () => {
57
+ return formComList.value.reduce((dtoObj, component) => {
58
+ return {
59
+ ...dtoObj,
60
+ ...component.getValue()
61
+ }
62
+ }, {})
63
+ }
64
+
65
+ defineExpose({
66
+ validate,
67
+ getValue
68
+ })
69
+ </script>
70
+
71
+ <style lang='less'>
72
+ .schema-form {
73
+ .form-item {
74
+ margin-bottom: 20px;
75
+ min-width: 500px;
76
+
77
+ .item-label {
78
+ margin-right: 15px;
79
+ min-width: 70px;
80
+ text-align: right;
81
+ font-size: 14px;
82
+ color: #ffffff;
83
+ word-break: break-all;
84
+
85
+ .required {
86
+ top: 2px;
87
+ padding-left: 4px;
88
+ color: #f56c6c;
89
+ font-size: 20px;
90
+ }
91
+ }
92
+
93
+ .item-value {
94
+ .component {
95
+ width: 320px;
96
+ }
97
+
98
+ .valid-border {
99
+ .el-input__wrapper {
100
+ border: 1px solid #F93F3F;
101
+ box-shadow: 0 0 0 0;
102
+ }
103
+
104
+ .el-select__wrapper {
105
+ border: 1px solid #F93F3F;
106
+ box-shadow: 0 0 0 0;
107
+ }
108
+ }
109
+ }
110
+
111
+ .valid-tips {
112
+ margin-left: 10px;
113
+ height: 36px;
114
+ line-height: 36px;
115
+ overflow: hidden;
116
+ font-size: 12px;
117
+ color: #F93F3F;
118
+ }
119
+ }
120
+ }
121
+ </style>
122
+
@@ -0,0 +1,42 @@
1
+ <template>
2
+ <el-date-picker v-model="dtoValue" v-bind="schema.option" class="date-range" type="daterange" range-separator="至"
3
+ :start-placeholder="schema.label + '(开始)'" :end-placeholder="schema.label + '(结束)'">
4
+ </el-date-picker>
5
+ </template>
6
+
7
+ <script setup>
8
+ import { ref, onMounted } from 'vue'
9
+ import moment from 'moment'
10
+
11
+ const { schemaKey, schema } = defineProps({
12
+ schemaKey: String,
13
+ schema: Object
14
+ })
15
+
16
+ const dtoValue = ref([])
17
+ const emit = defineEmits(['loaded'])
18
+
19
+ const getValue = () => {
20
+ return dtoValue.value.length === 2 ? {
21
+ [`${schemaKey}_start`]: moment(dtoValue.value[0]).format('YYYY-MM-DD'),
22
+ [`${schemaKey}_end`]: moment(dtoValue.value[1]).format('YYYY-MM-DD'),
23
+ } : {}
24
+ }
25
+
26
+ const reset = () => {
27
+ dtoValue.value = []
28
+ }
29
+
30
+ defineExpose({
31
+ getValue,
32
+ reset
33
+ })
34
+
35
+ onMounted(() => {
36
+ reset();
37
+ emit('loaded')
38
+ })
39
+ </script>
40
+
41
+ <style lang='less' scoped></style>
42
+
@@ -0,0 +1,55 @@
1
+ <template>
2
+ <el-select v-model="dtoValue" v-bind="schema.option" class="dynamic-select">
3
+ <el-option v-for="item in enumList" :key="item.value" :label="item.label" :value="item.value"></el-option>
4
+ </el-select>
5
+ </template>
6
+
7
+ <script setup>
8
+ import { ref, onMounted } from 'vue'
9
+ import $curl from '$elpisCommon/curl'
10
+
11
+ const { schemaKey, schema } = defineProps({
12
+ schemaKey: String,
13
+ schema: Object
14
+ })
15
+
16
+ const dtoValue = ref()
17
+ const emit = defineEmits(['loaded'])
18
+
19
+ const getValue = () => {
20
+ return dtoValue.value !== undefined ? {
21
+ [schemaKey]: dtoValue.value
22
+ } : {}
23
+ }
24
+
25
+ const reset = () => {
26
+ dtoValue.value = schema?.option?.default ?? enumList.value[0]?.value
27
+ }
28
+
29
+ const enumList = ref([])
30
+ const fetchEnunList = async () => {
31
+ const res = await $curl({
32
+ method: 'get',
33
+ url: schema.option?.api,
34
+ data: {}
35
+ })
36
+
37
+ if (res?.data?.length > 0) {
38
+ enumList.value.push(...res?.data);
39
+ }
40
+ }
41
+
42
+ onMounted(async () => {
43
+ await fetchEnunList();
44
+ reset();
45
+ emit('loaded')
46
+ })
47
+
48
+ defineExpose({
49
+ getValue,
50
+ reset
51
+ })
52
+ </script>
53
+
54
+ <style lang='less' scoped></style>
55
+