free-fe-core-modules 0.0.1

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 (112) hide show
  1. package/README.md +7 -0
  2. package/components/.gitkeep +0 -0
  3. package/components/Basic/BreadCrumbs.vue +87 -0
  4. package/components/Basic/EIcon.vue +84 -0
  5. package/components/Basic/LeveledMenus.vue +92 -0
  6. package/components/Basic/SummaryHead.vue +312 -0
  7. package/components/Dialog/BasicDialog.vue +442 -0
  8. package/components/Dialog/index.js +38 -0
  9. package/components/Dialog/index1.js +49 -0
  10. package/components/FloatingWindow/index.vue +140 -0
  11. package/components/SelectLocales/index.vue +47 -0
  12. package/components/SlidingCarousel/index.vue +86 -0
  13. package/components/SlidingNews/index.vue +138 -0
  14. package/components/StickyButtons/index.vue +98 -0
  15. package/components/ThemeSwitch/index.vue +77 -0
  16. package/field-components/Display/index.js +3 -0
  17. package/field-components/Fields/AgreementCheck.vue +161 -0
  18. package/field-components/Fields/ApiCall.vue +139 -0
  19. package/field-components/Fields/Boolean.vue +112 -0
  20. package/field-components/Fields/Category.vue +33 -0
  21. package/field-components/Fields/Check.vue +131 -0
  22. package/field-components/Fields/Customize.vue +103 -0
  23. package/field-components/Fields/Date.vue +142 -0
  24. package/field-components/Fields/DateRange.vue +199 -0
  25. package/field-components/Fields/DynamicList.vue +575 -0
  26. package/field-components/Fields/FieldEditor.vue +379 -0
  27. package/field-components/Fields/File.vue +382 -0
  28. package/field-components/Fields/FileList.vue +405 -0
  29. package/field-components/Fields/FileListCombined.vue +142 -0
  30. package/field-components/Fields/FixedList.vue +372 -0
  31. package/field-components/Fields/Image.vue +328 -0
  32. package/field-components/Fields/ImageList.vue +285 -0
  33. package/field-components/Fields/ImageListCombined.vue +76 -0
  34. package/field-components/Fields/InputFieldList.vue +299 -0
  35. package/field-components/Fields/Labels.vue +182 -0
  36. package/field-components/Fields/MixedTable.vue +367 -0
  37. package/field-components/Fields/Number.vue +247 -0
  38. package/field-components/Fields/Password.vue +79 -0
  39. package/field-components/Fields/Permission.vue +83 -0
  40. package/field-components/Fields/PermissionEditor.vue +205 -0
  41. package/field-components/Fields/QueryFilters.vue +162 -0
  42. package/field-components/Fields/RadioList.vue +81 -0
  43. package/field-components/Fields/Rich.vue +369 -0
  44. package/field-components/Fields/Search.vue +499 -0
  45. package/field-components/Fields/Select.vue +376 -0
  46. package/field-components/Fields/SelectionChain.vue +198 -0
  47. package/field-components/Fields/Separator.vue +26 -0
  48. package/field-components/Fields/SingleList.vue +125 -0
  49. package/field-components/Fields/Static.vue +22 -0
  50. package/field-components/Fields/String.vue +185 -0
  51. package/field-components/Fields/Text.vue +89 -0
  52. package/field-components/Fields/Time.vue +160 -0
  53. package/field-components/Fields/TimeRange.vue +348 -0
  54. package/field-components/Fields/UltimateFile.vue +100 -0
  55. package/field-components/Fields/Year.vue +124 -0
  56. package/field-components/Fields/YearRange.vue +188 -0
  57. package/field-components/Fields/components/FieldTypeOptions.vue +248 -0
  58. package/field-components/Fields/index.js +117 -0
  59. package/field-components/components/FieldComponents.vue +246 -0
  60. package/field-components/index.js +13 -0
  61. package/field-components/style.sass +11 -0
  62. package/free-fields/AutoHide.js +66 -0
  63. package/free-fields/CenterContent.js +15 -0
  64. package/free-fields/Draggable.js +30 -0
  65. package/free-fields/Droppable.js +114 -0
  66. package/free-fields/EditableString.js +63 -0
  67. package/free-fields/FieldCategory.js +83 -0
  68. package/free-fields/FieldTypeSelect.js +94 -0
  69. package/free-fields/fieldEditors/arrayEditor.js +3 -0
  70. package/free-fields/fieldEditors/boolEditor.js +22 -0
  71. package/free-fields/fieldEditors/dateEditor.js +23 -0
  72. package/free-fields/fieldEditors/datetimeEditor.js +23 -0
  73. package/free-fields/fieldEditors/index.js +21 -0
  74. package/free-fields/fieldEditors/jsonEditor.js +371 -0
  75. package/free-fields/fieldEditors/labeledField.js +74 -0
  76. package/free-fields/fieldEditors/numberEditor.js +51 -0
  77. package/free-fields/fieldEditors/objectEditor.js +3 -0
  78. package/free-fields/fieldEditors/selectEditor.js +0 -0
  79. package/free-fields/fieldEditors/stringEditor.js +49 -0
  80. package/free-fields/fieldEditors/textEditor.js +50 -0
  81. package/free-fields/fieldEditors/timeEditor.js +23 -0
  82. package/free-fields/index.js +402 -0
  83. package/i18n/en-us/index.js +73 -0
  84. package/i18n/fields/en-us/index.js +9 -0
  85. package/i18n/fields/zh-cn/index.js +9 -0
  86. package/i18n/zh-cn/index.js +73 -0
  87. package/index.js +367 -0
  88. package/package.json +11 -0
  89. package/router/dict/api.js +18 -0
  90. package/router/dict/data.js +48 -0
  91. package/router/dict/index.js +7 -0
  92. package/router/error/api.js +14 -0
  93. package/router/error/data.js +33 -0
  94. package/router/error/index.js +9 -0
  95. package/router/index.js +13 -0
  96. package/router/menu/api.js +24 -0
  97. package/router/menu/data.js +85 -0
  98. package/router/menu/index.js +7 -0
  99. package/router/system/api.js +10 -0
  100. package/router/system/data.js +46 -0
  101. package/router/system/index.js +7 -0
  102. package/stores/index.js +17 -0
  103. package/stores/module-mourning/actions.js +3 -0
  104. package/stores/module-mourning/getters.js +1 -0
  105. package/stores/module-mourning/index.js +11 -0
  106. package/stores/module-mourning/state.js +3 -0
  107. package/stores/mourning.js +3 -0
  108. package/view/dict/index.vue +284 -0
  109. package/view/error/list.vue +197 -0
  110. package/view/menu/index.vue +332 -0
  111. package/view/mourning/mourning.vue +45 -0
  112. package/view/system/index.vue +149 -0
