@10yun/cv-mobile-ui 0.5.41 → 0.5.43

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@10yun/cv-mobile-ui",
3
- "version": "0.5.41",
3
+ "version": "0.5.43",
4
4
  "description": "十云cvjs移动端ui,适用uniapp",
5
5
  "author": "10yun",
6
6
  "license": "Apache-2.0",
@@ -6,7 +6,7 @@
6
6
  <view class="action text-blue" @tap="cancel">取消</view>
7
7
  <view class="action text-green" @tap="confirm">确定</view>
8
8
  </view>
9
- <view class="padding-xl">
9
+ <view class="cv-dialog-body" :style="bodyClass">
10
10
  <slot name="default" />
11
11
  </view>
12
12
  </view>
@@ -24,6 +24,10 @@ export default {
24
24
  show: {
25
25
  type: Boolean,
26
26
  default: false
27
+ },
28
+ bodyClass: {
29
+ type: [String],
30
+ default: ''
27
31
  }
28
32
  },
29
33
  watch: {},
@@ -162,10 +166,11 @@ export default {
162
166
  .text-blue {
163
167
  color: #0081ff;
164
168
  }
165
- .padding-xl {
169
+ .cv-dialog-body {
166
170
  padding-top: 10px;
167
171
  max-height: 500px;
168
172
  overflow: auto;
169
173
  text-align: left;
174
+ background-color: #fff;
170
175
  }
171
176
  </style>
@@ -5,7 +5,7 @@
5
5
  <view class="action text-blue" @tap="cancel">取消</view>
6
6
  <view class="action text-green" @tap="confirm">确定</view>
7
7
  </view>
8
- <view class="padding-xl">
8
+ <view class="cv-dialog-body" :style="bodyClass">
9
9
  <slot name="default" />
10
10
  </view>
11
11
  </view>
@@ -22,6 +22,10 @@ export default {
22
22
  show: {
23
23
  type: Boolean,
24
24
  default: false
25
+ },
26
+ bodyClass: {
27
+ type: [String],
28
+ default: ''
25
29
  }
26
30
  },
27
31
  watch: {},
@@ -150,9 +154,10 @@ export default {
150
154
  .text-blue {
151
155
  color: #0081ff;
152
156
  }
153
- .padding-xl {
157
+ .cv-dialog-body {
154
158
  padding: 10px;
155
159
  height: calc(100% - 45px - 20px);
156
160
  overflow: auto;
161
+ background-color: #fff;
157
162
  }
158
163
  </style>
@@ -5,25 +5,34 @@
5
5
  <view class="cv-dia-share-h1">分享</view>
6
6
  <view class="cv-dia-share-list">
7
7
  <view class="cv-dia-share-item">
8
+ <!-- <cv-icons type="base-weixin" size="30" /> -->
8
9
  <cv-icons type="base-weixin-solid" color="#00b96d" size="28" />
9
10
  <view class="cv-dia-share-ititle">微信好友</view>
10
11
  </view>
11
12
  <view class="cv-dia-share-item">
12
13
  <cv-icons type="base-pengyouquan" color="#00b96d" size="28" />
13
- <view class="cv-dia-share-ititle">朋友圈</view>
14
+ <view class="cv-dia-share-ititle">微信朋友圈</view>
14
15
  </view>
15
16
  <view class="cv-dia-share-item">
17
+ <!-- <cv-icons type="base-sina-weibo" size="30" /> -->
16
18
  <cv-icons type="base-sina-weibo-solid" color="#fc5056" size="28" />
17
19
  <view class="cv-dia-share-ititle">新浪微博</view>
18
20
  </view>
19
21
  <view class="cv-dia-share-item">
22
+ <!-- <cv-icons type="base-QQ" size="30" /> -->
20
23
  <cv-icons type="base-QQ-solid" color="#00a6e2" size="28" />
21
- <view class="cv-dia-share-ititle">QQ</view>
24
+ <view class="cv-dia-share-ititle">QQ好友</view>
22
25
  </view>
23
26
  </view>
24
27
  <view class="cv-dia-share-clear-btn" @tap="shareDiaHide">取消</view>
25
28
  </view>
26
29
  </view>
30
+ <!-- <uni-popup :ref="localRefName" type="bottom">
31
+ <view class="share-tck-wrap">
32
+ <view class="share-tck-title">分享到</view>
33
+ <view class="share-tck-content"></view>
34
+ </view>
35
+ </uni-popup> -->
27
36
  </template>
28
37
  <script>
29
38
  import mpMixin from '../../libs/mixin/mpMixin.js';
@@ -33,29 +42,52 @@ export default {
33
42
  name: 'cvDialogShare',
34
43
  emits: ['input', 'update:modelValue'],
35
44
  props: {
36
- value: {
45
+ modelValue: {
37
46
  type: [String, Number],
38
47
  default: 0
39
48
  }
40
49
  },
41
50
  watch: {
42
- value(newVal) {
43
- if (newVal == 1) {
51
+ modelValue(newVal) {
52
+ if (newVal) {
44
53
  this.shareClass = 'show';
54
+ this.localIsShow = true;
45
55
  } else {
46
56
  this.shareClass = 'hide';
57
+ this.localIsShow = false;
47
58
  }
48
- this.localIsShow = newVal || 0;
49
59
  }
50
60
  },
51
61
  data() {
52
62
  return {
53
63
  shareClass: '',
54
- localIsShow: 0
64
+ localRefName: '',
65
+ localIsShow: false,
66
+ shareList: [
67
+ // { text: '微信', icon: 'grid-2.png', name: 'wx' },
68
+ // { text: '支付宝', icon: 'grid-8.png', name: 'wx' },
69
+ // { text: 'QQ', icon: 'gird-3.png', name: 'qq' },
70
+ // { text: '新浪', icon: 'grid-1.png', name: 'sina' },
71
+ // { text: '百度', icon: 'grid-7.png', name: 'copy' },
72
+ // { text: '其他', icon: 'grid-5.png', name: 'more' }
73
+ ]
55
74
  };
56
75
  },
57
- created() {},
76
+ created() {
77
+ this.localRefName = this._getRefName() || 'refModalTklBuy';
78
+ },
58
79
  methods: {
80
+ _getRefName() {
81
+ // #ifdef VUE3
82
+ return this.$.vnode.ref['r'];
83
+ // #endif
84
+ // #ifndef VUE3
85
+ return this.$options?._parentVnode.data?.ref;
86
+ // #endif
87
+ },
88
+ open(options) {
89
+ this.$refs[this.localRefName].open(options);
90
+ },
59
91
  discard() {},
60
92
  //分享
61
93
  // share(){
@@ -64,13 +96,13 @@ export default {
64
96
  // 分享
65
97
  shareDiaOpen() {
66
98
  this.shareClass = 'show';
67
- this.localIsShow = 1;
99
+ this.localIsShow = true;
68
100
  this.$emit('input', this.localIsShow);
69
101
  this.$emit('update:modelValue', this.localIsShow);
70
102
  },
71
103
  shareDiaHide() {
72
104
  this.shareClass = 'hide';
73
- this.localIsShow = 0;
105
+ this.localIsShow = false;
74
106
  setTimeout(() => {
75
107
  this.shareClass = 'none';
76
108
  }, 150);
@@ -95,7 +127,7 @@ export default {
95
127
  width: 100%;
96
128
  height: 100%;
97
129
  top: 0;
98
- z-index: 11;
130
+ z-index: 999;
99
131
  }
100
132
 
101
133
  .cv-dia-share-mask {
@@ -103,12 +135,13 @@ export default {
103
135
  }
104
136
 
105
137
  .cv-dia-share-layer {
106
- width: 92%;
138
+ width: 100%;
107
139
  position: fixed;
108
- z-index: 9999;
140
+ z-index: 999;
109
141
  padding: 0 4%;
110
142
  bottom: 0;
111
- background-color: rgba(255, 255, 255, 0.9);
143
+ /* background-color: rgba(255, 255, 255, 0.9); */
144
+ background-color: #fff;
112
145
  }
113
146
 
114
147
  .cv-dia-share-layer {
@@ -0,0 +1,202 @@
1
+ <template>
2
+ <view
3
+ v-if="show"
4
+ class="mask"
5
+ @click="toggleMask"
6
+ @touchmove.stop.prevent="stopPrevent"
7
+ :style="{ backgroundColor: backgroundColor }"
8
+ >
9
+ <view
10
+ class="mask-content"
11
+ @click.stop.prevent="stopPrevent"
12
+ :style="[
13
+ {
14
+ height: config.height,
15
+ transform: transform
16
+ }
17
+ ]"
18
+ >
19
+ <scroll-view class="view-content" scroll-y>
20
+ <view class="share-header">分享到</view>
21
+ <view class="share-list">
22
+ <view v-for="(item, index) in shareList" :key="index" class="share-item" @click="shareToFriend(item.text)">
23
+ <image :src="item.icon" mode=""></image>
24
+ <text>{{ item.text }}</text>
25
+ </view>
26
+ </view>
27
+ </scroll-view>
28
+ <view class="bottom b-t" @click="toggleMask">取消</view>
29
+ </view>
30
+ </view>
31
+ </template>
32
+
33
+ <script>
34
+ export default {
35
+ data() {
36
+ return {
37
+ transform: 'translateY(50vh)',
38
+ timer: 0,
39
+ backgroundColor: 'rgba(0,0,0,0)',
40
+ show: false,
41
+ config: {}
42
+ };
43
+ },
44
+ props: {
45
+ contentHeight: {
46
+ type: Number,
47
+ default: 0
48
+ },
49
+ //是否是tabbar页面
50
+ hasTabbar: {
51
+ type: Boolean,
52
+ default: false
53
+ },
54
+ shareList: {
55
+ type: Array,
56
+ default: () => {
57
+ return [];
58
+ }
59
+ }
60
+ },
61
+ created() {
62
+ const height = uni.rpx2px(this.contentHeight) + 'px';
63
+ this.config = {
64
+ height: height,
65
+ transform: `translateY(${height})`,
66
+ backgroundColor: 'rgba(0,0,0,.4)'
67
+ };
68
+ this.transform = this.config.transform;
69
+ },
70
+ methods: {
71
+ toggleMask() {
72
+ //防止高频点击
73
+ if (this.timer == 1) {
74
+ return;
75
+ }
76
+ this.timer = 1;
77
+ setTimeout(() => {
78
+ this.timer = 0;
79
+ }, 500);
80
+
81
+ if (this.show) {
82
+ this.transform = this.config.transform;
83
+ this.backgroundColor = 'rgba(0,0,0,0)';
84
+ setTimeout(() => {
85
+ this.show = false;
86
+ this.hasTabbar && uni.showTabBar();
87
+ }, 200);
88
+ return;
89
+ }
90
+
91
+ this.show = true;
92
+ //等待mask重绘完成执行
93
+ if (this.hasTabbar) {
94
+ uni.hideTabBar({
95
+ success: () => {
96
+ setTimeout(() => {
97
+ this.backgroundColor = this.config.backgroundColor;
98
+ this.transform = 'translateY(0px)';
99
+ }, 10);
100
+ }
101
+ });
102
+ } else {
103
+ setTimeout(() => {
104
+ this.backgroundColor = this.config.backgroundColor;
105
+ this.transform = 'translateY(0px)';
106
+ }, 10);
107
+ }
108
+ },
109
+ //防止冒泡和滚动穿透
110
+ stopPrevent() {},
111
+ //分享操作
112
+ shareToFriend(type) {
113
+ this.$api.msg(`分享给${type}`);
114
+ this.toggleMask();
115
+ }
116
+ }
117
+ };
118
+ </script>
119
+
120
+ <style>
121
+ .mask {
122
+ position: fixed;
123
+ left: 0;
124
+ top: 0;
125
+ right: 0;
126
+ bottom: 0;
127
+ display: flex;
128
+ justify-content: center;
129
+ align-items: flex-end;
130
+ z-index: 998;
131
+ transition: 0.3s;
132
+ }
133
+ .mask .bottom {
134
+ position: absolute;
135
+ left: 0;
136
+ bottom: 0;
137
+ display: flex;
138
+ justify-content: center;
139
+ align-items: center;
140
+ width: 100%;
141
+ height: 90rpx;
142
+ background: #fff;
143
+ z-index: 9;
144
+ font-size: 30rpx;
145
+ color: #303133;
146
+ }
147
+ .mask-content {
148
+ width: 100%;
149
+ height: 580rpx;
150
+ transition: 0.3s;
151
+ background: #fff;
152
+ }
153
+ .mask-content.has-bottom {
154
+ padding-bottom: 90rpx;
155
+ }
156
+ .mask-content .view-content {
157
+ height: 100%;
158
+ }
159
+ .share-header {
160
+ height: 110rpx;
161
+ font-size: 30rpx;
162
+ color: #303133;
163
+ display: flex;
164
+ align-items: center;
165
+ justify-content: center;
166
+ padding-top: 10rpx;
167
+ }
168
+ .share-header:before,
169
+ .share-header:after {
170
+ content: '';
171
+ width: 240rpx;
172
+ heighg: 0;
173
+ border-top: 1px solid #e4e7ed;
174
+ transform: scaleY(0.5);
175
+ margin-right: 30rpx;
176
+ }
177
+ .share-header:after {
178
+ margin-left: 30rpx;
179
+ margin-right: 0;
180
+ }
181
+ .share-list {
182
+ display: flex;
183
+ flex-wrap: wrap;
184
+ }
185
+ .share-item {
186
+ min-width: 33.33%;
187
+ display: flex;
188
+ flex-direction: column;
189
+ justify-content: center;
190
+ align-items: center;
191
+ height: 180rpx;
192
+ }
193
+ .share-item image {
194
+ width: 80rpx;
195
+ height: 80rpx;
196
+ margin-bottom: 16rpx;
197
+ }
198
+ .share-item text {
199
+ font-size: 28rpx;
200
+ color: #606266;
201
+ }
202
+ </style>
@@ -0,0 +1,120 @@
1
+ <template>
2
+ <view class="container">
3
+ <text class="tui-share-title">分享到</text>
4
+ <view class="tui-share-list">
5
+ <view class="tui-share-item" hover-class="tui-hover" :hover-stay-time="150" v-for="(item, index) in shareList" :key="index">
6
+ <view class="tui-share-icon"><image :src="'/static/images/share/' + item.icon" class="tui-icon-app"></image></view>
7
+ <text class="tui-share-text">{{ item.name }}</text>
8
+ </view>
9
+ </view>
10
+ <view class="tui-btn-cancel" @tap="shareCancel"><text class="tui-btn-text">取消</text></view>
11
+ </view>
12
+ </template>
13
+ <script>
14
+ export default {
15
+ data() {
16
+ return {
17
+ //"QQ","微信","朋友圈","新浪微博"
18
+ shareList: [
19
+ { name: 'QQ', icon: 'icon_qq.png' },
20
+ { name: '微信', icon: 'icon_wechat.png' },
21
+ { name: '朋友圈', icon: 'icon_moments.png' },
22
+ { name: '新浪微博', icon: 'icon_sina.png' }
23
+ ]
24
+ };
25
+ },
26
+ created() {
27
+ const vm = this;
28
+ // uni.$on('page-share', (data) => {
29
+ // vm.page = data.page;
30
+ // })
31
+ },
32
+ beforeDestroy() {
33
+ //uni.$off('page-share')
34
+ },
35
+ methods: {
36
+ shareCancel() {
37
+ const subNVue = uni.getCurrentSubNVue();
38
+ subNVue.hide('slide-out-bottom', 250);
39
+ }
40
+ }
41
+ };
42
+ </script>
43
+ <style scoped>
44
+ .container {
45
+ padding: 0;
46
+ background-color: #e8e8e8;
47
+ }
48
+
49
+ .tui-share-title {
50
+ font-size: 26rpx;
51
+ color: #7e7e7e;
52
+ text-align: center;
53
+ line-height: 26rpx;
54
+ padding-top: 30rpx;
55
+ padding-bottom: 80rpx;
56
+ }
57
+
58
+ .tui-share-list {
59
+ width: 750rpx;
60
+ padding-left: 36rpx;
61
+ padding-right: 36rpx;
62
+ flex-direction: row;
63
+ align-items: center;
64
+ justify-content: space-between;
65
+ }
66
+
67
+ .tui-share-item {
68
+ width: 126rpx;
69
+ align-items: center;
70
+ }
71
+
72
+ .tui-share-item:active {
73
+ opacity: 0.6;
74
+ }
75
+
76
+ .tui-share-icon {
77
+ align-items: center;
78
+ justify-content: center;
79
+ background-color: #ffffff;
80
+ height: 126rpx;
81
+ width: 126rpx;
82
+ border-radius: 32rpx;
83
+ }
84
+
85
+ .tui-icon-app {
86
+ height: 68rpx;
87
+ width: 68rpx;
88
+ }
89
+
90
+ .tui-share-text {
91
+ font-size: 24rpx;
92
+ line-height: 24rpx;
93
+ color: #7e7e7e;
94
+ padding-top: 20rpx;
95
+ padding-bottom: 20rpx;
96
+ }
97
+
98
+ .tui-btn-cancel {
99
+ width: 750rpx;
100
+ height: 100rpx;
101
+ position: fixed;
102
+ left: 0;
103
+ bottom: 0;
104
+ align-items: center;
105
+ justify-content: center;
106
+ background-color: #f6f6f6;
107
+ /* border-top-width: 1rpx;
108
+ border-top-style: solid;
109
+ border-top-color: #eaeef1; */
110
+ }
111
+
112
+ .tui-btn-cancle:active {
113
+ background-color: #eee;
114
+ }
115
+
116
+ .tui-btn-text {
117
+ font-size: 34rpx;
118
+ color: #3e3e3e;
119
+ }
120
+ </style>
@@ -0,0 +1,139 @@
1
+ <template>
2
+ <view class="uni-popup-share">
3
+ <view class="uni-share-title">
4
+ <text class="uni-share-title-text">{{ title }}</text>
5
+ </view>
6
+ <view class="uni-share-content">
7
+ <view class="uni-share-content-box">
8
+ <view class="uni-share-content-item" v-for="(item, index) in bottomData" :key="index" @click.stop="select(item, index)">
9
+ <image class="uni-share-image" :src="item.icon" mode="aspectFill"></image>
10
+ <text class="uni-share-text">{{ item.text }}</text>
11
+ </view>
12
+ </view>
13
+ </view>
14
+ <view class="uni-share-button-box">
15
+ <button class="uni-share-button" @click="close">取消</button>
16
+ </view>
17
+ </view>
18
+ </template>
19
+
20
+ <script>
21
+ export default {
22
+ data() {
23
+ return {
24
+ bottomData: [
25
+ { text: '微信', icon: 'grid-2.png', name: 'wx' },
26
+ { text: '支付宝', icon: 'grid-8.png', name: 'wx' },
27
+ { text: 'QQ', icon: 'gird-3.png', name: 'qq' },
28
+ { text: '新浪', icon: 'grid-1.png', name: 'sina' },
29
+ { text: '百度', icon: 'grid-7.png', name: 'copy' },
30
+ { text: '其他', icon: 'grid-5.png', name: 'more' }
31
+ ]
32
+ };
33
+ },
34
+ created() {},
35
+ methods: {
36
+ /**
37
+ * 选择内容
38
+ */
39
+ select(item, index) {
40
+ this.$emit(
41
+ 'select',
42
+ {
43
+ item,
44
+ index
45
+ },
46
+ () => {
47
+ this.popup.close();
48
+ }
49
+ );
50
+ },
51
+ /**
52
+ * 关闭窗口
53
+ */
54
+ close() {
55
+ this.popup.close();
56
+ }
57
+ }
58
+ };
59
+ </script>
60
+ <style scoped>
61
+ .uni-popup-share {
62
+ background-color: #fff;
63
+ }
64
+ .uni-share-title {
65
+ /* #ifndef APP-NVUE */
66
+ display: flex;
67
+ /* #endif */
68
+ flex-direction: row;
69
+ align-items: center;
70
+ justify-content: center;
71
+ height: 40px;
72
+ }
73
+ .uni-share-title-text {
74
+ font-size: 14px;
75
+ color: #666;
76
+ }
77
+ .uni-share-content {
78
+ /* #ifndef APP-NVUE */
79
+ display: flex;
80
+ /* #endif */
81
+ flex-direction: row;
82
+ justify-content: center;
83
+ padding-top: 10px;
84
+ }
85
+
86
+ .uni-share-content-box {
87
+ /* #ifndef APP-NVUE */
88
+ display: flex;
89
+ /* #endif */
90
+ flex-direction: row;
91
+ flex-wrap: wrap;
92
+ width: 360px;
93
+ }
94
+
95
+ .uni-share-content-item {
96
+ width: 90px;
97
+ /* #ifndef APP-NVUE */
98
+ display: flex;
99
+ /* #endif */
100
+ flex-direction: column;
101
+ justify-content: center;
102
+ padding: 10px 0;
103
+ align-items: center;
104
+ }
105
+
106
+ .uni-share-content-item:active {
107
+ background-color: #f5f5f5;
108
+ }
109
+
110
+ .uni-share-image {
111
+ width: 30px;
112
+ height: 30px;
113
+ }
114
+
115
+ .uni-share-text {
116
+ margin-top: 10px;
117
+ font-size: 14px;
118
+ color: #3b4144;
119
+ }
120
+
121
+ .uni-share-button-box {
122
+ /* #ifndef APP-NVUE */
123
+ display: flex;
124
+ /* #endif */
125
+ flex-direction: row;
126
+ padding: 10px 15px;
127
+ }
128
+
129
+ .uni-share-button {
130
+ flex: 1;
131
+ border-radius: 50px;
132
+ color: #666;
133
+ font-size: 16px;
134
+ }
135
+
136
+ .uni-share-button::after {
137
+ border-radius: 50px;
138
+ }
139
+ </style>
@@ -0,0 +1,81 @@
1
+ <template>
2
+ <img class="cv-svgs" :src="typeUrl" mode="widthFix" :style="iconStyle" @click="$emit('click', $event)" />
3
+ </template>
4
+ <script>
5
+ export default {
6
+ name: 'CcGgIcons',
7
+ emits: ['click'],
8
+ props: {
9
+ type: {
10
+ type: [String],
11
+ required: true,
12
+ validator(value) {
13
+ // 这里可以添加更严格的验证,比如检查是否是有效的 svgs 图标名称
14
+ return typeof value === 'string' && value.trim().length > 0;
15
+ }
16
+ },
17
+ size: {
18
+ type: [Number, String],
19
+ default: 24
20
+ // validator(value) {
21
+ // const size = Number(value);
22
+ // return !isNaN(size) && size > 0;
23
+ // }
24
+ },
25
+ color: {
26
+ type: String,
27
+ default: 'currentColor'
28
+ },
29
+ hoverColor: {
30
+ type: String,
31
+ default: ''
32
+ },
33
+ hoverEffect: {
34
+ type: Boolean,
35
+ default: false
36
+ }
37
+ },
38
+ computed: {
39
+ typeUrl() {
40
+ return 'https://10ui.cn/svg/' + this.type + '.svg';
41
+ },
42
+ sizeLast() {
43
+ if (this.size.includes('px') || this.size.includes('rpx')) {
44
+ return this.size;
45
+ } else {
46
+ return parseFloat(this.size) + 'px';
47
+ }
48
+ },
49
+ colorFilter() {
50
+ if (!this.color || this.color === 'currentColor') return '';
51
+ // 将颜色转换为滤镜(近似效果)
52
+ const hex = this.color.replace('#', '');
53
+ const r = parseInt(hex.substring(0, 2), 16);
54
+ const g = parseInt(hex.substring(2, 4), 16);
55
+ const b = parseInt(hex.substring(4, 6), 16);
56
+ return `filter: invert(1) sepia(1) saturate(10000%) hue-rotate(${this.calculateHue(r, g, b)}deg)`;
57
+ },
58
+ iconStyle() {
59
+ return {
60
+ width: this.sizeLast,
61
+ height: this.sizeLast,
62
+ color: this.color,
63
+ filter: this.colorFilter
64
+ // display: 'inline-block',
65
+ // verticalAlign: 'middle',
66
+ // cursor: this.$attrs.click ? 'pointer' : 'inherit'
67
+ };
68
+ }
69
+ },
70
+ methods: {
71
+ calculateHue(r, g, b) {
72
+ // 复杂计算颜色到 hue-rotate 的映射(简化版)
73
+ return 0; // 实际需要完整算法
74
+ }
75
+ }
76
+ };
77
+ </script>
78
+ <style>
79
+ .cv-svgs {
80
+ }
81
+ </style>
@@ -1,17 +1,82 @@
1
1
  /**
2
- * 判断是否在日期范围内
3
- * @param {*} monthStr
4
- * @param {*} startDateStr
5
- * @param {*} endDateStr
6
- * @returns
2
+ * 判断某个时间(年/月/日/时分秒)是否完全包含在范围内
3
+ * @param {string|Date} inputStr
4
+ * - 可为 "2020"、"2020-07"、"2020-07-25"、"2020-07-25 12:00:00"
5
+ * @param {string|Date} startDateStr - 开始时间
6
+ * @param {string|Date} endDateStr - 结束时间
7
+ * @returns {boolean}
7
8
  */
8
- export function cc_date_in_scope(monthStr, startDateStr, endDateStr) {
9
- // 将月份字符串转换为日期对象(当月第一天)
10
- const [year, month] = monthStr.split('-').map(Number);
11
- const targetDate = new Date(year, month - 1, 1); // 月份从0开始
12
- // 将日期字符串转换为日期对象
9
+ export function cc_date_time_in_scope(inputStr, startDateStr, endDateStr) {
13
10
  const startDate = new Date(startDateStr);
14
11
  const endDate = new Date(endDateStr);
15
- // 比较日期
16
- return targetDate >= startDate && targetDate <= endDate;
12
+ if (isNaN(startDate) || isNaN(endDate)) return false;
13
+
14
+ let inputStart, inputEnd;
15
+
16
+ if (typeof inputStr === 'string') {
17
+ if (/^\d{4}$/.test(inputStr)) {
18
+ // 年份:整年
19
+ inputStart = new Date(`${inputStr}-01-01T00:00:00`);
20
+ inputEnd = new Date(`${inputStr}-12-31T23:59:59`);
21
+ } else if (/^\d{4}-\d{2}$/.test(inputStr)) {
22
+ // 月份:整月
23
+ const [year, month] = inputStr.split('-').map(Number);
24
+ inputStart = new Date(year, month - 1, 1, 0, 0, 0);
25
+ inputEnd = new Date(year, month, 0, 23, 59, 59);
26
+ } else if (/^\d{4}-\d{2}-\d{2}$/.test(inputStr)) {
27
+ // 日期:整天
28
+ inputStart = new Date(`${inputStr}T00:00:00`);
29
+ inputEnd = new Date(`${inputStr}T23:59:59`);
30
+ } else {
31
+ // 时间点
32
+ const point = new Date(inputStr);
33
+ if (isNaN(point)) return false;
34
+ inputStart = point;
35
+ inputEnd = point;
36
+ }
37
+ } else if (inputStr instanceof Date) {
38
+ inputStart = inputStr;
39
+ inputEnd = inputStr;
40
+ } else {
41
+ return false;
42
+ }
43
+
44
+ return inputStart >= startDate && inputEnd <= endDate;
45
+ }
46
+ /**
47
+ * 判断某个月是否与指定时间范围有交集
48
+ * @param {string|Date} inputStr
49
+ * - 可为 "2020"、"2020-07"、"2020-07-25"、"2020-07-25 12:00:00"
50
+ * @param {string|Date} startDateStr - 开始时间
51
+ * @param {string|Date} endDateStr - 结束时间
52
+ * @returns {boolean}
53
+ */
54
+ export function cc_date_time_overlap_scope(inputStr, startDateStr, endDateStr) {
55
+ const startDate = new Date(startDateStr);
56
+ const endDate = new Date(endDateStr);
57
+ if (isNaN(startDate) || isNaN(endDate)) {
58
+ return false;
59
+ }
60
+ let inputStart, inputEnd;
61
+ if (/^\d{4}$/.test(inputStr)) {
62
+ // 年份:2025 → 2025-01-01 ~ 2025-12-31 23:59:59
63
+ inputStart = new Date(`${inputStr}-01-01T00:00:00`);
64
+ inputEnd = new Date(`${inputStr}-12-31T23:59:59`);
65
+ } else if (/^\d{4}-\d{2}$/.test(inputStr)) {
66
+ // 月份:2025-07 → 2025-07-01 ~ 2025-07-31
67
+ const [year, month] = inputStr.split('-').map(Number);
68
+ inputStart = new Date(year, month - 1, 1, 0, 0, 0);
69
+ inputEnd = new Date(year, month, 0, 23, 59, 59); // 当月最后一天
70
+ } else if (/^\d{4}-\d{2}-\d{2}$/.test(inputStr)) {
71
+ // 日期:2025-07-25 → 当天整天
72
+ inputStart = new Date(`${inputStr}T00:00:00`);
73
+ inputEnd = new Date(`${inputStr}T23:59:59`);
74
+ } else {
75
+ // 其他格式:默认作为精确时间点
76
+ const point = new Date(inputStr);
77
+ if (isNaN(point)) return false;
78
+ inputStart = point;
79
+ inputEnd = point;
80
+ }
81
+ return inputEnd >= startDate && inputStart <= endDate;
17
82
  }