@codertqy/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 (83) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc +55 -0
  3. package/README.md +218 -0
  4. package/app/controller/base.js +40 -0
  5. package/app/controller/project.js +81 -0
  6. package/app/controller/view.js +22 -0
  7. package/app/extend/logger.js +43 -0
  8. package/app/middleware/api-params-verify.js +73 -0
  9. package/app/middleware/api-sign-verify.js +49 -0
  10. package/app/middleware/error-handler.js +31 -0
  11. package/app/middleware/project-handler.js +26 -0
  12. package/app/middleware.js +44 -0
  13. package/app/pages/assets/custom.css +14 -0
  14. package/app/pages/boot.js +56 -0
  15. package/app/pages/common/curl.js +84 -0
  16. package/app/pages/common/index.css +3 -0
  17. package/app/pages/common/utils.js +1 -0
  18. package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +19 -0
  19. package/app/pages/dashboard/complex-view/header-view/header-view.vue +126 -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 +35 -0
  22. package/app/pages/dashboard/complex-view/schema-view/complex-view/table-panel/table-panel.vue +120 -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 +87 -0
  25. package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +100 -0
  26. package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +122 -0
  27. package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +161 -0
  28. package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +95 -0
  29. package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +19 -0
  30. package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +135 -0
  31. package/app/pages/dashboard/dashboard.vue +86 -0
  32. package/app/pages/dashboard/entry.dashboard.js +48 -0
  33. package/app/pages/store/index.js +3 -0
  34. package/app/pages/store/menu.js +68 -0
  35. package/app/pages/store/project.js +12 -0
  36. package/app/pages/widgets/header-container/asserts/avatar.png +0 -0
  37. package/app/pages/widgets/header-container/asserts/logo.png +0 -0
  38. package/app/pages/widgets/header-container/header-container.vue +107 -0
  39. package/app/pages/widgets/schema-form/complex-view/input/input.vue +138 -0
  40. package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +140 -0
  41. package/app/pages/widgets/schema-form/complex-view/select/select.vue +122 -0
  42. package/app/pages/widgets/schema-form/form-item-config.js +20 -0
  43. package/app/pages/widgets/schema-form/schema-form.vue +135 -0
  44. package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +51 -0
  45. package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +63 -0
  46. package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +41 -0
  47. package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +49 -0
  48. package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +126 -0
  49. package/app/pages/widgets/schema-search-bar/search-item-config.js +22 -0
  50. package/app/pages/widgets/schema-table/schema-table.vue +259 -0
  51. package/app/pages/widgets/sider-container/sider-container.vue +27 -0
  52. package/app/public/output/entry.page1.tpl +40 -0
  53. package/app/public/output/entry.page2.tpl +11 -0
  54. package/app/public/static/logo.png +0 -0
  55. package/app/public/static/normalize.css +239 -0
  56. package/app/router/project.js +22 -0
  57. package/app/router/view.js +17 -0
  58. package/app/router-schema/project.js +34 -0
  59. package/app/service/base.js +15 -0
  60. package/app/service/project.js +59 -0
  61. package/app/view/entry.tpl +25 -0
  62. package/app/webpack/config/webpack.base.js +280 -0
  63. package/app/webpack/config/webpack.dev.js +57 -0
  64. package/app/webpack/config/webpack.prod.js +127 -0
  65. package/app/webpack/dev.js +63 -0
  66. package/app/webpack/libs/blank.js +1 -0
  67. package/app/webpack/prod.js +22 -0
  68. package/config/config.beta.js +1 -0
  69. package/config/config.default.js +3 -0
  70. package/config/config.prod.js +1 -0
  71. package/elpis-core/env.js +27 -0
  72. package/elpis-core/index.js +98 -0
  73. package/elpis-core/loader/config.js +58 -0
  74. package/elpis-core/loader/controller.js +93 -0
  75. package/elpis-core/loader/extend.js +63 -0
  76. package/elpis-core/loader/middleware.js +84 -0
  77. package/elpis-core/loader/router-schema.js +56 -0
  78. package/elpis-core/loader/router.js +50 -0
  79. package/elpis-core/loader/service.js +85 -0
  80. package/index.js +38 -0
  81. package/model/index.js +129 -0
  82. package/package.json +92 -0
  83. package/test/controller/project.test.js +214 -0
