Commit 50776ea23908d9cf86eacddd8eef7f4b3e74d38a
Merge branch 'dev-ft' into 'main'
fix:修改通知和告警筛选问题 See merge request huang/thingskit-app!37
Showing
23 changed files
with
3938 additions
and
140 deletions
| 1 | /** | 1 | /** |
| 2 | * 需要修改 | 2 | * 需要修改 |
| 3 | */ | 3 | */ |
| 4 | -export const appId = 'wx0ad61d7bf6808e02' | ||
| 5 | -export const appSecrect = '74d43eca92c728b56d6e624bd0b146b8' | 4 | +const APPID = 'wxd5d018355f38262b' |
| 5 | +const APPSECRECT = 'f6975fcc2248b1de2fdd2e40e9d21476' | ||
| 6 | + | ||
| 7 | +module.exports = { | ||
| 8 | + appId: APPID, | ||
| 9 | + appSecrect: APPSECRECT, | ||
| 10 | +}; |
| @@ -94,10 +94,10 @@ | @@ -94,10 +94,10 @@ | ||
| 94 | </mescroll-body> | 94 | </mescroll-body> |
| 95 | <!-- 自带分页组件 --> | 95 | <!-- 自带分页组件 --> |
| 96 | <view style="height: 20rpx"></view> | 96 | <view style="height: 20rpx"></view> |
| 97 | - <!-- 告警筛选 --> | 97 | + <!-- 告警筛选--> |
| 98 | <u-popup @close="close" closeable bgColor="transparent" :overlay="true" :show="show" mode="bottom"> | 98 | <u-popup @close="close" closeable bgColor="transparent" :overlay="true" :show="show" mode="bottom"> |
| 99 | <view class="popup-page"> | 99 | <view class="popup-page"> |
| 100 | - <view class="popup-text"><text class="text">筛选条件</text></view> | 100 | + <view class="popup-text"><text class="text">告警筛选</text></view> |
| 101 | <view class="popup-alarm-page u-flex"> | 101 | <view class="popup-alarm-page u-flex"> |
| 102 | <view> | 102 | <view> |
| 103 | <view class="popup-alarm-text"><text class="text">告警状态</text></view> | 103 | <view class="popup-alarm-text"><text class="text">告警状态</text></view> |
| @@ -105,61 +105,66 @@ | @@ -105,61 +105,66 @@ | ||
| 105 | <view | 105 | <view |
| 106 | class="alarm-text" | 106 | class="alarm-text" |
| 107 | @click="getAlertStatus(item, index)" | 107 | @click="getAlertStatus(item, index)" |
| 108 | - :style="[index == current1 ? { background: '#377DFF' } : { background: '#F6F6F6' }]" | 108 | + :style="[index == current1 ? { background: 'rgba(55, 125, 255, 0.05)', border: '1rpx solid rgba(55, 125, 255, 0.3)' } : { background: '#F6F6F6' }]" |
| 109 | v-for="(item, index) in alertStatus" | 109 | v-for="(item, index) in alertStatus" |
| 110 | :key="index" | 110 | :key="index" |
| 111 | > | 111 | > |
| 112 | - <text class="text">{{ item.name }}</text> | 112 | + <text :class="[index == current1 ? 'select-text' : 'un-select-text']" class="text">{{ item.name }}</text> |
| 113 | </view> | 113 | </view> |
| 114 | </view> | 114 | </view> |
| 115 | - <view style="margin-top: 120rpx;"> | 115 | + <view style="margin-top: 169rpx;"> |
| 116 | <view class="popup-alarm-text"><text class="text">设备类型</text></view> | 116 | <view class="popup-alarm-text"><text class="text">设备类型</text></view> |
| 117 | <view class="u-flex popup-alarm-child"> | 117 | <view class="u-flex popup-alarm-child"> |
| 118 | <view | 118 | <view |
| 119 | class="alarm-text" | 119 | class="alarm-text" |
| 120 | @click="getTypeStatus(item, index)" | 120 | @click="getTypeStatus(item, index)" |
| 121 | - :style="[index == current2 ? { background: '#377DFF' } : { background: '#F6F6F6' }]" | 121 | + :style="[ |
| 122 | + index == current2 ? { background: 'rgba(55, 125, 255, 0.05)', border: '1rpx solid rgba(55, 125, 255, 0.3)' } : { background: '#F6F6F6' } | ||
| 123 | + ]" | ||
| 122 | v-for="(item, index) in deviceType" | 124 | v-for="(item, index) in deviceType" |
| 123 | :key="index" | 125 | :key="index" |
| 124 | > | 126 | > |
| 125 | - <text class="text">{{ item.name }}</text> | 127 | + <text :class="[index == current2 ? 'select-text' : 'un-select-text']" class="text">{{ item.name }}</text> |
| 126 | </view> | 128 | </view> |
| 127 | </view> | 129 | </view> |
| 128 | 130 | ||
| 129 | - <view style="margin-top: 120rpx;"> | 131 | + <view style="margin-top: 169rpx;"> |
| 130 | <view class="popup-alarm-text"><text class="text">告警等级</text></view> | 132 | <view class="popup-alarm-text"><text class="text">告警等级</text></view> |
| 131 | <view class="u-flex popup-alarm-child"> | 133 | <view class="u-flex popup-alarm-child"> |
| 132 | <view | 134 | <view |
| 133 | class="alarm-text" | 135 | class="alarm-text" |
| 134 | @click="getLevelStatus(item, index)" | 136 | @click="getLevelStatus(item, index)" |
| 135 | - :style="[index == current3 ? { background: '#377DFF' } : { background: '#F6F6F6' }]" | 137 | + :style="[ |
| 138 | + index == current3 ? { background: 'rgba(55, 125, 255, 0.05)', border: '1rpx solid rgba(55, 125, 255, 0.3)' } : { background: '#F6F6F6' } | ||
| 139 | + ]" | ||
| 136 | v-for="(item, index) in alertLevel" | 140 | v-for="(item, index) in alertLevel" |
| 137 | :key="index" | 141 | :key="index" |
| 138 | > | 142 | > |
| 139 | - <text class="text">{{ item.name }}</text> | 143 | + <text :class="[index == current3 ? 'select-text' : 'un-select-text']" class="text">{{ item.name }}</text> |
| 140 | </view> | 144 | </view> |
| 141 | </view> | 145 | </view> |
| 142 | - <view style="margin-top: 120rpx;"> | 146 | + <view style="margin-top: 169rpx;"> |
| 143 | <view class="popup-alarm-text"><text class="text">选择时间</text></view> | 147 | <view class="popup-alarm-text"><text class="text">选择时间</text></view> |
| 144 | <view class="u-flex popup-alarm-child"> | 148 | <view class="u-flex popup-alarm-child"> |
| 145 | <view | 149 | <view |
| 146 | class="alarm-text" | 150 | class="alarm-text" |
| 147 | @click="getTimeStatus(item, index)" | 151 | @click="getTimeStatus(item, index)" |
| 148 | - :style="[index == current4 ? { background: '#377DFF' } : { background: '#F6F6F6' }]" | 152 | + :style="[ |
| 153 | + index == current4 | ||
| 154 | + ? { background: 'rgba(55, 125, 255, 0.05)', border: '1rpx solid rgba(55, 125, 255, 0.3)' } | ||
| 155 | + : { background: '#F6F6F6' } | ||
| 156 | + ]" | ||
| 149 | v-for="(item, index) in timeArea" | 157 | v-for="(item, index) in timeArea" |
| 150 | :key="index" | 158 | :key="index" |
| 151 | > | 159 | > |
| 152 | - <text class="text">{{ item.name }}</text> | 160 | + <text :class="[index == current4 ? 'select-text' : 'un-select-text']" class="text">{{ item.name }}</text> |
| 153 | </view> | 161 | </view> |
| 154 | </view> | 162 | </view> |
| 155 | - <view style="margin-top: 120rpx;"> | 163 | + <view style="margin-top: 169rpx;margin-left: 22rpx;"> |
| 156 | <view class="u-flex popup-alarm-child"> | 164 | <view class="u-flex popup-alarm-child"> |
| 157 | - <view> | ||
| 158 | - <u--form :label-style="{ 'font-size': '29rpx', 'margin-left': '10rpx' }" labelPosition="left" :model="timeData"> | ||
| 159 | - <u-form-item style="font-size: 14px" label="选择日期" prop="selectTime" labelWidth="80" borderBottom @click="openTime"> | ||
| 160 | - <u--input v-model="timeData.selectTime" placeholder="请选择日期" border="none"></u--input> | ||
| 161 | - </u-form-item> | ||
| 162 | - </u--form> | 165 | + <view class="home-text-muted">选择日期</view> |
| 166 | + <view style="width: 623rpx;margin-left: 5rpx;margin-right: 70rpx;margin-top: 35rpx;"> | ||
| 167 | + <uni-datetime-picker v-model="range" type="daterange" /> | ||
| 163 | </view> | 168 | </view> |
| 164 | </view> | 169 | </view> |
| 165 | </view> | 170 | </view> |
| @@ -168,7 +173,7 @@ | @@ -168,7 +173,7 @@ | ||
| 168 | <view style="width: 300rpx"><u-button @click="resetData" type="info" shape="circle" text="重置"></u-button></view> | 173 | <view style="width: 300rpx"><u-button @click="resetData" type="info" shape="circle" text="重置"></u-button></view> |
| 169 | <view style="width: 300rpx; margin-left: 46rpx"><u-button @click="queryData" type="primary" shape="circle" text="确认"></u-button></view> | 174 | <view style="width: 300rpx; margin-left: 46rpx"><u-button @click="queryData" type="primary" shape="circle" text="确认"></u-button></view> |
| 170 | </view> | 175 | </view> |
| 171 | - <view style="height: 30rpx;"></view> | 176 | + <view style="height: 90rpx;"></view> |
| 172 | </view> | 177 | </view> |
| 173 | </view> | 178 | </view> |
| 174 | </view> | 179 | </view> |
| @@ -176,17 +181,6 @@ | @@ -176,17 +181,6 @@ | ||
| 176 | </view> | 181 | </view> |
| 177 | </view> | 182 | </view> |
| 178 | </u-popup> | 183 | </u-popup> |
| 179 | - <!-- 告警筛选 --> | ||
| 180 | - <u-calendar | ||
| 181 | - :show="showCalendar" | ||
| 182 | - mode="range" | ||
| 183 | - @confirm="calendarConfirm" | ||
| 184 | - @close="calendarClose" | ||
| 185 | - startText="开始时间" | ||
| 186 | - endText="结束时间" | ||
| 187 | - confirmDisabledText="请选择日期" | ||
| 188 | - :formatter="formatter" | ||
| 189 | - ></u-calendar> | ||
| 190 | <f-tabbar></f-tabbar> | 184 | <f-tabbar></f-tabbar> |
| 191 | </view> | 185 | </view> |
| 192 | </template> | 186 | </template> |
| @@ -194,7 +188,6 @@ | @@ -194,7 +188,6 @@ | ||
| 194 | <script> | 188 | <script> |
| 195 | import fTabbar from '@/components/module/f-tabbar/f-tabbar'; | 189 | import fTabbar from '@/components/module/f-tabbar/f-tabbar'; |
| 196 | import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js'; | 190 | import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js'; |
| 197 | -import { pageNumber, pageSize } from '@/config/constant.js'; | ||
| 198 | import { alertStatus, deviceType, alertLevel, timeArea } from './static/data.js'; | 191 | import { alertStatus, deviceType, alertLevel, timeArea } from './static/data.js'; |
| 199 | 192 | ||
| 200 | export default { | 193 | export default { |
| @@ -204,12 +197,11 @@ export default { | @@ -204,12 +197,11 @@ export default { | ||
| 204 | }, | 197 | }, |
| 205 | data() { | 198 | data() { |
| 206 | return { | 199 | return { |
| 200 | + range: ['', ''], | ||
| 207 | alertStatusVal: '', | 201 | alertStatusVal: '', |
| 208 | deviceTypeVal: '', | 202 | deviceTypeVal: '', |
| 209 | alertLevelVal: '', | 203 | alertLevelVal: '', |
| 210 | selectTimeVal: '', | 204 | selectTimeVal: '', |
| 211 | - startTime: '', | ||
| 212 | - endTime: '', | ||
| 213 | current1: 0, | 205 | current1: 0, |
| 214 | current2: 0, | 206 | current2: 0, |
| 215 | current3: 0, | 207 | current3: 0, |
| @@ -225,11 +217,10 @@ export default { | @@ -225,11 +217,10 @@ export default { | ||
| 225 | auto: false // 不自动加载 | 217 | auto: false // 不自动加载 |
| 226 | }, | 218 | }, |
| 227 | timeData: { | 219 | timeData: { |
| 228 | - selectTime: '', | ||
| 229 | - getTimeGap: '', | ||
| 230 | - getDateVal: '' | 220 | + selectTime: [], |
| 221 | + getTimeGapS: '', | ||
| 222 | + getTimeGapE: '' | ||
| 231 | }, | 223 | }, |
| 232 | - showCalendar: false, | ||
| 233 | show: false, | 224 | show: false, |
| 234 | list: [], | 225 | list: [], |
| 235 | alertStatus, | 226 | alertStatus, |
| @@ -269,6 +260,11 @@ export default { | @@ -269,6 +260,11 @@ export default { | ||
| 269 | this.loadData(1, type, null, null, null, null, null); | 260 | this.loadData(1, type, null, null, null, null, null); |
| 270 | } | 261 | } |
| 271 | }, | 262 | }, |
| 263 | + watch: { | ||
| 264 | + range(newval) { | ||
| 265 | + this.timeData.selectTime = this.range; | ||
| 266 | + } | ||
| 267 | + }, | ||
| 272 | methods: { | 268 | methods: { |
| 273 | inputChanged(e) { | 269 | inputChanged(e) { |
| 274 | this.loadData(1, null, null, null, null, null, null, e); | 270 | this.loadData(1, null, null, null, null, null, null, e); |
| @@ -288,19 +284,45 @@ export default { | @@ -288,19 +284,45 @@ export default { | ||
| 288 | getTimeStatus(e, i) { | 284 | getTimeStatus(e, i) { |
| 289 | this.current4 = i; | 285 | this.current4 = i; |
| 290 | this.selectTimeVal = e.value; | 286 | this.selectTimeVal = e.value; |
| 287 | + let curTime = new Date(); | ||
| 288 | + const formatS = curTime | ||
| 289 | + .getTime() | ||
| 290 | + .toString() | ||
| 291 | + .substring(0, 10); | ||
| 292 | + let addMinute = new Date(curTime.setMinutes(curTime.getMinutes() + this.selectTimeVal)); | ||
| 293 | + const formatE = addMinute | ||
| 294 | + .getTime() | ||
| 295 | + .toString() | ||
| 296 | + .substring(0, 10); | ||
| 297 | + this.timeData.getTimeGapS = formatS; | ||
| 298 | + this.timeData.getTimeGapE = formatE; | ||
| 291 | }, | 299 | }, |
| 292 | queryData() { | 300 | queryData() { |
| 293 | - let date1 = new Date(this.timeData.getDateVal[0]); | ||
| 294 | - let date2 = new Date(this.timeData.getDateVal[this.timeData.getDateVal.length - 1]); | 301 | + let date1 = new Date(this.timeData.selectTime[0]); |
| 302 | + let date2 = new Date(this.timeData.selectTime[1]); | ||
| 295 | let startTimeVa, endTimeVa; | 303 | let startTimeVa, endTimeVa; |
| 296 | - if (this.timeData.getDateVal.length == 0) { | 304 | + if (this.timeData.selectTime.length == 0) { |
| 297 | startTimeVa = ''; | 305 | startTimeVa = ''; |
| 298 | endTimeVa = ''; | 306 | endTimeVa = ''; |
| 299 | } else { | 307 | } else { |
| 300 | - startTimeVa = date1.getTime(); | ||
| 301 | - endTimeVa = date2.getTime(); | 308 | + startTimeVa = date1 |
| 309 | + .getTime() | ||
| 310 | + .toString() | ||
| 311 | + .substring(0, 10); | ||
| 312 | + endTimeVa = date2 | ||
| 313 | + .getTime() | ||
| 314 | + .toString() | ||
| 315 | + .substring(0, 10); | ||
| 316 | + } | ||
| 317 | + let startTimeArea, endTimeArea; | ||
| 318 | + if (this.timeData.getTimeGapS == '') { | ||
| 319 | + startTimeArea = ''; | ||
| 320 | + endTimeArea = ''; | ||
| 321 | + } else { | ||
| 322 | + startTimeArea = this.timeData.getTimeGapS; | ||
| 323 | + endTimeArea = this.timeData.getTimeGapE; | ||
| 302 | } | 324 | } |
| 303 | - this.loadData(1, this.alertStatusVal, startTimeVa, endTimeVa, this.alertLevelVal, this.deviceTypeVal); | 325 | + this.loadData(1, this.alertStatusVal, startTimeVa ? startTimeVa : startTimeArea, endTimeVa ? endTimeVa : endTimeArea, this.alertLevelVal, this.deviceTypeVal); |
| 304 | this.show = false; | 326 | this.show = false; |
| 305 | }, | 327 | }, |
| 306 | resetData() { | 328 | resetData() { |
| @@ -312,8 +334,10 @@ export default { | @@ -312,8 +334,10 @@ export default { | ||
| 312 | this.alertLevelVal = ''; | 334 | this.alertLevelVal = ''; |
| 313 | this.current4 = 0; | 335 | this.current4 = 0; |
| 314 | this.selectTimeVal = ''; | 336 | this.selectTimeVal = ''; |
| 315 | - this.timeData.getDateVal = ''; | ||
| 316 | - this.timeData.selectTime = ''; | 337 | + this.timeData.selectTime = []; |
| 338 | + this.timeDatagetTimeGapS = ''; | ||
| 339 | + this.timeDatagetTimeGapE = ''; | ||
| 340 | + this.range = []; | ||
| 317 | }, | 341 | }, |
| 318 | bindImageUrl(e) { | 342 | bindImageUrl(e) { |
| 319 | switch (e) { | 343 | switch (e) { |
| @@ -351,6 +375,7 @@ export default { | @@ -351,6 +375,7 @@ export default { | ||
| 351 | this.loadData(this.page.num); | 375 | this.loadData(this.page.num); |
| 352 | }, | 376 | }, |
| 353 | loadData(pageNo, statusV, startTimeV, endTimeV, severityV, deviceTypeV, organizationV, alarmName) { | 377 | loadData(pageNo, statusV, startTimeV, endTimeV, severityV, deviceTypeV, organizationV, alarmName) { |
| 378 | + let that = this; | ||
| 354 | let httpData = { | 379 | let httpData = { |
| 355 | page: pageNo, | 380 | page: pageNo, |
| 356 | pageSize: 10, | 381 | pageSize: 10, |
| @@ -372,18 +397,18 @@ export default { | @@ -372,18 +397,18 @@ export default { | ||
| 372 | .get('/yt/alarm', { params: httpData, custom: { load: false } }) | 397 | .get('/yt/alarm', { params: httpData, custom: { load: false } }) |
| 373 | .then(res => { | 398 | .then(res => { |
| 374 | uni.stopPullDownRefresh(); | 399 | uni.stopPullDownRefresh(); |
| 375 | - this.mescroll.endByPage(res.items.length, res.total); | ||
| 376 | - this.alertTotal = res.total; | 400 | + that.mescroll.endByPage(res.items.length, res.total); //必传参数(当前页的数据个数, 总页数) |
| 401 | + that.alertTotal = res.total; | ||
| 377 | if (pageNo == 1) { | 402 | if (pageNo == 1) { |
| 378 | - this.list = res.items; | 403 | + that.list = res.items; |
| 379 | } else { | 404 | } else { |
| 380 | - this.list = this.list.concat(res.items); | 405 | + that.list = that.list.concat(res.items); |
| 381 | } | 406 | } |
| 382 | }) | 407 | }) |
| 383 | .catch(e => { | 408 | .catch(e => { |
| 384 | uni.$u.toast(e.data?.message); | 409 | uni.$u.toast(e.data?.message); |
| 385 | //联网失败, 结束加载 | 410 | //联网失败, 结束加载 |
| 386 | - this.mescroll.endErr(); | 411 | + that.mescroll.endErr(); |
| 387 | }); | 412 | }); |
| 388 | }, | 413 | }, |
| 389 | openOrg() { | 414 | openOrg() { |
| @@ -398,18 +423,6 @@ export default { | @@ -398,18 +423,6 @@ export default { | ||
| 398 | this.show = true; | 423 | this.show = true; |
| 399 | this.resetData(); | 424 | this.resetData(); |
| 400 | }, | 425 | }, |
| 401 | - openTime() { | ||
| 402 | - this.showCalendar = true; | ||
| 403 | - uni.hideKeyboard(); | ||
| 404 | - }, | ||
| 405 | - calendarConfirm(e) { | ||
| 406 | - this.showCalendar = false; | ||
| 407 | - this.timeData.selectTime = `${e[0]} / ${e[e.length - 1]}`; | ||
| 408 | - this.timeData.getDateVal = e; | ||
| 409 | - }, | ||
| 410 | - calendarClose() { | ||
| 411 | - this.showCalendar = false; | ||
| 412 | - }, | ||
| 413 | //跳转告警详情 | 426 | //跳转告警详情 |
| 414 | openAlertDetail(e) { | 427 | openAlertDetail(e) { |
| 415 | let obj = { | 428 | let obj = { |
| @@ -449,4 +462,7 @@ export default { | @@ -449,4 +462,7 @@ export default { | ||
| 449 | /deep/ .u-cell__right-icon-wrap { | 462 | /deep/ .u-cell__right-icon-wrap { |
| 450 | margin-top: -55rpx !important; | 463 | margin-top: -55rpx !important; |
| 451 | } | 464 | } |
| 465 | +/deep/ .uni-calendar--fixed { | ||
| 466 | + bottom: 72rpx !important; | ||
| 467 | +} | ||
| 452 | </style> | 468 | </style> |
| @@ -196,35 +196,28 @@ | @@ -196,35 +196,28 @@ | ||
| 196 | margin-left: 98rpx; | 196 | margin-left: 98rpx; |
| 197 | flex-direction: column; | 197 | flex-direction: column; |
| 198 | justify-content: space-between; | 198 | justify-content: space-between; |
| 199 | - | ||
| 200 | .popup-alarm-text { | 199 | .popup-alarm-text { |
| 201 | width: 750rpx; | 200 | width: 750rpx; |
| 202 | margin-left: 14rpx; | 201 | margin-left: 14rpx; |
| 203 | - | ||
| 204 | .text { | 202 | .text { |
| 205 | color: #333333; | 203 | color: #333333; |
| 206 | font-size: 14px; | 204 | font-size: 14px; |
| 207 | } | 205 | } |
| 208 | } | 206 | } |
| 209 | - | ||
| 210 | .popup-alarm-child { | 207 | .popup-alarm-child { |
| 211 | margin-top: 15rpx; | 208 | margin-top: 15rpx; |
| 212 | - width: 650rpx; | 209 | + width: 750rpx; |
| 213 | height: 60rpx; | 210 | height: 60rpx; |
| 214 | - flex-direction: row; | ||
| 215 | flex-wrap: wrap; | 211 | flex-wrap: wrap; |
| 216 | - justify-content: space-between; | ||
| 217 | - align-content: space-between; | ||
| 218 | - | 212 | + margin-left: -10rpx; |
| 219 | .alarm-text { | 213 | .alarm-text { |
| 220 | - margin: 10rpx; | 214 | + margin: 25rpx; |
| 221 | line-height: 50rpx; | 215 | line-height: 50rpx; |
| 222 | text-align: center; | 216 | text-align: center; |
| 223 | width: 180rpx; | 217 | width: 180rpx; |
| 224 | height: 60rpx; | 218 | height: 60rpx; |
| 225 | background-color: #f6f6f6; | 219 | background-color: #f6f6f6; |
| 226 | border-radius: 32px; | 220 | border-radius: 32px; |
| 227 | - | ||
| 228 | .text { | 221 | .text { |
| 229 | color: #333333; | 222 | color: #333333; |
| 230 | font-size: 13px; | 223 | font-size: 13px; |
| @@ -110,35 +110,35 @@ const alertLevel = [{ | @@ -110,35 +110,35 @@ const alertLevel = [{ | ||
| 110 | const timeArea = [{ | 110 | const timeArea = [{ |
| 111 | index: 1, | 111 | index: 1, |
| 112 | name: '全部', | 112 | name: '全部', |
| 113 | - value: '全部', | 113 | + value: 0, |
| 114 | bgColor: '#F6F6F6', | 114 | bgColor: '#F6F6F6', |
| 115 | textColor: '#F6F6F6' | 115 | textColor: '#F6F6F6' |
| 116 | }, | 116 | }, |
| 117 | { | 117 | { |
| 118 | index: 2, | 118 | index: 2, |
| 119 | name: '30分钟', | 119 | name: '30分钟', |
| 120 | - value: '30', | 120 | + value: 30, |
| 121 | bgColor: '#F6F6F6', | 121 | bgColor: '#F6F6F6', |
| 122 | textColor: '#F6F6F6' | 122 | textColor: '#F6F6F6' |
| 123 | }, | 123 | }, |
| 124 | { | 124 | { |
| 125 | index: 3, | 125 | index: 3, |
| 126 | name: '1小时', | 126 | name: '1小时', |
| 127 | - value: '30', | 127 | + value: 60, |
| 128 | bgColor: '#F6F6F6', | 128 | bgColor: '#F6F6F6', |
| 129 | textColor: '#F6F6F6' | 129 | textColor: '#F6F6F6' |
| 130 | }, | 130 | }, |
| 131 | { | 131 | { |
| 132 | index: 4, | 132 | index: 4, |
| 133 | name: '2小时', | 133 | name: '2小时', |
| 134 | - value: '120', | 134 | + value: 120, |
| 135 | bgColor: '#F6F6F6', | 135 | bgColor: '#F6F6F6', |
| 136 | textColor: '#F6F6F6' | 136 | textColor: '#F6F6F6' |
| 137 | }, | 137 | }, |
| 138 | { | 138 | { |
| 139 | index: 5, | 139 | index: 5, |
| 140 | name: '近一天', | 140 | name: '近一天', |
| 141 | - value: '24', | 141 | + value: 1440, |
| 142 | bgColor: '#F6F6F6', | 142 | bgColor: '#F6F6F6', |
| 143 | textColor: '#F6F6F6' | 143 | textColor: '#F6F6F6' |
| 144 | } | 144 | } |
| @@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
| 3 | <!-- 公共组件-每个页面必须引入 --> | 3 | <!-- 公共组件-每个页面必须引入 --> |
| 4 | <public-module></public-module> | 4 | <public-module></public-module> |
| 5 | <view class="headBox"> | 5 | <view class="headBox"> |
| 6 | - <!-- #ifdef MP --> | 6 | + <!-- #ifdef MP || APP-PLUS --> |
| 7 | <!-- 登录 --> | 7 | <!-- 登录 --> |
| 8 | <view class="u-flex u-p-l-30 u-p-r-20 u-p-t-75 u-p-b-30"> | 8 | <view class="u-flex u-p-l-30 u-p-r-20 u-p-t-75 u-p-b-30"> |
| 9 | <block v-if="userInfo.isToken"> | 9 | <block v-if="userInfo.isToken"> |
| @@ -17,8 +17,6 @@ | @@ -17,8 +17,6 @@ | ||
| 17 | </view> | 17 | </view> |
| 18 | </view> | 18 | </view> |
| 19 | <view @click="openPersonalInfo" style="color:#FFFFFF;font-size: 14px;" v-if="userInfo.phoneNumber">{{ userInfo.phoneNumber | phone }}</view> | 19 | <view @click="openPersonalInfo" style="color:#FFFFFF;font-size: 14px;" v-if="userInfo.phoneNumber">{{ userInfo.phoneNumber | phone }}</view> |
| 20 | - <view v-else><text style="color:#FFFFFF;font-size: 14px;">手机号:未绑定</text></view> | ||
| 21 | - <view v-if="userInfo.isToken" @click="clearAccountFunc(userInfo)" class="detail"><text class="text">解绑</text></view> | ||
| 22 | </view> | 20 | </view> |
| 23 | </block> | 21 | </block> |
| 24 | <block v-else> | 22 | <block v-else> |
| @@ -30,37 +28,9 @@ | @@ -30,37 +28,9 @@ | ||
| 30 | <view v-if="!userInfo.isToken" @click="clickAccountFunc" class="detail"><text class="text">绑定账号</text></view> | 28 | <view v-if="!userInfo.isToken" @click="clickAccountFunc" class="detail"><text class="text">绑定账号</text></view> |
| 31 | </view> | 29 | </view> |
| 32 | </block> | 30 | </block> |
| 33 | - <view v-if="userInfo.isToken"><u-icon name="arrow-right" color="white" size="13"></u-icon></view> | 31 | + <view v-if="userInfo.isToken" @click="openPersonalInfo"><u-icon name="arrow-right" color="white" size="13"></u-icon></view> |
| 34 | </view> | 32 | </view> |
| 35 | - <!-- #endif --> | ||
| 36 | - <!-- #ifndef MP --> | ||
| 37 | <!-- 登录 --> | 33 | <!-- 登录 --> |
| 38 | - <view class="u-flex u-p-l-30 u-p-r-20 u-p-t-75 u-p-b-30"> | ||
| 39 | - <block v-if="userInfo.isToken"> | ||
| 40 | - <view @click="openPersonalInfo" class="u-m-r-20"> | ||
| 41 | - <image class="avatar" mode="aspectFill" :src="userInfo.avatar || userInfo.avatarUrl || '/static/default.png'"></image> | ||
| 42 | - </view> | ||
| 43 | - <view @click="openPersonalInfo" class="u-flex-1"> | ||
| 44 | - <view class="nickName u-flex"> | ||
| 45 | - <view class="name u-m-r-10" v-if="userInfo.realName || userInfo.nickName"> | ||
| 46 | - <text style="#FFFFFF;font-size: 18px;">{{ userInfo.realName || userInfo.nickName }}</text> | ||
| 47 | - </view> | ||
| 48 | - </view> | ||
| 49 | - <view style="color:#FFFFFF;font-size: 14px;" v-if="userInfo.phoneNumber">{{ userInfo.phoneNumber | phone }}</view> | ||
| 50 | - <view v-else><text style="color:#FFFFFF;font-size: 14px;">手机号:未绑定</text></view> | ||
| 51 | - </view> | ||
| 52 | - </block> | ||
| 53 | - <block v-else> | ||
| 54 | - <view class="u-m-r-20" @click="openLoginFunc"> | ||
| 55 | - <view class="avatar u-flex" style="justify-content: center"><u-icon name="account-fill" color="black" size="30"></u-icon></view> | ||
| 56 | - </view> | ||
| 57 | - <view class="u-flex-1"> | ||
| 58 | - <view @click="openLoginFunc" class="u-font-lg login-btn">登录</view> | ||
| 59 | - <view v-if="userInfo.isToken == '' || userInfo.isToken == null" @click="clickAccountFunc" style="color: black" class="detail">绑定账号</view> | ||
| 60 | - </view> | ||
| 61 | - </block> | ||
| 62 | - <view><u-icon name="arrow-right" color="black" size="13"></u-icon></view> | ||
| 63 | - </view> | ||
| 64 | <!-- #endif --> | 34 | <!-- #endif --> |
| 65 | </view> | 35 | </view> |
| 66 | <view class="u-flex my-nav"> | 36 | <view class="u-flex my-nav"> |
| @@ -195,7 +165,6 @@ export default { | @@ -195,7 +165,6 @@ export default { | ||
| 195 | if (e.obj != null) { | 165 | if (e.obj != null) { |
| 196 | const params = JSON.parse(decodeURIComponent(e.obj)); | 166 | const params = JSON.parse(decodeURIComponent(e.obj)); |
| 197 | this.thirdObj = params; | 167 | this.thirdObj = params; |
| 198 | - console.log(this.thirdObj); | ||
| 199 | } | 168 | } |
| 200 | }, | 169 | }, |
| 201 | computed: { | 170 | computed: { |
| @@ -223,7 +192,8 @@ export default { | @@ -223,7 +192,8 @@ export default { | ||
| 223 | }, | 192 | }, |
| 224 | openPersonalInfo() { | 193 | openPersonalInfo() { |
| 225 | let obj = { | 194 | let obj = { |
| 226 | - data: this.userInfo | 195 | + data: this.userInfo, |
| 196 | + third: this.thirdObj | ||
| 227 | }; | 197 | }; |
| 228 | uni.navigateTo({ | 198 | uni.navigateTo({ |
| 229 | url: '/publicLoginSubPage/other/set?data=' + JSON.stringify(obj) | 199 | url: '/publicLoginSubPage/other/set?data=' + JSON.stringify(obj) |
| @@ -290,7 +260,8 @@ export default { | @@ -290,7 +260,8 @@ export default { | ||
| 290 | } | 260 | } |
| 291 | }) | 261 | }) |
| 292 | .catch(e => { | 262 | .catch(e => { |
| 293 | - uni.$u.toast(e.data?.message); | 263 | + uni.$u.toast(e.data?.msg || e.data?.message); |
| 264 | + this.show = false; | ||
| 294 | }); | 265 | }); |
| 295 | } else { | 266 | } else { |
| 296 | const phoneRegular = /^1\d{10}$/; | 267 | const phoneRegular = /^1\d{10}$/; |
| @@ -349,7 +320,8 @@ export default { | @@ -349,7 +320,8 @@ export default { | ||
| 349 | this.saveUserInfo(); | 320 | this.saveUserInfo(); |
| 350 | }) | 321 | }) |
| 351 | .catch(e => { | 322 | .catch(e => { |
| 352 | - uni.$u.toast(e.data?.message); | 323 | + uni.$u.toast(e.data?.msg || e.data?.message); |
| 324 | + this.show = false; | ||
| 353 | }); | 325 | }); |
| 354 | } | 326 | } |
| 355 | }, | 327 | }, |
| @@ -439,18 +411,6 @@ export default { | @@ -439,18 +411,6 @@ export default { | ||
| 439 | } | 411 | } |
| 440 | } | 412 | } |
| 441 | }); | 413 | }); |
| 442 | - }, | ||
| 443 | - clearAccountFunc(e) { | ||
| 444 | - //解绑 | ||
| 445 | - let httpData = { | ||
| 446 | - appUserId: e.userId, | ||
| 447 | - thirdUserId: this.thirdObj.thirdUserId | ||
| 448 | - }; | ||
| 449 | - uni.$u.http.delete('/yt/third', httpData).then(res => { | ||
| 450 | - if (res) { | ||
| 451 | - this.getCodeState(); //开始倒计时 | ||
| 452 | - } | ||
| 453 | - }); | ||
| 454 | } | 414 | } |
| 455 | } | 415 | } |
| 456 | }; | 416 | }; |
| @@ -45,10 +45,24 @@ | @@ -45,10 +45,24 @@ | ||
| 45 | </u-form-item> | 45 | </u-form-item> |
| 46 | </u--form> | 46 | </u--form> |
| 47 | </view> | 47 | </view> |
| 48 | - <view class="basic-bottom"><button class="submit" size="default" @click="onSubmitFunc" :style="{ background: PrimaryColor }">确认</button></view> | 48 | + <view class="basic-bottom u-flex"> |
| 49 | + <view class="item" v-if="info.data.isToken"><button class="submit" size="default" @click="clearAccountFunc" :style="{ background: InfoColor }">解绑</button></view> | ||
| 50 | + <view class="item" style="margin-right: 60rpx;"><button class="submit" size="default" @click="onSubmitFunc" :style="{ background: PrimaryColor }">确认</button></view> | ||
| 51 | + </view> | ||
| 49 | <!-- #ifdef MP --> | 52 | <!-- #ifdef MP --> |
| 50 | <view class="u-m-t-40"><text style="visibility: hidden;">#</text></view> | 53 | <view class="u-m-t-40"><text style="visibility: hidden;">#</text></view> |
| 51 | <!-- #endif --> | 54 | <!-- #endif --> |
| 55 | + <!-- 解绑账号 --> | ||
| 56 | + <view> | ||
| 57 | + <u-popup bgColor="transparent" :overlay="true" :show="showBind" mode="bottom"> | ||
| 58 | + <view class="u-flex logout-main"> | ||
| 59 | + <view class="main"><text style="color: #999999">是否需要解绑?</text></view> | ||
| 60 | + <view @click="confrimBind(info)" class="main"><text style="color: #f95e5a">是</text></view> | ||
| 61 | + <view class="main1"><text @click="showBind = false" style="color: #3478f7">否</text></view> | ||
| 62 | + </view> | ||
| 63 | + </u-popup> | ||
| 64 | + </view> | ||
| 65 | + <!-- 解绑账号 --> | ||
| 52 | </view> | 66 | </view> |
| 53 | </template> | 67 | </template> |
| 54 | 68 | ||
| @@ -56,7 +70,9 @@ | @@ -56,7 +70,9 @@ | ||
| 56 | export default { | 70 | export default { |
| 57 | data() { | 71 | data() { |
| 58 | return { | 72 | return { |
| 59 | - PrimaryColor: '#0079fe', //主题色 | 73 | + showBind: false, |
| 74 | + PrimaryColor: '#377DFF', //主题色 | ||
| 75 | + InfoColor: '#E3E4E5', //主题色 | ||
| 60 | myInfoModel: { | 76 | myInfoModel: { |
| 61 | userInfo: { | 77 | userInfo: { |
| 62 | realName: '', | 78 | realName: '', |
| @@ -117,12 +133,14 @@ export default { | @@ -117,12 +133,14 @@ export default { | ||
| 117 | trigger: ['change', 'blur'] | 133 | trigger: ['change', 'blur'] |
| 118 | } | 134 | } |
| 119 | ] | 135 | ] |
| 120 | - } | 136 | + }, |
| 137 | + info: {} | ||
| 121 | }; | 138 | }; |
| 122 | }, | 139 | }, |
| 123 | onLoad(e) { | 140 | onLoad(e) { |
| 124 | if (e.data !== null) { | 141 | if (e.data !== null) { |
| 125 | let params = JSON.parse(e.data); | 142 | let params = JSON.parse(e.data); |
| 143 | + this.info = params; | ||
| 126 | this.myInfoModel.userInfo.realName = params.data.realName; | 144 | this.myInfoModel.userInfo.realName = params.data.realName; |
| 127 | this.myInfoModel.userInfo.phoneNumber = params.data.phoneNumber; | 145 | this.myInfoModel.userInfo.phoneNumber = params.data.phoneNumber; |
| 128 | this.myInfoModel.userInfo.username = params.data.username; | 146 | this.myInfoModel.userInfo.username = params.data.username; |
| @@ -133,6 +151,31 @@ export default { | @@ -133,6 +151,31 @@ export default { | ||
| 133 | } | 151 | } |
| 134 | }, | 152 | }, |
| 135 | methods: { | 153 | methods: { |
| 154 | + confrimBind(e) { | ||
| 155 | + if (e) { | ||
| 156 | + //解绑 | ||
| 157 | + let httpData = { | ||
| 158 | + appUserId: e.data?.userId, | ||
| 159 | + thirdUserId: e.third?.thirdUserId | ||
| 160 | + }; | ||
| 161 | + uni.$u.http.delete('/yt/third', httpData).then(res => { | ||
| 162 | + if (res) { | ||
| 163 | + uni.showToast({ | ||
| 164 | + title: '解绑成功' | ||
| 165 | + }); | ||
| 166 | + this.showBind = false; | ||
| 167 | + } else { | ||
| 168 | + uni.showToast({ | ||
| 169 | + title: '解绑失败' | ||
| 170 | + }); | ||
| 171 | + this.showBind = false; | ||
| 172 | + } | ||
| 173 | + }); | ||
| 174 | + } | ||
| 175 | + }, | ||
| 176 | + clearAccountFunc() { | ||
| 177 | + this.showBind = true; | ||
| 178 | + }, | ||
| 136 | // 修改头像 | 179 | // 修改头像 |
| 137 | upAvatar() { | 180 | upAvatar() { |
| 138 | var that = this; | 181 | var that = this; |
| @@ -46,6 +46,30 @@ | @@ -46,6 +46,30 @@ | ||
| 46 | padding-left: 15rpx; | 46 | padding-left: 15rpx; |
| 47 | } | 47 | } |
| 48 | .basic-bottom { | 48 | .basic-bottom { |
| 49 | - width: 500rpx; | ||
| 50 | - margin-left: 86rpx; | 49 | + width: 750rpx; |
| 50 | + justify-content: space-between; | ||
| 51 | + .item { | ||
| 52 | + width: 318rpx; | ||
| 53 | + } | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +.logout-main { | ||
| 57 | + flex-direction: column; | ||
| 58 | + height: 300rpx; | ||
| 59 | + margin: 30rpx 40rpx; | ||
| 60 | + background: #f5f5f5; | ||
| 61 | + border-radius: 20rpx; | ||
| 62 | + .main { | ||
| 63 | + width: 669rpx; | ||
| 64 | + height: 100rpx; | ||
| 65 | + border-bottom: 1rpx solid #d6d6d6; | ||
| 66 | + text-align: center; | ||
| 67 | + line-height: 86rpx; | ||
| 68 | + } | ||
| 69 | + .main1 { | ||
| 70 | + width: 669rpx; | ||
| 71 | + height: 100rpx; | ||
| 72 | + text-align: center; | ||
| 73 | + line-height: 86rpx; | ||
| 74 | + } | ||
| 51 | } | 75 | } |
| @@ -37,7 +37,7 @@ | @@ -37,7 +37,7 @@ | ||
| 37 | </template> | 37 | </template> |
| 38 | 38 | ||
| 39 | <script> | 39 | <script> |
| 40 | -import { mapMutations } from 'vuex'; | 40 | +import { mapMutations, mapActions } from 'vuex'; |
| 41 | import { loginApp } from '@/config/login'; | 41 | import { loginApp } from '@/config/login'; |
| 42 | import baseUrl from '@/config/baseUrl.js'; | 42 | import baseUrl from '@/config/baseUrl.js'; |
| 43 | import WXBizDataCrypt from '@/config/WXBizDataCrypt.js'; | 43 | import WXBizDataCrypt from '@/config/WXBizDataCrypt.js'; |
| @@ -70,6 +70,12 @@ export default { | @@ -70,6 +70,12 @@ export default { | ||
| 70 | this.openid = res.data.openid; | 70 | this.openid = res.data.openid; |
| 71 | this.session_key = res.data.session_key; | 71 | this.session_key = res.data.session_key; |
| 72 | } | 72 | } |
| 73 | + }, | ||
| 74 | + complete: e => { | ||
| 75 | + if (e.data.errcode != null) { | ||
| 76 | + return; | ||
| 77 | + // return uni.$u.toast('获取用户唯一id失败'); | ||
| 78 | + } | ||
| 73 | } | 79 | } |
| 74 | }); | 80 | }); |
| 75 | } else { | 81 | } else { |
| @@ -80,14 +86,19 @@ export default { | @@ -80,14 +86,19 @@ export default { | ||
| 80 | }, | 86 | }, |
| 81 | methods: { | 87 | methods: { |
| 82 | ...mapMutations(['setUserInfo']), | 88 | ...mapMutations(['setUserInfo']), |
| 89 | + ...mapActions(['updateBadgeTotal']), | ||
| 83 | //微信授权登录 | 90 | //微信授权登录 |
| 84 | //#ifdef MP | 91 | //#ifdef MP |
| 85 | onAuthorization(e) { | 92 | onAuthorization(e) { |
| 93 | + /** | ||
| 94 | + * 注意:通过wx.getUserProfile并不能获取用户的openid,openid是唯一识别用户的标识, | ||
| 95 | + * 所以最好在用户授权登录时就获取。调用wx.login()获取 | ||
| 96 | + */ | ||
| 86 | wx.getUserProfile({ | 97 | wx.getUserProfile({ |
| 87 | - desc: '获取用户信息', | 98 | + desc: '获取用户授权信息', |
| 88 | success: res => { | 99 | success: res => { |
| 89 | if (res) { | 100 | if (res) { |
| 90 | - //微信官方自带解密(node) | 101 | + //微信官方自带解密(node.js实现) |
| 91 | let pc = new WXBizDataCrypt(appId, this.session_key); | 102 | let pc = new WXBizDataCrypt(appId, this.session_key); |
| 92 | let data = pc.decryptData(res.encryptedData, res.iv); | 103 | let data = pc.decryptData(res.encryptedData, res.iv); |
| 93 | let obj = { | 104 | let obj = { |
| @@ -100,11 +111,12 @@ export default { | @@ -100,11 +111,12 @@ export default { | ||
| 100 | .get(`/yt/third/login/${this.openid}`) | 111 | .get(`/yt/third/login/${this.openid}`) |
| 101 | .then(res => { | 112 | .then(res => { |
| 102 | if (res.token == '' || res.token == null) { | 113 | if (res.token == '' || res.token == null) { |
| 103 | - //需要绑定,跳转我的页面 | 114 | + //需要绑定,跳转我的页面进行绑定,显示绑定按钮 |
| 104 | uni.reLaunch({ | 115 | uni.reLaunch({ |
| 105 | url: '/pages/personal/personal' | 116 | url: '/pages/personal/personal' |
| 106 | }); | 117 | }); |
| 107 | } else { | 118 | } else { |
| 119 | + // 不需要绑定 | ||
| 108 | // 储存登录信息 | 120 | // 储存登录信息 |
| 109 | let resObj = { | 121 | let resObj = { |
| 110 | refreshToken: res.refreshToken, | 122 | refreshToken: res.refreshToken, |
| @@ -122,12 +134,17 @@ export default { | @@ -122,12 +134,17 @@ export default { | ||
| 122 | icon: 'none' | 134 | icon: 'none' |
| 123 | }); | 135 | }); |
| 124 | this.saveUserInfo(); | 136 | this.saveUserInfo(); |
| 137 | + this.getAlarmTotalData(); | ||
| 125 | } | 138 | } |
| 126 | }) | 139 | }) |
| 127 | .catch(e => { | 140 | .catch(e => { |
| 128 | uni.$u.toast(e.data?.message); | 141 | uni.$u.toast(e.data?.message); |
| 129 | }); | 142 | }); |
| 130 | - // #ifdef APP-PLUS||MP | 143 | + /** |
| 144 | + * 有些时候uni.navigatorBack({})没有返回到上级页面 | ||
| 145 | + * 才使用uni.reLaunch()进行跳转 | ||
| 146 | + */ | ||
| 147 | + // #ifdef MP | ||
| 131 | setTimeout(() => { | 148 | setTimeout(() => { |
| 132 | uni.reLaunch({ | 149 | uni.reLaunch({ |
| 133 | url: '/pages/personal/personal?obj=' + encodeURIComponent(JSON.stringify(obj)) | 150 | url: '/pages/personal/personal?obj=' + encodeURIComponent(JSON.stringify(obj)) |
| @@ -147,6 +164,14 @@ export default { | @@ -147,6 +164,14 @@ export default { | ||
| 147 | } | 164 | } |
| 148 | }); | 165 | }); |
| 149 | }, | 166 | }, |
| 167 | + getAlarmTotalData() { | ||
| 168 | + uni.$u.http.get('/yt/homepage/app').then(res => { | ||
| 169 | + if (res) { | ||
| 170 | + //异步实时更新告警徽标数 | ||
| 171 | + this.updateBadgeTotal(res.totalAlarm.activedAlarm); | ||
| 172 | + } | ||
| 173 | + }); | ||
| 174 | + }, | ||
| 150 | onSubmitFunc() { | 175 | onSubmitFunc() { |
| 151 | if (this.loginForm.username == '') { | 176 | if (this.loginForm.username == '') { |
| 152 | return uni.$u.toast('请输入登录账号~'); | 177 | return uni.$u.toast('请输入登录账号~'); |
| @@ -199,6 +224,7 @@ export default { | @@ -199,6 +224,7 @@ export default { | ||
| 199 | // #endif | 224 | // #endif |
| 200 | }); | 225 | }); |
| 201 | this.saveUserInfo(); | 226 | this.saveUserInfo(); |
| 227 | + this.getAlarmTotalData(); | ||
| 202 | } | 228 | } |
| 203 | }) | 229 | }) |
| 204 | .catch(e => { | 230 | .catch(e => { |
| @@ -172,6 +172,19 @@ button { | @@ -172,6 +172,19 @@ button { | ||
| 172 | font-weight: 400; | 172 | font-weight: 400; |
| 173 | color: #2f384e; | 173 | color: #2f384e; |
| 174 | } | 174 | } |
| 175 | +//筛选字体颜色 | ||
| 176 | +.select-text { | ||
| 177 | + font-size: 13px; | ||
| 178 | + font-family: PingFangSC-Regular, PingFang SC; | ||
| 179 | + font-weight: 400; | ||
| 180 | + color: #377dff !important; | ||
| 181 | +} | ||
| 182 | +.un-select-text { | ||
| 183 | + font-size: 13px; | ||
| 184 | + font-family: PingFangSC-Regular, PingFang SC; | ||
| 185 | + font-weight: 400; | ||
| 186 | + color: #333333 !important; | ||
| 187 | +} | ||
| 175 | // 定义flex等分 | 188 | // 定义flex等分 |
| 176 | @for $i from 0 through 12 { | 189 | @for $i from 0 through 12 { |
| 177 | .u-flex-#{$i} { | 190 | .u-flex-#{$i} { |
| @@ -96,8 +96,9 @@ export default { | @@ -96,8 +96,9 @@ export default { | ||
| 96 | uni.hideKeyboard(); | 96 | uni.hideKeyboard(); |
| 97 | }, | 97 | }, |
| 98 | typeSelect(e) { | 98 | typeSelect(e) { |
| 99 | + this.page.num = 0; | ||
| 99 | this.model1.userInfo.type = e.name; | 100 | this.model1.userInfo.type = e.name; |
| 100 | - this.loadData(1, e.value); | 101 | + this.loadData(1, e.value == '' ? null : e.value); |
| 101 | }, | 102 | }, |
| 102 | /*下拉刷新的回调 */ | 103 | /*下拉刷新的回调 */ |
| 103 | downCallback() { | 104 | downCallback() { |
uni_modules/uni-datetime-picker/changelog.md
0 → 100644
| 1 | +## 2.2.3(2022-03-28) | ||
| 2 | +- 修复 Vue3 下动态赋值未响应的 bug | ||
| 3 | +## 2.2.2(2021-12-10) | ||
| 4 | +- 修复 clear-icon 属性在小程序平台不生效的 bug | ||
| 5 | +## 2.2.1(2021-12-10) | ||
| 6 | +- 修复 日期范围选在小程序平台,必须多点击一次才能取消选中状态的 bug | ||
| 7 | +## 2.2.0(2021-11-19) | ||
| 8 | +- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) | ||
| 9 | +- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-datetime-picker](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker) | ||
| 10 | +## 2.1.5(2021-11-09) | ||
| 11 | +- 新增 提供组件设计资源,组件样式调整 | ||
| 12 | +## 2.1.4(2021-09-10) | ||
| 13 | +- 修复 hide-second 在移动端的 bug | ||
| 14 | +- 修复 单选赋默认值时,赋值日期未高亮的 bug | ||
| 15 | +- 修复 赋默认值时,移动端未正确显示时间的 bug | ||
| 16 | +## 2.1.3(2021-09-09) | ||
| 17 | +- 新增 hide-second 属性,支持只使用时分,隐藏秒 | ||
| 18 | +## 2.1.2(2021-09-03) | ||
| 19 | +- 优化 取消选中时(范围选)直接开始下一次选择, 避免多点一次 | ||
| 20 | +- 优化 移动端支持清除按钮,同时支持通过 ref 调用组件的 clear 方法 | ||
| 21 | +- 优化 调整字号大小,美化日历界面 | ||
| 22 | +- 修复 因国际化导致的 placeholder 失效的 bug | ||
| 23 | +## 2.1.1(2021-08-24) | ||
| 24 | +- 新增 支持国际化 | ||
| 25 | +- 优化 范围选择器在 pc 端过宽的问题 | ||
| 26 | +## 2.1.0(2021-08-09) | ||
| 27 | +- 新增 适配 vue3 | ||
| 28 | +## 2.0.19(2021-08-09) | ||
| 29 | +- 新增 支持作为 uni-forms 子组件相关功能 | ||
| 30 | +- 修复 在 uni-forms 中使用时,选择时间报 NAN 错误的 bug | ||
| 31 | +## 2.0.18(2021-08-05) | ||
| 32 | +- 修复 type 属性动态赋值无效的 bug | ||
| 33 | +- 修复 ‘确认’按钮被 tabbar 遮盖 bug | ||
| 34 | +- 修复 组件未赋值时范围选左、右日历相同的 bug | ||
| 35 | +## 2.0.17(2021-08-04) | ||
| 36 | +- 修复 范围选未正确显示当前值的 bug | ||
| 37 | +- 修复 h5 平台(移动端)报错 'cale' of undefined 的 bug | ||
| 38 | +## 2.0.16(2021-07-21) | ||
| 39 | +- 新增 return-type 属性支持返回 date 日期对象 | ||
| 40 | +## 2.0.15(2021-07-14) | ||
| 41 | +- 修复 单选日期类型,初始赋值后不在当前日历的 bug | ||
| 42 | +- 新增 clearIcon 属性,显示框的清空按钮可配置显示隐藏(仅 pc 有效) | ||
| 43 | +- 优化 移动端移除显示框的清空按钮,无实际用途 | ||
| 44 | +## 2.0.14(2021-07-14) | ||
| 45 | +- 修复 组件赋值为空,界面未更新的 bug | ||
| 46 | +- 修复 start 和 end 不能动态赋值的 bug | ||
| 47 | +- 修复 范围选类型,用户选择后再次选择右侧日历(结束日期)显示不正确的 bug | ||
| 48 | +## 2.0.13(2021-07-08) | ||
| 49 | +- 修复 范围选择不能动态赋值的 bug | ||
| 50 | +## 2.0.12(2021-07-08) | ||
| 51 | +- 修复 范围选择的初始时间在一个月内时,造成无法选择的bug | ||
| 52 | +## 2.0.11(2021-07-08) | ||
| 53 | +- 优化 弹出层在超出视窗边缘定位不准确的问题 | ||
| 54 | +## 2.0.10(2021-07-08) | ||
| 55 | +- 修复 范围起始点样式的背景色与今日样式的字体前景色融合,导致日期字体看不清的 bug | ||
| 56 | +- 优化 弹出层在超出视窗边缘被遮盖的问题 | ||
| 57 | +## 2.0.9(2021-07-07) | ||
| 58 | +- 新增 maskClick 事件 | ||
| 59 | +- 修复 特殊情况日历 rpx 布局错误的 bug,rpx -> px | ||
| 60 | +- 修复 范围选择时清空返回值不合理的bug,['', ''] -> [] | ||
| 61 | +## 2.0.8(2021-07-07) | ||
| 62 | +- 新增 日期时间显示框支持插槽 | ||
| 63 | +## 2.0.7(2021-07-01) | ||
| 64 | +- 优化 添加 uni-icons 依赖 | ||
| 65 | +## 2.0.6(2021-05-22) | ||
| 66 | +- 修复 图标在小程序上不显示的 bug | ||
| 67 | +- 优化 重命名引用组件,避免潜在组件命名冲突 | ||
| 68 | +## 2.0.5(2021-05-20) | ||
| 69 | +- 优化 代码目录扁平化 | ||
| 70 | +## 2.0.4(2021-05-12) | ||
| 71 | +- 新增 组件示例地址 | ||
| 72 | +## 2.0.3(2021-05-10) | ||
| 73 | +- 修复 ios 下不识别 '-' 日期格式的 bug | ||
| 74 | +- 优化 pc 下弹出层添加边框和阴影 | ||
| 75 | +## 2.0.2(2021-05-08) | ||
| 76 | +- 修复 在 admin 中获取弹出层定位错误的bug | ||
| 77 | +## 2.0.1(2021-05-08) | ||
| 78 | +- 修复 type 属性向下兼容,默认值从 date 变更为 datetime | ||
| 79 | +## 2.0.0(2021-04-30) | ||
| 80 | +- 支持日历形式的日期+时间的范围选择 | ||
| 81 | + > 注意:此版本不向后兼容,不再支持单独时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker) | ||
| 82 | +## 1.0.6(2021-03-18) | ||
| 83 | +- 新增 hide-second 属性,时间支持仅选择时、分 | ||
| 84 | +- 修复 选择跟显示的日期不一样的 bug | ||
| 85 | +- 修复 chang事件触发2次的 bug | ||
| 86 | +- 修复 分、秒 end 范围错误的 bug | ||
| 87 | +- 优化 更好的 nvue 适配 |
| 1 | +<template> | ||
| 2 | + <view class="uni-calendar-item__weeks-box" :class="{ | ||
| 3 | + 'uni-calendar-item--disable':weeks.disable, | ||
| 4 | + 'uni-calendar-item--before-checked-x':weeks.beforeMultiple, | ||
| 5 | + 'uni-calendar-item--multiple': weeks.multiple, | ||
| 6 | + 'uni-calendar-item--after-checked-x':weeks.afterMultiple, | ||
| 7 | + }" @click="choiceDate(weeks)" @mouseenter="handleMousemove(weeks)"> | ||
| 8 | + <view class="uni-calendar-item__weeks-box-item" :class="{ | ||
| 9 | + 'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && (calendar.userChecked || !checkHover), | ||
| 10 | + 'uni-calendar-item--checked-range-text': checkHover, | ||
| 11 | + 'uni-calendar-item--before-checked':weeks.beforeMultiple, | ||
| 12 | + 'uni-calendar-item--multiple': weeks.multiple, | ||
| 13 | + 'uni-calendar-item--after-checked':weeks.afterMultiple, | ||
| 14 | + 'uni-calendar-item--disable':weeks.disable, | ||
| 15 | + }"> | ||
| 16 | + <text v-if="selected&&weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text> | ||
| 17 | + <text class="uni-calendar-item__weeks-box-text uni-calendar-item__weeks-box-text-disable uni-calendar-item--checked-text">{{weeks.date}}</text> | ||
| 18 | + </view> | ||
| 19 | + <view :class="{'uni-calendar-item--isDay': weeks.isDay}"></view> | ||
| 20 | + </view> | ||
| 21 | +</template> | ||
| 22 | + | ||
| 23 | +<script> | ||
| 24 | + export default { | ||
| 25 | + props: { | ||
| 26 | + weeks: { | ||
| 27 | + type: Object, | ||
| 28 | + default () { | ||
| 29 | + return {} | ||
| 30 | + } | ||
| 31 | + }, | ||
| 32 | + calendar: { | ||
| 33 | + type: Object, | ||
| 34 | + default: () => { | ||
| 35 | + return {} | ||
| 36 | + } | ||
| 37 | + }, | ||
| 38 | + selected: { | ||
| 39 | + type: Array, | ||
| 40 | + default: () => { | ||
| 41 | + return [] | ||
| 42 | + } | ||
| 43 | + }, | ||
| 44 | + lunar: { | ||
| 45 | + type: Boolean, | ||
| 46 | + default: false | ||
| 47 | + }, | ||
| 48 | + checkHover: { | ||
| 49 | + type: Boolean, | ||
| 50 | + default: false | ||
| 51 | + } | ||
| 52 | + }, | ||
| 53 | + methods: { | ||
| 54 | + choiceDate(weeks) { | ||
| 55 | + this.$emit('change', weeks) | ||
| 56 | + }, | ||
| 57 | + handleMousemove(weeks) { | ||
| 58 | + this.$emit('handleMouse', weeks) | ||
| 59 | + } | ||
| 60 | + } | ||
| 61 | + } | ||
| 62 | +</script> | ||
| 63 | + | ||
| 64 | +<style lang="scss" > | ||
| 65 | + .uni-calendar-item__weeks-box { | ||
| 66 | + flex: 1; | ||
| 67 | + /* #ifndef APP-NVUE */ | ||
| 68 | + display: flex; | ||
| 69 | + /* #endif */ | ||
| 70 | + flex-direction: column; | ||
| 71 | + justify-content: center; | ||
| 72 | + align-items: center; | ||
| 73 | + margin: 1px 0; | ||
| 74 | + position: relative; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + .uni-calendar-item__weeks-box-text { | ||
| 78 | + font-size: 14px; | ||
| 79 | + // font-family: Lato-Bold, Lato; | ||
| 80 | + font-weight: bold; | ||
| 81 | + color: #455997; | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + .uni-calendar-item__weeks-lunar-text { | ||
| 85 | + font-size: 12px; | ||
| 86 | + color: #333; | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + .uni-calendar-item__weeks-box-item { | ||
| 90 | + position: relative; | ||
| 91 | + /* #ifndef APP-NVUE */ | ||
| 92 | + display: flex; | ||
| 93 | + /* #endif */ | ||
| 94 | + flex-direction: column; | ||
| 95 | + justify-content: center; | ||
| 96 | + align-items: center; | ||
| 97 | + width: 40px; | ||
| 98 | + height: 40px; | ||
| 99 | + /* #ifdef H5 */ | ||
| 100 | + cursor: pointer; | ||
| 101 | + /* #endif */ | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + | ||
| 105 | + .uni-calendar-item__weeks-box-circle { | ||
| 106 | + position: absolute; | ||
| 107 | + top: 5px; | ||
| 108 | + right: 5px; | ||
| 109 | + width: 8px; | ||
| 110 | + height: 8px; | ||
| 111 | + border-radius: 8px; | ||
| 112 | + background-color: #dd524d; | ||
| 113 | + | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + .uni-calendar-item__weeks-box .uni-calendar-item--disable { | ||
| 117 | + // background-color: rgba(249, 249, 249, $uni-opacity-disabled); | ||
| 118 | + cursor: default; | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + .uni-calendar-item--disable .uni-calendar-item__weeks-box-text-disable { | ||
| 122 | + color: #D1D1D1; | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + .uni-calendar-item--isDay { | ||
| 126 | + position: absolute; | ||
| 127 | + top: 10px; | ||
| 128 | + right: 17%; | ||
| 129 | + background-color: #dd524d; | ||
| 130 | + width:6px; | ||
| 131 | + height: 6px; | ||
| 132 | + border-radius: 50%; | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + .uni-calendar-item--extra { | ||
| 136 | + color: #dd524d; | ||
| 137 | + opacity: 0.8; | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + .uni-calendar-item__weeks-box .uni-calendar-item--checked { | ||
| 141 | + background-color: #007aff; | ||
| 142 | + border-radius: 50%; | ||
| 143 | + box-sizing: border-box; | ||
| 144 | + border: 3px solid #fff; | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + .uni-calendar-item--checked .uni-calendar-item--checked-text { | ||
| 148 | + color: #fff; | ||
| 149 | + } | ||
| 150 | + | ||
| 151 | + .uni-calendar-item--multiple .uni-calendar-item--checked-range-text { | ||
| 152 | + color: #333; | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + .uni-calendar-item--multiple { | ||
| 156 | + background-color: #F6F7FC; | ||
| 157 | + // color: #fff; | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + .uni-calendar-item--multiple .uni-calendar-item--before-checked, | ||
| 161 | + .uni-calendar-item--multiple .uni-calendar-item--after-checked { | ||
| 162 | + background-color: #409eff; | ||
| 163 | + border-radius: 50%; | ||
| 164 | + box-sizing: border-box; | ||
| 165 | + border: 3px solid #F6F7FC; | ||
| 166 | + } | ||
| 167 | + | ||
| 168 | + .uni-calendar-item--before-checked .uni-calendar-item--checked-text, | ||
| 169 | + .uni-calendar-item--after-checked .uni-calendar-item--checked-text { | ||
| 170 | + color: #fff; | ||
| 171 | + } | ||
| 172 | + | ||
| 173 | + .uni-calendar-item--before-checked-x { | ||
| 174 | + border-top-left-radius: 50px; | ||
| 175 | + border-bottom-left-radius: 50px; | ||
| 176 | + box-sizing: border-box; | ||
| 177 | + background-color: #F6F7FC; | ||
| 178 | + } | ||
| 179 | + | ||
| 180 | + .uni-calendar-item--after-checked-x { | ||
| 181 | + border-top-right-radius: 50px; | ||
| 182 | + border-bottom-right-radius: 50px; | ||
| 183 | + background-color: #F6F7FC; | ||
| 184 | + } | ||
| 185 | +</style> |
| 1 | +<template> | ||
| 2 | + <view class="uni-calendar" @mouseleave="leaveCale"> | ||
| 3 | + <view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}" | ||
| 4 | + @click="clean"></view> | ||
| 5 | + <view v-if="insert || show" class="uni-calendar__content" | ||
| 6 | + :class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow, 'uni-calendar__content-mobile': aniMaskShow}"> | ||
| 7 | + <view class="uni-calendar__header" :class="{'uni-calendar__header-mobile' :!insert}"> | ||
| 8 | + <view v-if="left" class="uni-calendar__header-btn-box" @click.stop="pre"> | ||
| 9 | + <view class="uni-calendar__header-btn uni-calendar--left"></view> | ||
| 10 | + </view> | ||
| 11 | + <picker mode="date" :value="date" fields="month" @change="bindDateChange"> | ||
| 12 | + <text | ||
| 13 | + class="uni-calendar__header-text">{{ (nowDate.year||'') + ' 年 ' + ( nowDate.month||'') +' 月'}}</text> | ||
| 14 | + </picker> | ||
| 15 | + <view v-if="right" class="uni-calendar__header-btn-box" @click.stop="next"> | ||
| 16 | + <view class="uni-calendar__header-btn uni-calendar--right"></view> | ||
| 17 | + </view> | ||
| 18 | + <view v-if="!insert" class="dialog-close" @click="clean"> | ||
| 19 | + <view class="dialog-close-plus" data-id="close"></view> | ||
| 20 | + <view class="dialog-close-plus dialog-close-rotate" data-id="close"></view> | ||
| 21 | + </view> | ||
| 22 | + | ||
| 23 | + <!-- <text class="uni-calendar__backtoday" @click="backtoday">回到今天</text> --> | ||
| 24 | + </view> | ||
| 25 | + <view class="uni-calendar__box"> | ||
| 26 | + <view v-if="showMonth" class="uni-calendar__box-bg"> | ||
| 27 | + <text class="uni-calendar__box-bg-text">{{nowDate.month}}</text> | ||
| 28 | + </view> | ||
| 29 | + <view class="uni-calendar__weeks" style="padding-bottom: 7px;"> | ||
| 30 | + <view class="uni-calendar__weeks-day"> | ||
| 31 | + <text class="uni-calendar__weeks-day-text">{{SUNText}}</text> | ||
| 32 | + </view> | ||
| 33 | + <view class="uni-calendar__weeks-day"> | ||
| 34 | + <text class="uni-calendar__weeks-day-text">{{monText}}</text> | ||
| 35 | + </view> | ||
| 36 | + <view class="uni-calendar__weeks-day"> | ||
| 37 | + <text class="uni-calendar__weeks-day-text">{{TUEText}}</text> | ||
| 38 | + </view> | ||
| 39 | + <view class="uni-calendar__weeks-day"> | ||
| 40 | + <text class="uni-calendar__weeks-day-text">{{WEDText}}</text> | ||
| 41 | + </view> | ||
| 42 | + <view class="uni-calendar__weeks-day"> | ||
| 43 | + <text class="uni-calendar__weeks-day-text">{{THUText}}</text> | ||
| 44 | + </view> | ||
| 45 | + <view class="uni-calendar__weeks-day"> | ||
| 46 | + <text class="uni-calendar__weeks-day-text">{{FRIText}}</text> | ||
| 47 | + </view> | ||
| 48 | + <view class="uni-calendar__weeks-day"> | ||
| 49 | + <text class="uni-calendar__weeks-day-text">{{SATText}}</text> | ||
| 50 | + </view> | ||
| 51 | + </view> | ||
| 52 | + <view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex"> | ||
| 53 | + <view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex"> | ||
| 54 | + <calendar-item class="uni-calendar-item--hook" :weeks="weeks" :calendar="calendar" | ||
| 55 | + :selected="selected" :lunar="lunar" :checkHover="range" @change="choiceDate" | ||
| 56 | + @handleMouse="handleMouse"> | ||
| 57 | + </calendar-item> | ||
| 58 | + </view> | ||
| 59 | + </view> | ||
| 60 | + </view> | ||
| 61 | + <view v-if="!insert && !range && typeHasTime" class="uni-date-changed uni-calendar--fixed-top" | ||
| 62 | + style="padding: 0 80px;"> | ||
| 63 | + <view class="uni-date-changed--time-date">{{tempSingleDate ? tempSingleDate : selectDateText}}</view> | ||
| 64 | + <time-picker type="time" :start="reactStartTime" :end="reactEndTime" v-model="time" | ||
| 65 | + :disabled="!tempSingleDate" :border="false" :hide-second="hideSecond" class="time-picker-style"> | ||
| 66 | + </time-picker> | ||
| 67 | + </view> | ||
| 68 | + | ||
| 69 | + <view v-if="!insert && range && typeHasTime" class="uni-date-changed uni-calendar--fixed-top"> | ||
| 70 | + <view class="uni-date-changed--time-start"> | ||
| 71 | + <view class="uni-date-changed--time-date">{{tempRange.before ? tempRange.before : startDateText}} | ||
| 72 | + </view> | ||
| 73 | + <time-picker type="time" :start="reactStartTime" v-model="timeRange.startTime" :border="false" | ||
| 74 | + :hide-second="hideSecond" :disabled="!tempRange.before" class="time-picker-style"> | ||
| 75 | + </time-picker> | ||
| 76 | + </view> | ||
| 77 | + <uni-icons type="arrowthinright" color="#999" style="line-height: 50px;"></uni-icons> | ||
| 78 | + <view class="uni-date-changed--time-end"> | ||
| 79 | + <view class="uni-date-changed--time-date">{{tempRange.after ? tempRange.after : endDateText}}</view> | ||
| 80 | + <time-picker type="time" :end="reactEndTime" v-model="timeRange.endTime" :border="false" | ||
| 81 | + :hide-second="hideSecond" :disabled="!tempRange.after" class="time-picker-style"> | ||
| 82 | + </time-picker> | ||
| 83 | + </view> | ||
| 84 | + </view> | ||
| 85 | + <view v-if="!insert" class="uni-date-changed uni-date-btn--ok"> | ||
| 86 | + <!-- <view class="uni-calendar__header-btn-box"> | ||
| 87 | + <text class="uni-calendar__button-text uni-calendar--fixed-width">{{okText}}</text> | ||
| 88 | + </view> --> | ||
| 89 | + <view class="uni-datetime-picker--btn" @click="confirm">确认</view> | ||
| 90 | + </view> | ||
| 91 | + </view> | ||
| 92 | + </view> | ||
| 93 | +</template> | ||
| 94 | + | ||
| 95 | +<script> | ||
| 96 | + import Calendar from './util.js'; | ||
| 97 | + import calendarItem from './calendar-item.vue' | ||
| 98 | + import timePicker from './time-picker.vue' | ||
| 99 | + import { | ||
| 100 | + initVueI18n | ||
| 101 | + } from '@dcloudio/uni-i18n' | ||
| 102 | + import messages from './i18n/index.js' | ||
| 103 | + const { | ||
| 104 | + t | ||
| 105 | + } = initVueI18n(messages) | ||
| 106 | + /** | ||
| 107 | + * Calendar 日历 | ||
| 108 | + * @description 日历组件可以查看日期,选择任意范围内的日期,打点操作。常用场景如:酒店日期预订、火车机票选择购买日期、上下班打卡等 | ||
| 109 | + * @tutorial https://ext.dcloud.net.cn/plugin?id=56 | ||
| 110 | + * @property {String} date 自定义当前时间,默认为今天 | ||
| 111 | + * @property {Boolean} lunar 显示农历 | ||
| 112 | + * @property {String} startDate 日期选择范围-开始日期 | ||
| 113 | + * @property {String} endDate 日期选择范围-结束日期 | ||
| 114 | + * @property {Boolean} range 范围选择 | ||
| 115 | + * @property {Boolean} insert = [true|false] 插入模式,默认为false | ||
| 116 | + * @value true 弹窗模式 | ||
| 117 | + * @value false 插入模式 | ||
| 118 | + * @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容 | ||
| 119 | + * @property {Array} selected 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}] | ||
| 120 | + * @property {Boolean} showMonth 是否选择月份为背景 | ||
| 121 | + * @event {Function} change 日期改变,`insert :ture` 时生效 | ||
| 122 | + * @event {Function} confirm 确认选择`insert :false` 时生效 | ||
| 123 | + * @event {Function} monthSwitch 切换月份时触发 | ||
| 124 | + * @example <uni-calendar :insert="true":lunar="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" /> | ||
| 125 | + */ | ||
| 126 | + export default { | ||
| 127 | + components: { | ||
| 128 | + calendarItem, | ||
| 129 | + timePicker | ||
| 130 | + }, | ||
| 131 | + props: { | ||
| 132 | + date: { | ||
| 133 | + type: String, | ||
| 134 | + default: '' | ||
| 135 | + }, | ||
| 136 | + defTime: { | ||
| 137 | + type: [String, Object], | ||
| 138 | + default: '' | ||
| 139 | + }, | ||
| 140 | + selectableTimes: { | ||
| 141 | + type: [Object], | ||
| 142 | + default () { | ||
| 143 | + return {} | ||
| 144 | + } | ||
| 145 | + }, | ||
| 146 | + selected: { | ||
| 147 | + type: Array, | ||
| 148 | + default () { | ||
| 149 | + return [] | ||
| 150 | + } | ||
| 151 | + }, | ||
| 152 | + lunar: { | ||
| 153 | + type: Boolean, | ||
| 154 | + default: false | ||
| 155 | + }, | ||
| 156 | + startDate: { | ||
| 157 | + type: String, | ||
| 158 | + default: '' | ||
| 159 | + }, | ||
| 160 | + endDate: { | ||
| 161 | + type: String, | ||
| 162 | + default: '' | ||
| 163 | + }, | ||
| 164 | + range: { | ||
| 165 | + type: Boolean, | ||
| 166 | + default: false | ||
| 167 | + }, | ||
| 168 | + typeHasTime: { | ||
| 169 | + type: Boolean, | ||
| 170 | + default: false | ||
| 171 | + }, | ||
| 172 | + insert: { | ||
| 173 | + type: Boolean, | ||
| 174 | + default: true | ||
| 175 | + }, | ||
| 176 | + showMonth: { | ||
| 177 | + type: Boolean, | ||
| 178 | + default: true | ||
| 179 | + }, | ||
| 180 | + clearDate: { | ||
| 181 | + type: Boolean, | ||
| 182 | + default: true | ||
| 183 | + }, | ||
| 184 | + left: { | ||
| 185 | + type: Boolean, | ||
| 186 | + default: true | ||
| 187 | + }, | ||
| 188 | + right: { | ||
| 189 | + type: Boolean, | ||
| 190 | + default: true | ||
| 191 | + }, | ||
| 192 | + checkHover: { | ||
| 193 | + type: Boolean, | ||
| 194 | + default: true | ||
| 195 | + }, | ||
| 196 | + hideSecond: { | ||
| 197 | + type: [Boolean], | ||
| 198 | + default: false | ||
| 199 | + }, | ||
| 200 | + pleStatus: { | ||
| 201 | + type: Object, | ||
| 202 | + default () { | ||
| 203 | + return { | ||
| 204 | + before: '', | ||
| 205 | + after: '', | ||
| 206 | + data: [], | ||
| 207 | + fulldate: '' | ||
| 208 | + } | ||
| 209 | + } | ||
| 210 | + } | ||
| 211 | + }, | ||
| 212 | + data() { | ||
| 213 | + return { | ||
| 214 | + show: false, | ||
| 215 | + weeks: [], | ||
| 216 | + calendar: {}, | ||
| 217 | + nowDate: '', | ||
| 218 | + aniMaskShow: false, | ||
| 219 | + firstEnter: true, | ||
| 220 | + time: '', | ||
| 221 | + timeRange: { | ||
| 222 | + startTime: '', | ||
| 223 | + endTime: '' | ||
| 224 | + }, | ||
| 225 | + tempSingleDate: '', | ||
| 226 | + tempRange: { | ||
| 227 | + before: '', | ||
| 228 | + after: '' | ||
| 229 | + } | ||
| 230 | + } | ||
| 231 | + }, | ||
| 232 | + watch: { | ||
| 233 | + date: { | ||
| 234 | + immediate: true, | ||
| 235 | + handler(newVal, oldVal) { | ||
| 236 | + if (!this.range) { | ||
| 237 | + this.tempSingleDate = newVal | ||
| 238 | + setTimeout(() => { | ||
| 239 | + this.init(newVal) | ||
| 240 | + }, 100) | ||
| 241 | + } | ||
| 242 | + } | ||
| 243 | + }, | ||
| 244 | + defTime: { | ||
| 245 | + immediate: true, | ||
| 246 | + handler(newVal, oldVal) { | ||
| 247 | + if (!this.range) { | ||
| 248 | + this.time = newVal | ||
| 249 | + } else { | ||
| 250 | + // console.log('-----', newVal); | ||
| 251 | + this.timeRange.startTime = newVal.start | ||
| 252 | + this.timeRange.endTime = newVal.end | ||
| 253 | + } | ||
| 254 | + } | ||
| 255 | + }, | ||
| 256 | + startDate(val) { | ||
| 257 | + this.cale.resetSatrtDate(val) | ||
| 258 | + this.cale.setDate(this.nowDate.fullDate) | ||
| 259 | + this.weeks = this.cale.weeks | ||
| 260 | + }, | ||
| 261 | + endDate(val) { | ||
| 262 | + this.cale.resetEndDate(val) | ||
| 263 | + this.cale.setDate(this.nowDate.fullDate) | ||
| 264 | + this.weeks = this.cale.weeks | ||
| 265 | + }, | ||
| 266 | + selected(newVal) { | ||
| 267 | + this.cale.setSelectInfo(this.nowDate.fullDate, newVal) | ||
| 268 | + this.weeks = this.cale.weeks | ||
| 269 | + }, | ||
| 270 | + pleStatus: { | ||
| 271 | + immediate: true, | ||
| 272 | + handler(newVal, oldVal) { | ||
| 273 | + const { | ||
| 274 | + before, | ||
| 275 | + after, | ||
| 276 | + fulldate, | ||
| 277 | + which | ||
| 278 | + } = newVal | ||
| 279 | + this.tempRange.before = before | ||
| 280 | + this.tempRange.after = after | ||
| 281 | + setTimeout(() => { | ||
| 282 | + if (fulldate) { | ||
| 283 | + this.cale.setHoverMultiple(fulldate) | ||
| 284 | + if (before && after) { | ||
| 285 | + this.cale.lastHover = true | ||
| 286 | + if (this.rangeWithinMonth(after, before)) return | ||
| 287 | + this.setDate(before) | ||
| 288 | + } else { | ||
| 289 | + this.cale.setMultiple(fulldate) | ||
| 290 | + this.setDate(this.nowDate.fullDate) | ||
| 291 | + this.calendar.fullDate = '' | ||
| 292 | + this.cale.lastHover = false | ||
| 293 | + } | ||
| 294 | + } else { | ||
| 295 | + this.cale.setDefaultMultiple(before, after) | ||
| 296 | + if (which === 'left') { | ||
| 297 | + this.setDate(before) | ||
| 298 | + this.weeks = this.cale.weeks | ||
| 299 | + } else { | ||
| 300 | + this.setDate(after) | ||
| 301 | + this.weeks = this.cale.weeks | ||
| 302 | + } | ||
| 303 | + this.cale.lastHover = true | ||
| 304 | + } | ||
| 305 | + }, 16) | ||
| 306 | + } | ||
| 307 | + } | ||
| 308 | + }, | ||
| 309 | + computed: { | ||
| 310 | + reactStartTime() { | ||
| 311 | + const activeDate = this.range ? this.tempRange.before : this.calendar.fullDate | ||
| 312 | + const res = activeDate === this.startDate ? this.selectableTimes.start : '' | ||
| 313 | + return res | ||
| 314 | + }, | ||
| 315 | + reactEndTime() { | ||
| 316 | + const activeDate = this.range ? this.tempRange.after : this.calendar.fullDate | ||
| 317 | + const res = activeDate === this.endDate ? this.selectableTimes.end : '' | ||
| 318 | + return res | ||
| 319 | + }, | ||
| 320 | + /** | ||
| 321 | + * for i18n | ||
| 322 | + */ | ||
| 323 | + selectDateText() { | ||
| 324 | + return t("uni-datetime-picker.selectDate") | ||
| 325 | + }, | ||
| 326 | + startDateText() { | ||
| 327 | + return this.startPlaceholder || t("uni-datetime-picker.startDate") | ||
| 328 | + }, | ||
| 329 | + endDateText() { | ||
| 330 | + return this.endPlaceholder || t("uni-datetime-picker.endDate") | ||
| 331 | + }, | ||
| 332 | + okText() { | ||
| 333 | + return t("uni-datetime-picker.ok") | ||
| 334 | + }, | ||
| 335 | + monText() { | ||
| 336 | + return t("uni-calender.MON") | ||
| 337 | + }, | ||
| 338 | + TUEText() { | ||
| 339 | + return t("uni-calender.TUE") | ||
| 340 | + }, | ||
| 341 | + WEDText() { | ||
| 342 | + return t("uni-calender.WED") | ||
| 343 | + }, | ||
| 344 | + THUText() { | ||
| 345 | + return t("uni-calender.THU") | ||
| 346 | + }, | ||
| 347 | + FRIText() { | ||
| 348 | + return t("uni-calender.FRI") | ||
| 349 | + }, | ||
| 350 | + SATText() { | ||
| 351 | + return t("uni-calender.SAT") | ||
| 352 | + }, | ||
| 353 | + SUNText() { | ||
| 354 | + return t("uni-calender.SUN") | ||
| 355 | + }, | ||
| 356 | + }, | ||
| 357 | + created() { | ||
| 358 | + // 获取日历方法实例 | ||
| 359 | + this.cale = new Calendar({ | ||
| 360 | + // date: new Date(), | ||
| 361 | + selected: this.selected, | ||
| 362 | + startDate: this.startDate, | ||
| 363 | + endDate: this.endDate, | ||
| 364 | + range: this.range, | ||
| 365 | + // multipleStatus: this.pleStatus | ||
| 366 | + }) | ||
| 367 | + // 选中某一天 | ||
| 368 | + // this.cale.setDate(this.date) | ||
| 369 | + this.init(this.date) | ||
| 370 | + // this.setDay | ||
| 371 | + }, | ||
| 372 | + methods: { | ||
| 373 | + leaveCale() { | ||
| 374 | + this.firstEnter = true | ||
| 375 | + }, | ||
| 376 | + handleMouse(weeks) { | ||
| 377 | + if (weeks.disable) return | ||
| 378 | + if (this.cale.lastHover) return | ||
| 379 | + let { | ||
| 380 | + before, | ||
| 381 | + after | ||
| 382 | + } = this.cale.multipleStatus | ||
| 383 | + if (!before) return | ||
| 384 | + this.calendar = weeks | ||
| 385 | + // 设置范围选 | ||
| 386 | + this.cale.setHoverMultiple(this.calendar.fullDate) | ||
| 387 | + this.weeks = this.cale.weeks | ||
| 388 | + // hover时,进入一个日历,更新另一个 | ||
| 389 | + if (this.firstEnter) { | ||
| 390 | + this.$emit('firstEnterCale', this.cale.multipleStatus) | ||
| 391 | + this.firstEnter = false | ||
| 392 | + } | ||
| 393 | + }, | ||
| 394 | + rangeWithinMonth(A, B) { | ||
| 395 | + const [yearA, monthA] = A.split('-') | ||
| 396 | + const [yearB, monthB] = B.split('-') | ||
| 397 | + return yearA === yearB && monthA === monthB | ||
| 398 | + }, | ||
| 399 | + | ||
| 400 | + // 取消穿透 | ||
| 401 | + clean() { | ||
| 402 | + this.close() | ||
| 403 | + }, | ||
| 404 | + | ||
| 405 | + clearCalender() { | ||
| 406 | + if (this.range) { | ||
| 407 | + this.timeRange.startTime = '' | ||
| 408 | + this.timeRange.endTime = '' | ||
| 409 | + this.tempRange.before = '' | ||
| 410 | + this.tempRange.after = '' | ||
| 411 | + this.cale.multipleStatus.before = '' | ||
| 412 | + this.cale.multipleStatus.after = '' | ||
| 413 | + this.cale.multipleStatus.data = [] | ||
| 414 | + this.cale.lastHover = false | ||
| 415 | + } else { | ||
| 416 | + this.time = '' | ||
| 417 | + this.tempSingleDate = '' | ||
| 418 | + } | ||
| 419 | + this.calendar.fullDate = '' | ||
| 420 | + this.setDate() | ||
| 421 | + }, | ||
| 422 | + | ||
| 423 | + bindDateChange(e) { | ||
| 424 | + const value = e.detail.value + '-1' | ||
| 425 | + this.init(value) | ||
| 426 | + }, | ||
| 427 | + /** | ||
| 428 | + * 初始化日期显示 | ||
| 429 | + * @param {Object} date | ||
| 430 | + */ | ||
| 431 | + init(date) { | ||
| 432 | + this.cale.setDate(date) | ||
| 433 | + this.weeks = this.cale.weeks | ||
| 434 | + this.nowDate = this.calendar = this.cale.getInfo(date) | ||
| 435 | + }, | ||
| 436 | + // choiceDate(weeks) { | ||
| 437 | + // if (weeks.disable) return | ||
| 438 | + // this.calendar = weeks | ||
| 439 | + // // 设置多选 | ||
| 440 | + // this.cale.setMultiple(this.calendar.fullDate, true) | ||
| 441 | + // this.weeks = this.cale.weeks | ||
| 442 | + // this.tempSingleDate = this.calendar.fullDate | ||
| 443 | + // this.tempRange.before = this.cale.multipleStatus.before | ||
| 444 | + // this.tempRange.after = this.cale.multipleStatus.after | ||
| 445 | + // this.change() | ||
| 446 | + // }, | ||
| 447 | + /** | ||
| 448 | + * 打开日历弹窗 | ||
| 449 | + */ | ||
| 450 | + open() { | ||
| 451 | + // 弹窗模式并且清理数据 | ||
| 452 | + if (this.clearDate && !this.insert) { | ||
| 453 | + this.cale.cleanMultipleStatus() | ||
| 454 | + // this.cale.setDate(this.date) | ||
| 455 | + this.init(this.date) | ||
| 456 | + } | ||
| 457 | + this.show = true | ||
| 458 | + this.$nextTick(() => { | ||
| 459 | + setTimeout(() => { | ||
| 460 | + this.aniMaskShow = true | ||
| 461 | + }, 50) | ||
| 462 | + }) | ||
| 463 | + }, | ||
| 464 | + /** | ||
| 465 | + * 关闭日历弹窗 | ||
| 466 | + */ | ||
| 467 | + close() { | ||
| 468 | + this.aniMaskShow = false | ||
| 469 | + this.$nextTick(() => { | ||
| 470 | + setTimeout(() => { | ||
| 471 | + this.show = false | ||
| 472 | + this.$emit('close') | ||
| 473 | + }, 300) | ||
| 474 | + }) | ||
| 475 | + }, | ||
| 476 | + /** | ||
| 477 | + * 确认按钮 | ||
| 478 | + */ | ||
| 479 | + confirm() { | ||
| 480 | + this.setEmit('confirm') | ||
| 481 | + this.close() | ||
| 482 | + }, | ||
| 483 | + /** | ||
| 484 | + * 变化触发 | ||
| 485 | + */ | ||
| 486 | + change() { | ||
| 487 | + if (!this.insert) return | ||
| 488 | + this.setEmit('change') | ||
| 489 | + }, | ||
| 490 | + /** | ||
| 491 | + * 选择月份触发 | ||
| 492 | + */ | ||
| 493 | + monthSwitch() { | ||
| 494 | + let { | ||
| 495 | + year, | ||
| 496 | + month | ||
| 497 | + } = this.nowDate | ||
| 498 | + this.$emit('monthSwitch', { | ||
| 499 | + year, | ||
| 500 | + month: Number(month) | ||
| 501 | + }) | ||
| 502 | + }, | ||
| 503 | + /** | ||
| 504 | + * 派发事件 | ||
| 505 | + * @param {Object} name | ||
| 506 | + */ | ||
| 507 | + setEmit(name) { | ||
| 508 | + let { | ||
| 509 | + year, | ||
| 510 | + month, | ||
| 511 | + date, | ||
| 512 | + fullDate, | ||
| 513 | + lunar, | ||
| 514 | + extraInfo | ||
| 515 | + } = this.calendar | ||
| 516 | + this.$emit(name, { | ||
| 517 | + range: this.cale.multipleStatus, | ||
| 518 | + year, | ||
| 519 | + month, | ||
| 520 | + date, | ||
| 521 | + time: this.time, | ||
| 522 | + timeRange: this.timeRange, | ||
| 523 | + fulldate: fullDate, | ||
| 524 | + lunar, | ||
| 525 | + extraInfo: extraInfo || {} | ||
| 526 | + }) | ||
| 527 | + }, | ||
| 528 | + /** | ||
| 529 | + * 选择天触发 | ||
| 530 | + * @param {Object} weeks | ||
| 531 | + */ | ||
| 532 | + choiceDate(weeks) { | ||
| 533 | + if (weeks.disable) return | ||
| 534 | + this.calendar = weeks | ||
| 535 | + this.calendar.userChecked = true | ||
| 536 | + // 设置多选 | ||
| 537 | + this.cale.setMultiple(this.calendar.fullDate, true) | ||
| 538 | + this.weeks = this.cale.weeks | ||
| 539 | + this.tempSingleDate = this.calendar.fullDate | ||
| 540 | + this.tempRange.before = this.cale.multipleStatus.before | ||
| 541 | + this.tempRange.after = this.cale.multipleStatus.after | ||
| 542 | + this.change() | ||
| 543 | + }, | ||
| 544 | + /** | ||
| 545 | + * 回到今天 | ||
| 546 | + */ | ||
| 547 | + backtoday() { | ||
| 548 | + let date = this.cale.getDate(new Date()).fullDate | ||
| 549 | + // this.cale.setDate(date) | ||
| 550 | + this.init(date) | ||
| 551 | + this.change() | ||
| 552 | + }, | ||
| 553 | + /** | ||
| 554 | + * 比较时间大小 | ||
| 555 | + */ | ||
| 556 | + dateCompare(startDate, endDate) { | ||
| 557 | + // 计算截止时间 | ||
| 558 | + startDate = new Date(startDate.replace('-', '/').replace('-', '/')) | ||
| 559 | + // 计算详细项的截止时间 | ||
| 560 | + endDate = new Date(endDate.replace('-', '/').replace('-', '/')) | ||
| 561 | + if (startDate <= endDate) { | ||
| 562 | + return true | ||
| 563 | + } else { | ||
| 564 | + return false | ||
| 565 | + } | ||
| 566 | + }, | ||
| 567 | + /** | ||
| 568 | + * 上个月 | ||
| 569 | + */ | ||
| 570 | + pre() { | ||
| 571 | + const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate | ||
| 572 | + this.setDate(preDate) | ||
| 573 | + this.monthSwitch() | ||
| 574 | + | ||
| 575 | + }, | ||
| 576 | + /** | ||
| 577 | + * 下个月 | ||
| 578 | + */ | ||
| 579 | + next() { | ||
| 580 | + const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate | ||
| 581 | + this.setDate(nextDate) | ||
| 582 | + this.monthSwitch() | ||
| 583 | + }, | ||
| 584 | + /** | ||
| 585 | + * 设置日期 | ||
| 586 | + * @param {Object} date | ||
| 587 | + */ | ||
| 588 | + setDate(date) { | ||
| 589 | + this.cale.setDate(date) | ||
| 590 | + this.weeks = this.cale.weeks | ||
| 591 | + this.nowDate = this.cale.getInfo(date) | ||
| 592 | + } | ||
| 593 | + } | ||
| 594 | + } | ||
| 595 | +</script> | ||
| 596 | + | ||
| 597 | +<style lang="scss" > | ||
| 598 | + .uni-calendar { | ||
| 599 | + /* #ifndef APP-NVUE */ | ||
| 600 | + display: flex; | ||
| 601 | + /* #endif */ | ||
| 602 | + flex-direction: column; | ||
| 603 | + } | ||
| 604 | + | ||
| 605 | + .uni-calendar__mask { | ||
| 606 | + position: fixed; | ||
| 607 | + bottom: 0; | ||
| 608 | + top: 0; | ||
| 609 | + left: 0; | ||
| 610 | + right: 0; | ||
| 611 | + background-color: rgba(0, 0, 0, 0.4); | ||
| 612 | + transition-property: opacity; | ||
| 613 | + transition-duration: 0.3s; | ||
| 614 | + opacity: 0; | ||
| 615 | + /* #ifndef APP-NVUE */ | ||
| 616 | + z-index: 99; | ||
| 617 | + /* #endif */ | ||
| 618 | + } | ||
| 619 | + | ||
| 620 | + .uni-calendar--mask-show { | ||
| 621 | + opacity: 1 | ||
| 622 | + } | ||
| 623 | + | ||
| 624 | + .uni-calendar--fixed { | ||
| 625 | + position: fixed; | ||
| 626 | + bottom: calc(var(--window-bottom)); | ||
| 627 | + left: 0; | ||
| 628 | + right: 0; | ||
| 629 | + transition-property: transform; | ||
| 630 | + transition-duration: 0.3s; | ||
| 631 | + transform: translateY(460px); | ||
| 632 | + /* #ifndef APP-NVUE */ | ||
| 633 | + z-index: 99; | ||
| 634 | + /* #endif */ | ||
| 635 | + } | ||
| 636 | + | ||
| 637 | + .uni-calendar--ani-show { | ||
| 638 | + transform: translateY(0); | ||
| 639 | + } | ||
| 640 | + | ||
| 641 | + .uni-calendar__content { | ||
| 642 | + background-color: #fff; | ||
| 643 | + } | ||
| 644 | + | ||
| 645 | + .uni-calendar__content-mobile { | ||
| 646 | + border-top-left-radius: 10px; | ||
| 647 | + border-top-right-radius: 10px; | ||
| 648 | + box-shadow: 0px 0px 5px 3px rgba(0, 0, 0, 0.1); | ||
| 649 | + } | ||
| 650 | + | ||
| 651 | + .uni-calendar__header { | ||
| 652 | + position: relative; | ||
| 653 | + /* #ifndef APP-NVUE */ | ||
| 654 | + display: flex; | ||
| 655 | + /* #endif */ | ||
| 656 | + flex-direction: row; | ||
| 657 | + justify-content: center; | ||
| 658 | + align-items: center; | ||
| 659 | + height: 50px; | ||
| 660 | + } | ||
| 661 | + | ||
| 662 | + .uni-calendar__header-mobile { | ||
| 663 | + padding: 10px; | ||
| 664 | + padding-bottom: 0; | ||
| 665 | + } | ||
| 666 | + | ||
| 667 | + .uni-calendar--fixed-top { | ||
| 668 | + /* #ifndef APP-NVUE */ | ||
| 669 | + display: flex; | ||
| 670 | + /* #endif */ | ||
| 671 | + flex-direction: row; | ||
| 672 | + justify-content: space-between; | ||
| 673 | + border-top-color: rgba(0, 0, 0, 0.4); | ||
| 674 | + border-top-style: solid; | ||
| 675 | + border-top-width: 1px; | ||
| 676 | + } | ||
| 677 | + | ||
| 678 | + .uni-calendar--fixed-width { | ||
| 679 | + width: 50px; | ||
| 680 | + } | ||
| 681 | + | ||
| 682 | + .uni-calendar__backtoday { | ||
| 683 | + position: absolute; | ||
| 684 | + right: 0; | ||
| 685 | + top: 25rpx; | ||
| 686 | + padding: 0 5px; | ||
| 687 | + padding-left: 10px; | ||
| 688 | + height: 25px; | ||
| 689 | + line-height: 25px; | ||
| 690 | + font-size: 12px; | ||
| 691 | + border-top-left-radius: 25px; | ||
| 692 | + border-bottom-left-radius: 25px; | ||
| 693 | + color: #fff; | ||
| 694 | + background-color: #f1f1f1; | ||
| 695 | + } | ||
| 696 | + | ||
| 697 | + .uni-calendar__header-text { | ||
| 698 | + text-align: center; | ||
| 699 | + width: 100px; | ||
| 700 | + font-size: 15px; | ||
| 701 | + color: #666; | ||
| 702 | + } | ||
| 703 | + | ||
| 704 | + .uni-calendar__button-text { | ||
| 705 | + text-align: center; | ||
| 706 | + width: 100px; | ||
| 707 | + font-size: 14px; | ||
| 708 | + color: #007aff; | ||
| 709 | + /* #ifndef APP-NVUE */ | ||
| 710 | + letter-spacing: 3px; | ||
| 711 | + /* #endif */ | ||
| 712 | + } | ||
| 713 | + | ||
| 714 | + .uni-calendar__header-btn-box { | ||
| 715 | + /* #ifndef APP-NVUE */ | ||
| 716 | + display: flex; | ||
| 717 | + /* #endif */ | ||
| 718 | + flex-direction: row; | ||
| 719 | + align-items: center; | ||
| 720 | + justify-content: center; | ||
| 721 | + width: 50px; | ||
| 722 | + height: 50px; | ||
| 723 | + } | ||
| 724 | + | ||
| 725 | + .uni-calendar__header-btn { | ||
| 726 | + width: 9px; | ||
| 727 | + height: 9px; | ||
| 728 | + border-left-color: #808080; | ||
| 729 | + border-left-style: solid; | ||
| 730 | + border-left-width: 1px; | ||
| 731 | + border-top-color: #555555; | ||
| 732 | + border-top-style: solid; | ||
| 733 | + border-top-width: 1px; | ||
| 734 | + } | ||
| 735 | + | ||
| 736 | + .uni-calendar--left { | ||
| 737 | + transform: rotate(-45deg); | ||
| 738 | + } | ||
| 739 | + | ||
| 740 | + .uni-calendar--right { | ||
| 741 | + transform: rotate(135deg); | ||
| 742 | + } | ||
| 743 | + | ||
| 744 | + | ||
| 745 | + .uni-calendar__weeks { | ||
| 746 | + position: relative; | ||
| 747 | + /* #ifndef APP-NVUE */ | ||
| 748 | + display: flex; | ||
| 749 | + /* #endif */ | ||
| 750 | + flex-direction: row; | ||
| 751 | + } | ||
| 752 | + | ||
| 753 | + .uni-calendar__weeks-item { | ||
| 754 | + flex: 1; | ||
| 755 | + } | ||
| 756 | + | ||
| 757 | + .uni-calendar__weeks-day { | ||
| 758 | + flex: 1; | ||
| 759 | + /* #ifndef APP-NVUE */ | ||
| 760 | + display: flex; | ||
| 761 | + /* #endif */ | ||
| 762 | + flex-direction: column; | ||
| 763 | + justify-content: center; | ||
| 764 | + align-items: center; | ||
| 765 | + height: 40px; | ||
| 766 | + border-bottom-color: #F5F5F5; | ||
| 767 | + border-bottom-style: solid; | ||
| 768 | + border-bottom-width: 1px; | ||
| 769 | + } | ||
| 770 | + | ||
| 771 | + .uni-calendar__weeks-day-text { | ||
| 772 | + font-size: 12px; | ||
| 773 | + color: #B2B2B2; | ||
| 774 | + } | ||
| 775 | + | ||
| 776 | + .uni-calendar__box { | ||
| 777 | + position: relative; | ||
| 778 | + // padding: 0 10px; | ||
| 779 | + padding-bottom: 7px; | ||
| 780 | + } | ||
| 781 | + | ||
| 782 | + .uni-calendar__box-bg { | ||
| 783 | + /* #ifndef APP-NVUE */ | ||
| 784 | + display: flex; | ||
| 785 | + /* #endif */ | ||
| 786 | + justify-content: center; | ||
| 787 | + align-items: center; | ||
| 788 | + position: absolute; | ||
| 789 | + top: 0; | ||
| 790 | + left: 0; | ||
| 791 | + right: 0; | ||
| 792 | + bottom: 0; | ||
| 793 | + } | ||
| 794 | + | ||
| 795 | + .uni-calendar__box-bg-text { | ||
| 796 | + font-size: 200px; | ||
| 797 | + font-weight: bold; | ||
| 798 | + color: #999; | ||
| 799 | + opacity: 0.1; | ||
| 800 | + text-align: center; | ||
| 801 | + /* #ifndef APP-NVUE */ | ||
| 802 | + line-height: 1; | ||
| 803 | + /* #endif */ | ||
| 804 | + } | ||
| 805 | + | ||
| 806 | + .uni-date-changed { | ||
| 807 | + padding: 0 10px; | ||
| 808 | + // line-height: 50px; | ||
| 809 | + text-align: center; | ||
| 810 | + color: #333; | ||
| 811 | + border-top-color: #DCDCDC; | ||
| 812 | + ; | ||
| 813 | + border-top-style: solid; | ||
| 814 | + border-top-width: 1px; | ||
| 815 | + flex: 1; | ||
| 816 | + } | ||
| 817 | + | ||
| 818 | + .uni-date-btn--ok { | ||
| 819 | + padding: 20px 15px; | ||
| 820 | + } | ||
| 821 | + | ||
| 822 | + .uni-date-changed--time-start { | ||
| 823 | + /* #ifndef APP-NVUE */ | ||
| 824 | + display: flex; | ||
| 825 | + /* #endif */ | ||
| 826 | + align-items: center; | ||
| 827 | + } | ||
| 828 | + | ||
| 829 | + .uni-date-changed--time-end { | ||
| 830 | + /* #ifndef APP-NVUE */ | ||
| 831 | + display: flex; | ||
| 832 | + /* #endif */ | ||
| 833 | + align-items: center; | ||
| 834 | + } | ||
| 835 | + | ||
| 836 | + .uni-date-changed--time-date { | ||
| 837 | + color: #999; | ||
| 838 | + line-height: 50px; | ||
| 839 | + margin-right: 5px; | ||
| 840 | + // opacity: 0.6; | ||
| 841 | + } | ||
| 842 | + | ||
| 843 | + .time-picker-style { | ||
| 844 | + // width: 62px; | ||
| 845 | + /* #ifndef APP-NVUE */ | ||
| 846 | + display: flex; | ||
| 847 | + /* #endif */ | ||
| 848 | + justify-content: center; | ||
| 849 | + align-items: center | ||
| 850 | + } | ||
| 851 | + | ||
| 852 | + .mr-10 { | ||
| 853 | + margin-right: 10px; | ||
| 854 | + } | ||
| 855 | + | ||
| 856 | + .dialog-close { | ||
| 857 | + position: absolute; | ||
| 858 | + top: 0; | ||
| 859 | + right: 0; | ||
| 860 | + bottom: 0; | ||
| 861 | + /* #ifndef APP-NVUE */ | ||
| 862 | + display: flex; | ||
| 863 | + /* #endif */ | ||
| 864 | + flex-direction: row; | ||
| 865 | + align-items: center; | ||
| 866 | + padding: 0 25px; | ||
| 867 | + margin-top: 10px; | ||
| 868 | + } | ||
| 869 | + | ||
| 870 | + .dialog-close-plus { | ||
| 871 | + width: 16px; | ||
| 872 | + height: 2px; | ||
| 873 | + background-color: #737987; | ||
| 874 | + border-radius: 2px; | ||
| 875 | + transform: rotate(45deg); | ||
| 876 | + } | ||
| 877 | + | ||
| 878 | + .dialog-close-rotate { | ||
| 879 | + position: absolute; | ||
| 880 | + transform: rotate(-45deg); | ||
| 881 | + } | ||
| 882 | + | ||
| 883 | + .uni-datetime-picker--btn { | ||
| 884 | + border-radius: 100px; | ||
| 885 | + height: 40px; | ||
| 886 | + line-height: 40px; | ||
| 887 | + background-color: #007aff; | ||
| 888 | + color: #fff; | ||
| 889 | + font-size: 16px; | ||
| 890 | + letter-spacing: 5px; | ||
| 891 | + } | ||
| 892 | + | ||
| 893 | + /* #ifndef APP-NVUE */ | ||
| 894 | + .uni-datetime-picker--btn:active { | ||
| 895 | + opacity: 0.7; | ||
| 896 | + } | ||
| 897 | + /* #endif */ | ||
| 898 | +</style> |
| 1 | +{ | ||
| 2 | + "uni-datetime-picker.selectDate": "select date", | ||
| 3 | + "uni-datetime-picker.selectTime": "select time", | ||
| 4 | + "uni-datetime-picker.selectDateTime": "select datetime", | ||
| 5 | + "uni-datetime-picker.startDate": "start date", | ||
| 6 | + "uni-datetime-picker.endDate": "end date", | ||
| 7 | + "uni-datetime-picker.startTime": "start time", | ||
| 8 | + "uni-datetime-picker.endTime": "end time", | ||
| 9 | + "uni-datetime-picker.ok": "ok", | ||
| 10 | + "uni-datetime-picker.clear": "clear", | ||
| 11 | + "uni-datetime-picker.cancel": "cancel", | ||
| 12 | + "uni-calender.MON": "MON", | ||
| 13 | + "uni-calender.TUE": "TUE", | ||
| 14 | + "uni-calender.WED": "WED", | ||
| 15 | + "uni-calender.THU": "THU", | ||
| 16 | + "uni-calender.FRI": "FRI", | ||
| 17 | + "uni-calender.SAT": "SAT", | ||
| 18 | + "uni-calender.SUN": "SUN" | ||
| 19 | +} |
| 1 | +{ | ||
| 2 | + "uni-datetime-picker.selectDate": "选择日期", | ||
| 3 | + "uni-datetime-picker.selectTime": "选择时间", | ||
| 4 | + "uni-datetime-picker.selectDateTime": "选择日期时间", | ||
| 5 | + "uni-datetime-picker.startDate": "开始日期", | ||
| 6 | + "uni-datetime-picker.endDate": "结束日期", | ||
| 7 | + "uni-datetime-picker.startTime": "开始时间", | ||
| 8 | + "uni-datetime-picker.endTime": "结束时间", | ||
| 9 | + "uni-datetime-picker.ok": "确定", | ||
| 10 | + "uni-datetime-picker.clear": "清除", | ||
| 11 | + "uni-datetime-picker.cancel": "取消", | ||
| 12 | + "uni-calender.SUN": "日", | ||
| 13 | + "uni-calender.MON": "一", | ||
| 14 | + "uni-calender.TUE": "二", | ||
| 15 | + "uni-calender.WED": "三", | ||
| 16 | + "uni-calender.THU": "四", | ||
| 17 | + "uni-calender.FRI": "五", | ||
| 18 | + "uni-calender.SAT": "六" | ||
| 19 | +} |
| 1 | +{ | ||
| 2 | + "uni-datetime-picker.selectDate": "選擇日期", | ||
| 3 | + "uni-datetime-picker.selectTime": "選擇時間", | ||
| 4 | + "uni-datetime-picker.selectDateTime": "選擇日期時間", | ||
| 5 | + "uni-datetime-picker.startDate": "開始日期", | ||
| 6 | + "uni-datetime-picker.endDate": "結束日期", | ||
| 7 | + "uni-datetime-picker.startTime": "開始时间", | ||
| 8 | + "uni-datetime-picker.endTime": "結束时间", | ||
| 9 | + "uni-datetime-picker.ok": "確定", | ||
| 10 | + "uni-datetime-picker.clear": "清除", | ||
| 11 | + "uni-datetime-picker.cancel": "取消", | ||
| 12 | + "uni-calender.SUN": "日", | ||
| 13 | + "uni-calender.MON": "一", | ||
| 14 | + "uni-calender.TUE": "二", | ||
| 15 | + "uni-calender.WED": "三", | ||
| 16 | + "uni-calender.THU": "四", | ||
| 17 | + "uni-calender.FRI": "五", | ||
| 18 | + "uni-calender.SAT": "六" | ||
| 19 | +} |
| 1 | +// #ifdef H5 | ||
| 2 | +export default { | ||
| 3 | + name: 'Keypress', | ||
| 4 | + props: { | ||
| 5 | + disable: { | ||
| 6 | + type: Boolean, | ||
| 7 | + default: false | ||
| 8 | + } | ||
| 9 | + }, | ||
| 10 | + mounted () { | ||
| 11 | + const keyNames = { | ||
| 12 | + esc: ['Esc', 'Escape'], | ||
| 13 | + tab: 'Tab', | ||
| 14 | + enter: 'Enter', | ||
| 15 | + space: [' ', 'Spacebar'], | ||
| 16 | + up: ['Up', 'ArrowUp'], | ||
| 17 | + left: ['Left', 'ArrowLeft'], | ||
| 18 | + right: ['Right', 'ArrowRight'], | ||
| 19 | + down: ['Down', 'ArrowDown'], | ||
| 20 | + delete: ['Backspace', 'Delete', 'Del'] | ||
| 21 | + } | ||
| 22 | + const listener = ($event) => { | ||
| 23 | + if (this.disable) { | ||
| 24 | + return | ||
| 25 | + } | ||
| 26 | + const keyName = Object.keys(keyNames).find(key => { | ||
| 27 | + const keyName = $event.key | ||
| 28 | + const value = keyNames[key] | ||
| 29 | + return value === keyName || (Array.isArray(value) && value.includes(keyName)) | ||
| 30 | + }) | ||
| 31 | + if (keyName) { | ||
| 32 | + // 避免和其他按键事件冲突 | ||
| 33 | + setTimeout(() => { | ||
| 34 | + this.$emit(keyName, {}) | ||
| 35 | + }, 0) | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | + document.addEventListener('keyup', listener) | ||
| 39 | + this.$once('hook:beforeDestroy', () => { | ||
| 40 | + document.removeEventListener('keyup', listener) | ||
| 41 | + }) | ||
| 42 | + }, | ||
| 43 | + render: () => {} | ||
| 44 | +} | ||
| 45 | +// #endif |
| 1 | +<template> | ||
| 2 | + <view class="uni-datetime-picker"> | ||
| 3 | + <view @click="initTimePicker"> | ||
| 4 | + <slot> | ||
| 5 | + <view class="uni-datetime-picker-timebox-pointer" | ||
| 6 | + :class="{'uni-datetime-picker-disabled': disabled, 'uni-datetime-picker-timebox': border}"> | ||
| 7 | + <text class="uni-datetime-picker-text">{{time}}</text> | ||
| 8 | + <view v-if="!time" class="uni-datetime-picker-time"> | ||
| 9 | + <text class="uni-datetime-picker-text">{{selectTimeText}}</text> | ||
| 10 | + </view> | ||
| 11 | + </view> | ||
| 12 | + </slot> | ||
| 13 | + </view> | ||
| 14 | + <view v-if="visible" id="mask" class="uni-datetime-picker-mask" @click="tiggerTimePicker"></view> | ||
| 15 | + <view v-if="visible" class="uni-datetime-picker-popup" :class="[dateShow && timeShow ? '' : 'fix-nvue-height']" | ||
| 16 | + :style="fixNvueBug"> | ||
| 17 | + <view class="uni-title"> | ||
| 18 | + <text class="uni-datetime-picker-text">{{selectTimeText}}</text> | ||
| 19 | + </view> | ||
| 20 | + <view v-if="dateShow" class="uni-datetime-picker__container-box"> | ||
| 21 | + <picker-view class="uni-datetime-picker-view" :indicator-style="indicatorStyle" :value="ymd" | ||
| 22 | + @change="bindDateChange"> | ||
| 23 | + <picker-view-column> | ||
| 24 | + <view class="uni-datetime-picker-item" v-for="(item,index) in years" :key="index"> | ||
| 25 | + <text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text> | ||
| 26 | + </view> | ||
| 27 | + </picker-view-column> | ||
| 28 | + <picker-view-column> | ||
| 29 | + <view class="uni-datetime-picker-item" v-for="(item,index) in months" :key="index"> | ||
| 30 | + <text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text> | ||
| 31 | + </view> | ||
| 32 | + </picker-view-column> | ||
| 33 | + <picker-view-column> | ||
| 34 | + <view class="uni-datetime-picker-item" v-for="(item,index) in days" :key="index"> | ||
| 35 | + <text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text> | ||
| 36 | + </view> | ||
| 37 | + </picker-view-column> | ||
| 38 | + </picker-view> | ||
| 39 | + <!-- 兼容 nvue 不支持伪类 --> | ||
| 40 | + <text class="uni-datetime-picker-sign sign-left">-</text> | ||
| 41 | + <text class="uni-datetime-picker-sign sign-right">-</text> | ||
| 42 | + </view> | ||
| 43 | + <view v-if="timeShow" class="uni-datetime-picker__container-box"> | ||
| 44 | + <picker-view class="uni-datetime-picker-view" :class="[hideSecond ? 'time-hide-second' : '']" | ||
| 45 | + :indicator-style="indicatorStyle" :value="hms" @change="bindTimeChange"> | ||
| 46 | + <picker-view-column> | ||
| 47 | + <view class="uni-datetime-picker-item" v-for="(item,index) in hours" :key="index"> | ||
| 48 | + <text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text> | ||
| 49 | + </view> | ||
| 50 | + </picker-view-column> | ||
| 51 | + <picker-view-column> | ||
| 52 | + <view class="uni-datetime-picker-item" v-for="(item,index) in minutes" :key="index"> | ||
| 53 | + <text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text> | ||
| 54 | + </view> | ||
| 55 | + </picker-view-column> | ||
| 56 | + <picker-view-column v-if="!hideSecond"> | ||
| 57 | + <view class="uni-datetime-picker-item" v-for="(item,index) in seconds" :key="index"> | ||
| 58 | + <text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text> | ||
| 59 | + </view> | ||
| 60 | + </picker-view-column> | ||
| 61 | + </picker-view> | ||
| 62 | + <!-- 兼容 nvue 不支持伪类 --> | ||
| 63 | + <text class="uni-datetime-picker-sign" :class="[hideSecond ? 'sign-center' : 'sign-left']">:</text> | ||
| 64 | + <text v-if="!hideSecond" class="uni-datetime-picker-sign sign-right">:</text> | ||
| 65 | + </view> | ||
| 66 | + <view class="uni-datetime-picker-btn"> | ||
| 67 | + <view @click="clearTime"> | ||
| 68 | + <text class="uni-datetime-picker-btn-text">{{clearText}}</text> | ||
| 69 | + </view> | ||
| 70 | + <view class="uni-datetime-picker-btn-group"> | ||
| 71 | + <view class="uni-datetime-picker-cancel" @click="tiggerTimePicker"> | ||
| 72 | + <text class="uni-datetime-picker-btn-text">{{cancelText}}</text> | ||
| 73 | + </view> | ||
| 74 | + <view @click="setTime"> | ||
| 75 | + <text class="uni-datetime-picker-btn-text">{{okText}}</text> | ||
| 76 | + </view> | ||
| 77 | + </view> | ||
| 78 | + </view> | ||
| 79 | + </view> | ||
| 80 | + <!-- #ifdef H5 --> | ||
| 81 | + <!-- <keypress v-if="visible" @esc="tiggerTimePicker" @enter="setTime" /> --> | ||
| 82 | + <!-- #endif --> | ||
| 83 | + </view> | ||
| 84 | +</template> | ||
| 85 | + | ||
| 86 | +<script> | ||
| 87 | + // #ifdef H5 | ||
| 88 | + import keypress from './keypress' | ||
| 89 | + // #endif | ||
| 90 | + import { | ||
| 91 | + initVueI18n | ||
| 92 | + } from '@dcloudio/uni-i18n' | ||
| 93 | + import messages from './i18n/index.js' | ||
| 94 | + const { t } = initVueI18n(messages) | ||
| 95 | + | ||
| 96 | + /** | ||
| 97 | + * DatetimePicker 时间选择器 | ||
| 98 | + * @description 可以同时选择日期和时间的选择器 | ||
| 99 | + * @tutorial https://ext.dcloud.net.cn/plugin?id=xxx | ||
| 100 | + * @property {String} type = [datetime | date | time] 显示模式 | ||
| 101 | + * @property {Boolean} multiple = [true|false] 是否多选 | ||
| 102 | + * @property {String|Number} value 默认值 | ||
| 103 | + * @property {String|Number} start 起始日期或时间 | ||
| 104 | + * @property {String|Number} end 起始日期或时间 | ||
| 105 | + * @property {String} return-type = [timestamp | string] | ||
| 106 | + * @event {Function} change 选中发生变化触发 | ||
| 107 | + */ | ||
| 108 | + | ||
| 109 | + export default { | ||
| 110 | + name: 'UniDatetimePicker', | ||
| 111 | + components: { | ||
| 112 | + // #ifdef H5 | ||
| 113 | + keypress | ||
| 114 | + // #endif | ||
| 115 | + }, | ||
| 116 | + data() { | ||
| 117 | + return { | ||
| 118 | + indicatorStyle: `height: 50px;`, | ||
| 119 | + visible: false, | ||
| 120 | + fixNvueBug: {}, | ||
| 121 | + dateShow: true, | ||
| 122 | + timeShow: true, | ||
| 123 | + title: '日期和时间', | ||
| 124 | + // 输入框当前时间 | ||
| 125 | + time: '', | ||
| 126 | + // 当前的年月日时分秒 | ||
| 127 | + year: 1920, | ||
| 128 | + month: 0, | ||
| 129 | + day: 0, | ||
| 130 | + hour: 0, | ||
| 131 | + minute: 0, | ||
| 132 | + second: 0, | ||
| 133 | + // 起始时间 | ||
| 134 | + startYear: 1920, | ||
| 135 | + startMonth: 1, | ||
| 136 | + startDay: 1, | ||
| 137 | + startHour: 0, | ||
| 138 | + startMinute: 0, | ||
| 139 | + startSecond: 0, | ||
| 140 | + // 结束时间 | ||
| 141 | + endYear: 2120, | ||
| 142 | + endMonth: 12, | ||
| 143 | + endDay: 31, | ||
| 144 | + endHour: 23, | ||
| 145 | + endMinute: 59, | ||
| 146 | + endSecond: 59, | ||
| 147 | + } | ||
| 148 | + }, | ||
| 149 | + props: { | ||
| 150 | + type: { | ||
| 151 | + type: String, | ||
| 152 | + default: 'datetime' | ||
| 153 | + }, | ||
| 154 | + value: { | ||
| 155 | + type: [String, Number], | ||
| 156 | + default: '' | ||
| 157 | + }, | ||
| 158 | + modelValue: { | ||
| 159 | + type: [String, Number], | ||
| 160 | + default: '' | ||
| 161 | + }, | ||
| 162 | + start: { | ||
| 163 | + type: [Number, String], | ||
| 164 | + default: '' | ||
| 165 | + }, | ||
| 166 | + end: { | ||
| 167 | + type: [Number, String], | ||
| 168 | + default: '' | ||
| 169 | + }, | ||
| 170 | + returnType: { | ||
| 171 | + type: String, | ||
| 172 | + default: 'string' | ||
| 173 | + }, | ||
| 174 | + disabled: { | ||
| 175 | + type: [Boolean, String], | ||
| 176 | + default: false | ||
| 177 | + }, | ||
| 178 | + border: { | ||
| 179 | + type: [Boolean, String], | ||
| 180 | + default: true | ||
| 181 | + }, | ||
| 182 | + hideSecond: { | ||
| 183 | + type: [Boolean, String], | ||
| 184 | + default: false | ||
| 185 | + } | ||
| 186 | + }, | ||
| 187 | + watch: { | ||
| 188 | + value: { | ||
| 189 | + handler(newVal, oldVal) { | ||
| 190 | + if (newVal) { | ||
| 191 | + this.parseValue(this.fixIosDateFormat(newVal)) //兼容 iOS、safari 日期格式 | ||
| 192 | + this.initTime(false) | ||
| 193 | + } else { | ||
| 194 | + this.time = '' | ||
| 195 | + this.parseValue(Date.now()) | ||
| 196 | + } | ||
| 197 | + }, | ||
| 198 | + immediate: true | ||
| 199 | + }, | ||
| 200 | + type: { | ||
| 201 | + handler(newValue) { | ||
| 202 | + if (newValue === 'date') { | ||
| 203 | + this.dateShow = true | ||
| 204 | + this.timeShow = false | ||
| 205 | + this.title = '日期' | ||
| 206 | + } else if (newValue === 'time') { | ||
| 207 | + this.dateShow = false | ||
| 208 | + this.timeShow = true | ||
| 209 | + this.title = '时间' | ||
| 210 | + } else { | ||
| 211 | + this.dateShow = true | ||
| 212 | + this.timeShow = true | ||
| 213 | + this.title = '日期和时间' | ||
| 214 | + } | ||
| 215 | + }, | ||
| 216 | + immediate: true | ||
| 217 | + }, | ||
| 218 | + start: { | ||
| 219 | + handler(newVal) { | ||
| 220 | + this.parseDatetimeRange(this.fixIosDateFormat(newVal), 'start') //兼容 iOS、safari 日期格式 | ||
| 221 | + }, | ||
| 222 | + immediate: true | ||
| 223 | + }, | ||
| 224 | + end: { | ||
| 225 | + handler(newVal) { | ||
| 226 | + this.parseDatetimeRange(this.fixIosDateFormat(newVal), 'end') //兼容 iOS、safari 日期格式 | ||
| 227 | + }, | ||
| 228 | + immediate: true | ||
| 229 | + }, | ||
| 230 | + | ||
| 231 | + // 月、日、时、分、秒可选范围变化后,检查当前值是否在范围内,不在则当前值重置为可选范围第一项 | ||
| 232 | + months(newVal) { | ||
| 233 | + this.checkValue('month', this.month, newVal) | ||
| 234 | + }, | ||
| 235 | + days(newVal) { | ||
| 236 | + this.checkValue('day', this.day, newVal) | ||
| 237 | + }, | ||
| 238 | + hours(newVal) { | ||
| 239 | + this.checkValue('hour', this.hour, newVal) | ||
| 240 | + }, | ||
| 241 | + minutes(newVal) { | ||
| 242 | + this.checkValue('minute', this.minute, newVal) | ||
| 243 | + }, | ||
| 244 | + seconds(newVal) { | ||
| 245 | + this.checkValue('second', this.second, newVal) | ||
| 246 | + } | ||
| 247 | + }, | ||
| 248 | + computed: { | ||
| 249 | + // 当前年、月、日、时、分、秒选择范围 | ||
| 250 | + years() { | ||
| 251 | + return this.getCurrentRange('year') | ||
| 252 | + }, | ||
| 253 | + | ||
| 254 | + months() { | ||
| 255 | + return this.getCurrentRange('month') | ||
| 256 | + }, | ||
| 257 | + | ||
| 258 | + days() { | ||
| 259 | + return this.getCurrentRange('day') | ||
| 260 | + }, | ||
| 261 | + | ||
| 262 | + hours() { | ||
| 263 | + return this.getCurrentRange('hour') | ||
| 264 | + }, | ||
| 265 | + | ||
| 266 | + minutes() { | ||
| 267 | + return this.getCurrentRange('minute') | ||
| 268 | + }, | ||
| 269 | + | ||
| 270 | + seconds() { | ||
| 271 | + return this.getCurrentRange('second') | ||
| 272 | + }, | ||
| 273 | + | ||
| 274 | + // picker 当前值数组 | ||
| 275 | + ymd() { | ||
| 276 | + return [this.year - this.minYear, this.month - this.minMonth, this.day - this.minDay] | ||
| 277 | + }, | ||
| 278 | + hms() { | ||
| 279 | + return [this.hour - this.minHour, this.minute - this.minMinute, this.second - this.minSecond] | ||
| 280 | + }, | ||
| 281 | + | ||
| 282 | + // 当前 date 是 start | ||
| 283 | + currentDateIsStart() { | ||
| 284 | + return this.year === this.startYear && this.month === this.startMonth && this.day === this.startDay | ||
| 285 | + }, | ||
| 286 | + | ||
| 287 | + // 当前 date 是 end | ||
| 288 | + currentDateIsEnd() { | ||
| 289 | + return this.year === this.endYear && this.month === this.endMonth && this.day === this.endDay | ||
| 290 | + }, | ||
| 291 | + | ||
| 292 | + // 当前年、月、日、时、分、秒的最小值和最大值 | ||
| 293 | + minYear() { | ||
| 294 | + return this.startYear | ||
| 295 | + }, | ||
| 296 | + maxYear() { | ||
| 297 | + return this.endYear | ||
| 298 | + }, | ||
| 299 | + minMonth() { | ||
| 300 | + if (this.year === this.startYear) { | ||
| 301 | + return this.startMonth | ||
| 302 | + } else { | ||
| 303 | + return 1 | ||
| 304 | + } | ||
| 305 | + }, | ||
| 306 | + maxMonth() { | ||
| 307 | + if (this.year === this.endYear) { | ||
| 308 | + return this.endMonth | ||
| 309 | + } else { | ||
| 310 | + return 12 | ||
| 311 | + } | ||
| 312 | + }, | ||
| 313 | + minDay() { | ||
| 314 | + if (this.year === this.startYear && this.month === this.startMonth) { | ||
| 315 | + return this.startDay | ||
| 316 | + } else { | ||
| 317 | + return 1 | ||
| 318 | + } | ||
| 319 | + }, | ||
| 320 | + maxDay() { | ||
| 321 | + if (this.year === this.endYear && this.month === this.endMonth) { | ||
| 322 | + return this.endDay | ||
| 323 | + } else { | ||
| 324 | + return this.daysInMonth(this.year, this.month) | ||
| 325 | + } | ||
| 326 | + }, | ||
| 327 | + minHour() { | ||
| 328 | + if (this.type === 'datetime') { | ||
| 329 | + if (this.currentDateIsStart) { | ||
| 330 | + return this.startHour | ||
| 331 | + } else { | ||
| 332 | + return 0 | ||
| 333 | + } | ||
| 334 | + } | ||
| 335 | + if (this.type === 'time') { | ||
| 336 | + return this.startHour | ||
| 337 | + } | ||
| 338 | + }, | ||
| 339 | + maxHour() { | ||
| 340 | + if (this.type === 'datetime') { | ||
| 341 | + if (this.currentDateIsEnd) { | ||
| 342 | + return this.endHour | ||
| 343 | + } else { | ||
| 344 | + return 23 | ||
| 345 | + } | ||
| 346 | + } | ||
| 347 | + if (this.type === 'time') { | ||
| 348 | + return this.endHour | ||
| 349 | + } | ||
| 350 | + }, | ||
| 351 | + minMinute() { | ||
| 352 | + if (this.type === 'datetime') { | ||
| 353 | + if (this.currentDateIsStart && this.hour === this.startHour) { | ||
| 354 | + return this.startMinute | ||
| 355 | + } else { | ||
| 356 | + return 0 | ||
| 357 | + } | ||
| 358 | + } | ||
| 359 | + if (this.type === 'time') { | ||
| 360 | + if (this.hour === this.startHour) { | ||
| 361 | + return this.startMinute | ||
| 362 | + } else { | ||
| 363 | + return 0 | ||
| 364 | + } | ||
| 365 | + } | ||
| 366 | + }, | ||
| 367 | + maxMinute() { | ||
| 368 | + if (this.type === 'datetime') { | ||
| 369 | + if (this.currentDateIsEnd && this.hour === this.endHour) { | ||
| 370 | + return this.endMinute | ||
| 371 | + } else { | ||
| 372 | + return 59 | ||
| 373 | + } | ||
| 374 | + } | ||
| 375 | + if (this.type === 'time') { | ||
| 376 | + if (this.hour === this.endHour) { | ||
| 377 | + return this.endMinute | ||
| 378 | + } else { | ||
| 379 | + return 59 | ||
| 380 | + } | ||
| 381 | + } | ||
| 382 | + }, | ||
| 383 | + minSecond() { | ||
| 384 | + if (this.type === 'datetime') { | ||
| 385 | + if (this.currentDateIsStart && this.hour === this.startHour && this.minute === this.startMinute) { | ||
| 386 | + return this.startSecond | ||
| 387 | + } else { | ||
| 388 | + return 0 | ||
| 389 | + } | ||
| 390 | + } | ||
| 391 | + if (this.type === 'time') { | ||
| 392 | + if (this.hour === this.startHour && this.minute === this.startMinute) { | ||
| 393 | + return this.startSecond | ||
| 394 | + } else { | ||
| 395 | + return 0 | ||
| 396 | + } | ||
| 397 | + } | ||
| 398 | + }, | ||
| 399 | + maxSecond() { | ||
| 400 | + if (this.type === 'datetime') { | ||
| 401 | + if (this.currentDateIsEnd && this.hour === this.endHour && this.minute === this.endMinute) { | ||
| 402 | + return this.endSecond | ||
| 403 | + } else { | ||
| 404 | + return 59 | ||
| 405 | + } | ||
| 406 | + } | ||
| 407 | + if (this.type === 'time') { | ||
| 408 | + if (this.hour === this.endHour && this.minute === this.endMinute) { | ||
| 409 | + return this.endSecond | ||
| 410 | + } else { | ||
| 411 | + return 59 | ||
| 412 | + } | ||
| 413 | + } | ||
| 414 | + }, | ||
| 415 | + | ||
| 416 | + /** | ||
| 417 | + * for i18n | ||
| 418 | + */ | ||
| 419 | + selectTimeText() { | ||
| 420 | + return t("uni-datetime-picker.selectTime") | ||
| 421 | + }, | ||
| 422 | + okText() { | ||
| 423 | + return t("uni-datetime-picker.ok") | ||
| 424 | + }, | ||
| 425 | + clearText() { | ||
| 426 | + return t("uni-datetime-picker.clear") | ||
| 427 | + }, | ||
| 428 | + cancelText() { | ||
| 429 | + return t("uni-datetime-picker.cancel") | ||
| 430 | + } | ||
| 431 | + }, | ||
| 432 | + | ||
| 433 | + mounted() { | ||
| 434 | + // #ifdef APP-NVUE | ||
| 435 | + const res = uni.getSystemInfoSync(); | ||
| 436 | + this.fixNvueBug = { | ||
| 437 | + top: res.windowHeight / 2, | ||
| 438 | + left: res.windowWidth / 2 | ||
| 439 | + } | ||
| 440 | + // #endif | ||
| 441 | + }, | ||
| 442 | + | ||
| 443 | + methods: { | ||
| 444 | + /** | ||
| 445 | + * @param {Object} item | ||
| 446 | + * 小于 10 在前面加个 0 | ||
| 447 | + */ | ||
| 448 | + | ||
| 449 | + lessThanTen(item) { | ||
| 450 | + return item < 10 ? '0' + item : item | ||
| 451 | + }, | ||
| 452 | + | ||
| 453 | + /** | ||
| 454 | + * 解析时分秒字符串,例如:00:00:00 | ||
| 455 | + * @param {String} timeString | ||
| 456 | + */ | ||
| 457 | + parseTimeType(timeString) { | ||
| 458 | + if (timeString) { | ||
| 459 | + let timeArr = timeString.split(':') | ||
| 460 | + this.hour = Number(timeArr[0]) | ||
| 461 | + this.minute = Number(timeArr[1]) | ||
| 462 | + this.second = Number(timeArr[2]) | ||
| 463 | + } | ||
| 464 | + }, | ||
| 465 | + | ||
| 466 | + /** | ||
| 467 | + * 解析选择器初始值,类型可以是字符串、时间戳,例如:2000-10-02、'08:30:00'、 1610695109000 | ||
| 468 | + * @param {String | Number} datetime | ||
| 469 | + */ | ||
| 470 | + initPickerValue(datetime) { | ||
| 471 | + let defaultValue = null | ||
| 472 | + if (datetime) { | ||
| 473 | + defaultValue = this.compareValueWithStartAndEnd(datetime, this.start, this.end) | ||
| 474 | + } else { | ||
| 475 | + defaultValue = Date.now() | ||
| 476 | + defaultValue = this.compareValueWithStartAndEnd(defaultValue, this.start, this.end) | ||
| 477 | + } | ||
| 478 | + this.parseValue(defaultValue) | ||
| 479 | + }, | ||
| 480 | + | ||
| 481 | + /** | ||
| 482 | + * 初始值规则: | ||
| 483 | + * - 用户设置初始值 value | ||
| 484 | + * - 设置了起始时间 start、终止时间 end,并 start < value < end,初始值为 value, 否则初始值为 start | ||
| 485 | + * - 只设置了起始时间 start,并 start < value,初始值为 value,否则初始值为 start | ||
| 486 | + * - 只设置了终止时间 end,并 value < end,初始值为 value,否则初始值为 end | ||
| 487 | + * - 无起始终止时间,则初始值为 value | ||
| 488 | + * - 无初始值 value,则初始值为当前本地时间 Date.now() | ||
| 489 | + * @param {Object} value | ||
| 490 | + * @param {Object} dateBase | ||
| 491 | + */ | ||
| 492 | + compareValueWithStartAndEnd(value, start, end) { | ||
| 493 | + let winner = null | ||
| 494 | + value = this.superTimeStamp(value) | ||
| 495 | + start = this.superTimeStamp(start) | ||
| 496 | + end = this.superTimeStamp(end) | ||
| 497 | + | ||
| 498 | + if (start && end) { | ||
| 499 | + if (value < start) { | ||
| 500 | + winner = new Date(start) | ||
| 501 | + } else if (value > end) { | ||
| 502 | + winner = new Date(end) | ||
| 503 | + } else { | ||
| 504 | + winner = new Date(value) | ||
| 505 | + } | ||
| 506 | + } else if (start && !end) { | ||
| 507 | + winner = start <= value ? new Date(value) : new Date(start) | ||
| 508 | + } else if (!start && end) { | ||
| 509 | + winner = value <= end ? new Date(value) : new Date(end) | ||
| 510 | + } else { | ||
| 511 | + winner = new Date(value) | ||
| 512 | + } | ||
| 513 | + | ||
| 514 | + return winner | ||
| 515 | + }, | ||
| 516 | + | ||
| 517 | + /** | ||
| 518 | + * 转换为可比较的时间戳,接受日期、时分秒、时间戳 | ||
| 519 | + * @param {Object} value | ||
| 520 | + */ | ||
| 521 | + superTimeStamp(value) { | ||
| 522 | + let dateBase = '' | ||
| 523 | + if (this.type === 'time' && value && typeof value === 'string') { | ||
| 524 | + const now = new Date() | ||
| 525 | + const year = now.getFullYear() | ||
| 526 | + const month = now.getMonth() + 1 | ||
| 527 | + const day = now.getDate() | ||
| 528 | + dateBase = year + '/' + month + '/' + day + ' ' | ||
| 529 | + } | ||
| 530 | + if (Number(value) && typeof value !== NaN) { | ||
| 531 | + value = parseInt(value) | ||
| 532 | + dateBase = 0 | ||
| 533 | + } | ||
| 534 | + return this.createTimeStamp(dateBase + value) | ||
| 535 | + }, | ||
| 536 | + | ||
| 537 | + /** | ||
| 538 | + * 解析默认值 value,字符串、时间戳 | ||
| 539 | + * @param {Object} defaultTime | ||
| 540 | + */ | ||
| 541 | + parseValue(value) { | ||
| 542 | + if (!value) { | ||
| 543 | + return | ||
| 544 | + } | ||
| 545 | + if (this.type === 'time' && typeof value === "string") { | ||
| 546 | + this.parseTimeType(value) | ||
| 547 | + } else { | ||
| 548 | + let defaultDate = null | ||
| 549 | + defaultDate = new Date(value) | ||
| 550 | + if (this.type !== 'time') { | ||
| 551 | + this.year = defaultDate.getFullYear() | ||
| 552 | + this.month = defaultDate.getMonth() + 1 | ||
| 553 | + this.day = defaultDate.getDate() | ||
| 554 | + } | ||
| 555 | + if (this.type !== 'date') { | ||
| 556 | + this.hour = defaultDate.getHours() | ||
| 557 | + this.minute = defaultDate.getMinutes() | ||
| 558 | + this.second = defaultDate.getSeconds() | ||
| 559 | + } | ||
| 560 | + } | ||
| 561 | + if (this.hideSecond) { | ||
| 562 | + this.second = 0 | ||
| 563 | + } | ||
| 564 | + }, | ||
| 565 | + | ||
| 566 | + /** | ||
| 567 | + * 解析可选择时间范围 start、end,年月日字符串、时间戳 | ||
| 568 | + * @param {Object} defaultTime | ||
| 569 | + */ | ||
| 570 | + parseDatetimeRange(point, pointType) { | ||
| 571 | + // 时间为空,则重置为初始值 | ||
| 572 | + if (!point) { | ||
| 573 | + if (pointType === 'start') { | ||
| 574 | + this.startYear = 1920 | ||
| 575 | + this.startMonth = 1 | ||
| 576 | + this.startDay = 1 | ||
| 577 | + this.startHour = 0 | ||
| 578 | + this.startMinute = 0 | ||
| 579 | + this.startSecond = 0 | ||
| 580 | + } | ||
| 581 | + if (pointType === 'end') { | ||
| 582 | + this.endYear = 2120 | ||
| 583 | + this.endMonth = 12 | ||
| 584 | + this.endDay = 31 | ||
| 585 | + this.endHour = 23 | ||
| 586 | + this.endMinute = 59 | ||
| 587 | + this.endSecond = 59 | ||
| 588 | + } | ||
| 589 | + return | ||
| 590 | + } | ||
| 591 | + if (this.type === 'time') { | ||
| 592 | + const pointArr = point.split(':') | ||
| 593 | + this[pointType + 'Hour'] = Number(pointArr[0]) | ||
| 594 | + this[pointType + 'Minute'] = Number(pointArr[1]) | ||
| 595 | + this[pointType + 'Second'] = Number(pointArr[2]) | ||
| 596 | + } else { | ||
| 597 | + if (!point) { | ||
| 598 | + pointType === 'start' ? this.startYear = this.year - 60 : this.endYear = this.year + 60 | ||
| 599 | + return | ||
| 600 | + } | ||
| 601 | + if (Number(point) && Number(point) !== NaN) { | ||
| 602 | + point = parseInt(point) | ||
| 603 | + } | ||
| 604 | + // datetime 的 end 没有时分秒, 则不限制 | ||
| 605 | + const hasTime = /[0-9]:[0-9]/ | ||
| 606 | + if (this.type === 'datetime' && pointType === 'end' && typeof point === 'string' && !hasTime.test( | ||
| 607 | + point)) { | ||
| 608 | + point = point + ' 23:59:59' | ||
| 609 | + } | ||
| 610 | + const pointDate = new Date(point) | ||
| 611 | + this[pointType + 'Year'] = pointDate.getFullYear() | ||
| 612 | + this[pointType + 'Month'] = pointDate.getMonth() + 1 | ||
| 613 | + this[pointType + 'Day'] = pointDate.getDate() | ||
| 614 | + if (this.type === 'datetime') { | ||
| 615 | + this[pointType + 'Hour'] = pointDate.getHours() | ||
| 616 | + this[pointType + 'Minute'] = pointDate.getMinutes() | ||
| 617 | + this[pointType + 'Second'] = pointDate.getSeconds() | ||
| 618 | + } | ||
| 619 | + } | ||
| 620 | + }, | ||
| 621 | + | ||
| 622 | + // 获取 年、月、日、时、分、秒 当前可选范围 | ||
| 623 | + getCurrentRange(value) { | ||
| 624 | + const range = [] | ||
| 625 | + for (let i = this['min' + this.capitalize(value)]; i <= this['max' + this.capitalize(value)]; i++) { | ||
| 626 | + range.push(i) | ||
| 627 | + } | ||
| 628 | + return range | ||
| 629 | + }, | ||
| 630 | + | ||
| 631 | + // 字符串首字母大写 | ||
| 632 | + capitalize(str) { | ||
| 633 | + return str.charAt(0).toUpperCase() + str.slice(1) | ||
| 634 | + }, | ||
| 635 | + | ||
| 636 | + // 检查当前值是否在范围内,不在则当前值重置为可选范围第一项 | ||
| 637 | + checkValue(name, value, values) { | ||
| 638 | + if (values.indexOf(value) === -1) { | ||
| 639 | + this[name] = values[0] | ||
| 640 | + } | ||
| 641 | + }, | ||
| 642 | + | ||
| 643 | + // 每个月的实际天数 | ||
| 644 | + daysInMonth(year, month) { // Use 1 for January, 2 for February, etc. | ||
| 645 | + return new Date(year, month, 0).getDate(); | ||
| 646 | + }, | ||
| 647 | + | ||
| 648 | + //兼容 iOS、safari 日期格式 | ||
| 649 | + fixIosDateFormat(value) { | ||
| 650 | + if (typeof value === 'string') { | ||
| 651 | + value = value.replace(/-/g, '/') | ||
| 652 | + } | ||
| 653 | + return value | ||
| 654 | + }, | ||
| 655 | + | ||
| 656 | + /** | ||
| 657 | + * 生成时间戳 | ||
| 658 | + * @param {Object} time | ||
| 659 | + */ | ||
| 660 | + createTimeStamp(time) { | ||
| 661 | + if (!time) return | ||
| 662 | + if (typeof time === "number") { | ||
| 663 | + return time | ||
| 664 | + } else { | ||
| 665 | + time = time.replace(/-/g, '/') | ||
| 666 | + if (this.type === 'date') { | ||
| 667 | + time = time + ' ' + '00:00:00' | ||
| 668 | + } | ||
| 669 | + return Date.parse(time) | ||
| 670 | + } | ||
| 671 | + }, | ||
| 672 | + | ||
| 673 | + /** | ||
| 674 | + * 生成日期或时间的字符串 | ||
| 675 | + */ | ||
| 676 | + createDomSting() { | ||
| 677 | + const yymmdd = this.year + | ||
| 678 | + '-' + | ||
| 679 | + this.lessThanTen(this.month) + | ||
| 680 | + '-' + | ||
| 681 | + this.lessThanTen(this.day) | ||
| 682 | + | ||
| 683 | + let hhmmss = this.lessThanTen(this.hour) + | ||
| 684 | + ':' + | ||
| 685 | + this.lessThanTen(this.minute) | ||
| 686 | + | ||
| 687 | + if (!this.hideSecond) { | ||
| 688 | + hhmmss = hhmmss + ':' + this.lessThanTen(this.second) | ||
| 689 | + } | ||
| 690 | + | ||
| 691 | + if (this.type === 'date') { | ||
| 692 | + return yymmdd | ||
| 693 | + } else if (this.type === 'time') { | ||
| 694 | + return hhmmss | ||
| 695 | + } else { | ||
| 696 | + return yymmdd + ' ' + hhmmss | ||
| 697 | + } | ||
| 698 | + }, | ||
| 699 | + | ||
| 700 | + /** | ||
| 701 | + * 初始化返回值,并抛出 change 事件 | ||
| 702 | + */ | ||
| 703 | + initTime(emit = true) { | ||
| 704 | + this.time = this.createDomSting() | ||
| 705 | + if (!emit) return | ||
| 706 | + if (this.returnType === 'timestamp' && this.type !== 'time') { | ||
| 707 | + this.$emit('change', this.createTimeStamp(this.time)) | ||
| 708 | + this.$emit('input', this.createTimeStamp(this.time)) | ||
| 709 | + this.$emit('update:modelValue', this.createTimeStamp(this.time)) | ||
| 710 | + } else { | ||
| 711 | + this.$emit('change', this.time) | ||
| 712 | + this.$emit('input', this.time) | ||
| 713 | + this.$emit('update:modelValue', this.time) | ||
| 714 | + } | ||
| 715 | + }, | ||
| 716 | + | ||
| 717 | + /** | ||
| 718 | + * 用户选择日期或时间更新 data | ||
| 719 | + * @param {Object} e | ||
| 720 | + */ | ||
| 721 | + bindDateChange(e) { | ||
| 722 | + const val = e.detail.value | ||
| 723 | + this.year = this.years[val[0]] | ||
| 724 | + this.month = this.months[val[1]] | ||
| 725 | + this.day = this.days[val[2]] | ||
| 726 | + }, | ||
| 727 | + bindTimeChange(e) { | ||
| 728 | + const val = e.detail.value | ||
| 729 | + this.hour = this.hours[val[0]] | ||
| 730 | + this.minute = this.minutes[val[1]] | ||
| 731 | + this.second = this.seconds[val[2]] | ||
| 732 | + }, | ||
| 733 | + | ||
| 734 | + /** | ||
| 735 | + * 初始化弹出层 | ||
| 736 | + */ | ||
| 737 | + initTimePicker() { | ||
| 738 | + if (this.disabled) return | ||
| 739 | + const value = this.fixIosDateFormat(this.value) | ||
| 740 | + this.initPickerValue(value) | ||
| 741 | + this.visible = !this.visible | ||
| 742 | + }, | ||
| 743 | + | ||
| 744 | + /** | ||
| 745 | + * 触发或关闭弹框 | ||
| 746 | + */ | ||
| 747 | + tiggerTimePicker(e) { | ||
| 748 | + this.visible = !this.visible | ||
| 749 | + }, | ||
| 750 | + | ||
| 751 | + /** | ||
| 752 | + * 用户点击“清空”按钮,清空当前值 | ||
| 753 | + */ | ||
| 754 | + clearTime() { | ||
| 755 | + this.time = '' | ||
| 756 | + this.$emit('change', this.time) | ||
| 757 | + this.$emit('input', this.time) | ||
| 758 | + this.$emit('update:modelValue', this.time) | ||
| 759 | + this.tiggerTimePicker() | ||
| 760 | + }, | ||
| 761 | + | ||
| 762 | + /** | ||
| 763 | + * 用户点击“确定”按钮 | ||
| 764 | + */ | ||
| 765 | + setTime() { | ||
| 766 | + this.initTime() | ||
| 767 | + this.tiggerTimePicker() | ||
| 768 | + } | ||
| 769 | + } | ||
| 770 | + } | ||
| 771 | +</script> | ||
| 772 | + | ||
| 773 | +<style> | ||
| 774 | + .uni-datetime-picker { | ||
| 775 | + /* #ifndef APP-NVUE */ | ||
| 776 | + /* width: 100%; */ | ||
| 777 | + /* #endif */ | ||
| 778 | + } | ||
| 779 | + | ||
| 780 | + .uni-datetime-picker-view { | ||
| 781 | + height: 130px; | ||
| 782 | + width: 270px; | ||
| 783 | + /* #ifndef APP-NVUE */ | ||
| 784 | + cursor: pointer; | ||
| 785 | + /* #endif */ | ||
| 786 | + } | ||
| 787 | + | ||
| 788 | + .uni-datetime-picker-item { | ||
| 789 | + height: 50px; | ||
| 790 | + line-height: 50px; | ||
| 791 | + text-align: center; | ||
| 792 | + font-size: 14px; | ||
| 793 | + } | ||
| 794 | + | ||
| 795 | + .uni-datetime-picker-btn { | ||
| 796 | + margin-top: 60px; | ||
| 797 | + /* #ifndef APP-NVUE */ | ||
| 798 | + display: flex; | ||
| 799 | + cursor: pointer; | ||
| 800 | + /* #endif */ | ||
| 801 | + flex-direction: row; | ||
| 802 | + justify-content: space-between; | ||
| 803 | + } | ||
| 804 | + | ||
| 805 | + .uni-datetime-picker-btn-text { | ||
| 806 | + font-size: 14px; | ||
| 807 | + color: #007AFF; | ||
| 808 | + } | ||
| 809 | + | ||
| 810 | + .uni-datetime-picker-btn-group { | ||
| 811 | + /* #ifndef APP-NVUE */ | ||
| 812 | + display: flex; | ||
| 813 | + /* #endif */ | ||
| 814 | + flex-direction: row; | ||
| 815 | + } | ||
| 816 | + | ||
| 817 | + .uni-datetime-picker-cancel { | ||
| 818 | + margin-right: 30px; | ||
| 819 | + } | ||
| 820 | + | ||
| 821 | + .uni-datetime-picker-mask { | ||
| 822 | + position: fixed; | ||
| 823 | + bottom: 0px; | ||
| 824 | + top: 0px; | ||
| 825 | + left: 0px; | ||
| 826 | + right: 0px; | ||
| 827 | + background-color: rgba(0, 0, 0, 0.4); | ||
| 828 | + transition-duration: 0.3s; | ||
| 829 | + z-index: 998; | ||
| 830 | + } | ||
| 831 | + | ||
| 832 | + .uni-datetime-picker-popup { | ||
| 833 | + border-radius: 8px; | ||
| 834 | + padding: 30px; | ||
| 835 | + width: 270px; | ||
| 836 | + /* #ifdef APP-NVUE */ | ||
| 837 | + height: 500px; | ||
| 838 | + /* #endif */ | ||
| 839 | + /* #ifdef APP-NVUE */ | ||
| 840 | + width: 330px; | ||
| 841 | + /* #endif */ | ||
| 842 | + background-color: #fff; | ||
| 843 | + position: fixed; | ||
| 844 | + top: 50%; | ||
| 845 | + left: 50%; | ||
| 846 | + transform: translate(-50%, -50%); | ||
| 847 | + transition-duration: 0.3s; | ||
| 848 | + z-index: 999; | ||
| 849 | + } | ||
| 850 | + | ||
| 851 | + .fix-nvue-height { | ||
| 852 | + /* #ifdef APP-NVUE */ | ||
| 853 | + height: 330px; | ||
| 854 | + /* #endif */ | ||
| 855 | + } | ||
| 856 | + | ||
| 857 | + .uni-datetime-picker-time { | ||
| 858 | + color: grey; | ||
| 859 | + } | ||
| 860 | + | ||
| 861 | + .uni-datetime-picker-column { | ||
| 862 | + height: 50px; | ||
| 863 | + } | ||
| 864 | + | ||
| 865 | + .uni-datetime-picker-timebox { | ||
| 866 | + | ||
| 867 | + border: 1px solid #E5E5E5; | ||
| 868 | + border-radius: 5px; | ||
| 869 | + padding: 7px 10px; | ||
| 870 | + /* #ifndef APP-NVUE */ | ||
| 871 | + box-sizing: border-box; | ||
| 872 | + cursor: pointer; | ||
| 873 | + /* #endif */ | ||
| 874 | + } | ||
| 875 | + | ||
| 876 | + .uni-datetime-picker-timebox-pointer { | ||
| 877 | + /* #ifndef APP-NVUE */ | ||
| 878 | + cursor: pointer; | ||
| 879 | + /* #endif */ | ||
| 880 | + } | ||
| 881 | + | ||
| 882 | + | ||
| 883 | + .uni-datetime-picker-disabled { | ||
| 884 | + opacity: 0.4; | ||
| 885 | + /* #ifdef H5 */ | ||
| 886 | + cursor: not-allowed !important; | ||
| 887 | + /* #endif */ | ||
| 888 | + } | ||
| 889 | + | ||
| 890 | + .uni-datetime-picker-text { | ||
| 891 | + font-size: 14px; | ||
| 892 | + } | ||
| 893 | + | ||
| 894 | + .uni-datetime-picker-sign { | ||
| 895 | + position: absolute; | ||
| 896 | + top: 53px; | ||
| 897 | + /* 减掉 10px 的元素高度,兼容nvue */ | ||
| 898 | + color: #999; | ||
| 899 | + /* #ifdef APP-NVUE */ | ||
| 900 | + font-size: 16px; | ||
| 901 | + /* #endif */ | ||
| 902 | + } | ||
| 903 | + | ||
| 904 | + .sign-left { | ||
| 905 | + left: 86px; | ||
| 906 | + } | ||
| 907 | + | ||
| 908 | + .sign-right { | ||
| 909 | + right: 86px; | ||
| 910 | + } | ||
| 911 | + | ||
| 912 | + .sign-center { | ||
| 913 | + left: 135px; | ||
| 914 | + } | ||
| 915 | + | ||
| 916 | + .uni-datetime-picker__container-box { | ||
| 917 | + position: relative; | ||
| 918 | + display: flex; | ||
| 919 | + align-items: center; | ||
| 920 | + justify-content: center; | ||
| 921 | + margin-top: 40px; | ||
| 922 | + } | ||
| 923 | + | ||
| 924 | + .time-hide-second { | ||
| 925 | + width: 180px; | ||
| 926 | + } | ||
| 927 | +</style> |
| 1 | +<template> | ||
| 2 | + <view class="uni-date"> | ||
| 3 | + <view class="uni-date-editor" @click="show"> | ||
| 4 | + <slot> | ||
| 5 | + <view class="uni-date-editor--x" :class="{'uni-date-editor--x__disabled': disabled, | ||
| 6 | + 'uni-date-x--border': border}"> | ||
| 7 | + <view v-if="!isRange" class="uni-date-x uni-date-single"> | ||
| 8 | + <uni-icons type="calendar" color="#e1e1e1" size="22"></uni-icons> | ||
| 9 | + <input class="uni-date__x-input" type="text" v-model="singleVal" | ||
| 10 | + :placeholder="singlePlaceholderText" :disabled="true" /> | ||
| 11 | + </view> | ||
| 12 | + <view v-else class="uni-date-x uni-date-range"> | ||
| 13 | + <uni-icons type="calendar" color="#e1e1e1" size="22"></uni-icons> | ||
| 14 | + <input class="uni-date__x-input t-c" type="text" v-model="range.startDate" | ||
| 15 | + :placeholder="startPlaceholderText" :disabled="true" /> | ||
| 16 | + <slot> | ||
| 17 | + <view class="">{{rangeSeparator}}</view> | ||
| 18 | + </slot> | ||
| 19 | + <input class="uni-date__x-input t-c" type="text" v-model="range.endDate" | ||
| 20 | + :placeholder="endPlaceholderText" :disabled="true" /> | ||
| 21 | + </view> | ||
| 22 | + <view v-if="showClearIcon" class="uni-date__icon-clear" @click.stop="clear"> | ||
| 23 | + <uni-icons type="clear" color="#e1e1e1" size="18"></uni-icons> | ||
| 24 | + </view> | ||
| 25 | + </view> | ||
| 26 | + </slot> | ||
| 27 | + </view> | ||
| 28 | + | ||
| 29 | + <view v-show="popup" class="uni-date-mask" @click="close"></view> | ||
| 30 | + <view v-if="!isPhone" ref="datePicker" v-show="popup" class="uni-date-picker__container"> | ||
| 31 | + <view v-if="!isRange" class="uni-date-single--x" :style="popover"> | ||
| 32 | + <view class="uni-popper__arrow"></view> | ||
| 33 | + <view v-if="hasTime" class="uni-date-changed popup-x-header"> | ||
| 34 | + <input class="uni-date__input t-c" type="text" v-model="tempSingleDate" | ||
| 35 | + :placeholder="selectDateText" /> | ||
| 36 | + <time-picker type="time" v-model="time" :border="false" :disabled="!tempSingleDate" | ||
| 37 | + :start="reactStartTime" :end="reactEndTime" :hideSecond="hideSecond" style="width: 100%;"> | ||
| 38 | + <input class="uni-date__input t-c" type="text" v-model="time" :placeholder="selectTimeText" | ||
| 39 | + :disabled="!tempSingleDate" /> | ||
| 40 | + </time-picker> | ||
| 41 | + </view> | ||
| 42 | + <calendar ref="pcSingle" :showMonth="false" | ||
| 43 | + :start-date="caleRange.startDate" :end-date="caleRange.endDate" :date="defSingleDate" | ||
| 44 | + @change="singleChange" style="padding: 0 8px;" /> | ||
| 45 | + <view v-if="hasTime" class="popup-x-footer"> | ||
| 46 | + <!-- <text class="">此刻</text> --> | ||
| 47 | + <text class="confirm" @click="confirmSingleChange">{{okText}}</text> | ||
| 48 | + </view> | ||
| 49 | + <view class="uni-date-popper__arrow"></view> | ||
| 50 | + </view> | ||
| 51 | + | ||
| 52 | + <view v-else class="uni-date-range--x" :style="popover"> | ||
| 53 | + <view class="uni-popper__arrow"></view> | ||
| 54 | + <view v-if="hasTime" class="popup-x-header uni-date-changed"> | ||
| 55 | + <view class="popup-x-header--datetime"> | ||
| 56 | + <input class="uni-date__input uni-date-range__input" type="text" v-model="tempRange.startDate" | ||
| 57 | + :placeholder="startDateText" /> | ||
| 58 | + <time-picker type="time" v-model="tempRange.startTime" :start="reactStartTime" :border="false" | ||
| 59 | + :disabled="!tempRange.startDate" :hideSecond="hideSecond"> | ||
| 60 | + <input class="uni-date__input uni-date-range__input" type="text" | ||
| 61 | + v-model="tempRange.startTime" :placeholder="startTimeText" | ||
| 62 | + :disabled="!tempRange.startDate" /> | ||
| 63 | + </time-picker> | ||
| 64 | + </view> | ||
| 65 | + <uni-icons type="arrowthinright" color="#999" style="line-height: 40px;"></uni-icons> | ||
| 66 | + <view class="popup-x-header--datetime"> | ||
| 67 | + <input class="uni-date__input uni-date-range__input" type="text" v-model="tempRange.endDate" | ||
| 68 | + :placeholder="endDateText" /> | ||
| 69 | + <time-picker type="time" v-model="tempRange.endTime" :end="reactEndTime" :border="false" | ||
| 70 | + :disabled="!tempRange.endDate" :hideSecond="hideSecond"> | ||
| 71 | + <input class="uni-date__input uni-date-range__input" type="text" v-model="tempRange.endTime" | ||
| 72 | + :placeholder="endTimeText" :disabled="!tempRange.endDate" /> | ||
| 73 | + </time-picker> | ||
| 74 | + </view> | ||
| 75 | + </view> | ||
| 76 | + <view class="popup-x-body"> | ||
| 77 | + <calendar ref="left" :showMonth="false" | ||
| 78 | + :start-date="caleRange.startDate" :end-date="caleRange.endDate" :range="true" | ||
| 79 | + @change="leftChange" :pleStatus="endMultipleStatus" @firstEnterCale="updateRightCale" | ||
| 80 | + @monthSwitch="leftMonthSwitch" style="padding: 0 8px;" /> | ||
| 81 | + <calendar ref="right" :showMonth="false" | ||
| 82 | + :start-date="caleRange.startDate" :end-date="caleRange.endDate" :range="true" | ||
| 83 | + @change="rightChange" :pleStatus="startMultipleStatus" @firstEnterCale="updateLeftCale" | ||
| 84 | + @monthSwitch="rightMonthSwitch" style="padding: 0 8px;border-left: 1px solid #F1F1F1;" /> | ||
| 85 | + </view> | ||
| 86 | + <view v-if="hasTime" class="popup-x-footer"> | ||
| 87 | + <text class="" @click="clear">{{clearText}}</text> | ||
| 88 | + <text class="confirm" @click="confirmRangeChange">{{okText}}</text> | ||
| 89 | + </view> | ||
| 90 | + </view> | ||
| 91 | + </view> | ||
| 92 | + <calendar v-show="isPhone" ref="mobile" :clearDate="false" :date="defSingleDate" :defTime="reactMobDefTime" | ||
| 93 | + :start-date="caleRange.startDate" :end-date="caleRange.endDate" :selectableTimes="mobSelectableTime" | ||
| 94 | + :pleStatus="endMultipleStatus" :showMonth="false" :range="isRange" :typeHasTime="hasTime" :insert="false" | ||
| 95 | + :hideSecond="hideSecond" @confirm="mobileChange" /> | ||
| 96 | + </view> | ||
| 97 | +</template> | ||
| 98 | +<script> | ||
| 99 | + /** | ||
| 100 | + * DatetimePicker 时间选择器 | ||
| 101 | + * @description 同时支持 PC 和移动端使用日历选择日期和日期范围 | ||
| 102 | + * @tutorial https://ext.dcloud.net.cn/plugin?id=3962 | ||
| 103 | + * @property {String} type 选择器类型 | ||
| 104 | + * @property {String|Number|Array|Date} value 绑定值 | ||
| 105 | + * @property {String} placeholder 单选择时的占位内容 | ||
| 106 | + * @property {String} start 起始时间 | ||
| 107 | + * @property {String} end 终止时间 | ||
| 108 | + * @property {String} start-placeholder 范围选择时开始日期的占位内容 | ||
| 109 | + * @property {String} end-placeholder 范围选择时结束日期的占位内容 | ||
| 110 | + * @property {String} range-separator 选择范围时的分隔符 | ||
| 111 | + * @property {Boolean} border = [true|false] 是否有边框 | ||
| 112 | + * @property {Boolean} disabled = [true|false] 是否禁用 | ||
| 113 | + * @property {Boolean} clearIcon = [true|false] 是否显示清除按钮(仅PC端适用) | ||
| 114 | + * @event {Function} change 确定日期时触发的事件 | ||
| 115 | + * @event {Function} show 打开弹出层 | ||
| 116 | + * @event {Function} close 关闭弹出层 | ||
| 117 | + * @event {Function} clear 清除上次选中的状态和值 | ||
| 118 | + **/ | ||
| 119 | + import calendar from './calendar.vue' | ||
| 120 | + import timePicker from './time-picker.vue' | ||
| 121 | + import { | ||
| 122 | + initVueI18n | ||
| 123 | + } from '@dcloudio/uni-i18n' | ||
| 124 | + import messages from './i18n/index.js' | ||
| 125 | + const { | ||
| 126 | + t | ||
| 127 | + } = initVueI18n(messages) | ||
| 128 | + | ||
| 129 | + export default { | ||
| 130 | + name: 'UniDatetimePicker', | ||
| 131 | + components: { | ||
| 132 | + calendar, | ||
| 133 | + timePicker | ||
| 134 | + }, | ||
| 135 | + data() { | ||
| 136 | + return { | ||
| 137 | + isRange: false, | ||
| 138 | + hasTime: false, | ||
| 139 | + mobileRange: false, | ||
| 140 | + // 单选 | ||
| 141 | + singleVal: '', | ||
| 142 | + tempSingleDate: '', | ||
| 143 | + defSingleDate: '', | ||
| 144 | + time: '', | ||
| 145 | + // 范围选 | ||
| 146 | + caleRange: { | ||
| 147 | + startDate: '', | ||
| 148 | + startTime: '', | ||
| 149 | + endDate: '', | ||
| 150 | + endTime: '' | ||
| 151 | + }, | ||
| 152 | + range: { | ||
| 153 | + startDate: '', | ||
| 154 | + // startTime: '', | ||
| 155 | + endDate: '', | ||
| 156 | + // endTime: '' | ||
| 157 | + }, | ||
| 158 | + tempRange: { | ||
| 159 | + startDate: '', | ||
| 160 | + startTime: '', | ||
| 161 | + endDate: '', | ||
| 162 | + endTime: '' | ||
| 163 | + }, | ||
| 164 | + // 左右日历同步数据 | ||
| 165 | + startMultipleStatus: { | ||
| 166 | + before: '', | ||
| 167 | + after: '', | ||
| 168 | + data: [], | ||
| 169 | + fulldate: '' | ||
| 170 | + }, | ||
| 171 | + endMultipleStatus: { | ||
| 172 | + before: '', | ||
| 173 | + after: '', | ||
| 174 | + data: [], | ||
| 175 | + fulldate: '' | ||
| 176 | + }, | ||
| 177 | + visible: false, | ||
| 178 | + popup: false, | ||
| 179 | + popover: null, | ||
| 180 | + isEmitValue: false, | ||
| 181 | + isPhone: false, | ||
| 182 | + isFirstShow: true, | ||
| 183 | + } | ||
| 184 | + }, | ||
| 185 | + props: { | ||
| 186 | + type: { | ||
| 187 | + type: String, | ||
| 188 | + default: 'datetime' | ||
| 189 | + }, | ||
| 190 | + value: { | ||
| 191 | + type: [String, Number, Array, Date], | ||
| 192 | + default: '' | ||
| 193 | + }, | ||
| 194 | + modelValue: { | ||
| 195 | + type: [String, Number, Array, Date], | ||
| 196 | + default: '' | ||
| 197 | + }, | ||
| 198 | + start: { | ||
| 199 | + type: [Number, String], | ||
| 200 | + default: '' | ||
| 201 | + }, | ||
| 202 | + end: { | ||
| 203 | + type: [Number, String], | ||
| 204 | + default: '' | ||
| 205 | + }, | ||
| 206 | + returnType: { | ||
| 207 | + type: String, | ||
| 208 | + default: 'string' | ||
| 209 | + }, | ||
| 210 | + placeholder: { | ||
| 211 | + type: String, | ||
| 212 | + default: '' | ||
| 213 | + }, | ||
| 214 | + startPlaceholder: { | ||
| 215 | + type: String, | ||
| 216 | + default: '' | ||
| 217 | + }, | ||
| 218 | + endPlaceholder: { | ||
| 219 | + type: String, | ||
| 220 | + default: '' | ||
| 221 | + }, | ||
| 222 | + rangeSeparator: { | ||
| 223 | + type: String, | ||
| 224 | + default: '-' | ||
| 225 | + }, | ||
| 226 | + border: { | ||
| 227 | + type: [Boolean], | ||
| 228 | + default: true | ||
| 229 | + }, | ||
| 230 | + disabled: { | ||
| 231 | + type: [Boolean], | ||
| 232 | + default: false | ||
| 233 | + }, | ||
| 234 | + clearIcon: { | ||
| 235 | + type: [Boolean], | ||
| 236 | + default: true | ||
| 237 | + }, | ||
| 238 | + hideSecond: { | ||
| 239 | + type: [Boolean], | ||
| 240 | + default: false | ||
| 241 | + } | ||
| 242 | + }, | ||
| 243 | + watch: { | ||
| 244 | + type: { | ||
| 245 | + immediate: true, | ||
| 246 | + handler(newVal, oldVal) { | ||
| 247 | + if (newVal.indexOf('time') !== -1) { | ||
| 248 | + this.hasTime = true | ||
| 249 | + } else { | ||
| 250 | + this.hasTime = false | ||
| 251 | + } | ||
| 252 | + if (newVal.indexOf('range') !== -1) { | ||
| 253 | + this.isRange = true | ||
| 254 | + } else { | ||
| 255 | + this.isRange = false | ||
| 256 | + } | ||
| 257 | + } | ||
| 258 | + }, | ||
| 259 | + value: { | ||
| 260 | + immediate: true, | ||
| 261 | + handler(newVal, oldVal) { | ||
| 262 | + if (this.isEmitValue) { | ||
| 263 | + this.isEmitValue = false | ||
| 264 | + return | ||
| 265 | + } | ||
| 266 | + this.initPicker(newVal) | ||
| 267 | + } | ||
| 268 | + }, | ||
| 269 | + modelValue: { | ||
| 270 | + immediate: true, | ||
| 271 | + handler(newVal, oldVal) { | ||
| 272 | + if (this.isEmitValue) { | ||
| 273 | + this.isEmitValue = false | ||
| 274 | + return | ||
| 275 | + } | ||
| 276 | + this.initPicker(newVal) | ||
| 277 | + } | ||
| 278 | + }, | ||
| 279 | + start: { | ||
| 280 | + immediate: true, | ||
| 281 | + handler(newVal, oldVal) { | ||
| 282 | + if (!newVal) return | ||
| 283 | + const { | ||
| 284 | + defDate, | ||
| 285 | + defTime | ||
| 286 | + } = this.parseDate(newVal) | ||
| 287 | + this.caleRange.startDate = defDate | ||
| 288 | + if (this.hasTime) { | ||
| 289 | + this.caleRange.startTime = defTime | ||
| 290 | + } | ||
| 291 | + } | ||
| 292 | + }, | ||
| 293 | + end: { | ||
| 294 | + immediate: true, | ||
| 295 | + handler(newVal, oldVal) { | ||
| 296 | + if (!newVal) return | ||
| 297 | + const { | ||
| 298 | + defDate, | ||
| 299 | + defTime | ||
| 300 | + } = this.parseDate(newVal) | ||
| 301 | + this.caleRange.endDate = defDate | ||
| 302 | + if (this.hasTime) { | ||
| 303 | + this.caleRange.endTime = defTime | ||
| 304 | + } | ||
| 305 | + } | ||
| 306 | + }, | ||
| 307 | + }, | ||
| 308 | + computed: { | ||
| 309 | + reactStartTime() { | ||
| 310 | + const activeDate = this.isRange ? this.tempRange.startDate : this.tempSingleDate | ||
| 311 | + const res = activeDate === this.caleRange.startDate ? this.caleRange.startTime : '' | ||
| 312 | + return res | ||
| 313 | + }, | ||
| 314 | + reactEndTime() { | ||
| 315 | + const activeDate = this.isRange ? this.tempRange.endDate : this.tempSingleDate | ||
| 316 | + const res = activeDate === this.caleRange.endDate ? this.caleRange.endTime : '' | ||
| 317 | + return res | ||
| 318 | + }, | ||
| 319 | + reactMobDefTime() { | ||
| 320 | + const times = { | ||
| 321 | + start: this.tempRange.startTime, | ||
| 322 | + end: this.tempRange.endTime | ||
| 323 | + } | ||
| 324 | + return this.isRange ? times : this.time | ||
| 325 | + }, | ||
| 326 | + mobSelectableTime() { | ||
| 327 | + return { | ||
| 328 | + start: this.caleRange.startTime, | ||
| 329 | + end: this.caleRange.endTime | ||
| 330 | + } | ||
| 331 | + }, | ||
| 332 | + datePopupWidth() { | ||
| 333 | + // todo | ||
| 334 | + return this.isRange ? 653 : 301 | ||
| 335 | + }, | ||
| 336 | + | ||
| 337 | + /** | ||
| 338 | + * for i18n | ||
| 339 | + */ | ||
| 340 | + singlePlaceholderText() { | ||
| 341 | + return this.placeholder || (this.type === 'date' ? this.selectDateText : t( | ||
| 342 | + "uni-datetime-picker.selectDateTime")) | ||
| 343 | + }, | ||
| 344 | + startPlaceholderText() { | ||
| 345 | + return this.startPlaceholder || this.startDateText | ||
| 346 | + }, | ||
| 347 | + endPlaceholderText() { | ||
| 348 | + return this.endPlaceholder || this.endDateText | ||
| 349 | + }, | ||
| 350 | + selectDateText() { | ||
| 351 | + return t("uni-datetime-picker.selectDate") | ||
| 352 | + }, | ||
| 353 | + selectTimeText() { | ||
| 354 | + return t("uni-datetime-picker.selectTime") | ||
| 355 | + }, | ||
| 356 | + startDateText() { | ||
| 357 | + return this.startPlaceholder || t("uni-datetime-picker.startDate") | ||
| 358 | + }, | ||
| 359 | + startTimeText() { | ||
| 360 | + return t("uni-datetime-picker.startTime") | ||
| 361 | + }, | ||
| 362 | + endDateText() { | ||
| 363 | + return this.endPlaceholder || t("uni-datetime-picker.endDate") | ||
| 364 | + }, | ||
| 365 | + endTimeText() { | ||
| 366 | + return t("uni-datetime-picker.endTime") | ||
| 367 | + }, | ||
| 368 | + okText() { | ||
| 369 | + return t("uni-datetime-picker.ok") | ||
| 370 | + }, | ||
| 371 | + clearText() { | ||
| 372 | + return t("uni-datetime-picker.clear") | ||
| 373 | + }, | ||
| 374 | + showClearIcon() { | ||
| 375 | + const { clearIcon, disabled, singleVal, range } = this | ||
| 376 | + const bool = clearIcon && !disabled && (singleVal || (range.startDate && range.endDate)) | ||
| 377 | + return bool | ||
| 378 | + } | ||
| 379 | + }, | ||
| 380 | + created() { | ||
| 381 | + this.form = this.getForm('uniForms') | ||
| 382 | + this.formItem = this.getForm('uniFormsItem') | ||
| 383 | + | ||
| 384 | + // if (this.formItem) { | ||
| 385 | + // if (this.formItem.name) { | ||
| 386 | + // this.rename = this.formItem.name | ||
| 387 | + // this.form.inputChildrens.push(this) | ||
| 388 | + // } | ||
| 389 | + // } | ||
| 390 | + }, | ||
| 391 | + mounted() { | ||
| 392 | + this.platform() | ||
| 393 | + }, | ||
| 394 | + methods: { | ||
| 395 | + /** | ||
| 396 | + * 获取父元素实例 | ||
| 397 | + */ | ||
| 398 | + getForm(name = 'uniForms') { | ||
| 399 | + let parent = this.$parent; | ||
| 400 | + let parentName = parent.$options.name; | ||
| 401 | + while (parentName !== name) { | ||
| 402 | + parent = parent.$parent; | ||
| 403 | + if (!parent) return false | ||
| 404 | + parentName = parent.$options.name; | ||
| 405 | + } | ||
| 406 | + return parent; | ||
| 407 | + }, | ||
| 408 | + initPicker(newVal) { | ||
| 409 | + if (!newVal || Array.isArray(newVal) && !newVal.length) { | ||
| 410 | + this.$nextTick(() => { | ||
| 411 | + this.clear(false) | ||
| 412 | + }) | ||
| 413 | + return | ||
| 414 | + } | ||
| 415 | + if (!Array.isArray(newVal) && !this.isRange) { | ||
| 416 | + const { | ||
| 417 | + defDate, | ||
| 418 | + defTime | ||
| 419 | + } = this.parseDate(newVal) | ||
| 420 | + this.singleVal = defDate | ||
| 421 | + this.tempSingleDate = defDate | ||
| 422 | + this.defSingleDate = defDate | ||
| 423 | + if (this.hasTime) { | ||
| 424 | + this.singleVal = defDate + ' ' + defTime | ||
| 425 | + this.time = defTime | ||
| 426 | + } | ||
| 427 | + } else { | ||
| 428 | + const [before, after] = newVal | ||
| 429 | + if (!before && !after) return | ||
| 430 | + const defBefore = this.parseDate(before) | ||
| 431 | + const defAfter = this.parseDate(after) | ||
| 432 | + const startDate = defBefore.defDate | ||
| 433 | + const endDate = defAfter.defDate | ||
| 434 | + this.range.startDate = this.tempRange.startDate = startDate | ||
| 435 | + this.range.endDate = this.tempRange.endDate = endDate | ||
| 436 | + | ||
| 437 | + if (this.hasTime) { | ||
| 438 | + this.range.startDate = defBefore.defDate + ' ' + defBefore.defTime | ||
| 439 | + this.range.endDate = defAfter.defDate + ' ' + defAfter.defTime | ||
| 440 | + this.tempRange.startTime = defBefore.defTime | ||
| 441 | + this.tempRange.endTime = defAfter.defTime | ||
| 442 | + } | ||
| 443 | + const defaultRange = { | ||
| 444 | + before: defBefore.defDate, | ||
| 445 | + after: defAfter.defDate | ||
| 446 | + } | ||
| 447 | + this.startMultipleStatus = Object.assign({}, this.startMultipleStatus, defaultRange, { | ||
| 448 | + which: 'right' | ||
| 449 | + }) | ||
| 450 | + this.endMultipleStatus = Object.assign({}, this.endMultipleStatus, defaultRange, { | ||
| 451 | + which: 'left' | ||
| 452 | + }) | ||
| 453 | + } | ||
| 454 | + }, | ||
| 455 | + updateLeftCale(e) { | ||
| 456 | + const left = this.$refs.left | ||
| 457 | + // 设置范围选 | ||
| 458 | + left.cale.setHoverMultiple(e.after) | ||
| 459 | + left.setDate(this.$refs.left.nowDate.fullDate) | ||
| 460 | + }, | ||
| 461 | + updateRightCale(e) { | ||
| 462 | + const right = this.$refs.right | ||
| 463 | + // 设置范围选 | ||
| 464 | + right.cale.setHoverMultiple(e.after) | ||
| 465 | + right.setDate(this.$refs.right.nowDate.fullDate) | ||
| 466 | + }, | ||
| 467 | + platform() { | ||
| 468 | + const systemInfo = uni.getSystemInfoSync() | ||
| 469 | + this.isPhone = systemInfo.windowWidth <= 500 | ||
| 470 | + this.windowWidth = systemInfo.windowWidth | ||
| 471 | + }, | ||
| 472 | + show(event) { | ||
| 473 | + if (this.disabled) { | ||
| 474 | + return | ||
| 475 | + } | ||
| 476 | + this.platform() | ||
| 477 | + if (this.isPhone) { | ||
| 478 | + this.$refs.mobile.open() | ||
| 479 | + return | ||
| 480 | + } | ||
| 481 | + this.popover = { | ||
| 482 | + top: '10px' | ||
| 483 | + } | ||
| 484 | + const dateEditor = uni.createSelectorQuery().in(this).select(".uni-date-editor") | ||
| 485 | + dateEditor.boundingClientRect(rect => { | ||
| 486 | + if (this.windowWidth - rect.left < this.datePopupWidth) { | ||
| 487 | + this.popover.right = 0 | ||
| 488 | + } | ||
| 489 | + }).exec() | ||
| 490 | + setTimeout(() => { | ||
| 491 | + this.popup = !this.popup | ||
| 492 | + if (!this.isPhone && this.isRange && this.isFirstShow) { | ||
| 493 | + this.isFirstShow = false | ||
| 494 | + const { | ||
| 495 | + startDate, | ||
| 496 | + endDate | ||
| 497 | + } = this.range | ||
| 498 | + if (startDate && endDate) { | ||
| 499 | + if (this.diffDate(startDate, endDate) < 30) { | ||
| 500 | + this.$refs.right.next() | ||
| 501 | + } | ||
| 502 | + } else { | ||
| 503 | + this.$refs.right.next() | ||
| 504 | + this.$refs.right.cale.lastHover = false | ||
| 505 | + } | ||
| 506 | + } | ||
| 507 | + | ||
| 508 | + }, 50) | ||
| 509 | + }, | ||
| 510 | + | ||
| 511 | + close() { | ||
| 512 | + setTimeout(() => { | ||
| 513 | + this.popup = false | ||
| 514 | + this.$emit('maskClick', this.value) | ||
| 515 | + }, 20) | ||
| 516 | + }, | ||
| 517 | + setEmit(value) { | ||
| 518 | + if (this.returnType === "timestamp" || this.returnType === "date") { | ||
| 519 | + if (!Array.isArray(value)) { | ||
| 520 | + if (!this.hasTime) { | ||
| 521 | + value = value + ' ' + '00:00:00' | ||
| 522 | + } | ||
| 523 | + value = this.createTimestamp(value) | ||
| 524 | + if (this.returnType === "date") { | ||
| 525 | + value = new Date(value) | ||
| 526 | + } | ||
| 527 | + } else { | ||
| 528 | + if (!this.hasTime) { | ||
| 529 | + value[0] = value[0] + ' ' + '00:00:00' | ||
| 530 | + value[1] = value[1] + ' ' + '00:00:00' | ||
| 531 | + } | ||
| 532 | + value[0] = this.createTimestamp(value[0]) | ||
| 533 | + value[1] = this.createTimestamp(value[1]) | ||
| 534 | + if (this.returnType === "date") { | ||
| 535 | + value[0] = new Date(value[0]) | ||
| 536 | + value[1] = new Date(value[1]) | ||
| 537 | + } | ||
| 538 | + } | ||
| 539 | + } | ||
| 540 | + this.formItem && this.formItem.setValue(value) | ||
| 541 | + this.$emit('change', value) | ||
| 542 | + this.$emit('input', value) | ||
| 543 | + this.$emit('update:modelValue', value) | ||
| 544 | + this.isEmitValue = true | ||
| 545 | + }, | ||
| 546 | + createTimestamp(date) { | ||
| 547 | + date = this.fixIosDateFormat(date) | ||
| 548 | + return Date.parse(new Date(date)) | ||
| 549 | + }, | ||
| 550 | + singleChange(e) { | ||
| 551 | + this.tempSingleDate = e.fulldate | ||
| 552 | + if (this.hasTime) return | ||
| 553 | + this.confirmSingleChange() | ||
| 554 | + }, | ||
| 555 | + | ||
| 556 | + confirmSingleChange() { | ||
| 557 | + if (!this.tempSingleDate) { | ||
| 558 | + this.popup = false | ||
| 559 | + return | ||
| 560 | + } | ||
| 561 | + if (this.hasTime) { | ||
| 562 | + this.singleVal = this.tempSingleDate + ' ' + (this.time ? this.time : '00:00:00') | ||
| 563 | + } else { | ||
| 564 | + this.singleVal = this.tempSingleDate | ||
| 565 | + } | ||
| 566 | + this.setEmit(this.singleVal) | ||
| 567 | + this.popup = false | ||
| 568 | + }, | ||
| 569 | + | ||
| 570 | + leftChange(e) { | ||
| 571 | + const { | ||
| 572 | + before, | ||
| 573 | + after | ||
| 574 | + } = e.range | ||
| 575 | + this.rangeChange(before, after) | ||
| 576 | + const obj = { | ||
| 577 | + before: e.range.before, | ||
| 578 | + after: e.range.after, | ||
| 579 | + data: e.range.data, | ||
| 580 | + fulldate: e.fulldate | ||
| 581 | + } | ||
| 582 | + this.startMultipleStatus = Object.assign({}, this.startMultipleStatus, obj) | ||
| 583 | + }, | ||
| 584 | + | ||
| 585 | + rightChange(e) { | ||
| 586 | + const { | ||
| 587 | + before, | ||
| 588 | + after | ||
| 589 | + } = e.range | ||
| 590 | + this.rangeChange(before, after) | ||
| 591 | + const obj = { | ||
| 592 | + before: e.range.before, | ||
| 593 | + after: e.range.after, | ||
| 594 | + data: e.range.data, | ||
| 595 | + fulldate: e.fulldate | ||
| 596 | + } | ||
| 597 | + this.endMultipleStatus = Object.assign({}, this.endMultipleStatus, obj) | ||
| 598 | + }, | ||
| 599 | + | ||
| 600 | + mobileChange(e) { | ||
| 601 | + if (this.isRange) { | ||
| 602 | + const { | ||
| 603 | + before, | ||
| 604 | + after | ||
| 605 | + } = e.range | ||
| 606 | + this.handleStartAndEnd(before, after, true) | ||
| 607 | + if (this.hasTime) { | ||
| 608 | + const { | ||
| 609 | + startTime, | ||
| 610 | + endTime | ||
| 611 | + } = e.timeRange | ||
| 612 | + this.tempRange.startTime = startTime | ||
| 613 | + this.tempRange.endTime = endTime | ||
| 614 | + } | ||
| 615 | + this.confirmRangeChange() | ||
| 616 | + | ||
| 617 | + } else { | ||
| 618 | + if (this.hasTime) { | ||
| 619 | + this.singleVal = e.fulldate + ' ' + e.time | ||
| 620 | + } else { | ||
| 621 | + this.singleVal = e.fulldate | ||
| 622 | + } | ||
| 623 | + this.setEmit(this.singleVal) | ||
| 624 | + } | ||
| 625 | + this.$refs.mobile.close() | ||
| 626 | + }, | ||
| 627 | + | ||
| 628 | + rangeChange(before, after) { | ||
| 629 | + if (!(before && after)) return | ||
| 630 | + this.handleStartAndEnd(before, after, true) | ||
| 631 | + if (this.hasTime) return | ||
| 632 | + this.confirmRangeChange() | ||
| 633 | + }, | ||
| 634 | + | ||
| 635 | + confirmRangeChange() { | ||
| 636 | + if (!this.tempRange.startDate && !this.tempRange.endDate) { | ||
| 637 | + this.popup = false | ||
| 638 | + return | ||
| 639 | + } | ||
| 640 | + let start, end | ||
| 641 | + if (!this.hasTime) { | ||
| 642 | + start = this.range.startDate = this.tempRange.startDate | ||
| 643 | + end = this.range.endDate = this.tempRange.endDate | ||
| 644 | + } else { | ||
| 645 | + start = this.range.startDate = this.tempRange.startDate + ' ' + | ||
| 646 | + (this.tempRange.startTime ? this.tempRange.startTime : '00:00:00') | ||
| 647 | + end = this.range.endDate = this.tempRange.endDate + ' ' + | ||
| 648 | + (this.tempRange.endTime ? this.tempRange.endTime : '00:00:00') | ||
| 649 | + } | ||
| 650 | + const displayRange = [start, end] | ||
| 651 | + this.setEmit(displayRange) | ||
| 652 | + this.popup = false | ||
| 653 | + }, | ||
| 654 | + | ||
| 655 | + handleStartAndEnd(before, after, temp = false) { | ||
| 656 | + if (!(before && after)) return | ||
| 657 | + const type = temp ? 'tempRange' : 'range' | ||
| 658 | + if (this.dateCompare(before, after)) { | ||
| 659 | + this[type].startDate = before | ||
| 660 | + this[type].endDate = after | ||
| 661 | + } else { | ||
| 662 | + this[type].startDate = after | ||
| 663 | + this[type].endDate = before | ||
| 664 | + } | ||
| 665 | + }, | ||
| 666 | + | ||
| 667 | + /** | ||
| 668 | + * 比较时间大小 | ||
| 669 | + */ | ||
| 670 | + dateCompare(startDate, endDate) { | ||
| 671 | + // 计算截止时间 | ||
| 672 | + startDate = new Date(startDate.replace('-', '/').replace('-', '/')) | ||
| 673 | + // 计算详细项的截止时间 | ||
| 674 | + endDate = new Date(endDate.replace('-', '/').replace('-', '/')) | ||
| 675 | + if (startDate <= endDate) { | ||
| 676 | + return true | ||
| 677 | + } else { | ||
| 678 | + return false | ||
| 679 | + } | ||
| 680 | + }, | ||
| 681 | + | ||
| 682 | + /** | ||
| 683 | + * 比较时间差 | ||
| 684 | + */ | ||
| 685 | + diffDate(startDate, endDate) { | ||
| 686 | + // 计算截止时间 | ||
| 687 | + startDate = new Date(startDate.replace('-', '/').replace('-', '/')) | ||
| 688 | + // 计算详细项的截止时间 | ||
| 689 | + endDate = new Date(endDate.replace('-', '/').replace('-', '/')) | ||
| 690 | + const diff = (endDate - startDate) / (24 * 60 * 60 * 1000) | ||
| 691 | + return Math.abs(diff) | ||
| 692 | + }, | ||
| 693 | + | ||
| 694 | + clear(needEmit = true) { | ||
| 695 | + if (!this.isRange) { | ||
| 696 | + this.singleVal = '' | ||
| 697 | + this.tempSingleDate = '' | ||
| 698 | + this.time = '' | ||
| 699 | + if (this.isPhone) { | ||
| 700 | + this.$refs.mobile && this.$refs.mobile.clearCalender() | ||
| 701 | + } else { | ||
| 702 | + this.$refs.pcSingle && this.$refs.pcSingle.clearCalender() | ||
| 703 | + } | ||
| 704 | + if (needEmit) { | ||
| 705 | + this.formItem && this.formItem.setValue('') | ||
| 706 | + this.$emit('change', '') | ||
| 707 | + this.$emit('input', '') | ||
| 708 | + this.$emit('update:modelValue', '') | ||
| 709 | + } | ||
| 710 | + } else { | ||
| 711 | + this.range.startDate = '' | ||
| 712 | + this.range.endDate = '' | ||
| 713 | + this.tempRange.startDate = '' | ||
| 714 | + this.tempRange.startTime = '' | ||
| 715 | + this.tempRange.endDate = '' | ||
| 716 | + this.tempRange.endTime = '' | ||
| 717 | + if (this.isPhone) { | ||
| 718 | + this.$refs.mobile && this.$refs.mobile.clearCalender() | ||
| 719 | + } else { | ||
| 720 | + this.$refs.left && this.$refs.left.clearCalender() | ||
| 721 | + this.$refs.right && this.$refs.right.clearCalender() | ||
| 722 | + this.$refs.right && this.$refs.right.next() | ||
| 723 | + } | ||
| 724 | + if (needEmit) { | ||
| 725 | + this.formItem && this.formItem.setValue([]) | ||
| 726 | + this.$emit('change', []) | ||
| 727 | + this.$emit('input', []) | ||
| 728 | + this.$emit('update:modelValue', []) | ||
| 729 | + } | ||
| 730 | + } | ||
| 731 | + }, | ||
| 732 | + | ||
| 733 | + parseDate(date) { | ||
| 734 | + date = this.fixIosDateFormat(date) | ||
| 735 | + const defVal = new Date(date) | ||
| 736 | + const year = defVal.getFullYear() | ||
| 737 | + const month = defVal.getMonth() + 1 | ||
| 738 | + const day = defVal.getDate() | ||
| 739 | + const hour = defVal.getHours() | ||
| 740 | + const minute = defVal.getMinutes() | ||
| 741 | + const second = defVal.getSeconds() | ||
| 742 | + const defDate = year + '-' + this.lessTen(month) + '-' + this.lessTen(day) | ||
| 743 | + const defTime = this.lessTen(hour) + ':' + this.lessTen(minute) + (this.hideSecond ? '' : (':' + this | ||
| 744 | + .lessTen(second))) | ||
| 745 | + return { | ||
| 746 | + defDate, | ||
| 747 | + defTime | ||
| 748 | + } | ||
| 749 | + }, | ||
| 750 | + | ||
| 751 | + lessTen(item) { | ||
| 752 | + return item < 10 ? '0' + item : item | ||
| 753 | + }, | ||
| 754 | + | ||
| 755 | + //兼容 iOS、safari 日期格式 | ||
| 756 | + fixIosDateFormat(value) { | ||
| 757 | + if (typeof value === 'string') { | ||
| 758 | + value = value.replace(/-/g, '/') | ||
| 759 | + } | ||
| 760 | + return value | ||
| 761 | + }, | ||
| 762 | + | ||
| 763 | + leftMonthSwitch(e) { | ||
| 764 | + // console.log('leftMonthSwitch 返回:', e) | ||
| 765 | + }, | ||
| 766 | + rightMonthSwitch(e) { | ||
| 767 | + // console.log('rightMonthSwitch 返回:', e) | ||
| 768 | + } | ||
| 769 | + } | ||
| 770 | + } | ||
| 771 | +</script> | ||
| 772 | + | ||
| 773 | +<style> | ||
| 774 | + .uni-date-x { | ||
| 775 | + display: flex; | ||
| 776 | + flex-direction: row; | ||
| 777 | + align-items: center; | ||
| 778 | + justify-content: center; | ||
| 779 | + padding: 0 10px; | ||
| 780 | + border-radius: 4px; | ||
| 781 | + background-color: #fff; | ||
| 782 | + color: #666; | ||
| 783 | + font-size: 14px; | ||
| 784 | + } | ||
| 785 | + | ||
| 786 | + .uni-date-x--border { | ||
| 787 | + box-sizing: border-box; | ||
| 788 | + border-radius: 4px; | ||
| 789 | + border: 1px solid #dcdfe6; | ||
| 790 | + } | ||
| 791 | + | ||
| 792 | + .uni-date-editor--x { | ||
| 793 | + position: relative; | ||
| 794 | + } | ||
| 795 | + | ||
| 796 | + .uni-date-editor--x .uni-date__icon-clear { | ||
| 797 | + position: absolute; | ||
| 798 | + top: 0; | ||
| 799 | + right: 0; | ||
| 800 | + display: inline-block; | ||
| 801 | + box-sizing: border-box; | ||
| 802 | + border: 9px solid transparent; | ||
| 803 | + /* #ifdef H5 */ | ||
| 804 | + cursor: pointer; | ||
| 805 | + /* #endif */ | ||
| 806 | + } | ||
| 807 | + | ||
| 808 | + .uni-date__x-input { | ||
| 809 | + padding: 0 8px; | ||
| 810 | + height: 40px; | ||
| 811 | + width: 100%; | ||
| 812 | + line-height: 40px; | ||
| 813 | + font-size: 14px; | ||
| 814 | + } | ||
| 815 | + | ||
| 816 | + .t-c { | ||
| 817 | + text-align: center; | ||
| 818 | + } | ||
| 819 | + | ||
| 820 | + .uni-date__input { | ||
| 821 | + height: 40px; | ||
| 822 | + width: 100%; | ||
| 823 | + line-height: 40px; | ||
| 824 | + font-size: 14px; | ||
| 825 | + } | ||
| 826 | + | ||
| 827 | + .uni-date-range__input { | ||
| 828 | + text-align: center; | ||
| 829 | + max-width: 142px; | ||
| 830 | + } | ||
| 831 | + | ||
| 832 | + .uni-date-picker__container { | ||
| 833 | + position: relative; | ||
| 834 | + /* position: fixed; | ||
| 835 | + left: 0; | ||
| 836 | + right: 0; | ||
| 837 | + top: 0; | ||
| 838 | + bottom: 0; | ||
| 839 | + box-sizing: border-box; | ||
| 840 | + z-index: 996; | ||
| 841 | + font-size: 14px; */ | ||
| 842 | + } | ||
| 843 | + | ||
| 844 | + .uni-date-mask { | ||
| 845 | + position: fixed; | ||
| 846 | + bottom: 0px; | ||
| 847 | + top: 0px; | ||
| 848 | + left: 0px; | ||
| 849 | + right: 0px; | ||
| 850 | + background-color: rgba(0, 0, 0, 0); | ||
| 851 | + transition-duration: 0.3s; | ||
| 852 | + z-index: 996; | ||
| 853 | + } | ||
| 854 | + | ||
| 855 | + .uni-date-single--x { | ||
| 856 | + /* padding: 0 8px; */ | ||
| 857 | + background-color: #fff; | ||
| 858 | + position: absolute; | ||
| 859 | + top: 0; | ||
| 860 | + z-index: 999; | ||
| 861 | + border: 1px solid #EBEEF5; | ||
| 862 | + box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); | ||
| 863 | + border-radius: 4px; | ||
| 864 | + } | ||
| 865 | + | ||
| 866 | + .uni-date-range--x { | ||
| 867 | + /* padding: 0 8px; */ | ||
| 868 | + background-color: #fff; | ||
| 869 | + position: absolute; | ||
| 870 | + top: 0; | ||
| 871 | + z-index: 999; | ||
| 872 | + border: 1px solid #EBEEF5; | ||
| 873 | + box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); | ||
| 874 | + border-radius: 4px; | ||
| 875 | + } | ||
| 876 | + | ||
| 877 | + .uni-date-editor--x__disabled { | ||
| 878 | + opacity: 0.4; | ||
| 879 | + cursor: default; | ||
| 880 | + } | ||
| 881 | + | ||
| 882 | + .uni-date-editor--logo { | ||
| 883 | + width: 16px; | ||
| 884 | + height: 16px; | ||
| 885 | + vertical-align: middle; | ||
| 886 | + } | ||
| 887 | + | ||
| 888 | + /* 添加时间 */ | ||
| 889 | + .popup-x-header { | ||
| 890 | + /* #ifndef APP-NVUE */ | ||
| 891 | + display: flex; | ||
| 892 | + /* #endif */ | ||
| 893 | + flex-direction: row; | ||
| 894 | + /* justify-content: space-between; */ | ||
| 895 | + } | ||
| 896 | + | ||
| 897 | + .popup-x-header--datetime { | ||
| 898 | + /* #ifndef APP-NVUE */ | ||
| 899 | + display: flex; | ||
| 900 | + /* #endif */ | ||
| 901 | + flex-direction: row; | ||
| 902 | + flex: 1; | ||
| 903 | + } | ||
| 904 | + | ||
| 905 | + .popup-x-body { | ||
| 906 | + display: flex; | ||
| 907 | + } | ||
| 908 | + | ||
| 909 | + .popup-x-footer { | ||
| 910 | + padding: 0 15px; | ||
| 911 | + border-top-color: #F1F1F1; | ||
| 912 | + border-top-style: solid; | ||
| 913 | + border-top-width: 1px; | ||
| 914 | + /* background-color: #fff; */ | ||
| 915 | + line-height: 40px; | ||
| 916 | + text-align: right; | ||
| 917 | + color: #666; | ||
| 918 | + } | ||
| 919 | + | ||
| 920 | + .popup-x-footer text:hover { | ||
| 921 | + color: #007aff; | ||
| 922 | + cursor: pointer; | ||
| 923 | + opacity: 0.8; | ||
| 924 | + } | ||
| 925 | + | ||
| 926 | + .popup-x-footer .confirm { | ||
| 927 | + margin-left: 20px; | ||
| 928 | + color: #007aff; | ||
| 929 | + } | ||
| 930 | + | ||
| 931 | + .uni-date-changed { | ||
| 932 | + /* background-color: #fff; */ | ||
| 933 | + text-align: center; | ||
| 934 | + color: #333; | ||
| 935 | + border-bottom-color: #F1F1F1; | ||
| 936 | + border-bottom-style: solid; | ||
| 937 | + border-bottom-width: 1px; | ||
| 938 | + /* padding: 0 50px; */ | ||
| 939 | + } | ||
| 940 | + | ||
| 941 | + .uni-date-changed--time text { | ||
| 942 | + /* padding: 0 20px; */ | ||
| 943 | + height: 50px; | ||
| 944 | + line-height: 50px; | ||
| 945 | + } | ||
| 946 | + | ||
| 947 | + .uni-date-changed .uni-date-changed--time { | ||
| 948 | + /* display: flex; */ | ||
| 949 | + flex: 1; | ||
| 950 | + } | ||
| 951 | + | ||
| 952 | + .uni-date-changed--time-date { | ||
| 953 | + color: #333; | ||
| 954 | + opacity: 0.6; | ||
| 955 | + } | ||
| 956 | + | ||
| 957 | + .mr-50 { | ||
| 958 | + margin-right: 50px; | ||
| 959 | + } | ||
| 960 | + | ||
| 961 | + /* picker 弹出层通用的指示小三角, todo:扩展至上下左右方向定位 */ | ||
| 962 | + .uni-popper__arrow, | ||
| 963 | + .uni-popper__arrow::after { | ||
| 964 | + position: absolute; | ||
| 965 | + display: block; | ||
| 966 | + width: 0; | ||
| 967 | + height: 0; | ||
| 968 | + border-color: transparent; | ||
| 969 | + border-style: solid; | ||
| 970 | + border-width: 6px; | ||
| 971 | + } | ||
| 972 | + | ||
| 973 | + .uni-popper__arrow { | ||
| 974 | + filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03)); | ||
| 975 | + top: -6px; | ||
| 976 | + left: 10%; | ||
| 977 | + margin-right: 3px; | ||
| 978 | + border-top-width: 0; | ||
| 979 | + border-bottom-color: #EBEEF5; | ||
| 980 | + } | ||
| 981 | + | ||
| 982 | + .uni-popper__arrow::after { | ||
| 983 | + content: " "; | ||
| 984 | + top: 1px; | ||
| 985 | + margin-left: -6px; | ||
| 986 | + border-top-width: 0; | ||
| 987 | + border-bottom-color: #fff; | ||
| 988 | + } | ||
| 989 | +</style> |
| 1 | +class Calendar { | ||
| 2 | + constructor({ | ||
| 3 | + date, | ||
| 4 | + selected, | ||
| 5 | + startDate, | ||
| 6 | + endDate, | ||
| 7 | + range, | ||
| 8 | + // multipleStatus | ||
| 9 | + } = {}) { | ||
| 10 | + // 当前日期 | ||
| 11 | + this.date = this.getDate(new Date()) // 当前初入日期 | ||
| 12 | + // 打点信息 | ||
| 13 | + this.selected = selected || []; | ||
| 14 | + // 范围开始 | ||
| 15 | + this.startDate = startDate | ||
| 16 | + // 范围结束 | ||
| 17 | + this.endDate = endDate | ||
| 18 | + this.range = range | ||
| 19 | + // 多选状态 | ||
| 20 | + this.cleanMultipleStatus() | ||
| 21 | + // 每周日期 | ||
| 22 | + this.weeks = {} | ||
| 23 | + // this._getWeek(this.date.fullDate) | ||
| 24 | + // this.multipleStatus = multipleStatus | ||
| 25 | + this.lastHover = false | ||
| 26 | + } | ||
| 27 | + /** | ||
| 28 | + * 设置日期 | ||
| 29 | + * @param {Object} date | ||
| 30 | + */ | ||
| 31 | + setDate(date) { | ||
| 32 | + this.selectDate = this.getDate(date) | ||
| 33 | + this._getWeek(this.selectDate.fullDate) | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + /** | ||
| 37 | + * 清理多选状态 | ||
| 38 | + */ | ||
| 39 | + cleanMultipleStatus() { | ||
| 40 | + this.multipleStatus = { | ||
| 41 | + before: '', | ||
| 42 | + after: '', | ||
| 43 | + data: [] | ||
| 44 | + } | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + /** | ||
| 48 | + * 重置开始日期 | ||
| 49 | + */ | ||
| 50 | + resetSatrtDate(startDate) { | ||
| 51 | + // 范围开始 | ||
| 52 | + this.startDate = startDate | ||
| 53 | + | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + /** | ||
| 57 | + * 重置结束日期 | ||
| 58 | + */ | ||
| 59 | + resetEndDate(endDate) { | ||
| 60 | + // 范围结束 | ||
| 61 | + this.endDate = endDate | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + /** | ||
| 65 | + * 获取任意时间 | ||
| 66 | + */ | ||
| 67 | + getDate(date, AddDayCount = 0, str = 'day') { | ||
| 68 | + if (!date) { | ||
| 69 | + date = new Date() | ||
| 70 | + } | ||
| 71 | + if (typeof date !== 'object') { | ||
| 72 | + date = date.replace(/-/g, '/') | ||
| 73 | + } | ||
| 74 | + const dd = new Date(date) | ||
| 75 | + switch (str) { | ||
| 76 | + case 'day': | ||
| 77 | + dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期 | ||
| 78 | + break | ||
| 79 | + case 'month': | ||
| 80 | + if (dd.getDate() === 31) { | ||
| 81 | + dd.setDate(dd.getDate() + AddDayCount) | ||
| 82 | + } else { | ||
| 83 | + dd.setMonth(dd.getMonth() + AddDayCount) // 获取AddDayCount天后的日期 | ||
| 84 | + } | ||
| 85 | + break | ||
| 86 | + case 'year': | ||
| 87 | + dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期 | ||
| 88 | + break | ||
| 89 | + } | ||
| 90 | + const y = dd.getFullYear() | ||
| 91 | + const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0 | ||
| 92 | + const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0 | ||
| 93 | + return { | ||
| 94 | + fullDate: y + '-' + m + '-' + d, | ||
| 95 | + year: y, | ||
| 96 | + month: m, | ||
| 97 | + date: d, | ||
| 98 | + day: dd.getDay() | ||
| 99 | + } | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + | ||
| 103 | + /** | ||
| 104 | + * 获取上月剩余天数 | ||
| 105 | + */ | ||
| 106 | + _getLastMonthDays(firstDay, full) { | ||
| 107 | + let dateArr = [] | ||
| 108 | + for (let i = firstDay; i > 0; i--) { | ||
| 109 | + const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate() | ||
| 110 | + dateArr.push({ | ||
| 111 | + date: beforeDate, | ||
| 112 | + month: full.month - 1, | ||
| 113 | + disable: true | ||
| 114 | + }) | ||
| 115 | + } | ||
| 116 | + return dateArr | ||
| 117 | + } | ||
| 118 | + /** | ||
| 119 | + * 获取本月天数 | ||
| 120 | + */ | ||
| 121 | + _currentMonthDys(dateData, full) { | ||
| 122 | + let dateArr = [] | ||
| 123 | + let fullDate = this.date.fullDate | ||
| 124 | + for (let i = 1; i <= dateData; i++) { | ||
| 125 | + let isinfo = false | ||
| 126 | + let nowDate = full.year + '-' + (full.month < 10 ? | ||
| 127 | + full.month : full.month) + '-' + (i < 10 ? | ||
| 128 | + '0' + i : i) | ||
| 129 | + // 是否今天 | ||
| 130 | + let isDay = fullDate === nowDate | ||
| 131 | + // 获取打点信息 | ||
| 132 | + let info = this.selected && this.selected.find((item) => { | ||
| 133 | + if (this.dateEqual(nowDate, item.date)) { | ||
| 134 | + return item | ||
| 135 | + } | ||
| 136 | + }) | ||
| 137 | + | ||
| 138 | + // 日期禁用 | ||
| 139 | + let disableBefore = true | ||
| 140 | + let disableAfter = true | ||
| 141 | + if (this.startDate) { | ||
| 142 | + // let dateCompBefore = this.dateCompare(this.startDate, fullDate) | ||
| 143 | + // disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate) | ||
| 144 | + disableBefore = this.dateCompare(this.startDate, nowDate) | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + if (this.endDate) { | ||
| 148 | + // let dateCompAfter = this.dateCompare(fullDate, this.endDate) | ||
| 149 | + // disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate) | ||
| 150 | + disableAfter = this.dateCompare(nowDate, this.endDate) | ||
| 151 | + } | ||
| 152 | + let multiples = this.multipleStatus.data | ||
| 153 | + let checked = false | ||
| 154 | + let multiplesStatus = -1 | ||
| 155 | + if (this.range) { | ||
| 156 | + if (multiples) { | ||
| 157 | + multiplesStatus = multiples.findIndex((item) => { | ||
| 158 | + return this.dateEqual(item, nowDate) | ||
| 159 | + }) | ||
| 160 | + } | ||
| 161 | + if (multiplesStatus !== -1) { | ||
| 162 | + checked = true | ||
| 163 | + } | ||
| 164 | + } | ||
| 165 | + let data = { | ||
| 166 | + fullDate: nowDate, | ||
| 167 | + year: full.year, | ||
| 168 | + date: i, | ||
| 169 | + multiple: this.range ? checked : false, | ||
| 170 | + beforeMultiple: this.isLogicBefore(nowDate, this.multipleStatus.before, this.multipleStatus.after), | ||
| 171 | + afterMultiple: this.isLogicAfter(nowDate, this.multipleStatus.before, this.multipleStatus.after), | ||
| 172 | + month: full.month, | ||
| 173 | + disable: !(disableBefore && disableAfter), | ||
| 174 | + isDay, | ||
| 175 | + userChecked: false | ||
| 176 | + } | ||
| 177 | + if (info) { | ||
| 178 | + data.extraInfo = info | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + dateArr.push(data) | ||
| 182 | + } | ||
| 183 | + return dateArr | ||
| 184 | + } | ||
| 185 | + /** | ||
| 186 | + * 获取下月天数 | ||
| 187 | + */ | ||
| 188 | + _getNextMonthDays(surplus, full) { | ||
| 189 | + let dateArr = [] | ||
| 190 | + for (let i = 1; i < surplus + 1; i++) { | ||
| 191 | + dateArr.push({ | ||
| 192 | + date: i, | ||
| 193 | + month: Number(full.month) + 1, | ||
| 194 | + disable: true | ||
| 195 | + }) | ||
| 196 | + } | ||
| 197 | + return dateArr | ||
| 198 | + } | ||
| 199 | + | ||
| 200 | + /** | ||
| 201 | + * 获取当前日期详情 | ||
| 202 | + * @param {Object} date | ||
| 203 | + */ | ||
| 204 | + getInfo(date) { | ||
| 205 | + if (!date) { | ||
| 206 | + date = new Date() | ||
| 207 | + } | ||
| 208 | + const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate) | ||
| 209 | + return dateInfo | ||
| 210 | + } | ||
| 211 | + | ||
| 212 | + /** | ||
| 213 | + * 比较时间大小 | ||
| 214 | + */ | ||
| 215 | + dateCompare(startDate, endDate) { | ||
| 216 | + // 计算截止时间 | ||
| 217 | + startDate = new Date(startDate.replace('-', '/').replace('-', '/')) | ||
| 218 | + // 计算详细项的截止时间 | ||
| 219 | + endDate = new Date(endDate.replace('-', '/').replace('-', '/')) | ||
| 220 | + if (startDate <= endDate) { | ||
| 221 | + return true | ||
| 222 | + } else { | ||
| 223 | + return false | ||
| 224 | + } | ||
| 225 | + } | ||
| 226 | + | ||
| 227 | + /** | ||
| 228 | + * 比较时间是否相等 | ||
| 229 | + */ | ||
| 230 | + dateEqual(before, after) { | ||
| 231 | + // 计算截止时间 | ||
| 232 | + before = new Date(before.replace('-', '/').replace('-', '/')) | ||
| 233 | + // 计算详细项的截止时间 | ||
| 234 | + after = new Date(after.replace('-', '/').replace('-', '/')) | ||
| 235 | + if (before.getTime() - after.getTime() === 0) { | ||
| 236 | + return true | ||
| 237 | + } else { | ||
| 238 | + return false | ||
| 239 | + } | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + /** | ||
| 243 | + * 比较真实起始日期 | ||
| 244 | + */ | ||
| 245 | + | ||
| 246 | + isLogicBefore(currentDay, before, after) { | ||
| 247 | + let logicBefore = before | ||
| 248 | + if (before && after) { | ||
| 249 | + logicBefore = this.dateCompare(before, after) ? before : after | ||
| 250 | + } | ||
| 251 | + return this.dateEqual(logicBefore, currentDay) | ||
| 252 | + } | ||
| 253 | + | ||
| 254 | + isLogicAfter(currentDay, before, after) { | ||
| 255 | + let logicAfter = after | ||
| 256 | + if (before && after) { | ||
| 257 | + logicAfter = this.dateCompare(before, after) ? after : before | ||
| 258 | + } | ||
| 259 | + return this.dateEqual(logicAfter, currentDay) | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + /** | ||
| 263 | + * 获取日期范围内所有日期 | ||
| 264 | + * @param {Object} begin | ||
| 265 | + * @param {Object} end | ||
| 266 | + */ | ||
| 267 | + geDateAll(begin, end) { | ||
| 268 | + var arr = [] | ||
| 269 | + var ab = begin.split('-') | ||
| 270 | + var ae = end.split('-') | ||
| 271 | + var db = new Date() | ||
| 272 | + db.setFullYear(ab[0], ab[1] - 1, ab[2]) | ||
| 273 | + var de = new Date() | ||
| 274 | + de.setFullYear(ae[0], ae[1] - 1, ae[2]) | ||
| 275 | + var unixDb = db.getTime() - 24 * 60 * 60 * 1000 | ||
| 276 | + var unixDe = de.getTime() - 24 * 60 * 60 * 1000 | ||
| 277 | + for (var k = unixDb; k <= unixDe;) { | ||
| 278 | + k = k + 24 * 60 * 60 * 1000 | ||
| 279 | + arr.push(this.getDate(new Date(parseInt(k))).fullDate) | ||
| 280 | + } | ||
| 281 | + return arr | ||
| 282 | + } | ||
| 283 | + | ||
| 284 | + /** | ||
| 285 | + * 获取多选状态 | ||
| 286 | + */ | ||
| 287 | + setMultiple(fullDate) { | ||
| 288 | + let { | ||
| 289 | + before, | ||
| 290 | + after | ||
| 291 | + } = this.multipleStatus | ||
| 292 | + if (!this.range) return | ||
| 293 | + if (before && after) { | ||
| 294 | + if (!this.lastHover) { | ||
| 295 | + this.lastHover = true | ||
| 296 | + return | ||
| 297 | + } | ||
| 298 | + this.multipleStatus.before = fullDate | ||
| 299 | + this.multipleStatus.after = '' | ||
| 300 | + this.multipleStatus.data = [] | ||
| 301 | + this.multipleStatus.fulldate = '' | ||
| 302 | + this.lastHover = false | ||
| 303 | + } else { | ||
| 304 | + if (!before) { | ||
| 305 | + this.multipleStatus.before = fullDate | ||
| 306 | + this.lastHover = false | ||
| 307 | + } else { | ||
| 308 | + this.multipleStatus.after = fullDate | ||
| 309 | + if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) { | ||
| 310 | + this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus | ||
| 311 | + .after); | ||
| 312 | + } else { | ||
| 313 | + this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus | ||
| 314 | + .before); | ||
| 315 | + } | ||
| 316 | + this.lastHover = true | ||
| 317 | + } | ||
| 318 | + } | ||
| 319 | + this._getWeek(fullDate) | ||
| 320 | + } | ||
| 321 | + | ||
| 322 | + /** | ||
| 323 | + * 鼠标 hover 更新多选状态 | ||
| 324 | + */ | ||
| 325 | + setHoverMultiple(fullDate) { | ||
| 326 | + let { | ||
| 327 | + before, | ||
| 328 | + after | ||
| 329 | + } = this.multipleStatus | ||
| 330 | + | ||
| 331 | + if (!this.range) return | ||
| 332 | + if (this.lastHover) return | ||
| 333 | + | ||
| 334 | + if (!before) { | ||
| 335 | + this.multipleStatus.before = fullDate | ||
| 336 | + } else { | ||
| 337 | + this.multipleStatus.after = fullDate | ||
| 338 | + if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) { | ||
| 339 | + this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after); | ||
| 340 | + } else { | ||
| 341 | + this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before); | ||
| 342 | + } | ||
| 343 | + } | ||
| 344 | + this._getWeek(fullDate) | ||
| 345 | + } | ||
| 346 | + | ||
| 347 | + /** | ||
| 348 | + * 更新默认值多选状态 | ||
| 349 | + */ | ||
| 350 | + setDefaultMultiple(before, after) { | ||
| 351 | + this.multipleStatus.before = before | ||
| 352 | + this.multipleStatus.after = after | ||
| 353 | + if (before && after) { | ||
| 354 | + if (this.dateCompare(before, after)) { | ||
| 355 | + this.multipleStatus.data = this.geDateAll(before, after); | ||
| 356 | + this._getWeek(after) | ||
| 357 | + } else { | ||
| 358 | + this.multipleStatus.data = this.geDateAll(after, before); | ||
| 359 | + this._getWeek(before) | ||
| 360 | + } | ||
| 361 | + } | ||
| 362 | + } | ||
| 363 | + | ||
| 364 | + /** | ||
| 365 | + * 获取每周数据 | ||
| 366 | + * @param {Object} dateData | ||
| 367 | + */ | ||
| 368 | + _getWeek(dateData) { | ||
| 369 | + const { | ||
| 370 | + fullDate, | ||
| 371 | + year, | ||
| 372 | + month, | ||
| 373 | + date, | ||
| 374 | + day | ||
| 375 | + } = this.getDate(dateData) | ||
| 376 | + let firstDay = new Date(year, month - 1, 1).getDay() | ||
| 377 | + let currentDay = new Date(year, month, 0).getDate() | ||
| 378 | + let dates = { | ||
| 379 | + lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天 | ||
| 380 | + currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数 | ||
| 381 | + nextMonthDays: [], // 下个月开始几天 | ||
| 382 | + weeks: [] | ||
| 383 | + } | ||
| 384 | + let canlender = [] | ||
| 385 | + const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length) | ||
| 386 | + dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData)) | ||
| 387 | + canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays) | ||
| 388 | + let weeks = {} | ||
| 389 | + // 拼接数组 上个月开始几天 + 本月天数+ 下个月开始几天 | ||
| 390 | + for (let i = 0; i < canlender.length; i++) { | ||
| 391 | + if (i % 7 === 0) { | ||
| 392 | + weeks[parseInt(i / 7)] = new Array(7) | ||
| 393 | + } | ||
| 394 | + weeks[parseInt(i / 7)][i % 7] = canlender[i] | ||
| 395 | + } | ||
| 396 | + this.canlender = canlender | ||
| 397 | + this.weeks = weeks | ||
| 398 | + } | ||
| 399 | + | ||
| 400 | + //静态方法 | ||
| 401 | + // static init(date) { | ||
| 402 | + // if (!this.instance) { | ||
| 403 | + // this.instance = new Calendar(date); | ||
| 404 | + // } | ||
| 405 | + // return this.instance; | ||
| 406 | + // } | ||
| 407 | +} | ||
| 408 | + | ||
| 409 | + | ||
| 410 | +export default Calendar |
uni_modules/uni-datetime-picker/package.json
0 → 100644
| 1 | +{ | ||
| 2 | + "id": "uni-datetime-picker", | ||
| 3 | + "displayName": "uni-datetime-picker 日期选择器", | ||
| 4 | + "version": "2.2.3", | ||
| 5 | + "description": "uni-datetime-picker 日期时间选择器,支持日历,支持范围选择", | ||
| 6 | + "keywords": [ | ||
| 7 | + "uni-datetime-picker", | ||
| 8 | + "uni-ui", | ||
| 9 | + "uniui", | ||
| 10 | + "日期时间选择器", | ||
| 11 | + "日期时间" | ||
| 12 | +], | ||
| 13 | + "repository": "https://github.com/dcloudio/uni-ui", | ||
| 14 | + "engines": { | ||
| 15 | + "HBuilderX": "" | ||
| 16 | + }, | ||
| 17 | + "directories": { | ||
| 18 | + "example": "../../temps/example_temps" | ||
| 19 | + }, | ||
| 20 | + "dcloudext": { | ||
| 21 | + "category": [ | ||
| 22 | + "前端组件", | ||
| 23 | + "通用组件" | ||
| 24 | + ], | ||
| 25 | + "sale": { | ||
| 26 | + "regular": { | ||
| 27 | + "price": "0.00" | ||
| 28 | + }, | ||
| 29 | + "sourcecode": { | ||
| 30 | + "price": "0.00" | ||
| 31 | + } | ||
| 32 | + }, | ||
| 33 | + "contact": { | ||
| 34 | + "qq": "" | ||
| 35 | + }, | ||
| 36 | + "declaration": { | ||
| 37 | + "ads": "无", | ||
| 38 | + "data": "无", | ||
| 39 | + "permissions": "无" | ||
| 40 | + }, | ||
| 41 | + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" | ||
| 42 | + }, | ||
| 43 | + "uni_modules": { | ||
| 44 | + "dependencies": [ | ||
| 45 | + "uni-scss", | ||
| 46 | + "uni-icons" | ||
| 47 | + ], | ||
| 48 | + "encrypt": [], | ||
| 49 | + "platforms": { | ||
| 50 | + "cloud": { | ||
| 51 | + "tcb": "y", | ||
| 52 | + "aliyun": "y" | ||
| 53 | + }, | ||
| 54 | + "client": { | ||
| 55 | + "App": { | ||
| 56 | + "app-vue": "y", | ||
| 57 | + "app-nvue": "n" | ||
| 58 | + }, | ||
| 59 | + "H5-mobile": { | ||
| 60 | + "Safari": "y", | ||
| 61 | + "Android Browser": "y", | ||
| 62 | + "微信浏览器(Android)": "y", | ||
| 63 | + "QQ浏览器(Android)": "y" | ||
| 64 | + }, | ||
| 65 | + "H5-pc": { | ||
| 66 | + "Chrome": "y", | ||
| 67 | + "IE": "y", | ||
| 68 | + "Edge": "y", | ||
| 69 | + "Firefox": "y", | ||
| 70 | + "Safari": "y" | ||
| 71 | + }, | ||
| 72 | + "小程序": { | ||
| 73 | + "微信": "y", | ||
| 74 | + "阿里": "y", | ||
| 75 | + "百度": "y", | ||
| 76 | + "字节跳动": "y", | ||
| 77 | + "QQ": "y" | ||
| 78 | + }, | ||
| 79 | + "快应用": { | ||
| 80 | + "华为": "u", | ||
| 81 | + "联盟": "u" | ||
| 82 | + }, | ||
| 83 | + "Vue": { | ||
| 84 | + "vue2": "y", | ||
| 85 | + "vue3": "y" | ||
| 86 | + } | ||
| 87 | + } | ||
| 88 | + } | ||
| 89 | + } | ||
| 90 | +} |
uni_modules/uni-datetime-picker/readme.md
0 → 100644
| 1 | + | ||
| 2 | + | ||
| 3 | +> `重要通知:组件升级更新 2.0.0 后,支持日期+时间范围选择,组件 ui 将使用日历选择日期,ui 变化较大,同时支持 PC 和 移动端。此版本不向后兼容,不再支持单独的时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker)。若仍需使用旧版本,可在插件市场下载*非uni_modules版本*,旧版本将不再维护` | ||
| 4 | + | ||
| 5 | +## DatetimePicker 时间选择器 | ||
| 6 | + | ||
| 7 | +> **组件名:uni-datetime-picker** | ||
| 8 | +> 代码块: `uDatetimePicker` | ||
| 9 | + | ||
| 10 | + | ||
| 11 | +该组件的优势是,支持**时间戳**输入和输出(起始时间、终止时间也支持时间戳),可**同时选择**日期和时间。 | ||
| 12 | + | ||
| 13 | +若只是需要单独选择日期和时间,不需要时间戳输入和输出,可使用原生的 picker 组件。 | ||
| 14 | + | ||
| 15 | +**_点击 picker 默认值规则:_** | ||
| 16 | + | ||
| 17 | +- 若设置初始值 value, 会显示在 picker 显示框中 | ||
| 18 | +- 若无初始值 value,则初始值 value 为当前本地时间 Date.now(), 但不会显示在 picker 显示框中 | ||
| 19 | + | ||
| 20 | +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker) | ||
| 21 | +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 |