vome-core 0.1.54 → 0.1.56
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.
- package/dist/admin/config/plugin-dev.js +1 -1
- package/dist/admin/crud/components/vm-date-calendar-panel.vue +115 -87
- package/dist/admin/crud/components/vm-date-picker.vue +21 -17
- package/dist/admin/crud/components/vm-date-range.vue +8 -11
- package/dist/admin/crud/components/vm-datetime-field.vue +44 -48
- package/dist/admin/crud/components/vm-richtext-extensions.js +1 -1
- package/dist/admin/crud/config.d.ts +0 -1
- package/dist/admin/crud/config.js +1 -1
- package/dist/admin/crud/confirm.js +1 -1
- package/dist/admin/crud/dict.js +1 -1
- package/dist/admin/crud/key.d.ts +0 -2
- package/dist/admin/crud/key.js +1 -1
- package/dist/admin/crud/plugins.js +1 -1
- package/dist/admin/crud/registry.d.ts +0 -2
- package/dist/admin/crud/registry.js +0 -2
- package/dist/admin/crud/span.js +1 -1
- package/dist/admin/crud/style.d.ts +2 -2
- package/dist/admin/crud/style.js +1 -1
- package/dist/admin/crud/validate.d.ts +0 -10
- package/dist/admin/crud/validate.js +1 -1
- package/dist/admin/crud/vm-crud.vue +1 -9
- package/dist/admin/directives/perm.js +1 -1
- package/dist/admin/hooks/useUpload.js +1 -1
- package/dist/admin/lib/browser.js +1 -1
- package/dist/admin/lib/cn.js +1 -1
- package/dist/admin/lib/dialog-float.js +1 -1
- package/dist/admin/lib/export-excel.d.ts +0 -2
- package/dist/admin/lib/export-excel.js +1 -1
- package/dist/admin/lib/file-preview.d.ts +2 -4
- package/dist/admin/lib/file-preview.js +11 -11
- package/dist/admin/lib/import-excel.d.ts +3 -2
- package/dist/admin/lib/import-excel.js +1 -1
- package/dist/admin/lib/json.js +1 -1
- package/dist/admin/lib/menu.js +1 -1
- package/dist/admin/lib/tree.js +1 -1
- package/dist/admin/lib/upload.d.ts +0 -1
- package/dist/admin/lib/upload.js +1 -1
- package/dist/admin/lib/video-frame.d.ts +0 -3
- package/dist/admin/lib/video-frame.js +1 -1
- package/dist/agent/constants.d.ts +0 -7
- package/dist/agent/index.d.ts +0 -1
- package/dist/agent/index.js +2 -25
- package/dist/agent/protocol.d.ts +0 -2
- package/dist/ai/adapters/auth-headers.d.ts +2 -2
- package/dist/ai/adapters/openai-compatible.d.ts +1 -2
- package/dist/ai/index.js +0 -7
- package/dist/ai/transport.d.ts +0 -6
- package/dist/ai/types.d.ts +0 -2
- package/dist/client/vite-admin.d.ts +0 -5
- package/dist/client/vite-admin.js +0 -6
- package/dist/client/vite-plugin-eps.d.ts +0 -23
- package/dist/client/vite-plugin-eps.js +1 -1
- package/dist/comm/daily-log.d.ts +0 -2
- package/dist/comm/format-time.d.ts +0 -1
- package/dist/core/context/index.d.ts +0 -8
- package/dist/ext/load-plugin.d.ts +0 -4
- package/dist/index.js +1 -1
- package/dist/ioc/metadata.d.ts +0 -1
- package/dist/orm/column-comments.d.ts +2 -1
- package/dist/orm/field-ref.d.ts +2 -1
- package/dist/orm/import-excel.d.ts +2 -6
- package/dist/orm/join-tables.d.ts +0 -3
- package/dist/server/index.js +1 -1
- package/dist/shared/datetime-picker.d.ts +5 -22
- package/dist/shared/datetime-picker.js +1 -1
- package/dist/shared/excel.js +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/locale-json.js +1 -1
- package/dist/shared/tree.js +1 -1
- package/dist/typings/routing/crud.d.ts +1 -1
- package/package.json +1 -1
- package/typings/admin/comm/crud.d.ts +1 -1
- package/typings/admin/comm/crud.ts +1 -3
- package/typings/routing/crud.ts +1 -3
- package/dist/admin/crud/mitt.d.ts +0 -10
- package/dist/admin/crud/mitt.js +0 -1
- package/dist/agent/types.d.ts +0 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const _0x5bdd00=_0x3bd1;(function(_0xeb1cd4,_0x471399){const _0x560dfb=_0x3bd1,_0x3cf1d5=_0xeb1cd4();while(!![]){try{const _0x29ac44=-parseInt(_0x560dfb(0x124))/0x1*(-parseInt(_0x560dfb(0x132))/0x2)+parseInt(_0x560dfb(0x12e))/0x3*(-parseInt(_0x560dfb(0x12d))/0x4)+-parseInt(_0x560dfb(0x129))/0x5*(-parseInt(_0x560dfb(0x11f))/0x6)+parseInt(_0x560dfb(0x12f))/0x7*(parseInt(_0x560dfb(0x127))/0x8)+parseInt(_0x560dfb(0x123))/0x9*(parseInt(_0x560dfb(0x13c))/0xa)+parseInt(_0x560dfb(0x136))/0xb*(-parseInt(_0x560dfb(0x128))/0xc)+-parseInt(_0x560dfb(0x13e))/0xd*(-parseInt(_0x560dfb(0x135))/0xe);if(_0x29ac44===_0x471399)break;else _0x3cf1d5['push'](_0x3cf1d5['shift']());}catch(_0x2bab84){_0x3cf1d5['push'](_0x3cf1d5['shift']());}}}(_0x5b8e,0xbf09e));const ORG=_0x5bdd00(0x130);export function serviceUrlFromDocs(_0x4109c7){const _0x8c1717=_0x5bdd00,_0x590968=new URL(_0x4109c7),_0x2f2af3=_0x590968['hostname']['replace'](/^www\./,'')[_0x8c1717(0x126)](/^service\./,'');return _0x590968[_0x8c1717(0x122)]+'//service.'+_0x2f2af3;}function _0x5b8e(){const _0x3a84ca=['57QV5yMn56UV','mZG3mZuYyLf3rxvJ','mJrvu3n6wNa','ntG2nLj3rfjXsa','DM9TzwTQ','6zkP5A2qic8G5PYn5yQH56UV5O+s5lU26isA5OMl5P6277YilNzVBwxVVjRKU4uGC2vYDMvY77Yj77Ym6ycc5zci5lIk5lYG44cb55+T5l+H44cb5PsV5lUy562j6io95yQB5OMP5Bgv44cc','mMXoAMvsrG','Ahr0Chm6lY92B21LA2OUy29T','57QV5zco56UV','mtyYmdCXndjNwurvEfG','ndK1zevYCfvQ','l2fWCc9WBhvNAw5tDg9Yzs93ywXSzxqVBgLJzw5Zzs9PC3n1zq','Ahr0Chm6lY9NAxrODwiUy29TlW','5zco5y+W5B6U5BQu55sO6isA5OMl5P6277YilNzVBwxVVjRLKkSGD2vIl++8IE+8Jos7Psb3DwPPzsdMJilOVB3NI6ZNQ4VLIy3NQ6/POBxPNAlJGii','5yMn56UVicSG5zco56UV','z2L0zwu','mtq2mtm3otbxuu55CNu','zNjVBNrLBMq','mtnyuhP3rLy','yMfJA2vUza','mJu1otG0tKzWv3vm','Ahr0Chm6lY9NAxrLzs5JB20V','zNvSBa','ChjVDg9JB2W','ourwBfDezW','mJK0nZfuvNDnC0m','DM9Tzs1WBhvNAw4TzNjVBNq','CMvWBgfJzq','mJeYohPiv0HOCW','mZG0ntG4wgfPA2H1','mtvuCxnpAfi','DM9Tzs1WBhvNAw4TzNvSBa','DM9Tzs1WBhvNAw4TC2vYDMLJzq'];_0x5b8e=function(){return _0x3a84ca;};return _0x5b8e();}export function seatApiBaseFromDocs(_0x256f8b){return serviceUrlFromDocs(_0x256f8b)+'/app/pluginStore/seat';}export function licenseIssueUrlFromDocs(_0x1e1a61){const _0x46cf16=_0x5bdd00;return serviceUrlFromDocs(_0x1e1a61)+_0x46cf16(0x137);}function giteeArchive(_0x50aa0e){const _0x3e9951=_0x5bdd00;return _0x3e9951(0x120)+ORG+'/'+_0x50aa0e+'/repository/archive/master.zip';}function githubArchive(_0x2d75ca){const _0x3aa292=_0x5bdd00;return _0x3aa292(0x138)+ORG+'/'+_0x2d75ca+'/archive/refs/heads/master.zip';}function giteeRepo(_0x26d2ec){const _0x82e20e=_0x5bdd00;return _0x82e20e(0x120)+ORG+'/'+_0x26d2ec;}function githubRepo(_0x208bee){const _0x3cae19=_0x5bdd00;return _0x3cae19(0x138)+ORG+'/'+_0x208bee;}const docsUrl=_0x5bdd00(0x133);function _0x3bd1(_0x21268b,_0x15a47c){_0x21268b=_0x21268b-0x11e;const _0x5b8e14=_0x5b8e();let _0x3bd140=_0x5b8e14[_0x21268b];if(_0x3bd1['ttYZOf']===undefined){var _0x51c2db=function(_0x4c8084){const _0x4e720b='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x4109c7='',_0x590968='';for(let _0x2f2af3=0x0,_0x256f8b,_0x1e1a61,_0x50aa0e=0x0;_0x1e1a61=_0x4c8084['charAt'](_0x50aa0e++);~_0x1e1a61&&(_0x256f8b=_0x2f2af3%0x4?_0x256f8b*0x40+_0x1e1a61:_0x1e1a61,_0x2f2af3++%0x4)?_0x4109c7+=String['fromCharCode'](0xff&_0x256f8b>>(-0x2*_0x2f2af3&0x6)):0x0){_0x1e1a61=_0x4e720b['indexOf'](_0x1e1a61);}for(let _0x2d75ca=0x0,_0x26d2ec=_0x4109c7['length'];_0x2d75ca<_0x26d2ec;_0x2d75ca++){_0x590968+='%'+('00'+_0x4109c7['charCodeAt'](_0x2d75ca)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x590968);};_0x3bd1['RQllfG']=_0x51c2db,_0x3bd1['SpkxdG']={},_0x3bd1['ttYZOf']=!![];}const _0x348f8c=_0x5b8e14[0x0],_0x2eeb60=_0x21268b+_0x348f8c,_0x50a163=_0x3bd1['SpkxdG'][_0x2eeb60];return!_0x50a163?(_0x3bd140=_0x3bd1['RQllfG'](_0x3bd140),_0x3bd1['SpkxdG'][_0x2eeb60]=_0x3bd140):_0x3bd140=_0x50a163,_0x3bd140;}export const pluginDev={'docsUrl':docsUrl,'serviceUrl':serviceUrlFromDocs(docsUrl),'uploadUrl':docsUrl+'/plugins/upload','mirrors':{'prefer':_0x5bdd00(0x13b),'giteeOrg':_0x5bdd00(0x120)+ORG,'githubOrg':'https://github.com/'+ORG},'scaffolds':{'full':{'key':_0x5bdd00(0x121),'title':_0x5bdd00(0x13a),'desc':'完整业务模块脚手架(.vome:含\x20server\x20与\x20web),本地开发打包后发布。','repo':_0x5bdd00(0x12a),'repoUrl':giteeRepo(_0x5bdd00(0x12a)),'githubRepoUrl':githubRepo(_0x5bdd00(0x12a)),'downloadUrl':giteeArchive(_0x5bdd00(0x12a)),'githubDownloadUrl':githubArchive(_0x5bdd00(0x12a))},'backend':{'key':_0x5bdd00(0x11e),'title':_0x5bdd00(0x134),'desc':_0x5bdd00(0x131),'repo':_0x5bdd00(0x12b),'repoUrl':giteeRepo(_0x5bdd00(0x12b)),'githubRepoUrl':githubRepo(_0x5bdd00(0x12b)),'downloadUrl':giteeArchive(_0x5bdd00(0x12b)),'githubDownloadUrl':githubArchive(_0x5bdd00(0x12b))},'frontend':{'key':_0x5bdd00(0x13d),'title':_0x5bdd00(0x12c),'desc':_0x5bdd00(0x139),'repo':_0x5bdd00(0x125),'repoUrl':giteeRepo('vome-plugin-front'),'githubRepoUrl':githubRepo(_0x5bdd00(0x125)),'downloadUrl':giteeArchive('vome-plugin-front'),'githubDownloadUrl':githubArchive('vome-plugin-front')}}};
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
<div class="vm-dt-cal__grid">
|
|
27
27
|
<button
|
|
28
28
|
v-for="cell in monthCells"
|
|
29
|
-
:key="cell.
|
|
29
|
+
:key="cell.iso"
|
|
30
30
|
type="button"
|
|
31
31
|
class="vm-dt-cal__day"
|
|
32
32
|
:class="{
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
'is-today': cell.isToday,
|
|
35
35
|
'is-on': selectedIso === cell.iso,
|
|
36
36
|
}"
|
|
37
|
-
@click="
|
|
37
|
+
@click="emitValue(cell.iso)"
|
|
38
38
|
>
|
|
39
39
|
{{ cell.day }}
|
|
40
40
|
</button>
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
v-for="(lab, idx) in monthLabels"
|
|
47
47
|
:key="lab"
|
|
48
48
|
type="button"
|
|
49
|
-
class="vm-dt-
|
|
49
|
+
class="vm-dt-cal__cell"
|
|
50
50
|
:class="{ 'is-on': viewMonth === idx }"
|
|
51
51
|
@click="pickMonth(idx)"
|
|
52
52
|
>
|
|
@@ -54,12 +54,12 @@
|
|
|
54
54
|
</button>
|
|
55
55
|
</div>
|
|
56
56
|
|
|
57
|
-
<div v-else class="vm-dt-cal__body vm-dt-cal__body--
|
|
57
|
+
<div v-else class="vm-dt-cal__body vm-dt-cal__body--months">
|
|
58
58
|
<button
|
|
59
59
|
v-for="y in yearCells"
|
|
60
60
|
:key="y"
|
|
61
61
|
type="button"
|
|
62
|
-
class="vm-dt-
|
|
62
|
+
class="vm-dt-cal__cell"
|
|
63
63
|
:class="{ 'is-on': viewYear === y }"
|
|
64
64
|
@click="pickYear(y)"
|
|
65
65
|
>
|
|
@@ -67,35 +67,22 @@
|
|
|
67
67
|
</button>
|
|
68
68
|
</div>
|
|
69
69
|
|
|
70
|
-
<div v-if="
|
|
71
|
-
<label class="vm-dt-cal__time-field">
|
|
72
|
-
<span
|
|
70
|
+
<div v-if="isDatetime" class="vm-dt-cal__time" @pointerdown.stop>
|
|
71
|
+
<label v-for="f in timeFields" :key="f.key" class="vm-dt-cal__time-field">
|
|
72
|
+
<span>{{ f.label }}</span>
|
|
73
73
|
<input
|
|
74
|
-
type="
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
max="59"
|
|
87
|
-
:value="time.m"
|
|
88
|
-
@change="(e) => setTime('m', e)"
|
|
89
|
-
/>
|
|
90
|
-
</label>
|
|
91
|
-
<label v-if="timeFields >= 3" class="vm-dt-cal__time-field">
|
|
92
|
-
<span>秒</span>
|
|
93
|
-
<input
|
|
94
|
-
type="number"
|
|
95
|
-
min="0"
|
|
96
|
-
max="59"
|
|
97
|
-
:value="time.s"
|
|
98
|
-
@change="(e) => setTime('s', e)"
|
|
74
|
+
type="text"
|
|
75
|
+
inputmode="numeric"
|
|
76
|
+
autocomplete="off"
|
|
77
|
+
maxlength="2"
|
|
78
|
+
:value="draft[f.key]"
|
|
79
|
+
@pointerdown.stop
|
|
80
|
+
@mousedown.stop
|
|
81
|
+
@click.stop
|
|
82
|
+
@keydown.stop="onTimeKeydown(f.key, $event)"
|
|
83
|
+
@focus="onTimeFocus"
|
|
84
|
+
@input="(e) => onTimeInput(f.key, e)"
|
|
85
|
+
@blur="onTimeBlur(f.key)"
|
|
99
86
|
/>
|
|
100
87
|
</label>
|
|
101
88
|
</div>
|
|
@@ -108,13 +95,11 @@
|
|
|
108
95
|
</template>
|
|
109
96
|
|
|
110
97
|
<script setup lang="ts">
|
|
111
|
-
import { computed, ref, watch } from 'vue'
|
|
98
|
+
import { computed, reactive, ref, watch } from 'vue'
|
|
112
99
|
import {
|
|
113
100
|
buildMonthGrid,
|
|
114
|
-
|
|
101
|
+
clampTimePart,
|
|
115
102
|
formatYmd,
|
|
116
|
-
mergeDateAndTime,
|
|
117
|
-
monthTitle,
|
|
118
103
|
normalizeDateTimePrecision,
|
|
119
104
|
parseApiDateTime,
|
|
120
105
|
type DateTimePrecision,
|
|
@@ -139,23 +124,47 @@ const emit = defineEmits<{
|
|
|
139
124
|
}>()
|
|
140
125
|
|
|
141
126
|
const precision = computed(() => normalizeDateTimePrecision(props.precision))
|
|
127
|
+
const isDatetime = computed(() => precision.value === 'datetime')
|
|
142
128
|
const weekdays = ['日', '一', '二', '三', '四', '五', '六']
|
|
143
|
-
const monthLabels = [
|
|
129
|
+
const monthLabels = [
|
|
130
|
+
'1月',
|
|
131
|
+
'2月',
|
|
132
|
+
'3月',
|
|
133
|
+
'4月',
|
|
134
|
+
'5月',
|
|
135
|
+
'6月',
|
|
136
|
+
'7月',
|
|
137
|
+
'8月',
|
|
138
|
+
'9月',
|
|
139
|
+
'10月',
|
|
140
|
+
'11月',
|
|
141
|
+
'12月',
|
|
142
|
+
]
|
|
143
|
+
const timeFields = [
|
|
144
|
+
{ key: 'h' as const, label: '时', max: 23 },
|
|
145
|
+
{ key: 'm' as const, label: '分', max: 59 },
|
|
146
|
+
{ key: 's' as const, label: '秒', max: 59 },
|
|
147
|
+
]
|
|
144
148
|
|
|
145
149
|
type PanelView = 'date' | 'month' | 'year'
|
|
146
150
|
const view = ref<PanelView>('date')
|
|
147
|
-
|
|
148
|
-
const
|
|
149
|
-
const viewYear = ref(
|
|
150
|
-
const viewMonth = ref(
|
|
151
|
+
const draft = reactive({ h: '0', m: '0', s: '0' })
|
|
152
|
+
const timeFocused = ref(false)
|
|
153
|
+
const viewYear = ref(new Date().getFullYear())
|
|
154
|
+
const viewMonth = ref(new Date().getMonth())
|
|
151
155
|
|
|
152
156
|
watch(
|
|
153
157
|
() => props.modelValue,
|
|
154
|
-
() => {
|
|
155
|
-
const d = parseApiDateTime(
|
|
158
|
+
(v) => {
|
|
159
|
+
const d = parseApiDateTime(v) || new Date()
|
|
156
160
|
viewYear.value = d.getFullYear()
|
|
157
161
|
viewMonth.value = d.getMonth()
|
|
162
|
+
if (timeFocused.value) return
|
|
163
|
+
draft.h = String(d.getHours())
|
|
164
|
+
draft.m = String(d.getMinutes())
|
|
165
|
+
draft.s = String(d.getSeconds())
|
|
158
166
|
},
|
|
167
|
+
{ immediate: true },
|
|
159
168
|
)
|
|
160
169
|
|
|
161
170
|
const selectedIso = computed(() => {
|
|
@@ -164,7 +173,6 @@ const selectedIso = computed(() => {
|
|
|
164
173
|
})
|
|
165
174
|
|
|
166
175
|
const monthCells = computed(() => buildMonthGrid(viewYear.value, viewMonth.value))
|
|
167
|
-
|
|
168
176
|
const yearStart = computed(() => Math.floor(viewYear.value / 10) * 10)
|
|
169
177
|
const yearCells = computed(() =>
|
|
170
178
|
Array.from({ length: 12 }, (_, i) => yearStart.value + i),
|
|
@@ -173,19 +181,56 @@ const yearCells = computed(() =>
|
|
|
173
181
|
const headTitle = computed(() => {
|
|
174
182
|
if (view.value === 'year') return `${yearStart.value}年 - ${yearStart.value + 11}年`
|
|
175
183
|
if (view.value === 'month') return `${viewYear.value}年`
|
|
176
|
-
return
|
|
184
|
+
return `${viewYear.value}年${String(viewMonth.value + 1).padStart(2, '0')}月`
|
|
177
185
|
})
|
|
178
186
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
)
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
+
function currentTime() {
|
|
188
|
+
return {
|
|
189
|
+
h: clampTimePart('h', Number(draft.h) || 0),
|
|
190
|
+
m: clampTimePart('m', Number(draft.m) || 0),
|
|
191
|
+
s: clampTimePart('s', Number(draft.s) || 0),
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function emitDatetime(isoDate: string, t = currentTime()) {
|
|
196
|
+
const pad = (n: number) => String(n).padStart(2, '0')
|
|
197
|
+
emit(
|
|
198
|
+
'update:modelValue',
|
|
199
|
+
`${isoDate} ${pad(t.h)}:${pad(t.m)}:${pad(t.s)}`,
|
|
200
|
+
)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function onTimeFocus() {
|
|
204
|
+
timeFocused.value = true
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** 手输过程只改 draft,失焦 / Enter 再提交,避免受控回写打乱光标 */
|
|
208
|
+
function onTimeInput(k: 'h' | 'm' | 's', e: Event) {
|
|
209
|
+
const raw = (e.target as HTMLInputElement).value.replace(/\D/g, '').slice(0, 2)
|
|
210
|
+
draft[k] = raw
|
|
211
|
+
;(e.target as HTMLInputElement).value = raw
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function commitTimeField(k: 'h' | 'm' | 's') {
|
|
215
|
+
const n = Number(draft[k])
|
|
216
|
+
const next = currentTime()
|
|
217
|
+
next[k] = Number.isFinite(n) ? clampTimePart(k, n) : 0
|
|
218
|
+
draft[k] = String(next[k])
|
|
219
|
+
emitDatetime(selectedIso.value || formatYmd(new Date()), next)
|
|
220
|
+
}
|
|
187
221
|
|
|
188
|
-
|
|
222
|
+
function onTimeBlur(k: 'h' | 'm' | 's') {
|
|
223
|
+
commitTimeField(k)
|
|
224
|
+
timeFocused.value = false
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function onTimeKeydown(k: 'h' | 'm' | 's', e: KeyboardEvent) {
|
|
228
|
+
if (e.key === 'Enter') {
|
|
229
|
+
e.preventDefault()
|
|
230
|
+
commitTimeField(k)
|
|
231
|
+
;(e.target as HTMLInputElement).blur()
|
|
232
|
+
}
|
|
233
|
+
}
|
|
189
234
|
|
|
190
235
|
function toggleView() {
|
|
191
236
|
view.value = view.value === 'date' ? 'month' : view.value === 'month' ? 'year' : 'date'
|
|
@@ -226,15 +271,8 @@ function nextPage() {
|
|
|
226
271
|
}
|
|
227
272
|
|
|
228
273
|
function emitValue(isoDate: string) {
|
|
229
|
-
if (
|
|
230
|
-
|
|
231
|
-
isoDate,
|
|
232
|
-
time.value.h,
|
|
233
|
-
time.value.m,
|
|
234
|
-
time.value.s,
|
|
235
|
-
precision.value,
|
|
236
|
-
)
|
|
237
|
-
emit('update:modelValue', v)
|
|
274
|
+
if (isDatetime.value) {
|
|
275
|
+
emitDatetime(isoDate)
|
|
238
276
|
return
|
|
239
277
|
}
|
|
240
278
|
if (precision.value === 'month') {
|
|
@@ -248,13 +286,6 @@ function emitValue(isoDate: string) {
|
|
|
248
286
|
emit('update:modelValue', isoDate)
|
|
249
287
|
}
|
|
250
288
|
|
|
251
|
-
function pickDate(iso: string) {
|
|
252
|
-
emitValue(iso)
|
|
253
|
-
if (precision.value === 'day') {
|
|
254
|
-
view.value = 'date'
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
289
|
function pickMonth(idx: number) {
|
|
259
290
|
viewMonth.value = idx
|
|
260
291
|
view.value = 'date'
|
|
@@ -278,15 +309,6 @@ function pickToday() {
|
|
|
278
309
|
view.value = 'date'
|
|
279
310
|
emitValue(formatYmd(now))
|
|
280
311
|
}
|
|
281
|
-
|
|
282
|
-
function setTime(k: 'h' | 'm' | 's', e: Event) {
|
|
283
|
-
const n = Number((e.target as HTMLInputElement).value)
|
|
284
|
-
if (!Number.isFinite(n)) return
|
|
285
|
-
const iso = selectedIso.value || formatYmd(new Date())
|
|
286
|
-
const next = { ...time.value, [k]: Math.max(0, Math.min(k === 'h' ? 23 : 59, n)) }
|
|
287
|
-
const v = mergeDateAndTime(iso, next.h, next.m, next.s, precision.value)
|
|
288
|
-
emit('update:modelValue', v)
|
|
289
|
-
}
|
|
290
312
|
</script>
|
|
291
313
|
|
|
292
314
|
<style lang="scss" scoped>
|
|
@@ -299,7 +321,6 @@ function setTime(k: 'h' | 'm' | 's', e: Event) {
|
|
|
299
321
|
background: var(--card, #fff);
|
|
300
322
|
box-shadow: 0 8px 24px rgb(15 23 42 / 10%);
|
|
301
323
|
color: var(--foreground, #1f2937);
|
|
302
|
-
user-select: none;
|
|
303
324
|
}
|
|
304
325
|
|
|
305
326
|
.vm-dt-cal__head {
|
|
@@ -416,16 +437,14 @@ function setTime(k: 'h' | 'm' | 's', e: Event) {
|
|
|
416
437
|
}
|
|
417
438
|
}
|
|
418
439
|
|
|
419
|
-
.vm-dt-cal__body--months
|
|
420
|
-
.vm-dt-cal__body--years {
|
|
440
|
+
.vm-dt-cal__body--months {
|
|
421
441
|
display: grid;
|
|
422
442
|
grid-template-columns: repeat(3, 1fr);
|
|
423
443
|
gap: 8px 6px;
|
|
424
444
|
padding: 4px 0 8px;
|
|
425
445
|
}
|
|
426
446
|
|
|
427
|
-
.vm-dt-
|
|
428
|
-
.vm-dt-cal__year {
|
|
447
|
+
.vm-dt-cal__cell {
|
|
429
448
|
height: 36px;
|
|
430
449
|
border: 0;
|
|
431
450
|
border-radius: 8px;
|
|
@@ -464,19 +483,28 @@ function setTime(k: 'h' | 'm' | 's', e: Event) {
|
|
|
464
483
|
color: var(--muted-foreground, #64748b);
|
|
465
484
|
|
|
466
485
|
input {
|
|
486
|
+
box-sizing: border-box;
|
|
467
487
|
width: 100%;
|
|
468
488
|
min-width: 0;
|
|
469
489
|
height: 28px;
|
|
470
490
|
padding: 0 6px;
|
|
471
491
|
border: 1px solid var(--border, #e8ebf5);
|
|
472
492
|
border-radius: 8px;
|
|
473
|
-
background:
|
|
474
|
-
color:
|
|
493
|
+
background: #fff;
|
|
494
|
+
color: var(--foreground, #1f2937);
|
|
475
495
|
font-size: 13px;
|
|
496
|
+
line-height: 28px;
|
|
497
|
+
text-align: center;
|
|
476
498
|
outline: none;
|
|
499
|
+
cursor: text;
|
|
500
|
+
user-select: text;
|
|
501
|
+
-webkit-user-select: text;
|
|
502
|
+
caret-color: var(--primary, var(--vm-brand, #4e5dff));
|
|
477
503
|
|
|
478
504
|
&:focus {
|
|
479
505
|
border-color: var(--primary, var(--vm-brand, #4e5dff));
|
|
506
|
+
background: #fff;
|
|
507
|
+
box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary, #4e5dff) 18%, transparent);
|
|
480
508
|
}
|
|
481
509
|
}
|
|
482
510
|
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<VmDatetimeField
|
|
3
|
-
:model-value="
|
|
3
|
+
:model-value="modelValue || null"
|
|
4
4
|
:precision="precision"
|
|
5
5
|
:placeholder="placeholderText"
|
|
6
6
|
:disabled="disabled"
|
|
7
7
|
:style="{ width }"
|
|
8
8
|
@update:model-value="onUpdate"
|
|
9
|
-
@change="onUpdate"
|
|
10
9
|
/>
|
|
11
10
|
</template>
|
|
12
11
|
|
|
@@ -14,6 +13,7 @@
|
|
|
14
13
|
import { computed } from 'vue'
|
|
15
14
|
import { useCrud } from '../useCrud'
|
|
16
15
|
import VmDatetimeField from './vm-datetime-field.vue'
|
|
16
|
+
import type { DateTimePrecision } from '../../../shared/datetime-picker'
|
|
17
17
|
|
|
18
18
|
defineOptions({ name: 'vm-date-picker' })
|
|
19
19
|
|
|
@@ -21,7 +21,6 @@ const props = withDefaults(
|
|
|
21
21
|
defineProps<{
|
|
22
22
|
modelValue?: string | null
|
|
23
23
|
type?: 'date' | 'datetime' | 'month' | 'year'
|
|
24
|
-
valueFormat?: string
|
|
25
24
|
prop?: string
|
|
26
25
|
width?: string
|
|
27
26
|
disabled?: boolean
|
|
@@ -42,22 +41,27 @@ const emit = defineEmits<{
|
|
|
42
41
|
|
|
43
42
|
const crud = useCrud()
|
|
44
43
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
44
|
+
const TYPE_PRECISION: Record<string, DateTimePrecision> = {
|
|
45
|
+
date: 'day',
|
|
46
|
+
datetime: 'datetime',
|
|
47
|
+
month: 'month',
|
|
48
|
+
year: 'year',
|
|
49
|
+
}
|
|
51
50
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
})
|
|
51
|
+
const TYPE_PLACEHOLDER: Record<string, string> = {
|
|
52
|
+
date: '选择日期',
|
|
53
|
+
datetime: '选择日期时间',
|
|
54
|
+
month: '选择月份',
|
|
55
|
+
year: '选择年份',
|
|
56
|
+
}
|
|
59
57
|
|
|
60
|
-
const
|
|
58
|
+
const precision = computed(
|
|
59
|
+
() => TYPE_PRECISION[props.type] ?? ('day' as DateTimePrecision),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
const placeholderText = computed(
|
|
63
|
+
() => props.placeholder || TYPE_PLACEHOLDER[props.type] || '选择日期',
|
|
64
|
+
)
|
|
61
65
|
|
|
62
66
|
function onUpdate(v: string | null) {
|
|
63
67
|
const out = v || ''
|
|
@@ -2,36 +2,35 @@
|
|
|
2
2
|
<div class="vm-date-range" :class="{ 'is-disabled': disabled }">
|
|
3
3
|
<VmDatetimeField
|
|
4
4
|
class="vm-date-range__field"
|
|
5
|
-
:model-value="
|
|
5
|
+
:model-value="modelValue?.[0] ?? null"
|
|
6
6
|
:precision="precision"
|
|
7
7
|
:placeholder="startPlaceholder"
|
|
8
8
|
:disabled="disabled"
|
|
9
9
|
@update:model-value="(v) => set(0, v)"
|
|
10
|
-
@change="(v) => set(0, v)"
|
|
11
10
|
/>
|
|
12
11
|
<span class="vm-date-range__sep">-</span>
|
|
13
12
|
<VmDatetimeField
|
|
14
13
|
class="vm-date-range__field"
|
|
15
|
-
:model-value="
|
|
14
|
+
:model-value="modelValue?.[1] ?? null"
|
|
16
15
|
:precision="precision"
|
|
17
16
|
:placeholder="endPlaceholder"
|
|
18
17
|
:disabled="disabled"
|
|
19
18
|
@update:model-value="(v) => set(1, v)"
|
|
20
|
-
@change="(v) => set(1, v)"
|
|
21
19
|
/>
|
|
22
20
|
</div>
|
|
23
21
|
</template>
|
|
24
22
|
|
|
25
23
|
<script setup lang="ts">
|
|
26
|
-
defineOptions({ name: 'vm-date-range' })
|
|
27
|
-
|
|
28
24
|
import VmDatetimeField from './vm-datetime-field.vue'
|
|
25
|
+
import type { DateTimePrecision } from '../../../shared/datetime-picker'
|
|
26
|
+
|
|
27
|
+
defineOptions({ name: 'vm-date-range' })
|
|
29
28
|
|
|
30
29
|
const props = withDefaults(
|
|
31
30
|
defineProps<{
|
|
32
31
|
modelValue?: Array<string | null>
|
|
33
|
-
/**
|
|
34
|
-
precision?:
|
|
32
|
+
/** year | month | day | datetime */
|
|
33
|
+
precision?: DateTimePrecision
|
|
35
34
|
startPlaceholder?: string
|
|
36
35
|
endPlaceholder?: string
|
|
37
36
|
disabled?: boolean
|
|
@@ -65,7 +64,6 @@ function set(idx: 0 | 1, v: string | null) {
|
|
|
65
64
|
box-sizing: border-box;
|
|
66
65
|
width: 100%;
|
|
67
66
|
align-items: center;
|
|
68
|
-
gap: 0;
|
|
69
67
|
|
|
70
68
|
&.is-disabled {
|
|
71
69
|
opacity: 0.55;
|
|
@@ -79,12 +77,11 @@ function set(idx: 0 | 1, v: string | null) {
|
|
|
79
77
|
}
|
|
80
78
|
|
|
81
79
|
.vm-date-range__sep {
|
|
82
|
-
flex:
|
|
80
|
+
flex: none;
|
|
83
81
|
padding: 0 8px;
|
|
84
82
|
color: var(--muted-foreground, #94a3b8);
|
|
85
83
|
font-size: 13px;
|
|
86
84
|
font-weight: 600;
|
|
87
|
-
line-height: 1;
|
|
88
85
|
user-select: none;
|
|
89
86
|
}
|
|
90
87
|
</style>
|