@yukihong/schema-admin-x 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 (80) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc +55 -0
  3. package/README.md +208 -0
  4. package/app/controller/base.js +39 -0
  5. package/app/controller/project.js +80 -0
  6. package/app/controller/view.js +20 -0
  7. package/app/extend/logger.js +39 -0
  8. package/app/middleware/api-params-verify.js +79 -0
  9. package/app/middleware/api-sign-verify.js +34 -0
  10. package/app/middleware/error-handler.js +34 -0
  11. package/app/middleware/project-handler.js +27 -0
  12. package/app/middleware.js +40 -0
  13. package/app/pages/asserts/custom.css +13 -0
  14. package/app/pages/boot.js +53 -0
  15. package/app/pages/common/curl.js +91 -0
  16. package/app/pages/common/utils.js +3 -0
  17. package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +21 -0
  18. package/app/pages/dashboard/complex-view/header-view/header-view.vue +127 -0
  19. package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +44 -0
  20. package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue +41 -0
  21. package/app/pages/dashboard/complex-view/schema-view/complex-view/table-panel/table-panel.vue +131 -0
  22. package/app/pages/dashboard/complex-view/schema-view/components/component-config.js +23 -0
  23. package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +100 -0
  24. package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +106 -0
  25. package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +131 -0
  26. package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +126 -0
  27. package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +102 -0
  28. package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +26 -0
  29. package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +128 -0
  30. package/app/pages/dashboard/dashboard.vue +99 -0
  31. package/app/pages/dashboard/entry.dashboard.js +44 -0
  32. package/app/pages/store/index.js +4 -0
  33. package/app/pages/store/menu.js +61 -0
  34. package/app/pages/store/project.js +17 -0
  35. package/app/pages/widgets/header-container/asserts/avatar.png +0 -0
  36. package/app/pages/widgets/header-container/asserts/logo.png +0 -0
  37. package/app/pages/widgets/header-container/header-container.vue +109 -0
  38. package/app/pages/widgets/schema-form/complex-view/input/input.vue +146 -0
  39. package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +140 -0
  40. package/app/pages/widgets/schema-form/complex-view/select/select.vue +121 -0
  41. package/app/pages/widgets/schema-form/form-item-config.js +23 -0
  42. package/app/pages/widgets/schema-form/schema-form.vue +131 -0
  43. package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +50 -0
  44. package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +65 -0
  45. package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +44 -0
  46. package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +51 -0
  47. package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +127 -0
  48. package/app/pages/widgets/schema-search-bar/search-item-config.js +27 -0
  49. package/app/pages/widgets/schema-table/schema-table.vue +248 -0
  50. package/app/pages/widgets/sider-container/sider-container.vue +28 -0
  51. package/app/public/static/logo.png +0 -0
  52. package/app/public/static/normalize.css +239 -0
  53. package/app/router/project.js +7 -0
  54. package/app/router/view.js +10 -0
  55. package/app/router-schema/project.js +30 -0
  56. package/app/service/base.js +13 -0
  57. package/app/service/project.js +50 -0
  58. package/app/view/entry.tpl +25 -0
  59. package/app/webpack/config/webpack.base.js +213 -0
  60. package/app/webpack/config/webpack.dev.js +61 -0
  61. package/app/webpack/config/webpack.prod.js +124 -0
  62. package/app/webpack/dev.js +63 -0
  63. package/app/webpack/libs/blank.js +1 -0
  64. package/app/webpack/prod.js +19 -0
  65. package/config/config.beta.js +3 -0
  66. package/config/config.default.js +3 -0
  67. package/config/config.prod.js +3 -0
  68. package/elpis-core/env.js +20 -0
  69. package/elpis-core/index.js +99 -0
  70. package/elpis-core/loader/config.js +52 -0
  71. package/elpis-core/loader/controller.js +75 -0
  72. package/elpis-core/loader/extend.js +55 -0
  73. package/elpis-core/loader/middleware.js +64 -0
  74. package/elpis-core/loader/router-schema.js +47 -0
  75. package/elpis-core/loader/router.js +59 -0
  76. package/elpis-core/loader/service.js +75 -0
  77. package/index.js +40 -0
  78. package/model/index.js +102 -0
  79. package/package.json +93 -0
  80. package/test/controller/project.test.js +217 -0
