From 403162307651133bab15e392d5dfca3623f43e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=9D=99?= <sco@didichuxing.com> Date: Wed, 18 Apr 2018 20:07:35 +0800 Subject: [PATCH] a --- .../components/calendar/HmFullCalendar.vue | 434 +++++++++++++++--- src/views/haomo/components/calendar/index.vue | 89 +++- 2 files changed, 449 insertions(+), 74 deletions(-) diff --git a/src/views/haomo/components/calendar/HmFullCalendar.vue b/src/views/haomo/components/calendar/HmFullCalendar.vue index 804fccf..d47e4b4 100644 --- a/src/views/haomo/components/calendar/HmFullCalendar.vue +++ b/src/views/haomo/components/calendar/HmFullCalendar.vue @@ -1,89 +1,381 @@ <template> - <div class="showcalender"> - <div id='calendar'></div> - </div> + <div class="datebook-root" :style='componentW?"width:"+componentW+";":""'> + <div class='top-panel'> + <ul> + <li class='btn left-btn' @click='monthChange(-1)'></li> + <li class='show-wrap'>{{showTimeStr}}</li> + <li class='btn right-btn' @click='monthChange(1)'></li> + </ul> + </div> + <div class='item-wrap'> + <div class="week-day"> + <span>æ—¥</span> + <span>一</span> + <span>二</span> + <span>三</span> + <span>å››</span> + <span>五</span> + <span>å…</span> + </div> + <ul class="date-item-wrap"> + <li v-for='(day,index) in dateItems' :class="'date-item '+day.classStr" :key='"day_"+index' @click='dateChange(day)'> + <span class='item-content'>{{day.content}}</span> + </li> + + </ul> + </div> + </div> </template> +<style> + ul li{ + list-style: none; + } + .datebook-root{ + box-sizing:border-box; + width: 280px; + border:1px solid #ececec; + } + .datebook-root .top-panel{ + padding-top: 10px; + width: 100%; + } + .datebook-root .top-panel ul{ + overflow: hidden; + } + .datebook-root .top-panel li{ + float: left; + } + .datebook-root .top-panel li.btn{ + width: 20%; + height: 40px; + line-height: 40px; + cursor: pointer; + } + .datebook-root .top-panel li.btn:before{ + content: ''; + display: block; + width: 10px; + height: 10px; + border-style: solid; + border-width: 1px; + border-color: #999 #999 transparent transparent ; + margin:15px auto; + } + .datebook-root .top-panel li.left-btn:before{ + transform: rotate(-135deg); + } + .datebook-root .top-panel li.right-btn:before{ + transform: rotate(45deg); + } + .datebook-root .top-panel li.show-wrap{ + width: 60%; + height: 40px; + line-height: 40px; + color: #999 ; + font-size: 14px; + text-align: center; + } + .datebook-root .item-wrap{ + box-sizing:border-box; + width: 100%; + padding: 6px; + } + .datebook-root .week-day{ + width: 100%; + overflow: hidden; + } + .datebook-root .week-day span{ + display: block; + float: left; + width: 14.2857%; + height: 36px; + line-height: 36px; + text-align: center; + font-size: 14px; + color: #999; + } + .datebook-root .date-item-wrap{ + width: 100% ; + padding:10px 0; + overflow: hidden; + } + .datebook-root .date-item{ + box-sizing:border-box; + float: left; + width: 14.2857%; + height: 0; + padding-bottom: 14.2857%; + margin: 2px 0; + font-size: 14px; + text-align: center; + user-select:none; + position: relative; + cursor: pointer; + } + .datebook-root .date-item .item-content{ + box-sizing:border-box; + position: absolute; + width: 20px; + height: 20px; + line-height: 20px; + padding: 0; + border: none; + left: 50%; + top: 50%; + -webkit-transform:translate(-50%,-50%); + -moz-transform:translate(-50%,-50%); + -ms-transform:translate(-50%,-50%); + -o-transform:translate(-50%,-50%); + transform:translate(-50%,-50%); + } + + .datebook-root .date-item.empty{ + cursor: auto; + } + .datebook-root .date-item.today:before{ + content: ''; + display: block; + width: 12px; + height: 5px; + position: absolute; + bottom: 3px; + left: 50%; + margin-left: -6px; + background: #2db7f5; + border-radius: 50%; + opacity: .5 ; + } + .datebook-root .date-item.schedule:after{ + content: ''; + display: block; + box-sizing:border-box; + width: 100%; + height: 100%; + border:1px solid #2db7f5; + border-radius: 50%; + opacity: .5; + position: absolute; + left: 0; + top: 0; + cursor: pointer; + } + .datebook-root .date-item.schedule.active{ + color: #333; + } + .datebook-root .date-item.schedule.active:after{ + background: #2db7f5 ; + } +</style> <script> - import $ from 'jquery' - import 'fullcalendar' - export default { - name: 'calender', - // 继承其他组件 - extends: {}, - // 使用其它组件 - components: { - - }, - props: { - - }, + /** + /* 选项傿•°ï¼š + * width: 控制宽度,值为带å•ä½çš„å—符串,例如‘400px’,å¯ä¸ä¼ ,默认280px ï¼› + * schedules:行程安排数æ®ï¼ˆæ•°ç»„ï¼‰æ ¼å¼å¦‚下: + * [ + * { + * date:12212220000,//日期时间戳 + * title:'xxxxxx',//è¡Œç¨‹æ ‡é¢˜ + * //æ›´å¤šå…¶ä»–å—æ®µï¼Œéšæ„,事件å‘ç”Ÿæ—¶å°†å…¨éƒ¨å›žä¼ ã€‚ + * }, + * { + * date:12242220000,//日期时间戳 + * title:'xxxxxx',//è¡Œç¨‹æ ‡é¢˜ + * //æ›´å¤šå…¶ä»–å—æ®µï¼Œéšæ„。 + * } + * ] + * + *initTime:åˆå§‹åŒ–æ—¶é—´ï¼ˆæ—¶é—´æˆ³æ ¼å¼ï¼‰ï¼Œé¡µé¢è½½å…¥æ—¶å±•示该时间所在月份的日历,å¯ä¸ä¼ ,默认展示当å‰ç³»ç»Ÿæ—¶é—´ + *dateChange事件:用户点击一个带有日程安排的日期时触å‘(é‡å¤ç‚¹å‡»åŒä¸€æ—¥æœŸä»…触å‘一次),将返回该日程数æ®ï¼› + *monthChangeäº‹ä»¶ï¼Œåˆ‡æ¢æœˆä»½æ—¶è§¦å‘ï¼Œåˆ·æ–°æ—¥åŽ†æ˜¾ç¤ºï¼Œå¹¶ä¼ å›žå½“å‰æœˆä»½çš„æ•°ç»„,包å«è¯¥æœˆç¬¬ä¸€å¤©çš„0:0:0 å’Œ 该月最åŽä¸€å¤©çš„23:59:59 的时间戳,例如,7月,返回 [1498838400000,1501516799000] ,对应:Sat Jul 01 2017 00:00:00 GMT+0800 (ä¸å›½æ ‡å‡†æ—¶é—´) å’Œ Mon Jul 31 2017 23:59:59 GMT+0800 (ä¸å›½æ ‡å‡†æ—¶é—´) + */ + export default{ data() { return { + componentW: '', // 组件宽度 + showTimeData: '', // 展示时间,æ—¶é—´æˆ³æ ¼å¼ + dateItems: '' // 当剿œˆä»½æ‰€æœ‰æ—¥æœŸçš„æ•°æ® } }, + props: ['width', 'schedules', 'initTime', 'showActive'], computed: { + showTimeStr() { + var result = '' + if (this.showTimeData) { + var dateObj = new Date(this.showTimeData) + var year = dateObj.getFullYear() + var month = dateObj.getMonth() + 1 + var monthStr = month > 9 ? month : '0' + month + result = year + '-' + monthStr + } + return result + } }, - filters: { + watch: { // 监控showTimeDateå’Œschedules ; å…¶ä¸ä»»ä½•一个改å˜ï¼Œéƒ½è¦æ‰§è¡Œåˆ·æ–°æ—¥åކ颿¿çš„æ“ä½œã€‚ + showTimeData: {// 负责刷新当å‰å±•ç¤ºçš„æœˆä»½æ•°æ® + handler() { + if (this.showTimeData) { + var dateObj = new Date(this.showTimeData) + this.madePanel(dateObj) + } + }, + deep: true + }, + schedules: { // è´Ÿè´£åˆ·æ–°å½“å‰æœˆä»½çš„æ—¥ç¨‹å®‰æŽ’ + handler() { + if (this.schedules) { + var dateObj = new Date(this.showTimeData) + this.madePanel(dateObj) + } + }, + deep: true + } }, - created() { - $(function() { - $('#calendar').fullCalendar({ - customButtons: { - myCustomButton: { - text: '自定义按钮', - click: function() { - alert('点击了自定义按钮!') + methods: { + initData() { + this.componentW = this.width || '' + this.showTimeData = this.initTime || new Date().getTime() + }, + madePanel(dateObj) { + // console.log('madePanel执行了') + if (!dateObj) { + return + } + // 今天的年月日 + var now = new Date() + var nowYear = now.getFullYear() + var nowMonth = now.getMonth() + var nowDay = now.getDate() + // ä¼ å…¥çš„dateObj的年月日 + var year = dateObj.getFullYear() + var month = dateObj.getMonth() + // var day = dateObj.getDate() + // 本月拥有的总天数 + var totalDays = new Date(year, month + 1, 0).getDate() + // æœ¬æœˆç¬¬ä¸€å¤©æ˜¯æ˜ŸæœŸå‡ ï¼š + var firstDay = new Date(year, month, 1).getDay() + // å¾ªçŽ¯ç”Ÿæˆæœ¬æœˆçš„æ—¥æœŸæ•°æ®ï¼Œå›ºå®šç”Ÿæˆ42个,å³6个星期的; + var arr = [] + for (var i = 0; i < 42; i++) { + if (i < firstDay) { // 在第一天之å‰ï¼Œä¸ºç©ºspanå ä½ + var dayObj = { + content: null, + schedule: null, + active: false, + today: false, + classStr: 'empty' + } + arr.push(dayObj) + } else if (i >= firstDay && i < (totalDays + firstDay)) { + if (year === nowYear && month === nowMonth && (i - firstDay + 1) === nowDay) { // 年月日和now相åŒï¼Œå³ä¸ºâ€˜ä»Šå¤©â€™ + dayObj = { + content: i - firstDay + 1, + schedule: null, + active: false, + today: true, + classStr: 'today' + } + } else { + dayObj = { + content: i - firstDay + 1, + schedule: null, + active: false, + today: false, + classStr: '' } } - }, - header: { - left: 'title', - center: '', - right: 'today prev,next myCustomButton' - }, - currentTimezone: 'Asia/Beijing', - weekNumbersWithinDays: true, - handleWindowResize: true, - eventLimit: true, - views: { - agenda: { - eventLimit: 3 + // æ·»åŠ schedulesæ•°æ® + if (this.schedules && this.schedules.length > 0) { + for (var j = 0; j < this.schedules.length; j++) { + var schedule = this.schedules[j] + var scheduleDate = new Date(schedule.date) + var scheduleYear = scheduleDate.getFullYear() + var scheduleMonth = scheduleDate.getMonth() + var scheduleDay = scheduleDate.getDate() + if (year === scheduleYear && month === scheduleMonth && (i - firstDay + 1) === scheduleDay) { + dayObj.schedule = schedule + dayObj.classStr += ' schedule' + } + } } - }, - weekNumberCalculation: 'ISO', - dayClick: function() { - alert('a day has been clicked!') - }, - events: [ - { - title: 'event1', - start: '2018-04-17' - }, - { - title: 'event2', - start: '2018-04-17', - end: '2018-04-18' - }, - { - title: 'event3', - start: '', - allDay: false // will make the time show + arr.push(dayObj) + } else { // 余下的还是空spanå ä½ + const dayObj = { + content: null, + schedule: null, + active: false, + today: false, + classStr: 'empty' } - ] - }) - }) + arr.push(dayObj) + } + } + this.dateItems = arr + }, + dateChange(dateItem) { + // console.log(dateItem) + var dateObj = new Date(this.showTimeData) + var year = dateObj.getFullYear() + var month = dateObj.getMonth() + var day = parseInt(dateItem.content) + var begin = new Date(year, month, day, 0, 0, 0).getTime() + var end = new Date(year, month, day, 23, 59, 59).getTime() + var result = { + date: [begin, end], + schedule: dateItem.schedule + } + if (!dateItem.schedule) { // 点击没有行程的,ä¸ä½œå应 + this.$emit('dateChange', result) + return + } else { + if (!dateItem.active) { // 未激活行程æç¤ºçš„ï¼Œåˆ™æ¿€æ´»è¯¥è¡Œç¨‹ï¼Œå…¶ä»–è¡Œç¨‹ä¸æ¿€æ´» + if (this.showActive) { + // 循环清除所有的activeçŠ¶æ€ + for (var i = 0; i < this.dateItems.length; i++) { + if (this.dateItems[i].active) { + this.dateItems[i].active = false + this.dateItems[i].classStr = this.dateItems[i].classStr.replace('active', '').replace(/^\s+|\s+$/g, '') + } else { + continue + } + } + // 当å‰è¡Œç¨‹æ·»åŠ activeçŠ¶æ€ + dateItem.active = !dateItem.active + dateItem.classStr += ' active' + } else { + // ä¸éœ€è¦å±•示active类(active状æ€è¿˜æ˜¯è¦åŠ çš„ï¼Œæ•°æ®ä¸ŠåŒºåˆ†è¢«æ¿€æ´»å’Œæœªè¢«æ¿€æ´»ï¼Œæ¿€æ´»çš„冿¬¡ç‚¹å‡»æ˜¯æ— 效的) + for (i = 0; i < this.dateItems.length; i++) { + if (this.dateItems[i].active) { + this.dateItems[i].active = false + } else { + continue + } + } + // 当å‰è¡Œç¨‹æ·»åŠ activeçŠ¶æ€ + dateItem.active = !dateItem.active + } + // å‘上å‘逿œ¬æ¬¡ç‚¹å‡»çš„è¡Œç¨‹æ•°æ® + this.$emit('dateChange', result) + } else { // 已激活行程æç¤ºçš„,ä¸ä½œå应 + return + } + } + }, + monthChange(step) { + var curDate = new Date(this.showTimeData) + var newDate = curDate.setMonth(curDate.getMonth() + step) + this.showTimeData = newDate + // è®¡ç®—å¼€å§‹æ—¶é—´å’Œç»“æŸæ—¶é—´ + var dateObj = new Date(newDate) + var year = dateObj.getFullYear() + var month = dateObj.getMonth() + var totalDays = new Date(year, month + 1, 0).getDate() // 该月份共有多少天。 + var begin = new Date(year, month, 1, 0, 0, 0) + var end = new Date(year, month, totalDays, 23, 59, 59) + this.$emit('monthChange', [begin.getTime(), end.getTime()]) + } }, - methods: { - + mounted() { + this.initData() } } </script> -<style scoped> - -</style> -<style> - .fc-button-group, .fc button { - display: block !important; - } -</style> - diff --git a/src/views/haomo/components/calendar/index.vue b/src/views/haomo/components/calendar/index.vue index 925a5c2..0701e5e 100644 --- a/src/views/haomo/components/calendar/index.vue +++ b/src/views/haomo/components/calendar/index.vue @@ -1,6 +1,16 @@ <template> <div class="app-container calendar-list-container"> - <hm-full-calendar></hm-full-calendar> + <hm-full-calendar + :width="width" + :schedules="schedules" + @dateChange="datechange" + @monthChange="monthchange" + ></hm-full-calendar> + <div v-if="show" class="incident"> + <p>{{currentDate}}</p> + <span>{{event}}</span> + <span class="close" @click="closeEvent">X</span> + </div> </div> </template> @@ -15,7 +25,13 @@ 'hm-full-calendar': HmFullCalendar }, data() { - return {} + return { + show: false, + width: '300px', + currentDate: '', + event: '', + schedules: [{ date: 1524043625000, title: '个梵蒂是的舞蹈æœå¯æŽ¥å—的看似简å•è®¡ç®—çš„è¯æŸå¸¦ç»“å‘会计师对海å£å¸‚è®°å¾—å›žå¤æ˜¯æ¡†æž¶çš„看就好山东矿机会计师å‘é€çš„甲方是看得è§çœ‹è§çš„说法开始冈地方' }, { date: 1523955299000, title: '个梵蒂冈地方' }] + } }, filters: { @@ -23,7 +39,74 @@ created() { }, - methods: {} + methods: { + datechange(data) { + this.show = true + console.log(data) + if (data.schedule) { + const currentTime = this.timestampToTime(data.schedule.date) + console.log(currentTime) + this.currentDate = currentTime + this.event = data.schedule.title + } + }, + closeEvent() { + this.show = false + }, + monthchange(data) { + console.log(data, '--------') + }, + timestampToTime(timestamp) { + var date = new Date(timestamp) // 时间戳为10ä½éœ€*1000,时间戳为13ä½çš„è¯ä¸éœ€ä¹˜1000 + const Y = date.getFullYear() + 'å¹´' + const M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '月' + const D = date.getDate() + 'æ—¥' + return Y + M + D + } + } } </script> +<style> + .calendar-list-container .incident{ + top: -350px; + left:270px; + display:inline-block; + position:relative; + background-color:#202020; + width:180px; + padding:20px; + color:#CCC; + text-align:center; + font-size:14px; + font-family:微软雅黑; + border-radius:10px; + margin:50px; + box-shadow:1px 1px 2px #202020; + -o-box-shadow:1px 1px 2px #202020; + -moz-box-shadow:1px 1px 2px #202020; + -webkit-border-shadow:1px 1px 2px #202020; + } + .close{ + position: absolute; + top:0; + cursor: pointer; + right:0; + } + .incident span { + font-size: 10px; + padding: 10px 20px; + } + .incident:before{ + content:''; + position:absolute; + width:0; + height:0; + border:15px solid; + color:transparent; + border-right-color:#202020; + left:-30px; + top:50%; + margin-top:-15px; + } +</style> -- 2.21.0