@94ai/nf-double-half-year 3.1.13

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,49 @@
1
+ import { HalfYearItem } from './types';
2
+ declare const _default: import("vue-demi").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
3
+ year?: number | undefined;
4
+ halfYear?: string[] | undefined;
5
+ showLeft?: boolean | undefined;
6
+ showRight?: boolean | undefined;
7
+ }>, {
8
+ year: number;
9
+ halfYear: () => never[];
10
+ showLeft: boolean;
11
+ showRight: boolean;
12
+ }>, {}, {}, {}, {}, import("vue/types/v3-component-options").ComponentOptionsMixin, import("vue/types/v3-component-options").ComponentOptionsMixin, {
13
+ "on-half-year-click": (val: HalfYearItem) => void;
14
+ "update:year": (value: number) => void;
15
+ "on-year-change": (value: number) => void;
16
+ }, string, Readonly<import("vue-demi").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
17
+ year?: number | undefined;
18
+ halfYear?: string[] | undefined;
19
+ showLeft?: boolean | undefined;
20
+ showRight?: boolean | undefined;
21
+ }>, {
22
+ year: number;
23
+ halfYear: () => never[];
24
+ showLeft: boolean;
25
+ showRight: boolean;
26
+ }>>>, {
27
+ year: number;
28
+ halfYear: string[];
29
+ showLeft: boolean;
30
+ showRight: boolean;
31
+ }>;
32
+ export default _default;
33
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
34
+ type __VLS_TypePropsToRuntimeProps<T> = {
35
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
36
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
37
+ } : {
38
+ type: import('vue').PropType<T[K]>;
39
+ required: true;
40
+ };
41
+ };
42
+ type __VLS_WithDefaults<P, D> = {
43
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_Prettify<P[K] & {
44
+ default: D[K];
45
+ }> : P[K];
46
+ };
47
+ type __VLS_Prettify<T> = {
48
+ [K in keyof T]: T[K];
49
+ } & {};
@@ -0,0 +1 @@
1
+
@@ -0,0 +1 @@
1
+ import '@94ai/nf-theme-chalk/lib/css/nf-double-half-year.css'
@@ -0,0 +1 @@
1
+
@@ -0,0 +1 @@
1
+ import '@94ai/nf-theme-chalk/lib/nf-double-half-year.scss'
package/lib/types.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export interface HalfYearItem {
2
+ label: '上半年' | '下半年';
3
+ value: string;
4
+ year: number;
5
+ halfYear: 1 | 2;
6
+ }
@@ -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,300 @@
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 '@94ai/common-utils'
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
+ rangeSeparator: '-',
113
+ readonly: false,
114
+ clearable: true,
115
+ startPlaceholder: '开始半年',
116
+ endPlaceholder: '结束半年',
117
+ disabled: false,
118
+ offset: 0,
119
+ prefixIcon: 'el-icon-date',
120
+ clearIcon: 'el-icon-circle-close',
121
+ transition: 'el-zoom-in-top',
122
+ placement: 'bottom-start',
123
+ popperClass: '',
124
+ trigger: 'click',
125
+ visibleArrow: true,
126
+ openDelay: undefined,
127
+ closeDelay: 200,
128
+ tabindex: 0,
129
+ appendToBody: true,
130
+ format: (data:string) => (data),
131
+ popperOptions: () => ({ boundariesElement: 'body', gpuAcceleration: false }),
132
+ })
133
+
134
+ const emits = defineEmits<{
135
+ (e: 'update:value', val: string[] | null): void,
136
+ (e: 'input', val: string[] | null): void,
137
+ (e: 'change', value: (HalfYearItem & { startDate: string, endDate: string})[]): void
138
+ (e: 'show', value:undefined): void
139
+ (e: 'after-enter', value:undefined): void
140
+ (e: 'hide', value: undefined): void
141
+ (e: 'after-leave', value:undefined): void
142
+ (e: 'blur', value: any ): void
143
+ (e: 'focus', value: any): void
144
+ }>()
145
+
146
+ const now = new Date()
147
+ const nfDoubleQuatterPopoverVisible = ref(false)
148
+ // 开始
149
+ const startYear = ref(now.getFullYear())
150
+ const startHalfYear = ref<string[]>([])
151
+ // 结束
152
+ const endYear = ref(now.getFullYear() + 1)
153
+ const endHalfYear = ref<string[]>([])
154
+ // 整合后的月份
155
+ const halfYear = ref<HalfYearItem[]>([])
156
+ const nfDoubleHalfYearElDatePicker = ref()
157
+
158
+
159
+ const formatValue = computed(() => {
160
+ if (props.value) {
161
+ const startDate = new Date(props.value[0])
162
+ const endDate = new Date(props.value[1])
163
+ const startHalfyear = getHalfYear(startDate)
164
+ const endHalfyear = getHalfYear(endDate)
165
+ const res = [`${startDate.getFullYear()}-${startHalfyear === 2 ? '下半年' : '上半年'}`, `${endDate.getFullYear()}-${endHalfyear === 2 ? '下半年' : '上半年'}`]
166
+ if (props.format) {
167
+ return props.format(res)
168
+ }
169
+ return res
170
+ }
171
+ return null
172
+ })
173
+
174
+ const showValue = computed(() => {
175
+ if (props.value) {
176
+ const startDate = new Date(props.value[0])
177
+ const endDate = new Date(props.value[1])
178
+ return [`${startDate.getFullYear()}-${getHalfYear(startDate)}`, `${endDate.getFullYear()}-${getHalfYear(endDate)}`]
179
+ }
180
+ return null
181
+ })
182
+
183
+ watch(() => {
184
+ return formatValue.value
185
+ }, () => {
186
+ nextTick(() => {
187
+ if (nfDoubleHalfYearElDatePicker.value && formatValue.value) {
188
+ nfDoubleHalfYearElDatePicker.value.userInput = formatValue.value
189
+ }
190
+ })
191
+ }, {
192
+ deep: true,
193
+ immediate: true
194
+ })
195
+
196
+
197
+ watch(() => {
198
+ return nfDoubleHalfYearElDatePicker.value?.userInput
199
+ }, (current) => {
200
+ if (!current && formatValue.value && nfDoubleHalfYearElDatePicker.value) {
201
+ nextTick(() => {
202
+ nfDoubleHalfYearElDatePicker.value.userInput = formatValue.value
203
+ })
204
+ }
205
+ })
206
+
207
+
208
+ const handleOpenPicker = (instance) => {
209
+ let startDate = new Date()
210
+ let endDate = getNextYear(startDate)
211
+ if (props.value) {
212
+ startDate = new Date(props.value[0])
213
+ endDate = new Date(props.value[1])
214
+ startHalfYear.value = [`${startDate.getFullYear()}-${getHalfYear(startDate)}`]
215
+ endHalfYear.value = [`${endDate.getFullYear()}-${getHalfYear(endDate)}`]
216
+ }
217
+
218
+ startYear.value = startDate.getFullYear()
219
+ // 结束
220
+ endYear.value = endDate.getFullYear()
221
+ if (startYear.value >= endYear.value) {
222
+ endYear.value = startYear.value + 1
223
+ }
224
+ // 清空已选中
225
+ halfYear.value.splice(0, halfYear.value.length)
226
+ emits('focus', instance)
227
+ }
228
+ const handleStartYearChange = (year) => {
229
+ endYear.value = year + 1
230
+ }
231
+ const handleStartQuarterClick = (halfYearItem: HalfYearItem) => {
232
+ if (halfYear.value.length == 0) {
233
+ startHalfYear.value.splice(0, startHalfYear.value.length)
234
+ endHalfYear.value.splice(0, endHalfYear.value.length)
235
+ }
236
+
237
+ const index = startHalfYear.value.indexOf(halfYearItem.value)
238
+ if (index > -1) {
239
+ startHalfYear.value.splice(index, 1)
240
+ } else {
241
+ startHalfYear.value.push(halfYearItem.value)
242
+ }
243
+
244
+ halfYear.value.push(halfYearItem)
245
+
246
+ handleCheckQuarterRange()
247
+ }
248
+ const handleEndQuarterClick = (halfYearItem: HalfYearItem) => {
249
+ if (halfYear.value.length == 0) {
250
+ startHalfYear.value.splice(0, startHalfYear.value.length)
251
+ endHalfYear.value.splice(0, endHalfYear.value.length)
252
+ }
253
+ const index = endHalfYear.value.indexOf(halfYearItem.value)
254
+ if (index > -1) {
255
+ endHalfYear.value.splice(index, 1)
256
+ } else {
257
+ endHalfYear.value.push(halfYearItem.value)
258
+ }
259
+ halfYear.value.push(halfYearItem)
260
+ handleCheckQuarterRange()
261
+ }
262
+ const handleCheckQuarterRange = () => {
263
+ if (halfYear.value.length == 2) {
264
+ // 排序
265
+ halfYear.value.sort((a, b) => {
266
+ if (a.year == b.year) {
267
+ return a.halfYear - b.halfYear
268
+ } else {
269
+ return a.year - b.year
270
+ }
271
+ })
272
+ const result: (HalfYearItem & { startDate: string, endDate: string})[] = []
273
+ for (let item of halfYear.value) {
274
+ const months = getHarfYearOptionMonths(item.halfYear)
275
+ if(months.length) {
276
+ result.push({
277
+ ...item,
278
+ startDate: formatDate(startOf(new Date(item.year, months[0] - 1), 'month'), 'YYYY-MM-DD'),
279
+ endDate: formatDate(endOf(new Date(item.year, months[months.length - 1] - 1), 'month'), 'YYYY-MM-DD')
280
+ })
281
+ }
282
+ }
283
+ emits('update:value', [result[0].startDate, result[1].endDate])
284
+ emits('input', [result[0].startDate, result[1].endDate])
285
+ emits('change', result)
286
+ nfDoubleQuatterPopoverVisible.value = false
287
+ }
288
+ }
289
+ const handleEndYearChange = () => {
290
+ startYear.value = endYear.value - 1
291
+ }
292
+ const handleChange = (val) => {
293
+ if (!val) {
294
+ startHalfYear.value.splice(0, startHalfYear.value.length)
295
+ endHalfYear.value.splice(0, endHalfYear.value.length)
296
+ emits('update:value', null)
297
+ emits('input', null)
298
+ }
299
+ }
300
+ </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 '@94ai/common-utils'
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
+ }
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@94ai/nf-double-half-year",
3
+ "version": "3.1.13",
4
+ "description": "> TODO: description",
5
+ "keywords": [],
6
+ "author": "zoujiahe <zoujiahe@94ai.com>",
7
+ "homepage": "https://oss.xccjh.top/common-ui/#/ai-index",
8
+ "license": "ISC",
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "http://94ai.gitlab.com/zoujiahe/common-ui.git"
15
+ },
16
+ "dependencies": {
17
+ "@94ai/common-utils": "^3.1.13",
18
+ "@94ai/nf-theme-chalk": "^3.1.13",
19
+ "vue-demi": "^0.14.5"
20
+ },
21
+ "peerDependenciesMeta": {
22
+ "@vue/composition-api": {
23
+ "optional": true
24
+ }
25
+ },
26
+ "peerDependencies": {
27
+ "@vue/composition-api": "^1.0.0-rc.1",
28
+ "element-ui": ">=2.13.2",
29
+ "vue": "^2.0.0 || >=3.0.0"
30
+ },
31
+ "types": "lib/index.d.ts",
32
+ "main": "lib/nf-double-half-year.cjs.js",
33
+ "module": "lib/nf-double-half-year.esm-bundler.js",
34
+ "gitHead": "a8c56183ccc8e979008e2d38bfde2d7d1448654c"
35
+ }
@@ -0,0 +1,8 @@
1
+ export default {
2
+ plugins: {
3
+ // 这个工具可以实现自动添加CSS3前缀
4
+ autoprefixer: {
5
+ overrideBrowserslist: ['last 5 version', '>1%', 'ie >=8']
6
+ },
7
+ },
8
+ }