@neatui/vue 3.0.0 → 4.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 (53) hide show
  1. package/README.md +1 -10
  2. package/package.json +5 -2
  3. package/rollup.config.js +42 -2
  4. package/src/components/basic/IDraggable@b.vue +1 -1
  5. package/src/components/basic/IFollowView.vue +2 -2
  6. package/src/components/basic/IScrollView.vue +441 -45
  7. package/src/components/basic/LayerView/Layer.vue +193 -42
  8. package/src/components/display/Calendar.vue +6 -6
  9. package/src/components/display/CalendarReg.vue +6 -6
  10. package/src/components/display/PhotoEditor.vue +2 -2
  11. package/src/components/display/TreeView.vue +4 -3
  12. package/src/components/form/Cascader.vue +3 -3
  13. package/src/components/form/DatePicker.vue +2 -2
  14. package/src/components/form/{DateRangePicker@v3.vue → DateRangePicker.vue} +2 -1
  15. package/src/components/form/{DateRangeView@v3.vue → DateRangeView.vue} +11 -11
  16. package/src/components/form/DateView.vue +461 -82
  17. package/src/components/form/ImgUpload.vue +3 -3
  18. package/src/components/form/{MoreSelect@v3.vue → MoreSelect.vue} +1 -1
  19. package/src/components/form/MoreSelectList.vue +1 -1
  20. package/src/components/form/{MoreSelectPanel@v3.vue → MoreSelectPanel.vue} +1 -1
  21. package/src/components/form/MoreSelectPicker.vue +3 -3
  22. package/src/components/form/MoreSelectTags.vue +1 -1
  23. package/src/components/form/PageMoreSelect.vue +1 -1
  24. package/src/components/form/PageSelect.vue +1 -1
  25. package/src/components/form/SearchMoreSelect.vue +1 -1
  26. package/src/components/form/{SearchSelect@v3.vue → SearchSelect.vue} +1 -1
  27. package/src/components/form/{Select@v3.vue → Select.vue} +1 -1
  28. package/src/components/form/SelectList.vue +1 -1
  29. package/src/components/form/SelectPicker.vue +3 -3
  30. package/src/components/form/SelectTree/{SelectTree@v1.vue → SelectTree.vue} +1 -1
  31. package/src/components/form/Switch.vue +2 -1
  32. package/src/components/form/TimeView.vue +6 -6
  33. package/src/components/form/Upload.vue +22 -11
  34. package/src/components/form/index.ts +8 -8
  35. package/src/components/loader/FormLoader/FormLoader.vue +124 -103
  36. package/src/components/loader/LayerLoader/LayerLoader.vue +6 -7
  37. package/src/components/loader/LimitLoader/{LimitLoader@v3.vue → LimitLoader.vue} +4 -4
  38. package/src/components/loader/LimitLoader/index.ts +1 -1
  39. package/src/components/loader/TableLoader/TableLoader.vue +7 -7
  40. package/src/components/loader/TableLoader/TableRender.vue +0 -1
  41. package/src/components/loader/ViewLoader/{ViewLoader@v1.vue → ViewLoader.vue} +124 -103
  42. package/src/components/loader/ViewLoader/index.ts +1 -1
  43. package/src/components/tools/FormDraftsView.vue +4 -4
  44. package/src/components/tools/FormVerifyView.vue +2 -2
  45. package/src/components/tools/MoreTools.vue +5 -5
  46. package/src/components/tools/Pagination@a.vue +4 -4
  47. package/src/components/tools/Pagination@b.vue +4 -4
  48. package/tsconfig.json +1 -2
  49. package/src/components/form/DateView@v2.vue +0 -386
  50. package/src/components/form/DateView@v3.vue +0 -608
  51. package/src/components/tools/MoreTools@v2.vue +0 -74
  52. /package/src/components/form/{Input@v3.vue → Input.vue} +0 -0
  53. /package/src/components/form/{TextArea.vue → Textarea.vue} +0 -0
