@pixel-shell/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 (80) hide show
  1. package/.eslintgnore +1 -0
  2. package/.eslintrc +55 -0
  3. package/README.md +194 -0
  4. package/app/controller/base.js +40 -0
  5. package/app/controller/project.js +56 -0
  6. package/app/controller/view.js +18 -0
  7. package/app/extend/logger.js +37 -0
  8. package/app/middleware/api-params-verify.js +71 -0
  9. package/app/middleware/api-sign-verify.js +32 -0
  10. package/app/middleware/error-handler.js +33 -0
  11. package/app/middleware/project-handler.js +27 -0
  12. package/app/middleware.js +31 -0
  13. package/app/pages/asserts/custom.css +12 -0
  14. package/app/pages/boot.js +47 -0
  15. package/app/pages/common/curl.js +88 -0
  16. package/app/pages/common/utils.js +2 -0
  17. package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +17 -0
  18. package/app/pages/dashboard/complex-view/header-view/header-view.vue +129 -0
  19. package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +43 -0
  20. package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue +37 -0
  21. package/app/pages/dashboard/complex-view/schema-view/complex-view/table-panel/table-panel.vue +114 -0
  22. package/app/pages/dashboard/complex-view/schema-view/components/component-config.js +22 -0
  23. package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +85 -0
  24. package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +92 -0
  25. package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +106 -0
  26. package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +123 -0
  27. package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +88 -0
  28. package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +18 -0
  29. package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +117 -0
  30. package/app/pages/dashboard/dashboard.vue +89 -0
  31. package/app/pages/dashboard/entry.dashboard.js +42 -0
  32. package/app/pages/store/index.js +5 -0
  33. package/app/pages/store/menu.js +57 -0
  34. package/app/pages/store/project.js +15 -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 +102 -0
  38. package/app/pages/widgets/schema-form/complex-view/input/input.vue +129 -0
  39. package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +130 -0
  40. package/app/pages/widgets/schema-form/complex-view/select/select.vue +116 -0
  41. package/app/pages/widgets/schema-form/form-item-config.js +23 -0
  42. package/app/pages/widgets/schema-form/schema-form.vue +121 -0
  43. package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +41 -0
  44. package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +51 -0
  45. package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +34 -0
  46. package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +36 -0
  47. package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +121 -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 +227 -0
  50. package/app/pages/widgets/sider-container/sider-container.vue +29 -0
  51. package/app/public/static/logo.png +0 -0
  52. package/app/public/static/normalize.css +241 -0
  53. package/app/router/project.js +6 -0
  54. package/app/router/view.js +8 -0
  55. package/app/router-schema/project.js +30 -0
  56. package/app/service/base.js +10 -0
  57. package/app/service/project.js +40 -0
  58. package/app/view/entry.tpl +25 -0
  59. package/app/webpack/build.js +18 -0
  60. package/app/webpack/config/webpack.base.js +234 -0
  61. package/app/webpack/config/webpack.dev.js +58 -0
  62. package/app/webpack/config/webpack.prod.js +113 -0
  63. package/app/webpack/dev.js +60 -0
  64. package/app/webpack/libs/blank.js +1 -0
  65. package/app/webpack/prod.js +22 -0
  66. package/config/config.default.js +3 -0
  67. package/docs/dashboard-mode.js +141 -0
  68. package/elpis-core/env.js +16 -0
  69. package/elpis-core/index.js +70 -0
  70. package/elpis-core/loader/config.js +51 -0
  71. package/elpis-core/loader/controller.js +71 -0
  72. package/elpis-core/loader/extend.js +61 -0
  73. package/elpis-core/loader/middleware.js +69 -0
  74. package/elpis-core/loader/roter-schema.js +54 -0
  75. package/elpis-core/loader/router.js +42 -0
  76. package/elpis-core/loader/service.js +70 -0
  77. package/index.js +35 -0
  78. package/model/index.js +86 -0
  79. package/package.json +92 -0
  80. package/test/controller/project.test.js +194 -0
