@94ai/nf-double-half-year 3.1.37 → 3.1.39

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.
@@ -0,0 +1,40 @@
1
+ /**
2
+ * 半年对应筛选项
3
+ */
4
+ export const halfYearOptions = [
5
+ {
6
+ label: '上半年',
7
+ value: 1,
8
+ months: [1, 2, 3, 4, 5, 6]
9
+ },
10
+ {
11
+ label: '下半年',
12
+ value: 2,
13
+ months: [7, 8, 9, 10, 11, 12]
14
+ },
15
+ ];
16
+
17
+ /**
18
+ * 获取半年对应的月份
19
+ * @returns
20
+ */
21
+ export function getHarfYearOptionMonths(value) {
22
+ for (let item of halfYearOptions) {
23
+ if (item.value == value) {
24
+ return item.months;
25
+ }
26
+ }
27
+ return []
28
+ }
29
+
30
+ /**
31
+ * 获取日期对应季度
32
+ * @returns
33
+ */
34
+ export function getHarfYearItemOfMonth(month) {
35
+ for (let item of halfYearOptions) {
36
+ if (item.months.includes(month)) {
37
+ return item;
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,8 @@
1
+ import NfDoubleHalfYear from './nf-double-half-year.vue'
2
+ import { Vue2, PluginObject } from 'vue-demi'
3
+
4
+ NfDoubleHalfYear.install = (app: typeof Vue2) => {
5
+ app!.component('nf-double-half-year', NfDoubleHalfYear)
6
+ }
7
+
8
+ export default NfDoubleHalfYear as typeof NfDoubleHalfYear & PluginObject<undefined>
@@ -0,0 +1,301 @@
1
+ <template>
2
+ <el-popover
3
+ class="nf-double-half-year nf-half-year-range-picker"
4
+ v-model="nfDoubleQuatterPopoverVisible"
5
+ :placement="placement"
6
+ :transition="transition"
7
+ :disabled="disabled"
8
+ :offset="offset"
9
+ :popper-class="(popperClass || '') + ' nf-double-half-year nf-half-year-range-picker'"
10
+ :trigger="trigger"
11
+ :visible-arrow="visibleArrow"
12
+ :popper-options="popperOptions"
13
+ :open-delay="openDelay"
14
+ :close-delay="closeDelay"
15
+ :tabindex="tabindex"
16
+ @show="$emit('show')"
17
+ @after-enter="$emit('after-enter')"
18
+ @hide="$emit('hide')"
19
+ @after-leave="$emit('after-leave')"
20
+ :append-to-body="appendToBody"
21
+ >
22
+ <el-date-picker slot="reference"
23
+ ref="nfDoubleHalfYearElDatePicker"
24
+ popper-class="nf-double-half-year nf-half-year-range-picker-el-date-picker"
25
+ type="monthrange"
26
+ @focus="handleOpenPicker"
27
+ :value="showValue"
28
+ @change="handleChange"
29
+ @blur="$emit('blur', $event)"
30
+ :validate-event="false"
31
+ :disabled="disabled"
32
+ :readonly="readonly"
33
+ :range-separator="rangeSeparator"
34
+ :clear-icon="clearIcon"
35
+ :prefix-icon="prefixIcon"
36
+ :clearable="clearable"
37
+ :size="size"
38
+ :start-placeholder="startPlaceholder"
39
+ :end-placeholder="endPlaceholder" >
40
+ </el-date-picker>
41
+ <div class="nf-half-year-range-picker__content">
42
+ <half-year-picker-item :year.sync="startYear"
43
+ :half-year="startHalfYear"
44
+ :showRight="false"
45
+ @on-half-year-click="handleStartQuarterClick"
46
+ @on-year-change="handleStartYearChange"></half-year-picker-item>
47
+ <half-year-picker-item :year.sync="endYear"
48
+ :showLeft="false"
49
+ :half-year.sync="endHalfYear"
50
+ @on-half-year-click="handleEndQuarterClick"
51
+ @on-year-change="handleEndYearChange"></half-year-picker-item>
52
+ </div>
53
+ </el-popover>
54
+ </template>
55
+
56
+ <script lang="ts">
57
+ import {
58
+ defineComponent,
59
+ } from 'vue-demi'
60
+
61
+ export default defineComponent({
62
+ name: 'NfDoubleHalfYear',
63
+ })
64
+ </script>
65
+ <script setup lang="ts">
66
+ import HalfYearPickerItem from './nf-half-year-picker-item.vue'
67
+ import {
68
+ ref,
69
+ defineProps,
70
+ defineEmits,
71
+ computed,
72
+ watch,
73
+ nextTick
74
+ } from 'vue-demi'
75
+ import {
76
+ endOf,
77
+ formatDate,
78
+ getNextYear,
79
+ getHalfYear,
80
+ startOf
81
+ } from './util'
82
+ import { getHarfYearOptionMonths } from './config'
83
+ import { HalfYearItem } from './types'
84
+
85
+ const props = withDefaults(defineProps<{
86
+ // [起始日期,结束日期]
87
+ value?: string[],
88
+ size?: 'mini' | 'small' | 'medium' | 'large',
89
+ rangeSeparator?: string,
90
+ readonly?: boolean,
91
+ clearable?: boolean,
92
+ startPlaceholder?: string,
93
+ endPlaceholder?: string,
94
+ format?: Function,
95
+ disabled?: boolean,
96
+ prefixIcon?: string,
97
+ clearIcon?: string,
98
+ transition?: string,
99
+ placement?: string,
100
+ popperClass?: string,
101
+ trigger?: string,
102
+ offset?: number,
103
+ visibleArrow?: boolean,
104
+ popperOptions?: Object,
105
+ openDelay?: number,
106
+ closeDelay?: number,
107
+ tabindex?: number,
108
+ appendToBody?: boolean
109
+ }>(), {
110
+ // [起始日期,结束日期]
111
+ value: undefined,
112
+ size: 'mini',
113
+ rangeSeparator: '-',
114
+ readonly: false,
115
+ clearable: true,
116
+ startPlaceholder: '开始半年',
117
+ endPlaceholder: '结束半年',
118
+ disabled: false,
119
+ offset: 0,
120
+ prefixIcon: 'el-icon-date',
121
+ clearIcon: 'el-icon-circle-close',
122
+ transition: 'el-zoom-in-top',
123
+ placement: 'bottom-start',
124
+ popperClass: '',
125
+ trigger: 'click',
126
+ visibleArrow: true,
127
+ openDelay: undefined,
128
+ closeDelay: 200,
129
+ tabindex: 0,
130
+ appendToBody: true,
131
+ format: (data:string) => (data),
132
+ popperOptions: () => ({ boundariesElement: 'body', gpuAcceleration: false }),
133
+ })
134
+
135
+ const emits = defineEmits<{
136
+ (e: 'update:value', val: string[] | null): void,
137
+ (e: 'input', val: string[] | null): void,
138
+ (e: 'change', value: (HalfYearItem & { startDate: string, endDate: string})[]): void
139
+ (e: 'show', value:undefined): void
140
+ (e: 'after-enter', value:undefined): void
141
+ (e: 'hide', value: undefined): void
142
+ (e: 'after-leave', value:undefined): void
143
+ (e: 'blur', value: any ): void
144
+ (e: 'focus', value: any): void
145
+ }>()
146
+
147
+ const now = new Date()
148
+ const nfDoubleQuatterPopoverVisible = ref(false)
149
+ // 开始
150
+ const startYear = ref(now.getFullYear())
151
+ const startHalfYear = ref<string[]>([])
152
+ // 结束
153
+ const endYear = ref(now.getFullYear() + 1)
154
+ const endHalfYear = ref<string[]>([])
155
+ // 整合后的月份
156
+ const halfYear = ref<HalfYearItem[]>([])
157
+ const nfDoubleHalfYearElDatePicker = ref()
158
+
159
+
160
+ const formatValue = computed(() => {
161
+ if (props.value) {
162
+ const startDate = new Date(props.value[0])
163
+ const endDate = new Date(props.value[1])
164
+ const startHalfyear = getHalfYear(startDate)
165
+ const endHalfyear = getHalfYear(endDate)
166
+ const res = [`${startDate.getFullYear()}-${startHalfyear === 2 ? '下半年' : '上半年'}`, `${endDate.getFullYear()}-${endHalfyear === 2 ? '下半年' : '上半年'}`]
167
+ if (props.format) {
168
+ return props.format(res)
169
+ }
170
+ return res
171
+ }
172
+ return null
173
+ })
174
+
175
+ const showValue = computed(() => {
176
+ if (props.value) {
177
+ const startDate = new Date(props.value[0])
178
+ const endDate = new Date(props.value[1])
179
+ return [`${startDate.getFullYear()}-${getHalfYear(startDate)}`, `${endDate.getFullYear()}-${getHalfYear(endDate)}`]
180
+ }
181
+ return null
182
+ })
183
+
184
+ watch(() => {
185
+ return formatValue.value
186
+ }, () => {
187
+ nextTick(() => {
188
+ if (nfDoubleHalfYearElDatePicker.value && formatValue.value) {
189
+ nfDoubleHalfYearElDatePicker.value.userInput = formatValue.value
190
+ }
191
+ })
192
+ }, {
193
+ deep: true,
194
+ immediate: true
195
+ })
196
+
197
+
198
+ watch(() => {
199
+ return nfDoubleHalfYearElDatePicker.value?.userInput
200
+ }, (current) => {
201
+ if (!current && formatValue.value && nfDoubleHalfYearElDatePicker.value) {
202
+ nextTick(() => {
203
+ nfDoubleHalfYearElDatePicker.value.userInput = formatValue.value
204
+ })
205
+ }
206
+ })
207
+
208
+
209
+ const handleOpenPicker = (instance) => {
210
+ let startDate = new Date()
211
+ let endDate = getNextYear(startDate)
212
+ if (props.value) {
213
+ startDate = new Date(props.value[0])
214
+ endDate = new Date(props.value[1])
215
+ startHalfYear.value = [`${startDate.getFullYear()}-${getHalfYear(startDate)}`]
216
+ endHalfYear.value = [`${endDate.getFullYear()}-${getHalfYear(endDate)}`]
217
+ }
218
+
219
+ startYear.value = startDate.getFullYear()
220
+ // 结束
221
+ endYear.value = endDate.getFullYear()
222
+ if (startYear.value >= endYear.value) {
223
+ endYear.value = startYear.value + 1
224
+ }
225
+ // 清空已选中
226
+ halfYear.value.splice(0, halfYear.value.length)
227
+ emits('focus', instance)
228
+ }
229
+ const handleStartYearChange = (year) => {
230
+ endYear.value = year + 1
231
+ }
232
+ const handleStartQuarterClick = (halfYearItem: HalfYearItem) => {
233
+ if (halfYear.value.length == 0) {
234
+ startHalfYear.value.splice(0, startHalfYear.value.length)
235
+ endHalfYear.value.splice(0, endHalfYear.value.length)
236
+ }
237
+
238
+ const index = startHalfYear.value.indexOf(halfYearItem.value)
239
+ if (index > -1) {
240
+ startHalfYear.value.splice(index, 1)
241
+ } else {
242
+ startHalfYear.value.push(halfYearItem.value)
243
+ }
244
+
245
+ halfYear.value.push(halfYearItem)
246
+
247
+ handleCheckQuarterRange()
248
+ }
249
+ const handleEndQuarterClick = (halfYearItem: HalfYearItem) => {
250
+ if (halfYear.value.length == 0) {
251
+ startHalfYear.value.splice(0, startHalfYear.value.length)
252
+ endHalfYear.value.splice(0, endHalfYear.value.length)
253
+ }
254
+ const index = endHalfYear.value.indexOf(halfYearItem.value)
255
+ if (index > -1) {
256
+ endHalfYear.value.splice(index, 1)
257
+ } else {
258
+ endHalfYear.value.push(halfYearItem.value)
259
+ }
260
+ halfYear.value.push(halfYearItem)
261
+ handleCheckQuarterRange()
262
+ }
263
+ const handleCheckQuarterRange = () => {
264
+ if (halfYear.value.length == 2) {
265
+ // 排序
266
+ halfYear.value.sort((a, b) => {
267
+ if (a.year == b.year) {
268
+ return a.halfYear - b.halfYear
269
+ } else {
270
+ return a.year - b.year
271
+ }
272
+ })
273
+ const result: (HalfYearItem & { startDate: string, endDate: string})[] = []
274
+ for (let item of halfYear.value) {
275
+ const months = getHarfYearOptionMonths(item.halfYear)
276
+ if(months.length) {
277
+ result.push({
278
+ ...item,
279
+ startDate: formatDate(startOf(new Date(item.year, months[0] - 1), 'month'), 'YYYY-MM-DD'),
280
+ endDate: formatDate(endOf(new Date(item.year, months[months.length - 1] - 1), 'month'), 'YYYY-MM-DD')
281
+ })
282
+ }
283
+ }
284
+ emits('update:value', [result[0].startDate, result[1].endDate])
285
+ emits('input', [result[0].startDate, result[1].endDate])
286
+ emits('change', result)
287
+ nfDoubleQuatterPopoverVisible.value = false
288
+ }
289
+ }
290
+ const handleEndYearChange = () => {
291
+ startYear.value = endYear.value - 1
292
+ }
293
+ const handleChange = (val) => {
294
+ if (!val) {
295
+ startHalfYear.value.splice(0, startHalfYear.value.length)
296
+ endHalfYear.value.splice(0, endHalfYear.value.length)
297
+ emits('update:value', null)
298
+ emits('input', null)
299
+ }
300
+ }
301
+ </script>
@@ -0,0 +1,108 @@
1
+ <template>
2
+ <div class="nf-double-half-year nf-half-year-picker-item">
3
+ <div class="nf-half-year-picker__header">
4
+ <i class="el-icon-d-arrow-left"
5
+ @click="handlePrevYear"
6
+ v-if="showLeft"></i>
7
+ <span v-else
8
+ class="empty-arrow"></span>
9
+ <div class="nf-half-year-picker__title">{{ year }}</div>
10
+ <i class="el-icon-d-arrow-right"
11
+ @click="handleNextYear"
12
+ v-if="showRight"></i>
13
+ <span v-else
14
+ class="empty-arrow"></span>
15
+ </div>
16
+ <div class="nf-half-year-picker__options">
17
+ <template v-for="item in options">
18
+ <div class="nf-half-year-picker__item"
19
+ v-bind:key="item.value"
20
+ :data-value="item.value"
21
+ @click="handleItemClick(item)"
22
+ :class="{
23
+ 'nf-half-year-picker__item__today': item.value == now_half_year,
24
+ 'nf-half-year-picker__item--active': halfYear.includes(item.value),
25
+ }">
26
+ <div class="nf-half-year-picker__item__label">{{ item.label }}</div>
27
+ </div>
28
+ </template>
29
+ </div>
30
+ </div>
31
+ </template>
32
+
33
+ <script lang="ts">
34
+ import { defineComponent } from 'vue-demi'
35
+
36
+ export default defineComponent({
37
+ name: 'nf-half-year-picker-item',
38
+ })
39
+ </script>
40
+ <script setup lang="ts">
41
+ import {
42
+ computed,
43
+ defineEmits,
44
+ defineProps,
45
+ ref
46
+ } from 'vue-demi'
47
+ import { halfYearOptions } from './config'
48
+ import { HalfYearItem } from './types'
49
+ import { getHalfYear } from './util'
50
+
51
+ const props = withDefaults(defineProps<{
52
+ // 当前年
53
+ year?: number,
54
+ // 当前半年
55
+ halfYear?: string[],
56
+ // 显示左边按钮
57
+ showLeft?: boolean,
58
+ // 显示右边按钮
59
+ showRight?: boolean
60
+ }>(), {
61
+ // 当前年
62
+ year: new Date().getFullYear(),
63
+ // 当前半年
64
+ halfYear: () => { return [] },
65
+ // 显示左边按钮
66
+ showLeft: true,
67
+ // 显示右边按钮
68
+ showRight: true
69
+ })
70
+
71
+
72
+ const emits = defineEmits<{
73
+ (e: 'on-half-year-click', val: HalfYearItem): void,
74
+ (e: 'update:year', value: number): void
75
+ (e: 'on-year-change', value: number): void
76
+ }>()
77
+ const now = new Date();
78
+ const now_year = ref(now.getFullYear());
79
+ const now_half_year = `${now_year.value}-${getHalfYear(now)}`
80
+ const options = computed(() => {
81
+ return halfYearOptions.map(item => {
82
+ return {
83
+ label: item.label,
84
+ value: `${props.year}-${item.value}`,
85
+ year: props.year,
86
+ halfYear: item.value,
87
+ }
88
+ })
89
+ })
90
+
91
+
92
+ const handleItemClick = (item) => {
93
+ emits('on-half-year-click', item);
94
+ }
95
+
96
+ const handlePrevYear = () => {
97
+ const year = props.year - 1;
98
+ emits('update:year', year);
99
+ emits('on-year-change', year);
100
+ }
101
+
102
+ const handleNextYear = () => {
103
+ const year = props.year + 1;
104
+ emits('update:year', year);
105
+ emits('on-year-change', year);
106
+ }
107
+ </script>
108
+
@@ -0,0 +1 @@
1
+ import '@94ai/nf-theme-chalk/lib/css/nf-double-half-year.css'
@@ -0,0 +1 @@
1
+ import '@94ai/nf-theme-chalk/lib/nf-double-half-year.scss'
@@ -0,0 +1,6 @@
1
+ export interface HalfYearItem {
2
+ label: '上半年' | '下半年',
3
+ value: string,
4
+ year: number,
5
+ halfYear: 1 | 2,
6
+ }
@@ -0,0 +1,58 @@
1
+ export function getHalfYear(date = new Date()) {
2
+ const currMonth = date.getMonth() + 1
3
+ return Math.floor((currMonth % 6 == 0 ? (currMonth / 6) : (currMonth / 6 + 1)))
4
+ }
5
+
6
+ export function getNextYear(date = new Date()) {
7
+ return new Date(date.setFullYear(date.getFullYear() + 1))
8
+ }
9
+
10
+ export function endOf(now = new Date(), unit) {
11
+ if (unit === 'year') {
12
+ return new Date(now.getFullYear(), 11, 31, 23, 59, 59, 999);
13
+ }
14
+ if (unit === 'month') {
15
+ return new Date(new Date(now.getFullYear(), now.getMonth() + 1, 1).getTime() - 1);
16
+ }
17
+ if (unit === 'week') {
18
+ return new Date(now.getFullYear(), now.getMonth(), now.getDate() + (6 - now.getDay()), 23, 59, 59, 999);
19
+ }
20
+ return new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999);
21
+ }
22
+
23
+ export function startOf(date, unit) {
24
+ const newDate = new Date(date)
25
+ if (unit === 'year') {
26
+ newDate.setMonth(0)
27
+ newDate.setDate(1)
28
+ newDate.setHours(0, 0, 0, 0)
29
+ } else if (unit === 'month') {
30
+ newDate.setDate(1)
31
+ newDate.setHours(0, 0, 0, 0)
32
+ } else if (unit === '') {
33
+ newDate.setHours(0, 0, 0, 0)
34
+ } else if (unit === 'hour') {
35
+ newDate.setMinutes(0, 0, 0)
36
+ } else if (unit === 'minute') {
37
+ newDate.setSeconds(0, 0)
38
+ } else if (unit === 'second') {
39
+ newDate.setMilliseconds(0)
40
+ }
41
+ return newDate
42
+ }
43
+
44
+ export function formatDate(date, format) {
45
+ const year = date.getFullYear()
46
+ const month = date.getMonth() + 1
47
+ const day = date.getDate()
48
+ const hours = date.getHours()
49
+ const minutes = date.getMinutes()
50
+ const seconds = date.getSeconds()
51
+ format = format.replace('YYYY', year)
52
+ format = format.replace('MM', String(month).padStart(2, '0'))
53
+ format = format.replace('DD', String(day).padStart(2, '0'))
54
+ format = format.replace('HH', String(hours).padStart(2, '0'))
55
+ format = format.replace('mm', String(minutes).padStart(2, '0'))
56
+ format = format.replace('ss', String(seconds).padStart(2, '0'))
57
+ return format
58
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@94ai/nf-double-half-year",
3
- "version": "3.1.37",
3
+ "version": "3.1.39",
4
4
  "description": "> TODO: description",
5
5
  "keywords": [],
6
6
  "author": "zoujiahe <zoujiahe@94ai.com>",
@@ -14,7 +14,7 @@
14
14
  "url": "http://94ai.gitlab.com/zoujiahe/common-ui.git"
15
15
  },
16
16
  "dependencies": {
17
- "@94ai/nf-theme-chalk": "^3.1.37",
17
+ "@94ai/nf-theme-chalk": "^1.0.0",
18
18
  "vue-demi": "^0.14.5"
19
19
  },
20
20
  "peerDependenciesMeta": {
@@ -30,5 +30,5 @@
30
30
  "types": "lib/index.d.ts",
31
31
  "main": "lib/nf-double-half-year.cjs.js",
32
32
  "module": "lib/nf-double-half-year.esm-bundler.js",
33
- "gitHead": "14dfc729b9988003d4686b414e1e9c0aaa7c4dcd"
33
+ "gitHead": "2b60696b405feafbbaeed385e5bcf666ceefbf2c"
34
34
  }