@@ -1,608 +0,0 @@
1
- <template>
2
- <div ui-date="@a" class="fekit-date-view pr" :class="`${frame ? 'b-solid bk-line b-xs r-sm' : ''}`" ui-flex="col xy" style="width: 22em">
3
- <div ui-date-head="" class="flex-fixed nx-ms mt-ss ny-sm b-solid bk-line" ui-flex="row xm">
4
- <div ui-flex="row lm" class="o-lm">
5
- <div ui-btn="@a s none :square" @click="prev()">
6
- <Icon name="arrow-left" />
7
- </div>
8
- </div>
9
- <div ui-btns="@a none s" @click="setPanelType()">
10
- <p v-if="state.type === 2" class="nowrap" ui-flex="row cm">
11
- <b class="nx-ss">{{ panel.sta }}年</b>
12
- <span class="nx-xs">-</span>
13
- <b class="nx-ss">{{ panel.end }}年</b>
14
- </p>
15
- <p v-else-if="state.type === 1" class="nowrap" ui-flex="row cm">
16
- <b class="nx-ss">{{ state.curr.y }}年</b>
17
- </p>
18
- <p v-else class="nowrap" ui-flex="row cm">
19
- <b class="nx-xs">{{ state.curr.y }}年</b>
20
- <b class="nx-xs">{{ state.curr.M }}月</b>
21
- </p>
22
- </div>
23
- <div ui-flex="row rm" class="o-lm">
24
- <div ui-btn="@a s none :square" @click="next()">
25
- <Icon name="arrow-right" />
26
- </div>
27
- </div>
28
- </div>
29
- <div ui-date-body="" :class="['flex-block pr', bodyClass]">
30
- <div v-if="state.type === 2" class="full">
31
- <ul ui-grid="mob:4" class="n-ms ny-sm-sub">
32
- <li v-for="(year, idx) in panel.years" :key="idx" ui-flex="col cm" @click="setDateValue('y', year)">
33
- <div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedYear(year) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">
34
- {{ year }}
35
- </div>
36
- </li>
37
- </ul>
38
- </div>
39
- <div v-else-if="state.type === 1" class="full">
40
- <ul ui-grid="mob:4" class="n-ms ny-sm-sub">
41
- <li ui-flex="col cm" @click="setDateValue('m', 1)">
42
- <div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(1) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">1月</div>
43
- </li>
44
- <li ui-flex="col cm" @click="setDateValue('m', 2)">
45
- <div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(2) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">2月</div>
46
- </li>
47
- <li ui-flex="col cm" @click="setDateValue('m', 3)">
48
- <div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(3) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">3月</div>
49
- </li>
50
- <li ui-flex="col cm" @click="setDateValue('m', 4)">
51
- <div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(4) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">4月</div>
52
- </li>
53
- <li ui-flex="col cm" @click="setDateValue('m', 5)">
54
- <div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(5) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">5月</div>
55
- </li>
56
- <li ui-flex="col cm" @click="setDateValue('m', 6)">
57
- <div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(6) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">6月</div>
58
- </li>
59
- <li ui-flex="col cm" @click="setDateValue('m', 7)">
60
- <div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(7) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">7月</div>
61
- </li>
62
- <li ui-flex="col cm" @click="setDateValue('m', 8)">
63
- <div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(8) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">8月</div>
64
- </li>
65
- <li ui-flex="col cm" @click="setDateValue('m', 9)">
66
- <div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(9) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">9月</div>
67
- </li>
68
- <li ui-flex="col cm" @click="setDateValue('m', 10)">
69
- <div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(10) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">10月</div>
70
- </li>
71
- <li ui-flex="col cm" @click="setDateValue('m', 11)">
72
- <div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(11) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">11月</div>
73
- </li>
74
- <li ui-flex="col cm" @click="setDateValue('m', 12)">
75
- <div ui-flex="col cm" class="w-ss h-xs ac ux-none r-sm" :class="isSelectedMonth(12) ? 'active bg-main-o-lm co-w' : 'co-main:hover'">12月</div>
76
- </li>
77
- </ul>
78
- </div>
79
- <div v-else class="full">
80
- <ul ui-flex="row am" class="fs-xs nx-sm nt-ss">
81
- <li class="flex-block ac"><span>日</span></li>
82
- <li class="flex-block ac"><span>一</span></li>
83
- <li class="flex-block ac"><span>二</span></li>
84
- <li class="flex-block ac"><span>三</span></li>
85
- <li class="flex-block ac"><span>四</span></li>
86
- <li class="flex-block ac"><span>五</span></li>
87
- <li class="flex-block ac"><span>六</span></li>
88
- </ul>
89
- <ul ui-date-days="" ui-flex="col xm" class="flex-wrap nx-sm">
90
- <li v-for="(week, idx) in state.curr.days" :key="idx" :ui-date-week="idx + 1" class="flex-block" ui-flex="row am" style="margin-bottom: -0.25em">
91
- <div v-for="(item, i) in week" :key="i" class="pr flex-block nb-sm" ui-flex="col xy">
92
- <div
93
- v-if="item.day"
94
- :ui-date-day="item.day"
95
- class="flex-block"
96
- :class="`${item.range ? 'bg-main-o-xs' : ''} ${item.sta ? 'r-lt-sl r-lb-sl' : ''} ${item.end ? 'r-rt-sl r-rb-sl' : ''}`"
97
- ui-flex="col cm"
98
- @click="change(item)"
99
- >
100
- <div
101
- ui-flex="col cm"
102
- class="r-sm b-solid bk-none b-xs my-ss ux-scale"
103
- style="width: 1.8em; height: 1.8em"
104
- :class="`${item.isLastMonth || item.isNextMonth ? 'co-idle' : item.isHoliday ? 'co-risk' : ''} ${item.selected ? 'active bg-main-o-lm co-w' : 'bg-weak:hover co-main:hover'}`"
105
- >
106
- <span>{{ item.day }}</span>
107
- </div>
108
- </div>
109
- <div class="pa w-full lh-xs ny-ss ob-no ol-no nowrap s-ml bold" style="transform-origin: 50% 100%" ui-flex="row ct" v-html="extras(item)"></div>
110
- </div>
111
- </li>
112
- </ul>
113
- </div>
114
- </div>
115
- <template v-if="!state.isNoTime">
116
- <div v-if="state.type === 0" class="h-ss ny-sm nx-ms">
117
- <div class="full ac b-solid bk-line b-xs r-sm" ui-row="mob-8" style="width: 100%; height: 3em; padding: 0.5em">
118
- <ul
119
- :style="`${state.panel ? '' : 'pointer-events: none; opacity:.35'}`"
120
- class="fekit-date-view-time-scroll"
121
- ref="ths"
122
- ui-scroll=":y xs"
123
- ui-btns="@a none s :block"
124
- data-type="h"
125
- @scroll="timeScroll"
126
- >
127
- <li v-for="(item, idx) in hours" :key="idx">
128
- {{ item }}
129
- </li>
130
- </ul>
131
- <ul
132
- :style="`${state.panel ? '' : 'pointer-events: none; opacity:.35'}`"
133
- class="fekit-date-view-time-scroll"
134
- ref="tms"
135
- ui-scroll=":y xs"
136
- ui-btns="@a none s :block"
137
- data-type="m"
138
- @scroll="timeScroll"
139
- >
140
- <li v-for="(item, idx) in seconds" :key="idx">
141
- {{ item }}
142
- </li>
143
- </ul>
144
- <ul
145
- :style="`${state.panel ? '' : 'pointer-events: none; opacity:.35'}`"
146
- class="fekit-date-view-time-scroll"
147
- ref="tss"
148
- ui-scroll=":y xs"
149
- ui-btns="@a none s :block"
150
- data-type="s"
151
- @scroll="timeScroll"
152
- >
153
- <li v-for="(item, idx) in seconds" :key="idx">
154
- {{ item }}
155
- </li>
156
- </ul>
157
- </div>
158
- </div>
159
- <div v-else class="h-ss"></div>
160
- </template>
161
- <div v-if="showTools" ui-date-foot="" ui-flex="row xm" class="flex-fixed nx-sl ny-sl b-solid bk-line bt-xs">
162
- <div ui-flex="row lm" class="nl-ss">
163
- <div v-if="state.panel" ui-flex="row lm">
164
- <span :anim-editing="state.type === baseType" class="nx-ss">{{ idate(state.panel).format(panelFormat) }}</span>
165
- <!-- <span v-if="!state.isNoTime" :anim-editing="state.type === baseType" class="nx-ss">{{ idate(state.panel).format('HH:mm:ss') }}</span> -->
166
- </div>
167
- <div v-else-if="state.shortcuts?.length" ui-flex="row lm">
168
- <div class="mr-sm-sub nx-sl-sub ny-ss-sub lh-ss nowrap fs-ss dib-sub" ui-scroll=":x y:hidden">
169
- <p v-for="(item, idx) in state.shortcuts" :key="idx" class="bg-main-o-ss co-main r-xl" ui-btn="@a xs none :round" @click="item?.func">{{ item?.text }}</p>
170
- <p class="bg-main-o-ss co-main r-xl" ui-btn="@a xs none :round"><Icon class="co-main" name="more" /></p>
171
- </div>
172
- </div>
173
- <div>&nbsp;</div>
174
- </div>
175
- <div class="ml-ss-sub" ui-flex="row rm">
176
- <button v-if="state.panel" ui-btn="@a xs none" class="nx-ss co-risk" @click="remove">清除</button>
177
- <button v-if="state.panel && !state.isNoTime" ui-btn="@a xs none" class="nx-ss co-main" @click="update">确定</button>
178
- </div>
179
- </div>
180
- </div>
181
- </template>
182
- <script setup lang="ts">
183
- import { computed, ref, reactive, watch, onMounted } from 'vue';
184
- import { idate, isDateString, isObject, isString } from '@fekit/utils';
185
- import { Icon } from '../basic';
186
-
187
- const normalizeDateInput = (value: any) => {
188
- if (!value) {
189
- return value;
190
- }
191
- if (isString(value)) {
192
- if (/^\d{4}$/.test(value)) {
193
- return `${value}-01-01`;
194
- }
195
- if (/^\d{4}-(\d{1,2})$/.test(value)) {
196
- const [year, month] = value.split('-');
197
- const m = month.padStart(2, '0');
198
- return `${year}-${m}-01`;
199
- }
200
- }
201
- return value;
202
- };
203
-
204
- interface PickerConfig {
205
- baseType: number;
206
- format: string;
207
- bodyClass: string;
208
- tools: boolean;
209
- }
210
-
211
- const PICKER_CONFIGS: Record<string, PickerConfig> = {
212
- date: { baseType: 0, format: 'YYYY-MM-DD', bodyClass: 'min-h-ls+', tools: true },
213
- month: { baseType: 1, format: 'YYYY-MM', bodyClass: 'min-h-ms', tools: false },
214
- year: { baseType: 2, format: 'YYYY', bodyClass: 'min-h-ms', tools: false },
215
- };
216
-
217
- // 创建日期
218
- const cDate = (date: any = null) => {
219
- const normalized = normalizeDateInput(date);
220
- // iOS 兼容:Safari 不支持 "YYYY-MM-DD" 格式,需要替换为 "YYYY/MM/DD"
221
- return isDateString(normalized) ? new Date(normalized?.replace(/-/g, '/')) : new Date();
222
- };
223
-
224
- // 快捷预设
225
- const shortcutsList: any = {
226
- yesterday: {
227
- text: '昨天',
228
- func() {
229
- change({ date: idate(new Date().setDate(new Date().getDate() - 1)).format('YYYY-MM-DD') });
230
- },
231
- },
232
- today: {
233
- text: '今天',
234
- func() {
235
- change({ date: idate(new Date()).format('YYYY-MM-DD') });
236
- },
237
- },
238
- tomorrow: {
239
- text: '明天',
240
- func() {
241
- change({ date: idate(new Date().setDate(new Date().getDate() + 1)).format('YYYY-MM-DD') });
242
- },
243
- },
244
- };
245
-
246
- const emits: any = defineEmits(['update:modelValue', 'change', 'update']);
247
- interface TimeProps {
248
- h: boolean | number;
249
- m?: boolean | number;
250
- s?: boolean | number;
251
- }
252
- interface Props {
253
- modelValue?: string | number;
254
- frame: boolean;
255
- tools?: boolean;
256
- range?: boolean;
257
- format?: string;
258
- picker?: 'date' | 'week' | 'month' | 'quarter' | 'year';
259
- holiday?: object;
260
- shortcuts?: Array<'yesterday' | 'today' | 'tomorrow'>;
261
- extras?: (item: any) => string;
262
- time?: boolean | TimeProps;
263
- lang?: string;
264
- }
265
- const props: any = withDefaults(defineProps<Props>(), {
266
- // 值
267
- modelValue: '',
268
- // 是否显示框架
269
- frame: false,
270
- // 是否是示工具
271
- tools: undefined,
272
- // 时间范围
273
- range: false,
274
- // 面板类型
275
- picker: 'date',
276
- // 额外内容
277
- extras: (item: any) => {
278
- return `<i class="dib o-ms mb-xs r-xl ${item.today ? 'bg-main' : 'bg-none'}" style="width:.5em; height:.5em;"></i>`;
279
- },
280
- // 快捷选择
281
- shortcuts: () => ['yesterday', 'today', 'tomorrow'],
282
- // 数据格式化
283
- format: undefined,
284
- // 节假日
285
- holiday: () => ({}),
286
- time: false,
287
- // 语言
288
- lang: 'zh-CN',
289
- });
290
-
291
- const pickerConfig = computed<PickerConfig>(() => {
292
- const key = props.picker || 'date';
293
- return PICKER_CONFIGS[key] || PICKER_CONFIGS.date;
294
- });
295
-
296
- // 小时
297
- const hours = computed(() => {
298
- const _hours: any = [];
299
- for (let i = 0; i < 24; i++) {
300
- _hours.push(i > 9 ? `${i}` : `0${i}`);
301
- }
302
- return _hours;
303
- });
304
- // 分秒
305
- const seconds = computed(() => {
306
- const _seconds: any = [];
307
- for (let i = 0; i < 60; i++) {
308
- _seconds.push(i > 9 ? `${i}` : `0${i}`);
309
- }
310
- return _seconds;
311
- });
312
-
313
- const baseType = computed(() => pickerConfig.value.baseType);
314
-
315
- const panelFormat = computed(() => props.format || pickerConfig.value.format);
316
-
317
- const bodyClass = computed(() => pickerConfig.value.bodyClass);
318
-
319
- const showTools = computed(() => {
320
- if (props.tools !== undefined) {
321
- return !!props.tools;
322
- }
323
- return pickerConfig.value.tools;
324
- });
325
-
326
- const isSelectedYear = (year: number) => {
327
- return !!state.panel && state.curr?.y === year;
328
- };
329
-
330
- const isSelectedMonth = (month: number) => {
331
- return !!state.panel && state.curr?.M === month;
332
- };
333
-
334
- // 内部数据
335
- const state: any = reactive({
336
- // 面板显示时间
337
- panel: undefined,
338
- // 面板年份选择
339
- years: 0,
340
- // 当前时间计算
341
- curr: computed(() => {
342
- const date = idate(state.panel);
343
- const days = date.calendar({ group: true, value: [state.panel] });
344
- return { days, ...date.attr };
345
- }),
346
- // 当前面板类型
347
- type: 0,
348
- // 值
349
- value: undefined,
350
- // 快捷选择
351
- shortcuts: computed(() => {
352
- return props.shortcuts.map((item: any) => {
353
- return isString(item) ? shortcutsList[item] : item;
354
- });
355
- }),
356
- // 不带时间(只要时或分的也考虑到)
357
- isNoTime: computed(() => {
358
- if (isObject(props.time)) {
359
- return !(props.time.h || props.time.m || props.time.s);
360
- } else {
361
- return !props.time;
362
- }
363
- }),
364
- });
365
-
366
- watch(
367
- () => baseType.value,
368
- (value) => {
369
- state.type = value;
370
- },
371
- { immediate: true },
372
- );
373
-
374
- watch(
375
- () => panelFormat.value,
376
- (format) => {
377
- if (state.panel) {
378
- const formatted = idate(state.panel).format(format);
379
- if (formatted !== state.panel) {
380
- state.panel = formatted;
381
- }
382
- state.value = formatted;
383
- }
384
- },
385
- { immediate: true },
386
- );
387
-
388
- // 面板
389
- const panel: any = reactive({
390
- years: computed(() => {
391
- const startYear = Math.floor(state.curr.year / 10) * 10;
392
- const list = [];
393
- for (let i = 0; i < 10; i++) {
394
- list.push(startYear + i);
395
- }
396
- return list;
397
- }),
398
- sta: computed(() => {
399
- return panel.years[0];
400
- }),
401
- end: computed(() => {
402
- return panel.years[9];
403
- }),
404
- });
405
-
406
- // 设置日期
407
- const setDateValue = (type: any, value: number = 0, add: number = 0) => {
408
- const panelValue = upload(type, value, add);
409
- state.panel = panelValue;
410
- state.value = panelValue;
411
- // 面板返回上一级
412
- const base = baseType.value;
413
- const nextType = Math.max(base, state.type - 1);
414
- state.type = nextType;
415
-
416
- if (base > 0 && nextType === base) {
417
- emits('change', panelValue);
418
- update();
419
- }
420
- };
421
-
422
- // 时分秒
423
- const ths: any = ref(null);
424
- const tms: any = ref(null);
425
- const tss: any = ref(null);
426
- const setTimeValue = () => {
427
- const { H = 0, m = 0, s = 0 }: any = state.curr || {};
428
- if (state.panel) {
429
- if (ths.value && ths.value.children[H]) {
430
- ths.value.scrollTop = ths.value.children[H].offsetTop;
431
- }
432
- if (tms.value && tms.value.children[m]) {
433
- tms.value.scrollTop = tms.value.children[m].offsetTop;
434
- }
435
- if (tss.value && tss.value.children[s]) {
436
- tss.value.scrollTop = tss.value.children[s].offsetTop;
437
- }
438
- } else {
439
- if (ths.value && ths.value.children[H]) {
440
- ths.value.scrollTop = ths.value.children[0].offsetTop;
441
- }
442
- if (tms.value && tms.value.children[m]) {
443
- tms.value.scrollTop = tms.value.children[0].offsetTop;
444
- }
445
- if (tss.value && tss.value.children[s]) {
446
- tss.value.scrollTop = tss.value.children[0].offsetTop;
447
- }
448
- }
449
- };
450
-
451
- watch(
452
- () => props.modelValue,
453
- (value: any) => {
454
- const formatted = value ? idate(value).format(panelFormat.value) : undefined;
455
- // 面板显示日期
456
- state.panel = formatted;
457
- // 值
458
- state.value = formatted;
459
- },
460
- { deep: true, immediate: true },
461
- );
462
-
463
- onMounted(() => {
464
- setTimeValue();
465
- });
466
- watch(
467
- () => state.panel,
468
- () => {
469
- setTimeValue();
470
- },
471
- );
472
-
473
- // 更新时间
474
- const upload = (type: string = 'm', value: number = 0, add: number = 1) => {
475
- const date = cDate(state.panel);
476
-
477
- switch (type) {
478
- case 'y':
479
- if (value !== 0) {
480
- date.setFullYear(value);
481
- } else {
482
- date.setFullYear(date.getFullYear() + add);
483
- }
484
- break;
485
- case 'm':
486
- if (value !== 0) {
487
- date.setMonth(value - 1);
488
- } else {
489
- date.setMonth(date.getMonth() + add);
490
- }
491
- break;
492
- case 'd':
493
- if (value !== 0) {
494
- date.setDate(value);
495
- } else {
496
- date.setDate(date.getDate() + add);
497
- }
498
- break;
499
- case 'h':
500
- if (value !== 0) {
501
- date.setHours(value);
502
- } else {
503
- date.setHours(date.getHours() + add);
504
- }
505
- break;
506
- case 'n':
507
- if (value !== 0) {
508
- date.setMinutes(value);
509
- } else {
510
- date.setMinutes(date.getMinutes() + add);
511
- }
512
- break;
513
- case 's':
514
- if (value !== 0) {
515
- date.setSeconds(value);
516
- } else {
517
- date.setSeconds(date.getSeconds() + add);
518
- }
519
- break;
520
- default:
521
- break;
522
- }
523
- return idate(date).format(panelFormat.value);
524
- };
525
-
526
- // 日期前翻
527
- const prev = () => {
528
- state.panel = upload(state.type > 0 ? 'y' : 'm', 0, state.type === 2 ? -10 : -1);
529
- };
530
- // 日期后翻
531
- const next = () => {
532
- state.panel = upload(state.type > 0 ? 'y' : 'm', 0, state.type === 2 ? 10 : 1);
533
- };
534
-
535
- // 向外通信
536
- const change = (item: any) => {
537
- const panelValue = item ? idate(item.date).format(panelFormat.value) : item;
538
- state.panel = panelValue;
539
- state.value = panelValue;
540
- emits('change', panelValue);
541
- if (state.isNoTime) {
542
- update();
543
- }
544
- };
545
-
546
- // 清空日期
547
- const remove = () => {
548
- state.panel = undefined;
549
- state.value = undefined;
550
- update();
551
- };
552
-
553
- // 更新数据
554
- const update = () => {
555
- const nextValue = state.panel ? idate(state.panel).format(panelFormat.value) : undefined;
556
- if (state.panel && nextValue !== state.panel) {
557
- state.panel = nextValue;
558
- }
559
- state.value = nextValue;
560
- emits('update:modelValue', nextValue);
561
- emits('update', nextValue);
562
- };
563
-
564
- // 面板类型
565
- const setPanelType = () => {
566
- if (state.type < 2) {
567
- state.type += 1;
568
- }
569
- };
570
-
571
- // 时间滚动
572
- const _timer: any = ref(null);
573
- const timeScroll = (ev: any) => {
574
- const item: any = ev.target?.children[0];
575
- const type: any = ev.target.getAttribute('data-type') || '';
576
- if (state.panel && item) {
577
- clearTimeout(_timer.value);
578
- _timer.value = setTimeout(() => {
579
- const h = item.offsetHeight;
580
- const idx = Math.floor(ev.target.scrollTop / h);
581
- const maxIdx = type === 'h' ? 23 : 59;
582
- const safeIdx = Math.min(Math.max(idx, 0), maxIdx);
583
- const { YYYY = 0, MM = 0, DD = 0, HH = '', mm = '', ss = '' }: any = state.curr || {};
584
- let _panel = `${YYYY}-${MM}-${DD}`;
585
- if (type === 'h') {
586
- _panel += ` ${safeIdx}:${mm}:${ss}`;
587
- }
588
- if (type === 'm') {
589
- _panel += ` ${HH}:${safeIdx}:${ss}`;
590
- }
591
- if (type === 's') {
592
- _panel += ` ${HH}:${mm}:${safeIdx}`;
593
- }
594
- state.panel = idate(_panel).format('YYYY-MM-DD HH:mm:ss');
595
- }, 100);
596
- }
597
- };
598
- </script>
599
- <style lang="scss">
600
- .fekit-date-view-time-scroll {
601
- position: relative;
602
- height: 100%;
603
- scroll-snap-type: y mandatory;
604
- & > * {
605
- scroll-snap-align: center;
606
- }
607
- }
608
- </style>
@@ -1,74 +0,0 @@
1
- <template>
2
- <div ui-tips="@a ux:hover">
3
- <button :ui-btn="`@a none s :square`"><i class="icon icon-more"></i></button>
4
- <div ui-tips-box="bl" class="n-sl">
5
- <slot name="prefix"></slot>
6
- <slot>
7
- <div>
8
- <h6 class="fs-xs o-mm nowrap">每页显示数量</h6>
9
- <div ui-btns="@a line s :group :border">
10
- <button @click="setLinkMode('default')"><code :class="`${state.tools.confs.linkMode === 'default' ? 'co-main' : ''}`">跳转</code></button>
11
- <button @click="setLinkMode('preview')"><code :class="`${state.tools.confs.linkMode === 'preview' ? 'co-main' : ''}`">预览</code></button>
12
- <button @click="setLinkMode('windows')"><code :class="`${state.tools.confs.linkMode === 'windows' ? 'co-main' : ''}`">新窗口</code></button>
13
- </div>
14
- </div>
15
- <div ui-line="@a" class="mt-sm mb-ss"></div>
16
- <div>
17
- <h6 class="fs-xs o-mm nowrap">每页显示数量</h6>
18
- <div ui-btns="@a line s :group :border">
19
- <button @click="setPageSize(10)"><code :class="`${state.tools.param.pageSize === 10 ? 'co-main' : ''}`">10</code></button>
20
- <button @click="setPageSize(20)"><code :class="`${state.tools.param.pageSize === 20 ? 'co-main' : ''}`">20</code></button>
21
- <button @click="setPageSize(50)"><code :class="`${state.tools.param.pageSize === 50 ? 'co-main' : ''}`">50</code></button>
22
- <button @click="setPageSize(100)"><code :class="`${state.tools.param.pageSize === 100 ? 'co-main' : ''}`">100</code></button>
23
- </div>
24
- </div>
25
- </slot>
26
- <slot name="prefix"></slot>
27
- </div>
28
- </div>
29
- </template>
30
- <script setup lang="ts">
31
- import { reactive, computed } from 'vue';
32
- import { useRoute } from 'vue-router';
33
- const emits = defineEmits(['update:confs', 'update:param']);
34
- const props = defineProps({
35
- confs: {
36
- type: Object,
37
- default: () => ({})
38
- },
39
- param: {
40
- type: Object,
41
- default: () => ({})
42
- }
43
- });
44
-
45
- const route = useRoute();
46
- const state: any = reactive({
47
- name: computed(() => 'confs' + route.path?.replace(/\//g, '_')),
48
- tools: {
49
- confs: {},
50
- param: {}
51
- }
52
- });
53
-
54
- const init = () => {
55
- const _cache = JSON.parse(localStorage.getItem(`${state.name}`) || '{}');
56
- state.tools.confs = _cache.confs || JSON.parse(JSON.stringify(props.confs));
57
- state.tools.param = _cache.param || JSON.parse(JSON.stringify(props.param));
58
- emits('update:confs', state.tools.confs);
59
- emits('update:param', state.tools.param);
60
- };
61
- init();
62
-
63
- const setLinkMode = (linkMode: any) => {
64
- state.tools.confs.linkMode = linkMode;
65
- emits('update:confs', state.tools.confs);
66
- localStorage.setItem(state.name, JSON.stringify(state.tools));
67
- };
68
-
69
- const setPageSize = (pageSize: any) => {
70
- state.tools.param.pageSize = pageSize;
71
- emits('update:param', state.tools.param);
72
- localStorage.setItem(state.name, JSON.stringify(state.tools));
73
- };
74
- </script>
File without changes