@@ -0,0 +1,131 @@
1
+ <template>
2
+ <el-row v-if="schema && schema.properties" class="schema-form">
3
+ <template v-for="(itemSchema, key) in schema.properties">
4
+ <component
5
+ ref="formComList"
6
+ v-show="itemSchema.option.visible !== false"
7
+ :is="FormItemConfig[itemSchema.option?.comType]?.component"
8
+ :schemaKey="key"
9
+ :schema="itemSchema"
10
+ :model="model ? model[key] : undefined"
11
+ ></component>
12
+ </template>
13
+ </el-row>
14
+ </template>
15
+
16
+ <script setup>
17
+ import { ref, toRefs, provide } from 'vue';
18
+ import FormItemConfig from './form-item-config.js';
19
+
20
+ const Ajv = require('ajv');
21
+ const ajv = new Ajv();
22
+ provide('ajv',ajv);
23
+
24
+ const props = defineProps({
25
+ /**
26
+ * schema 配置,结构如下:
27
+ {
28
+ type: 'object',
29
+ properties: {
30
+ key: {
31
+ ...schema, // 标准 schema 配置
32
+ type: '', // 字段类型
33
+ label: '', // 字段的中文名
34
+ required: false, // 表单项是否必填,默认 false
35
+ option: {
36
+ ...elComponentConfig, // 标准 el-component-column 配置
37
+ comType: '', // 控件类型 input/select/input-number
38
+ visible: true, // 是否展示(true/false),默认为 true
39
+ disabled: false, // 是否禁用(true/false),默认为 false
40
+ default: '', // 默认值
41
+
42
+ // comType === 'select'
43
+ enumList: [], // 下拉框可选项
44
+ }
45
+ },
46
+ ...
47
+ }
48
+ }
49
+ */
50
+ schema: Object,
51
+
52
+ /**
53
+ * 表单数据
54
+ */
55
+ model: Object,
56
+ });
57
+
58
+ const { schema } = toRefs(props);
59
+
60
+ const formComList = ref([]);
61
+
62
+ // 表单校验
63
+ const validate = () => {
64
+ return formComList.value.every(component => component.validate());
65
+ }
66
+
67
+ // 获取表单值
68
+ const getValue = () => {
69
+ return formComList.value.reduce((dtoObj, component) => {
70
+ return {
71
+ ...dtoObj,
72
+ ...component.getValue()
73
+ }
74
+ }, {})
75
+ }
76
+
77
+ defineExpose({
78
+ validate,
79
+ getValue
80
+ });
81
+
82
+
83
+ </script>
84
+
85
+ <style lang="less">
86
+ .schema-form {
87
+ .form-item {
88
+ margin-bottom: 20px;
89
+ min-width: 500px;
90
+
91
+ .item-label {
92
+ margin-right: 15px;
93
+ min-width: 70px;
94
+ text-align: right;
95
+ font-size: 14px;
96
+ color: #ffffff;
97
+ word-break: break-all;
98
+
99
+ .required {
100
+ top: 2px;
101
+ padding-left: 4px;
102
+ color: #f56c6c;
103
+ font-size: 20px;
104
+ }
105
+ }
106
+ .item-value {
107
+ .component {
108
+ width: 320px;
109
+ }
110
+ .valid-border {
111
+ .el-input__wrapper {
112
+ border: 1px solid #f93f3f;
113
+ box-shadow: 0 0 0 0;
114
+ }
115
+ .el-select__wrapper {
116
+ border: 1px solid #f93f3f;
117
+ box-shadow: 0 0 0 0;
118
+ }
119
+ }
120
+ }
121
+ .valid-tips {
122
+ margin-left: 10px;
123
+ height: 36px;
124
+ line-height: 36px;
125
+ overflow: hidden;
126
+ font-size: 12px;
127
+ color: #f93f3f;
128
+ }
129
+ }
130
+ }
131
+ </style>
@@ -0,0 +1,50 @@
1
+ <template>
2
+ <el-date-picker
3
+ v-model="dtoValue"
4
+ v-bind="schema.option"
5
+ type="daterange"
6
+ range-separator="至"
7
+ :start-placeholder="schema.label + '(开始)'"
8
+ :end-placeholder="schema.label + '(结束)'"
9
+ class="date-range"
10
+ ></el-date-picker>
11
+ </template>
12
+
13
+ <script setup>
14
+ import { ref, onMounted } from 'vue';
15
+ import moment from 'moment';
16
+
17
+ const { schemaKey, schema } = defineProps({
18
+ schemaKey: String,
19
+ schema: Object
20
+ });
21
+
22
+ const emit = defineEmits(['loaded']);
23
+
24
+ const dtoValue = ref([]);
25
+ const getValue = () => {
26
+ return dtoValue.value?.length === 2 ? {
27
+ [`${schemaKey}_start`]: moment(dtoValue.value[0]).format('YYYY-MM-DD'),
28
+ [`${schemaKey}_end`]: moment(dtoValue.value[0]).format('YYYY-MM-DD')
29
+ } : {}
30
+ }
31
+
32
+ const reset = () => {
33
+ dtoValue.value = [];
34
+ }
35
+
36
+ onMounted(() => {
37
+ reset();
38
+ emit('loaded');
39
+ });
40
+
41
+ defineExpose({
42
+ getValue,
43
+ reset
44
+ })
45
+
46
+
47
+ </script>
48
+
49
+ <style lang="less" scoped>
50
+ </style>
@@ -0,0 +1,65 @@
1
+ <template>
2
+ <el-select
3
+ v-model="dtoValue"
4
+ v-bind="schema.option"
5
+ class="dynamic-select"
6
+ >
7
+ <el-option
8
+ v-for="item in enumList"
9
+ :key="item.value"
10
+ :label="item.label"
11
+ :value="item.value"
12
+ ></el-option>
13
+ </el-select>
14
+ </template>
15
+
16
+ <script setup>
17
+ import { ref, onMounted } from 'vue';
18
+ import $curl from '$elpisCommon/curl.js';
19
+
20
+ const { schemaKey, schema } = defineProps({
21
+ schemaKey: String,
22
+ schema: Object
23
+ });
24
+
25
+ const emit = defineEmits(['loaded']);
26
+
27
+ const dtoValue = ref();
28
+ const getValue = () => {
29
+ return dtoValue.value !== undefined ? {
30
+ [schemaKey]: dtoValue.value
31
+ } : {}
32
+ }
33
+
34
+ const enumList = ref([]);
35
+ const fetchEnumList = async () => {
36
+ const res = await $curl({
37
+ method: 'get',
38
+ url: schema.option?.api,
39
+ data: {}
40
+ });
41
+ if(res?.data?.length > 0) {
42
+ enumList.value.push(...res?.data);
43
+ }
44
+ }
45
+
46
+ const reset = () => {
47
+ dtoValue.value = schema?.option?.default ?? enumList.value[0]?.value;
48
+ }
49
+
50
+ onMounted(async () => {
51
+ await fetchEnumList();
52
+ reset();
53
+ emit('loaded');
54
+ });
55
+
56
+ defineExpose({
57
+ getValue,
58
+ reset
59
+ })
60
+
61
+
62
+ </script>
63
+
64
+ <style lang="less" scoped>
65
+ </style>
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <el-input
3
+ v-model="dtoValue"
4
+ v-bind="schema.option"
5
+ class="input"
6
+ ></el-input>
7
+ </template>
8
+
9
+ <script setup>
10
+ import { ref, onMounted } from 'vue';
11
+
12
+ const { schemaKey, schema } = defineProps({
13
+ schemaKey: String,
14
+ schema: Object
15
+ });
16
+
17
+ const emit = defineEmits(['loaded']);
18
+
19
+ const dtoValue = ref();
20
+ const getValue = () => {
21
+ return dtoValue.value !== undefined ? {
22
+ [schemaKey]: dtoValue.value
23
+ } : {}
24
+ }
25
+
26
+ const reset = () => {
27
+ dtoValue.value = schema?.option?.default;
28
+ }
29
+
30
+ onMounted(() => {
31
+ reset();
32
+ emit('loaded');
33
+ });
34
+
35
+ defineExpose({
36
+ getValue,
37
+ reset
38
+ })
39
+
40
+
41
+ </script>
42
+
43
+ <style lang="less" scoped>
44
+ </style>
@@ -0,0 +1,51 @@
1
+ <template>
2
+ <el-select
3
+ v-model="dtoValue"
4
+ v-bind="schema.option"
5
+ class="select"
6
+ >
7
+ <el-option
8
+ v-for="item in schema.option?.enumList"
9
+ :key="item.value"
10
+ :label="item.label"
11
+ :value="item.value"
12
+ ></el-option>
13
+ </el-select>
14
+ </template>
15
+
16
+ <script setup>
17
+ import { ref, onMounted } from 'vue';
18
+
19
+ const { schemaKey, schema } = defineProps({
20
+ schemaKey: String,
21
+ schema: Object
22
+ });
23
+
24
+ const emit = defineEmits(['loaded']);
25
+
26
+ const dtoValue = ref();
27
+ const getValue = () => {
28
+ return dtoValue.value !== undefined ? {
29
+ [schemaKey]: dtoValue.value
30
+ } : {}
31
+ }
32
+
33
+ const reset = () => {
34
+ dtoValue.value = schema?.option?.default ?? schema.option?.enumList[0]?.value;
35
+ }
36
+
37
+ onMounted(() => {
38
+ reset();
39
+ emit('loaded');
40
+ });
41
+
42
+ defineExpose({
43
+ getValue,
44
+ reset
45
+ })
46
+
47
+
48
+ </script>
49
+
50
+ <style lang="less" scoped>
51
+ </style>
@@ -0,0 +1,127 @@
1
+ <template>
2
+ <el-form
3
+ v-if="schema && schema.properties"
4
+ :inline="true"
5
+ class="schema-search-bar"
6
+ >
7
+ <!-- 动态组件 -->
8
+ <el-form-item
9
+ v-for="(schemaItem, key) in schema.properties"
10
+ :key="key"
11
+ :label="schemaItem.label"
12
+ >
13
+ <!-- 展示子组件 -->
14
+ <component
15
+ :ref="searchComList"
16
+ :is="SearchItemConfig[schemaItem.option?.comType]?.component"
17
+ :schemaKey="key"
18
+ :schema="schemaItem"
19
+ @loaded="handleChildLoaded"
20
+ ></component>
21
+ </el-form-item>
22
+ <!-- 操作区域 -->
23
+ <el-form-item>
24
+ <el-button
25
+ type="primary"
26
+ plain
27
+ class="search-btn"
28
+ @click="search"
29
+ >搜索</el-button>
30
+ <el-button
31
+ plain
32
+ class="reset-btn"
33
+ @click="reset"
34
+ >重置</el-button>
35
+ </el-form-item>
36
+
37
+ </el-form>
38
+ </template>
39
+
40
+ <script setup>
41
+ import { ref, toRefs } from 'vue';
42
+ import SearchItemConfig from './search-item-config.js';
43
+ const props = defineProps({
44
+ /**
45
+ * schema 配置,结构如下:
46
+ {
47
+ type: 'object',
48
+ properties: {
49
+ key: {
50
+ ...schema, // 标准 schema 配置
51
+ type: '', // 字段类型
52
+ label: '', // 字段的中文名
53
+ option: {
54
+ ...eleComponentConfig, // 标准 el-component-column 配置
55
+ comType: '', // 配置组件类型 input/select/...
56
+ default: '', // 默认值
57
+ }
58
+ },
59
+ ...
60
+ }
61
+ }
62
+ */
63
+ schema: Object
64
+ });
65
+ const { schema } = toRefs(props);
66
+
67
+ const emit = defineEmits(['load', 'search', 'reset']);
68
+
69
+ const searchComList = ref([]);
70
+ const getValue = () => {
71
+ let dtoObj = {};
72
+ searchComList.value.forEach(component => {
73
+ dtoObj = {
74
+ ...dtoObj,
75
+ ...component?.getValue()
76
+ }
77
+ })
78
+
79
+ return dtoObj;
80
+ }
81
+
82
+ let childComLoadedCount = 0;
83
+ const handleChildLoaded = () => {
84
+ childComLoadedCount++;
85
+ if(childComLoadedCount >= Object.keys(schema?.value?.properties).length) {
86
+ emit('load', getValue());
87
+ }
88
+ }
89
+
90
+ const search = () => {
91
+ emit('search', getValue());
92
+ }
93
+
94
+ const reset = () => {
95
+ searchComList.value.forEach(component => component?.reset());
96
+ emit('reset');
97
+ }
98
+
99
+ defineExpose({
100
+ reset,
101
+ getValue
102
+ })
103
+
104
+
105
+ </script>
106
+
107
+ <style lang="less">
108
+ .schema-search-bar {
109
+ min-width: 500px;
110
+
111
+ .select {
112
+ width: 177px;
113
+ }
114
+
115
+ .dynamic-select {
116
+ width: 177px;
117
+ }
118
+
119
+ .search-btn {
120
+ width: 100px;
121
+ }
122
+
123
+ .reset-btn {
124
+ width: 100px;
125
+ }
126
+ }
127
+ </style>
@@ -0,0 +1,27 @@
1
+ import input from './complex-view/input/input';
2
+ import select from './complex-view/select/select';
3
+ import dynamicSelect from './complex-view/dynamic-select/dynamic-select';
4
+ import dateRange from './complex-view/date-range/date-range';
5
+
6
+ // 业务扩展 search-item 配置
7
+ import BusinessSearchItemConfig from '$businessSearchItemConfig';
8
+
9
+ const SearchItemConfig = {
10
+ input: {
11
+ component: input
12
+ },
13
+ select: {
14
+ component: select
15
+ },
16
+ dynamicSelect: {
17
+ component: dynamicSelect
18
+ },
19
+ dateRange: {
20
+ component: dateRange
21
+ }
22
+ }
23
+
24
+ export default {
25
+ ...SearchItemConfig,
26
+ ...BusinessSearchItemConfig
27
+ }