@@ -0,0 +1,122 @@
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
+ <script setup>
32
+ import { ref, toRefs, watch, inject, onMounted } from "vue";
33
+ const ajv = inject("ajv");
34
+
35
+ const props = defineProps({
36
+ schemaKey: {
37
+ type: String,
38
+ },
39
+ schema: {
40
+ type: Object,
41
+ },
42
+ model: {
43
+ type: null,
44
+ },
45
+ });
46
+ const { schemaKey, schema } = props;
47
+ const { model } = toRefs(props);
48
+
49
+ const dtoValue = ref();
50
+ const validTips = ref(null);
51
+ const name = ref("select");
52
+
53
+ const initData = () => {
54
+ dtoValue.value = model.value ?? schema.option.default;
55
+ validTips.value = null;
56
+ };
57
+
58
+ onMounted(() => {
59
+ initData();
60
+ });
61
+
62
+ watch(
63
+ [model, schema],
64
+ () => {
65
+ initData();
66
+ },
67
+ { deep: true },
68
+ );
69
+
70
+ const validate = () => {
71
+ validTips.value = null;
72
+ // const { type } = schema;
73
+ // 校验是否必填
74
+ if (schema.option?.required && !dtoValue.value) {
75
+ validTips.value = "不能为空";
76
+ return false;
77
+ }
78
+ // 校验 schema
79
+ if (dtoValue.value) {
80
+ let dtoEnum = [];
81
+ if (schema.option?.enumList) {
82
+ dtoEnum = schema.option?.enumList.map((item) => item.value);
83
+ }
84
+ const validate = ajv.compile({
85
+ schema,
86
+ ...{ enum: dtoEnum },
87
+ });
88
+
89
+ const valid = validate(dtoValue.value);
90
+ if (!valid && validate.errros && validate.errors[0]) {
91
+ if (validate.errors[0].keyword === "enum") {
92
+ validTips.value = "取值超出枚举范围";
93
+ } else {
94
+ console.log(validate.errors[0]);
95
+ validTips.value = "不符合要求";
96
+ }
97
+ return false;
98
+ }
99
+ }
100
+ return true;
101
+ };
102
+ const getValue = () => {
103
+ return dtoValue.value !== undefined
104
+ ? {
105
+ [schemaKey]: dtoValue.value,
106
+ }
107
+ : {};
108
+ };
109
+
110
+ // 监听 change
111
+ const onChange = (value) => {
112
+ validate();
113
+ };
114
+
115
+ defineExpose({
116
+ name,
117
+ validate,
118
+ getValue,
119
+ });
120
+ </script>
121
+
122
+ <style scoped lang="less"></style>
@@ -0,0 +1,20 @@
1
+ import input from "./complex-view/input/input.vue";
2
+ import select from "./complex-view/select/select.vue";
3
+ import inputNumber from "./complex-view/input-number/input-number.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 { ...FormItemConfig, ...BusinessFormItemConfig };
@@ -0,0 +1,135 @@
1
+ <template>
2
+ <el-row v-if="schema && schema.properties" class="schema-form">
3
+ <!-- 这里遍历的是 对象,所以key是每一项的键名 -->
4
+ <template v-for="(itemSchema, key) in schema.properties">
5
+ <component
6
+ :is="FormItemConfig[itemSchema.option?.comType]?.component"
7
+ ref="formComList"
8
+ v-show="itemSchema.option.visible !== false"
9
+ :schemaKey="key"
10
+ :schema="itemSchema"
11
+ :model="model ? model[key] : undefined"
12
+ ></component>
13
+ </template>
14
+ </el-row>
15
+ </template>
16
+ <script setup>
17
+ import { ref, toRefs, provide } from "vue";
18
+ import FormItemConfig from "./form-item-config";
19
+
20
+ // 校验工具
21
+ const Ajv = require("ajv");
22
+ const ajv = new Ajv();
23
+ provide("ajv", ajv);
24
+
25
+ const props = defineProps({
26
+ /** schema 配置结构如下
27
+ * {
28
+ type: "object",
29
+ properties: {
30
+ key: {
31
+ ...schema, // 标准 schema 配置
32
+ type: "", // 字段类型
33
+ tabel: "", // 字段的中文名
34
+ option: {
35
+ ...elTableColumnConfig, // 标准 el-component-column 配置
36
+ comType: "", // 控件类型 input/select/....
37
+ required: false, // 是否必填(true/false) 默认为 false
38
+ visible: true, // 是否展示(true/false) 默认为 true
39
+ disabled: false, //是否禁用(true/false) 默认为 false
40
+ default: "", //默认值
41
+ enumList: [], //枚举列表
42
+ },
43
+ },
44
+ },
45
+ },
46
+ */
47
+ schema: {
48
+ type: Object,
49
+ },
50
+
51
+ /**
52
+ * 表单数据
53
+ */
54
+ model: {
55
+ type: Object,
56
+ },
57
+ });
58
+ const { schema, model } = toRefs(props);
59
+
60
+ const formComList = ref([]);
61
+ // 表单校验
62
+ const validate = () => {
63
+ // 遍历所有组件,进行校验,有一个为false都是false
64
+ return formComList.value.every((component) => {
65
+ const result = component.validate();
66
+ return result;
67
+ });
68
+ };
69
+ // 获取表单值
70
+ const getValue = () => {
71
+ return formComList.value.reduce((dtoObj, component) => {
72
+ return { ...dtoObj, ...component.getValue() };
73
+ }, {});
74
+ // let dtoObj = {};
75
+ // // 遍历
76
+ // formComList.value.forEach((component) => {
77
+ // dtoObj = {
78
+ // ...dtoObj,
79
+ // ...component.getValue(),
80
+ // };
81
+ // });
82
+ // return dtoObj;
83
+ };
84
+
85
+ defineExpose({
86
+ validate,
87
+ getValue,
88
+ });
89
+ </script>
90
+
91
+ <style lang="less">
92
+ .schema-form {
93
+ .form-item {
94
+ margin-bottom: 20px;
95
+ min-width: 500px;
96
+ .item-label {
97
+ margin-right: 15px;
98
+ min-width: 70px;
99
+ text-align: right;
100
+ font-size: 14px;
101
+ color: #ffffff;
102
+ word-break: break-all;
103
+ .required {
104
+ top: 2px;
105
+ padding-left: 4px;
106
+ color: #f56c6c;
107
+ font-size: 20px;
108
+ }
109
+ }
110
+ .item-value {
111
+ .component {
112
+ width: 320px;
113
+ }
114
+ .valid-border {
115
+ .el-input__warpper {
116
+ border: 1px solid #f93f3f;
117
+ box-shadow: 0 0 0 0;
118
+ }
119
+ .el-select__warpper {
120
+ border: 1px solid #f93f3f;
121
+ box-shadow: 0 0 0 0;
122
+ }
123
+ }
124
+ }
125
+ .valid-tips {
126
+ margin-left: 10px;
127
+ height: 36px;
128
+ line-height: 36px;
129
+ overflow: hidden;
130
+ font-size: 12px;
131
+ color: #f93f3f;
132
+ }
133
+ }
134
+ }
135
+ </style>
@@ -0,0 +1,51 @@
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
+ const { schemaKey, schema } = defineProps({
16
+ schemaKey: {
17
+ type: String,
18
+ },
19
+ schema: {
20
+ type: Object,
21
+ },
22
+ });
23
+
24
+ const emit = defineEmits(["loaded"]);
25
+
26
+ const dtoValue = ref([]);
27
+ const getValue = () => {
28
+ return dtoValue.value?.length === 2
29
+ ? {
30
+ [`${schemaKey}_start`]: moment(dtoValue.value[0]).format("YYYY-MM-DD"),
31
+ [`${schemaKey}_end`]: moment(dtoValue.value[1]).format("YYYY-MM-DD"),
32
+ }
33
+ : {};
34
+ };
35
+
36
+ const reset = () => {
37
+ dtoValue.value = [];
38
+ };
39
+
40
+ onMounted(() => {
41
+ reset();
42
+ emit("loaded");
43
+ });
44
+
45
+ defineExpose({
46
+ getValue,
47
+ reset,
48
+ });
49
+ </script>
50
+
51
+ <style lang="less" scoped></style>
@@ -0,0 +1,63 @@
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.js";
14
+ const { schemaKey, schema } = defineProps({
15
+ schemaKey: {
16
+ type: String,
17
+ },
18
+ schema: {
19
+ type: Object,
20
+ },
21
+ });
22
+
23
+ const emit = defineEmits(["loaded"]);
24
+
25
+ const dtoValue = ref();
26
+ const getValue = () => {
27
+ return dtoValue.value !== undefined
28
+ ? {
29
+ [schemaKey]: dtoValue.value,
30
+ }
31
+ : {};
32
+ };
33
+
34
+ const reset = () => {
35
+ // 如果没有值,则给下拉框第一项
36
+ dtoValue.value = schema?.option?.default ?? enumList.value[0].value;
37
+ };
38
+ const enumList = ref([]);
39
+ const fetchEnumList = async () => {
40
+ const res = await $curl({
41
+ method: "get",
42
+ url: schema?.option?.api,
43
+ data: {},
44
+ });
45
+
46
+ if (res?.data?.length > 0) {
47
+ enumList.value.push(...res?.data);
48
+ }
49
+ };
50
+
51
+ onMounted(async() => {
52
+ await fetchEnumList();
53
+ reset();
54
+ emit("loaded");
55
+ });
56
+
57
+ defineExpose({
58
+ getValue,
59
+ reset,
60
+ });
61
+ </script>
62
+
63
+ <style lang="less" scoped></style>
@@ -0,0 +1,41 @@
1
+ <template>
2
+ <el-input v-model="dtoValue" v-bind="schema.option" class="input"></el-input>
3
+ </template>
4
+ <script setup>
5
+ import { ref, onMounted } from "vue";
6
+
7
+ const { schemaKey, schema } = defineProps({
8
+ schemaKey: {
9
+ type: String,
10
+ },
11
+ schema: {
12
+ type: Object,
13
+ },
14
+ });
15
+
16
+ const emit = defineEmits(["loaded"]);
17
+ const dtoValue = ref();
18
+ const getValue = () => {
19
+ return dtoValue.value !== undefined
20
+ ? {
21
+ [schemaKey]: dtoValue.value,
22
+ }
23
+ : {};
24
+ };
25
+
26
+ onMounted(() => {
27
+ reset();
28
+ emit("loaded");
29
+ });
30
+
31
+ const reset = () => {
32
+ dtoValue.value = schema?.option?.default;
33
+ };
34
+
35
+ defineExpose({
36
+ getValue,
37
+ reset,
38
+ });
39
+ </script>
40
+
41
+ <style lang="less" scoped></style>
@@ -0,0 +1,49 @@
1
+ <template>
2
+ <el-select v-model="dtoValue" v-bind="schema.option" class="select">
3
+ <el-option
4
+ v-for="item in schema.option?.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
+
14
+ const { schemaKey, schema } = defineProps({
15
+ schemaKey: {
16
+ type: String,
17
+ },
18
+ schema: {
19
+ type: Object,
20
+ },
21
+ });
22
+
23
+ const emit = defineEmits(["loaded"]);
24
+
25
+ const dtoValue = ref();
26
+ const getValue = () => {
27
+ return dtoValue.value !== undefined
28
+ ? {
29
+ [schemaKey]: dtoValue.value,
30
+ }
31
+ : {};
32
+ };
33
+ onMounted(() => {
34
+ reset();
35
+ emit("loaded");
36
+ });
37
+ const reset = () => {
38
+ // 如果没有值,则给下拉框第一项
39
+ dtoValue.value =
40
+ schema?.option?.default ?? schema?.option?.enumList[0]?.value;
41
+ };
42
+
43
+ defineExpose({
44
+ getValue,
45
+ reset,
46
+ });
47
+ </script>
48
+
49
+ <style lang="less" scoped></style>
@@ -0,0 +1,126 @@
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 type="primary" plain class="search-btn" @click="search">
25
+ 搜索
26
+ </el-button>
27
+ <el-button plain class="reset-btn" @click="reset"> 重置 </el-button>
28
+ </el-form-item>
29
+ </el-form>
30
+ </template>
31
+ <script setup>
32
+ import { ref, toRefs } from "vue";
33
+ import SearchItemConfig from "./search-item-config";
34
+ const props = defineProps({
35
+ /**
36
+ schema 配置,结构如下:
37
+ type: "object",
38
+ properties: {
39
+ key: {
40
+ ...schema, // 标准 schema 配置
41
+ type: "", // 字段类型
42
+ tabel: "", // 字段的中文名
43
+ // 字段在 table 中的相关配置
44
+ tableOption: {
45
+ ...elTableColumnConfig, // 标准 el-table-column 配置
46
+ visiable: true, // 默认为 true (false ,表示不在表单中显示)
47
+ toFixed: 2,
48
+ },
49
+ // 字段在 search-abr 中的相关配置
50
+ searchOption: {
51
+ ...elComponentConfig, // 标准 el-component-column 配置 比如组件库中的input、form等
52
+ comType: "", // 配置组件类型 input/select/....
53
+ default: "", // 默认值
54
+ },
55
+ },
56
+ },
57
+ */
58
+ schema: {
59
+ type: Object,
60
+ required: true,
61
+ },
62
+ });
63
+ const { schema } = toRefs(props);
64
+ // 因为该组件也需要调用api来获取数据
65
+ const emit = defineEmits(["load", "search", "reset"]);
66
+
67
+ // 保存动态组件中的每个实例对象
68
+ const searchComList = ref([]);
69
+ const getValue = () => {
70
+ let dtoObj = {};
71
+ // 遍历
72
+ searchComList.value.forEach((component) => {
73
+ dtoObj = {
74
+ ...dtoObj,
75
+ ...component?.getValue(),
76
+ };
77
+ });
78
+ return dtoObj;
79
+ };
80
+ const search = () => {
81
+ emit("search", getValue());
82
+ };
83
+ const reset = () => {
84
+ // 调用每一个组件中的 reset 方法
85
+ searchComList.value.forEach((component) => {
86
+ component.reset();
87
+ });
88
+ emit("reset");
89
+ };
90
+
91
+ /**
92
+ * 动态子组件中的加载完成之后,才会执行后续
93
+ */
94
+ let childComLoadedCount = 0;
95
+ const handleChildLoaded = () => {
96
+ childComLoadedCount++;
97
+ if (childComLoadedCount === Object.keys(schema?.value?.properties).length) {
98
+ emit("load", getValue());
99
+ }
100
+ };
101
+ defineExpose({
102
+ reset,
103
+ getValue,
104
+ });
105
+ </script>
106
+
107
+ <style lang="less">
108
+ .schema-search-bar {
109
+ min-width: 500px;
110
+ .input {
111
+ width: 280px;
112
+ }
113
+ .select {
114
+ width: 180px;
115
+ }
116
+ .dynamic-select {
117
+ width: 180px;
118
+ }
119
+ .search-btn {
120
+ width: 100px;
121
+ }
122
+ .reset-btn {
123
+ width: 100px;
124
+ }
125
+ }
126
+ </style>
@@ -0,0 +1,22 @@
1
+ import input from "./complex-view/input/input.vue";
2
+ import select from "./complex-view/select/select.vue";
3
+ import dynamicSelect from "./complex-view/dynamic-select/dynamic-select.vue";
4
+ import dateRange from "./complex-view/date-range/date-range.vue";
5
+
6
+ // 业务扩展 search-item 配置
7
+ import BusinessSearchItemConfig from "$businessSearchItemConfig";
8
+ const SearchItemConfig = {
9
+ input: {
10
+ component: input,
11
+ },
12
+ select: {
13
+ component: select,
14
+ },
15
+ dynamicSelect: {
16
+ component: dynamicSelect,
17
+ },
18
+ dateRange: {
19
+ component: dateRange,
20
+ },
21
+ };
22
+ export default { ...SearchItemConfig, ...BusinessSearchItemConfig };