@@ -0,0 +1,348 @@
1
+ <template>
2
+ <span class="simple-field input-field-time-range row items-center no-wrap">
3
+ <span v-if="Field.ReadOnly">
4
+ <span
5
+ :class="`field-label field-label-readonly ${(Field.Label && Field.Label.trim().length)
6
+ ? '' : 'field-label-empty'} ${Field.Required ? 'required' : ''}`"
7
+ v-if="typeof Field.Label !== 'undefined'"
8
+ >
9
+ <q-tooltip v-if="Field.Description" anchor="top right">{{Field.Description}}</q-tooltip>
10
+ {{Field.Label || ''}}
11
+ <span v-if="Field.Required" class="required-mark">*</span>
12
+ </span>
13
+ <span class="readonly-content">{{fieldData}}</span>
14
+ </span>
15
+ <span v-else class="row items-center no-wrap">
16
+ <span v-if="typeof Field.Label !== 'undefined'" class="q-field__before">
17
+ <span
18
+ :class="`field-label ${(Field.Label && Field.Label.trim().length)
19
+ ? '' : 'field-label-empty'} ${Field.Required ? 'required' : ''}`"
20
+ >
21
+ <q-tooltip v-if="Field.Description" anchor="top right">{{Field.Description}}</q-tooltip>
22
+ {{Field.Label || ''}}
23
+ <span v-if="Field.Required" class="required-mark">*</span>
24
+ </span>
25
+ </span>
26
+ <q-input
27
+ v-model="min"
28
+ v-bind="$attrs"
29
+ hide-bottom-space
30
+ :readonly="Field.ReadOnly"
31
+ :ref="`input_field_validator_first`"
32
+ >
33
+ <q-popup-proxy
34
+ v-if="!Field.ReadOnly"
35
+ ref="qDateProxy1"
36
+ transition-show="scale"
37
+ transition-hide="scale"
38
+ >
39
+ <span class="row" style="min-width: 580px;">
40
+ <q-date
41
+ v-model="min"
42
+ :options="minDateOptions"
43
+ mask="YYYY-MM-DD HH:mm"
44
+ :locale="locale"
45
+ />
46
+ <q-time
47
+ v-model="min"
48
+ mask="YYYY-MM-DD HH:mm"
49
+ :hour-options="minHourOptions"
50
+ :minute-options="minMinuteOptions"
51
+ :options="timeOptions"
52
+ format24h />
53
+ </span>
54
+ </q-popup-proxy>
55
+ <template v-slot:append>
56
+ <q-icon name="event" class="cursor-pointer"></q-icon>
57
+ </template>
58
+ </q-input>
59
+
60
+ <span class="input-field-range-separator">{{`${Field.Separator || '~'}`}}</span>
61
+
62
+ <q-input
63
+ v-model="max"
64
+ v-bind="$attrs"
65
+ hide-bottom-space
66
+ :readonly="Field.ReadOnly"
67
+ :ref="`input_field_validator_second`"
68
+ >
69
+ <q-popup-proxy
70
+ v-if="!Field.ReadOnly"
71
+ ref="qDateProxy1"
72
+ transition-show="scale"
73
+ transition-hide="scale"
74
+ >
75
+ <span class="row" style="min-width: 580px;">
76
+ <q-date
77
+ v-model="max"
78
+ :options="maxDateOptions"
79
+ mask="YYYY-MM-DD HH:mm"
80
+ :locale="locale"
81
+ />
82
+ <q-time
83
+ v-model="max"
84
+ mask="YYYY-MM-DD HH:mm"
85
+ :hour-options="maxHourOptions"
86
+ :minute-options="maxMinuteOptions"
87
+ :options="timeOptions"
88
+ format24h />
89
+ </span>
90
+ </q-popup-proxy>
91
+ <template v-slot:append>
92
+ <q-icon name="event" class="cursor-pointer"></q-icon>
93
+ </template>
94
+ </q-input>
95
+ </span>
96
+ <slot name="warning"></slot>
97
+ </span>
98
+ </template>
99
+
100
+ <script>
101
+ import { defineComponent } from 'vue';
102
+ import mixins from 'free-fe-mixins';
103
+
104
+ export default defineComponent({
105
+ name: 'InputFieldTimeRange',
106
+ mixins: [mixins.InputFieldMixin],
107
+ emits:['input'],
108
+ fieldInfo: {
109
+ Category: 'DateTime',
110
+ Label: '时间范围',
111
+ Value: 'TimeRange',
112
+ Extra: [
113
+ {
114
+ Type: 'String',
115
+ Label: '最小值',
116
+ Name: 'MinValue',
117
+ },
118
+ {
119
+ Type: 'String',
120
+ Label: '最大值',
121
+ Name: 'MaxValue',
122
+ },
123
+ {
124
+ Type: 'Boolean',
125
+ Label: '最大至“现在”',
126
+ Name: 'Info.TillNow',
127
+ },
128
+ {
129
+ Type: 'Boolean',
130
+ Label: '最小从“现在”',
131
+ Name: 'Info.FromNow',
132
+ },
133
+ {
134
+ Type: 'Select',
135
+ Label: '小时可选',
136
+ Name: 'Options.hour',
137
+ Placeholder: '请选择',
138
+ Multiple: true,
139
+ Options: new Array(25).fill('').map((item, index) => ({
140
+ Label: `${index}`,
141
+ Value: index,
142
+ })),
143
+ },
144
+ {
145
+ Type: 'Select',
146
+ Label: '分钟可选',
147
+ Name: 'Options.minute',
148
+ Placeholder: '请选择',
149
+ Multiple: true,
150
+ Options: new Array(61).fill('').map((item, index) => ({
151
+ Label: `${index}`,
152
+ Value: index,
153
+ })),
154
+ },
155
+ ],
156
+ Description: '',
157
+ },
158
+ data() {
159
+ return {
160
+ min: '',
161
+ max: '',
162
+ };
163
+ },
164
+ watch: {
165
+ fieldData() {
166
+ const yl = (this.fieldData || '').split(this.Field.Separator || '~');
167
+ this.min = yl[0] && yl[0].trim();
168
+ this.max = yl[1] && yl[1].trim();
169
+ },
170
+ min() {
171
+ this.fieldData = [this.min, this.max].join(this.Field.Separator || '~');
172
+ this.$emit('input');
173
+ },
174
+ max() {
175
+ this.fieldData = [this.min, this.max].join(this.Field.Separator || '~');
176
+ this.$emit('input');
177
+ },
178
+ },
179
+ computed: {
180
+ locale() {
181
+ return this.ctx.config.locales.find(
182
+ (l) => l.locale === (this.ctx.config.locale || this.ctx.config.defaultLocale),
183
+ ).calendar;
184
+ },
185
+ minDateOptions() {
186
+ let minDate = '1900/01/01';
187
+ let maxDate = '2050/12/31';
188
+
189
+ if (this.Field.MinValue) {
190
+ minDate = this.Field.MinValue.replace(/-/g, '/');
191
+ [minDate] = minDate.split(' ');
192
+ }
193
+
194
+ if (this.Field.TillNow) {
195
+ maxDate = new Date().toLocaleDateString();
196
+ } else if (this.Field.MaxValue) {
197
+ maxDate = this.Field.MaxValue.replace(/-/g, '/');
198
+ [maxDate] = maxDate.split(' ');
199
+ }
200
+
201
+ if (this.max && this.max.replace(/-/g, '/') < maxDate) {
202
+ return (date) => date >= minDate && date <= this.max.replace(/-/g, '/').split(' ')[0];
203
+ }
204
+
205
+ return (date) => date >= minDate && date <= maxDate;
206
+ },
207
+ maxDateOptions() {
208
+ let minDate = '1900/01/01';
209
+ let maxDate = '2050/12/31';
210
+
211
+ if (this.Field.MinValue) {
212
+ minDate = this.Field.MinValue.replace(/-/g, '/');
213
+ [minDate] = minDate.split(' ');
214
+ }
215
+
216
+ if (this.Field.TillNow) {
217
+ maxDate = new Date().toLocaleDateString();
218
+ } else if (this.Field.MaxValue) {
219
+ maxDate = this.Field.MaxValue.replace(/-/g, '/');
220
+ [maxDate] = maxDate.split(' ');
221
+ }
222
+
223
+ if (this.min && this.min.replace(/-/g, '/') > minDate) {
224
+ return (date) => date >= this.min.replace(/-/g, '/').split(' ')[0] && date <= maxDate;
225
+ }
226
+
227
+ return (date) => date >= minDate && date <= maxDate;
228
+ },
229
+ minTimeLimit() {
230
+ if (this.min && this.Field.MinValue) {
231
+ try {
232
+ const dSplit = this.Field.MinValue.split(' ');
233
+ const mD = dSplit[0];
234
+
235
+ if (this.min.split(' ')[0] <= mD) {
236
+ const [mH, mM] = dSplit[1].split(':');
237
+
238
+ if (mH && mM) {
239
+ return {
240
+ hour: (t) => t >= Number(mH),
241
+ minute: (t) => t >= 0, // Number(mM),
242
+ };
243
+ }
244
+ }
245
+ } catch {
246
+ //
247
+ }
248
+ }
249
+
250
+ return {
251
+ hour: (t) => t >= 0,
252
+ minute: (t) => t >= 0,
253
+ };
254
+ },
255
+ maxTimeLimit() {
256
+ if (this.max && this.Field.MaxValue) {
257
+ try {
258
+ const dSplit = this.Field.MaxValue.split(' ');
259
+ const mD = dSplit[0];
260
+
261
+ if (this.max.split(' ')[0] >= mD) {
262
+ const [mH, mM] = dSplit[1].split(':');
263
+
264
+ if (mH && mM) {
265
+ return {
266
+ hour: (t) => t <= Number(mH),
267
+ minute: (t) => t >= 0, // <= Number(mM),
268
+ };
269
+ }
270
+ }
271
+ } catch {
272
+ //
273
+ }
274
+ }
275
+
276
+ return {
277
+ hour: (t) => t >= 0,
278
+ minute: (t) => t >= 0,
279
+ };
280
+ },
281
+ minHourOptions() {
282
+ return this.objOptions
283
+ ? (this.objOptions.hour || []).filter(this.minTimeLimit.hour) : undefined;
284
+ },
285
+ minMinuteOptions() {
286
+ return this.objOptions
287
+ ? (this.objOptions.minute || []).filter(this.minTimeLimit.minute) : undefined;
288
+ },
289
+ maxHourOptions() {
290
+ return this.objOptions
291
+ ? (this.objOptions.hour || []).filter(this.maxTimeLimit.hour) : undefined;
292
+ },
293
+ maxMinuteOptions() {
294
+ return this.objOptions
295
+ ? (this.objOptions.minute || []).filter(this.maxTimeLimit.minute) : undefined;
296
+ },
297
+ objOptions() {
298
+ if (this.Field.Options) {
299
+ return this.Field.Options;
300
+ }
301
+ return undefined;
302
+ },
303
+ timeOptions() {
304
+ if (this.objOptions) return undefined;
305
+
306
+ if (!this.Field.MinValue && !this.Field.MaxValue) {
307
+ return undefined;
308
+ }
309
+
310
+ let minH;
311
+ let minM;
312
+ let minS;
313
+
314
+ if (this.Field.MinValue) {
315
+ [minH, minM, minS] = this.Field.MinValue;
316
+ }
317
+
318
+ let maxH;
319
+ let maxM;
320
+ let maxS;
321
+ if (this.Field.MaxValue) {
322
+ [maxH, maxM, maxS] = this.Field.MaxValue;
323
+ }
324
+
325
+ minH = minH || 0;
326
+ minM = minM || 0;
327
+ minS = minS || 0;
328
+
329
+ maxH = maxH || 24;
330
+ maxM = maxM || 60;
331
+ maxS = maxS || 60;
332
+
333
+ return (hr, min, sec) => {
334
+ if (hr < minH || hr > maxH) {
335
+ return false;
336
+ }
337
+ if (min < minM || min > maxM) {
338
+ return false;
339
+ }
340
+ if (sec < minS || sec > maxS) {
341
+ return false;
342
+ }
343
+ return true;
344
+ };
345
+ },
346
+ },
347
+ });
348
+ </script>
@@ -0,0 +1,100 @@
1
+ <template>
2
+ <div class="row input-field-file-list combined input-field--readonly">
3
+ <span
4
+ :class="`field-label ${(Field.Label && Field.Label.trim().length)
5
+ ? '' : 'field-label-empty'} ${Field.Required ? 'required' : ''}`"
6
+ v-if="typeof Field.Label !== 'undefined'">
7
+ <q-tooltip v-if="Field.Description" anchor="top right">{{Field.Description}}</q-tooltip>
8
+ {{Field.Label || ''}}
9
+ </span>
10
+ <q-uploader
11
+ multiple
12
+ :class="`q-ma-xs`"
13
+ ref="uploader"
14
+ >
15
+ <template v-slot:list="scope">
16
+ <div v-if="scope.files.length && Field.AsList"
17
+ class="file-list file-list-list">
18
+ <q-list>
19
+ <q-item
20
+ class="file-list-item"
21
+ v-for="(file, index) in scope.files" :key="index">
22
+ <span class="file-name full-width ellipsis">
23
+ {{ file.name }}
24
+ <q-tooltip>{{ file.name }}</q-tooltip>
25
+ </span>
26
+
27
+ <span class="file-size full-width ellipsis">
28
+ Size: {{ file.sizeLabel || file.__sizeLabel }}
29
+ </span>
30
+ </q-item>
31
+ </q-list>
32
+ </div>
33
+
34
+ <div v-if="scope.files.length && !Field.AsList"
35
+ class="file-list file-list-card row items-start justify-start q-gutter-xl">
36
+ <q-card
37
+ flat
38
+ class="file-list-item"
39
+ v-for="(file, index) in scope.files" :key="index">
40
+ <q-img class="file-image" :src="fileThumb(file)">
41
+ <div class="view-btn-wrapper absolute-full justify-center text-center">
42
+ <q-btn
43
+ flat
44
+ class="view-btn full-height full-width"
45
+ @click="preview(file)"
46
+ >查看</q-btn>
47
+ </div>
48
+ </q-img>
49
+ <span class="file-name full-width ellipsis">
50
+ {{ file.name }}
51
+ <q-tooltip>{{ file.name }}</q-tooltip>
52
+ </span>
53
+
54
+ <span class="file-size full-width ellipsis">
55
+ Size: {{ file.sizeLabel || file.__sizeLabel }}
56
+ </span>
57
+ </q-card>
58
+ </div>
59
+ </template>
60
+ </q-uploader>
61
+ <q-dialog class="image-preview-dialog"
62
+ flat
63
+ full-width full-height v-model="showPreview"
64
+ style="background: rgba(0,0,0,0)">
65
+ <div class="image-preview">
66
+ <q-img contain :src="previewFile"
67
+ @click="showPreview=false"
68
+ style="height: 100%; max-width: 100%;"></q-img>
69
+ </div>
70
+ </q-dialog>
71
+ </div>
72
+ </template>
73
+
74
+ <script>
75
+ import { defineComponent } from 'vue';
76
+ import mixnins from 'free-fe-mixins';
77
+
78
+ export default defineComponent({
79
+ name: 'InputFieldUltimateFile',
80
+ mixins: [mixnins.UploaderMixin, mixnins.InputFieldMixin],
81
+ fieldInfo: {
82
+ Category: 'Upload',
83
+ Label: '上传文件',
84
+ Value: 'UltimateFile',
85
+ Description: '',
86
+ },
87
+ watch: {
88
+ fieldData() {
89
+ if (this.fieldData) {
90
+ this.$refs.uploader.files = this.fieldData;
91
+ }
92
+ },
93
+ },
94
+ });
95
+ </script>
96
+
97
+ <style lang="sass">
98
+ .q-uploader__header
99
+ display: none
100
+ </style>
@@ -0,0 +1,124 @@
1
+ <template>
2
+ <span class="input-field-year simple-field row items-center no-wrap">
3
+ <q-select
4
+ v-model="fieldData"
5
+ hide-bottom-space
6
+ :options="yearOptions"
7
+ :readonly="Field.ReadOnly"
8
+ @input="$emit('input')"
9
+ :ref="`input_field_validator_${Field.Name || Field.Label}`"
10
+ map-options
11
+ :label="Field.Placeholder"
12
+ emit-value
13
+ v-bind="$attrs"
14
+ >
15
+ <template v-slot:before v-if="typeof Field.Label !== 'undefined'">
16
+ <span
17
+ :class="`field-label ${(Field.Label && Field.Label.trim().length)
18
+ ? '' : 'field-label-empty'} ${Field.Required ? 'required' : ''}`">
19
+ <q-tooltip v-if="Field.Description" anchor="top right">{{Field.Description}}</q-tooltip>
20
+ {{Field.Label || ''}}
21
+ <span v-if="Field.Required" class="required-mark">*</span>
22
+ </span>
23
+ </template>
24
+ </q-select>
25
+ <slot name="warning"></slot>
26
+ </span>
27
+ </template>
28
+
29
+ <script>
30
+ import { defineComponent } from 'vue';
31
+ import mixins from 'free-fe-mixins';
32
+
33
+ export default defineComponent({
34
+ name: 'InputFieldYear',
35
+ mixins: [mixins.InputFieldMixin],
36
+ fieldInfo: {
37
+ Category: 'DateTime',
38
+ Label: '年份',
39
+ Value: 'Year',
40
+ Extra: [
41
+ {
42
+ Type: 'String',
43
+ Label: '最小值',
44
+ Name: 'MinValue',
45
+ },
46
+ {
47
+ Type: 'String',
48
+ Label: '最大值',
49
+ Name: 'MaxValue',
50
+ },
51
+ {
52
+ Type: 'Boolean',
53
+ Label: '最大至“现在”',
54
+ Name: 'Info.TillNow',
55
+ },
56
+ {
57
+ Type: 'Boolean',
58
+ Label: '最小从“现在”',
59
+ Name: 'Info.FromNow',
60
+ },
61
+ {
62
+ Type: 'DynamicList',
63
+ Label: '选项',
64
+ Name: 'Options',
65
+ Options: {
66
+ Columns: [
67
+ {
68
+ Label: 'Year',
69
+ Name: 'Value',
70
+ },
71
+ {
72
+ Label: 'Extra',
73
+ Name: 'Extra',
74
+ Type: 'FieldList',
75
+ Options: {
76
+ Columns: [
77
+ {
78
+ Label: '#',
79
+ Name: 'Index',
80
+ },
81
+ {
82
+ Label: '名称',
83
+ Name: 'Name',
84
+ },
85
+ {
86
+ Label: '标题',
87
+ Name: 'Label',
88
+ },
89
+ ],
90
+ },
91
+ },
92
+ ],
93
+ },
94
+ },
95
+ ],
96
+ Description: '',
97
+ },
98
+ computed: {
99
+ yearOptions() {
100
+ if (this.Field.Type !== 'Year') return [];
101
+
102
+ if (this.Field.Options && Array.isArray(this.Field.Options)) {
103
+ return this.Field.Options;
104
+ }
105
+
106
+ let minYear = 1900;
107
+ let maxYear = Date.now().year;
108
+
109
+ if (this.Field.MinValue && Number(this.Field.MinValue)) {
110
+ minYear = Number(this.Field.MinValue);
111
+ }
112
+ if (this.Field.MaxValue && Number(this.Field.MaxValue)) {
113
+ maxYear = Number(this.Field.MaxValue);
114
+ }
115
+
116
+ const options = [];
117
+ for (let i = minYear; i <= maxYear; i += 1) {
118
+ options.push(i);
119
+ }
120
+ return options;
121
+ },
122
+ },
123
+ });
124
+ </script>