@@ -0,0 +1,102 @@
1
+ <template>
2
+ <div class="header-container">
3
+ <el-container class="header-container">
4
+ <el-header class="header">
5
+ <el-row type="flex" align="middle" class="header-row">
6
+ <!-- 左上方 title -->
7
+ <el-row type="flex" align="middle" class="title-panel">
8
+ <img src="./asserts/logo.png" class="logo" />
9
+ <el-row class="text">{{ title }}</el-row>
10
+ </el-row>
11
+ <!-- 菜单区域 -->
12
+ <slot name="menu-content"></slot>
13
+ <!-- 用户信息区域 -->
14
+ <el-row type="flex" align="middle" justify="end" class="user-panel">
15
+ <slot name="setting-content"></slot>
16
+ <img src="./asserts/avatar.png" class="avatar" />
17
+ <el-dropdown @command="handleUserCommand">
18
+ <span class="username">
19
+ {{ userName }}<i class="el-icon-arrow-down el-icon--right"></i>
20
+ </span>
21
+ <template #dropdown>
22
+ <el-breadcrumb-item command="logout">退出登录</el-breadcrumb-item>
23
+ </template>
24
+ </el-dropdown>
25
+ </el-row>
26
+ </el-row>
27
+ </el-header>
28
+ <el-main class="main-container">
29
+ <slot name="main-content"></slot>
30
+ </el-main>
31
+ </el-container>
32
+ </div>
33
+ </template>
34
+ <script setup>
35
+ import { ref } from 'vue'
36
+ defineProps({
37
+ title: {
38
+ type: String,
39
+ default: "ELPIS",
40
+ },
41
+ })
42
+ const userName = ref('Miguo')
43
+ const handleUserCommand = (command) => {
44
+ console.log(command)
45
+ }
46
+ </script>
47
+ <style lang="less" scoped>
48
+ .header-container {
49
+ height: 100%;
50
+ min-width: 1000px;
51
+ overflow: hidden;
52
+
53
+ .header {
54
+ max-height: 120px;
55
+ border-bottom: 1px solid #E8E8E8;
56
+
57
+ .header-row {
58
+ height: 60px;
59
+ padding: 0 20px;
60
+ .title-panel {
61
+ width: 180px;
62
+ min-width: 180px;
63
+ .logo {
64
+ margin-right: 10px;
65
+ width: 25px;
66
+ height: 25px;
67
+ border-radius: 50%;
68
+ }
69
+ .text {
70
+ font-size: 16px;
71
+ font-weight: 500;
72
+ }
73
+ }
74
+
75
+ .user-panel {
76
+ margin-left: auto;
77
+ min-width: 190px;
78
+ .avatar {
79
+ margin-right: 12px;
80
+ width: 25px;
81
+ height: 25px;
82
+ border-radius: 50%;
83
+ }
84
+ .username {
85
+ font-size: 16px;
86
+ font-weight: 500;
87
+ cursor: pointer;
88
+ height: 60px;
89
+ line-height: 60px;
90
+ outline: none;
91
+ }
92
+ }
93
+ }
94
+ }
95
+ .main-container {
96
+ padding: 0;
97
+ }
98
+ }
99
+ :deep(.el-header) {
100
+ padding: 0;
101
+ }
102
+ </style>
@@ -0,0 +1,129 @@
1
+ <template>
2
+ <el-row type="flex" align="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"
6
+ >*</el-row
7
+ >
8
+ {{ schema.label }}
9
+ </el-row>
10
+ <!-- value -->
11
+ <el-row class="item-value">
12
+ <el-input
13
+ v-model="dtoValue"
14
+ v-bind="schema.option"
15
+ :placeholder="placeholder"
16
+ class="component"
17
+ :class="validTips ? 'valid-border' : ''"
18
+ @focus="onFocus"
19
+ @blur="onBlur"
20
+ ></el-input>
21
+ </el-row>
22
+ <!-- 错误信息 -->
23
+ <el-row v-if="validTips" class="valid-tips">{{ validTips }}</el-row>
24
+ </el-row>
25
+ </template>
26
+
27
+ <script setup>
28
+ import { ref, toRefs, watch, inject, onMounted } from "vue";
29
+ const ajv = inject("ajv");
30
+
31
+ const props = defineProps({
32
+ schemaKey: String,
33
+ schema: Object,
34
+ model: String,
35
+ });
36
+ const { schemaKey, schema } = props;
37
+ const { model } = toRefs(props);
38
+
39
+ const name = ref("input");
40
+ const dtoValue = ref(undefined);
41
+ const placeholder = ref("");
42
+ const validTips = ref(null);
43
+
44
+ const initData = () => {
45
+ dtoValue.value = model.value ?? schema.option?.default;
46
+ validTips.value = null;
47
+
48
+ const { minlength, maxlength, pattern } = schema.option;
49
+ const ruleList = [];
50
+ if (schema.option?.placeholder) {
51
+ ruleList.push(schema.option.placeholder);
52
+ }
53
+ if (minlength) {
54
+ ruleList.push(`最小长度:${minlength}`);
55
+ }
56
+ if (maxlength) {
57
+ ruleList.push(`最大长度:${maxlength}`);
58
+ }
59
+ if (pattern) {
60
+ ruleList.push(`格式:${pattern}`);
61
+ }
62
+ placeholder.value = ruleList.join("|");
63
+ };
64
+
65
+ onMounted(() => {
66
+ initData();
67
+ });
68
+
69
+ watch(
70
+ [model, schema],
71
+ () => {
72
+ initData();
73
+ },
74
+ { deep: true },
75
+ );
76
+
77
+ // 表单校验
78
+ const validate = () => {
79
+ validTips.value = null;
80
+ const { type } = schema;
81
+ // 校验是否必填
82
+ if (schema.option?.required && !dtoValue.value) {
83
+ validTips.value = "不能为空";
84
+ return false;
85
+ }
86
+ // ajv 校验 schema
87
+ if (dtoValue.value) {
88
+ const validate = ajv.compile(schema);
89
+ const valid = validate(dtoValue.value);
90
+ if (!valid && validate.errors && validate.errors[0]) {
91
+ const { keyword, params } = validate.errors[0];
92
+ if (keyword === "type") {
93
+ validTips.value = `类型必须为${type}`;
94
+ } else if (keyword === "maxlength") {
95
+ validTips.value = `最大长度应为${params.limit}`;
96
+ } else if (keyword === "minlength") {
97
+ validTips.value = `最小长度应为${params.limit}`;
98
+ } else if (keyword === "pattern") {
99
+ validTips.value = `格式错误`;
100
+ } else {
101
+ validTips.value = `校验失败`;
102
+ }
103
+ return false;
104
+ }
105
+ }
106
+ return true;
107
+ };
108
+
109
+ // 获取表单值
110
+ const getValue = () => {
111
+ return dtoValue.value !== undefined ? { [schemaKey]: dtoValue.value } : {};
112
+ };
113
+
114
+ const onFocus = () => {
115
+ validTips.value = null;
116
+ };
117
+
118
+ const onBlur = () => {
119
+ validate();
120
+ };
121
+
122
+ defineExpose({
123
+ name,
124
+ validate,
125
+ getValue,
126
+ });
127
+ </script>
128
+
129
+ <style lang="less" scoped></style>
@@ -0,0 +1,130 @@
1
+ <template>
2
+ <el-row type="flex" align="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"
6
+ >*</el-row
7
+ >
8
+ {{ schema.label }}
9
+ </el-row>
10
+ <!-- value -->
11
+ <el-row class="item-value">
12
+ <el-input-number
13
+ v-model="dtoValue"
14
+ v-bind="schema.option"
15
+ :controls="false"
16
+ :placeholder="placeholder"
17
+ class="component"
18
+ :class="validTips ? 'valid-border' : ''"
19
+ @focus="onFocus"
20
+ @blur="onBlur"
21
+ ></el-input-number>
22
+ </el-row>
23
+ <!-- 错误信息 -->
24
+ <el-row v-if="validTips" class="valid-tips">{{ validTips }}</el-row>
25
+ </el-row>
26
+ </template>
27
+
28
+ <script setup>
29
+ import { ref, toRefs, watch, inject, onMounted } from "vue";
30
+ const ajv = inject("ajv");
31
+
32
+ const props = defineProps({
33
+ schemaKey: String,
34
+ schema: Object,
35
+ model: Number,
36
+ });
37
+ const { schemaKey, schema } = props;
38
+ const { model } = toRefs(props);
39
+ const name = ref("inputNumber");
40
+ const dtoValue = ref(undefined);
41
+ const placeholder = ref("");
42
+ const validTips = ref(null);
43
+
44
+ const initData = () => {
45
+ dtoValue.value = model.value ?? schema.option?.default;
46
+ validTips.value = null;
47
+
48
+ const { minimum, maximum } = schema;
49
+
50
+ const ruleList = [];
51
+ if (schema.option?.placeholder) {
52
+ ruleList.push(schema.option.placeholder);
53
+ }
54
+ if (minimum !== undefined) {
55
+ ruleList.push(`最小值为${minimum}`);
56
+ }
57
+ if (maximum !== undefined) {
58
+ ruleList.push(`最大值为${maximum}`);
59
+ }
60
+
61
+ placeholder.value = ruleList.join("|");
62
+ };
63
+
64
+ onMounted(() => {
65
+ initData();
66
+ });
67
+
68
+ watch(
69
+ [model, schema],
70
+ () => {
71
+ initData();
72
+ },
73
+ { deep: true },
74
+ );
75
+
76
+ // 表单校验
77
+ const validate = () => {
78
+ validTips.value = null;
79
+ const { type } = schema;
80
+ // 校验是否必填
81
+ if (schema.option?.required && !dtoValue.value) {
82
+ validTips.value = "不能为空";
83
+ return false;
84
+ }
85
+ // ajv 校验 schema
86
+ if (dtoValue.value) {
87
+ const validate = ajv.compile(schema);
88
+ const valid = validate(dtoValue.value);
89
+ if (!valid && validate.errors && validate.errors[0]) {
90
+ const { keyword, params } = validate.errors[0];
91
+ if (keyword === "type") {
92
+ validTips.value = `类型必须为${type}`;
93
+ } else if (keyword === "minimum") {
94
+ validTips.value = `最小值为${params.limit}`;
95
+ } else if (keyword === "maximum") {
96
+ validTips.value = `最大值为${params.limit}`;
97
+ } else {
98
+ validTips.value = `校验失败`;
99
+ }
100
+ return false;
101
+ }
102
+ }
103
+ return true;
104
+ };
105
+
106
+ // 获取表单值
107
+ const getValue = () => {
108
+ return dtoValue.value !== undefined ? { [schemaKey]: dtoValue.value } : {};
109
+ };
110
+
111
+ const onFocus = () => {
112
+ validTips.value = null;
113
+ };
114
+
115
+ const onBlur = () => {
116
+ validate();
117
+ };
118
+
119
+ defineExpose({
120
+ name,
121
+ validate,
122
+ getValue,
123
+ });
124
+ </script>
125
+
126
+ <style lang="less" scoped>
127
+ :deep(.el-input-number, .el-input__inner) {
128
+ text-align: left;
129
+ }
130
+ </style>
@@ -0,0 +1,116 @@
1
+ <template>
2
+ <el-row type="flex" align="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"
6
+ >*</el-row
7
+ >
8
+ {{ schema.label }}
9
+ </el-row>
10
+ <!-- value -->
11
+ <el-row class="item-value">
12
+ <el-select
13
+ v-model="dtoValue"
14
+ v-bind="schema.option"
15
+ class="component"
16
+ :class="validTips ? 'valid-border' : ''"
17
+ @change="onChange"
18
+ >
19
+ <el-option
20
+ v-for="item in schema.option?.enumList"
21
+ :key="item.value"
22
+ :label="item.label"
23
+ :value="item.value"
24
+ ></el-option>
25
+ </el-select>
26
+ </el-row>
27
+ <!-- 错误信息 -->
28
+ <el-row v-if="validTips" class="valid-tips">{{ validTips }}</el-row>
29
+ </el-row>
30
+ </template>
31
+
32
+ <script setup>
33
+ import { ref, toRefs, watch, inject, onMounted } from "vue";
34
+ const ajv = inject("ajv");
35
+
36
+ const props = defineProps({
37
+ schemaKey: String,
38
+ schema: Object,
39
+ model: null,
40
+ });
41
+ const { schemaKey, schema } = props;
42
+ const { model } = toRefs(props);
43
+ const name = ref("select");
44
+ const dtoValue = ref(undefined);
45
+ const validTips = ref(null);
46
+
47
+ const initData = () => {
48
+ dtoValue.value = model.value ?? schema.option?.default;
49
+ validTips.value = null;
50
+ };
51
+
52
+ onMounted(() => {
53
+ initData();
54
+ });
55
+
56
+ watch(
57
+ [model, schema],
58
+ () => {
59
+ initData();
60
+ },
61
+ { deep: true },
62
+ );
63
+
64
+ // 表单校验
65
+ const validate = () => {
66
+ validTips.value = null;
67
+ // 校验是否必填
68
+ if (schema.option?.required && !dtoValue.value) {
69
+ validTips.value = "不能为空";
70
+ return false;
71
+ }
72
+ // ajv 校验 schema
73
+ if (dtoValue.value) {
74
+ let dtoEnum = [];
75
+ if (schema.option?.enumList) {
76
+ dtoEnum = schema.option.enumList.map((item) => item.value);
77
+ }
78
+ const validate = ajv.compile({
79
+ schema,
80
+ ...{ enum: dtoEnum },
81
+ })
82
+ const valid = validate(dtoValue.value);
83
+ if(!valid && validate.errors && validate.errors[0]) {
84
+ const { keyword } = validate.errors[0];
85
+ if(keyword === "enum") {
86
+ validTips.value = "取值超出枚举范围";
87
+ } else {
88
+ validTips.value = "不符合要求";
89
+ }
90
+ return false;
91
+ }
92
+ }
93
+ return true;
94
+ };
95
+
96
+ // 获取表单值
97
+ const getValue = () => {
98
+ return dtoValue.value !== undefined ? { [schemaKey]: dtoValue.value } : {};
99
+ };
100
+
101
+ const onChange = () => {
102
+ validate();
103
+ };
104
+
105
+ defineExpose({
106
+ name,
107
+ validate,
108
+ getValue,
109
+ });
110
+ </script>
111
+
112
+ <style lang="less" scoped>
113
+ :deep(.el-input-number, .el-input__inner) {
114
+ text-align: left;
115
+ }
116
+ </style>
@@ -0,0 +1,23 @@
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
+ // 业务扩展FormItem 配置
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 {
21
+ ...FormItemConfig,
22
+ ...BusinessFormItemConfig
23
+ }
@@ -0,0 +1,121 @@
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
+ v-show="itemSchema.option.visible !== false"
6
+ ref="formComList"
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
+ option: {
35
+ ...elComponentConfig, //标准 el-component 配置
36
+ comType: "", // 控件类型,枚举值:input,select 。。。
37
+ visible: true, // 是否显示
38
+ disabled: false, // 是否禁用
39
+ default: "", // 默认值
40
+
41
+ // comType === select 时,相关配置
42
+ enumList: [], // 下拉选项列表
43
+ }
44
+ },
45
+ },
46
+ }
47
+ */
48
+ schema: Object,
49
+ /**
50
+ * 表单数据
51
+ */
52
+ model: Object,
53
+ });
54
+ const { schema } = toRefs(props);
55
+ const formComList = ref([]);
56
+
57
+ // 表单校验
58
+ const validate = () => {
59
+ return formComList.value.every((item) => {
60
+ return item.validate();
61
+ });
62
+ };
63
+ // 获取表单值
64
+ const getValue = () => {
65
+ return formComList.value.reduce((dtoObj, item) => {
66
+ return { ...dtoObj, ...item.getValue() };
67
+ }, {});
68
+ };
69
+ defineExpose({
70
+ validate,
71
+ getValue,
72
+ });
73
+ </script>
74
+
75
+ <style lang="less">
76
+ .schema-form {
77
+ .form-item {
78
+ margin-bottom: 20px;
79
+ min-width: 500px;
80
+
81
+ .item-label {
82
+ margin-right: 15px;
83
+ min-width: 70px;
84
+ text-align: right;
85
+ font-size: 14px;
86
+ color: #fff;
87
+ word-break: break-all;
88
+
89
+ .required {
90
+ top: 2px;
91
+ padding-left: 4px;
92
+ color: #f56c6c;
93
+ font-size: 20px;
94
+ }
95
+ }
96
+ .item-value {
97
+ .component {
98
+ width: 320px;
99
+ }
100
+ .valid-border {
101
+ .el-input__wrapper {
102
+ border: 1px solid #f93f3f;
103
+ box-shadow: 0 0 0 0;
104
+ }
105
+ .el-select__wrapper {
106
+ border: 1px solid #f93f3f;
107
+ box-shadow: 0 0 0 0;
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>
@@ -0,0 +1,41 @@
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
+ <script setup>
13
+ import { ref, onMounted } from "vue";
14
+ import moment from "moment";
15
+
16
+ const { schemaKey, schema } = defineProps({
17
+ schemaKey: String,
18
+ schema: Object,
19
+ });
20
+
21
+ const emit = defineEmits(["loaded"]);
22
+ const dtoValue = ref([]);
23
+ const getValue = () => {
24
+ return dtoValue.value?.length === 2 ? {
25
+ [`${schemaKey}_start`]: moment(dtoValue.value[0]).format("YYYY-MM-DD"),
26
+ [`${schemaKey}_end`]: moment(dtoValue.value[1]).format("YYYY-MM-DD"),
27
+ } : {};
28
+ };
29
+ const reset = () => {
30
+ dtoValue.value = [];
31
+ };
32
+ onMounted(() => {
33
+ reset();
34
+ emit("loaded");
35
+ });
36
+ defineExpose({
37
+ getValue,
38
+ reset,
39
+ });
40
+ </script>
41
+ <style lang="scss" scoped></style>
@@ -0,0 +1,51 @@
1
+ <template>
2
+ <el-select v-model="dtoValue" v-bind="schema.option" class="dynamic-select">
3
+ <el-option
4
+ v-for="item in enumList"
5
+ :key="item.value"
6
+ :label="item.label"
7
+ :value="item.value"
8
+ ></el-option
9
+ ></el-select>
10
+ </template>
11
+ <script setup>
12
+ import { ref, onMounted } from "vue";
13
+ import $curl from "$elpisCommon/curl";
14
+
15
+ const { schemaKey, schema } = defineProps({
16
+ schemaKey: String,
17
+ schema: Object,
18
+ });
19
+ const emit = defineEmits(["loaded"]);
20
+
21
+ const enumList = ref([]);
22
+ const fetchEnumList = async () => {
23
+ const res = await $curl({
24
+ method: "GET",
25
+ url: schema?.option?.api,
26
+ data: {}
27
+ })
28
+
29
+ if(res?.data?.length > 0) {
30
+ enumList.value.push(...res?.data)
31
+ }
32
+ }
33
+
34
+ const dtoValue = ref();
35
+ const getValue = () => {
36
+ return dtoValue.value !== undefined ? { [schemaKey]: dtoValue.value } : {};
37
+ };
38
+ const reset = () => {
39
+ dtoValue.value = schema?.option?.default ?? enumList.value[0]?.value;
40
+ };
41
+ onMounted(async() => {
42
+ await fetchEnumList();
43
+ reset();
44
+ emit("loaded");
45
+ })
46
+ defineExpose({
47
+ getValue,
48
+ reset,
49
+ });
50
+ </script>
51
+ <style lang="scss" scoped></style>