From 5cc9b892b8e08fb8eb27589e9047292d58fafb01 Mon Sep 17 00:00:00 2001
From: 梁灏 <admin@aresn.com>
Date: Fri, 30 Dec 2016 10:57:10 +0800
Subject: [PATCH] update DateTimePicker

---
 src/components/date-picker/base/confirm.vue     | 11 +++++++++++
 src/components/date-picker/base/date-table.vue  |  7 ++++++-
 src/components/date-picker/panel/date-range.vue |  4 ++--
 src/components/date-picker/panel/date.vue       | 57 +++++++++++++++++++++++++++++++++++++++++++--------------
 src/components/date-picker/panel/time.vue       | 16 ++++++++++++++--
 src/components/date-picker/picker.vue           |  8 +++++++-
 src/styles/components/date-picker.less          | 14 ++++++++++++++
 test/routers/date.vue                           |  2 +-
 8 files changed, 98 insertions(+), 21 deletions(-)

diff --git a/src/components/date-picker/base/confirm.vue b/src/components/date-picker/base/confirm.vue
index e7f05a4..edc43e1 100644
--- a/src/components/date-picker/base/confirm.vue
+++ b/src/components/date-picker/base/confirm.vue
@@ -1,5 +1,9 @@
 <template>
     <div :class="[prefixCls + '-confirm']">
+        <span v-if="showTime" @click="handleToggleTime">
+            <template v-if="isTime">选择日期</template>
+            <template v-else>选择时间</template>
+        </span>
         <i-button size="small" type="text" @click="handleClear">清空</i-button>
         <i-button size="small" type="primary" @click="handleSuccess">确定</i-button>
     </div>
@@ -11,6 +15,10 @@
 
     export default {
         components: { iButton },
+        props: {
+            showTime: false,
+            isTime: false
+        },
         data () {
             return {
                 prefixCls: prefixCls
@@ -22,6 +30,9 @@
             },
             handleSuccess () {
                 this.$emit('on-pick-success');
+            },
+            handleToggleTime () {
+                this.$emit('on-pick-toggle-time');
             }
         }
     };
diff --git a/src/components/date-picker/base/date-table.vue b/src/components/date-picker/base/date-table.vue
index 99c0175..2ab18e0 100644
--- a/src/components/date-picker/base/date-table.vue
+++ b/src/components/date-picker/base/date-table.vue
@@ -168,6 +168,11 @@
                 let month = this.month;
                 let day = cell.text;
 
+                const date = this.date;
+                const hours = date.getHours();
+                const minutes = date.getMinutes();
+                const seconds = date.getSeconds();
+
                 if (cell.type === 'prev-month') {
                     if (month === 0) {
                         month = 11;
@@ -184,7 +189,7 @@
                     }
                 }
 
-                return new Date(year, month, day);
+                return new Date(year, month, day, hours, minutes, seconds);
             },
             handleClick (event) {
                 const target = event.target;
diff --git a/src/components/date-picker/panel/date-range.vue b/src/components/date-picker/panel/date-range.vue
index e446166..6b03bc9 100644
--- a/src/components/date-picker/panel/date-range.vue
+++ b/src/components/date-picker/panel/date-range.vue
@@ -126,7 +126,7 @@
     import YearTable from '../base/year-table.vue';
     import MonthTable from '../base/month-table.vue';
     import Confirm from '../base/confirm.vue';
-    import { toDate, prevMonth, nextMonth } from '../util';
+    import { toDate, prevMonth, nextMonth, initTimeDate } from '../util';
 
     import Mixin from './mixin';
 
@@ -141,7 +141,7 @@
                 prefixCls: prefixCls,
                 datePrefixCls: datePrefixCls,
                 shortcuts: [],
-                date: new Date(),
+                date: initTimeDate(),
                 value: '',
                 minDate: '',
                 maxDate: '',
diff --git a/src/components/date-picker/panel/date.vue b/src/components/date-picker/panel/date.vue
index 6657b61..186cc25 100644
--- a/src/components/date-picker/panel/date.vue
+++ b/src/components/date-picker/panel/date.vue
@@ -59,9 +59,18 @@
                     :disabled-date="disabledDate"
                     @on-pick="handleMonthPick"
                     @on-pick-click="handlePickClick"></month-table>
+                <time-picker
+                    v-show="currentView === 'time'"
+                    v-ref:time-picker
+                    :date="date"
+                    :value="value"
+                    @on-pick="handleTimePick"></time-picker>
             </div>
             <Confirm
                 v-if="confirm"
+                :show-time="showTime"
+                :is-time="isTime"
+                @on-pick-toggle-time="handleToggleTime"
                 @on-pick-clear="handlePickClear"
                 @on-pick-success="handlePickSuccess"></Confirm>
         </div>
@@ -72,30 +81,34 @@
     import DateTable from '../base/date-table.vue';
     import YearTable from '../base/year-table.vue';
     import MonthTable from '../base/month-table.vue';
+    import TimePicker from './time.vue';
     import Confirm from '../base/confirm.vue';
 
     import Mixin from './mixin';
 
+    import { initTimeDate } from '../util';
+
     const prefixCls = 'ivu-picker-panel';
     const datePrefixCls = 'ivu-date-picker';
 
     export default {
         mixins: [Mixin],
-        components: { Icon, DateTable, YearTable, MonthTable, Confirm },
+        components: { Icon, DateTable, YearTable, MonthTable, TimePicker, Confirm },
         data () {
             return {
                 prefixCls: prefixCls,
                 datePrefixCls: datePrefixCls,
                 shortcuts: [],
                 currentView: 'date',
-                date: new Date(),
+                date: initTimeDate(),
                 value: '',
                 showTime: false,
                 selectionMode: 'day',
                 disabledDate: '',
                 year: null,
                 month: null,
-                confirm: false
+                confirm: false,
+                isTime: false
             };
         },
         computed: {
@@ -126,23 +139,29 @@
                     this.year = newVal.getFullYear();
                     this.month = newVal.getMonth();
                 }
+            },
+            currentView (val) {
+                if (val === 'time') this.$refs.timePicker.updateScroll();
             }
         },
         methods: {
             resetDate () {
                 this.date = new Date(this.date);
             },
-            handleClear() {
+            handleClear () {
                 this.date = new Date();
                 this.$emit('on-pick', '');
+                if (this.showTime) this.$refs.timePicker.handleClear();
             },
-            resetView() {
-                if (this.selectionMode === 'month') {
-                    this.currentView = 'month';
-                } else if (this.selectionMode === 'year') {
-                    this.currentView = 'year';
-                } else {
-                    this.currentView = 'date';
+            resetView (reset = false) {
+                if (this.currentView !== 'time' || reset) {
+                    if (this.selectionMode === 'month') {
+                        this.currentView = 'month';
+                    } else if (this.selectionMode === 'year') {
+                        this.currentView = 'year';
+                    } else {
+                        this.currentView = 'date';
+                    }
                 }
 
                 this.year = this.date.getFullYear();
@@ -186,6 +205,15 @@
             showMonthPicker () {
                 this.currentView = 'month';
             },
+            handleToggleTime () {
+                if (this.currentView === 'date') {
+                    this.currentView = 'time';
+                    this.isTime = true;
+                } else if (this.currentView === 'time') {
+                    this.currentView = 'date';
+                    this.isTime = false;
+                }
+            },
             handleYearPick(year, close = true) {
                 this.year = year;
                 if (!close) return;
@@ -216,15 +244,16 @@
             },
             handleDatePick (value) {
                 if (this.selectionMode === 'day') {
-                    if (!this.showTime) {
-                        this.$emit('on-pick', new Date(value.getTime()));
-                    }
+                    this.$emit('on-pick', new Date(value.getTime()));
                     this.date.setFullYear(value.getFullYear());
                     this.date.setMonth(value.getMonth());
                     this.date.setDate(value.getDate());
                 }
 
                 this.resetDate();
+            },
+            handleTimePick (date) {
+                this.handleDatePick(date);
             }
         },
         compiled () {
diff --git a/src/components/date-picker/panel/time.vue b/src/components/date-picker/panel/time.vue
index 53dad98..d35010c 100644
--- a/src/components/date-picker/panel/time.vue
+++ b/src/components/date-picker/panel/time.vue
@@ -3,6 +3,7 @@
         <div :class="[prefixCls + '-body']">
             <div :class="[prefixCls + '-content']">
                 <time-spinner
+                    v-ref:time-spinner
                     :show-seconds="showSeconds"
                     :hours="hours"
                     :minutes="minutes"
@@ -35,13 +36,21 @@
     export default {
         mixins: [Mixin],
         components: { TimeSpinner, Confirm },
+        props: {
+            date: {
+                default () {
+                    return initTimeDate()
+                }
+            },
+            value: {
+                default: ''
+            }
+        },
         data () {
             return {
                 prefixCls: prefixCls,
                 timePrefixCls: timePrefixCls,
                 format: 'HH:mm:ss',
-                date: initTimeDate(),
-                value: '',
                 hours: '',
                 minutes: '',
                 seconds: '',
@@ -92,6 +101,9 @@
                     this.seconds = this.date.getSeconds();
                 }
                 if (emit) this.$emit('on-pick', this.date, true);
+            },
+            updateScroll () {
+                this.$refs.timeSpinner.updateScroll();
             }
         }
     };
diff --git a/src/components/date-picker/picker.vue b/src/components/date-picker/picker.vue
index b72e402..be95418 100644
--- a/src/components/date-picker/picker.vue
+++ b/src/components/date-picker/picker.vue
@@ -362,7 +362,13 @@
             },
             showPicker () {
                 if (!this.picker) {
+                    const type = this.type;
+
                     this.picker = new Vue(this.panel).$mount(this.$els.picker);
+                    if (type === 'datetime' || type === 'datetimerange') {
+                        this.confirm = true;
+                        this.picker.showTime = true;
+                    }
                     this.picker.value = this.internalValue;
                     this.picker.confirm = this.confirm;
                     this.picker.selectionMode = this.selectionMode;
@@ -430,7 +436,7 @@
                     this.$refs.drop.update();
                     if (this.open === null) this.$emit('on-open-change', true);
                 } else {
-                    if (this.picker) this.picker.resetView && this.picker.resetView();
+                    if (this.picker) this.picker.resetView && this.picker.resetView(true);
                     this.$refs.drop.destroy();
                     if (this.open === null) this.$emit('on-open-change', false);
                 }
diff --git a/src/styles/components/date-picker.less b/src/styles/components/date-picker.less
index 48c4009..b1d7a77 100644
--- a/src/styles/components/date-picker.less
+++ b/src/styles/components/date-picker.less
@@ -244,5 +244,19 @@
         text-align: right;
         padding: 8px;
         clear: both;
+        & > span{
+            color: @link-color;
+            cursor: pointer;
+            user-select: none;
+            float: left;
+            padding: 2px 0;
+            transition: all @transition-time @ease-in-out;
+            &:hover{
+                color: @link-hover-color;
+            }
+            &:active{
+                color: @link-active-color;
+            }
+        }
     }
 }
\ No newline at end of file
diff --git a/test/routers/date.vue b/test/routers/date.vue
index 4caeebf..3578e55 100644
--- a/test/routers/date.vue
+++ b/test/routers/date.vue
@@ -24,7 +24,7 @@
                 <!--style="width: 168px"></time-picker>-->
         <!--</i-col>-->
         <i-col span="12">
-            <Time-picker type="timerange" confirm placeholder="选择时间" style="width: 168px"></Time-picker>
+            <Date-picker type="datetime" placeholder="选择日期时间" style="width: 200px" @on-change="c"></Date-picker>
             <!--<time-picker-->
                 <!--:value="value2"-->
                 <!--type="timerange"-->
--
libgit2 0.21.4