Compare View
Commits (5)
-
结构调整
-
打卡模板创建
-
打卡功能简单版
Showing
92 changed files
Show diff stats
app.js
| @@ -44,9 +44,10 @@ App({ | @@ -44,9 +44,10 @@ App({ | ||
| 44 | view.onShareAppMessage = function () { | 44 | view.onShareAppMessage = function () { |
| 45 | //你的分享配置 | 45 | //你的分享配置 |
| 46 | return { | 46 | return { |
| 47 | - title: name + '推荐大家都在用的升学大数据宝典', | 47 | + title: name + '推荐您 一起开始自主学习之旅', |
| 48 | path: '/pages/index/index', | 48 | path: '/pages/index/index', |
| 49 | - imageUrl: 'https://proxy.shunzhi.net:51315/mp_share2.jpg', | 49 | + // imageUrl: 'https://proxy.shunzhi.net:51315/mp_share2.jpg', |
| 50 | + imageUrl: 'https://szyundisk.oss-cn-hangzhou.aliyuncs.com/AdmissionsManageSys/37317060-9e67-41e1-9731-b722c83cff8a.jpg', | ||
| 50 | }; | 51 | }; |
| 51 | } | 52 | } |
| 52 | } | 53 | } |
app.json
| 1 | { | 1 | { |
| 2 | "pages": [ | 2 | "pages": [ |
| 3 | - "pages/index/index", | ||
| 4 | - "pages/index/rank/rank", | 3 | + "pages/login/loginNew/loginNew", |
| 4 | + "pages/login/codeLogin/codeLogin", | ||
| 5 | "pages/index/achievement/achievement", | 5 | "pages/index/achievement/achievement", |
| 6 | - "pages/index/punchDetail/punchDetail", | 6 | + "pages/index/rank/rank", |
| 7 | + "pages/index/index", | ||
| 7 | "pages/index/newPunch/newPunch", | 8 | "pages/index/newPunch/newPunch", |
| 8 | - "pages/login/codeLogin/codeLogin", | 9 | + "pages/mine/record/record", |
| 10 | + "pages/mine/index", | ||
| 11 | + "pages/index/punchDetail/punchDetail", | ||
| 9 | "pages/login/protocol/protocol", | 12 | "pages/login/protocol/protocol", |
| 10 | "pages/login/policy/policy", | 13 | "pages/login/policy/policy", |
| 11 | - "pages/mine/index", | ||
| 12 | - "pages/mine/record/record", | ||
| 13 | "pages/webview/webview" | 14 | "pages/webview/webview" |
| 14 | ], | 15 | ], |
| 15 | "window": { | 16 | "window": { |
| 16 | "backgroundTextStyle": "dark", | 17 | "backgroundTextStyle": "dark", |
| 17 | "navigationBarBackgroundColor": "#fff", | 18 | "navigationBarBackgroundColor": "#fff", |
| 18 | - "navigationBarTitleText": "计划管家", | 19 | + "navigationBarTitleText": "打卡管理", |
| 19 | "navigationBarTextStyle": "black" | 20 | "navigationBarTextStyle": "black" |
| 20 | }, | 21 | }, |
| 21 | "tabBar": { | 22 | "tabBar": { |
| @@ -24,7 +25,7 @@ | @@ -24,7 +25,7 @@ | ||
| 24 | "borderStyle": "white", | 25 | "borderStyle": "white", |
| 25 | "list": [ | 26 | "list": [ |
| 26 | { | 27 | { |
| 27 | - "pagePath": "pages/index/index", | 28 | + "pagePath": "pages/index/rank/rank", |
| 28 | "text": "首页", | 29 | "text": "首页", |
| 29 | "iconPath": "./img/tab_home_normat.png", | 30 | "iconPath": "./img/tab_home_normat.png", |
| 30 | "selectedIconPath": "./img/tab_home_selected.png" | 31 | "selectedIconPath": "./img/tab_home_selected.png" |
app.wxss
| 1 | -/* @import "/miniprogram_npm/@vant/weapp/common/index.wxss"; */ | ||
| 2 | -page{ | 1 | +@import "/miniprogram_npm/@vant/weapp/common/index.wxss"; |
| 2 | +/* page{ | ||
| 3 | background: #fff; | 3 | background: #fff; |
| 4 | -} | 4 | +} */ |
| 5 | /* 二级页面顶部统一返回按钮,位置可能需要根据机型调整 */ | 5 | /* 二级页面顶部统一返回按钮,位置可能需要根据机型调整 */ |
| 6 | .navigation_back{ | 6 | .navigation_back{ |
| 7 | width: 80rpx; | 7 | width: 80rpx; |
| @@ -0,0 +1,144 @@ | @@ -0,0 +1,144 @@ | ||
| 1 | +import { dateUtil, getCalendarConfig } from './utils/index' | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * 计算当前月份前后两月应占的格子 | ||
| 5 | + * @param {number} year 年份 | ||
| 6 | + * @param {number} month 月份 | ||
| 7 | + */ | ||
| 8 | +function calculateEmptyGrids(year, month, config) { | ||
| 9 | + const prevMonthGrids = calculatePrevMonthGrids(year, month, config) | ||
| 10 | + const nextMonthGrids = calculateNextMonthGrids(year, month, config) | ||
| 11 | + return { | ||
| 12 | + prevMonthGrids, | ||
| 13 | + nextMonthGrids | ||
| 14 | + } | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * 计算上月应占的格子 | ||
| 19 | + * @param {number} year 年份 | ||
| 20 | + * @param {number} month 月份 | ||
| 21 | + */ | ||
| 22 | +function calculatePrevMonthGrids(year, month, config) { | ||
| 23 | + let emptyGrids = [] | ||
| 24 | + const prevMonthDays = dateUtil.getDatesCountOfMonth(year, month - 1) | ||
| 25 | + let firstDayOfWeek = dateUtil.firstDayOfWeek(year, month) | ||
| 26 | + if (config.firstDayOfWeek === 'Mon') { | ||
| 27 | + if (firstDayOfWeek === 0) { | ||
| 28 | + firstDayOfWeek = 6 | ||
| 29 | + } else { | ||
| 30 | + firstDayOfWeek -= 1 | ||
| 31 | + } | ||
| 32 | + } | ||
| 33 | + if (firstDayOfWeek > 0) { | ||
| 34 | + const len = prevMonthDays - firstDayOfWeek | ||
| 35 | + const { onlyShowCurrentMonth } = config | ||
| 36 | + const YMInfo = dateUtil.getPrevMonthInfo({ year, month }) | ||
| 37 | + for (let i = prevMonthDays; i > len; i--) { | ||
| 38 | + if (onlyShowCurrentMonth) { | ||
| 39 | + emptyGrids.push('') | ||
| 40 | + } else { | ||
| 41 | + const week = dateUtil.getDayOfWeek(+year, +month, i) | ||
| 42 | + emptyGrids.push({ | ||
| 43 | + ...YMInfo, | ||
| 44 | + date: i, | ||
| 45 | + week | ||
| 46 | + }) | ||
| 47 | + } | ||
| 48 | + } | ||
| 49 | + emptyGrids.reverse() | ||
| 50 | + } | ||
| 51 | + return emptyGrids | ||
| 52 | +} | ||
| 53 | +/** | ||
| 54 | + * 计算下一月日期是否需要多展示的日期 | ||
| 55 | + * 某些月份日期为5排,某些月份6排,统一为6排 | ||
| 56 | + * @param {number} year | ||
| 57 | + * @param {number} month | ||
| 58 | + * @param {object} config | ||
| 59 | + */ | ||
| 60 | +function calculateExtraEmptyDate(year, month, config) { | ||
| 61 | + let extDate = 0 | ||
| 62 | + if (+month === 2) { | ||
| 63 | + extDate += 7 | ||
| 64 | + let firstDayofMonth = dateUtil.getDayOfWeek(year, month, 1) | ||
| 65 | + if (config.firstDayOfWeek === 'Mon') { | ||
| 66 | + if (+firstDayofMonth === 1) extDate += 7 | ||
| 67 | + } else { | ||
| 68 | + if (+firstDayofMonth === 0) extDate += 7 | ||
| 69 | + } | ||
| 70 | + } else { | ||
| 71 | + let firstDayofMonth = dateUtil.getDayOfWeek(year, month, 1) | ||
| 72 | + if (config.firstDayOfWeek === 'Mon') { | ||
| 73 | + if (firstDayofMonth !== 0 && firstDayofMonth < 6) { | ||
| 74 | + extDate += 7 | ||
| 75 | + } | ||
| 76 | + } else { | ||
| 77 | + if (firstDayofMonth <= 5) { | ||
| 78 | + extDate += 7 | ||
| 79 | + } | ||
| 80 | + } | ||
| 81 | + } | ||
| 82 | + return extDate | ||
| 83 | +} | ||
| 84 | +/** | ||
| 85 | + * 计算下月应占的格子 | ||
| 86 | + * @param {number} year 年份 | ||
| 87 | + * @param {number} month 月份 | ||
| 88 | + */ | ||
| 89 | +function calculateNextMonthGrids(year, month, config) { | ||
| 90 | + let emptyGrids = [] | ||
| 91 | + const datesCount = dateUtil.getDatesCountOfMonth(year, month) | ||
| 92 | + let lastDayWeek = dateUtil.getDayOfWeek(year, month, datesCount) | ||
| 93 | + if (config.firstDayOfWeek === 'Mon') { | ||
| 94 | + if (lastDayWeek === 0) { | ||
| 95 | + lastDayWeek = 6 | ||
| 96 | + } else { | ||
| 97 | + lastDayWeek -= 1 | ||
| 98 | + } | ||
| 99 | + } | ||
| 100 | + let len = 7 - (lastDayWeek + 1) | ||
| 101 | + const { onlyShowCurrentMonth } = config | ||
| 102 | + if (!onlyShowCurrentMonth) { | ||
| 103 | + len = len + calculateExtraEmptyDate(year, month, config) | ||
| 104 | + } | ||
| 105 | + const YMInfo = dateUtil.getNextMonthInfo({ year, month }) | ||
| 106 | + for (let i = 1; i <= len; i++) { | ||
| 107 | + const week = dateUtil.getDayOfWeek(+year, +month, i) | ||
| 108 | + if (onlyShowCurrentMonth) { | ||
| 109 | + emptyGrids.push('') | ||
| 110 | + } else { | ||
| 111 | + emptyGrids.push({ | ||
| 112 | + id: i - 1, | ||
| 113 | + ...YMInfo, | ||
| 114 | + date: i, | ||
| 115 | + week: week || 7 | ||
| 116 | + }) | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | + return emptyGrids | ||
| 120 | +} | ||
| 121 | +/** | ||
| 122 | + * 设置日历面板数据 | ||
| 123 | + * @param {number} year 年份 | ||
| 124 | + * @param {number} month 月份 | ||
| 125 | + * @param {number} curDate 日期 | ||
| 126 | + */ | ||
| 127 | +function calculateCurrentMonthDates(year, month) { | ||
| 128 | + return dateUtil.calcDates(year, month) | ||
| 129 | +} | ||
| 130 | + | ||
| 131 | +export function calcJumpData({ dateInfo, config, component }) { | ||
| 132 | + dateInfo = dateInfo || dateUtil.todayFMD() | ||
| 133 | + const { year, month, date } = dateInfo | ||
| 134 | + const calendarConfig = config || getCalendarConfig(component) | ||
| 135 | + const emptyGrids = calculateEmptyGrids(year, month, calendarConfig) | ||
| 136 | + const calendar = { | ||
| 137 | + curYear: year, | ||
| 138 | + curMonth: month, | ||
| 139 | + curDate: date, | ||
| 140 | + dates: calculateCurrentMonthDates(year, month), | ||
| 141 | + ...emptyGrids | ||
| 142 | + } | ||
| 143 | + return calendar | ||
| 144 | +} |
| @@ -0,0 +1,12 @@ | @@ -0,0 +1,12 @@ | ||
| 1 | +import { dateUtil } from './utils/index' | ||
| 2 | + | ||
| 3 | +export function calcTargetYMInfo() { | ||
| 4 | + return { | ||
| 5 | + right: dateUtil.getPrevMonthInfo, | ||
| 6 | + left: dateUtil.getNextMonthInfo, | ||
| 7 | + prev_month: dateUtil.getPrevMonthInfo, | ||
| 8 | + next_month: dateUtil.getNextMonthInfo, | ||
| 9 | + prev_year: dateUtil.getPrevYearInfo, | ||
| 10 | + next_year: dateUtil.getNextYearInfo | ||
| 11 | + } | ||
| 12 | +} |
| @@ -0,0 +1,257 @@ | @@ -0,0 +1,257 @@ | ||
| 1 | +import plugins from './plugins/index' | ||
| 2 | +import { calcJumpData } from './core' | ||
| 3 | +import { renderCalendar } from './render' | ||
| 4 | +import { calcTargetYMInfo } from './helper' | ||
| 5 | +import { dateUtil, calendarGesture, logger } from './utils/index' | ||
| 6 | + | ||
| 7 | +Component({ | ||
| 8 | + options: { | ||
| 9 | + styleIsolation: 'apply-shared', | ||
| 10 | + multipleSlots: true // 在组件定义时的选项中启用多slot支持 | ||
| 11 | + }, | ||
| 12 | + properties: { | ||
| 13 | + config: { | ||
| 14 | + type: Object, | ||
| 15 | + value: {} | ||
| 16 | + } | ||
| 17 | + }, | ||
| 18 | + lifetimes: { | ||
| 19 | + attached: function() { | ||
| 20 | + this.initComp() | ||
| 21 | + } | ||
| 22 | + }, | ||
| 23 | + methods: { | ||
| 24 | + initComp() { | ||
| 25 | + const calendarConfig = this.setDefaultDisableDate() | ||
| 26 | + this.setConfig(calendarConfig) | ||
| 27 | + }, | ||
| 28 | + // 禁用某天日期配置默认为今天 | ||
| 29 | + setDefaultDisableDate() { | ||
| 30 | + const calendarConfig = this.properties.config || {} | ||
| 31 | + if (calendarConfig.disableMode && !calendarConfig.disableMode.date) { | ||
| 32 | + calendarConfig.disableMode.date = dateUtil.toTimeStr( | ||
| 33 | + dateUtil.todayFMD() | ||
| 34 | + ) | ||
| 35 | + } | ||
| 36 | + return calendarConfig | ||
| 37 | + }, | ||
| 38 | + initCalendar(config) { | ||
| 39 | + const { defaultDate } = config | ||
| 40 | + let date = dateUtil.todayFMD() | ||
| 41 | + if (defaultDate && typeof defaultDate === 'string') { | ||
| 42 | + const dateInfo = defaultDate.split('-') | ||
| 43 | + if (dateInfo.length < 3) { | ||
| 44 | + return logger.warn('defaultDate配置格式应为: 2018-4-2 或 2018-04-02') | ||
| 45 | + } else { | ||
| 46 | + date = { | ||
| 47 | + year: +dateInfo[0], | ||
| 48 | + month: +dateInfo[1], | ||
| 49 | + date: +dateInfo[2] | ||
| 50 | + } | ||
| 51 | + } | ||
| 52 | + } | ||
| 53 | + const waitRenderData = calcJumpData({ | ||
| 54 | + dateInfo: date, | ||
| 55 | + config | ||
| 56 | + }) | ||
| 57 | + const timestamp = dateUtil.todayTimestamp() | ||
| 58 | + if (config.autoChoosedWhenJump) { | ||
| 59 | + const target = waitRenderData.dates.filter( | ||
| 60 | + item => dateUtil.toTimeStr(item) === dateUtil.toTimeStr(date) | ||
| 61 | + ) | ||
| 62 | + if (target && target.length) { | ||
| 63 | + if (!waitRenderData.selectedDates) { | ||
| 64 | + waitRenderData.selectedDates = target | ||
| 65 | + } else { | ||
| 66 | + waitRenderData.selectedDates.push(target[0]) | ||
| 67 | + } | ||
| 68 | + } | ||
| 69 | + } | ||
| 70 | + return { | ||
| 71 | + ...waitRenderData, | ||
| 72 | + todayTimestamp: timestamp, | ||
| 73 | + weeksCh: dateUtil.getWeekHeader(config.firstDayOfWeek) | ||
| 74 | + } | ||
| 75 | + }, | ||
| 76 | + setConfig(config) { | ||
| 77 | + if (config.markToday && typeof config.markToday === 'string') { | ||
| 78 | + config.highlightToday = true | ||
| 79 | + } | ||
| 80 | + config.theme = config.theme || 'default' | ||
| 81 | + this.setData( | ||
| 82 | + { | ||
| 83 | + config | ||
| 84 | + }, | ||
| 85 | + () => { | ||
| 86 | + for (let plugin of plugins.installed) { | ||
| 87 | + const [, p] = plugin | ||
| 88 | + if (typeof p.install === 'function') { | ||
| 89 | + p.install(this) | ||
| 90 | + } | ||
| 91 | + if (typeof p.methods === 'function') { | ||
| 92 | + const methods = p.methods(this) | ||
| 93 | + for (let fnName in methods) { | ||
| 94 | + if (fnName.startsWith('__')) continue | ||
| 95 | + const fn = methods[fnName] | ||
| 96 | + if (typeof fn === 'function') { | ||
| 97 | + if (!this.calendar) this.calendar = {} | ||
| 98 | + this.calendar[fnName] = fn | ||
| 99 | + } | ||
| 100 | + } | ||
| 101 | + } | ||
| 102 | + } | ||
| 103 | + const initData = this.initCalendar(config) | ||
| 104 | + renderCalendar.call(this, initData, config) | ||
| 105 | + } | ||
| 106 | + ) | ||
| 107 | + }, | ||
| 108 | + tapDate(e) { | ||
| 109 | + const { info } = e.currentTarget.dataset | ||
| 110 | + const { date, disable } = info || {} | ||
| 111 | + if (disable || !date) return | ||
| 112 | + const { calendar, config } = this.data | ||
| 113 | + let calendarData = calendar | ||
| 114 | + let calendarConfig = config | ||
| 115 | + if (config.takeoverTap) { | ||
| 116 | + return this.triggerEvent('takeoverTap', info) | ||
| 117 | + } | ||
| 118 | + for (let plugin of plugins.installed) { | ||
| 119 | + const [, p] = plugin | ||
| 120 | + if (typeof p.onTapDate === 'function') { | ||
| 121 | + const { | ||
| 122 | + calendarData: __calendarData, | ||
| 123 | + calendarConfig: __calendarConfig | ||
| 124 | + } = p.onTapDate(info, calendarData, calendarConfig) | ||
| 125 | + calendarData = __calendarData | ||
| 126 | + calendarConfig = __calendarConfig | ||
| 127 | + } | ||
| 128 | + } | ||
| 129 | + renderCalendar.call(this, calendarData, calendarConfig).then(() => { | ||
| 130 | + this.triggerEvent('afterTapDate', info) | ||
| 131 | + }) | ||
| 132 | + }, | ||
| 133 | + /** | ||
| 134 | + * 日历滑动开始 | ||
| 135 | + * @param {object} e | ||
| 136 | + */ | ||
| 137 | + calendarTouchstart(e) { | ||
| 138 | + const t = e.touches[0] | ||
| 139 | + const startX = t.clientX | ||
| 140 | + const startY = t.clientY | ||
| 141 | + this.swipeLock = true | ||
| 142 | + this.setData({ | ||
| 143 | + 'gesture.startX': startX, | ||
| 144 | + 'gesture.startY': startY | ||
| 145 | + }) | ||
| 146 | + }, | ||
| 147 | + /** | ||
| 148 | + * 日历滑动中 | ||
| 149 | + * @param {object} e | ||
| 150 | + */ | ||
| 151 | + calendarTouchmove(e) { | ||
| 152 | + const { gesture } = this.data | ||
| 153 | + const { preventSwipe } = this.properties.config | ||
| 154 | + if (!this.swipeLock || preventSwipe) return | ||
| 155 | + if (calendarGesture.isLeft(gesture, e.touches[0])) { | ||
| 156 | + this.handleSwipe('left') | ||
| 157 | + this.swipeLock = false | ||
| 158 | + } | ||
| 159 | + if (calendarGesture.isRight(gesture, e.touches[0])) { | ||
| 160 | + this.handleSwipe('right') | ||
| 161 | + this.swipeLock = false | ||
| 162 | + } | ||
| 163 | + }, | ||
| 164 | + calendarTouchend(e) { | ||
| 165 | + this.setData({ | ||
| 166 | + 'calendar.leftSwipe': 0, | ||
| 167 | + 'calendar.rightSwipe': 0 | ||
| 168 | + }) | ||
| 169 | + }, | ||
| 170 | + handleSwipe(direction) { | ||
| 171 | + let swipeKey = 'calendar.leftSwipe' | ||
| 172 | + if (direction === 'right') { | ||
| 173 | + swipeKey = 'calendar.rightSwipe' | ||
| 174 | + } | ||
| 175 | + this.setData({ | ||
| 176 | + [swipeKey]: 1 | ||
| 177 | + }) | ||
| 178 | + const { calendar } = this.data | ||
| 179 | + let calendarData = calendar | ||
| 180 | + const { curYear, curMonth } = calendarData | ||
| 181 | + const getMonthInfo = calcTargetYMInfo()[direction] | ||
| 182 | + const target = getMonthInfo({ | ||
| 183 | + year: +curYear, | ||
| 184 | + month: +curMonth | ||
| 185 | + }) | ||
| 186 | + target.direction = direction | ||
| 187 | + this.renderCalendar(target) | ||
| 188 | + }, | ||
| 189 | + changeDate(e) { | ||
| 190 | + const { type } = e.currentTarget.dataset | ||
| 191 | + const { calendar: calendarData } = this.data | ||
| 192 | + const { curYear, curMonth } = calendarData | ||
| 193 | + const getMonthInfo = calcTargetYMInfo()[type] | ||
| 194 | + const target = getMonthInfo({ | ||
| 195 | + year: +curYear, | ||
| 196 | + month: +curMonth | ||
| 197 | + }) | ||
| 198 | + target.direction = type | ||
| 199 | + this.renderCalendar(target) | ||
| 200 | + }, | ||
| 201 | + renderCalendar(target) { | ||
| 202 | + let { calendar: calendarData, config } = this.data | ||
| 203 | + const { curYear, curMonth } = calendarData || {} | ||
| 204 | + for (let plugin of plugins.installed) { | ||
| 205 | + const [, p] = plugin | ||
| 206 | + if (typeof p.onSwitchCalendar === 'function') { | ||
| 207 | + calendarData = p.onSwitchCalendar(target, calendarData, this) | ||
| 208 | + } | ||
| 209 | + } | ||
| 210 | + return renderCalendar.call(this, calendarData, config).then(() => { | ||
| 211 | + let triggerEventName = 'whenChangeMonth' | ||
| 212 | + if (config.weekMode) { | ||
| 213 | + triggerEventName = 'whenChangeWeek' | ||
| 214 | + } | ||
| 215 | + this.triggerEvent(triggerEventName, { | ||
| 216 | + current: { | ||
| 217 | + year: +curYear, | ||
| 218 | + month: +curMonth | ||
| 219 | + }, | ||
| 220 | + next: target | ||
| 221 | + }) | ||
| 222 | + this.triggerEvent('onSwipe', { | ||
| 223 | + current: { | ||
| 224 | + year: +curYear, | ||
| 225 | + month: +curMonth | ||
| 226 | + }, | ||
| 227 | + next: target, | ||
| 228 | + type: triggerEventName | ||
| 229 | + }) | ||
| 230 | + }) | ||
| 231 | + }, | ||
| 232 | + doubleClickJumpToToday() { | ||
| 233 | + const { multi, weekMode } = this.calendar.getCalendarConfig() || {} | ||
| 234 | + if (multi || weekMode) return | ||
| 235 | + if (this.count === undefined) { | ||
| 236 | + this.count = 1 | ||
| 237 | + } else { | ||
| 238 | + this.count += 1 | ||
| 239 | + } | ||
| 240 | + if (this.lastClick) { | ||
| 241 | + const difference = new Date().getTime() - this.lastClick | ||
| 242 | + if ( | ||
| 243 | + difference < 500 && | ||
| 244 | + this.count >= 2 && | ||
| 245 | + typeof this.calendar.jump === 'function' | ||
| 246 | + ) { | ||
| 247 | + const today = dateUtil.todayFMD() | ||
| 248 | + this.calendar.jump(today) | ||
| 249 | + } | ||
| 250 | + this.count = undefined | ||
| 251 | + this.lastClick = undefined | ||
| 252 | + } else { | ||
| 253 | + this.lastClick = new Date().getTime() | ||
| 254 | + } | ||
| 255 | + } | ||
| 256 | + } | ||
| 257 | +}) |
| @@ -0,0 +1,60 @@ | @@ -0,0 +1,60 @@ | ||
| 1 | +<view class="flex b tb ac" wx:if="{{calendar}}"> | ||
| 2 | + <view class="calendar b tb"> | ||
| 3 | + <!-- 头部操作栏 --> | ||
| 4 | + <view | ||
| 5 | + wx:if="{{!config.hideHeader}}" | ||
| 6 | + class="handle {{config.theme}}_handle-color fs28 b lr ac pc"> | ||
| 7 | + <view class="prev fs36" wx:if="{{!config.weekMode}}"> | ||
| 8 | + <text class="prev-handle iconfont icon-doubleleft" bindtap="changeDate" data-type="prev_year"></text> | ||
| 9 | + <text class="prev-handle iconfont icon-left" bindtap="changeDate" data-type="prev_month"></text> | ||
| 10 | + </view> | ||
| 11 | + <view class="flex date-in-handle b lr cc" bindtap="doubleClickJumpToToday">{{calendar.curYear || "--"}} 年 {{calendar.curMonth || "--"}} 月</view> | ||
| 12 | + <view class="next fs36" wx:if="{{!config.weekMode}}"> | ||
| 13 | + <text class="next-handle iconfont icon-right" bindtap="changeDate" data-type="next_month"></text> | ||
| 14 | + <text class="next-handle iconfont icon-doubleright" bindtap="changeDate" data-type="next_year"></text> | ||
| 15 | + </view> | ||
| 16 | + </view> | ||
| 17 | + <!-- 星期栏 --> | ||
| 18 | + <view class="weeks b lr ac {{config.theme}}_week-color"> | ||
| 19 | + <view class="week fs28" wx:for="{{calendar.weeksCh}}" wx:key="index" data-idx="{{index}}">{{item}}</view> | ||
| 20 | + </view> | ||
| 21 | + <!-- 日历面板主体 --> | ||
| 22 | + <view class="b lr wrap" bindtouchstart="calendarTouchstart" catchtouchmove="calendarTouchmove" catchtouchend="calendarTouchend"> | ||
| 23 | + <!-- 上月日期格子 --> | ||
| 24 | + <view class="grid b ac pc {{config.theme}}_prev-month-date" wx:for="{{calendar.prevMonthGrids}}" wx:key="index" data-idx="{{index}}"> | ||
| 25 | + <view class="date-wrap b cc"> | ||
| 26 | + <view class="date"> | ||
| 27 | + {{item.date}} | ||
| 28 | + </view> | ||
| 29 | + </view> | ||
| 30 | + </view> | ||
| 31 | + <!-- 本月日期格子 --> | ||
| 32 | + <view wx:for="{{calendar.dates}}" wx:key="index" data-idx="{{index}}" data-info="{{item}}" bindtap="tapDate" class="grid {{item.class ? item.class : ''}} {{config.theme}}_normal-date b ac pc"> | ||
| 33 | + <view class="date-wrap b cc {{config.emphasisWeek && (item.week === 0 || item.week === 6) ? config.theme + '_weekend-color' : ''}}"> | ||
| 34 | + <view class="date b ac pc {{item.class ? item.class : ''}} {{item.isToday && config.highlightToday ? config.theme + '_today' : ''}} {{item.choosed ? config.theme + '_choosed' : ''}} {{item.disable ? config.theme + '_date-disable' : ''}} {{config.chooseAreaMode ? 'date-area-mode' : ''}} {{calendar.todoLabelCircle && item.showTodoLabel && !item.choosed ? config.theme + '_todo-circle todo-circle' : '' }}"> | ||
| 35 | + {{config.markToday && item.isToday ? config.markToday : item.date}} | ||
| 36 | + <view | ||
| 37 | + wx:if="{{(config.showLunar && item.lunar && !item.showTodoLabel) || (item.showTodoLabel && calendar.todoLabelPos !== 'bottom') || config.showHolidays}}" | ||
| 38 | + class="date-desc {{config.theme}}_date-desc date-desc-bottom {{(item.choosed || item.isToday) ? 'date-desc-bottom-always' : ''}} {{item.disable ? config.theme + '_date-desc-disable' : ''}}"> | ||
| 39 | + <text class="{{config.showHolidays && !item.showTodoLabel && item.label && !item.choosed ? config.theme + '_date-desc-lunar' : ''}} {{item.type === 'festival' ? config.theme + '_festival' : ''}}">{{item.label || item.lunar.Term || item.lunar.IDayCn}}</text> | ||
| 40 | + </view> | ||
| 41 | + <view | ||
| 42 | + wx:if="{{item.showTodoLabel && !calendar.todoLabelCircle}}" | ||
| 43 | + class="{{item.todoText ? 'date-desc' : config.theme + '_todo-dot todo-dot'}} {{config.showLunar ? config.theme + '_date-desc-lunar' : ''}} {{calendar.todoLabelPos === 'bottom' ? 'date-desc-bottom todo-dot-bottom' : 'date-desc-top todo-dot-top'}} {{calendar.showLabelAlways && item.choosed && calendar.todoLabelPos === 'bottom' ? 'date-desc-bottom-always todo-dot-bottom-always' : ''}} {{calendar.showLabelAlways && item.choosed && calendar.todoLabelPos === 'top' ? 'date-desc-top-always todo-dot-top-always' : ''}}" | ||
| 44 | + style="background-color: {{item.todoText ? '' : item.color || calendar.todoLabelColor}}; color: {{item.color}}"> | ||
| 45 | + {{item.todoText}} | ||
| 46 | + </view> | ||
| 47 | + </view> | ||
| 48 | + </view> | ||
| 49 | + </view> | ||
| 50 | + <!-- 下月日期格子 --> | ||
| 51 | + <view class="grid b ac pc {{config.theme}}_next-month-date" wx:for="{{calendar.nextMonthGrids}}" wx:key="index" data-idx="{{index}}"> | ||
| 52 | + <view class="date-wrap b cc"> | ||
| 53 | + <view class="date"> | ||
| 54 | + {{item.date}} | ||
| 55 | + </view> | ||
| 56 | + </view> | ||
| 57 | + </view> | ||
| 58 | + </view> | ||
| 59 | + </view> | ||
| 60 | +</view> |
| @@ -0,0 +1,214 @@ | @@ -0,0 +1,214 @@ | ||
| 1 | +@import './theme/iconfont.wxss'; | ||
| 2 | +@import './theme/theme-default.wxss'; | ||
| 3 | +@import './theme/theme-elegant.wxss'; | ||
| 4 | + | ||
| 5 | +.b { | ||
| 6 | + display: flex; | ||
| 7 | +} | ||
| 8 | + | ||
| 9 | +.lr { | ||
| 10 | + flex-direction: row; | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +.tb { | ||
| 14 | + flex-direction: column; | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +.pc { | ||
| 18 | + justify-content: center; | ||
| 19 | +} | ||
| 20 | + | ||
| 21 | +.ac { | ||
| 22 | + align-items: center; | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +.cc { | ||
| 26 | + align-items: center; | ||
| 27 | + justify-content: center; | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +.wrap { | ||
| 31 | + flex-wrap: wrap; | ||
| 32 | +} | ||
| 33 | + | ||
| 34 | +.flex { | ||
| 35 | + flex-grow: 1; | ||
| 36 | +} | ||
| 37 | + | ||
| 38 | +.bg { | ||
| 39 | + background-image: linear-gradient(to bottom, #faefe7, #ffcbd7); | ||
| 40 | + overflow: hidden; | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +.white-color { | ||
| 44 | + color: #fff; | ||
| 45 | +} | ||
| 46 | + | ||
| 47 | +.fs24 { | ||
| 48 | + font-size: 24rpx; | ||
| 49 | +} | ||
| 50 | + | ||
| 51 | +.fs28 { | ||
| 52 | + font-size: 28rpx; | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | +.fs32 { | ||
| 56 | + font-size: 32rpx; | ||
| 57 | +} | ||
| 58 | + | ||
| 59 | +.fs36 { | ||
| 60 | + font-size: 36rpx; | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +.calendar { | ||
| 64 | + width: 100%; | ||
| 65 | + box-sizing: border-box; | ||
| 66 | +} | ||
| 67 | + | ||
| 68 | +/* 日历操作栏 */ | ||
| 69 | + | ||
| 70 | +.handle { | ||
| 71 | + height: 80rpx; | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +.prev-handle, | ||
| 75 | +.next-handle { | ||
| 76 | + padding: 20rpx; | ||
| 77 | +} | ||
| 78 | + | ||
| 79 | +.date-in-handle { | ||
| 80 | + height: 80rpx; | ||
| 81 | +} | ||
| 82 | + | ||
| 83 | +/* 星期栏 */ | ||
| 84 | + | ||
| 85 | +.weeks { | ||
| 86 | + height: 50rpx; | ||
| 87 | + line-height: 50rpx; | ||
| 88 | + opacity: 0.5; | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +.week { | ||
| 92 | + text-align: center; | ||
| 93 | +} | ||
| 94 | + | ||
| 95 | +.grid, | ||
| 96 | +.week { | ||
| 97 | + width: 14.286014285714286%; | ||
| 98 | +} | ||
| 99 | + | ||
| 100 | +.date-wrap { | ||
| 101 | + width: 100%; | ||
| 102 | + height: 80rpx; | ||
| 103 | + position: relative; | ||
| 104 | + left: 0; | ||
| 105 | + top: 0; | ||
| 106 | +} | ||
| 107 | + | ||
| 108 | +.date { | ||
| 109 | + position: relative; | ||
| 110 | + left: 0; | ||
| 111 | + top: 0; | ||
| 112 | + width: 55rpx; | ||
| 113 | + height: 55rpx; | ||
| 114 | + text-align: center; | ||
| 115 | + line-height: 55rpx; | ||
| 116 | + font-size: 26rpx; | ||
| 117 | + font-weight: 200; | ||
| 118 | + border-radius: 50%; | ||
| 119 | + transition: all 0.3s; | ||
| 120 | + animation-name: choosed; | ||
| 121 | + animation-duration: 0.5s; | ||
| 122 | + animation-timing-function: linear; | ||
| 123 | + animation-iteration-count: 1; | ||
| 124 | +} | ||
| 125 | + | ||
| 126 | +.date-area-mode { | ||
| 127 | + width: 100%; | ||
| 128 | + border-radius: 0; | ||
| 129 | +} | ||
| 130 | + | ||
| 131 | +.date-desc { | ||
| 132 | + width: 150%; | ||
| 133 | + height: 32rpx; | ||
| 134 | + font-size: 20rpx; | ||
| 135 | + line-height: 32rpx; | ||
| 136 | + position: absolute; | ||
| 137 | + left: 50%; | ||
| 138 | + transform: translateX(-50%); | ||
| 139 | + overflow: hidden; | ||
| 140 | + word-break: break-all; | ||
| 141 | + text-overflow: ellipsis; | ||
| 142 | + white-space: nowrap; | ||
| 143 | + -webkit-line-clamp: 1; | ||
| 144 | + text-align: center; | ||
| 145 | +} | ||
| 146 | + | ||
| 147 | +@keyframes choosed { | ||
| 148 | + from { | ||
| 149 | + transform: scale(1); | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + 50% { | ||
| 153 | + transform: scale(0.9); | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + to { | ||
| 157 | + transform: scale(1); | ||
| 158 | + } | ||
| 159 | +} | ||
| 160 | + | ||
| 161 | +/* 日期圆圈标记 */ | ||
| 162 | +.todo-circle { | ||
| 163 | + border-width: 1rpx; | ||
| 164 | + border-style: solid; | ||
| 165 | + box-sizing: border-box; | ||
| 166 | +} | ||
| 167 | + | ||
| 168 | +/* 待办点标记相关样式 */ | ||
| 169 | +.todo-dot { | ||
| 170 | + width: 10rpx; | ||
| 171 | + height: 10rpx; | ||
| 172 | + border-radius: 50%; | ||
| 173 | + position: absolute; | ||
| 174 | + left: 50%; | ||
| 175 | + transform: translateX(-50%); | ||
| 176 | +} | ||
| 177 | + | ||
| 178 | +.todo-dot-top { | ||
| 179 | + top: 3rpx; | ||
| 180 | +} | ||
| 181 | + | ||
| 182 | +.todo-dot.todo-dot-top-always { | ||
| 183 | + top: -8rpx; | ||
| 184 | +} | ||
| 185 | + | ||
| 186 | +.todo-dot.todo-dot-bottom { | ||
| 187 | + bottom: 0; | ||
| 188 | +} | ||
| 189 | + | ||
| 190 | +.todo-dot.todo-dot-bottom-always { | ||
| 191 | + bottom: -10rpx; | ||
| 192 | +} | ||
| 193 | + | ||
| 194 | +/* 日期描述文字(待办文字/农历)相关样式 */ | ||
| 195 | + | ||
| 196 | +.date-desc.date-desc-top { | ||
| 197 | + top: -6rpx; | ||
| 198 | +} | ||
| 199 | + | ||
| 200 | +.date-desc.date-desc-top-always { | ||
| 201 | + top: -20rpx; | ||
| 202 | +} | ||
| 203 | + | ||
| 204 | +.date-desc.date-desc-bottom { | ||
| 205 | + bottom: -14rpx; | ||
| 206 | +} | ||
| 207 | + | ||
| 208 | +.todo-circle .date-desc.date-desc-bottom { | ||
| 209 | + bottom: -30rpx; | ||
| 210 | +} | ||
| 211 | + | ||
| 212 | +.date-desc.date-desc-bottom-always { | ||
| 213 | + bottom: -28rpx; | ||
| 214 | +} |
| @@ -0,0 +1,212 @@ | @@ -0,0 +1,212 @@ | ||
| 1 | +/* * | ||
| 2 | + @Author: drfu* | ||
| 3 | + @Description: 数据来源于国务院办公厅关于2020年部分节假日安排的通知(国办发明电〔2019〕16号)_政府信息公开专栏,http://www.gov.cn/zhengce/content/2019-11/21/content_5454164.htm | ||
| 4 | + @Date: 2020-10-12 14:29:45* | ||
| 5 | + * @Last Modified by: drfu | ||
| 6 | + * @Last Modified time: 2020-10-16 17:38:08 | ||
| 7 | +*/ | ||
| 8 | + | ||
| 9 | +// 节日列表 | ||
| 10 | +export const festival = { | ||
| 11 | + // 农历固定日期节日 | ||
| 12 | + lunar: { | ||
| 13 | + 1: { | ||
| 14 | + 1: { | ||
| 15 | + type: 'festival', | ||
| 16 | + name: '春节', | ||
| 17 | + label: '春节' | ||
| 18 | + }, | ||
| 19 | + 8: { | ||
| 20 | + type: 'festival', | ||
| 21 | + name: '腊八节', | ||
| 22 | + label: '腊八' | ||
| 23 | + }, | ||
| 24 | + 15: { | ||
| 25 | + type: 'festival', | ||
| 26 | + name: '元宵节', | ||
| 27 | + label: '元宵' | ||
| 28 | + } | ||
| 29 | + }, | ||
| 30 | + 7: { | ||
| 31 | + 7: { | ||
| 32 | + type: 'festival', | ||
| 33 | + name: '七夕节', | ||
| 34 | + label: '七夕' | ||
| 35 | + }, | ||
| 36 | + 15: { | ||
| 37 | + type: 'festival', | ||
| 38 | + name: '中元节', | ||
| 39 | + label: '中元节' | ||
| 40 | + } | ||
| 41 | + }, | ||
| 42 | + 9: { | ||
| 43 | + 9: { | ||
| 44 | + type: 'festival', | ||
| 45 | + name: '重阳节', | ||
| 46 | + label: '重阳节' | ||
| 47 | + } | ||
| 48 | + } | ||
| 49 | + }, | ||
| 50 | + // 阳历固定日期节日 | ||
| 51 | + solar: { | ||
| 52 | + 2: { | ||
| 53 | + 14: { | ||
| 54 | + type: 'festival', | ||
| 55 | + name: '情人节', | ||
| 56 | + label: '情人节' | ||
| 57 | + } | ||
| 58 | + }, | ||
| 59 | + 3: { | ||
| 60 | + 12: { | ||
| 61 | + type: 'festival', | ||
| 62 | + name: '植树节', | ||
| 63 | + label: '植树节' | ||
| 64 | + } | ||
| 65 | + }, | ||
| 66 | + 4: { | ||
| 67 | + 1: { | ||
| 68 | + type: 'festival', | ||
| 69 | + name: '愚人节', | ||
| 70 | + label: '愚人节' | ||
| 71 | + }, | ||
| 72 | + 5: { | ||
| 73 | + type: 'festival', | ||
| 74 | + name: '清明节', | ||
| 75 | + label: '清明节' | ||
| 76 | + } | ||
| 77 | + }, | ||
| 78 | + 5: { | ||
| 79 | + 1: { | ||
| 80 | + type: 'festival', | ||
| 81 | + name: '劳动节', | ||
| 82 | + label: '劳动节' | ||
| 83 | + } | ||
| 84 | + }, | ||
| 85 | + 6: { | ||
| 86 | + 1: { | ||
| 87 | + type: 'festival', | ||
| 88 | + name: '儿童节', | ||
| 89 | + label: '儿童节' | ||
| 90 | + } | ||
| 91 | + }, | ||
| 92 | + 7: { | ||
| 93 | + 1: { | ||
| 94 | + type: 'festival', | ||
| 95 | + name: '建党节', | ||
| 96 | + label: '建党节' | ||
| 97 | + } | ||
| 98 | + }, | ||
| 99 | + 8: { | ||
| 100 | + 1: { | ||
| 101 | + type: 'festival', | ||
| 102 | + name: '建军节', | ||
| 103 | + label: '建军节' | ||
| 104 | + } | ||
| 105 | + }, | ||
| 106 | + 9: { | ||
| 107 | + 10: { | ||
| 108 | + type: 'festival', | ||
| 109 | + name: '教师节', | ||
| 110 | + label: '教师节' | ||
| 111 | + } | ||
| 112 | + }, | ||
| 113 | + 10: { | ||
| 114 | + 1: { | ||
| 115 | + type: 'festival', | ||
| 116 | + name: '国庆节', | ||
| 117 | + label: '国庆节' | ||
| 118 | + } | ||
| 119 | + }, | ||
| 120 | + 12: { | ||
| 121 | + 25: { | ||
| 122 | + type: 'festival', | ||
| 123 | + name: '圣诞节', | ||
| 124 | + label: '圣诞节' | ||
| 125 | + } | ||
| 126 | + } | ||
| 127 | + } | ||
| 128 | +} | ||
| 129 | + | ||
| 130 | +export const holidays = { | ||
| 131 | + 2020: { | ||
| 132 | + 1: { | ||
| 133 | + 1: { | ||
| 134 | + type: 'holiday', | ||
| 135 | + name: '元旦', | ||
| 136 | + label: '休' | ||
| 137 | + }, | ||
| 138 | + 19: { | ||
| 139 | + type: 'work', | ||
| 140 | + name: '调班', | ||
| 141 | + label: '班' | ||
| 142 | + }, | ||
| 143 | + '24-30': { | ||
| 144 | + type: 'holiday', | ||
| 145 | + name: '春节', | ||
| 146 | + label: '休' | ||
| 147 | + } | ||
| 148 | + }, | ||
| 149 | + 2: { | ||
| 150 | + 1: { | ||
| 151 | + type: 'work', | ||
| 152 | + name: '调班', | ||
| 153 | + label: '班' | ||
| 154 | + } | ||
| 155 | + }, | ||
| 156 | + 4: { | ||
| 157 | + '4-6': { | ||
| 158 | + type: 'holiday', | ||
| 159 | + name: '清明节', | ||
| 160 | + label: '休' | ||
| 161 | + }, | ||
| 162 | + 26: { | ||
| 163 | + type: 'work', | ||
| 164 | + name: '调班', | ||
| 165 | + label: '班' | ||
| 166 | + } | ||
| 167 | + }, | ||
| 168 | + 5: { | ||
| 169 | + '1-5': { | ||
| 170 | + type: 'holiday', | ||
| 171 | + name: '劳动节', | ||
| 172 | + label: '休' | ||
| 173 | + }, | ||
| 174 | + 9: { | ||
| 175 | + type: 'work', | ||
| 176 | + name: '调班', | ||
| 177 | + label: '班' | ||
| 178 | + } | ||
| 179 | + }, | ||
| 180 | + 6: { | ||
| 181 | + '25-27': { | ||
| 182 | + type: 'holiday', | ||
| 183 | + name: '端午节', | ||
| 184 | + label: '休' | ||
| 185 | + }, | ||
| 186 | + 28: { | ||
| 187 | + type: 'work', | ||
| 188 | + name: '调班', | ||
| 189 | + label: '班' | ||
| 190 | + } | ||
| 191 | + }, | ||
| 192 | + 9: { | ||
| 193 | + 27: { | ||
| 194 | + type: 'work', | ||
| 195 | + name: '调班', | ||
| 196 | + label: '班' | ||
| 197 | + } | ||
| 198 | + }, | ||
| 199 | + 10: { | ||
| 200 | + '1-8': { | ||
| 201 | + type: 'holiday', | ||
| 202 | + name: '国庆节/中秋节', | ||
| 203 | + label: '休' | ||
| 204 | + }, | ||
| 205 | + 10: { | ||
| 206 | + type: 'work', | ||
| 207 | + name: '调班', | ||
| 208 | + label: '班' | ||
| 209 | + } | ||
| 210 | + } | ||
| 211 | + } | ||
| 212 | +} |
| @@ -0,0 +1,201 @@ | @@ -0,0 +1,201 @@ | ||
| 1 | +/* * | ||
| 2 | + @Author: drfu* | ||
| 3 | + @Description: 显示法定节假日班/休情况 | ||
| 4 | + @Date: 2020-10-12 14:29:45* | ||
| 5 | + * @Last Modified by: drfu | ||
| 6 | + * @Last Modified time: 2020-10-16 17:34:13 | ||
| 7 | +*/ | ||
| 8 | + | ||
| 9 | +import { holidays, festival } from './holidays-map' | ||
| 10 | +import { dateUtil, getCalendarData, logger } from '../../utils/index' | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * 当前是否在休假期内 | ||
| 14 | + * @param {object} { year, month } | ||
| 15 | + * @param {object} { start, end, current } | ||
| 16 | + * @returns | ||
| 17 | + */ | ||
| 18 | +function inHolidays({ year, month }, { start, end, current }) { | ||
| 19 | + const getTimeStamp = dateUtil.getTimeStamp | ||
| 20 | + const startTimestamp = getTimeStamp({ | ||
| 21 | + year, | ||
| 22 | + month, | ||
| 23 | + date: start | ||
| 24 | + }) | ||
| 25 | + const endTimestamp = getTimeStamp({ | ||
| 26 | + year, | ||
| 27 | + month, | ||
| 28 | + date: end | ||
| 29 | + }) | ||
| 30 | + const currentDateTimestamp = getTimeStamp({ | ||
| 31 | + year, | ||
| 32 | + month, | ||
| 33 | + date: current | ||
| 34 | + }) | ||
| 35 | + if ( | ||
| 36 | + currentDateTimestamp >= startTimestamp && | ||
| 37 | + currentDateTimestamp <= endTimestamp | ||
| 38 | + ) { | ||
| 39 | + return true | ||
| 40 | + } | ||
| 41 | + return false | ||
| 42 | +} | ||
| 43 | + | ||
| 44 | +function addSpecialFestival(date, component) { | ||
| 45 | + const { convertlLunar2Solar, convertSolarLunar } = component.calendar || {} | ||
| 46 | + const lunarDateInfo = convertSolarLunar(date) | ||
| 47 | + const { lYear, lMonth } = lunarDateInfo || {} | ||
| 48 | + // 春节 | ||
| 49 | + const info = { | ||
| 50 | + type: 'festival', | ||
| 51 | + name: '除夕', | ||
| 52 | + label: '除夕' | ||
| 53 | + } | ||
| 54 | + if (lMonth === 12) { | ||
| 55 | + if (!festival.lunar['12']) festival.lunar['12'] = {} | ||
| 56 | + if (convertlLunar2Solar(`${lYear}-12-30`) === -1) { | ||
| 57 | + festival.lunar['12']['29'] = info | ||
| 58 | + } else { | ||
| 59 | + festival.lunar['12']['30'] = info | ||
| 60 | + } | ||
| 61 | + } | ||
| 62 | +} | ||
| 63 | + | ||
| 64 | +/** | ||
| 65 | + * 是否匹配到节日 | ||
| 66 | + * @param {object} [dateInfo={}] | ||
| 67 | + * @param {object} [component={}] | ||
| 68 | + * @returns {object|boolean} 匹配到的节日数据或者false | ||
| 69 | + */ | ||
| 70 | +function hasFestivalDate(dateInfo = {}, component = {}) { | ||
| 71 | + const { month, date } = dateInfo | ||
| 72 | + let festivalDate = festival.solar[month] && festival.solar[month][date] | ||
| 73 | + if (!festivalDate) { | ||
| 74 | + const { convertSolarLunar } = component.calendar || {} | ||
| 75 | + const lunarDateInfo = convertSolarLunar(dateInfo) | ||
| 76 | + const { lMonth, lDay } = lunarDateInfo | ||
| 77 | + festivalDate = festival.lunar[lMonth] && festival.lunar[lMonth][lDay] | ||
| 78 | + if (!festivalDate) { | ||
| 79 | + const festivalOfMonth = festival.lunar[lMonth] || {} | ||
| 80 | + const festivalDateKey = Object.keys(festivalOfMonth).find(item => | ||
| 81 | + item.match(new RegExp(`\\b${lDay}\\b`)) | ||
| 82 | + ) | ||
| 83 | + if (!festivalDateKey) { | ||
| 84 | + festivalDate = false | ||
| 85 | + } else { | ||
| 86 | + const festivalInfo = festival.lunar[lMonth][festivalDateKey] | ||
| 87 | + if (!festivalInfo) { | ||
| 88 | + festivalDate = false | ||
| 89 | + } else { | ||
| 90 | + const { condition } = festivalInfo | ||
| 91 | + if (typeof condition === 'function') { | ||
| 92 | + festivalDate = condition(lunarDateInfo) | ||
| 93 | + } else { | ||
| 94 | + festivalDate = false | ||
| 95 | + } | ||
| 96 | + } | ||
| 97 | + } | ||
| 98 | + } | ||
| 99 | + } | ||
| 100 | + return festivalDate | ||
| 101 | +} | ||
| 102 | + | ||
| 103 | +export default () => { | ||
| 104 | + return { | ||
| 105 | + name: 'holidays', | ||
| 106 | + beforeRender(calendarData = {}, calendarConfig = {}, component) { | ||
| 107 | + let { dates = [] } = calendarData | ||
| 108 | + if (calendarConfig.showHolidays || calendarConfig.showFestival) { | ||
| 109 | + dates = dates.map(d => { | ||
| 110 | + let item = { ...d } | ||
| 111 | + const { year, month, date } = item | ||
| 112 | + const holidaysOfMonth = | ||
| 113 | + (holidays[year] && holidays[year][month]) || {} | ||
| 114 | + const holidayDate = holidaysOfMonth[date] | ||
| 115 | + if (holidayDate) { | ||
| 116 | + item = { | ||
| 117 | + ...item, | ||
| 118 | + ...holidayDate | ||
| 119 | + } | ||
| 120 | + } else { | ||
| 121 | + const holidayKeys = Object.keys(holidaysOfMonth).filter(item => | ||
| 122 | + item.includes('-') | ||
| 123 | + ) | ||
| 124 | + let target = '' | ||
| 125 | + for (let v of holidayKeys) { | ||
| 126 | + const [start, end] = v.split('-') | ||
| 127 | + if (+d.date >= +start && +d.date <= +end) { | ||
| 128 | + target = v | ||
| 129 | + break | ||
| 130 | + } | ||
| 131 | + } | ||
| 132 | + const [start, end] = target.split('-') | ||
| 133 | + const isInHolidays = inHolidays( | ||
| 134 | + { | ||
| 135 | + year, | ||
| 136 | + month | ||
| 137 | + }, | ||
| 138 | + { | ||
| 139 | + start, | ||
| 140 | + end, | ||
| 141 | + current: date | ||
| 142 | + } | ||
| 143 | + ) | ||
| 144 | + if (isInHolidays) { | ||
| 145 | + item = { | ||
| 146 | + ...item, | ||
| 147 | + ...holidaysOfMonth[target] | ||
| 148 | + } | ||
| 149 | + } else if (calendarConfig.showFestival) { | ||
| 150 | + const { convertSolarLunar, convertlLunar2Solar } = | ||
| 151 | + component.calendar || {} | ||
| 152 | + if ( | ||
| 153 | + typeof convertSolarLunar !== 'function' || | ||
| 154 | + typeof convertlLunar2Solar !== 'function' | ||
| 155 | + ) { | ||
| 156 | + return logger.warn( | ||
| 157 | + '农历节日显示需要引入农历插件(/component/v2/plugins/solarLunar)' | ||
| 158 | + ) | ||
| 159 | + } | ||
| 160 | + addSpecialFestival(item, component) | ||
| 161 | + const festivalDate = hasFestivalDate(item, component) | ||
| 162 | + if (festivalDate) { | ||
| 163 | + item = { | ||
| 164 | + ...item, | ||
| 165 | + ...festivalDate | ||
| 166 | + } | ||
| 167 | + } | ||
| 168 | + } | ||
| 169 | + } | ||
| 170 | + return item | ||
| 171 | + }) | ||
| 172 | + } | ||
| 173 | + return { | ||
| 174 | + calendarData: { | ||
| 175 | + ...calendarData, | ||
| 176 | + dates: dates | ||
| 177 | + }, | ||
| 178 | + calendarConfig | ||
| 179 | + } | ||
| 180 | + }, | ||
| 181 | + methods(component) { | ||
| 182 | + return { | ||
| 183 | + getHolidaysOfCurrentYear() { | ||
| 184 | + const calendar = getCalendarData('calendar', component) | ||
| 185 | + const { curYear } = calendar | ||
| 186 | + return this.methods(component).getHolidaysOfYear(curYear) | ||
| 187 | + }, | ||
| 188 | + getHolidaysOfYear(year) { | ||
| 189 | + if (!year) return logger.warn('getHolidaysOfCurrentYear() 入参错误') | ||
| 190 | + if (!holidays[year]) { | ||
| 191 | + logger.warn('未匹配到当前年份节假日信息,请自行补充') | ||
| 192 | + return { | ||
| 193 | + err: 'not match' | ||
| 194 | + } | ||
| 195 | + } | ||
| 196 | + return holidays[year] | ||
| 197 | + } | ||
| 198 | + } | ||
| 199 | + } | ||
| 200 | + } | ||
| 201 | +} |
| @@ -0,0 +1,18 @@ | @@ -0,0 +1,18 @@ | ||
| 1 | +import preset from './preset/index' | ||
| 2 | + | ||
| 3 | +export default { | ||
| 4 | + installed: [...preset], | ||
| 5 | + use(plugin) { | ||
| 6 | + if (typeof plugin !== 'function') return | ||
| 7 | + const info = plugin() || {} | ||
| 8 | + const { name } = info | ||
| 9 | + if ( | ||
| 10 | + name && | ||
| 11 | + name !== 'methods' && | ||
| 12 | + !this.installed.some(p => p[0] === name) | ||
| 13 | + ) { | ||
| 14 | + this.installed.unshift([name, info]) | ||
| 15 | + } | ||
| 16 | + return this | ||
| 17 | + } | ||
| 18 | +} |
| @@ -0,0 +1,277 @@ | @@ -0,0 +1,277 @@ | ||
| 1 | +/** | ||
| 2 | + * @Author: drfu* | ||
| 3 | + * @Description: 基础功能 | ||
| 4 | + * @Date: 2020-10-08 21:22:09* | ||
| 5 | + * @Last Modified by: drfu | ||
| 6 | + * @Last Modified time: 2020-10-11 13:28:52 | ||
| 7 | + * */ | ||
| 8 | + | ||
| 9 | +import { calcJumpData } from '../../core' | ||
| 10 | +import { renderCalendar } from '../../render' | ||
| 11 | +import { | ||
| 12 | + dateUtil, | ||
| 13 | + getCalendarData, | ||
| 14 | + setCalendarData, | ||
| 15 | + getCalendarConfig | ||
| 16 | +} from '../../utils/index' | ||
| 17 | + | ||
| 18 | +export default () => { | ||
| 19 | + return { | ||
| 20 | + name: 'base', | ||
| 21 | + beforeRender(calendarData = {}, calendarConfig) { | ||
| 22 | + const calendar = calendarData | ||
| 23 | + const { selectedDates = [], dates } = calendar | ||
| 24 | + let _dates = [...dates] | ||
| 25 | + if (selectedDates.length) { | ||
| 26 | + const selectedDatesStr = selectedDates.map(date => | ||
| 27 | + dateUtil.toTimeStr(date) | ||
| 28 | + ) | ||
| 29 | + _dates.forEach(date => { | ||
| 30 | + const dateStr = dateUtil.toTimeStr(date) | ||
| 31 | + if (selectedDatesStr.includes(dateStr)) { | ||
| 32 | + date.choosed = true | ||
| 33 | + } | ||
| 34 | + }) | ||
| 35 | + } | ||
| 36 | + return { | ||
| 37 | + calendarData: { | ||
| 38 | + ...calendarData, | ||
| 39 | + dates: _dates | ||
| 40 | + }, | ||
| 41 | + calendarConfig | ||
| 42 | + } | ||
| 43 | + }, | ||
| 44 | + onTapDate(tapedDate, calendarData = {}, calendarConfig = {}) { | ||
| 45 | + const calendar = { | ||
| 46 | + ...calendarData | ||
| 47 | + } | ||
| 48 | + const dateIndex = dateUtil.findDateIndexInArray( | ||
| 49 | + tapedDate, | ||
| 50 | + calendarData.dates | ||
| 51 | + ) | ||
| 52 | + const { multi, inverse } = calendarConfig | ||
| 53 | + let dates = [...calendar.dates] | ||
| 54 | + const { selectedDates = [] } = calendar | ||
| 55 | + if (!multi) { | ||
| 56 | + let preSelectedDate = {} | ||
| 57 | + if (selectedDates.length) { | ||
| 58 | + preSelectedDate = [...selectedDates].pop() || {} | ||
| 59 | + } | ||
| 60 | + const timeStr = dateUtil.toTimeStr | ||
| 61 | + if (!inverse && timeStr(preSelectedDate) === timeStr(tapedDate)) { | ||
| 62 | + return calendar | ||
| 63 | + } | ||
| 64 | + let _tapedDate = { ...tapedDate, choosed: !tapedDate.choosed } | ||
| 65 | + | ||
| 66 | + dates[dateIndex] = _tapedDate | ||
| 67 | + if (preSelectedDate.date) { | ||
| 68 | + const idx = dateUtil.findDateIndexInArray(preSelectedDate, dates) | ||
| 69 | + const date = dates[idx] | ||
| 70 | + if (date) { | ||
| 71 | + date.choosed = false | ||
| 72 | + } | ||
| 73 | + } | ||
| 74 | + if (dates[dateIndex].choosed) { | ||
| 75 | + calendar.selectedDates = [dates[dateIndex]] | ||
| 76 | + } else { | ||
| 77 | + calendar.selectedDates = [] | ||
| 78 | + } | ||
| 79 | + } else { | ||
| 80 | + dates[dateIndex] = { | ||
| 81 | + ...dates[dateIndex], | ||
| 82 | + choosed: !dates[dateIndex].choosed | ||
| 83 | + } | ||
| 84 | + if (!calendar.selectedDates) { | ||
| 85 | + calendar.selectedDates = [] | ||
| 86 | + } | ||
| 87 | + if (dates[dateIndex].choosed) { | ||
| 88 | + calendar.selectedDates.push(dates[dateIndex]) | ||
| 89 | + } else { | ||
| 90 | + calendar.selectedDates = calendar.selectedDates.filter( | ||
| 91 | + date => | ||
| 92 | + dateUtil.toTimeStr(date) !== dateUtil.toTimeStr(dates[dateIndex]) | ||
| 93 | + ) | ||
| 94 | + } | ||
| 95 | + } | ||
| 96 | + return { | ||
| 97 | + calendarData: { | ||
| 98 | + ...calendar, | ||
| 99 | + dates | ||
| 100 | + }, | ||
| 101 | + calendarConfig | ||
| 102 | + } | ||
| 103 | + }, | ||
| 104 | + onSwitchCalendar(date, calendarData = {}, component) { | ||
| 105 | + const calendarConfig = getCalendarConfig(component) | ||
| 106 | + if (calendarConfig.weekMode) { | ||
| 107 | + return calendarData | ||
| 108 | + } | ||
| 109 | + const updatedRenderData = calcJumpData({ | ||
| 110 | + dateInfo: date, | ||
| 111 | + config: calendarConfig | ||
| 112 | + }) | ||
| 113 | + return { | ||
| 114 | + ...calendarData, | ||
| 115 | + ...updatedRenderData | ||
| 116 | + } | ||
| 117 | + }, | ||
| 118 | + methods(component) { | ||
| 119 | + return { | ||
| 120 | + jump: dateInfo => { | ||
| 121 | + if (Object.prototype.toString.call(dateInfo) !== '[object Object]') | ||
| 122 | + return | ||
| 123 | + const updatedRenderData = calcJumpData({ | ||
| 124 | + dateInfo, | ||
| 125 | + component | ||
| 126 | + }) | ||
| 127 | + const existCalendarData = getCalendarData('calendar', component) | ||
| 128 | + const config = getCalendarConfig(component) | ||
| 129 | + if (config.autoChoosedWhenJump) { | ||
| 130 | + const target = updatedRenderData.dates[dateInfo.date - 1] | ||
| 131 | + if (!updatedRenderData.selectedDates) { | ||
| 132 | + updatedRenderData.selectedDates = [target] | ||
| 133 | + } else { | ||
| 134 | + updatedRenderData.selectedDates.push(target) | ||
| 135 | + } | ||
| 136 | + } | ||
| 137 | + return renderCalendar.call(component, { | ||
| 138 | + ...existCalendarData, | ||
| 139 | + ...updatedRenderData | ||
| 140 | + }) | ||
| 141 | + }, | ||
| 142 | + getCalendarConfig() { | ||
| 143 | + return getCalendarConfig(component) | ||
| 144 | + }, | ||
| 145 | + setCalendarConfig(config) { | ||
| 146 | + return new Promise((resolve, reject) => { | ||
| 147 | + if (!component || !component.data.config) { | ||
| 148 | + reject('异常:未找到组件配置信息') | ||
| 149 | + return | ||
| 150 | + } | ||
| 151 | + let conf = { ...component.data.config, ...config } | ||
| 152 | + component.data.config = conf | ||
| 153 | + setCalendarData({ config: conf }, component) | ||
| 154 | + .then(resolve) | ||
| 155 | + .catch(reject) | ||
| 156 | + }) | ||
| 157 | + }, | ||
| 158 | + cancelSelectedDates(cancelDates = []) { | ||
| 159 | + const existCalendarData = getCalendarData('calendar', component) || {} | ||
| 160 | + const { dates = [], selectedDates = [] } = existCalendarData | ||
| 161 | + let updatedRenderData = {} | ||
| 162 | + const config = getCalendarConfig(component) | ||
| 163 | + let chooseAreaData = {} | ||
| 164 | + if (config.chooseAreaMode) { | ||
| 165 | + chooseAreaData = { | ||
| 166 | + chooseAreaTimestamp: [], | ||
| 167 | + tempChooseAreaTimestamp: [] | ||
| 168 | + } | ||
| 169 | + } | ||
| 170 | + if (!cancelDates.length) { | ||
| 171 | + dates.forEach(item => { | ||
| 172 | + item.choosed = false | ||
| 173 | + }) | ||
| 174 | + updatedRenderData = { | ||
| 175 | + dates, | ||
| 176 | + selectedDates: [] | ||
| 177 | + } | ||
| 178 | + } else { | ||
| 179 | + const cancelDatesStr = cancelDates.map(date => | ||
| 180 | + dateUtil.toTimeStr(date) | ||
| 181 | + ) | ||
| 182 | + const filterSelectedDates = selectedDates.filter( | ||
| 183 | + date => !cancelDatesStr.includes(dateUtil.toTimeStr(date)) | ||
| 184 | + ) | ||
| 185 | + dates.forEach(date => { | ||
| 186 | + if (cancelDatesStr.includes(dateUtil.toTimeStr(date))) { | ||
| 187 | + date.choosed = false | ||
| 188 | + } | ||
| 189 | + }) | ||
| 190 | + updatedRenderData = { | ||
| 191 | + dates, | ||
| 192 | + selectedDates: filterSelectedDates | ||
| 193 | + } | ||
| 194 | + } | ||
| 195 | + | ||
| 196 | + return renderCalendar.call(component, { | ||
| 197 | + ...existCalendarData, | ||
| 198 | + ...updatedRenderData, | ||
| 199 | + ...chooseAreaData | ||
| 200 | + }) | ||
| 201 | + }, | ||
| 202 | + setSelectedDates: targetDates => { | ||
| 203 | + const existCalendarData = getCalendarData('calendar', component) | ||
| 204 | + let { dates, selectedDates = [] } = existCalendarData || {} | ||
| 205 | + let __selectedDates = [] | ||
| 206 | + let __dates = dates | ||
| 207 | + if (!targetDates) { | ||
| 208 | + __dates = dates.map(item => { | ||
| 209 | + const date = { ...item } | ||
| 210 | + date.choosed = true | ||
| 211 | + if (existCalendarData.showLabelAlways && date.showTodoLabel) { | ||
| 212 | + date.showTodoLabel = true | ||
| 213 | + } else { | ||
| 214 | + date.showTodoLabel = false | ||
| 215 | + } | ||
| 216 | + return date | ||
| 217 | + }) | ||
| 218 | + __selectedDates = dates | ||
| 219 | + } else if (targetDates && targetDates.length) { | ||
| 220 | + const allSelected = dateUtil.uniqueArrayByDate( | ||
| 221 | + selectedDates.concat(targetDates) | ||
| 222 | + ) | ||
| 223 | + const allSelectedDateStr = allSelected.map(d => | ||
| 224 | + dateUtil.toTimeStr(d) | ||
| 225 | + ) | ||
| 226 | + __dates = dates.map(item => { | ||
| 227 | + const date = { ...item } | ||
| 228 | + if (allSelectedDateStr.includes(dateUtil.toTimeStr(date))) { | ||
| 229 | + date.choosed = true | ||
| 230 | + __selectedDates.push(date) | ||
| 231 | + } | ||
| 232 | + if (existCalendarData.showLabelAlways && date.showTodoLabel) { | ||
| 233 | + date.showTodoLabel = true | ||
| 234 | + } else { | ||
| 235 | + date.showTodoLabel = false | ||
| 236 | + } | ||
| 237 | + return date | ||
| 238 | + }) | ||
| 239 | + } | ||
| 240 | + return renderCalendar.call(component, { | ||
| 241 | + ...existCalendarData, | ||
| 242 | + dates: __dates, | ||
| 243 | + selectedDates: __selectedDates | ||
| 244 | + }) | ||
| 245 | + }, | ||
| 246 | + setDateStyle: toSetDates => { | ||
| 247 | + if (!Array.isArray(toSetDates)) return Promise.reject() | ||
| 248 | + const existCalendarData = getCalendarData('calendar', component) | ||
| 249 | + const { dates = [], specialStyleDates } = existCalendarData || {} | ||
| 250 | + if (Array.isArray(specialStyleDates)) { | ||
| 251 | + toSetDates = dateUtil.uniqueArrayByDate([ | ||
| 252 | + ...specialStyleDates, | ||
| 253 | + ...toSetDates | ||
| 254 | + ]) | ||
| 255 | + } | ||
| 256 | + const toSetDatesStr = toSetDates.map(item => dateUtil.toTimeStr(item)) | ||
| 257 | + const _dates = dates.map(item => { | ||
| 258 | + const idx = toSetDatesStr.indexOf(dateUtil.toTimeStr(item)) | ||
| 259 | + if (idx > -1) { | ||
| 260 | + return { | ||
| 261 | + ...item, | ||
| 262 | + class: toSetDates[idx].class | ||
| 263 | + } | ||
| 264 | + } else { | ||
| 265 | + return item | ||
| 266 | + } | ||
| 267 | + }) | ||
| 268 | + return renderCalendar.call(component, { | ||
| 269 | + ...existCalendarData, | ||
| 270 | + dates: _dates, | ||
| 271 | + specialStyleDates: toSetDates | ||
| 272 | + }) | ||
| 273 | + } | ||
| 274 | + } | ||
| 275 | + } | ||
| 276 | + } | ||
| 277 | +} |
| @@ -0,0 +1,69 @@ | @@ -0,0 +1,69 @@ | ||
| 1 | +/** | ||
| 2 | + * @Author: drfu* | ||
| 3 | + * @Description: 获取日历数据 | ||
| 4 | + * @Date: 2020-10-08 21:22:09* | ||
| 5 | + * @Last Modified by: drfu | ||
| 6 | + * @Last Modified time: 2020-10-11 13:42:37 | ||
| 7 | + * */ | ||
| 8 | + | ||
| 9 | +import { getCalendarData, logger, getCalendarConfig } from '../../utils/index' | ||
| 10 | + | ||
| 11 | +function wrapDateWithLunar(dates = [], convertFn) { | ||
| 12 | + const datesWithLunar = JSON.parse(JSON.stringify(dates)).map(date => ({ | ||
| 13 | + ...date, | ||
| 14 | + lunar: convertFn(date) | ||
| 15 | + })) | ||
| 16 | + return datesWithLunar | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +export default () => { | ||
| 20 | + return { | ||
| 21 | + name: 'getData', | ||
| 22 | + methods(component) { | ||
| 23 | + return { | ||
| 24 | + getCurrentYM: () => { | ||
| 25 | + const { curYear, curMonth } = getCalendarData('calendar', component) | ||
| 26 | + return { | ||
| 27 | + year: curYear, | ||
| 28 | + month: curMonth | ||
| 29 | + } | ||
| 30 | + }, | ||
| 31 | + getSelectedDates: (options = {}) => { | ||
| 32 | + const dates = | ||
| 33 | + getCalendarData('calendar.selectedDates', component) || [] | ||
| 34 | + const config = getCalendarConfig(component) || {} | ||
| 35 | + if (options.lunar && !config.showLunar) { | ||
| 36 | + const injectedFns = component.calendar || {} | ||
| 37 | + if (typeof injectedFns.convertSolarLunar === 'function') { | ||
| 38 | + return wrapDateWithLunar(dates, injectedFns.convertSolarLunar) | ||
| 39 | + } else { | ||
| 40 | + logger.warn('获取农历信息需引入农历插件') | ||
| 41 | + } | ||
| 42 | + } else { | ||
| 43 | + return dates | ||
| 44 | + } | ||
| 45 | + }, | ||
| 46 | + getCalendarDates: (options = {}) => { | ||
| 47 | + const config = getCalendarConfig(component) || {} | ||
| 48 | + const dates = getCalendarData('calendar.dates', component) | ||
| 49 | + if (options.lunar && !config.showLunar) { | ||
| 50 | + const injectedFns = component.calendar || {} | ||
| 51 | + if (typeof injectedFns.convertSolarLunar === 'function') { | ||
| 52 | + return wrapDateWithLunar(dates, injectedFns.convertSolarLunar) | ||
| 53 | + } else { | ||
| 54 | + logger.warn('获取农历信息需引入农历插件') | ||
| 55 | + } | ||
| 56 | + } else { | ||
| 57 | + return dates | ||
| 58 | + } | ||
| 59 | + }, | ||
| 60 | + getCalendarAllData: () => { | ||
| 61 | + return { | ||
| 62 | + data: getCalendarData('calendar', component) || {}, | ||
| 63 | + config: getCalendarConfig(component) || {} | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + } | ||
| 67 | + } | ||
| 68 | + } | ||
| 69 | +} |
| @@ -0,0 +1,219 @@ | @@ -0,0 +1,219 @@ | ||
| 1 | +/** | ||
| 2 | + * @Author: drfu* | ||
| 3 | + * @Description: 禁用、启用日期选择 | ||
| 4 | + * @Date: 2020-10-08 21:22:09* | ||
| 5 | + * @Last Modified by: drfu | ||
| 6 | + * @Last Modified time: 2020-10-08 21:25:00 | ||
| 7 | + * */ | ||
| 8 | + | ||
| 9 | +import { getCalendarData, dateUtil, logger } from '../utils/index' | ||
| 10 | +import { renderCalendar } from '../render' | ||
| 11 | + | ||
| 12 | +function convertEnableAreaToTimestamp(timearea = []) { | ||
| 13 | + const start = timearea[0].split('-') | ||
| 14 | + const end = timearea[1].split('-') | ||
| 15 | + if (start.length !== 3 || end.length !== 3) { | ||
| 16 | + logger.warn('enableArea() 参数格式为: ["2018-2-1", "2018-3-1"]') | ||
| 17 | + return {} | ||
| 18 | + } | ||
| 19 | + const startTimestamp = dateUtil | ||
| 20 | + .newDate(start[0], start[1], start[2]) | ||
| 21 | + .getTime() | ||
| 22 | + const endTimestamp = dateUtil.newDate(end[0], end[1], end[2]).getTime() | ||
| 23 | + return { | ||
| 24 | + start, | ||
| 25 | + end, | ||
| 26 | + startTimestamp, | ||
| 27 | + endTimestamp | ||
| 28 | + } | ||
| 29 | +} | ||
| 30 | + | ||
| 31 | +function isValiditeOfDateArea(dateArea) { | ||
| 32 | + const { | ||
| 33 | + start, | ||
| 34 | + end, | ||
| 35 | + startTimestamp, | ||
| 36 | + endTimestamp | ||
| 37 | + } = convertEnableAreaToTimestamp(dateArea) | ||
| 38 | + if (!start || !end) return | ||
| 39 | + const datesCountOfStart = dateUtil.getDatesCountOfMonth(start[0], start[1]) | ||
| 40 | + const datesCountOfEnd = dateUtil.getDatesCountOfMonth(end[0], end[1]) | ||
| 41 | + if (start[2] > datesCountOfStart || start[2] < 1) { | ||
| 42 | + logger.warn('enableArea() 开始日期错误,指定日期不在指定月份天数范围内') | ||
| 43 | + return false | ||
| 44 | + } else if (start[1] > 12 || start[1] < 1) { | ||
| 45 | + logger.warn('enableArea() 开始日期错误,月份超出1-12月份') | ||
| 46 | + return false | ||
| 47 | + } else if (end[2] > datesCountOfEnd || end[2] < 1) { | ||
| 48 | + logger.warn('enableArea() 截止日期错误,指定日期不在指定月份天数范围内') | ||
| 49 | + return false | ||
| 50 | + } else if (end[1] > 12 || end[1] < 1) { | ||
| 51 | + logger.warn('enableArea() 截止日期错误,月份超出1-12月份') | ||
| 52 | + return false | ||
| 53 | + } else if (startTimestamp > endTimestamp) { | ||
| 54 | + logger.warn('enableArea()参数最小日期大于了最大日期') | ||
| 55 | + return false | ||
| 56 | + } else { | ||
| 57 | + return true | ||
| 58 | + } | ||
| 59 | +} | ||
| 60 | + | ||
| 61 | +function handleDisableMode(calendarConfig) { | ||
| 62 | + const { disableMode } = calendarConfig | ||
| 63 | + if (!disableMode) return {} | ||
| 64 | + const disableBound = | ||
| 65 | + dateUtil.getTimeStamp(disableMode.date) || dateUtil.todayTimestamp() | ||
| 66 | + return { | ||
| 67 | + disableBound, | ||
| 68 | + disableType: disableMode.type | ||
| 69 | + } | ||
| 70 | +} | ||
| 71 | + | ||
| 72 | +function disabledByConfig(dateInfo, currentDate, calendarConfig) { | ||
| 73 | + const date = { ...dateInfo } | ||
| 74 | + const { disableType, disableBound } = handleDisableMode(calendarConfig) | ||
| 75 | + if ( | ||
| 76 | + (disableType === 'before' && disableBound && currentDate < disableBound) || | ||
| 77 | + (disableType === 'after' && disableBound && currentDate > disableBound) | ||
| 78 | + ) { | ||
| 79 | + date.disable = true | ||
| 80 | + } else { | ||
| 81 | + date.disable = false | ||
| 82 | + } | ||
| 83 | + return date | ||
| 84 | +} | ||
| 85 | + | ||
| 86 | +export default () => { | ||
| 87 | + return { | ||
| 88 | + name: 'enable', | ||
| 89 | + beforeRender(calendarData = {}, calendarConfig = {}) { | ||
| 90 | + const { | ||
| 91 | + dates, | ||
| 92 | + enableArea, | ||
| 93 | + enableDates, | ||
| 94 | + disableDates, | ||
| 95 | + renderCausedBy | ||
| 96 | + } = calendarData | ||
| 97 | + const _dates = [...dates].map(date => { | ||
| 98 | + let item = { ...date } | ||
| 99 | + const timeStr = dateUtil.toTimeStr(date) | ||
| 100 | + const timestamp = +dateUtil.getTimeStamp(item) | ||
| 101 | + if (renderCausedBy === 'enableDates') { | ||
| 102 | + if (enableDates && enableDates.length) { | ||
| 103 | + if (enableDates.includes(timeStr)) { | ||
| 104 | + item.disable = false | ||
| 105 | + } else { | ||
| 106 | + item.disable = true | ||
| 107 | + } | ||
| 108 | + return item | ||
| 109 | + } | ||
| 110 | + } else if (renderCausedBy === 'enableArea') { | ||
| 111 | + if (enableArea && enableArea.length) { | ||
| 112 | + const [startTimestamp, endTimestamp] = enableArea || [] | ||
| 113 | + const ifOutofArea = | ||
| 114 | + +startTimestamp > timestamp || timestamp > +endTimestamp | ||
| 115 | + item.disable = ifOutofArea | ||
| 116 | + return item | ||
| 117 | + } | ||
| 118 | + } else if (renderCausedBy === 'disableDates') { | ||
| 119 | + if (disableDates && disableDates.length) { | ||
| 120 | + if (disableDates && disableDates.includes(timeStr)) { | ||
| 121 | + item.disable = true | ||
| 122 | + } | ||
| 123 | + return item | ||
| 124 | + } | ||
| 125 | + } | ||
| 126 | + return disabledByConfig(item, timestamp, calendarConfig) | ||
| 127 | + }) | ||
| 128 | + | ||
| 129 | + return { | ||
| 130 | + calendarData: { | ||
| 131 | + ...calendarData, | ||
| 132 | + dates: _dates | ||
| 133 | + }, | ||
| 134 | + calendarConfig | ||
| 135 | + } | ||
| 136 | + }, | ||
| 137 | + methods(component) { | ||
| 138 | + return { | ||
| 139 | + enableArea: (dateArea = []) => { | ||
| 140 | + if (dateArea.length === 2) { | ||
| 141 | + const validate = isValiditeOfDateArea(dateArea) | ||
| 142 | + if (validate) { | ||
| 143 | + const existCalendarData = getCalendarData('calendar', component) | ||
| 144 | + const { | ||
| 145 | + startTimestamp, | ||
| 146 | + endTimestamp | ||
| 147 | + } = convertEnableAreaToTimestamp(dateArea) | ||
| 148 | + | ||
| 149 | + return renderCalendar.call(component, { | ||
| 150 | + ...existCalendarData, | ||
| 151 | + renderCausedBy: 'enableArea', | ||
| 152 | + enableArea: [startTimestamp, endTimestamp] | ||
| 153 | + }) | ||
| 154 | + } | ||
| 155 | + } else { | ||
| 156 | + return Promise.inject( | ||
| 157 | + 'enableArea()参数需为时间范围数组,形如:["2018-8-4" , "2018-8-24"]' | ||
| 158 | + ) | ||
| 159 | + } | ||
| 160 | + }, | ||
| 161 | + enableDates: (toSet = []) => { | ||
| 162 | + if (!toSet.length) return | ||
| 163 | + const existCalendarData = getCalendarData('calendar', component) | ||
| 164 | + const { enableDates = [] } = existCalendarData || {} | ||
| 165 | + let toSetDates = toSet.map(item => { | ||
| 166 | + if (typeof item === 'string') { | ||
| 167 | + return dateUtil.transformDateRow2Dict(item) | ||
| 168 | + } | ||
| 169 | + return item | ||
| 170 | + }) | ||
| 171 | + if (enableDates.length) { | ||
| 172 | + toSetDates = dateUtil.uniqueArrayByDate([ | ||
| 173 | + ...toSetDates, | ||
| 174 | + ...enableDates.map(d => dateUtil.transformDateRow2Dict(d)) | ||
| 175 | + ]) | ||
| 176 | + } | ||
| 177 | + return renderCalendar.call(component, { | ||
| 178 | + ...existCalendarData, | ||
| 179 | + renderCausedBy: 'enableDates', | ||
| 180 | + enableDates: toSetDates.map(date => { | ||
| 181 | + if (typeof date !== 'string') { | ||
| 182 | + return dateUtil.toTimeStr(date) | ||
| 183 | + } | ||
| 184 | + return date | ||
| 185 | + }) | ||
| 186 | + }) | ||
| 187 | + }, | ||
| 188 | + disableDates: toSet => { | ||
| 189 | + const existCalendarData = getCalendarData('calendar', component) | ||
| 190 | + const { disableDates = [], dates = [] } = existCalendarData || {} | ||
| 191 | + let toSetDates = toSet.map(item => { | ||
| 192 | + let date = { ...item } | ||
| 193 | + if (typeof date === 'string') { | ||
| 194 | + return dateUtil.transformDateRow2Dict(item) | ||
| 195 | + } | ||
| 196 | + return item | ||
| 197 | + }) | ||
| 198 | + if (disableDates && disableDates.length) { | ||
| 199 | + toSetDates = dateUtil.uniqueArrayByDate([ | ||
| 200 | + ...toSetDates, | ||
| 201 | + ...disableDates.map(d => dateUtil.transformDateRow2Dict(d)) | ||
| 202 | + ]) | ||
| 203 | + } | ||
| 204 | + return renderCalendar.call(component, { | ||
| 205 | + ...existCalendarData, | ||
| 206 | + renderCausedBy: 'disableDates', | ||
| 207 | + dates, | ||
| 208 | + disableDates: toSetDates.map(date => { | ||
| 209 | + if (typeof date !== 'string') { | ||
| 210 | + return dateUtil.toTimeStr(date) | ||
| 211 | + } | ||
| 212 | + return date | ||
| 213 | + }) | ||
| 214 | + }) | ||
| 215 | + } | ||
| 216 | + } | ||
| 217 | + } | ||
| 218 | + } | ||
| 219 | +} |
| @@ -0,0 +1,1036 @@ | @@ -0,0 +1,1036 @@ | ||
| 1 | +/** | ||
| 2 | + * @1900-2100区间内的公历、农历互转 | ||
| 3 | + * @Version 1.0.3 | ||
| 4 | + * @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0] | ||
| 5 | + * @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0] | ||
| 6 | + */ | ||
| 7 | +/* 公历年月日转农历数据 返回json */ | ||
| 8 | +// calendar.solar2lunar(1987,11,01); | ||
| 9 | +/** 农历年月日转公历年月日 **/ | ||
| 10 | +// calendar.lunar2solar(1987,9,10); | ||
| 11 | +// 调用以上方法后返回类似如下object(json)具体以上就不需要解释了吧! | ||
| 12 | +// c开头的是公历各属性值 l开头的自然就是农历咯 gz开头的就是天干地支纪年的数据啦~ | ||
| 13 | +// { | ||
| 14 | +// Animal: "兔", | ||
| 15 | +// IDayCn: "初十", | ||
| 16 | +// IMonthCn: "九月", | ||
| 17 | +// Term: null, | ||
| 18 | +// astro: "天蝎座", | ||
| 19 | +// cDay: 1, | ||
| 20 | +// cMonth: 11, | ||
| 21 | +// cYear: 1987, | ||
| 22 | +// gzDay: "甲寅", | ||
| 23 | +// gzMonth: "庚戌", | ||
| 24 | +// gzYear: "丁卯", | ||
| 25 | +// isLeap: false, | ||
| 26 | +// isTerm: false, | ||
| 27 | +// isToday: false, | ||
| 28 | +// lDay: 10, | ||
| 29 | +// lMonth: 9, | ||
| 30 | +// lYear: 1987, | ||
| 31 | +// nWeek: 7, | ||
| 32 | +// ncWeek: "星期日" | ||
| 33 | +// } | ||
| 34 | +// 该代码还有其他可以调用的方法,请自己查看代码中的详细注释 | ||
| 35 | +const calendar = { | ||
| 36 | + /** | ||
| 37 | + * 农历1900-2100的润大小信息表 | ||
| 38 | + * @Array Of Property | ||
| 39 | + * @return Hex | ||
| 40 | + */ | ||
| 41 | + lunarInfo: [ | ||
| 42 | + 0x04bd8, | ||
| 43 | + 0x04ae0, | ||
| 44 | + 0x0a570, | ||
| 45 | + 0x054d5, | ||
| 46 | + 0x0d260, | ||
| 47 | + 0x0d950, | ||
| 48 | + 0x16554, | ||
| 49 | + 0x056a0, | ||
| 50 | + 0x09ad0, | ||
| 51 | + 0x055d2, // 1900-1909 | ||
| 52 | + 0x04ae0, | ||
| 53 | + 0x0a5b6, | ||
| 54 | + 0x0a4d0, | ||
| 55 | + 0x0d250, | ||
| 56 | + 0x1d255, | ||
| 57 | + 0x0b540, | ||
| 58 | + 0x0d6a0, | ||
| 59 | + 0x0ada2, | ||
| 60 | + 0x095b0, | ||
| 61 | + 0x14977, // 1910-1919 | ||
| 62 | + 0x04970, | ||
| 63 | + 0x0a4b0, | ||
| 64 | + 0x0b4b5, | ||
| 65 | + 0x06a50, | ||
| 66 | + 0x06d40, | ||
| 67 | + 0x1ab54, | ||
| 68 | + 0x02b60, | ||
| 69 | + 0x09570, | ||
| 70 | + 0x052f2, | ||
| 71 | + 0x04970, // 1920-1929 | ||
| 72 | + 0x06566, | ||
| 73 | + 0x0d4a0, | ||
| 74 | + 0x0ea50, | ||
| 75 | + 0x06e95, | ||
| 76 | + 0x05ad0, | ||
| 77 | + 0x02b60, | ||
| 78 | + 0x186e3, | ||
| 79 | + 0x092e0, | ||
| 80 | + 0x1c8d7, | ||
| 81 | + 0x0c950, // 1930-1939 | ||
| 82 | + 0x0d4a0, | ||
| 83 | + 0x1d8a6, | ||
| 84 | + 0x0b550, | ||
| 85 | + 0x056a0, | ||
| 86 | + 0x1a5b4, | ||
| 87 | + 0x025d0, | ||
| 88 | + 0x092d0, | ||
| 89 | + 0x0d2b2, | ||
| 90 | + 0x0a950, | ||
| 91 | + 0x0b557, // 1940-1949 | ||
| 92 | + 0x06ca0, | ||
| 93 | + 0x0b550, | ||
| 94 | + 0x15355, | ||
| 95 | + 0x04da0, | ||
| 96 | + 0x0a5b0, | ||
| 97 | + 0x14573, | ||
| 98 | + 0x052b0, | ||
| 99 | + 0x0a9a8, | ||
| 100 | + 0x0e950, | ||
| 101 | + 0x06aa0, // 1950-1959 | ||
| 102 | + 0x0aea6, | ||
| 103 | + 0x0ab50, | ||
| 104 | + 0x04b60, | ||
| 105 | + 0x0aae4, | ||
| 106 | + 0x0a570, | ||
| 107 | + 0x05260, | ||
| 108 | + 0x0f263, | ||
| 109 | + 0x0d950, | ||
| 110 | + 0x05b57, | ||
| 111 | + 0x056a0, // 1960-1969 | ||
| 112 | + 0x096d0, | ||
| 113 | + 0x04dd5, | ||
| 114 | + 0x04ad0, | ||
| 115 | + 0x0a4d0, | ||
| 116 | + 0x0d4d4, | ||
| 117 | + 0x0d250, | ||
| 118 | + 0x0d558, | ||
| 119 | + 0x0b540, | ||
| 120 | + 0x0b6a0, | ||
| 121 | + 0x195a6, // 1970-1979 | ||
| 122 | + 0x095b0, | ||
| 123 | + 0x049b0, | ||
| 124 | + 0x0a974, | ||
| 125 | + 0x0a4b0, | ||
| 126 | + 0x0b27a, | ||
| 127 | + 0x06a50, | ||
| 128 | + 0x06d40, | ||
| 129 | + 0x0af46, | ||
| 130 | + 0x0ab60, | ||
| 131 | + 0x09570, // 1980-1989 | ||
| 132 | + 0x04af5, | ||
| 133 | + 0x04970, | ||
| 134 | + 0x064b0, | ||
| 135 | + 0x074a3, | ||
| 136 | + 0x0ea50, | ||
| 137 | + 0x06b58, | ||
| 138 | + 0x055c0, | ||
| 139 | + 0x0ab60, | ||
| 140 | + 0x096d5, | ||
| 141 | + 0x092e0, // 1990-1999 | ||
| 142 | + 0x0c960, | ||
| 143 | + 0x0d954, | ||
| 144 | + 0x0d4a0, | ||
| 145 | + 0x0da50, | ||
| 146 | + 0x07552, | ||
| 147 | + 0x056a0, | ||
| 148 | + 0x0abb7, | ||
| 149 | + 0x025d0, | ||
| 150 | + 0x092d0, | ||
| 151 | + 0x0cab5, // 2000-2009 | ||
| 152 | + 0x0a950, | ||
| 153 | + 0x0b4a0, | ||
| 154 | + 0x0baa4, | ||
| 155 | + 0x0ad50, | ||
| 156 | + 0x055d9, | ||
| 157 | + 0x04ba0, | ||
| 158 | + 0x0a5b0, | ||
| 159 | + 0x15176, | ||
| 160 | + 0x052b0, | ||
| 161 | + 0x0a930, // 2010-2019 | ||
| 162 | + 0x07954, | ||
| 163 | + 0x06aa0, | ||
| 164 | + 0x0ad50, | ||
| 165 | + 0x05b52, | ||
| 166 | + 0x04b60, | ||
| 167 | + 0x0a6e6, | ||
| 168 | + 0x0a4e0, | ||
| 169 | + 0x0d260, | ||
| 170 | + 0x0ea65, | ||
| 171 | + 0x0d530, // 2020-2029 | ||
| 172 | + 0x05aa0, | ||
| 173 | + 0x076a3, | ||
| 174 | + 0x096d0, | ||
| 175 | + 0x04afb, | ||
| 176 | + 0x04ad0, | ||
| 177 | + 0x0a4d0, | ||
| 178 | + 0x1d0b6, | ||
| 179 | + 0x0d250, | ||
| 180 | + 0x0d520, | ||
| 181 | + 0x0dd45, // 2030-2039 | ||
| 182 | + 0x0b5a0, | ||
| 183 | + 0x056d0, | ||
| 184 | + 0x055b2, | ||
| 185 | + 0x049b0, | ||
| 186 | + 0x0a577, | ||
| 187 | + 0x0a4b0, | ||
| 188 | + 0x0aa50, | ||
| 189 | + 0x1b255, | ||
| 190 | + 0x06d20, | ||
| 191 | + 0x0ada0, // 2040-2049 | ||
| 192 | + /** Add By JJonline@JJonline.Cn **/ | ||
| 193 | + 0x14b63, | ||
| 194 | + 0x09370, | ||
| 195 | + 0x049f8, | ||
| 196 | + 0x04970, | ||
| 197 | + 0x064b0, | ||
| 198 | + 0x168a6, | ||
| 199 | + 0x0ea50, | ||
| 200 | + 0x06b20, | ||
| 201 | + 0x1a6c4, | ||
| 202 | + 0x0aae0, // 2050-2059 | ||
| 203 | + 0x0a2e0, | ||
| 204 | + 0x0d2e3, | ||
| 205 | + 0x0c960, | ||
| 206 | + 0x0d557, | ||
| 207 | + 0x0d4a0, | ||
| 208 | + 0x0da50, | ||
| 209 | + 0x05d55, | ||
| 210 | + 0x056a0, | ||
| 211 | + 0x0a6d0, | ||
| 212 | + 0x055d4, // 2060-2069 | ||
| 213 | + 0x052d0, | ||
| 214 | + 0x0a9b8, | ||
| 215 | + 0x0a950, | ||
| 216 | + 0x0b4a0, | ||
| 217 | + 0x0b6a6, | ||
| 218 | + 0x0ad50, | ||
| 219 | + 0x055a0, | ||
| 220 | + 0x0aba4, | ||
| 221 | + 0x0a5b0, | ||
| 222 | + 0x052b0, // 2070-2079 | ||
| 223 | + 0x0b273, | ||
| 224 | + 0x06930, | ||
| 225 | + 0x07337, | ||
| 226 | + 0x06aa0, | ||
| 227 | + 0x0ad50, | ||
| 228 | + 0x14b55, | ||
| 229 | + 0x04b60, | ||
| 230 | + 0x0a570, | ||
| 231 | + 0x054e4, | ||
| 232 | + 0x0d160, // 2080-2089 | ||
| 233 | + 0x0e968, | ||
| 234 | + 0x0d520, | ||
| 235 | + 0x0daa0, | ||
| 236 | + 0x16aa6, | ||
| 237 | + 0x056d0, | ||
| 238 | + 0x04ae0, | ||
| 239 | + 0x0a9d4, | ||
| 240 | + 0x0a2d0, | ||
| 241 | + 0x0d150, | ||
| 242 | + 0x0f252, // 2090-2099 | ||
| 243 | + 0x0d520 | ||
| 244 | + ], // 2100 | ||
| 245 | + | ||
| 246 | + /** | ||
| 247 | + * 公历每个月份的天数普通表 | ||
| 248 | + * @Array Of Property | ||
| 249 | + * @return Number | ||
| 250 | + */ | ||
| 251 | + solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], | ||
| 252 | + | ||
| 253 | + /** | ||
| 254 | + * 天干地支之天干速查表 | ||
| 255 | + * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"] | ||
| 256 | + * @return Cn string | ||
| 257 | + */ | ||
| 258 | + Gan: [ | ||
| 259 | + '\u7532', | ||
| 260 | + '\u4e59', | ||
| 261 | + '\u4e19', | ||
| 262 | + '\u4e01', | ||
| 263 | + '\u620a', | ||
| 264 | + '\u5df1', | ||
| 265 | + '\u5e9a', | ||
| 266 | + '\u8f9b', | ||
| 267 | + '\u58ec', | ||
| 268 | + '\u7678' | ||
| 269 | + ], | ||
| 270 | + | ||
| 271 | + /** | ||
| 272 | + * 天干地支之地支速查表 | ||
| 273 | + * @Array Of Property | ||
| 274 | + * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"] | ||
| 275 | + * @return Cn string | ||
| 276 | + */ | ||
| 277 | + Zhi: [ | ||
| 278 | + '\u5b50', | ||
| 279 | + '\u4e11', | ||
| 280 | + '\u5bc5', | ||
| 281 | + '\u536f', | ||
| 282 | + '\u8fb0', | ||
| 283 | + '\u5df3', | ||
| 284 | + '\u5348', | ||
| 285 | + '\u672a', | ||
| 286 | + '\u7533', | ||
| 287 | + '\u9149', | ||
| 288 | + '\u620c', | ||
| 289 | + '\u4ea5' | ||
| 290 | + ], | ||
| 291 | + | ||
| 292 | + /** | ||
| 293 | + * 天干地支之地支速查表<=>生肖 | ||
| 294 | + * @Array Of Property | ||
| 295 | + * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"] | ||
| 296 | + * @return Cn string | ||
| 297 | + */ | ||
| 298 | + Animals: [ | ||
| 299 | + '\u9f20', | ||
| 300 | + '\u725b', | ||
| 301 | + '\u864e', | ||
| 302 | + '\u5154', | ||
| 303 | + '\u9f99', | ||
| 304 | + '\u86c7', | ||
| 305 | + '\u9a6c', | ||
| 306 | + '\u7f8a', | ||
| 307 | + '\u7334', | ||
| 308 | + '\u9e21', | ||
| 309 | + '\u72d7', | ||
| 310 | + '\u732a' | ||
| 311 | + ], | ||
| 312 | + | ||
| 313 | + /** | ||
| 314 | + * 24节气速查表 | ||
| 315 | + * @Array Of Property | ||
| 316 | + * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"] | ||
| 317 | + * @return Cn string | ||
| 318 | + */ | ||
| 319 | + solarTerm: [ | ||
| 320 | + '\u5c0f\u5bd2', | ||
| 321 | + '\u5927\u5bd2', | ||
| 322 | + '\u7acb\u6625', | ||
| 323 | + '\u96e8\u6c34', | ||
| 324 | + '\u60ca\u86f0', | ||
| 325 | + '\u6625\u5206', | ||
| 326 | + '\u6e05\u660e', | ||
| 327 | + '\u8c37\u96e8', | ||
| 328 | + '\u7acb\u590f', | ||
| 329 | + '\u5c0f\u6ee1', | ||
| 330 | + '\u8292\u79cd', | ||
| 331 | + '\u590f\u81f3', | ||
| 332 | + '\u5c0f\u6691', | ||
| 333 | + '\u5927\u6691', | ||
| 334 | + '\u7acb\u79cb', | ||
| 335 | + '\u5904\u6691', | ||
| 336 | + '\u767d\u9732', | ||
| 337 | + '\u79cb\u5206', | ||
| 338 | + '\u5bd2\u9732', | ||
| 339 | + '\u971c\u964d', | ||
| 340 | + '\u7acb\u51ac', | ||
| 341 | + '\u5c0f\u96ea', | ||
| 342 | + '\u5927\u96ea', | ||
| 343 | + '\u51ac\u81f3' | ||
| 344 | + ], | ||
| 345 | + | ||
| 346 | + /** | ||
| 347 | + * 1900-2100各年的24节气日期速查表 | ||
| 348 | + * @Array Of Property | ||
| 349 | + * @return 0x string For splice | ||
| 350 | + */ | ||
| 351 | + sTermInfo: [ | ||
| 352 | + '9778397bd097c36b0b6fc9274c91aa', | ||
| 353 | + '97b6b97bd19801ec9210c965cc920e', | ||
| 354 | + '97bcf97c3598082c95f8c965cc920f', | ||
| 355 | + '97bd0b06bdb0722c965ce1cfcc920f', | ||
| 356 | + 'b027097bd097c36b0b6fc9274c91aa', | ||
| 357 | + '97b6b97bd19801ec9210c965cc920e', | ||
| 358 | + '97bcf97c359801ec95f8c965cc920f', | ||
| 359 | + '97bd0b06bdb0722c965ce1cfcc920f', | ||
| 360 | + 'b027097bd097c36b0b6fc9274c91aa', | ||
| 361 | + '97b6b97bd19801ec9210c965cc920e', | ||
| 362 | + '97bcf97c359801ec95f8c965cc920f', | ||
| 363 | + '97bd0b06bdb0722c965ce1cfcc920f', | ||
| 364 | + 'b027097bd097c36b0b6fc9274c91aa', | ||
| 365 | + '9778397bd19801ec9210c965cc920e', | ||
| 366 | + '97b6b97bd19801ec95f8c965cc920f', | ||
| 367 | + '97bd09801d98082c95f8e1cfcc920f', | ||
| 368 | + '97bd097bd097c36b0b6fc9210c8dc2', | ||
| 369 | + '9778397bd197c36c9210c9274c91aa', | ||
| 370 | + '97b6b97bd19801ec95f8c965cc920e', | ||
| 371 | + '97bd09801d98082c95f8e1cfcc920f', | ||
| 372 | + '97bd097bd097c36b0b6fc9210c8dc2', | ||
| 373 | + '9778397bd097c36c9210c9274c91aa', | ||
| 374 | + '97b6b97bd19801ec95f8c965cc920e', | ||
| 375 | + '97bcf97c3598082c95f8e1cfcc920f', | ||
| 376 | + '97bd097bd097c36b0b6fc9210c8dc2', | ||
| 377 | + '9778397bd097c36c9210c9274c91aa', | ||
| 378 | + '97b6b97bd19801ec9210c965cc920e', | ||
| 379 | + '97bcf97c3598082c95f8c965cc920f', | ||
| 380 | + '97bd097bd097c35b0b6fc920fb0722', | ||
| 381 | + '9778397bd097c36b0b6fc9274c91aa', | ||
| 382 | + '97b6b97bd19801ec9210c965cc920e', | ||
| 383 | + '97bcf97c3598082c95f8c965cc920f', | ||
| 384 | + '97bd097bd097c35b0b6fc920fb0722', | ||
| 385 | + '9778397bd097c36b0b6fc9274c91aa', | ||
| 386 | + '97b6b97bd19801ec9210c965cc920e', | ||
| 387 | + '97bcf97c359801ec95f8c965cc920f', | ||
| 388 | + '97bd097bd097c35b0b6fc920fb0722', | ||
| 389 | + '9778397bd097c36b0b6fc9274c91aa', | ||
| 390 | + '97b6b97bd19801ec9210c965cc920e', | ||
| 391 | + '97bcf97c359801ec95f8c965cc920f', | ||
| 392 | + '97bd097bd097c35b0b6fc920fb0722', | ||
| 393 | + '9778397bd097c36b0b6fc9274c91aa', | ||
| 394 | + '97b6b97bd19801ec9210c965cc920e', | ||
| 395 | + '97bcf97c359801ec95f8c965cc920f', | ||
| 396 | + '97bd097bd07f595b0b6fc920fb0722', | ||
| 397 | + '9778397bd097c36b0b6fc9210c8dc2', | ||
| 398 | + '9778397bd19801ec9210c9274c920e', | ||
| 399 | + '97b6b97bd19801ec95f8c965cc920f', | ||
| 400 | + '97bd07f5307f595b0b0bc920fb0722', | ||
| 401 | + '7f0e397bd097c36b0b6fc9210c8dc2', | ||
| 402 | + '9778397bd097c36c9210c9274c920e', | ||
| 403 | + '97b6b97bd19801ec95f8c965cc920f', | ||
| 404 | + '97bd07f5307f595b0b0bc920fb0722', | ||
| 405 | + '7f0e397bd097c36b0b6fc9210c8dc2', | ||
| 406 | + '9778397bd097c36c9210c9274c91aa', | ||
| 407 | + '97b6b97bd19801ec9210c965cc920e', | ||
| 408 | + '97bd07f1487f595b0b0bc920fb0722', | ||
| 409 | + '7f0e397bd097c36b0b6fc9210c8dc2', | ||
| 410 | + '9778397bd097c36b0b6fc9274c91aa', | ||
| 411 | + '97b6b97bd19801ec9210c965cc920e', | ||
| 412 | + '97bcf7f1487f595b0b0bb0b6fb0722', | ||
| 413 | + '7f0e397bd097c35b0b6fc920fb0722', | ||
| 414 | + '9778397bd097c36b0b6fc9274c91aa', | ||
| 415 | + '97b6b97bd19801ec9210c965cc920e', | ||
| 416 | + '97bcf7f1487f595b0b0bb0b6fb0722', | ||
| 417 | + '7f0e397bd097c35b0b6fc920fb0722', | ||
| 418 | + '9778397bd097c36b0b6fc9274c91aa', | ||
| 419 | + '97b6b97bd19801ec9210c965cc920e', | ||
| 420 | + '97bcf7f1487f531b0b0bb0b6fb0722', | ||
| 421 | + '7f0e397bd097c35b0b6fc920fb0722', | ||
| 422 | + '9778397bd097c36b0b6fc9274c91aa', | ||
| 423 | + '97b6b97bd19801ec9210c965cc920e', | ||
| 424 | + '97bcf7f1487f531b0b0bb0b6fb0722', | ||
| 425 | + '7f0e397bd07f595b0b6fc920fb0722', | ||
| 426 | + '9778397bd097c36b0b6fc9274c91aa', | ||
| 427 | + '97b6b97bd19801ec9210c9274c920e', | ||
| 428 | + '97bcf7f0e47f531b0b0bb0b6fb0722', | ||
| 429 | + '7f0e397bd07f595b0b0bc920fb0722', | ||
| 430 | + '9778397bd097c36b0b6fc9210c91aa', | ||
| 431 | + '97b6b97bd197c36c9210c9274c920e', | ||
| 432 | + '97bcf7f0e47f531b0b0bb0b6fb0722', | ||
| 433 | + '7f0e397bd07f595b0b0bc920fb0722', | ||
| 434 | + '9778397bd097c36b0b6fc9210c8dc2', | ||
| 435 | + '9778397bd097c36c9210c9274c920e', | ||
| 436 | + '97b6b7f0e47f531b0723b0b6fb0722', | ||
| 437 | + '7f0e37f5307f595b0b0bc920fb0722', | ||
| 438 | + '7f0e397bd097c36b0b6fc9210c8dc2', | ||
| 439 | + '9778397bd097c36b0b70c9274c91aa', | ||
| 440 | + '97b6b7f0e47f531b0723b0b6fb0721', | ||
| 441 | + '7f0e37f1487f595b0b0bb0b6fb0722', | ||
| 442 | + '7f0e397bd097c35b0b6fc9210c8dc2', | ||
| 443 | + '9778397bd097c36b0b6fc9274c91aa', | ||
| 444 | + '97b6b7f0e47f531b0723b0b6fb0721', | ||
| 445 | + '7f0e27f1487f595b0b0bb0b6fb0722', | ||
| 446 | + '7f0e397bd097c35b0b6fc920fb0722', | ||
| 447 | + '9778397bd097c36b0b6fc9274c91aa', | ||
| 448 | + '97b6b7f0e47f531b0723b0b6fb0721', | ||
| 449 | + '7f0e27f1487f531b0b0bb0b6fb0722', | ||
| 450 | + '7f0e397bd097c35b0b6fc920fb0722', | ||
| 451 | + '9778397bd097c36b0b6fc9274c91aa', | ||
| 452 | + '97b6b7f0e47f531b0723b0b6fb0721', | ||
| 453 | + '7f0e27f1487f531b0b0bb0b6fb0722', | ||
| 454 | + '7f0e397bd097c35b0b6fc920fb0722', | ||
| 455 | + '9778397bd097c36b0b6fc9274c91aa', | ||
| 456 | + '97b6b7f0e47f531b0723b0b6fb0721', | ||
| 457 | + '7f0e27f1487f531b0b0bb0b6fb0722', | ||
| 458 | + '7f0e397bd07f595b0b0bc920fb0722', | ||
| 459 | + '9778397bd097c36b0b6fc9274c91aa', | ||
| 460 | + '97b6b7f0e47f531b0723b0787b0721', | ||
| 461 | + '7f0e27f0e47f531b0b0bb0b6fb0722', | ||
| 462 | + '7f0e397bd07f595b0b0bc920fb0722', | ||
| 463 | + '9778397bd097c36b0b6fc9210c91aa', | ||
| 464 | + '97b6b7f0e47f149b0723b0787b0721', | ||
| 465 | + '7f0e27f0e47f531b0723b0b6fb0722', | ||
| 466 | + '7f0e397bd07f595b0b0bc920fb0722', | ||
| 467 | + '9778397bd097c36b0b6fc9210c8dc2', | ||
| 468 | + '977837f0e37f149b0723b0787b0721', | ||
| 469 | + '7f07e7f0e47f531b0723b0b6fb0722', | ||
| 470 | + '7f0e37f5307f595b0b0bc920fb0722', | ||
| 471 | + '7f0e397bd097c35b0b6fc9210c8dc2', | ||
| 472 | + '977837f0e37f14998082b0787b0721', | ||
| 473 | + '7f07e7f0e47f531b0723b0b6fb0721', | ||
| 474 | + '7f0e37f1487f595b0b0bb0b6fb0722', | ||
| 475 | + '7f0e397bd097c35b0b6fc9210c8dc2', | ||
| 476 | + '977837f0e37f14998082b0787b06bd', | ||
| 477 | + '7f07e7f0e47f531b0723b0b6fb0721', | ||
| 478 | + '7f0e27f1487f531b0b0bb0b6fb0722', | ||
| 479 | + '7f0e397bd097c35b0b6fc920fb0722', | ||
| 480 | + '977837f0e37f14998082b0787b06bd', | ||
| 481 | + '7f07e7f0e47f531b0723b0b6fb0721', | ||
| 482 | + '7f0e27f1487f531b0b0bb0b6fb0722', | ||
| 483 | + '7f0e397bd097c35b0b6fc920fb0722', | ||
| 484 | + '977837f0e37f14998082b0787b06bd', | ||
| 485 | + '7f07e7f0e47f531b0723b0b6fb0721', | ||
| 486 | + '7f0e27f1487f531b0b0bb0b6fb0722', | ||
| 487 | + '7f0e397bd07f595b0b0bc920fb0722', | ||
| 488 | + '977837f0e37f14998082b0787b06bd', | ||
| 489 | + '7f07e7f0e47f531b0723b0b6fb0721', | ||
| 490 | + '7f0e27f1487f531b0b0bb0b6fb0722', | ||
| 491 | + '7f0e397bd07f595b0b0bc920fb0722', | ||
| 492 | + '977837f0e37f14998082b0787b06bd', | ||
| 493 | + '7f07e7f0e47f149b0723b0787b0721', | ||
| 494 | + '7f0e27f0e47f531b0b0bb0b6fb0722', | ||
| 495 | + '7f0e397bd07f595b0b0bc920fb0722', | ||
| 496 | + '977837f0e37f14998082b0723b06bd', | ||
| 497 | + '7f07e7f0e37f149b0723b0787b0721', | ||
| 498 | + '7f0e27f0e47f531b0723b0b6fb0722', | ||
| 499 | + '7f0e397bd07f595b0b0bc920fb0722', | ||
| 500 | + '977837f0e37f14898082b0723b02d5', | ||
| 501 | + '7ec967f0e37f14998082b0787b0721', | ||
| 502 | + '7f07e7f0e47f531b0723b0b6fb0722', | ||
| 503 | + '7f0e37f1487f595b0b0bb0b6fb0722', | ||
| 504 | + '7f0e37f0e37f14898082b0723b02d5', | ||
| 505 | + '7ec967f0e37f14998082b0787b0721', | ||
| 506 | + '7f07e7f0e47f531b0723b0b6fb0722', | ||
| 507 | + '7f0e37f1487f531b0b0bb0b6fb0722', | ||
| 508 | + '7f0e37f0e37f14898082b0723b02d5', | ||
| 509 | + '7ec967f0e37f14998082b0787b06bd', | ||
| 510 | + '7f07e7f0e47f531b0723b0b6fb0721', | ||
| 511 | + '7f0e37f1487f531b0b0bb0b6fb0722', | ||
| 512 | + '7f0e37f0e37f14898082b072297c35', | ||
| 513 | + '7ec967f0e37f14998082b0787b06bd', | ||
| 514 | + '7f07e7f0e47f531b0723b0b6fb0721', | ||
| 515 | + '7f0e27f1487f531b0b0bb0b6fb0722', | ||
| 516 | + '7f0e37f0e37f14898082b072297c35', | ||
| 517 | + '7ec967f0e37f14998082b0787b06bd', | ||
| 518 | + '7f07e7f0e47f531b0723b0b6fb0721', | ||
| 519 | + '7f0e27f1487f531b0b0bb0b6fb0722', | ||
| 520 | + '7f0e37f0e366aa89801eb072297c35', | ||
| 521 | + '7ec967f0e37f14998082b0787b06bd', | ||
| 522 | + '7f07e7f0e47f149b0723b0787b0721', | ||
| 523 | + '7f0e27f1487f531b0b0bb0b6fb0722', | ||
| 524 | + '7f0e37f0e366aa89801eb072297c35', | ||
| 525 | + '7ec967f0e37f14998082b0723b06bd', | ||
| 526 | + '7f07e7f0e47f149b0723b0787b0721', | ||
| 527 | + '7f0e27f0e47f531b0723b0b6fb0722', | ||
| 528 | + '7f0e37f0e366aa89801eb072297c35', | ||
| 529 | + '7ec967f0e37f14998082b0723b06bd', | ||
| 530 | + '7f07e7f0e37f14998083b0787b0721', | ||
| 531 | + '7f0e27f0e47f531b0723b0b6fb0722', | ||
| 532 | + '7f0e37f0e366aa89801eb072297c35', | ||
| 533 | + '7ec967f0e37f14898082b0723b02d5', | ||
| 534 | + '7f07e7f0e37f14998082b0787b0721', | ||
| 535 | + '7f07e7f0e47f531b0723b0b6fb0722', | ||
| 536 | + '7f0e36665b66aa89801e9808297c35', | ||
| 537 | + '665f67f0e37f14898082b0723b02d5', | ||
| 538 | + '7ec967f0e37f14998082b0787b0721', | ||
| 539 | + '7f07e7f0e47f531b0723b0b6fb0722', | ||
| 540 | + '7f0e36665b66a449801e9808297c35', | ||
| 541 | + '665f67f0e37f14898082b0723b02d5', | ||
| 542 | + '7ec967f0e37f14998082b0787b06bd', | ||
| 543 | + '7f07e7f0e47f531b0723b0b6fb0721', | ||
| 544 | + '7f0e36665b66a449801e9808297c35', | ||
| 545 | + '665f67f0e37f14898082b072297c35', | ||
| 546 | + '7ec967f0e37f14998082b0787b06bd', | ||
| 547 | + '7f07e7f0e47f531b0723b0b6fb0721', | ||
| 548 | + '7f0e26665b66a449801e9808297c35', | ||
| 549 | + '665f67f0e37f1489801eb072297c35', | ||
| 550 | + '7ec967f0e37f14998082b0787b06bd', | ||
| 551 | + '7f07e7f0e47f531b0723b0b6fb0721', | ||
| 552 | + '7f0e27f1487f531b0b0bb0b6fb0722' | ||
| 553 | + ], | ||
| 554 | + | ||
| 555 | + /** | ||
| 556 | + * 数字转中文速查表 | ||
| 557 | + * @Array Of Property | ||
| 558 | + * @trans ['日','一','二','三','四','五','六','七','八','九','十'] | ||
| 559 | + * @return Cn string | ||
| 560 | + */ | ||
| 561 | + nStr1: [ | ||
| 562 | + '\u65e5', | ||
| 563 | + '\u4e00', | ||
| 564 | + '\u4e8c', | ||
| 565 | + '\u4e09', | ||
| 566 | + '\u56db', | ||
| 567 | + '\u4e94', | ||
| 568 | + '\u516d', | ||
| 569 | + '\u4e03', | ||
| 570 | + '\u516b', | ||
| 571 | + '\u4e5d', | ||
| 572 | + '\u5341' | ||
| 573 | + ], | ||
| 574 | + | ||
| 575 | + /** | ||
| 576 | + * 日期转农历称呼速查表 | ||
| 577 | + * @Array Of Property | ||
| 578 | + * @trans ['初','十','廿','卅'] | ||
| 579 | + * @return Cn string | ||
| 580 | + */ | ||
| 581 | + nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'], | ||
| 582 | + | ||
| 583 | + /** | ||
| 584 | + * 月份转农历称呼速查表 | ||
| 585 | + * @Array Of Property | ||
| 586 | + * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊'] | ||
| 587 | + * @return Cn string | ||
| 588 | + */ | ||
| 589 | + nStr3: [ | ||
| 590 | + '\u6b63', | ||
| 591 | + '\u4e8c', | ||
| 592 | + '\u4e09', | ||
| 593 | + '\u56db', | ||
| 594 | + '\u4e94', | ||
| 595 | + '\u516d', | ||
| 596 | + '\u4e03', | ||
| 597 | + '\u516b', | ||
| 598 | + '\u4e5d', | ||
| 599 | + '\u5341', | ||
| 600 | + '\u51ac', | ||
| 601 | + '\u814a' | ||
| 602 | + ], | ||
| 603 | + | ||
| 604 | + /** | ||
| 605 | + * 返回农历y年一整年的总天数 | ||
| 606 | + * @param lunar Year | ||
| 607 | + * @return Number | ||
| 608 | + * @eg:var count = calendar.lYearDays(1987) ;//count=387 | ||
| 609 | + */ | ||
| 610 | + lYearDays: function(y) { | ||
| 611 | + let i | ||
| 612 | + let sum = 348 | ||
| 613 | + for (i = 0x8000; i > 0x8; i >>= 1) { | ||
| 614 | + sum += calendar.lunarInfo[y - 1900] & i ? 1 : 0 | ||
| 615 | + } | ||
| 616 | + return sum + calendar.leapDays(y) | ||
| 617 | + }, | ||
| 618 | + | ||
| 619 | + /** | ||
| 620 | + * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0 | ||
| 621 | + * @param lunar Year | ||
| 622 | + * @return Number (0-12) | ||
| 623 | + * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6 | ||
| 624 | + */ | ||
| 625 | + leapMonth: function(y) { | ||
| 626 | + // 闰字编码 \u95f0 | ||
| 627 | + return calendar.lunarInfo[y - 1900] & 0xf | ||
| 628 | + }, | ||
| 629 | + | ||
| 630 | + /** | ||
| 631 | + * 返回农历y年闰月的天数 若该年没有闰月则返回0 | ||
| 632 | + * @param lunar Year | ||
| 633 | + * @return Number (0、29、30) | ||
| 634 | + * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29 | ||
| 635 | + */ | ||
| 636 | + leapDays: function(y) { | ||
| 637 | + if (calendar.leapMonth(y)) { | ||
| 638 | + return calendar.lunarInfo[y - 1900] & 0x10000 ? 30 : 29 | ||
| 639 | + } | ||
| 640 | + return 0 | ||
| 641 | + }, | ||
| 642 | + | ||
| 643 | + /** | ||
| 644 | + * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法 | ||
| 645 | + * @param lunar Year | ||
| 646 | + * @return Number (-1、29、30) | ||
| 647 | + * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29 | ||
| 648 | + */ | ||
| 649 | + monthDays: function(y, m) { | ||
| 650 | + if (m > 12 || m < 1) return -1 // 月份参数从1至12,参数错误返回-1 | ||
| 651 | + return calendar.lunarInfo[y - 1900] & (0x10000 >> m) ? 30 : 29 | ||
| 652 | + }, | ||
| 653 | + | ||
| 654 | + /** | ||
| 655 | + * 返回公历(!)y年m月的天数 | ||
| 656 | + * @param solar Year | ||
| 657 | + * @return Number (-1、28、29、30、31) | ||
| 658 | + * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30 | ||
| 659 | + */ | ||
| 660 | + solarDays: function(y, m) { | ||
| 661 | + if (m > 12 || m < 1) return -1 // 若参数错误 返回-1 | ||
| 662 | + const ms = m - 1 | ||
| 663 | + if (+ms === 1) { | ||
| 664 | + // 2月份的闰平规律测算后确认返回28或29 | ||
| 665 | + return (y % 4 === 0 && y % 100 !== 0) || y % 400 === 0 ? 29 : 28 | ||
| 666 | + } else { | ||
| 667 | + return calendar.solarMonth[ms] | ||
| 668 | + } | ||
| 669 | + }, | ||
| 670 | + | ||
| 671 | + /** | ||
| 672 | + * 农历年份转换为干支纪年 | ||
| 673 | + * @param lYear 农历年的年份数 | ||
| 674 | + * @return Cn string | ||
| 675 | + */ | ||
| 676 | + toGanZhiYear: function(lYear) { | ||
| 677 | + let ganKey = (lYear - 3) % 10 | ||
| 678 | + let zhiKey = (lYear - 3) % 12 | ||
| 679 | + if (+ganKey === 0) ganKey = 10 // 如果余数为0则为最后一个天干 | ||
| 680 | + if (+zhiKey === 0) zhiKey = 12 // 如果余数为0则为最后一个地支 | ||
| 681 | + return calendar.Gan[ganKey - 1] + calendar.Zhi[zhiKey - 1] | ||
| 682 | + }, | ||
| 683 | + | ||
| 684 | + /** | ||
| 685 | + * 公历月、日判断所属星座 | ||
| 686 | + * @param cMonth [description] | ||
| 687 | + * @param cDay [description] | ||
| 688 | + * @return Cn string | ||
| 689 | + */ | ||
| 690 | + toAstro: function(cMonth, cDay) { | ||
| 691 | + const s = | ||
| 692 | + '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf' | ||
| 693 | + const arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22] | ||
| 694 | + return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7' // 座 | ||
| 695 | + }, | ||
| 696 | + | ||
| 697 | + /** | ||
| 698 | + * 传入offset偏移量返回干支 | ||
| 699 | + * @param offset 相对甲子的偏移量 | ||
| 700 | + * @return Cn string | ||
| 701 | + */ | ||
| 702 | + toGanZhi: function(offset) { | ||
| 703 | + return calendar.Gan[offset % 10] + calendar.Zhi[offset % 12] | ||
| 704 | + }, | ||
| 705 | + | ||
| 706 | + /** | ||
| 707 | + * 传入公历(!)y年获得该年第n个节气的公历日期 | ||
| 708 | + * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起 | ||
| 709 | + * @return day Number | ||
| 710 | + * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春 | ||
| 711 | + */ | ||
| 712 | + getTerm: function(y, n) { | ||
| 713 | + if (y < 1900 || y > 2100) return -1 | ||
| 714 | + if (n < 1 || n > 24) return -1 | ||
| 715 | + const _table = calendar.sTermInfo[y - 1900] | ||
| 716 | + const _info = [ | ||
| 717 | + parseInt('0x' + _table.substr(0, 5)).toString(), | ||
| 718 | + parseInt('0x' + _table.substr(5, 5)).toString(), | ||
| 719 | + parseInt('0x' + _table.substr(10, 5)).toString(), | ||
| 720 | + parseInt('0x' + _table.substr(15, 5)).toString(), | ||
| 721 | + parseInt('0x' + _table.substr(20, 5)).toString(), | ||
| 722 | + parseInt('0x' + _table.substr(25, 5)).toString() | ||
| 723 | + ] | ||
| 724 | + const _calday = [ | ||
| 725 | + _info[0].substr(0, 1), | ||
| 726 | + _info[0].substr(1, 2), | ||
| 727 | + _info[0].substr(3, 1), | ||
| 728 | + _info[0].substr(4, 2), | ||
| 729 | + | ||
| 730 | + _info[1].substr(0, 1), | ||
| 731 | + _info[1].substr(1, 2), | ||
| 732 | + _info[1].substr(3, 1), | ||
| 733 | + _info[1].substr(4, 2), | ||
| 734 | + | ||
| 735 | + _info[2].substr(0, 1), | ||
| 736 | + _info[2].substr(1, 2), | ||
| 737 | + _info[2].substr(3, 1), | ||
| 738 | + _info[2].substr(4, 2), | ||
| 739 | + | ||
| 740 | + _info[3].substr(0, 1), | ||
| 741 | + _info[3].substr(1, 2), | ||
| 742 | + _info[3].substr(3, 1), | ||
| 743 | + _info[3].substr(4, 2), | ||
| 744 | + | ||
| 745 | + _info[4].substr(0, 1), | ||
| 746 | + _info[4].substr(1, 2), | ||
| 747 | + _info[4].substr(3, 1), | ||
| 748 | + _info[4].substr(4, 2), | ||
| 749 | + | ||
| 750 | + _info[5].substr(0, 1), | ||
| 751 | + _info[5].substr(1, 2), | ||
| 752 | + _info[5].substr(3, 1), | ||
| 753 | + _info[5].substr(4, 2) | ||
| 754 | + ] | ||
| 755 | + return parseInt(_calday[n - 1]) | ||
| 756 | + }, | ||
| 757 | + | ||
| 758 | + /** | ||
| 759 | + * 传入农历数字月份返回汉语通俗表示法 | ||
| 760 | + * @param lunar month | ||
| 761 | + * @return Cn string | ||
| 762 | + * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月' | ||
| 763 | + */ | ||
| 764 | + toChinaMonth: function(m) { | ||
| 765 | + // 月 => \u6708 | ||
| 766 | + if (m > 12 || m < 1) return -1 // 若参数错误 返回-1 | ||
| 767 | + let s = calendar.nStr3[m - 1] | ||
| 768 | + s += '\u6708' // 加上月字 | ||
| 769 | + return s | ||
| 770 | + }, | ||
| 771 | + | ||
| 772 | + /** | ||
| 773 | + * 传入农历日期数字返回汉字表示法 | ||
| 774 | + * @param lunar day | ||
| 775 | + * @return Cn string | ||
| 776 | + * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一' | ||
| 777 | + */ | ||
| 778 | + toChinaDay: function(d) { | ||
| 779 | + // 日 => \u65e5 | ||
| 780 | + let s | ||
| 781 | + switch (d) { | ||
| 782 | + case 10: | ||
| 783 | + s = '\u521d\u5341' | ||
| 784 | + break | ||
| 785 | + case 20: | ||
| 786 | + s = '\u4e8c\u5341' | ||
| 787 | + break | ||
| 788 | + case 30: | ||
| 789 | + s = '\u4e09\u5341' | ||
| 790 | + break | ||
| 791 | + default: | ||
| 792 | + s = calendar.nStr2[Math.floor(d / 10)] | ||
| 793 | + s += calendar.nStr1[d % 10] | ||
| 794 | + } | ||
| 795 | + return s | ||
| 796 | + }, | ||
| 797 | + | ||
| 798 | + /** | ||
| 799 | + * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春” | ||
| 800 | + * @param y year | ||
| 801 | + * @return Cn string | ||
| 802 | + * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔' | ||
| 803 | + */ | ||
| 804 | + getAnimal: function(y) { | ||
| 805 | + return calendar.Animals[(y - 4) % 12] | ||
| 806 | + }, | ||
| 807 | + | ||
| 808 | + /** | ||
| 809 | + * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON | ||
| 810 | + * @param y solar year | ||
| 811 | + * @param m solar month | ||
| 812 | + * @param d solar day | ||
| 813 | + * @return JSON object | ||
| 814 | + * @eg:console.log(calendar.solar2lunar(1987,11,01)); | ||
| 815 | + */ | ||
| 816 | + solar2lunar: function(y, m, d) { | ||
| 817 | + // 参数区间1900.1.31~2100.12.31 | ||
| 818 | + // 年份限定、上限 | ||
| 819 | + if (y < 1900 || y > 2100) { | ||
| 820 | + return -1 // undefined转换为数字变为NaN | ||
| 821 | + } | ||
| 822 | + // 公历传参最下限 | ||
| 823 | + if (+y === 1900 && +m === 1 && +d < 31) { | ||
| 824 | + return -1 | ||
| 825 | + } | ||
| 826 | + // 未传参 获得当天 | ||
| 827 | + let objDate | ||
| 828 | + if (!y) { | ||
| 829 | + objDate = new Date() | ||
| 830 | + } else { | ||
| 831 | + objDate = new Date(y, parseInt(m) - 1, d) | ||
| 832 | + } | ||
| 833 | + let i | ||
| 834 | + let leap = 0 | ||
| 835 | + let temp = 0 | ||
| 836 | + // 修正ymd参数 | ||
| 837 | + y = objDate.getFullYear() | ||
| 838 | + m = objDate.getMonth() + 1 | ||
| 839 | + d = objDate.getDate() | ||
| 840 | + let offset = | ||
| 841 | + (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - | ||
| 842 | + Date.UTC(1900, 0, 31)) / | ||
| 843 | + 86400000 | ||
| 844 | + for (i = 1900; i < 2101 && offset > 0; i++) { | ||
| 845 | + temp = calendar.lYearDays(i) | ||
| 846 | + offset -= temp | ||
| 847 | + } | ||
| 848 | + if (offset < 0) { | ||
| 849 | + offset += temp | ||
| 850 | + i-- | ||
| 851 | + } | ||
| 852 | + | ||
| 853 | + // 是否今天 | ||
| 854 | + const isTodayObj = new Date() | ||
| 855 | + let isToday = false | ||
| 856 | + if ( | ||
| 857 | + isTodayObj.getFullYear() === +y && | ||
| 858 | + isTodayObj.getMonth() + 1 === +m && | ||
| 859 | + isTodayObj.getDate() === +d | ||
| 860 | + ) { | ||
| 861 | + isToday = true | ||
| 862 | + } | ||
| 863 | + // 星期几 | ||
| 864 | + let nWeek = objDate.getDay() | ||
| 865 | + const cWeek = calendar.nStr1[nWeek] | ||
| 866 | + // 数字表示周几顺应天朝周一开始的惯例 | ||
| 867 | + if (+nWeek === 0) { | ||
| 868 | + nWeek = 7 | ||
| 869 | + } | ||
| 870 | + // 农历年 | ||
| 871 | + const year = i | ||
| 872 | + leap = calendar.leapMonth(i) // 闰哪个月 | ||
| 873 | + let isLeap = false | ||
| 874 | + | ||
| 875 | + // 效验闰月 | ||
| 876 | + for (i = 1; i < 13 && offset > 0; i++) { | ||
| 877 | + // 闰月 | ||
| 878 | + if (leap > 0 && i === leap + 1 && isLeap === false) { | ||
| 879 | + --i | ||
| 880 | + isLeap = true | ||
| 881 | + temp = calendar.leapDays(year) // 计算农历闰月天数 | ||
| 882 | + } else { | ||
| 883 | + temp = calendar.monthDays(year, i) // 计算农历普通月天数 | ||
| 884 | + } | ||
| 885 | + // 解除闰月 | ||
| 886 | + if (isLeap === true && i === leap + 1) isLeap = false | ||
| 887 | + offset -= temp | ||
| 888 | + } | ||
| 889 | + // 闰月导致数组下标重叠取反 | ||
| 890 | + if (offset === 0 && leap > 0 && i === leap + 1) { | ||
| 891 | + if (isLeap) { | ||
| 892 | + isLeap = false | ||
| 893 | + } else { | ||
| 894 | + isLeap = true | ||
| 895 | + --i | ||
| 896 | + } | ||
| 897 | + } | ||
| 898 | + if (offset < 0) { | ||
| 899 | + offset += temp | ||
| 900 | + --i | ||
| 901 | + } | ||
| 902 | + // 农历月 | ||
| 903 | + const month = i | ||
| 904 | + // 农历日 | ||
| 905 | + const day = offset + 1 | ||
| 906 | + // 天干地支处理 | ||
| 907 | + const sm = m - 1 | ||
| 908 | + const gzY = calendar.toGanZhiYear(year) | ||
| 909 | + | ||
| 910 | + // 当月的两个节气 | ||
| 911 | + // bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year` | ||
| 912 | + const firstNode = calendar.getTerm(y, m * 2 - 1) // 返回当月「节」为几日开始 | ||
| 913 | + const secondNode = calendar.getTerm(y, m * 2) // 返回当月「节」为几日开始 | ||
| 914 | + | ||
| 915 | + // 依据12节气修正干支月 | ||
| 916 | + let gzM = calendar.toGanZhi((y - 1900) * 12 + m + 11) | ||
| 917 | + if (d >= firstNode) { | ||
| 918 | + gzM = calendar.toGanZhi((y - 1900) * 12 + m + 12) | ||
| 919 | + } | ||
| 920 | + | ||
| 921 | + // 传入的日期的节气与否 | ||
| 922 | + let isTerm = false | ||
| 923 | + let Term = null | ||
| 924 | + if (+firstNode === d) { | ||
| 925 | + isTerm = true | ||
| 926 | + Term = calendar.solarTerm[m * 2 - 2] | ||
| 927 | + } | ||
| 928 | + if (+secondNode === d) { | ||
| 929 | + isTerm = true | ||
| 930 | + Term = calendar.solarTerm[m * 2 - 1] | ||
| 931 | + } | ||
| 932 | + // 日柱 当月一日与 1900/1/1 相差天数 | ||
| 933 | + const dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10 | ||
| 934 | + const gzD = calendar.toGanZhi(dayCyclical + d - 1) | ||
| 935 | + // 该日期所属的星座 | ||
| 936 | + const astro = calendar.toAstro(m, d) | ||
| 937 | + | ||
| 938 | + return { | ||
| 939 | + lYear: year, | ||
| 940 | + lMonth: month, | ||
| 941 | + lDay: day, | ||
| 942 | + Animal: calendar.getAnimal(year), | ||
| 943 | + IMonthCn: (isLeap ? '\u95f0' : '') + calendar.toChinaMonth(month), | ||
| 944 | + IDayCn: calendar.toChinaDay(day), | ||
| 945 | + cYear: y, | ||
| 946 | + cMonth: m, | ||
| 947 | + cDay: d, | ||
| 948 | + gzYear: gzY, | ||
| 949 | + gzMonth: gzM, | ||
| 950 | + gzDay: gzD, | ||
| 951 | + isToday: isToday, | ||
| 952 | + isLeap: isLeap, | ||
| 953 | + nWeek: nWeek, | ||
| 954 | + ncWeek: '\u661f\u671f' + cWeek, | ||
| 955 | + isTerm: isTerm, | ||
| 956 | + Term: Term, | ||
| 957 | + astro: astro | ||
| 958 | + } | ||
| 959 | + }, | ||
| 960 | + | ||
| 961 | + /** | ||
| 962 | + * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON | ||
| 963 | + * @param y lunar year | ||
| 964 | + * @param m lunar month | ||
| 965 | + * @param d lunar day | ||
| 966 | + * @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可] | ||
| 967 | + * @return JSON object | ||
| 968 | + * @eg:console.log(calendar.lunar2solar(1987,9,10)); | ||
| 969 | + */ | ||
| 970 | + lunar2solar: function(y, m, d, isLeapMonth) { | ||
| 971 | + // 参数区间1900.1.31~2100.12.1 | ||
| 972 | + isLeapMonth = !!isLeapMonth | ||
| 973 | + // let leapOffset = 0; | ||
| 974 | + const leapMonth = calendar.leapMonth(y) | ||
| 975 | + // let leapDay = calendar.leapDays(y); | ||
| 976 | + if (isLeapMonth && leapMonth !== m) return -1 // 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同 | ||
| 977 | + if ( | ||
| 978 | + (+y === 2100 && +m === 12 && +d > 1) || | ||
| 979 | + (+y === 1900 && +m === 1 && +d < 31) | ||
| 980 | + ) | ||
| 981 | + return -1 // 超出了最大极限值 | ||
| 982 | + const day = calendar.monthDays(y, m) | ||
| 983 | + let _day = day | ||
| 984 | + // bugFix 2016-9-25 | ||
| 985 | + // if month is leap, _day use leapDays method | ||
| 986 | + if (isLeapMonth) { | ||
| 987 | + _day = calendar.leapDays(y, m) | ||
| 988 | + } | ||
| 989 | + if (y < 1900 || y > 2100 || d > _day) return -1 // 参数合法性效验 | ||
| 990 | + | ||
| 991 | + // 计算农历的时间差 | ||
| 992 | + let offset = 0 | ||
| 993 | + for (let i = 1900; i < y; i++) { | ||
| 994 | + offset += calendar.lYearDays(i) | ||
| 995 | + } | ||
| 996 | + let leap = 0 | ||
| 997 | + let isAdd = false | ||
| 998 | + for (let i = 1; i < m; i++) { | ||
| 999 | + leap = calendar.leapMonth(y) | ||
| 1000 | + if (!isAdd) { | ||
| 1001 | + // 处理闰月 | ||
| 1002 | + if (leap <= i && leap > 0) { | ||
| 1003 | + offset += calendar.leapDays(y) | ||
| 1004 | + isAdd = true | ||
| 1005 | + } | ||
| 1006 | + } | ||
| 1007 | + offset += calendar.monthDays(y, i) | ||
| 1008 | + } | ||
| 1009 | + // 转换闰月农历 需补充该年闰月的前一个月的时差 | ||
| 1010 | + if (isLeapMonth) offset += day | ||
| 1011 | + // 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点) | ||
| 1012 | + const stmap = Date.UTC(1900, 1, 30, 0, 0, 0) | ||
| 1013 | + const calObj = new Date((offset + d - 31) * 86400000 + stmap) | ||
| 1014 | + const cY = calObj.getUTCFullYear() | ||
| 1015 | + const cM = calObj.getUTCMonth() + 1 | ||
| 1016 | + const cD = calObj.getUTCDate() | ||
| 1017 | + | ||
| 1018 | + return calendar.solar2lunar(cY, cM, cD) | ||
| 1019 | + } | ||
| 1020 | +} | ||
| 1021 | + | ||
| 1022 | +const { | ||
| 1023 | + Gan, | ||
| 1024 | + Zhi, | ||
| 1025 | + nStr1, | ||
| 1026 | + nStr2, | ||
| 1027 | + nStr3, | ||
| 1028 | + Animals, | ||
| 1029 | + solarTerm, | ||
| 1030 | + lunarInfo, | ||
| 1031 | + sTermInfo, | ||
| 1032 | + solarMonth, | ||
| 1033 | + ...rest | ||
| 1034 | +} = calendar | ||
| 1035 | + | ||
| 1036 | +export default rest |
| @@ -0,0 +1,59 @@ | @@ -0,0 +1,59 @@ | ||
| 1 | +import { dateUtil } from '../../utils/index' | ||
| 2 | +import convertSolarLunar from './convertSolarLunar' | ||
| 3 | + | ||
| 4 | +function getDateRow2Dict(dateInfo) { | ||
| 5 | + if (!dateInfo) return dateInfo | ||
| 6 | + if (typeof dateInfo === 'string' && dateInfo.includes('-')) { | ||
| 7 | + dateInfo = dateUtil.transformDateRow2Dict(dateInfo) | ||
| 8 | + } | ||
| 9 | + return dateInfo | ||
| 10 | +} | ||
| 11 | + | ||
| 12 | +export default () => { | ||
| 13 | + return { | ||
| 14 | + name: 'convertSolarLunar', | ||
| 15 | + beforeRender(calendarData = {}, calendarConfig = {}) { | ||
| 16 | + let { dates = [], selectedDates = [] } = calendarData | ||
| 17 | + if (calendarConfig.showLunar) { | ||
| 18 | + dates = dates.map(dataInfo => { | ||
| 19 | + const { year, month, date } = dataInfo | ||
| 20 | + return { | ||
| 21 | + ...dataInfo, | ||
| 22 | + lunar: convertSolarLunar.solar2lunar(year, month, date) | ||
| 23 | + } | ||
| 24 | + }) | ||
| 25 | + selectedDates = selectedDates.map(dataInfo => { | ||
| 26 | + const { year, month, date } = dataInfo | ||
| 27 | + return { | ||
| 28 | + ...dataInfo, | ||
| 29 | + lunar: convertSolarLunar.solar2lunar(year, month, date) | ||
| 30 | + } | ||
| 31 | + }) | ||
| 32 | + } | ||
| 33 | + return { | ||
| 34 | + calendarData: { | ||
| 35 | + ...calendarData, | ||
| 36 | + dates: dates, | ||
| 37 | + selectedDates: selectedDates | ||
| 38 | + }, | ||
| 39 | + calendarConfig | ||
| 40 | + } | ||
| 41 | + }, | ||
| 42 | + methods() { | ||
| 43 | + return { | ||
| 44 | + convertSolarLunar: dateInfo => { | ||
| 45 | + dateInfo = getDateRow2Dict(dateInfo) | ||
| 46 | + if (!dateInfo) return dateInfo | ||
| 47 | + const { year, month, date } = dateInfo | ||
| 48 | + return convertSolarLunar.solar2lunar(year, month, date) | ||
| 49 | + }, | ||
| 50 | + convertlLunar2Solar: (dateInfo, isLeapMonth) => { | ||
| 51 | + dateInfo = getDateRow2Dict(dateInfo) | ||
| 52 | + if (!dateInfo) return dateInfo | ||
| 53 | + const { year, month, date } = dateInfo | ||
| 54 | + return convertSolarLunar.lunar2solar(year, month, date, isLeapMonth) | ||
| 55 | + } | ||
| 56 | + } | ||
| 57 | + } | ||
| 58 | + } | ||
| 59 | +} |
| @@ -0,0 +1,309 @@ | @@ -0,0 +1,309 @@ | ||
| 1 | +/** | ||
| 2 | + * @Author: drfu* | ||
| 3 | + * @Description: 时间区域选择 | ||
| 4 | + * @Date: 2020-10-08 21:22:09* | ||
| 5 | + * @Last Modified by: drfu | ||
| 6 | + * @Last Modified time: 2020-10-11 13:56:32 | ||
| 7 | + * */ | ||
| 8 | + | ||
| 9 | +import { renderCalendar } from '../render' | ||
| 10 | +import { | ||
| 11 | + logger, | ||
| 12 | + dateUtil, | ||
| 13 | + getCalendarConfig, | ||
| 14 | + getCalendarData | ||
| 15 | +} from '../utils/index' | ||
| 16 | + | ||
| 17 | +function pusheNextMonthDateArea( | ||
| 18 | + dateInfo = {}, | ||
| 19 | + startTimestamp, | ||
| 20 | + endTimestamp, | ||
| 21 | + selectedDates = [] | ||
| 22 | +) { | ||
| 23 | + let tempOfSelectedDate = [...selectedDates] | ||
| 24 | + const dates = dateUtil.calcDates(dateInfo.year, dateInfo.month) | ||
| 25 | + let datesLen = dates.length | ||
| 26 | + for (let i = 0; i < datesLen; i++) { | ||
| 27 | + const date = dates[i] | ||
| 28 | + const timeStamp = dateUtil.getTimeStamp(date) | ||
| 29 | + if (timeStamp <= endTimestamp && timeStamp >= startTimestamp) { | ||
| 30 | + tempOfSelectedDate.push({ | ||
| 31 | + ...date, | ||
| 32 | + choosed: true | ||
| 33 | + }) | ||
| 34 | + } | ||
| 35 | + if (i === datesLen - 1 && timeStamp < endTimestamp) { | ||
| 36 | + tempOfSelectedDate = pusheNextMonthDateArea( | ||
| 37 | + dateUtil.getNextMonthInfo(date), | ||
| 38 | + startTimestamp, | ||
| 39 | + endTimestamp, | ||
| 40 | + tempOfSelectedDate | ||
| 41 | + ) | ||
| 42 | + } | ||
| 43 | + } | ||
| 44 | + return tempOfSelectedDate | ||
| 45 | +} | ||
| 46 | +function pushPrevMonthDateArea( | ||
| 47 | + dateInfo = {}, | ||
| 48 | + startTimestamp, | ||
| 49 | + endTimestamp, | ||
| 50 | + selectedDates = [] | ||
| 51 | +) { | ||
| 52 | + let tempOfSelectedDate = [...selectedDates] | ||
| 53 | + const dates = dateUtil.sortDatesByTime( | ||
| 54 | + dateUtil.calcDates(dateInfo.year, dateInfo.month), | ||
| 55 | + 'desc' | ||
| 56 | + ) | ||
| 57 | + let datesLen = dates.length | ||
| 58 | + let firstDate = dateUtil.getTimeStamp(dates[0]) | ||
| 59 | + for (let i = 0; i < datesLen; i++) { | ||
| 60 | + const date = dates[i] | ||
| 61 | + const timeStamp = dateUtil.getTimeStamp(date) | ||
| 62 | + if (timeStamp >= startTimestamp && timeStamp <= endTimestamp) { | ||
| 63 | + tempOfSelectedDate.push({ | ||
| 64 | + ...date, | ||
| 65 | + choosed: true | ||
| 66 | + }) | ||
| 67 | + } | ||
| 68 | + if (i === datesLen - 1 && firstDate > startTimestamp) { | ||
| 69 | + tempOfSelectedDate = pushPrevMonthDateArea( | ||
| 70 | + dateUtil.getPrevMonthInfo(date), | ||
| 71 | + startTimestamp, | ||
| 72 | + endTimestamp, | ||
| 73 | + tempOfSelectedDate | ||
| 74 | + ) | ||
| 75 | + } | ||
| 76 | + } | ||
| 77 | + return tempOfSelectedDate | ||
| 78 | +} | ||
| 79 | +/** | ||
| 80 | + * 当设置日期区域非当前时保存其他月份的日期至已选日期数组 | ||
| 81 | + * @param {object} info | ||
| 82 | + */ | ||
| 83 | +function calcDateWhenNotInOneMonth(info) { | ||
| 84 | + const { firstDate, lastDate, startTimestamp, endTimestamp } = info | ||
| 85 | + let { selectedDate } = info | ||
| 86 | + if (dateUtil.getTimeStamp(firstDate) > startTimestamp) { | ||
| 87 | + selectedDate = pushPrevMonthDateArea( | ||
| 88 | + dateUtil.getPrevMonthInfo(firstDate), | ||
| 89 | + startTimestamp, | ||
| 90 | + endTimestamp, | ||
| 91 | + selectedDate | ||
| 92 | + ) | ||
| 93 | + } | ||
| 94 | + if (dateUtil.getTimeStamp(lastDate) < endTimestamp) { | ||
| 95 | + selectedDate = pusheNextMonthDateArea( | ||
| 96 | + dateUtil.getNextMonthInfo(lastDate), | ||
| 97 | + startTimestamp, | ||
| 98 | + endTimestamp, | ||
| 99 | + selectedDate | ||
| 100 | + ) | ||
| 101 | + } | ||
| 102 | + return [...selectedDate] | ||
| 103 | +} | ||
| 104 | + | ||
| 105 | +/** | ||
| 106 | + * 指定日期区域转时间戳 | ||
| 107 | + * @param {array} timearea 时间区域 | ||
| 108 | + */ | ||
| 109 | +export function convertTimeRangeToTimestamp(timearea = []) { | ||
| 110 | + const start = timearea[0].split('-') | ||
| 111 | + const end = timearea[1].split('-') | ||
| 112 | + if (start.length !== 3 || end.length !== 3) { | ||
| 113 | + logger.warn('enableArea() 参数格式为: ["2018-2-1", "2018-3-1"]') | ||
| 114 | + return {} | ||
| 115 | + } | ||
| 116 | + const startTimestamp = dateUtil | ||
| 117 | + .newDate(start[0], start[1], start[2]) | ||
| 118 | + .getTime() | ||
| 119 | + const endTimestamp = dateUtil.newDate(end[0], end[1], end[2]).getTime() | ||
| 120 | + return { | ||
| 121 | + start, | ||
| 122 | + end, | ||
| 123 | + startTimestamp, | ||
| 124 | + endTimestamp | ||
| 125 | + } | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | +/** | ||
| 129 | + * 校验时间区域是否合法 | ||
| 130 | + * @param {array} dateArea 时间区域 | ||
| 131 | + */ | ||
| 132 | +function validateTimeRange(dateArea) { | ||
| 133 | + const { | ||
| 134 | + start, | ||
| 135 | + end, | ||
| 136 | + startTimestamp, | ||
| 137 | + endTimestamp | ||
| 138 | + } = convertTimeRangeToTimestamp(dateArea) | ||
| 139 | + if (!start || !end) return | ||
| 140 | + const startMonthDays = dateUtil.getDatesCountOfMonth(start[0], start[1]) | ||
| 141 | + const endMonthDays = dateUtil.getDatesCountOfMonth(end[0], end[1]) | ||
| 142 | + if (start[2] > startMonthDays || start[2] < 1) { | ||
| 143 | + logger.warn('enableArea() 开始日期错误,指定日期不在当前月份天数范围内') | ||
| 144 | + return false | ||
| 145 | + } else if (start[1] > 12 || start[1] < 1) { | ||
| 146 | + logger.warn('enableArea() 开始日期错误,月份超出1-12月份') | ||
| 147 | + return false | ||
| 148 | + } else if (end[2] > endMonthDays || end[2] < 1) { | ||
| 149 | + logger.warn('enableArea() 截止日期错误,指定日期不在当前月份天数范围内') | ||
| 150 | + return false | ||
| 151 | + } else if (end[1] > 12 || end[1] < 1) { | ||
| 152 | + logger.warn('enableArea() 截止日期错误,月份超出1-12月份') | ||
| 153 | + return false | ||
| 154 | + } else if (startTimestamp > endTimestamp) { | ||
| 155 | + logger.warn('enableArea()参数最小日期大于了最大日期') | ||
| 156 | + return false | ||
| 157 | + } else { | ||
| 158 | + return true | ||
| 159 | + } | ||
| 160 | +} | ||
| 161 | + | ||
| 162 | +export default () => { | ||
| 163 | + return { | ||
| 164 | + name: 'timeRange', | ||
| 165 | + beforeRender(calendarData = {}, calendarConfig = {}) { | ||
| 166 | + const { | ||
| 167 | + chooseAreaTimestamp = [], | ||
| 168 | + dates = [], | ||
| 169 | + selectedDates = [] | ||
| 170 | + } = calendarData | ||
| 171 | + let __dates = dates | ||
| 172 | + let __selectedDates = selectedDates | ||
| 173 | + const [startDateTimestamp, endDateTimestamp] = chooseAreaTimestamp | ||
| 174 | + if (chooseAreaTimestamp.length === 2) { | ||
| 175 | + __selectedDates = [] | ||
| 176 | + __dates = dates.map(d => { | ||
| 177 | + const date = { ...d } | ||
| 178 | + const dateTimeStamp = dateUtil.getTimeStamp(date) | ||
| 179 | + if ( | ||
| 180 | + dateTimeStamp >= startDateTimestamp && | ||
| 181 | + endDateTimestamp >= dateTimeStamp | ||
| 182 | + ) { | ||
| 183 | + date.choosed = true | ||
| 184 | + __selectedDates.push(date) | ||
| 185 | + } else { | ||
| 186 | + date.choosed = false | ||
| 187 | + __selectedDates = __selectedDates.filter( | ||
| 188 | + item => dateUtil.getTimeStamp(item) !== dateTimeStamp | ||
| 189 | + ) | ||
| 190 | + } | ||
| 191 | + return date | ||
| 192 | + }) | ||
| 193 | + const { year: startYear, month: startMonth } = dateUtil.formatTimestamp( | ||
| 194 | + startDateTimestamp | ||
| 195 | + ) | ||
| 196 | + const { year: endYear, month: endMonth } = dateUtil.formatTimestamp( | ||
| 197 | + endDateTimestamp | ||
| 198 | + ) | ||
| 199 | + if (startMonth !== endMonth || startYear !== endYear) { | ||
| 200 | + __selectedDates = calcDateWhenNotInOneMonth({ | ||
| 201 | + firstDate: __dates[0], | ||
| 202 | + lastDate: __dates[__dates.length - 1], | ||
| 203 | + startTimestamp: startDateTimestamp, | ||
| 204 | + endTimestamp: endDateTimestamp, | ||
| 205 | + selectedDate: __selectedDates | ||
| 206 | + }) | ||
| 207 | + } | ||
| 208 | + } | ||
| 209 | + return { | ||
| 210 | + calendarData: { | ||
| 211 | + ...calendarData, | ||
| 212 | + dates: __dates, | ||
| 213 | + selectedDates: dateUtil.sortDatesByTime( | ||
| 214 | + dateUtil.uniqueArrayByDate(__selectedDates) | ||
| 215 | + ) | ||
| 216 | + }, | ||
| 217 | + calendarConfig | ||
| 218 | + } | ||
| 219 | + }, | ||
| 220 | + onTapDate(tapedDate, calendarData = {}, calendarConfig = {}) { | ||
| 221 | + if (!calendarConfig.chooseAreaMode) { | ||
| 222 | + return { | ||
| 223 | + calendarData, | ||
| 224 | + calendarConfig | ||
| 225 | + } | ||
| 226 | + } | ||
| 227 | + let { | ||
| 228 | + tempChooseAreaTimestamp = [], | ||
| 229 | + chooseAreaTimestamp: existChooseAreaTimestamp = [], | ||
| 230 | + selectedDates = [], | ||
| 231 | + dates = [] | ||
| 232 | + } = calendarData | ||
| 233 | + const timestamp = dateUtil.getTimeStamp(tapedDate) | ||
| 234 | + let __dates = [...dates] | ||
| 235 | + let __selectedDates = [...selectedDates] | ||
| 236 | + if ( | ||
| 237 | + tempChooseAreaTimestamp.length === 2 || | ||
| 238 | + existChooseAreaTimestamp.length === 2 | ||
| 239 | + ) { | ||
| 240 | + tempChooseAreaTimestamp = [tapedDate] | ||
| 241 | + __selectedDates = [] | ||
| 242 | + __dates.forEach(d => (d.choosed = false)) | ||
| 243 | + } else if (tempChooseAreaTimestamp.length === 1) { | ||
| 244 | + const preChoosedDate = tempChooseAreaTimestamp[0] | ||
| 245 | + const preTimestamp = dateUtil.getTimeStamp(preChoosedDate) | ||
| 246 | + if (preTimestamp <= timestamp) { | ||
| 247 | + tempChooseAreaTimestamp.push(tapedDate) | ||
| 248 | + } else if (preTimestamp > timestamp) { | ||
| 249 | + tempChooseAreaTimestamp.unshift(tapedDate) | ||
| 250 | + } | ||
| 251 | + } else { | ||
| 252 | + tempChooseAreaTimestamp = [tapedDate] | ||
| 253 | + } | ||
| 254 | + let chooseAreaTimestamp = [] | ||
| 255 | + if (tempChooseAreaTimestamp.length === 2) { | ||
| 256 | + const [startDate, endDate] = tempChooseAreaTimestamp | ||
| 257 | + const startDateTimestamp = dateUtil.getTimeStamp(startDate) | ||
| 258 | + const endDateTimestamp = dateUtil.getTimeStamp(endDate) | ||
| 259 | + chooseAreaTimestamp = [startDateTimestamp, endDateTimestamp] | ||
| 260 | + } | ||
| 261 | + return { | ||
| 262 | + calendarData: { | ||
| 263 | + ...calendarData, | ||
| 264 | + chooseAreaTimestamp, | ||
| 265 | + tempChooseAreaTimestamp, | ||
| 266 | + dates: __dates, | ||
| 267 | + selectedDates: __selectedDates | ||
| 268 | + }, | ||
| 269 | + calendarConfig: { | ||
| 270 | + ...calendarConfig, | ||
| 271 | + multi: true | ||
| 272 | + } | ||
| 273 | + } | ||
| 274 | + }, | ||
| 275 | + methods(component) { | ||
| 276 | + return { | ||
| 277 | + /** | ||
| 278 | + * 设置连续日期选择区域 | ||
| 279 | + * @param {array} dateArea 区域开始结束日期数组 | ||
| 280 | + */ | ||
| 281 | + chooseDateArea: (dateArea = []) => { | ||
| 282 | + if (dateArea.length === 1) { | ||
| 283 | + dateArea = dateArea.concat(dateArea) | ||
| 284 | + } | ||
| 285 | + if (dateArea.length !== 2) return | ||
| 286 | + const isRight = validateTimeRange(dateArea) | ||
| 287 | + if (!isRight) return | ||
| 288 | + const config = getCalendarConfig(component) || {} | ||
| 289 | + const { startTimestamp, endTimestamp } = convertTimeRangeToTimestamp( | ||
| 290 | + dateArea | ||
| 291 | + ) | ||
| 292 | + const existCalendarData = getCalendarData('calendar', component) | ||
| 293 | + return renderCalendar.call( | ||
| 294 | + component, | ||
| 295 | + { | ||
| 296 | + ...existCalendarData, | ||
| 297 | + chooseAreaTimestamp: [startTimestamp, endTimestamp] | ||
| 298 | + }, | ||
| 299 | + { | ||
| 300 | + ...config, | ||
| 301 | + multi: true, | ||
| 302 | + chooseAreaMode: true | ||
| 303 | + } | ||
| 304 | + ) | ||
| 305 | + } | ||
| 306 | + } | ||
| 307 | + } | ||
| 308 | + } | ||
| 309 | +} |
| @@ -0,0 +1,135 @@ | @@ -0,0 +1,135 @@ | ||
| 1 | +/** | ||
| 2 | + * @Author: drfu* | ||
| 3 | + * @Description: 代办事项 | ||
| 4 | + * @Date: 2020-10-08 21:22:09* | ||
| 5 | + * @Last Modified by: drfu | ||
| 6 | + * @Last Modified time: 2020-10-11 14:23:02 | ||
| 7 | + * */ | ||
| 8 | + | ||
| 9 | +import { getCalendarData, dateUtil } from '../utils/index' | ||
| 10 | +import { renderCalendar } from '../render' | ||
| 11 | + | ||
| 12 | +function updateDatePropertyOfTodoLabel(todos, dates, showLabelAlways) { | ||
| 13 | + const datesInfo = [...dates] | ||
| 14 | + for (let todo of todos) { | ||
| 15 | + let targetIdx = datesInfo.findIndex( | ||
| 16 | + item => dateUtil.toTimeStr(item) === dateUtil.toTimeStr(todo) | ||
| 17 | + ) | ||
| 18 | + let target = datesInfo[targetIdx] | ||
| 19 | + if (!target) continue | ||
| 20 | + if (showLabelAlways) { | ||
| 21 | + target.showTodoLabel = true | ||
| 22 | + } else { | ||
| 23 | + target.showTodoLabel = !target.choosed | ||
| 24 | + } | ||
| 25 | + if (target.showTodoLabel) { | ||
| 26 | + target.todoText = todo.todoText | ||
| 27 | + } | ||
| 28 | + target.color = todo.color | ||
| 29 | + } | ||
| 30 | + return datesInfo | ||
| 31 | +} | ||
| 32 | + | ||
| 33 | +export default () => { | ||
| 34 | + return { | ||
| 35 | + name: 'todo', | ||
| 36 | + beforeRender(calendarData = {}, calendarConfig = {}, component) { | ||
| 37 | + const { todos = [], dates = [], showLabelAlways } = calendarData | ||
| 38 | + const dateWithTodoInfo = updateDatePropertyOfTodoLabel( | ||
| 39 | + todos, | ||
| 40 | + dates, | ||
| 41 | + showLabelAlways | ||
| 42 | + ) | ||
| 43 | + return { | ||
| 44 | + calendarData: { | ||
| 45 | + ...calendarData, | ||
| 46 | + dates: dateWithTodoInfo | ||
| 47 | + }, | ||
| 48 | + calendarConfig | ||
| 49 | + } | ||
| 50 | + }, | ||
| 51 | + methods(component) { | ||
| 52 | + return { | ||
| 53 | + setTodos: (options = {}) => { | ||
| 54 | + const calendar = getCalendarData('calendar', component) | ||
| 55 | + if (!calendar || !calendar.dates) { | ||
| 56 | + return Promise.reject('请等待日历初始化完成后再调用该方法') | ||
| 57 | + } | ||
| 58 | + const { | ||
| 59 | + circle, | ||
| 60 | + dotColor = '', | ||
| 61 | + pos = 'bottom', | ||
| 62 | + showLabelAlways, | ||
| 63 | + dates: todoDates = [] | ||
| 64 | + } = options | ||
| 65 | + const { todos = [] } = calendar | ||
| 66 | + const tranformStr2NumOfTodo = todoDates.map(date => | ||
| 67 | + dateUtil.tranformStr2NumOfDate(date) | ||
| 68 | + ) | ||
| 69 | + const calendarData = { | ||
| 70 | + dates: calendar.dates, | ||
| 71 | + todos: dateUtil.uniqueArrayByDate( | ||
| 72 | + todos.concat(tranformStr2NumOfTodo) | ||
| 73 | + ) | ||
| 74 | + } | ||
| 75 | + if (!circle) { | ||
| 76 | + calendarData.todoLabelPos = pos | ||
| 77 | + calendarData.todoLabelColor = dotColor | ||
| 78 | + } | ||
| 79 | + calendarData.todoLabelCircle = circle || false | ||
| 80 | + calendarData.showLabelAlways = showLabelAlways || false | ||
| 81 | + const existCalendarData = getCalendarData('calendar', component) | ||
| 82 | + return renderCalendar.call(component, { | ||
| 83 | + ...existCalendarData, | ||
| 84 | + ...calendarData | ||
| 85 | + }) | ||
| 86 | + }, | ||
| 87 | + deleteTodos(todos = []) { | ||
| 88 | + if (!(todos instanceof Array) || !todos.length) | ||
| 89 | + return Promise.reject('deleteTodos()应为入参为非空数组') | ||
| 90 | + const existCalendarData = getCalendarData('calendar', component) | ||
| 91 | + const allTodos = existCalendarData.todos || [] | ||
| 92 | + const toDeleteTodos = todos.map(item => dateUtil.toTimeStr(item)) | ||
| 93 | + const remainTodos = allTodos.filter( | ||
| 94 | + item => !toDeleteTodos.includes(dateUtil.toTimeStr(item)) | ||
| 95 | + ) | ||
| 96 | + const { dates, curYear, curMonth } = existCalendarData | ||
| 97 | + const _dates = [...dates] | ||
| 98 | + const currentMonthTodos = dateUtil.filterDatesByYM( | ||
| 99 | + { | ||
| 100 | + year: curYear, | ||
| 101 | + month: curMonth | ||
| 102 | + }, | ||
| 103 | + remainTodos | ||
| 104 | + ) | ||
| 105 | + _dates.forEach(item => { | ||
| 106 | + item.showTodoLabel = false | ||
| 107 | + }) | ||
| 108 | + currentMonthTodos.forEach(item => { | ||
| 109 | + _dates[item.date - 1].showTodoLabel = !_dates[item.date - 1].choosed | ||
| 110 | + }) | ||
| 111 | + return renderCalendar.call(component, { | ||
| 112 | + ...existCalendarData, | ||
| 113 | + dates: _dates, | ||
| 114 | + todos: remainTodos | ||
| 115 | + }) | ||
| 116 | + }, | ||
| 117 | + clearTodos() { | ||
| 118 | + const existCalendarData = getCalendarData('calendar', component) | ||
| 119 | + const _dates = [...existCalendarData.dates] | ||
| 120 | + _dates.forEach(item => { | ||
| 121 | + item.showTodoLabel = false | ||
| 122 | + }) | ||
| 123 | + return renderCalendar.call(component, { | ||
| 124 | + ...existCalendarData, | ||
| 125 | + dates: _dates, | ||
| 126 | + todos: [] | ||
| 127 | + }) | ||
| 128 | + }, | ||
| 129 | + getTodos() { | ||
| 130 | + return getCalendarData('calendar.todos', component) || [] | ||
| 131 | + } | ||
| 132 | + } | ||
| 133 | + } | ||
| 134 | + } | ||
| 135 | +} |
| @@ -0,0 +1,432 @@ | @@ -0,0 +1,432 @@ | ||
| 1 | +/** | ||
| 2 | + * @Author: drfu* | ||
| 3 | + * @Description: 周视图 | ||
| 4 | + * @Date: 2020-10-08 21:22:09* | ||
| 5 | + * @Last Modified by: drfu | ||
| 6 | + * @Last Modified time: 2020-10-12 14:39:45 | ||
| 7 | + * */ | ||
| 8 | + | ||
| 9 | +import { renderCalendar } from '../render' | ||
| 10 | +import { | ||
| 11 | + getCalendarConfig, | ||
| 12 | + getCalendarData, | ||
| 13 | + logger, | ||
| 14 | + dateUtil | ||
| 15 | +} from '../utils/index' | ||
| 16 | +import { calcJumpData } from '../core' | ||
| 17 | + | ||
| 18 | +/** | ||
| 19 | + * 当月第一周所有日期 | ||
| 20 | + */ | ||
| 21 | +function firstWeekInMonth( | ||
| 22 | + target = {}, | ||
| 23 | + calendarDates = [], | ||
| 24 | + calendarConfig = {} | ||
| 25 | +) { | ||
| 26 | + const { firstDayOfWeek } = calendarConfig | ||
| 27 | + const firstDayOfWeekIsMon = firstDayOfWeek === 'Mon' | ||
| 28 | + const { year, month } = target | ||
| 29 | + let firstDay = dateUtil.getDayOfWeek(year, month, 1) | ||
| 30 | + if (firstDayOfWeekIsMon && firstDay === 0) { | ||
| 31 | + firstDay = 7 | ||
| 32 | + } | ||
| 33 | + const [, end] = [0, 7 - firstDay] | ||
| 34 | + return calendarDates.slice(0, firstDayOfWeekIsMon ? end + 1 : end) | ||
| 35 | +} | ||
| 36 | + | ||
| 37 | +/** | ||
| 38 | + * 当月最后一周所有日期 | ||
| 39 | + */ | ||
| 40 | +function lastWeekInMonth(target = {}, calendarDates = [], calendarConfig = {}) { | ||
| 41 | + const { firstDayOfWeek } = calendarConfig | ||
| 42 | + const firstDayOfWeekIsMon = firstDayOfWeek === 'Mon' | ||
| 43 | + const { year, month } = target | ||
| 44 | + const lastDay = dateUtil.getDatesCountOfMonth(year, month) | ||
| 45 | + let lastDayWeek = dateUtil.getDayOfWeek(year, month, lastDay) | ||
| 46 | + if (firstDayOfWeekIsMon && lastDayWeek === 0) { | ||
| 47 | + lastDayWeek = 7 | ||
| 48 | + } | ||
| 49 | + const [start, end] = [lastDay - lastDayWeek, lastDay] | ||
| 50 | + return calendarDates.slice(firstDayOfWeekIsMon ? start : start - 1, end) | ||
| 51 | +} | ||
| 52 | + | ||
| 53 | +/** | ||
| 54 | + * 判断目标日期是否在某些指定日历内 | ||
| 55 | + */ | ||
| 56 | +function dateIsInDatesRange(target, dates) { | ||
| 57 | + if (!target || !dates || !dates.length) return false | ||
| 58 | + const targetDateStr = dateUtil.toTimeStr(target) | ||
| 59 | + let rst = false | ||
| 60 | + for (let date of dates) { | ||
| 61 | + const dateStr = dateUtil.toTimeStr(date) | ||
| 62 | + if (dateStr === targetDateStr) { | ||
| 63 | + rst = true | ||
| 64 | + return rst | ||
| 65 | + } | ||
| 66 | + rst = false | ||
| 67 | + } | ||
| 68 | + return rst | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | +function getDatesWhenTargetInFirstWeek(target, firstWeekDates) { | ||
| 72 | + const { year, month } = target | ||
| 73 | + const prevMonthInfo = dateUtil.getPrevMonthInfo({ year, month }) | ||
| 74 | + let lastMonthDatesCount = dateUtil.getDatesCountOfMonth( | ||
| 75 | + prevMonthInfo.year, | ||
| 76 | + prevMonthInfo.month | ||
| 77 | + ) | ||
| 78 | + let dates = firstWeekDates | ||
| 79 | + let firstWeekCount = firstWeekDates.length | ||
| 80 | + for (let i = 0; i < 7 - firstWeekCount; i++) { | ||
| 81 | + const week = dateUtil.getDayOfWeek(+year, +month, lastMonthDatesCount) | ||
| 82 | + dates.unshift({ | ||
| 83 | + year: prevMonthInfo.year, | ||
| 84 | + month: prevMonthInfo.month, | ||
| 85 | + date: lastMonthDatesCount, | ||
| 86 | + week | ||
| 87 | + }) | ||
| 88 | + lastMonthDatesCount -= 1 | ||
| 89 | + } | ||
| 90 | + return dates | ||
| 91 | +} | ||
| 92 | + | ||
| 93 | +function getDatesWhenTargetInLastWeek(target, lastWeekDates) { | ||
| 94 | + const { year, month } = target | ||
| 95 | + const prevMonthInfo = dateUtil.getNextMonthInfo({ year, month }) | ||
| 96 | + let dates = lastWeekDates | ||
| 97 | + let lastWeekCount = lastWeekDates.length | ||
| 98 | + for (let i = 0; i < 7 - lastWeekCount; i++) { | ||
| 99 | + const week = dateUtil.getDayOfWeek(+year, +month, i + 1) | ||
| 100 | + dates.push({ | ||
| 101 | + year: prevMonthInfo.year, | ||
| 102 | + month: prevMonthInfo.month, | ||
| 103 | + date: i + 1, | ||
| 104 | + week | ||
| 105 | + }) | ||
| 106 | + } | ||
| 107 | + return dates | ||
| 108 | +} | ||
| 109 | + | ||
| 110 | +function getDates(target, calendarDates = [], calendarConfig = {}) { | ||
| 111 | + const { year, month, date } = target | ||
| 112 | + const targetDay = dateUtil.getDayOfWeek(year, month, date) | ||
| 113 | + const { firstDayOfWeek } = calendarConfig | ||
| 114 | + const firstDayOfWeekIsMon = firstDayOfWeek === 'Mon' | ||
| 115 | + if (firstDayOfWeekIsMon) { | ||
| 116 | + const startIdx = date - (targetDay || 7) | ||
| 117 | + return calendarDates.splice(startIdx, 7) | ||
| 118 | + } else { | ||
| 119 | + const startIdx = date - targetDay - 1 | ||
| 120 | + return calendarDates.splice(startIdx, 7) | ||
| 121 | + } | ||
| 122 | +} | ||
| 123 | + | ||
| 124 | +function getTargetWeekDates(target, calendarConfig) { | ||
| 125 | + if (!target) return | ||
| 126 | + const { year, month } = target | ||
| 127 | + const calendarDates = dateUtil.calcDates(year, month) | ||
| 128 | + const firstWeekDates = firstWeekInMonth(target, calendarDates, calendarConfig) | ||
| 129 | + const lastWeekDates = lastWeekInMonth(target, calendarDates, calendarConfig) | ||
| 130 | + if (dateIsInDatesRange(target, firstWeekDates)) { | ||
| 131 | + return getDatesWhenTargetInFirstWeek(target, firstWeekDates) | ||
| 132 | + } else if (dateIsInDatesRange(target, lastWeekDates)) { | ||
| 133 | + return getDatesWhenTargetInLastWeek(target, lastWeekDates) | ||
| 134 | + } else { | ||
| 135 | + return getDates(target, calendarDates, calendarConfig) | ||
| 136 | + } | ||
| 137 | +} | ||
| 138 | + | ||
| 139 | +/** | ||
| 140 | + * 计算周视图下当前这一周最后一天 | ||
| 141 | + */ | ||
| 142 | +function calculateLastDateOfCurrentWeek(calendarData = {}) { | ||
| 143 | + const { dates = [] } = calendarData | ||
| 144 | + return dates[dates.length - 1] | ||
| 145 | +} | ||
| 146 | +/** | ||
| 147 | + * 计算周视图下当前这一周第一天 | ||
| 148 | + */ | ||
| 149 | +function calculateFirstDateOfCurrentWeek(calendarData = {}) { | ||
| 150 | + const { dates } = calendarData | ||
| 151 | + return dates[0] | ||
| 152 | +} | ||
| 153 | + | ||
| 154 | +/** | ||
| 155 | + * 计算下一周的日期 | ||
| 156 | + */ | ||
| 157 | +function calculateNextWeekDates(calendarData = {}) { | ||
| 158 | + let { curYear, curMonth } = calendarData | ||
| 159 | + let calendarDates = [] | ||
| 160 | + let lastDateInThisWeek = calculateLastDateOfCurrentWeek(calendarData) | ||
| 161 | + const { year: LYear, month: LMonth } = lastDateInThisWeek | ||
| 162 | + if (curYear !== LYear || curMonth !== LMonth) { | ||
| 163 | + calendarDates = dateUtil.calcDates(LYear, LMonth) | ||
| 164 | + curYear = LYear | ||
| 165 | + curMonth = LMonth | ||
| 166 | + } else { | ||
| 167 | + calendarDates = dateUtil.calcDates(curYear, curMonth) | ||
| 168 | + } | ||
| 169 | + const lastDateInThisMonth = dateUtil.getDatesCountOfMonth(curYear, curMonth) | ||
| 170 | + const count = lastDateInThisMonth - lastDateInThisWeek.date | ||
| 171 | + const lastDateIdx = calendarDates.findIndex( | ||
| 172 | + date => dateUtil.toTimeStr(date) === dateUtil.toTimeStr(lastDateInThisWeek) | ||
| 173 | + ) | ||
| 174 | + const startIdx = lastDateIdx + 1 | ||
| 175 | + if (count >= 7) { | ||
| 176 | + return { | ||
| 177 | + dates: calendarDates.splice(startIdx, 7), | ||
| 178 | + year: curYear, | ||
| 179 | + month: curMonth | ||
| 180 | + } | ||
| 181 | + } else { | ||
| 182 | + const nextMonth = dateUtil.getNextMonthInfo({ | ||
| 183 | + year: curYear, | ||
| 184 | + month: curMonth | ||
| 185 | + }) | ||
| 186 | + const { year, month } = nextMonth || {} | ||
| 187 | + const calendarDatesOfNextMonth = dateUtil.calcDates(year, month) | ||
| 188 | + const remainDatesOfThisMonth = calendarDates.splice(startIdx) | ||
| 189 | + const patchDatesOfNextMonth = calendarDatesOfNextMonth.splice( | ||
| 190 | + 0, | ||
| 191 | + 7 - remainDatesOfThisMonth.length | ||
| 192 | + ) | ||
| 193 | + return { | ||
| 194 | + dates: [...remainDatesOfThisMonth, ...patchDatesOfNextMonth], | ||
| 195 | + ...nextMonth | ||
| 196 | + } | ||
| 197 | + } | ||
| 198 | +} | ||
| 199 | + | ||
| 200 | +/** | ||
| 201 | + * 计算上一周的日期 | ||
| 202 | + */ | ||
| 203 | +function calculatePrevWeekDates(calendarData = {}) { | ||
| 204 | + let { curYear, curMonth } = calendarData | ||
| 205 | + let firstDateInThisWeek = calculateFirstDateOfCurrentWeek(calendarData) | ||
| 206 | + let calendarDates = [] | ||
| 207 | + const { year: FYear, month: FMonth } = firstDateInThisWeek | ||
| 208 | + if (curYear !== FYear || curMonth !== FMonth) { | ||
| 209 | + calendarDates = dateUtil.calcDates(FYear, FMonth) | ||
| 210 | + curYear = FYear | ||
| 211 | + curMonth = FMonth | ||
| 212 | + } else { | ||
| 213 | + calendarDates = dateUtil.calcDates(curYear, curMonth) | ||
| 214 | + } | ||
| 215 | + const firstDateIdx = calendarDates.findIndex( | ||
| 216 | + date => dateUtil.toTimeStr(date) === dateUtil.toTimeStr(firstDateInThisWeek) | ||
| 217 | + ) | ||
| 218 | + if (firstDateIdx - 7 >= 0) { | ||
| 219 | + const startIdx = firstDateIdx - 7 | ||
| 220 | + return { | ||
| 221 | + dates: calendarDates.splice(startIdx, 7), | ||
| 222 | + year: curYear, | ||
| 223 | + month: curMonth | ||
| 224 | + } | ||
| 225 | + } else { | ||
| 226 | + const prevMonth = dateUtil.getPrevMonthInfo({ | ||
| 227 | + year: curYear, | ||
| 228 | + month: curMonth | ||
| 229 | + }) | ||
| 230 | + const { year, month } = prevMonth || {} | ||
| 231 | + const calendarDatesOfPrevMonth = dateUtil.calcDates(year, month) | ||
| 232 | + const remainDatesOfThisMonth = calendarDates.splice( | ||
| 233 | + 0, | ||
| 234 | + firstDateInThisWeek.date - 1 | ||
| 235 | + ) | ||
| 236 | + const patchDatesOfPrevMonth = calendarDatesOfPrevMonth.splice( | ||
| 237 | + -(7 - remainDatesOfThisMonth.length) | ||
| 238 | + ) | ||
| 239 | + return { | ||
| 240 | + dates: [...patchDatesOfPrevMonth, ...remainDatesOfThisMonth], | ||
| 241 | + ...prevMonth | ||
| 242 | + } | ||
| 243 | + } | ||
| 244 | +} | ||
| 245 | + | ||
| 246 | +export default () => { | ||
| 247 | + return { | ||
| 248 | + name: 'week', | ||
| 249 | + beforeRender(calendarData = {}, calendarConfig = {}, component) { | ||
| 250 | + const { initializedWeekMode, selectedDates } = calendarData | ||
| 251 | + if (calendarConfig.weekMode && !initializedWeekMode) { | ||
| 252 | + const { defaultDate } = calendarConfig | ||
| 253 | + const target = | ||
| 254 | + (selectedDates && selectedDates[0]) || | ||
| 255 | + (defaultDate && dateUtil.transformDateRow2Dict(defaultDate)) || | ||
| 256 | + dateUtil.todayFMD() | ||
| 257 | + const waitRenderData = this.methods( | ||
| 258 | + component | ||
| 259 | + ).__calcDatesWhenSwitchView('week', target) | ||
| 260 | + const { data, config } = waitRenderData || {} | ||
| 261 | + const setSelectDates = this.methods( | ||
| 262 | + component | ||
| 263 | + ).__selectTargetDateWhenJump(target, data.dates, config) | ||
| 264 | + return { | ||
| 265 | + calendarData: { | ||
| 266 | + ...data, | ||
| 267 | + ...setSelectDates, | ||
| 268 | + weeksCh: dateUtil.getWeekHeader(calendarConfig.firstDayOfWeek), | ||
| 269 | + initializedWeekMode: true | ||
| 270 | + }, | ||
| 271 | + calendarConfig | ||
| 272 | + } | ||
| 273 | + } | ||
| 274 | + return { | ||
| 275 | + calendarData, | ||
| 276 | + calendarConfig | ||
| 277 | + } | ||
| 278 | + }, | ||
| 279 | + onSwitchCalendar(target = {}, calendarData = {}, component) { | ||
| 280 | + const { direction } = target | ||
| 281 | + const { curYear, curMonth } = calendarData | ||
| 282 | + const calendarConfig = getCalendarConfig(component) | ||
| 283 | + let waitRenderData = {} | ||
| 284 | + if (calendarConfig.weekMode) { | ||
| 285 | + if (direction === 'left') { | ||
| 286 | + waitRenderData = calculateNextWeekDates(calendarData) | ||
| 287 | + } else { | ||
| 288 | + waitRenderData = calculatePrevWeekDates(calendarData) | ||
| 289 | + } | ||
| 290 | + const { dates, year, month } = waitRenderData | ||
| 291 | + return { | ||
| 292 | + ...calendarData, | ||
| 293 | + dates, | ||
| 294 | + curYear: year || curYear, | ||
| 295 | + curMonth: month || curMonth | ||
| 296 | + } | ||
| 297 | + } | ||
| 298 | + return calendarData | ||
| 299 | + }, | ||
| 300 | + methods(component) { | ||
| 301 | + return { | ||
| 302 | + __selectTargetDateWhenJump: (target = {}, dates = [], config = {}) => { | ||
| 303 | + let selectedDate = target | ||
| 304 | + const weekDates = dates.map((date, idx) => { | ||
| 305 | + const tmp = { ...date } | ||
| 306 | + tmp.id = idx | ||
| 307 | + const isTarget = | ||
| 308 | + dateUtil.toTimeStr(target) === dateUtil.toTimeStr(tmp) | ||
| 309 | + if (isTarget && !target.choosed && config.autoChoosedWhenJump) { | ||
| 310 | + tmp.choosed = true | ||
| 311 | + selectedDate = tmp | ||
| 312 | + } | ||
| 313 | + return tmp | ||
| 314 | + }) | ||
| 315 | + return { | ||
| 316 | + dates: weekDates, | ||
| 317 | + selectedDates: [selectedDate] | ||
| 318 | + } | ||
| 319 | + }, | ||
| 320 | + __calcDatesForWeekMode(target, config = {}, calendarData = {}) { | ||
| 321 | + const { year, month } = target || {} | ||
| 322 | + const weekDates = getTargetWeekDates(target, config) | ||
| 323 | + weekDates.forEach((date, idx) => (date.id = idx)) | ||
| 324 | + return { | ||
| 325 | + data: { | ||
| 326 | + ...calendarData, | ||
| 327 | + prevMonthGrids: null, | ||
| 328 | + nextMonthGrids: null, | ||
| 329 | + dates: weekDates, | ||
| 330 | + curYear: year, | ||
| 331 | + curMonth: month | ||
| 332 | + }, | ||
| 333 | + config: { | ||
| 334 | + ...config, | ||
| 335 | + weekMode: true | ||
| 336 | + } | ||
| 337 | + } | ||
| 338 | + }, | ||
| 339 | + __calcDatesForMonthMode(target, config = {}, calendarData = {}) { | ||
| 340 | + const { year, month } = target || {} | ||
| 341 | + const waitRenderData = calcJumpData({ | ||
| 342 | + dateInfo: target, | ||
| 343 | + config | ||
| 344 | + }) | ||
| 345 | + return { | ||
| 346 | + data: { | ||
| 347 | + ...calendarData, | ||
| 348 | + ...waitRenderData, | ||
| 349 | + curYear: year, | ||
| 350 | + curMonth: month | ||
| 351 | + }, | ||
| 352 | + config: { | ||
| 353 | + ...config, | ||
| 354 | + weekMode: false | ||
| 355 | + } | ||
| 356 | + } | ||
| 357 | + }, | ||
| 358 | + /** | ||
| 359 | + * 周、月视图切换 | ||
| 360 | + * @param {string} view 视图 [week, month] | ||
| 361 | + * @param {object} target | ||
| 362 | + */ | ||
| 363 | + __calcDatesWhenSwitchView: (view, target) => { | ||
| 364 | + const calendarConfig = getCalendarConfig(component) | ||
| 365 | + if (calendarConfig.multi) | ||
| 366 | + return logger.warn('多选模式不能切换周月视图') | ||
| 367 | + const existCalendarData = getCalendarData('calendar', component) || {} | ||
| 368 | + const { | ||
| 369 | + selectedDates = [], | ||
| 370 | + dates = [], | ||
| 371 | + curYear, | ||
| 372 | + curMonth | ||
| 373 | + } = existCalendarData | ||
| 374 | + const currentMonthSelected = selectedDates.filter( | ||
| 375 | + item => curYear === +item.year || curMonth === +item.month | ||
| 376 | + ) | ||
| 377 | + let jumpTarget = {} | ||
| 378 | + if (target) { | ||
| 379 | + jumpTarget = target | ||
| 380 | + } else { | ||
| 381 | + if (currentMonthSelected.length) { | ||
| 382 | + jumpTarget = currentMonthSelected.pop() | ||
| 383 | + } else { | ||
| 384 | + jumpTarget = dates[0] | ||
| 385 | + } | ||
| 386 | + } | ||
| 387 | + if (view === 'week') { | ||
| 388 | + return this.methods(component).__calcDatesForWeekMode( | ||
| 389 | + jumpTarget, | ||
| 390 | + calendarConfig, | ||
| 391 | + existCalendarData | ||
| 392 | + ) | ||
| 393 | + } else { | ||
| 394 | + return this.methods(component).__calcDatesForMonthMode( | ||
| 395 | + jumpTarget, | ||
| 396 | + calendarConfig, | ||
| 397 | + existCalendarData | ||
| 398 | + ) | ||
| 399 | + } | ||
| 400 | + }, | ||
| 401 | + weekModeJump: dateInfo => { | ||
| 402 | + const target = dateInfo || dateUtil.todayFMD() | ||
| 403 | + const existCalendarData = getCalendarData('calendar', component) || {} | ||
| 404 | + const waitRenderData = this.methods( | ||
| 405 | + component | ||
| 406 | + ).__calcDatesWhenSwitchView('week', target) | ||
| 407 | + const { data, config } = waitRenderData || {} | ||
| 408 | + const setSelectDates = this.methods( | ||
| 409 | + component | ||
| 410 | + ).__selectTargetDateWhenJump(target, data.dates, config) | ||
| 411 | + return renderCalendar.call( | ||
| 412 | + component, | ||
| 413 | + { | ||
| 414 | + ...existCalendarData, | ||
| 415 | + ...data, | ||
| 416 | + ...setSelectDates | ||
| 417 | + }, | ||
| 418 | + config | ||
| 419 | + ) | ||
| 420 | + }, | ||
| 421 | + switchView: (view, target) => { | ||
| 422 | + const waitRenderData = this.methods( | ||
| 423 | + component | ||
| 424 | + ).__calcDatesWhenSwitchView(view, target) | ||
| 425 | + const { data, config } = waitRenderData || {} | ||
| 426 | + if (!data) return logger.warn('当前状态不能切换为周视图') | ||
| 427 | + return renderCalendar.call(component, data, config) | ||
| 428 | + } | ||
| 429 | + } | ||
| 430 | + } | ||
| 431 | + } | ||
| 432 | +} |
| @@ -0,0 +1,51 @@ | @@ -0,0 +1,51 @@ | ||
| 1 | +import plugins from './plugins/index' | ||
| 2 | +import { getCalendarConfig } from './utils/index' | ||
| 3 | + | ||
| 4 | +/** | ||
| 5 | + * 渲染日历 | ||
| 6 | + */ | ||
| 7 | +export function renderCalendar(calendarData, calendarConfig) { | ||
| 8 | + return new Promise(resolve => { | ||
| 9 | + const Component = this | ||
| 10 | + if (Component.firstRender === void 0) { | ||
| 11 | + Component.firstRender = true | ||
| 12 | + } else { | ||
| 13 | + Component.firstRender = false | ||
| 14 | + } | ||
| 15 | + const exitData = Component.data.calendar || {} | ||
| 16 | + for (let plugin of plugins.installed) { | ||
| 17 | + const [, p] = plugin | ||
| 18 | + if (typeof p.beforeRender === 'function') { | ||
| 19 | + const { | ||
| 20 | + calendarData: newData, | ||
| 21 | + calendarConfig: newConfig | ||
| 22 | + } = p.beforeRender( | ||
| 23 | + { ...exitData, ...calendarData }, | ||
| 24 | + calendarConfig || getCalendarConfig(Component), | ||
| 25 | + Component | ||
| 26 | + ) | ||
| 27 | + calendarData = newData | ||
| 28 | + calendarConfig = newConfig | ||
| 29 | + } | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + Component.setData( | ||
| 33 | + { | ||
| 34 | + config: calendarConfig, | ||
| 35 | + calendar: calendarData | ||
| 36 | + }, | ||
| 37 | + () => { | ||
| 38 | + const rst = { | ||
| 39 | + calendar: calendarData, | ||
| 40 | + config: calendarConfig, | ||
| 41 | + firstRender: Component.firstRender | ||
| 42 | + } | ||
| 43 | + resolve(rst) | ||
| 44 | + if (Component.firstRender) { | ||
| 45 | + Component.triggerEvent('afterCalendarRender', rst) | ||
| 46 | + Component.firstRender = false | ||
| 47 | + } | ||
| 48 | + } | ||
| 49 | + ) | ||
| 50 | + }) | ||
| 51 | +} |
| @@ -0,0 +1,29 @@ | @@ -0,0 +1,29 @@ | ||
| 1 | +@font-face { | ||
| 2 | + font-family: 'iconfont'; | ||
| 3 | + src: url(data:font/truetype;charset=utf-8;base64,AAEAAAANAIAAAwBQRkZUTYda3jUAAAfEAAAAHEdERUYAKQANAAAHpAAAAB5PUy8yPllJ4AAAAVgAAABWY21hcAAP65kAAAHIAAABQmdhc3D//wADAAAHnAAAAAhnbHlmLotR3AAAAxwAAAGkaGVhZBTU+ykAAADcAAAANmhoZWEHKwOFAAABFAAAACRobXR4DasB4gAAAbAAAAAWbG9jYQC0AR4AAAMMAAAAEG1heHABEwAyAAABOAAAACBuYW1lKeYRVQAABMAAAAKIcG9zdEoLnOYAAAdIAAAAUgABAAAAAQAAiPM8al8PPPUACwQAAAAAANjbW5YAAAAA2NtblgCzAAQDTQL8AAAACAACAAAAAAAAAAEAAAOA/4AAXAQAAAAAAANNAAEAAAAAAAAAAAAAAAAAAAAEAAEAAAAHACYAAgAAAAAAAgAAAAoACgAAAP8AAAAAAAAAAQQAAZAABQAAAokCzAAAAI8CiQLMAAAB6wAyAQgAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA5+vn7gOA/4AAXAOAAIAAAAABAAAAAAAABAAAAAAAAAAEAAAABAABLgD4ALQAswAAAAAAAwAAAAMAAAAcAAEAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAA5+7//wAA5+v//xgYAAEAAAAAAAABBgAAAQAAAAAAAAABAgAAAAIAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJgBMAI4A0gABAS4ABAMKAvwAEgAACQEmBh0BFBcJAQYdARQWNwE2NAL+/j0ECQYBaP6YBgkEAcMMAZkBYAMEBU0IBf7n/ucFCE0FBAMBYAoeAAAAAQD4AAQC1AL8ABIAAAE1NCYHAQYUFwEWNj0BNCcJATYC1AkE/j0MDAHDBAkG/pgBaAYCpk0FBAP+oAoeCv6gAwQFTQgFARkBGQUAAAIAtAAgA00C4AASACUAAAkBNiYrASIHAwYUFwEWOwEyNicTATYmKwEiBwMGFBcBFjsBMjYnAREBCQMEBU0IBf8HBwD/BQhNBQQDJwEJAwQFTQgF/wcHAP8FCE0FBAMBgAFTBAkG/roJFgn+ugYJBAFTAVMECQb+ugkWCf66BgkEAAAAAAIAswAgA0wC4AASACUAAAEDJisBIgYXCQEGFjsBMjcBNjQlAyYrASIGFwkBBhY7ATI3ATY0AhX/BQhNBQQDAQn+9wMEBU0IBQD/BwEp/wUITQUEAwEJ/vcDBAVNCAUA/wcBlAFGBgkE/q3+rQQJBgFGCRYJAUYGCQT+rf6tBAkGAUYJFgAAAAAAABIA3gABAAAAAAAAABUALAABAAAAAAABAAgAVAABAAAAAAACAAcAbQABAAAAAAADAAgAhwABAAAAAAAEAAgAogABAAAAAAAFAAsAwwABAAAAAAAGAAgA4QABAAAAAAAKACsBQgABAAAAAAALABMBlgADAAEECQAAACoAAAADAAEECQABABAAQgADAAEECQACAA4AXQADAAEECQADABAAdQADAAEECQAEABAAkAADAAEECQAFABYAqwADAAEECQAGABAAzwADAAEECQAKAFYA6gADAAEECQALACYBbgAKAEMAcgBlAGEAdABlAGQAIABiAHkAIABpAGMAbwBuAGYAbwBuAHQACgAACkNyZWF0ZWQgYnkgaWNvbmZvbnQKAABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABSAGUAZwB1AGwAYQByAABSZWd1bGFyAABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABWAGUAcgBzAGkAbwBuACAAMQAuADAAAFZlcnNpb24gMS4wAABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAHMAdgBnADIAdAB0AGYAIABmAHIAbwBtACAARgBvAG4AdABlAGwAbABvACAAcAByAG8AagBlAGMAdAAuAABHZW5lcmF0ZWQgYnkgc3ZnMnR0ZiBmcm9tIEZvbnRlbGxvIHByb2plY3QuAABoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAABodHRwOi8vZm9udGVsbG8uY29tAAACAAAAAAAAAAoAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAcAAAABAAIBAgEDAQQBBQVyaWdodARsZWZ0CmRvdWJsZWxlZnQLZG91YmxlcmlnaHQAAAAAAAH//wACAAEAAAAMAAAAFgAAAAIAAQADAAYAAQAEAAAAAgAAAAAAAAABAAAAANWkJwgAAAAA2NtblgAAAADY21uW) format('truetype'); | ||
| 4 | + font-weight: normal; | ||
| 5 | + font-style: normal; | ||
| 6 | +} | ||
| 7 | + | ||
| 8 | +.iconfont { | ||
| 9 | + font-family: "iconfont" !important; | ||
| 10 | + font-size: 16px; | ||
| 11 | + font-style: normal; | ||
| 12 | + -webkit-font-smoothing: antialiased; | ||
| 13 | +} | ||
| 14 | + | ||
| 15 | +.icon-right::before { | ||
| 16 | + content: "\e7eb"; | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +.icon-left::before { | ||
| 20 | + content: "\e7ec"; | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +.icon-doubleleft::before { | ||
| 24 | + content: "\e7ed"; | ||
| 25 | +} | ||
| 26 | + | ||
| 27 | +.icon-doubleright::before { | ||
| 28 | + content: "\e7ee"; | ||
| 29 | +} |
| @@ -0,0 +1,61 @@ | @@ -0,0 +1,61 @@ | ||
| 1 | + | ||
| 2 | +/* 日历主要颜色相关样式 */ | ||
| 3 | + | ||
| 4 | +.default_color, | ||
| 5 | +.default_weekend-color, | ||
| 6 | +.default_handle-color, | ||
| 7 | +.default_week-color { | ||
| 8 | + color: #ff629a; | ||
| 9 | +} | ||
| 10 | + | ||
| 11 | +.default_today { | ||
| 12 | + color: #fff; | ||
| 13 | + background-color: #874fb4; | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +.default_choosed { | ||
| 17 | + color: #fff; | ||
| 18 | + background-color: #ff629a; | ||
| 19 | +} | ||
| 20 | + | ||
| 21 | +.default_date-disable { | ||
| 22 | + color: #c7c7c7; | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +.default_choosed.default_date-disable { | ||
| 26 | + color: #e2e2e2; | ||
| 27 | + background-color: #c2afb6; | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +.default_prev-month-date, | ||
| 31 | +.default_next-month-date { | ||
| 32 | + color: #e2e2e2; | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | +.default_normal-date { | ||
| 36 | + color: #88d2ac; | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | +.default_todo-circle { | ||
| 40 | + border-color: #88d2ac; | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +.default_todo-dot { | ||
| 44 | + background-color: #e54d42; | ||
| 45 | +} | ||
| 46 | + | ||
| 47 | +.default_date-desc { | ||
| 48 | + color: #c2c2c2; | ||
| 49 | +} | ||
| 50 | + | ||
| 51 | +.default_date-desc-lunar { | ||
| 52 | + color: #e54d42; | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | +.default_date-desc-disable { | ||
| 56 | + color: #e2e2e2; | ||
| 57 | +} | ||
| 58 | + | ||
| 59 | +.default_festival { | ||
| 60 | + color: #c2c2c2; | ||
| 61 | +} |
| @@ -0,0 +1,58 @@ | @@ -0,0 +1,58 @@ | ||
| 1 | +.elegant_color, | ||
| 2 | +.elegant_weekend-color, | ||
| 3 | +.elegant_handle-color, | ||
| 4 | +.elegant_week-color { | ||
| 5 | + color: #333; | ||
| 6 | +} | ||
| 7 | + | ||
| 8 | +.elegant_today { | ||
| 9 | + color: #000; | ||
| 10 | + background-color: #e1e7f5; | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +.elegant_choosed { | ||
| 14 | + color: #000; | ||
| 15 | + background-color: #e2e2e2; | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +.elegant_date-disable { | ||
| 19 | + color: #c7c7c7; | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +.elegant_choosed.elegant_date-disable { | ||
| 23 | + color: #999; | ||
| 24 | + background-color: #ebebeb; | ||
| 25 | +} | ||
| 26 | + | ||
| 27 | +.elegant_prev-month-date, | ||
| 28 | +.elegant_next-month-date { | ||
| 29 | + color: #e2e2e2; | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +.elegant_normal-date { | ||
| 33 | + color: #777; | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | +.elegant_todo-circle { | ||
| 37 | + border-color: #161035; | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +.elegant_todo-dot { | ||
| 41 | + background-color: #161035; | ||
| 42 | +} | ||
| 43 | + | ||
| 44 | +.elegant_date-desc { | ||
| 45 | + color: #c2c2c2; | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +.elegant_date-desc-lunar { | ||
| 49 | + color: #161035; | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +.elegant_date-desc-disable { | ||
| 53 | + color: #e2e2e2; | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +.elegant_festival { | ||
| 57 | + color: #c2c2c2; | ||
| 58 | +} |
| @@ -0,0 +1,284 @@ | @@ -0,0 +1,284 @@ | ||
| 1 | +import Logger from './logger' | ||
| 2 | +import WxData from './wxData' | ||
| 3 | + | ||
| 4 | +let systemInfo | ||
| 5 | +export function getSystemInfo() { | ||
| 6 | + if (systemInfo) return systemInfo | ||
| 7 | + systemInfo = wx.getSystemInfoSync() | ||
| 8 | + return systemInfo | ||
| 9 | +} | ||
| 10 | + | ||
| 11 | +export function isIos() { | ||
| 12 | + const sys = getSystemInfo() | ||
| 13 | + return /iphone|ios/i.test(sys.platform) | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +class Gesture { | ||
| 17 | + /** | ||
| 18 | + * 左滑 | ||
| 19 | + * @param {object} e 事件对象 | ||
| 20 | + * @returns {boolean} 布尔值 | ||
| 21 | + */ | ||
| 22 | + isLeft(gesture = {}, touche = {}) { | ||
| 23 | + const { startX, startY } = gesture | ||
| 24 | + const deltaX = touche.clientX - startX | ||
| 25 | + const deltaY = touche.clientY - startY | ||
| 26 | + if (deltaX < -60 && deltaY < 20 && deltaY > -20) { | ||
| 27 | + return true | ||
| 28 | + } else { | ||
| 29 | + return false | ||
| 30 | + } | ||
| 31 | + } | ||
| 32 | + /** | ||
| 33 | + * 右滑 | ||
| 34 | + * @param {object} e 事件对象 | ||
| 35 | + * @returns {boolean} 布尔值 | ||
| 36 | + */ | ||
| 37 | + isRight(gesture = {}, touche = {}) { | ||
| 38 | + const { startX, startY } = gesture | ||
| 39 | + const deltaX = touche.clientX - startX | ||
| 40 | + const deltaY = touche.clientY - startY | ||
| 41 | + | ||
| 42 | + if (deltaX > 60 && deltaY < 20 && deltaY > -20) { | ||
| 43 | + return true | ||
| 44 | + } else { | ||
| 45 | + return false | ||
| 46 | + } | ||
| 47 | + } | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +class DateUtil { | ||
| 51 | + newDate(year, month, date) { | ||
| 52 | + let cur = `${+year}-${+month}-${+date}` | ||
| 53 | + if (isIos()) { | ||
| 54 | + cur = `${+year}/${+month}/${+date}` | ||
| 55 | + } | ||
| 56 | + return new Date(cur) | ||
| 57 | + } | ||
| 58 | + /** | ||
| 59 | + * 计算指定日期时间戳 | ||
| 60 | + * @param {object} date | ||
| 61 | + */ | ||
| 62 | + getTimeStamp(dateInfo) { | ||
| 63 | + if (typeof dateInfo === 'string') { | ||
| 64 | + dateInfo = this.transformDateRow2Dict(dateInfo) | ||
| 65 | + } | ||
| 66 | + if (Object.prototype.toString.call(dateInfo) !== '[object Object]') return | ||
| 67 | + const dateUtil = new DateUtil() | ||
| 68 | + return dateUtil | ||
| 69 | + .newDate(dateInfo.year, dateInfo.month, dateInfo.date) | ||
| 70 | + .getTime() | ||
| 71 | + } | ||
| 72 | + /** | ||
| 73 | + * 计算指定月份共多少天 | ||
| 74 | + * @param {number} year 年份 | ||
| 75 | + * @param {number} month 月份 | ||
| 76 | + */ | ||
| 77 | + getDatesCountOfMonth(year, month) { | ||
| 78 | + return new Date(Date.UTC(year, month, 0)).getUTCDate() | ||
| 79 | + } | ||
| 80 | + /** | ||
| 81 | + * 计算指定月份第一天星期几 | ||
| 82 | + * @param {number} year 年份 | ||
| 83 | + * @param {number} month 月份 | ||
| 84 | + */ | ||
| 85 | + firstDayOfWeek(year, month) { | ||
| 86 | + return new Date(Date.UTC(year, month - 1, 1)).getUTCDay() | ||
| 87 | + } | ||
| 88 | + /** | ||
| 89 | + * 计算指定日期星期几 | ||
| 90 | + * @param {number} year 年份 | ||
| 91 | + * @param {number} month 月份 | ||
| 92 | + * @param {number} date 日期 | ||
| 93 | + */ | ||
| 94 | + getDayOfWeek(year, month, date) { | ||
| 95 | + return new Date(Date.UTC(year, month - 1, date)).getUTCDay() | ||
| 96 | + } | ||
| 97 | + formatTimestamp(timestamp) { | ||
| 98 | + const date = new Date(timestamp) | ||
| 99 | + return { | ||
| 100 | + year: date.getFullYear(), | ||
| 101 | + month: date.getMonth() + 1, | ||
| 102 | + date: date.getDate() | ||
| 103 | + } | ||
| 104 | + } | ||
| 105 | + todayTimestamp() { | ||
| 106 | + return new Date().getTime() | ||
| 107 | + } | ||
| 108 | + todayFMD() { | ||
| 109 | + const timestamp = this.todayTimestamp() | ||
| 110 | + return this.formatTimestamp(timestamp) | ||
| 111 | + } | ||
| 112 | + toTimeStr(dateInfo = {}) { | ||
| 113 | + return `${+dateInfo.year}-${+dateInfo.month}-${+dateInfo.date}` | ||
| 114 | + } | ||
| 115 | + transformDateRow2Dict(dateStr) { | ||
| 116 | + if (typeof dateStr === 'string' && dateStr.includes('-')) { | ||
| 117 | + const [year, month, date] = dateStr.split('-') | ||
| 118 | + return this.tranformStr2NumOfDate({ | ||
| 119 | + year, | ||
| 120 | + month, | ||
| 121 | + date | ||
| 122 | + }) | ||
| 123 | + } | ||
| 124 | + return {} | ||
| 125 | + } | ||
| 126 | + tranformStr2NumOfDate(date = {}) { | ||
| 127 | + const target = { ...date } | ||
| 128 | + // 可能传入字符串 | ||
| 129 | + target.year = +target.year | ||
| 130 | + target.month = +target.month | ||
| 131 | + target.date = +target.date | ||
| 132 | + return target | ||
| 133 | + } | ||
| 134 | + sortDatesByTime(dates = [], sortType) { | ||
| 135 | + return dates.sort((a, b) => { | ||
| 136 | + const at = this.getTimeStamp(a) | ||
| 137 | + const bt = this.getTimeStamp(b) | ||
| 138 | + if (at < bt && sortType !== 'desc') { | ||
| 139 | + return -1 | ||
| 140 | + } else { | ||
| 141 | + return 1 | ||
| 142 | + } | ||
| 143 | + }) | ||
| 144 | + } | ||
| 145 | + getPrevMonthInfo(date = {}) { | ||
| 146 | + const prevMonthInfo = | ||
| 147 | + Number(date.month) > 1 | ||
| 148 | + ? { | ||
| 149 | + year: +date.year, | ||
| 150 | + month: Number(date.month) - 1 | ||
| 151 | + } | ||
| 152 | + : { | ||
| 153 | + year: Number(date.year) - 1, | ||
| 154 | + month: 12 | ||
| 155 | + } | ||
| 156 | + return prevMonthInfo | ||
| 157 | + } | ||
| 158 | + getNextMonthInfo(date = {}) { | ||
| 159 | + const nextMonthInfo = | ||
| 160 | + Number(date.month) < 12 | ||
| 161 | + ? { | ||
| 162 | + year: +date.year, | ||
| 163 | + month: Number(date.month) + 1 | ||
| 164 | + } | ||
| 165 | + : { | ||
| 166 | + year: Number(date.year) + 1, | ||
| 167 | + month: 1 | ||
| 168 | + } | ||
| 169 | + return nextMonthInfo | ||
| 170 | + } | ||
| 171 | + getPrevYearInfo(date = {}) { | ||
| 172 | + return { | ||
| 173 | + year: Number(date.year) - 1, | ||
| 174 | + month: +date.month | ||
| 175 | + } | ||
| 176 | + } | ||
| 177 | + getNextYearInfo(date = {}) { | ||
| 178 | + return { | ||
| 179 | + year: Number(date.year) + 1, | ||
| 180 | + month: +date.month | ||
| 181 | + } | ||
| 182 | + } | ||
| 183 | + findDateIndexInArray(target, dates) { | ||
| 184 | + return dates.findIndex( | ||
| 185 | + item => dateUtil.toTimeStr(item) === dateUtil.toTimeStr(target) | ||
| 186 | + ) | ||
| 187 | + } | ||
| 188 | + calcDates(year, month) { | ||
| 189 | + const datesCount = this.getDatesCountOfMonth(year, month) | ||
| 190 | + const dates = [] | ||
| 191 | + const today = dateUtil.todayFMD() | ||
| 192 | + for (let i = 1; i <= datesCount; i++) { | ||
| 193 | + const week = dateUtil.getDayOfWeek(+year, +month, i) | ||
| 194 | + const date = { | ||
| 195 | + year: +year, | ||
| 196 | + id: i - 1, | ||
| 197 | + month: +month, | ||
| 198 | + date: i, | ||
| 199 | + week, | ||
| 200 | + isToday: | ||
| 201 | + +today.year === +year && +today.month === +month && i === +today.date | ||
| 202 | + } | ||
| 203 | + dates.push(date) | ||
| 204 | + } | ||
| 205 | + return dates | ||
| 206 | + } | ||
| 207 | + /** | ||
| 208 | + * 日期数组根据日期去重 | ||
| 209 | + * @param {array} array 数组 | ||
| 210 | + */ | ||
| 211 | + uniqueArrayByDate(array = []) { | ||
| 212 | + let uniqueObject = {} | ||
| 213 | + let uniqueArray = [] | ||
| 214 | + array.forEach(item => { | ||
| 215 | + uniqueObject[dateUtil.toTimeStr(item)] = item | ||
| 216 | + }) | ||
| 217 | + for (let i in uniqueObject) { | ||
| 218 | + uniqueArray.push(uniqueObject[i]) | ||
| 219 | + } | ||
| 220 | + return uniqueArray | ||
| 221 | + } | ||
| 222 | + /** | ||
| 223 | + * 筛选指定年月日期 | ||
| 224 | + * @param {object} target 指定年月 | ||
| 225 | + * @param {array} dates 待筛选日期 | ||
| 226 | + */ | ||
| 227 | + filterDatesByYM(target, dates) { | ||
| 228 | + if (target) { | ||
| 229 | + const { year, month } = target | ||
| 230 | + const _dates = dates.filter( | ||
| 231 | + item => +item.year === +year && +item.month === +month | ||
| 232 | + ) | ||
| 233 | + return _dates | ||
| 234 | + } | ||
| 235 | + return dates | ||
| 236 | + } | ||
| 237 | + getWeekHeader(firstDayOfWeek) { | ||
| 238 | + let weeksCh = ['日', '一', '二', '三', '四', '五', '六'] | ||
| 239 | + if (firstDayOfWeek === 'Mon') { | ||
| 240 | + weeksCh = ['一', '二', '三', '四', '五', '六', '日'] | ||
| 241 | + } | ||
| 242 | + return weeksCh | ||
| 243 | + } | ||
| 244 | +} | ||
| 245 | + | ||
| 246 | +/** | ||
| 247 | + * 获取当前页面实例 | ||
| 248 | + */ | ||
| 249 | +export function getCurrentPage() { | ||
| 250 | + const pages = getCurrentPages() || [] | ||
| 251 | + const last = pages.length - 1 | ||
| 252 | + return pages[last] || {} | ||
| 253 | +} | ||
| 254 | + | ||
| 255 | +export function getComponentById(componentId) { | ||
| 256 | + const logger = new Logger() | ||
| 257 | + let page = getCurrentPage() || {} | ||
| 258 | + if (page.selectComponent && typeof page.selectComponent === 'function') { | ||
| 259 | + if (componentId) { | ||
| 260 | + return page.selectComponent(componentId) | ||
| 261 | + } else { | ||
| 262 | + logger.warn('请传入组件ID') | ||
| 263 | + } | ||
| 264 | + } else { | ||
| 265 | + logger.warn('该基础库暂不支持多个小程序日历组件') | ||
| 266 | + } | ||
| 267 | +} | ||
| 268 | + | ||
| 269 | +export const logger = new Logger() | ||
| 270 | +export const calendarGesture = new Gesture() | ||
| 271 | +export const dateUtil = new DateUtil() | ||
| 272 | +export const getCalendarData = (key, component) => | ||
| 273 | + new WxData(component).getData(key) | ||
| 274 | +export const setCalendarData = (data, component) => | ||
| 275 | + new WxData(component).setData(data) | ||
| 276 | +export const getCalendarConfig = component => | ||
| 277 | + getCalendarData('config', component) | ||
| 278 | +export const setCalendarConfig = (config, component) => | ||
| 279 | + setCalendarData( | ||
| 280 | + { | ||
| 281 | + config | ||
| 282 | + }, | ||
| 283 | + component | ||
| 284 | + ) |
| @@ -0,0 +1,23 @@ | @@ -0,0 +1,23 @@ | ||
| 1 | +export default class Logger { | ||
| 2 | + info(msg) { | ||
| 3 | + console.log( | ||
| 4 | + '%cInfo: %c' + msg, | ||
| 5 | + 'color:#FF0080;font-weight:bold', | ||
| 6 | + 'color: #FF509B' | ||
| 7 | + ) | ||
| 8 | + } | ||
| 9 | + warn(msg) { | ||
| 10 | + console.log( | ||
| 11 | + '%cWarn: %c' + msg, | ||
| 12 | + 'color:#FF6600;font-weight:bold', | ||
| 13 | + 'color: #FF9933' | ||
| 14 | + ) | ||
| 15 | + } | ||
| 16 | + tips(msg) { | ||
| 17 | + console.log( | ||
| 18 | + '%cTips: %c' + msg, | ||
| 19 | + 'color:#00B200;font-weight:bold', | ||
| 20 | + 'color: #00CC33' | ||
| 21 | + ) | ||
| 22 | + } | ||
| 23 | +} |
| @@ -0,0 +1,30 @@ | @@ -0,0 +1,30 @@ | ||
| 1 | +class WxData { | ||
| 2 | + constructor(component) { | ||
| 3 | + this.Component = component | ||
| 4 | + } | ||
| 5 | + getData(key) { | ||
| 6 | + const data = this.Component.data | ||
| 7 | + if (!key) return data | ||
| 8 | + if (key.includes('.')) { | ||
| 9 | + let keys = key.split('.') | ||
| 10 | + const tmp = keys.reduce((prev, next) => { | ||
| 11 | + return prev[next] | ||
| 12 | + }, data) | ||
| 13 | + return tmp | ||
| 14 | + } else { | ||
| 15 | + return this.Component.data[key] | ||
| 16 | + } | ||
| 17 | + } | ||
| 18 | + setData(data) { | ||
| 19 | + return new Promise((resolve, reject) => { | ||
| 20 | + if (!data) return reject('no data to set') | ||
| 21 | + if (typeof data === 'object') { | ||
| 22 | + this.Component.setData(data, () => { | ||
| 23 | + resolve(data) | ||
| 24 | + }) | ||
| 25 | + } | ||
| 26 | + }) | ||
| 27 | + } | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +export default WxData |
config.js
| 1 | //域名要在小程序的管理平台配置好,如果出现调用时报错,无效的域名,可在微信开发工具左边点项目-》配置信息-》看一下配置的域名【request合法域名】有没有刷新下来,没有的话就点下面的刷新 | 1 | //域名要在小程序的管理平台配置好,如果出现调用时报错,无效的域名,可在微信开发工具左边点项目-》配置信息-》看一下配置的域名【request合法域名】有没有刷新下来,没有的话就点下面的刷新 |
| 2 | 2 | ||
| 3 | -let host = 'https://proxy.shunzhi.net/'; //正式 | 3 | +// let host = 'https://proxy.shunzhi.net/'; //正式 |
| 4 | +let host = 'https://proxy.shunzhi.net/card'; //正式 | ||
| 4 | 5 | ||
| 5 | let file = 'https://wxsxh.myjxt.com:51314/file-center/'; //图片上传 | 6 | let file = 'https://wxsxh.myjxt.com:51314/file-center/'; //图片上传 |
| 6 | 7 |
2.52 KB
2.9 KB
3.28 KB
12.7 KB
1.62 KB
4.08 KB
1.16 KB
5.09 KB
6.51 KB
4.32 KB
62.6 KB
3.82 KB
2.99 KB
4.35 KB
2.95 KB
84.5 KB
package-lock.json
| 1 | { | 1 | { |
| 2 | - "name": "sxhClockIn", | ||
| 3 | - "version": "2.0.0", | ||
| 4 | - "lockfileVersion": 2, | 2 | + "name": "sxh_clock_in", |
| 3 | + "version": "1.0.0", | ||
| 4 | + "lockfileVersion": 1, | ||
| 5 | "requires": true, | 5 | "requires": true, |
| 6 | - "packages": { | ||
| 7 | - "": { | ||
| 8 | - "name": "sxhClockIn", | ||
| 9 | - "version": "2.0.0", | ||
| 10 | - "license": "ISC", | ||
| 11 | - "dependencies": { | ||
| 12 | - "@vant/weapp": "^1.10.5" | ||
| 13 | - } | ||
| 14 | - }, | ||
| 15 | - "node_modules/@vant/weapp": { | ||
| 16 | - "version": "1.10.5", | ||
| 17 | - "resolved": "https://registry.npmmirror.com/@vant/weapp/-/weapp-1.10.5.tgz", | ||
| 18 | - "integrity": "sha512-bAHp9r0ZiRsOqPOLzQHI/ZvkAlXzol1/TFhM70MyghuxkzJTjcDUd8RIfLkCN3c1MCK/PfBGw2an8/afygftCg==" | ||
| 19 | - } | ||
| 20 | - }, | ||
| 21 | "dependencies": { | 6 | "dependencies": { |
| 22 | "@vant/weapp": { | 7 | "@vant/weapp": { |
| 23 | "version": "1.10.5", | 8 | "version": "1.10.5", |
| 24 | "resolved": "https://registry.npmmirror.com/@vant/weapp/-/weapp-1.10.5.tgz", | 9 | "resolved": "https://registry.npmmirror.com/@vant/weapp/-/weapp-1.10.5.tgz", |
| 25 | "integrity": "sha512-bAHp9r0ZiRsOqPOLzQHI/ZvkAlXzol1/TFhM70MyghuxkzJTjcDUd8RIfLkCN3c1MCK/PfBGw2an8/afygftCg==" | 10 | "integrity": "sha512-bAHp9r0ZiRsOqPOLzQHI/ZvkAlXzol1/TFhM70MyghuxkzJTjcDUd8RIfLkCN3c1MCK/PfBGw2an8/afygftCg==" |
| 11 | + }, | ||
| 12 | + "moment": { | ||
| 13 | + "version": "2.29.4", | ||
| 14 | + "resolved": "https://registry.npmmirror.com/moment/-/moment-2.29.4.tgz", | ||
| 15 | + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" | ||
| 26 | } | 16 | } |
| 27 | } | 17 | } |
| 28 | } | 18 | } |
package.json
| @@ -4,7 +4,8 @@ | @@ -4,7 +4,8 @@ | ||
| 4 | "description": "计划管家", | 4 | "description": "计划管家", |
| 5 | "main": "app.js", | 5 | "main": "app.js", |
| 6 | "dependencies": { | 6 | "dependencies": { |
| 7 | - "@vant/weapp": "^1.10.5" | 7 | + "@vant/weapp": "^1.10.5", |
| 8 | + "moment": "^2.29.4" | ||
| 8 | }, | 9 | }, |
| 9 | "scripts": { | 10 | "scripts": { |
| 10 | "test": "echo \"Error: no test specified\" && exit 1" | 11 | "test": "echo \"Error: no test specified\" && exit 1" |
pages/index/achievement/achievement.js
| 1 | // pages/index/achievement/achievement.js | 1 | // pages/index/achievement/achievement.js |
| 2 | +// 引入插件安装器 | ||
| 3 | +import plugin from '../../../component/v2/plugins/index' | ||
| 4 | +import week from '../../../component/v2/plugins/week' | ||
| 5 | +import todo from '../../../component/v2/plugins/todo' | ||
| 6 | +import request from '../../../api/request.js' | ||
| 7 | +import moment from 'moment'; | ||
| 8 | +plugin | ||
| 9 | + .use(week) | ||
| 10 | + .use(todo) | ||
| 2 | Page({ | 11 | Page({ |
| 3 | 12 | ||
| 4 | /** | 13 | /** |
| 5 | * 页面的初始数据 | 14 | * 页面的初始数据 |
| 6 | */ | 15 | */ |
| 7 | data: { | 16 | data: { |
| 17 | + calendarConfig: { | ||
| 18 | + theme: 'elegant', | ||
| 19 | + weekMode: true, // 周视图模式 | ||
| 20 | + // highlightToday: true, // 是否高亮显示当天 | ||
| 21 | + hideHeader: true, // 隐藏日历头部操作栏 | ||
| 22 | + autoChoosedWhenJump: true, // 设置默认日期及跳转到指定日期后是否需要自动选中 | ||
| 23 | + defaultDate: moment(new Date().getTime()).format('YYYY-MM-DD'), // 默认选中指定某天,如需选中需配置 autoChoosedWhenJump: true | ||
| 24 | + }, | ||
| 25 | + isDisplay: false, | ||
| 26 | + calendar: {}, //日历 | ||
| 27 | + valueId: '', //任务ID | ||
| 28 | + taskVo: { | ||
| 29 | + allowRepairCard: 0, | ||
| 30 | + hasData: 0, | ||
| 31 | + statisticsUnit: "", | ||
| 32 | + submitCondition: "", | ||
| 33 | + id: 0, | ||
| 34 | + releaseTime: "", | ||
| 35 | + signTotal: 0, | ||
| 36 | + taskCycle: 0, | ||
| 37 | + taskDesc: "", | ||
| 38 | + taskFrequency: "", | ||
| 39 | + taskTitle: "", | ||
| 40 | + weekDay: "" | ||
| 41 | + }, | ||
| 42 | + resData: [], //成果数据 | ||
| 43 | + recordVo: { | ||
| 44 | + commitTime: "", | ||
| 45 | + files: [], | ||
| 46 | + signDate: "", | ||
| 47 | + taskRecordDesc: "", | ||
| 48 | + taskStatisticsParam: "" | ||
| 49 | + }, //成果数据当天 | ||
| 50 | + recordVoShow: false, | ||
| 51 | + dayMoment: 0, //数据月份 | ||
| 52 | + }, | ||
| 53 | + /** | ||
| 54 | + * 选择日期后执行的事件 | ||
| 55 | + */ | ||
| 56 | + afterTapDate(e) { | ||
| 57 | + let date = e.detail.date | ||
| 58 | + // let month = e.detail.month | ||
| 59 | + // let year = e.detail.year | ||
| 60 | + let recordVo = this.data.resData.eventDetails[date - 1].recordVo | ||
| 61 | + if (recordVo != null) { | ||
| 62 | + console.log('复制', recordVo) | ||
| 63 | + this.setData({ | ||
| 64 | + recordVo: recordVo | ||
| 65 | + }) | ||
| 66 | + this.setData({ | ||
| 67 | + recordVoShow: true | ||
| 68 | + }) | ||
| 69 | + } else { | ||
| 70 | + this.setData({ | ||
| 71 | + recordVoShow: false | ||
| 72 | + }) | ||
| 73 | + } | ||
| 74 | + }, | ||
| 75 | + //获取信息 | ||
| 76 | + getInfo(doday, isOne = 0) { | ||
| 77 | + request({ | ||
| 78 | + url: `/wx/task/getSignRecord`, | ||
| 79 | + method: 'get', | ||
| 80 | + data: { | ||
| 81 | + // wx.getStorageSync('userInfo_id'), | ||
| 82 | + "taskId": this.data.valueId, | ||
| 83 | + "signDate": doday | ||
| 84 | + }, | ||
| 85 | + }).then(res => { | ||
| 86 | + if (res.code == 0) { | ||
| 87 | + this.setData({ | ||
| 88 | + resData: res.data | ||
| 89 | + }) | ||
| 90 | + this.getV2(res.data) | ||
| 91 | + if (isOne == 1) { | ||
| 92 | + let e = { | ||
| 93 | + detail: { | ||
| 94 | + date: moment().date(), | ||
| 95 | + month: moment().month() + 1, | ||
| 96 | + year: moment().year() | ||
| 97 | + } | ||
| 98 | + } | ||
| 99 | + this.afterTapDate(e) | ||
| 100 | + } | ||
| 101 | + } else { | ||
| 102 | + wx.showToast({ | ||
| 103 | + title: res.msg, | ||
| 104 | + icon: 'none' | ||
| 105 | + }) | ||
| 106 | + } | ||
| 107 | + }) | ||
| 108 | + }, | ||
| 109 | + //初始化日历 | ||
| 110 | + initialize() { | ||
| 111 | + // 设置待办 | ||
| 112 | + this.setData({ | ||
| 113 | + 'calendar': this.selectComponent('#calendar').calendar | ||
| 114 | + }) | ||
| 115 | + }, | ||
| 116 | + //显示日历 | ||
| 117 | + getV2(resData) { | ||
| 118 | + this.setData({ | ||
| 119 | + taskVo: resData.taskVo | ||
| 120 | + }) | ||
| 121 | + // const calendar = this.selectComponent('#calendar').calendar | ||
| 122 | + this.data.calendar.setTodos({ | ||
| 123 | + // 待办点标记设置 | ||
| 124 | + pos: 'bottom', // 待办点标记位置 ['top', 'bottom'] | ||
| 125 | + dotColor: 'red', // 待办点标记颜色 | ||
| 126 | + circle: false, // 待办圆圈标记设置(如圆圈标记已签到日期),该设置与点标记设置互斥 | ||
| 127 | + showLabelAlways: true, // 点击时是否显示待办事项(圆点/文字),在 circle 为 true 及当日历配置 showLunar 为 true 时,此配置失效 | ||
| 128 | + dates: resData.eventDetails | ||
| 129 | + }) | ||
| 8 | }, | 130 | }, |
| 9 | - | ||
| 10 | /** | 131 | /** |
| 11 | * 生命周期函数--监听页面加载 | 132 | * 生命周期函数--监听页面加载 |
| 12 | */ | 133 | */ |
| 13 | onLoad(options) { | 134 | onLoad(options) { |
| 14 | - | 135 | + this.setData({ |
| 136 | + valueId: options.valueId | ||
| 137 | + }) | ||
| 15 | }, | 138 | }, |
| 16 | // 统一返回 | 139 | // 统一返回 |
| 17 | handleBack() { | 140 | handleBack() { |
| 18 | wx.navigateBack() | 141 | wx.navigateBack() |
| 19 | }, | 142 | }, |
| 20 | /** | 143 | /** |
| 21 | - * 用户点击右上角分享 | 144 | + * 生命周期函数--监听页面初次渲染完成 |
| 22 | */ | 145 | */ |
| 23 | - onShareAppMessage() { | ||
| 24 | - | ||
| 25 | - } | 146 | + onReady() { |
| 147 | + this.initialize() | ||
| 148 | + this.getInfo(moment(new Date().getTime()).format('YYYY-MM-DD'), 1) | ||
| 149 | + }, | ||
| 26 | }) | 150 | }) |
| 27 | \ No newline at end of file | 151 | \ No newline at end of file |
pages/index/achievement/achievement.json
| 1 | { | 1 | { |
| 2 | "usingComponents": { | 2 | "usingComponents": { |
| 3 | - "van-icon": "@vant/weapp/icon/index" | 3 | + "van-icon": "@vant/weapp/icon/index", |
| 4 | + "calendar": "/component/v2/index", | ||
| 5 | + "van-popup": "@vant/weapp/popup/index", | ||
| 6 | + "van-field": "@vant/weapp/field/index", | ||
| 7 | + "van-image": "@vant/weapp/image/index", | ||
| 8 | + "van-button": "@vant/weapp/button/index" | ||
| 4 | }, | 9 | }, |
| 5 | - "navigationStyle": "custom" | 10 | + "navigationBarTitleText": "我的成果" |
| 6 | } | 11 | } |
| 7 | \ No newline at end of file | 12 | \ No newline at end of file |
pages/index/achievement/achievement.wxml
| 1 | <!--pages/index/achievement/achievement.wxml--> | 1 | <!--pages/index/achievement/achievement.wxml--> |
| 2 | <view class="punch_detail"> | 2 | <view class="punch_detail"> |
| 3 | - <!-- 顶部统一返回 --> | ||
| 4 | - <view class="navigation_back" bindtap="handleBack"> | ||
| 5 | - <van-icon name="arrow-left" /> | 3 | + <calendar id="calendar" config="{{calendarConfig}}" bind:afterTapDate="afterTapDate"/> |
| 4 | + <!-- <view class="btn" bindtap="getInfo">按钮</view> --> | ||
| 5 | + <view class="line_grey"></view> | ||
| 6 | + <view class="card"> | ||
| 7 | + <view class="card_title">{{taskVo.taskTitle}}</view> | ||
| 8 | + <view class="card_flex"> | ||
| 9 | + <view class="flex_grey">已进行 {{taskVo.signTotal +' / ' +taskVo.taskCycle}} 天</view> | ||
| 10 | + <view class="flex_grey">打卡频次 : {{taskVo.taskFrequency}}</view> | ||
| 11 | + <view class="flex_grey">{{taskVo.allowRepairCard == 1 ?'允许补卡': '不允许补卡'}}</view> | ||
| 12 | + </view> | ||
| 13 | + <view class="card_context">{{taskVo.taskDesc}}</view> | ||
| 14 | + <view class="grey_font"> | ||
| 15 | + <view>我发布与{{taskVo.weekDay}} {{taskVo.releaseTime}}</view> | ||
| 16 | + <view class="grey_font_bottom"></view> | ||
| 17 | + </view> | ||
| 6 | </view> | 18 | </view> |
| 7 | - <image class="temporary" src="/img/_check_in5.png" mode="widthFix" alt="" /> | ||
| 8 | 19 | ||
| 20 | + <view class="grey_line"></view> | ||
| 21 | + <view class="box" wx:if="{{recordVoShow}}"> | ||
| 22 | + <view class="box_title">打卡成果</view> | ||
| 23 | + <view class="box_blue" wx:if="{{recordVo.hasData==1}}">本次打卡坚持了<span>{{recordVo.taskStatisticsParam}}{{taskVo.statisticsUnit}}</span></view> | ||
| 24 | + <view class="box_grey">"{{recordVo.taskRecordDesc}}"</view> | ||
| 25 | + <view class="box_pic"> | ||
| 26 | + <view class="box_img" wx:for="{{recordVo.files}}" wx:key="index" wx:for-item="value"> | ||
| 27 | + <van-image width="100%" height="26vw" fit="fill" src="{{value}}" /> | ||
| 28 | + </view> | ||
| 29 | + </view> | ||
| 30 | + </view> | ||
| 9 | </view> | 31 | </view> |
| 10 | \ No newline at end of file | 32 | \ No newline at end of file |
pages/index/achievement/achievement.wxss
| 1 | /* pages/index/achievement/achievement.wxss */ | 1 | /* pages/index/achievement/achievement.wxss */ |
| 2 | +.btn { | ||
| 3 | + width: 20vw; | ||
| 4 | + height: 20vw; | ||
| 5 | + background-color: aqua; | ||
| 6 | + font-size: 5vw; | ||
| 7 | +} | ||
| 8 | +.line_grey { | ||
| 9 | + width: 90vw; | ||
| 10 | + height: 1px; | ||
| 11 | + background-color: #999; | ||
| 12 | + margin: 10px 5vw 20px; | ||
| 13 | +} | ||
| 14 | +.card { | ||
| 15 | + width: 92vw; | ||
| 16 | + margin-left: 4vw; | ||
| 17 | +} | ||
| 18 | +.card_title { | ||
| 19 | + font-size: 18px; | ||
| 20 | + color: #556191; | ||
| 21 | + margin: 15px 0; | ||
| 22 | +} | ||
| 23 | +.card_flex { | ||
| 24 | + display: flex; | ||
| 25 | +} | ||
| 26 | +.flex_grey { | ||
| 27 | + padding: 7px 10px; | ||
| 28 | + box-sizing: border-box; | ||
| 29 | + margin: 0 5px 10px 0; | ||
| 30 | + font-size: 13px; | ||
| 31 | + background-color: #F4F4F4; | ||
| 32 | + color: #666666; | ||
| 33 | + border-radius: 3px; | ||
| 34 | +} | ||
| 35 | +.card_context { | ||
| 36 | + font-size: 16px; | ||
| 37 | + margin: 10px 0; | ||
| 38 | +} | ||
| 39 | +.grey_font { | ||
| 40 | + font-size: 14px; | ||
| 41 | + color: #999999; | ||
| 42 | + margin: 20px 0; | ||
| 43 | +} | ||
| 44 | +.grey_font_bottom { | ||
| 45 | + margin-top: 5px; | ||
| 46 | +} | ||
| 47 | +.btn_box { | ||
| 48 | + display: flex; | ||
| 49 | + justify-content: space-around; | ||
| 50 | + position: fixed; | ||
| 51 | + bottom: 50px; | ||
| 52 | + width: 100vw; | ||
| 53 | +} | ||
| 54 | +.pop_title { | ||
| 55 | + font-size: 18px; | ||
| 56 | + font-weight: bold; | ||
| 57 | + text-align: center; | ||
| 58 | + margin: 20px 0; | ||
| 59 | +} | ||
| 60 | +.pop_flex { | ||
| 61 | + display: flex; | ||
| 62 | + justify-content: space-between; | ||
| 63 | + align-items: center; | ||
| 64 | + padding: 0 20px; | ||
| 65 | + box-sizing: border-box; | ||
| 66 | +} | ||
| 67 | +.pop_cell { | ||
| 68 | + width: 40vw; | ||
| 69 | + display: flex; | ||
| 70 | + align-items: center; | ||
| 71 | +} | ||
| 72 | +.pop_fz { | ||
| 73 | + width: 70px; | ||
| 74 | +} | ||
| 75 | +.pop_btn { | ||
| 76 | + position: absolute; | ||
| 77 | + bottom: 30px; | ||
| 78 | + width: 90vw; | ||
| 79 | + margin: 0 5vw; | ||
| 80 | +} | ||
| 81 | +.pop_tip { | ||
| 82 | + position: absolute; | ||
| 83 | + bottom: 90px; | ||
| 84 | + width: 90vw; | ||
| 85 | + margin: 0 5vw; | ||
| 86 | +} | ||
| 87 | +.pop_pic { | ||
| 88 | + width: 70px; | ||
| 89 | + height: 30px; | ||
| 90 | +} | ||
| 91 | +.grey_line { | ||
| 92 | + width: 90vw; | ||
| 93 | + height: 1px; | ||
| 94 | + margin: 20vw 5vw 10vw ; | ||
| 95 | + background-color: #999; | ||
| 96 | +} | ||
| 97 | +.box { | ||
| 98 | + padding: 0 5vw; | ||
| 99 | + box-sizing: border-box; | ||
| 100 | + margin-bottom: 20px; | ||
| 101 | +} | ||
| 102 | +.box_title { | ||
| 103 | + font-size: 20px; | ||
| 104 | + font-weight: bold; | ||
| 105 | +} | ||
| 106 | +.box_blue { | ||
| 107 | + padding: 7px 10px; | ||
| 108 | + box-sizing: border-box; | ||
| 109 | + background-color: #EDF5FF; | ||
| 110 | + color: #333333; | ||
| 111 | + margin: 15px 0; | ||
| 112 | + border-radius: 10px; | ||
| 113 | +} | ||
| 114 | +.box_blue span { | ||
| 115 | + color: #3A86F5; | ||
| 116 | +} | ||
| 117 | +.box_grey { | ||
| 118 | + padding: 18px 10px; | ||
| 119 | + box-sizing: border-box; | ||
| 120 | + background-color: #FBFBFB; | ||
| 121 | + color: #666666 ; | ||
| 122 | + margin: 15px 0; | ||
| 123 | + border-radius: 10px; | ||
| 124 | +} | ||
| 125 | +.box_pic { | ||
| 126 | + display: flex; | ||
| 127 | + justify-content: space-between; | ||
| 128 | + flex-wrap: wrap; | ||
| 129 | +} | ||
| 130 | +.box_img { | ||
| 131 | + width: 26vw; | ||
| 132 | + margin:0 0 10px; | ||
| 133 | + border-radius: 10px; | ||
| 134 | +} | ||
| 2 | \ No newline at end of file | 135 | \ No newline at end of file |
pages/index/index.js
| @@ -4,63 +4,73 @@ import request from '../../api/request.js' | @@ -4,63 +4,73 @@ import request from '../../api/request.js' | ||
| 4 | 4 | ||
| 5 | Page({ | 5 | Page({ |
| 6 | data: { | 6 | data: { |
| 7 | - showAdd: false, //新建打卡 | ||
| 8 | - tabindex: 1, | 7 | + active: 1, |
| 8 | + taskList: [] | ||
| 9 | // bannerList: [], // 轮播图 | 9 | // bannerList: [], // 轮播图 |
| 10 | }, | 10 | }, |
| 11 | - /** | ||
| 12 | - * 生命周期函数--监听页面加载 | ||
| 13 | - */ | ||
| 14 | - onLoad: function (options) { | ||
| 15 | - // this.getBannerList() //获取banner | ||
| 16 | - }, | ||
| 17 | - onShow:function (options) { | ||
| 18 | - this.setData({ | ||
| 19 | - showAdd:false | ||
| 20 | - }) | ||
| 21 | - }, | ||
| 22 | - // 排行榜 | ||
| 23 | - handleRank(){ | ||
| 24 | - wx.navigateTo({ | ||
| 25 | - url: '/pages/index/rank/rank', | ||
| 26 | - }) | ||
| 27 | - }, | ||
| 28 | - handleTab1() { | ||
| 29 | - this.setData({ | ||
| 30 | - tabindex: 1 | ||
| 31 | - }) | ||
| 32 | - }, | ||
| 33 | - handleTab2() { | 11 | + checkTabs(e) { |
| 12 | + let index = e.currentTarget.dataset.index | ||
| 34 | this.setData({ | 13 | this.setData({ |
| 35 | - tabindex: 2 | ||
| 36 | - }) | 14 | + active: index |
| 15 | + }) //修改参数 | ||
| 37 | }, | 16 | }, |
| 38 | - handleAdd() { | ||
| 39 | - this.setData({ | ||
| 40 | - showAdd: true | 17 | + |
| 18 | + //打卡记录列表 | ||
| 19 | + getTaskList() { | ||
| 20 | + request({ | ||
| 21 | + url: `/wx/task/cardTaskList`, | ||
| 22 | + method: 'post', | ||
| 23 | + data: { | ||
| 24 | + "oneselfFlag": 1, | ||
| 25 | + "page": 1, | ||
| 26 | + "pageSize": 999, | ||
| 27 | + "userId": wx.getStorageSync("userInfo_id") | ||
| 28 | + }, | ||
| 29 | + }).then(res => { | ||
| 30 | + if (res.code == 0) { | ||
| 31 | + this.setData({ | ||
| 32 | + taskList: res.rows | ||
| 33 | + }) | ||
| 34 | + } else { | ||
| 35 | + wx.showToast({ | ||
| 36 | + title: res.msg, | ||
| 37 | + icon: 'none', | ||
| 38 | + duration: 1500 | ||
| 39 | + }) | ||
| 40 | + } | ||
| 41 | }) | 41 | }) |
| 42 | }, | 42 | }, |
| 43 | - closeAdd() { | ||
| 44 | - this.setData({ | ||
| 45 | - showAdd: false | 43 | + |
| 44 | + //查看排行榜 | ||
| 45 | + toRank() { | ||
| 46 | + wx.switchTab({ | ||
| 47 | + url: './rank/rank', | ||
| 46 | }) | 48 | }) |
| 47 | }, | 49 | }, |
| 48 | - // 打卡成果 | ||
| 49 | - handleAchievement(){ | 50 | + |
| 51 | + // 打卡成果 | ||
| 52 | + handleAchievement(e){ | ||
| 50 | wx.navigateTo({ | 53 | wx.navigateTo({ |
| 51 | - url: '/pages/index/achievement/achievement', | 54 | + url: '/pages/index/achievement/achievement?valueId='+e.currentTarget.dataset.valueid , |
| 52 | }) | 55 | }) |
| 53 | }, | 56 | }, |
| 54 | // 去打卡 | 57 | // 去打卡 |
| 55 | - handleDetail(){ | 58 | + handleDetail(e){ |
| 59 | + let eData = e.currentTarget.dataset | ||
| 56 | wx.navigateTo({ | 60 | wx.navigateTo({ |
| 57 | - url: '/pages/index/punchDetail/punchDetail', | 61 | + url: '/pages/index/punchDetail/punchDetail?valueId='+eData.valueid , |
| 58 | }) | 62 | }) |
| 63 | + }, | ||
| 64 | + /** | ||
| 65 | + * 生命周期函数--监听页面加载 | ||
| 66 | + */ | ||
| 67 | + onLoad: function (options) { | ||
| 68 | + // this.getBannerList() //获取banner | ||
| 59 | }, | 69 | }, |
| 60 | - // 自定义模板 | ||
| 61 | - handleNewPunch(){ | ||
| 62 | - wx.navigateTo({ | ||
| 63 | - url: '/pages/index/newPunch/newPunch', | 70 | + onShow: function (options) { |
| 71 | + this.getTaskList() | ||
| 72 | + this.setData({ | ||
| 73 | + showAdd: false | ||
| 64 | }) | 74 | }) |
| 65 | }, | 75 | }, |
| 66 | // 获取banner图 | 76 | // 获取banner图 |
pages/index/index.json
| 1 | { | 1 | { |
| 2 | "usingComponents": { | 2 | "usingComponents": { |
| 3 | - "van-popup": "@vant/weapp/popup/index" | 3 | + "van-popup": "@vant/weapp/popup/index", |
| 4 | + "van-tab": "@vant/weapp/tab/index", | ||
| 5 | + "van-tabs": "@vant/weapp/tabs/index", | ||
| 6 | + "van-progress": "@vant/weapp/progress/index" | ||
| 4 | }, | 7 | }, |
| 5 | "navigationBarTextStyle": "black", | 8 | "navigationBarTextStyle": "black", |
| 6 | - "navigationStyle": "custom" | 9 | + "navigationBarTitleText": "打卡" |
| 7 | } | 10 | } |
| 8 | \ No newline at end of file | 11 | \ No newline at end of file |
pages/index/index.wxml
| 1 | <view class="main"> | 1 | <view class="main"> |
| 2 | - <image class="temporary" hidden="{{tabindex==2}}" src="/img/_index1.png" mode="widthFix" alt="" /> | ||
| 3 | - <image class="temporary" hidden="{{tabindex==1}}" src="/img/_index2.png" mode="widthFix" alt="" /> | ||
| 4 | - <!-- 排行榜 --> | ||
| 5 | - <text class="temporary_box" style="width: 370rpx;height: 100rpx;position: absolute;top: 192rpx;left: 20rpx;" bindtap="handleRank"></text> | ||
| 6 | - <!-- 两个tab --> | ||
| 7 | - <text class="temporary_box" style="width: 160rpx;height: 80rpx;position: absolute;top: 300rpx;left: 32rpx;" bindtap="handleTab1"></text> | ||
| 8 | - <text class="temporary_box" style="width: 160rpx;height: 80rpx;position: absolute;top: 300rpx;left: 200rpx;" bindtap="handleTab2"></text> | ||
| 9 | - <!-- 打卡成果 --> | ||
| 10 | - <text class="temporary_box" style="width: 350rpx;height: 100rpx;position: absolute;top: 1000rpx;left: 20rpx;" bindtap="handleAchievement"></text> | ||
| 11 | - <!-- 去打卡 --> | ||
| 12 | - <text class="temporary_box" style="width: 350rpx;height: 100rpx;position: absolute;top: 1000rpx;right: 20rpx;" bindtap="handleDetail"></text> | ||
| 13 | - <!-- 新建打卡 --> | ||
| 14 | - <text class="temporary_box" style="width: 120rpx;height: 120rpx;position: absolute;top: 1200rpx;right: 20rpx;" bindtap="handleAdd"></text> | ||
| 15 | - <van-popup show="{{ showAdd }}" position="bottom" custom-style="height: 80%;" bind:close="closeAdd"> | ||
| 16 | - <image class="temporary" src="/img/_index3.png" mode="widthFix" alt="" /> | ||
| 17 | - <!-- 自定义模板 --> | ||
| 18 | - <text class="temporary_box" style="width: 180rpx;height: 220rpx;position: absolute;top: 364rpx;left: 20rpx;" bindtap="handleNewPunch"></text> | ||
| 19 | - </van-popup> | 2 | + <!-- <view class="bck" style="background-image: url('https://szyundisk.oss-cn-hangzhou.aliyuncs.com/null/67c3d489-6635-4bef-90f2-03553f56fd0a.png')"> |
| 3 | + </view> --> | ||
| 4 | + <!-- 打卡排行榜 --> | ||
| 5 | + <!-- <view class="box"> | ||
| 6 | + <view class="title_name"> | ||
| 7 | + </view> | ||
| 8 | + <vidw class="title_view" bindtap="toRank">立即查看</vidw> | ||
| 9 | + <view class="tabs_css"> | ||
| 10 | + <view class="{{active == 1?'tabs_item check' :'tabs_item no_check'}}" bindtap="checkTabs" data-index='1'>我的打卡</view> | ||
| 11 | + <view class="{{active == 2?'tabs_item check' :'tabs_item no_check'}} " bindtap='checkTabs' data-index='2'>我创建的</view> | ||
| 12 | + </view> | ||
| 13 | + <view class="tabs_div"></view> | ||
| 14 | + </view> --> | ||
| 15 | + <view class="white_box"> | ||
| 16 | + <view class="card" wx:for="{{taskList}}" wx:key="index" wx:for-item="value"> | ||
| 17 | + <view class="card_title"> | ||
| 18 | + <view class="title_L"> | ||
| 19 | + <image class="title_pic" src="/img/answer/bj.png" alt="" /> | ||
| 20 | + </view> | ||
| 21 | + <view class="title_R"> | ||
| 22 | + <view>{{value.taskTitle}}</view> | ||
| 23 | + <view class="grey_font">开始时间 {{value.startDate}}</view> | ||
| 24 | + </view> | ||
| 25 | + </view> | ||
| 26 | + <view class="day_font">{{value.taskDesc}}</view> | ||
| 27 | + <!-- <view class="day_font2">已坚持打卡 | ||
| 28 | + <text class="day_font2_large">1/50 </text>天 | ||
| 29 | + </view> --> | ||
| 30 | + <view> | ||
| 31 | + <van-progress percentage="50" color='#3F5EFF' stroke-width="13" pivot-text=' ' /> | ||
| 32 | + </view> | ||
| 33 | + <view class="flex_font"> | ||
| 34 | + <text class="grey_flex">打卡频次:</text> | ||
| 35 | + {{value.taskFrequency}} | ||
| 36 | + </view> | ||
| 37 | + <view class="flex_font" wx:if="{{value.submitCondition != null}}"> | ||
| 38 | + <text class="grey_flex">打卡要求:</text> | ||
| 39 | + {{ value.submitCondition == '无限制' ? '无限制': '需要 '+value.submitCondition}} | ||
| 40 | + </view> | ||
| 41 | + <view class="flex_font"> | ||
| 42 | + <view class="grey_flex">其他:</view> | ||
| 43 | + {{value.allowRepairCard == 1 ? '允许补卡': '不允许补卡'}} | ||
| 44 | + </view> | ||
| 45 | + <view class="grey_line"></view> | ||
| 46 | + <view class="blue_font"> | ||
| 47 | + <view bindtap="handleAchievement" data-valueId="{{value.id}}">打卡成果</view> | ||
| 48 | + <view class="blue_line"></view> | ||
| 49 | + <view bindtap="handleDetail" data-valueId="{{value.id}}">去打卡</view> | ||
| 50 | + </view> | ||
| 51 | + </view> | ||
| 52 | + </view> | ||
| 20 | 53 | ||
| 21 | </view> | 54 | </view> |
| 22 | \ No newline at end of file | 55 | \ No newline at end of file |
pages/index/index.wxss
| @@ -0,0 +1,196 @@ | @@ -0,0 +1,196 @@ | ||
| 1 | +.bck { | ||
| 2 | + position: absolute; | ||
| 3 | + top: 0; | ||
| 4 | + left: 0; | ||
| 5 | + width: 100%; | ||
| 6 | + height: 250px; | ||
| 7 | + z-index: -1; | ||
| 8 | + background-size: 100% 100%; | ||
| 9 | +} | ||
| 10 | + | ||
| 11 | +.box { | ||
| 12 | + padding: 100px 7vw 0; | ||
| 13 | + box-sizing: border-box; | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +.title_name { | ||
| 17 | + font-size: 7vw; | ||
| 18 | + font-weight: bold; | ||
| 19 | + letter-spacing: 1.5vw; | ||
| 20 | + color: #fff; | ||
| 21 | + margin-bottom: 20px; | ||
| 22 | +} | ||
| 23 | + | ||
| 24 | +.title_view { | ||
| 25 | + height: 20px; | ||
| 26 | + font-size: 4.8vw; | ||
| 27 | + letter-spacing: 0.5vw; | ||
| 28 | + color: #fff; | ||
| 29 | + opacity: 0.7; | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +.tabs_css { | ||
| 33 | + margin: 30px 0; | ||
| 34 | + display: flex; | ||
| 35 | +} | ||
| 36 | +.tabs_div { | ||
| 37 | + margin: 30px 0; | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +.tabs_item { | ||
| 41 | + margin-right: 20px; | ||
| 42 | + font-size: 4.3vw; | ||
| 43 | + color: #fff; | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +.check {} | ||
| 47 | + | ||
| 48 | +.no_check { | ||
| 49 | + opacity: 0.6; | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +/**/ | ||
| 53 | +.white_box { | ||
| 54 | + width: 100vw; | ||
| 55 | + min-height: 550px; | ||
| 56 | + /* background-color: rebeccapurple; */ | ||
| 57 | + background-color: #F5F6FA; | ||
| 58 | + border-top-left-radius: 8vw; | ||
| 59 | + border-top-right-radius: 8vw; | ||
| 60 | + padding: 10vw 5vw; | ||
| 61 | + box-sizing: border-box; | ||
| 62 | +} | ||
| 63 | + | ||
| 64 | +.card { | ||
| 65 | + width: 90vw; | ||
| 66 | + background-color: #fff; | ||
| 67 | + border-radius: 8vw; | ||
| 68 | + padding: 8vw 7vw; | ||
| 69 | + margin-bottom: 30px; | ||
| 70 | + box-sizing: border-box; | ||
| 71 | + box-shadow: 1px 1px 1px 1px rgb(196, 196, 196); | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +.card_title { | ||
| 75 | + display: flex; | ||
| 76 | +} | ||
| 77 | + | ||
| 78 | +.title_L { | ||
| 79 | + flex-shrink: 0; | ||
| 80 | + width: 50px; | ||
| 81 | + height: 50px; | ||
| 82 | + margin-right: 15px; | ||
| 83 | +} | ||
| 84 | + | ||
| 85 | +.title_pic { | ||
| 86 | + width: 100%; | ||
| 87 | + height: 100%; | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | +.title_R { | ||
| 91 | + height: 50px; | ||
| 92 | + display: flex; | ||
| 93 | + align-content: space-between; | ||
| 94 | + flex-wrap: wrap; | ||
| 95 | + font-size: 4.6vw; | ||
| 96 | +} | ||
| 97 | + | ||
| 98 | +.grey_font { | ||
| 99 | + width: 100%; | ||
| 100 | + color: #999; | ||
| 101 | + font-size: 3.8vw; | ||
| 102 | +} | ||
| 103 | + | ||
| 104 | +.day_font { | ||
| 105 | + margin: 20px 0 20px; | ||
| 106 | + letter-spacing: 0.2vw; | ||
| 107 | + font-size: 4vw; | ||
| 108 | +} | ||
| 109 | + | ||
| 110 | +.day_font2 { | ||
| 111 | + margin: 20px 0; | ||
| 112 | + letter-spacing: 0.2vw; | ||
| 113 | + font-size: 3.8vw; | ||
| 114 | +} | ||
| 115 | + | ||
| 116 | +.day_font2_large { | ||
| 117 | + font-size: 5.5vw; | ||
| 118 | + font-weight: bold; | ||
| 119 | +} | ||
| 120 | + | ||
| 121 | +.flex_font { | ||
| 122 | + font-size: 3.5vw; | ||
| 123 | + margin: 20px 0; | ||
| 124 | + display: flex; | ||
| 125 | +} | ||
| 126 | + | ||
| 127 | +.grey_flex { | ||
| 128 | + width: 80px; | ||
| 129 | + color: #999; | ||
| 130 | +} | ||
| 131 | + | ||
| 132 | +.grey_line { | ||
| 133 | + width: 100%; | ||
| 134 | + height: 1px; | ||
| 135 | + background-color: #E5E5E5; | ||
| 136 | +} | ||
| 137 | + | ||
| 138 | +.blue_line { | ||
| 139 | + width: 1px; | ||
| 140 | + height: 20px; | ||
| 141 | + background-color: #EAEAEA; | ||
| 142 | +} | ||
| 143 | + | ||
| 144 | +.blue_font { | ||
| 145 | + display: flex; | ||
| 146 | + justify-content: space-around; | ||
| 147 | + margin-top: 20px; | ||
| 148 | + font-size: 4.1vw; | ||
| 149 | + color: #4C92F9; | ||
| 150 | +} | ||
| 151 | + | ||
| 152 | +.blue_tip { | ||
| 153 | + position: fixed; | ||
| 154 | + bottom: 40px; | ||
| 155 | + right: 3vw; | ||
| 156 | +} | ||
| 157 | + | ||
| 158 | +.img_tip { | ||
| 159 | + width: 70px; | ||
| 160 | + height: 70px; | ||
| 161 | +} | ||
| 162 | + | ||
| 163 | +.pop_card { | ||
| 164 | + padding: 5vw; | ||
| 165 | + box-sizing: border-box; | ||
| 166 | +} | ||
| 167 | + | ||
| 168 | +.pop_title { | ||
| 169 | + font-size: 4.8vw; | ||
| 170 | + font-weight: bold; | ||
| 171 | + letter-spacing: 1px; | ||
| 172 | + margin-bottom: 30px; | ||
| 173 | +} | ||
| 174 | + | ||
| 175 | +.tem_box { | ||
| 176 | + display: flex; | ||
| 177 | + flex-wrap: wrap; | ||
| 178 | +} | ||
| 179 | + | ||
| 180 | +.tem_item { | ||
| 181 | + width: 23vw; | ||
| 182 | + height: 170px; | ||
| 183 | + text-align: center; | ||
| 184 | + margin: 0 3vw 30px; | ||
| 185 | +} | ||
| 186 | + | ||
| 187 | +.tem_pic { | ||
| 188 | + width: 23vw; | ||
| 189 | + height: 120px; | ||
| 190 | + border-radius: 10px; | ||
| 191 | +} | ||
| 192 | + | ||
| 193 | +.tem_font { | ||
| 194 | + font-size: 3.9vw; | ||
| 195 | + margin-top: 10px; | ||
| 196 | +} | ||
| 0 | \ No newline at end of file | 197 | \ No newline at end of file |
pages/index/newPunch/newPunch.js
| 1 | // pages/index/rank/rank.js | 1 | // pages/index/rank/rank.js |
| 2 | +import request from '../../../api/request.js' | ||
| 3 | +import moment from 'moment'; | ||
| 2 | Page({ | 4 | Page({ |
| 3 | 5 | ||
| 4 | /** | 6 | /** |
| 5 | * 页面的初始数据 | 7 | * 页面的初始数据 |
| 6 | */ | 8 | */ |
| 7 | data: { | 9 | data: { |
| 10 | + tempId: 0, | ||
| 11 | + form: { | ||
| 12 | + taskTitle: '', //任务标题 | ||
| 13 | + taskDesc: '', //任务描述内容 | ||
| 14 | + allowRepairCard: 2, //是否允许补卡 1是 2否 | ||
| 15 | + hasData: 2, //是否需要提交数据 1是 2否 | ||
| 16 | + // id: '', // 任务ID | ||
| 17 | + lackNum: '', // 缺卡次数 | ||
| 18 | + remindTime: '', // 打卡提醒时间点 | ||
| 19 | + startDate: '', // 打卡开始时间 | ||
| 20 | + statisticsUnit: '', // 统计单位 hasData=1 时,必传 | ||
| 21 | + submitCondition: '', //提交包含条件:图片、视频、音频 | ||
| 22 | + taskCycle: '', //打卡周期 | ||
| 23 | + taskFileUrl: [], //任务文件(含多个) | ||
| 24 | + taskFrequency: '', //打卡频次 | ||
| 25 | + userId: '', //所属用户ID | ||
| 26 | + }, | ||
| 27 | + fileList: [], | ||
| 28 | + //弹出层 | ||
| 29 | + //统计单位 | ||
| 30 | + unitShow: false, | ||
| 31 | + columnsUnit: ['分钟', '小时', '个', '篇', '本', '张', '页', '次'], | ||
| 32 | + //开始时间 | ||
| 33 | + startTimeShow: false, | ||
| 34 | + columnsStartTime: ['9', '10', '11', '12'], | ||
| 35 | + minDate: new Date().getTime(), | ||
| 36 | + currentDate: new Date().getTime(), | ||
| 37 | + formatter(type, value) { | ||
| 38 | + if (type === 'year') { | ||
| 39 | + return `${value}年`; | ||
| 40 | + } | ||
| 41 | + if (type === 'month') { | ||
| 42 | + return `${value}月`; | ||
| 43 | + } | ||
| 44 | + return value; | ||
| 45 | + }, | ||
| 46 | + //打卡周期 | ||
| 47 | + clockCycleShow: false, | ||
| 48 | + columnsClockCycle: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10','11', '12', '13', '14', '15', '16', '17', '18', '19', '20','21', '22', '23', '24', '25', '26', '27', '28', '29', '30','31', | ||
| 49 | + '32', '33', '34', '35', '36', '37', '38', '39', '40','41', | ||
| 50 | + '42', '43', '44', '45', '46', '47', '48', '49', '40','51', | ||
| 51 | + '52', '53', '54', '55', '56', '57', '58', '59', '60','61', | ||
| 52 | + '62', '63', '64', '65', '66', '67', '68', '69', '70','71', | ||
| 53 | + '72', '73', '74', '75', '76', '77', '78', '79', '80','81', | ||
| 54 | + '82', '83', '84', '85', '86', '87', '88', '89', '90'], | ||
| 55 | + //打卡频次 | ||
| 56 | + clockRateShow: false, | ||
| 57 | + columnsClockRate: ['每天', '7天', '一个月'], | ||
| 58 | + //打卡提醒 | ||
| 59 | + clockRemindShow: false, | ||
| 60 | + columnsClockRemind: [ | ||
| 61 | + { | ||
| 62 | + values: ['每天','周一', '周二', '周三', '周四', '周五', '周六', '周日'], | ||
| 63 | + defaultIndex: 2, | ||
| 64 | + }, | ||
| 65 | + // 第二列 | ||
| 66 | + { | ||
| 67 | + values: ['8:00', '9:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00'], | ||
| 68 | + defaultIndex: 1, | ||
| 69 | + }, | ||
| 70 | + ], | ||
| 71 | + //打卡缺卡提醒 | ||
| 72 | + clockLackShow: false, | ||
| 73 | + columnsClockLack: [1,2,3], | ||
| 74 | + //必须包含 | ||
| 75 | + containShow: false, | ||
| 76 | + columnsContain: ['无限制','图片'], | ||
| 77 | + }, | ||
| 78 | + //获取模板详情 / 空模板 | ||
| 79 | + getDetail() { | ||
| 80 | + request({ | ||
| 81 | + url: `/wx/temp/getTempDetail`, | ||
| 82 | + method: 'get', | ||
| 83 | + data: { | ||
| 84 | + "tempId": this.data.tempId, | ||
| 85 | + }, | ||
| 86 | + }).then(res => { | ||
| 87 | + if (res.code == 0) { | ||
| 88 | + const data = res.data | ||
| 89 | + this.setData({ | ||
| 90 | + 'form.taskTitle': data.taskTitle | ||
| 91 | + }) | ||
| 92 | + this.setData({ | ||
| 93 | + 'form.taskDesc': data.taskDesc | ||
| 94 | + }) | ||
| 95 | + this.setData({ | ||
| 96 | + 'form.allowRepairCard': data.allowRepairCard | ||
| 97 | + }) | ||
| 98 | + this.setData({ | ||
| 99 | + 'form.hasData': data.hasData | ||
| 100 | + }) | ||
| 101 | + this.setData({ | ||
| 102 | + 'form.lackNum': data.lackNum | ||
| 103 | + }) | ||
| 104 | + this.setData({ | ||
| 105 | + 'form.remindTime': data.remindTime | ||
| 106 | + }) | ||
| 107 | + this.setData({ | ||
| 108 | + 'form.startDate': moment(new Date().getTime()).format('YYYY-MM-DD') | ||
| 109 | + }) | ||
| 110 | + this.setData({ | ||
| 111 | + 'form.statisticsUnit': data.statisticsUnit | ||
| 112 | + }) | ||
| 113 | + this.setData({ | ||
| 114 | + 'form.submitCondition': data.submitCondition | ||
| 115 | + }) | ||
| 116 | + this.setData({ | ||
| 117 | + 'form.taskCycle': data.taskCycle | ||
| 118 | + }) | ||
| 119 | + this.setData({ | ||
| 120 | + 'form.taskFileUrl': [] | ||
| 121 | + }) | ||
| 122 | + this.setData({ | ||
| 123 | + 'form.taskFrequency': data.taskFrequency | ||
| 124 | + }) | ||
| 125 | + } else { | ||
| 126 | + wx.showToast({ | ||
| 127 | + title: res.msg, | ||
| 128 | + icon: 'none', | ||
| 129 | + duration: 1000 | ||
| 130 | + }) | ||
| 131 | + } | ||
| 132 | + }) | ||
| 133 | + }, | ||
| 134 | + //输入 | ||
| 135 | + onfieldChange(e) { | ||
| 136 | + this.setData({ | ||
| 137 | + 'form.taskTitle': e.detail | ||
| 138 | + }) | ||
| 139 | + }, | ||
| 140 | + //输入 | ||
| 141 | + onfieldDescChange(e) { | ||
| 142 | + this.setData({ | ||
| 143 | + 'form.taskDesc': e.detail | ||
| 144 | + }) | ||
| 145 | + }, | ||
| 146 | + //开关 | ||
| 147 | + onSwitch(e) { | ||
| 148 | + console.log(e) | ||
| 149 | + this.setData({ | ||
| 150 | + 'form.hasData': e.detail | ||
| 151 | + }) | ||
| 152 | + }, | ||
| 153 | + onChange(e) { | ||
| 154 | + console.log(e) | ||
| 155 | + this.setData({ | ||
| 156 | + 'form.allowRepairCard': e.detail | ||
| 157 | + }) | ||
| 158 | + }, | ||
| 159 | + //文件上传 | ||
| 160 | + afterRead(event) { | ||
| 161 | + const { | ||
| 162 | + file | ||
| 163 | + } = event.detail; | ||
| 164 | + var that = this | ||
| 165 | + // 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式 | ||
| 166 | + wx.uploadFile({ | ||
| 167 | + url: 'https://market.myjxt.com:51311/file/fileUpload', // 仅为示例,非真实的接口地址 | ||
| 168 | + filePath: file.url, | ||
| 169 | + name: 'file', | ||
| 170 | + formData: { | ||
| 171 | + user: 'test' | ||
| 172 | + }, | ||
| 173 | + success(res) { | ||
| 174 | + // 上传完成需要更新 fileList | ||
| 175 | + const { | ||
| 176 | + fileList = [] | ||
| 177 | + } = that.data; | ||
| 178 | + fileList.push({ | ||
| 179 | + ...file, | ||
| 180 | + url: res.data | ||
| 181 | + }); | ||
| 182 | + console.log(res,fileList) | ||
| 183 | + that.setData({ | ||
| 184 | + fileList | ||
| 185 | + }); | ||
| 186 | + that.setData({ | ||
| 187 | + 'form.taskFileUrl': fileList.map(v => v.url) | ||
| 188 | + }) | ||
| 189 | + }, | ||
| 190 | + }); | ||
| 191 | + }, | ||
| 192 | + //删除 | ||
| 193 | + delFile(event) { | ||
| 194 | + let [list,index] = [this.data.fileList,event.detail.index] | ||
| 195 | + list.splice(index,1) | ||
| 196 | + this.setData({ | ||
| 197 | + fileList:list | ||
| 198 | + }) | ||
| 199 | + this.setData({ | ||
| 200 | + 'form.taskFileUrl': this.data.fileList.map(v => v.url) | ||
| 201 | + }) | ||
| 202 | + }, | ||
| 203 | + //开关 | ||
| 204 | + onswitchChange({ | ||
| 205 | + detail | ||
| 206 | + }) { | ||
| 207 | + this.setData({ | ||
| 208 | + 'form.checked': detail | ||
| 209 | + }); | ||
| 210 | + }, | ||
| 211 | + //创建 | ||
| 212 | + createTask() { | ||
| 213 | + console.log(this.data.form) | ||
| 214 | + if(this.data.form.hasData == 1 && !this.data.form.statisticsUnit) { | ||
| 215 | + return wx.showToast({title: '请选择统计单位',icon: 'none',}) | ||
| 216 | + } | ||
| 217 | + request({ | ||
| 218 | + url: `/wx/task/addCardTask`, | ||
| 219 | + method: 'post', | ||
| 220 | + data: this.data.form, | ||
| 221 | + }).then(res => { | ||
| 222 | + if (res.code == 0) { | ||
| 223 | + wx.navigateTo({ | ||
| 224 | + url: '../../mine/record/record' | ||
| 225 | + }) | ||
| 226 | + }else { | ||
| 227 | + wx.showToast({ | ||
| 228 | + title: res.msg, | ||
| 229 | + icon: 'none', | ||
| 230 | + duration: 1000 | ||
| 231 | + }) | ||
| 232 | + } | ||
| 233 | + }) | ||
| 8 | }, | 234 | }, |
| 9 | - | ||
| 10 | /** | 235 | /** |
| 11 | * 生命周期函数--监听页面加载 | 236 | * 生命周期函数--监听页面加载 |
| 12 | */ | 237 | */ |
| 13 | onLoad(options) { | 238 | onLoad(options) { |
| 14 | - | 239 | + this.setData({ |
| 240 | + 'form.userId': wx.getStorageSync('userInfo_id') | ||
| 241 | + }) | ||
| 242 | + this.setData({ | ||
| 243 | + tempId: options.tempId | ||
| 244 | + }, () => { | ||
| 245 | + this.getDetail() | ||
| 246 | + }) | ||
| 15 | }, | 247 | }, |
| 16 | // 创建完成 | 248 | // 创建完成 |
| 17 | - handleCreate(){ | 249 | + handleCreate() { |
| 18 | // console.log(111) | 250 | // console.log(111) |
| 19 | wx.switchTab({ | 251 | wx.switchTab({ |
| 20 | - url: '/pages/index/index', | 252 | + url: '/pages/index/index', |
| 21 | }) | 253 | }) |
| 22 | }, | 254 | }, |
| 23 | // 统一返回 | 255 | // 统一返回 |
| @@ -29,5 +261,154 @@ Page({ | @@ -29,5 +261,154 @@ Page({ | ||
| 29 | */ | 261 | */ |
| 30 | onShareAppMessage() { | 262 | onShareAppMessage() { |
| 31 | 263 | ||
| 32 | - } | 264 | + }, |
| 265 | + /* | ||
| 266 | + 弹出层 - 统计单位 | ||
| 267 | + */ | ||
| 268 | + openUnitShow() { | ||
| 269 | + this.setData({ | ||
| 270 | + unitShow: true | ||
| 271 | + }) | ||
| 272 | + }, | ||
| 273 | + closeUnitShow() { | ||
| 274 | + this.setData({ | ||
| 275 | + unitShow: false | ||
| 276 | + }) | ||
| 277 | + }, | ||
| 278 | + changeUnitShow(e) { | ||
| 279 | + console.log(e) | ||
| 280 | + this.setData({ | ||
| 281 | + 'form.statisticsUnit': e.detail.value | ||
| 282 | + }) | ||
| 283 | + this.setData({ | ||
| 284 | + unitShow: false | ||
| 285 | + }) | ||
| 286 | + }, | ||
| 287 | + /* | ||
| 288 | + 弹出层 - 开始时间 | ||
| 289 | + */ | ||
| 290 | + openStartTimeShow() { | ||
| 291 | + this.setData({ | ||
| 292 | + startTimeShow: true | ||
| 293 | + }) | ||
| 294 | + }, | ||
| 295 | + closeStartTimeShow() { | ||
| 296 | + this.setData({ | ||
| 297 | + startTimeShow: false | ||
| 298 | + }) | ||
| 299 | + }, | ||
| 300 | + changeStartTimeShow(e) { | ||
| 301 | + let time = moment(e.detail).format('YYYY-MM-DD') | ||
| 302 | + this.setData({ | ||
| 303 | + 'form.startDate': time, | ||
| 304 | + }); | ||
| 305 | + this.setData({ | ||
| 306 | + startTimeShow: false | ||
| 307 | + }) | ||
| 308 | + }, | ||
| 309 | + /* | ||
| 310 | + 弹出层 - 打卡周期 | ||
| 311 | + */ | ||
| 312 | + openClockCycleShow() { | ||
| 313 | + this.setData({ | ||
| 314 | + clockCycleShow: true | ||
| 315 | + }) | ||
| 316 | + }, | ||
| 317 | + closeClockCycleShow() { | ||
| 318 | + this.setData({ | ||
| 319 | + clockCycleShow: false | ||
| 320 | + }) | ||
| 321 | + }, | ||
| 322 | + changeClockCycleShow(e) { | ||
| 323 | + this.setData({ | ||
| 324 | + 'form.taskCycle': e.detail.value | ||
| 325 | + }) | ||
| 326 | + this.setData({ | ||
| 327 | + clockCycleShow: false | ||
| 328 | + }) | ||
| 329 | + }, | ||
| 330 | + /* | ||
| 331 | + 弹出层 - 打卡频次 | ||
| 332 | + */ | ||
| 333 | + openClockRateShow() { | ||
| 334 | + this.setData({ | ||
| 335 | + clockRateShow: true | ||
| 336 | + }) | ||
| 337 | + }, | ||
| 338 | + closeClockRateShow() { | ||
| 339 | + this.setData({ | ||
| 340 | + clockRateShow: false | ||
| 341 | + }) | ||
| 342 | + }, | ||
| 343 | + changeClockRateShow(e) { | ||
| 344 | + this.setData({ | ||
| 345 | + 'form.taskFrequency': e.detail.value | ||
| 346 | + }) | ||
| 347 | + this.setData({ | ||
| 348 | + clockRateShow: false | ||
| 349 | + }) | ||
| 350 | + }, | ||
| 351 | + /* | ||
| 352 | + 弹出层 - 打卡提醒 | ||
| 353 | + */ | ||
| 354 | + openClockRemindShow() { | ||
| 355 | + this.setData({ | ||
| 356 | + clockRemindShow: true | ||
| 357 | + }) | ||
| 358 | + }, | ||
| 359 | + closeClockRemindShow() { | ||
| 360 | + this.setData({ | ||
| 361 | + clockRemindShow: false | ||
| 362 | + }) | ||
| 363 | + }, | ||
| 364 | + changeClockRemindShow(e) { | ||
| 365 | + this.setData({ | ||
| 366 | + 'form.remindTime': e.detail.value[0] + '::' + e.detail.value[1] | ||
| 367 | + }) | ||
| 368 | + this.setData({ | ||
| 369 | + clockRemindShow: false | ||
| 370 | + }) | ||
| 371 | + }, | ||
| 372 | + /* | ||
| 373 | + 弹出层 - 打卡缺卡提醒 | ||
| 374 | + */ | ||
| 375 | + openClockLackShow() { | ||
| 376 | + this.setData({ | ||
| 377 | + clockLackShow: true | ||
| 378 | + }) | ||
| 379 | + }, | ||
| 380 | + closeClockLackShow() { | ||
| 381 | + this.setData({ | ||
| 382 | + clockLackShow: false | ||
| 383 | + }) | ||
| 384 | + }, | ||
| 385 | + changeClockLackShow(e) { | ||
| 386 | + this.setData({ | ||
| 387 | + 'form.lackNum': e.detail.value | ||
| 388 | + }) | ||
| 389 | + this.setData({ | ||
| 390 | + clockLackShow: false | ||
| 391 | + }) | ||
| 392 | + }, | ||
| 393 | + /* | ||
| 394 | + 弹出层 - 必须包含 | ||
| 395 | + */ | ||
| 396 | + openContainShow() { | ||
| 397 | + this.setData({ | ||
| 398 | + containShow: true | ||
| 399 | + }) | ||
| 400 | + }, | ||
| 401 | + closeContainShow() { | ||
| 402 | + this.setData({ | ||
| 403 | + containShow: false | ||
| 404 | + }) | ||
| 405 | + }, | ||
| 406 | + changeContainShow(e) { | ||
| 407 | + this.setData({ | ||
| 408 | + 'form.submitCondition': e.detail.value | ||
| 409 | + }) | ||
| 410 | + this.setData({ | ||
| 411 | + containShow: false | ||
| 412 | + }) | ||
| 413 | + }, | ||
| 33 | }) | 414 | }) |
| 34 | \ No newline at end of file | 415 | \ No newline at end of file |
pages/index/newPunch/newPunch.json
| 1 | { | 1 | { |
| 2 | "usingComponents": { | 2 | "usingComponents": { |
| 3 | - "van-icon": "@vant/weapp/icon/index" | 3 | + "van-icon": "@vant/weapp/icon/index", |
| 4 | + "van-cell-group": "@vant/weapp/cell-group/index", | ||
| 5 | + "van-field": "@vant/weapp/field/index", | ||
| 6 | + "van-cell": "@vant/weapp/cell/index", | ||
| 7 | + "van-switch": "@vant/weapp/switch/index", | ||
| 8 | + "van-button": "@vant/weapp/button/index", | ||
| 9 | + "van-popup": "@vant/weapp/popup/index", | ||
| 10 | + "van-picker": "@vant/weapp/picker/index", | ||
| 11 | + "van-uploader": "@vant/weapp/uploader/index", | ||
| 12 | + "van-datetime-picker": "@vant/weapp/datetime-picker/index" | ||
| 4 | }, | 13 | }, |
| 5 | - "navigationStyle": "custom" | 14 | + "navigationBarTitleText": "打卡模板" |
| 6 | } | 15 | } |
| 7 | \ No newline at end of file | 16 | \ No newline at end of file |
pages/index/newPunch/newPunch.wxml
| 1 | <!--pages/index/rank/rank.wxml--> | 1 | <!--pages/index/rank/rank.wxml--> |
| 2 | <view class="punch_detail"> | 2 | <view class="punch_detail"> |
| 3 | - <!-- 顶部统一返回 --> | ||
| 4 | - <view class="navigation_back" bindtap="handleBack"> | ||
| 5 | - <van-icon name="arrow-left" /> | 3 | + <view class="title_card"> |
| 4 | + <van-cell-group border="{{ false }}"> | ||
| 5 | + <van-field value="{{ form.taskTitle }}" placeholder="请输入标题" border="{{ false }}" bind:change="onfieldChange" /> | ||
| 6 | + </van-cell-group> | ||
| 7 | + <view class="grey_line"></view> | ||
| 8 | + <view class="box_card"> | ||
| 9 | + <van-cell-group border="{{ false }}"> | ||
| 10 | + <van-field value="{{ form.taskDesc }}" type="textarea" placeholder="请输入" autosize border="{{ false }}" bind:change="onfieldDescChange" /> | ||
| 11 | + </van-cell-group> | ||
| 12 | + </view> | ||
| 13 | + <view class="tip_card"> | ||
| 14 | + <van-uploader accept='image' file-list="{{ fileList }}" deletable="{{ true }}" bind:after-read="afterRead" bind:delete="delFile"> | ||
| 15 | + <view class="tip_item"> | ||
| 16 | + <image class="pic" src="/img/answer/tp1.png" alt="" /> | ||
| 17 | + </view> | ||
| 18 | + </van-uploader> | ||
| 19 | + <!-- <view class="tip_item"> | ||
| 20 | + <image class="pic" src="/img/answer/sp1.png" alt="" /> | ||
| 21 | + </view> | ||
| 22 | + <view class="tip_item"> | ||
| 23 | + <image class="pic" src="/img/answer/yp1.png" alt="" /> | ||
| 24 | + </view> --> | ||
| 25 | + </view> | ||
| 6 | </view> | 26 | </view> |
| 7 | - <image class="temporary" src="/img/_new_punch.png" mode="widthFix" alt="" /> | ||
| 8 | - <!-- 创建完成返回首页 --> | ||
| 9 | - <text class="temporary_box" style="width: 700rpx;height: 100rpx;position: absolute;top: 2392rpx;right: 32rpx;" bindtap="handleCreate"></text> | 27 | + <view class="white_card"> |
| 28 | + <view class="bold_font">需要提交数据</view> | ||
| 29 | + <view> | ||
| 30 | + <van-switch checked="{{ form.hasData }}" size='20' active-value='1' inactive-value='2' bind:change="onSwitch" /> | ||
| 31 | + </view> | ||
| 32 | + </view> | ||
| 33 | + <view class="grey_line"></view> | ||
| 34 | + <view class="white_card_nopadding" wx:if="{{form.hasData == 1}}"> | ||
| 35 | + <van-cell-group border="{{ false }}"> | ||
| 36 | + <van-cell title="统计单位" value="{{ form.statisticsUnit }}" is-link label="请选择统计单位" border="{{ false }}" bindtap="openUnitShow" /> | ||
| 37 | + </van-cell-group> | ||
| 38 | + </view> | ||
| 39 | + <view class="white_card"> | ||
| 40 | + <view>允许补卡</view> | ||
| 41 | + <view> | ||
| 42 | + <van-switch checked="{{ form.allowRepairCard }}" size='20' bind:change="onChange" active-value='1' inactive-value='2' /> | ||
| 43 | + </view> | ||
| 44 | + </view> | ||
| 45 | + <view class="sm_grey_font"> | ||
| 46 | + 开启后,在打卡周期内,学生家长可对未打卡的任务进行补卡。 | ||
| 47 | + </view> | ||
| 48 | + <view class="white_card_nopadding"> | ||
| 49 | + <van-cell-group border="{{ false }}"> | ||
| 50 | + <van-cell title="开始时间" value="{{ form.startDate }}" is-link border="{{ false }}" bindtap="openStartTimeShow" /> | ||
| 51 | + </van-cell-group> | ||
| 52 | + </view> | ||
| 53 | + <view class="white_card_nopadding"> | ||
| 54 | + <van-cell-group border="{{ false }}"> | ||
| 55 | + <van-cell title="打卡周期" value="{{ form.taskCycle + ' 天'}}" is-link border="{{ false }}" bindtap="openClockCycleShow" /> | ||
| 56 | + </van-cell-group> | ||
| 57 | + </view> | ||
| 58 | + <view class="white_card_nopadding"> | ||
| 59 | + <van-cell-group border="{{ false }}"> | ||
| 60 | + <van-cell title="打卡频次" value="{{ form.taskFrequency }}" is-link border="{{ false }}" bindtap="openClockRateShow" /> | ||
| 61 | + </van-cell-group> | ||
| 62 | + </view> | ||
| 63 | + | ||
| 64 | + <view class="clearance"></view> | ||
| 65 | + <view class="white_card_nopadding"> | ||
| 66 | + <van-cell-group border="{{ false }}"> | ||
| 67 | + <van-cell title="打卡提醒" value="{{ form.remindTime }}" is-link border="{{ false }}" bindtap="openClockRemindShow" /> | ||
| 68 | + </van-cell-group> | ||
| 69 | + </view> | ||
| 70 | + <view class="white_card_nopadding"> | ||
| 71 | + <van-cell-group border="{{ false }}"> | ||
| 72 | + <van-cell title="缺卡打卡提醒" value="{{ form.lackNum + ' 次' }}" is-link border="{{ false }}" bindtap="openClockLackShow" /> | ||
| 73 | + </van-cell-group> | ||
| 74 | + </view> | ||
| 75 | + | ||
| 76 | + <view class="sm_grey_font"> | ||
| 77 | + 学生如缺卡达到一定条件,将会提醒家长 | ||
| 78 | + </view> | ||
| 79 | + <view class="white_card_nopadding"> | ||
| 80 | + <van-cell-group border="{{ false }}" > | ||
| 81 | + <van-cell title="提交时必须包含" value="{{ form.submitCondition }}" is-link border="{{ false }}" bindtap="openContainShow" /> | ||
| 82 | + </van-cell-group> | ||
| 83 | + </view> | ||
| 84 | + | ||
| 85 | + <view class="clearance"></view> | ||
| 86 | + <view class="btn"> | ||
| 87 | + <van-button type="info" round block bindtap="createTask">创建打卡</van-button> | ||
| 88 | + </view> | ||
| 89 | + | ||
| 90 | + <!--统计单位--> | ||
| 91 | + <van-popup show="{{ unitShow }}" position="bottom" custom-style="height: 40%;" round bind:close="closeUnitShow"> | ||
| 92 | + <van-picker columns="{{ columnsUnit }}" bind:confirm="changeUnitShow" bind:cancel="closeUnitShow" show-toolbar title="统计单位" /> | ||
| 93 | + </van-popup> | ||
| 94 | + | ||
| 95 | + <!--开始时间--> | ||
| 96 | + <van-popup show="{{ startTimeShow }}" position="bottom" custom-style="height: 40%;" round bind:close="closeStartTimeShow"> | ||
| 97 | + <!-- <van-picker columns="{{ columnsStartTime }}" bind:confirm="changeStartTimeShow" bind:cancel="closeStartTimeShow" show-toolbar title="开始时间" /> --> | ||
| 98 | + <van-datetime-picker title="开始时间" type="date" value="{{ form.startTimeShow }}" min-date="{{ minDate }}" bind:confirm="changeStartTimeShow" bind:cancel="closeStartTimeShow" formatter="{{ formatter }}" /> | ||
| 99 | + </van-popup> | ||
| 100 | + | ||
| 101 | + <!--打卡周期--> | ||
| 102 | + <van-popup show="{{ clockCycleShow }}" position="bottom" custom-style="height: 40%;" round bind:close="closeClockCycleShow"> | ||
| 103 | + <van-picker columns="{{ columnsClockCycle }}" bind:confirm="changeClockCycleShow" bind:cancel="closeClockCycleShow" show-toolbar title="打卡周期" /> | ||
| 104 | + </van-popup> | ||
| 105 | + | ||
| 106 | + <!--打卡频次--> | ||
| 107 | + <van-popup show="{{ clockRateShow }}" position="bottom" custom-style="height: 40%;" round bind:close="closeClockRateShow"> | ||
| 108 | + <van-picker columns="{{ columnsClockRate }}" bind:confirm="changeClockRateShow" bind:cancel="closeClockRateShow" show-toolbar title="打卡频次" /> | ||
| 109 | + </van-popup> | ||
| 110 | + | ||
| 111 | + <!--打卡提醒--> | ||
| 112 | + <van-popup show="{{ clockRemindShow }}" position="bottom" custom-style="height: 40%;" round bind:close="closeClockRemindShow"> | ||
| 113 | + <van-picker columns="{{ columnsClockRemind }}" bind:confirm="changeClockRemindShow" bind:cancel="closeClockRemindShow" show-toolbar title="打卡提醒" /> | ||
| 114 | + </van-popup> | ||
| 115 | + | ||
| 116 | + <!--打卡缺卡提醒--> | ||
| 117 | + <van-popup show="{{ clockLackShow }}" position="bottom" custom-style="height: 40%;" round bind:close="closeClockLackShow"> | ||
| 118 | + <van-picker columns="{{ columnsClockLack }}" bind:confirm="changeClockLackShow" bind:cancel="closeClockLackShow" show-toolbar title="缺卡打卡提醒" /> | ||
| 119 | + </van-popup> | ||
| 10 | 120 | ||
| 121 | + <!-- 必须包含 --> | ||
| 122 | + <van-popup show="{{ containShow }}" position="bottom" custom-style="height: 40%;" round bind:close="closeContainShow"> | ||
| 123 | + <van-picker columns="{{ columnsContain }}" bind:confirm="changeContainShow" bind:cancel="closeContainShow" show-toolbar title="提交时必须包含" /> | ||
| 124 | + </van-popup> | ||
| 11 | </view> | 125 | </view> |
| 12 | \ No newline at end of file | 126 | \ No newline at end of file |
pages/index/newPunch/newPunch.wxss
| 1 | /* pages/index/newPunch/newPunch.wxss */ | 1 | /* pages/index/newPunch/newPunch.wxss */ |
| 2 | +.punch_detail { | ||
| 3 | + position: absolute; | ||
| 4 | + width: 100vw; | ||
| 5 | + min-height: 100vh; | ||
| 6 | + background-color: #F5F6FA; | ||
| 7 | +} | ||
| 8 | + | ||
| 9 | +.title_card { | ||
| 10 | + margin: 15px 0; | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +.grey_line { | ||
| 14 | + width: 80vw; | ||
| 15 | + height: 1px; | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +.box_card { | ||
| 19 | + width: 100vw; | ||
| 20 | + min-height: 120px; | ||
| 21 | + background-color: #fff; | ||
| 22 | +} | ||
| 23 | + | ||
| 24 | +.tip_card { | ||
| 25 | + padding: 20px; | ||
| 26 | + box-sizing: border-box; | ||
| 27 | + display: flex; | ||
| 28 | + background-color: #fff; | ||
| 29 | +} | ||
| 30 | + | ||
| 31 | +.tip_item { | ||
| 32 | + width: 70px; | ||
| 33 | + height: 30px; | ||
| 34 | + margin-right: 5vw; | ||
| 35 | +} | ||
| 36 | + | ||
| 37 | +.pic { | ||
| 38 | + width: 100%; | ||
| 39 | + height: 100%; | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +.white_card { | ||
| 43 | + width: 100vw; | ||
| 44 | + background-color: #fff; | ||
| 45 | + padding: 20px 15px; | ||
| 46 | + box-sizing: border-box; | ||
| 47 | + display: flex; | ||
| 48 | + justify-content: space-between; | ||
| 49 | +} | ||
| 50 | + | ||
| 51 | +.bold_font { | ||
| 52 | + font-weight: bold; | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | +.white_card_nopadding { | ||
| 56 | + width: 100vw; | ||
| 57 | + background-color: #fff; | ||
| 58 | + font-weight: bold; | ||
| 59 | + height: 60px; | ||
| 60 | + padding-top: 11px; | ||
| 61 | + box-sizing: border-box; | ||
| 62 | +} | ||
| 63 | + | ||
| 64 | +.sm_grey_font { | ||
| 65 | + padding: 15px 0 15px 20px; | ||
| 66 | + box-sizing: border-box; | ||
| 67 | + font-size: 12px; | ||
| 68 | + color: #999; | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | +.clearance { | ||
| 72 | + width: 100vw; | ||
| 73 | + height: 20px; | ||
| 74 | +} | ||
| 75 | + | ||
| 76 | +.btn { | ||
| 77 | + width: 100vw; | ||
| 78 | + height: 80px; | ||
| 79 | + background-color: #fff; | ||
| 80 | + padding: 20px 30px 80px; | ||
| 81 | + box-sizing: border-box; | ||
| 82 | +} | ||
| 2 | \ No newline at end of file | 83 | \ No newline at end of file |
pages/index/punchDetail/punchDetail.js
| 1 | -// pages/index/punchDetail/punchDetail.js | 1 | +// pages/index/achievement/achievement.js |
| 2 | +// 引入插件安装器 | ||
| 3 | +import plugin from '../../../component/v2/plugins/index' | ||
| 4 | +import week from '../../../component/v2/plugins/week' | ||
| 5 | +import todo from '../../../component/v2/plugins/todo' | ||
| 6 | +import request from '../../../api/request.js' | ||
| 7 | +import moment from 'moment'; | ||
| 8 | +plugin | ||
| 9 | + .use(week) | ||
| 10 | + .use(todo) | ||
| 2 | Page({ | 11 | Page({ |
| 3 | 12 | ||
| 4 | /** | 13 | /** |
| 5 | * 页面的初始数据 | 14 | * 页面的初始数据 |
| 6 | */ | 15 | */ |
| 7 | data: { | 16 | data: { |
| 8 | - showEdit: false, //确认打卡 | ||
| 9 | - Clocked: false, //已打卡状态,只是为了演示用 | ||
| 10 | - showSuccess:false | 17 | + calendarConfig: { |
| 18 | + theme: 'elegant', | ||
| 19 | + weekMode: true, // 周视图模式 | ||
| 20 | + highlightToday: true, // 是否高亮显示当天 | ||
| 21 | + hideHeader: true, // 隐藏日历头部操作栏 | ||
| 22 | + }, | ||
| 23 | + isDisplay: false, | ||
| 24 | + clockShow: false, | ||
| 25 | + form: { | ||
| 26 | + id: '', //任务ID | ||
| 27 | + isRepair: 1, //是否补卡1立即打卡2补卡 | ||
| 28 | + repairDate: '', //补卡日期,当isRepair=2时必传,格式:YYYY-MM-dd | ||
| 29 | + statisticsUnit: '', //统计单位所含内容 | ||
| 30 | + taskDesc: '', //打卡描述内容 | ||
| 31 | + taskFileUrl: [], //任务文件(含多个) | ||
| 32 | + userId: '' | ||
| 33 | + }, | ||
| 34 | + fileList: [], | ||
| 35 | + calendar: {}, //日历 | ||
| 36 | + valueId: '', //任务ID | ||
| 37 | + taskVo: { | ||
| 38 | + allowRepairCard: 0, | ||
| 39 | + hasData: 0, | ||
| 40 | + statisticsUnit: "", | ||
| 41 | + submitCondition: "", | ||
| 42 | + id: 0, | ||
| 43 | + releaseTime: "", | ||
| 44 | + signTotal: 0, | ||
| 45 | + taskCycle: 0, | ||
| 46 | + taskDesc: "", | ||
| 47 | + taskFrequency: "", | ||
| 48 | + taskTitle: "", | ||
| 49 | + weekDay: "" | ||
| 50 | + }, | ||
| 51 | + resData: [], //成果数据 | ||
| 52 | + recordVo: { | ||
| 53 | + commitTime: "", | ||
| 54 | + files: [], | ||
| 55 | + signDate: "", | ||
| 56 | + taskRecordDesc: "", | ||
| 57 | + taskStatisticsParam: "" | ||
| 58 | + }, //成果数据当天 | ||
| 59 | + recordVoShow: false, | ||
| 60 | + isToday:true,//是否是今天 | ||
| 61 | + isLarge:false, //是否大于今天 | ||
| 62 | + repairText: '' | ||
| 11 | }, | 63 | }, |
| 12 | - | ||
| 13 | - /** | ||
| 14 | - * 生命周期函数--监听页面加载 | 64 | + /** |
| 65 | + * 选择日期后执行的事件 | ||
| 15 | */ | 66 | */ |
| 16 | - onLoad(options) { | 67 | + afterTapDate(e) { |
| 68 | + let date = e.detail.date | ||
| 69 | + this.setData({ | ||
| 70 | + isToday:e.detail.isToday | ||
| 71 | + }) | ||
| 72 | + //选择的年月日 | ||
| 73 | + let checkDay = e.detail.year +'-' + e.detail.month +'-' + e.detail.date | ||
| 74 | + let checktimeDate= new Date(moment(checkDay).format('YYYY-MM-DD')).getTime() | ||
| 75 | + //选择的日期是否大于今天 | ||
| 76 | + if(checktimeDate > new Date().getTime()) { | ||
| 77 | + console.log('ff') | ||
| 78 | + this.setData({ | ||
| 79 | + isLarge: true | ||
| 80 | + }) | ||
| 81 | + }else { | ||
| 82 | + this.setData({ | ||
| 83 | + isLarge: false | ||
| 84 | + }) | ||
| 85 | + } | ||
| 86 | + this.setData({ | ||
| 87 | + repairText: e.detail.todoText | ||
| 88 | + }) | ||
| 89 | + let recordVo = this.data.resData.eventDetails[date - 1].recordVo | ||
| 90 | + //匹配数据 | ||
| 91 | + if (recordVo != null) { | ||
| 92 | + console.log('复制',recordVo) | ||
| 93 | + this.setData({ | ||
| 94 | + recordVo: recordVo | ||
| 95 | + }) | ||
| 96 | + this.setData({ | ||
| 97 | + recordVoShow: true | ||
| 98 | + }) | ||
| 99 | + }else { | ||
| 100 | + this.setData({ | ||
| 101 | + recordVoShow: false | ||
| 102 | + }) | ||
| 103 | + } | ||
| 104 | + }, | ||
| 105 | + //获取信息 | ||
| 106 | + getInfo(doday) { | ||
| 107 | + request({ | ||
| 108 | + url: `/wx/task/getSignRecord`, | ||
| 109 | + method: 'get', | ||
| 110 | + data: { | ||
| 111 | + // wx.getStorageSync('userInfo_id'), | ||
| 112 | + "taskId": this.data.valueId, | ||
| 113 | + "signDate": doday | ||
| 114 | + }, | ||
| 115 | + }).then(res => { | ||
| 116 | + if (res.code == 0) { | ||
| 117 | + this.setData({ | ||
| 118 | + resData: res.data | ||
| 119 | + }) | ||
| 120 | + this.getV2(res.data) | ||
| 121 | + } else { | ||
| 122 | + wx.showToast({ | ||
| 123 | + title: res.msg, | ||
| 124 | + icon: 'none' | ||
| 125 | + }) | ||
| 126 | + } | ||
| 127 | + }) | ||
| 128 | + }, | ||
| 129 | + //初始化日历 | ||
| 130 | + initialize() { | ||
| 131 | + // 设置待办 | ||
| 132 | + this.setData({ | ||
| 133 | + 'calendar': this.selectComponent('#calendar').calendar | ||
| 134 | + }) | ||
| 17 | 135 | ||
| 18 | }, | 136 | }, |
| 19 | - // 打卡成果 | ||
| 20 | - handleAchievement(){ | 137 | + //显示日历 |
| 138 | + getV2(resData) { | ||
| 139 | + this.setData({ | ||
| 140 | + taskVo: resData.taskVo | ||
| 141 | + }) | ||
| 142 | + // const calendar = this.selectComponent('#calendar').calendar | ||
| 143 | + this.data.calendar.setTodos({ | ||
| 144 | + // 待办点标记设置 | ||
| 145 | + pos: 'bottom', // 待办点标记位置 ['top', 'bottom'] | ||
| 146 | + dotColor: 'purple', // 待办点标记颜色 | ||
| 147 | + circle: false, // 待办圆圈标记设置(如圆圈标记已签到日期),该设置与点标记设置互斥 | ||
| 148 | + showLabelAlways: true, // 点击时是否显示待办事项(圆点/文字),在 circle 为 true 及当日历配置 showLunar 为 true 时,此配置失效 | ||
| 149 | + dates: resData.eventDetails | ||
| 150 | + }) | ||
| 151 | + }, | ||
| 152 | + //成果 | ||
| 153 | + toAchieve(e) { | ||
| 21 | wx.navigateTo({ | 154 | wx.navigateTo({ |
| 22 | - url: '/pages/index/achievement/achievement', | 155 | + url: '../achievement/achievement?valueId='+this.data.valueId, |
| 23 | }) | 156 | }) |
| 24 | }, | 157 | }, |
| 25 | - // 打开打卡信息填写 | ||
| 26 | - handleEdit() { | ||
| 27 | - console.log(111) | 158 | + //唤起 打卡 |
| 159 | + toClock() { | ||
| 28 | this.setData({ | 160 | this.setData({ |
| 29 | - showEdit: true | 161 | + clockShow: true |
| 30 | }) | 162 | }) |
| 31 | }, | 163 | }, |
| 32 | - // 关闭打卡信息填写 | ||
| 33 | - closeEdit() { | 164 | + //唤起补卡 |
| 165 | + toRepairClock() { | ||
| 166 | + let selectData = this.data.calendar.getSelectedDates() | ||
| 167 | + let doday = selectData[0].year + '-' + selectData[0].month + '-' + selectData[0].date | ||
| 168 | + console.log(doday) | ||
| 169 | + let repairDate= moment(doday).format('YYYY-MM-DD') | ||
| 170 | + this.setData({ | ||
| 171 | + 'form.isRepair':2 | ||
| 172 | + }) | ||
| 173 | + this.setData({ | ||
| 174 | + 'form.repairDate':repairDate | ||
| 175 | + }) | ||
| 34 | this.setData({ | 176 | this.setData({ |
| 35 | - showEdit: false | 177 | + clockShow: true |
| 36 | }) | 178 | }) |
| 37 | }, | 179 | }, |
| 38 | - // 提交打卡信息,跳转打卡成功页面 | ||
| 39 | - handleSubmit() { | 180 | + //确定-打卡 |
| 181 | + toCardTask() { | ||
| 40 | this.setData({ | 182 | this.setData({ |
| 41 | - Clocked: true, | ||
| 42 | - showEdit: false, | ||
| 43 | - showSuccess:true | 183 | + 'form.id': this.data.valueId |
| 184 | + }) | ||
| 185 | + this.setData({ | ||
| 186 | + 'form.userId': wx.getStorageSync('userInfo_id') | ||
| 187 | + }) | ||
| 188 | + if(this.data.taskVo.submitCondition=='图片') { | ||
| 189 | + if(this.data.form.taskFileUrl.length == 0) { | ||
| 190 | + return wx.showToast({ | ||
| 191 | + title: '请上传图片', | ||
| 192 | + icon: 'none' | ||
| 193 | + }) | ||
| 194 | + } | ||
| 195 | + } | ||
| 196 | + request({ | ||
| 197 | + url: `/wx/task/commitCardTask`, | ||
| 198 | + method: 'post', | ||
| 199 | + data: this.data.form, | ||
| 200 | + }).then(res => { | ||
| 201 | + if (res.code == 0) { | ||
| 202 | + wx.showToast({ | ||
| 203 | + title: '打卡成功', | ||
| 204 | + icon: 'none' | ||
| 205 | + }) | ||
| 206 | + this.closeClockShow() | ||
| 207 | + this.getInfo(moment(new Date().getTime()).format('YYYY-MM-DD')) | ||
| 208 | + } else { | ||
| 209 | + wx.showToast({ | ||
| 210 | + title: res.msg, | ||
| 211 | + icon: 'none' | ||
| 212 | + }) | ||
| 213 | + } | ||
| 44 | }) | 214 | }) |
| 45 | }, | 215 | }, |
| 46 | - colseSuccess(){ | 216 | + /** |
| 217 | + * 生命周期函数--监听页面加载 | ||
| 218 | + */ | ||
| 219 | + onLoad(options) { | ||
| 47 | this.setData({ | 220 | this.setData({ |
| 48 | - showSuccess:false | 221 | + valueId: options.valueId |
| 49 | }) | 222 | }) |
| 50 | }, | 223 | }, |
| 224 | + /** | ||
| 225 | + * 生命周期函数--监听页面初次渲染完成 | ||
| 226 | + */ | ||
| 227 | + onReady() { | ||
| 228 | + this.initialize() | ||
| 229 | + this.getInfo(moment(new Date().getTime()).format('YYYY-MM-DD')) | ||
| 230 | + }, | ||
| 231 | + // 统一返回 | ||
| 51 | handleBack() { | 232 | handleBack() { |
| 52 | wx.navigateBack() | 233 | wx.navigateBack() |
| 53 | }, | 234 | }, |
| @@ -56,5 +237,79 @@ Page({ | @@ -56,5 +237,79 @@ Page({ | ||
| 56 | */ | 237 | */ |
| 57 | onShareAppMessage() { | 238 | onShareAppMessage() { |
| 58 | 239 | ||
| 240 | + }, | ||
| 241 | + //统计单位所含内容 | ||
| 242 | + onStatisChange(e) { | ||
| 243 | + this.setData({ | ||
| 244 | + 'form.statisticsUnit': e.detail | ||
| 245 | + }) | ||
| 246 | + }, | ||
| 247 | + //内容 | ||
| 248 | + onTaskDescChange(e) { | ||
| 249 | + this.setData({ | ||
| 250 | + 'form.taskDesc': e.detail | ||
| 251 | + }) | ||
| 252 | + }, | ||
| 253 | + //文件上传 | ||
| 254 | + afterRead(event) { | ||
| 255 | + const { | ||
| 256 | + file | ||
| 257 | + } = event.detail; | ||
| 258 | + var that = this | ||
| 259 | + // 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式 | ||
| 260 | + wx.uploadFile({ | ||
| 261 | + url: 'https://market.myjxt.com:51311/file/fileUpload', // 仅为示例,非真实的接口地址 | ||
| 262 | + filePath: file.url, | ||
| 263 | + name: 'file', | ||
| 264 | + formData: { | ||
| 265 | + user: 'test' | ||
| 266 | + }, | ||
| 267 | + success(res) { | ||
| 268 | + // 上传完成需要更新 fileList | ||
| 269 | + const { | ||
| 270 | + fileList = [] | ||
| 271 | + } = that.data; | ||
| 272 | + fileList.push({ | ||
| 273 | + ...file, | ||
| 274 | + url: res.data | ||
| 275 | + }); | ||
| 276 | + console.log(res, fileList) | ||
| 277 | + that.setData({ | ||
| 278 | + fileList | ||
| 279 | + }); | ||
| 280 | + that.setData({ | ||
| 281 | + 'form.taskFileUrl': fileList.map(v => v.url) | ||
| 282 | + }) | ||
| 283 | + }, | ||
| 284 | + }); | ||
| 285 | + }, | ||
| 286 | + //删除 | ||
| 287 | + delFile(event) { | ||
| 288 | + let [list, index] = [this.data.fileList, event.detail.index] | ||
| 289 | + list.splice(index, 1) | ||
| 290 | + this.setData({ | ||
| 291 | + fileList: list | ||
| 292 | + }) | ||
| 293 | + this.setData({ | ||
| 294 | + 'form.taskFileUrl': this.data.fileList.map(v => v.url) | ||
| 295 | + }) | ||
| 296 | + }, | ||
| 297 | + //关闭 | ||
| 298 | + closeClockShow() { | ||
| 299 | + this.setData({ | ||
| 300 | + clockShow: false | ||
| 301 | + }) | ||
| 302 | + let form = { | ||
| 303 | + id: '', //任务ID | ||
| 304 | + isRepair: 1, //是否补卡1立即打卡2补卡 | ||
| 305 | + repairDate: '', //补卡日期,当isRepair=2时必传,格式:YYYY-MM-dd | ||
| 306 | + statisticsUnit: '', //统计单位所含内容 | ||
| 307 | + taskDesc: '', //打卡描述内容 | ||
| 308 | + taskFileUrl: [], //任务文件(含多个) | ||
| 309 | + userId: '' | ||
| 310 | + } | ||
| 311 | + this.setData({ | ||
| 312 | + form: form | ||
| 313 | + }) | ||
| 59 | } | 314 | } |
| 60 | }) | 315 | }) |
| 61 | \ No newline at end of file | 316 | \ No newline at end of file |
pages/index/punchDetail/punchDetail.json
| 1 | { | 1 | { |
| 2 | "usingComponents": { | 2 | "usingComponents": { |
| 3 | "van-icon": "@vant/weapp/icon/index", | 3 | "van-icon": "@vant/weapp/icon/index", |
| 4 | - "van-popup": "@vant/weapp/popup/index" | 4 | + "calendar": "/component/v2/index", |
| 5 | + "van-popup": "@vant/weapp/popup/index", | ||
| 6 | + "van-field": "@vant/weapp/field/index", | ||
| 7 | + "van-uploader": "@vant/weapp/uploader/index", | ||
| 8 | + "van-button": "@vant/weapp/button/index" | ||
| 5 | }, | 9 | }, |
| 6 | - "navigationStyle": "custom" | 10 | + "navigationBarTitleText": "立即打卡" |
| 7 | } | 11 | } |
| 8 | \ No newline at end of file | 12 | \ No newline at end of file |
pages/index/punchDetail/punchDetail.wxml
| 1 | -<!--pages/index/punchDetail/punchDetail.wxml--> | 1 | +<!--pages/index/achievement/achievement.wxml--> |
| 2 | <view class="punch_detail"> | 2 | <view class="punch_detail"> |
| 3 | - <!-- 顶部统一返回 --> | ||
| 4 | - <view class="navigation_back" bindtap="handleBack"> | ||
| 5 | - <van-icon name="arrow-left" /> | 3 | + <calendar id="calendar" config="{{calendarConfig}}" bind:afterTapDate="afterTapDate"/> |
| 4 | + <!-- <view class="btn" bindtap="getInfo">按钮</view> --> | ||
| 5 | + <view class="line_grey"></view> | ||
| 6 | + <view class="card"> | ||
| 7 | + <view class="card_title">{{taskVo.taskTitle}}</view> | ||
| 8 | + <view class="card_flex"> | ||
| 9 | + <view class="flex_grey">已进行 {{taskVo.signTotal +' / ' +taskVo.taskCycle}} 天</view> | ||
| 10 | + <view class="flex_grey">打卡频次 : {{taskVo.taskFrequency}}</view> | ||
| 11 | + <view class="flex_grey">{{taskVo.allowRepairCard == 1 ?'允许补卡': '不允许补卡'}}</view> | ||
| 12 | + </view> | ||
| 13 | + <view class="card_context">{{taskVo.taskDesc}}</view> | ||
| 14 | + <view class="grey_font"> | ||
| 15 | + <view>我发布与{{taskVo.weekDay}} {{taskVo.releaseTime}}</view> | ||
| 16 | + <view class="grey_font_bottom"></view> | ||
| 17 | + </view> | ||
| 18 | + </view> | ||
| 19 | + <view class="btn_box"> | ||
| 20 | + <van-button round color="#F4F4F4" bindtap='toAchieve' custom-style="color: #000;">我 的 成 果</van-button> | ||
| 21 | + <van-button round type="info" bindtap='toClock' wx:if="{{isToday}}">立 即 打 卡</van-button> | ||
| 22 | + <van-button round type="warning" bindtap='toRepairClock' wx:if="{{taskVo.allowRepairCard == 1&&repairText=='未打卡'&&!isToday&&!isLarge}}">补 卡</van-button> | ||
| 6 | </view> | 23 | </view> |
| 7 | - <!-- 已打卡 --> | ||
| 8 | - <image class="temporary" wx:if="{{Clocked}}" src="/img/_check_in3.png" mode="widthFix" alt="" /> | ||
| 9 | - <!-- 未打卡 --> | ||
| 10 | - <image class="temporary" wx:else src="/img/_check_in1.png" mode="widthFix" alt="" /> | ||
| 11 | - <!-- 我的成果 --> | ||
| 12 | - <text class="temporary_box" wx:if="{{!Clocked}}" style="width: 308rpx;height: 100rpx;position: absolute;top: 1412rpx;left: 32rpx;" bindtap="handleAchievement"></text> | ||
| 13 | - <!-- 立即打卡 --> | ||
| 14 | - <text class="temporary_box" wx:if="{{!Clocked}}" style="width: 308rpx;height: 100rpx;position: absolute;top: 1412rpx;right: 32rpx;" bindtap="handleEdit"></text> | ||
| 15 | 24 | ||
| 16 | - <!-- 立即打卡 --> | ||
| 17 | - <van-popup show="{{ showEdit }}" position="bottom" custom-style="height: 80%;" bind:close="closeEdit"> | ||
| 18 | - <image class="temporary" src="/img/_check_in2.png" mode="widthFix" alt="" /> | ||
| 19 | - <text class="temporary_box" style="width: 700rpx;height: 100rpx;position: absolute;top: 1452rpx;right: 32rpx;" bindtap="handleSubmit"></text> | ||
| 20 | - </van-popup> | ||
| 21 | - <!-- 打卡成果 --> | ||
| 22 | - <van-popup show="{{ showSuccess }}" custom-style="width:80%;height: 80%;" bind:close="colseSuccess"> | ||
| 23 | - <image class="temporary" src="/img/_check_in4.png" mode="widthFix" alt="" /> | ||
| 24 | - <text class="temporary_box" style="width: 200rpx;height: 60rpx;position: absolute;top: 800rpx;left: 200rpx;" bindtap="colseSuccess"></text> | 25 | + <!--打卡--> |
| 26 | + <van-popup show="{{ clockShow }}" position="bottom" custom-style="height: 60%;" round bind:close="closeClockShow"> | ||
| 27 | + <view class="pop_title">{{form.isRepair == 2? '补交打卡成果' : '提交打卡成果'}}</view> | ||
| 28 | + <view class="pop_flex" wx:if="{{taskVo.hasData==1}}"> | ||
| 29 | + <view>提交数据</view> | ||
| 30 | + <view class="pop_cell"> | ||
| 31 | + <view> | ||
| 32 | + <van-cell-group> | ||
| 33 | + <van-field value="{{ form.statisticsUnit }}" placeholder="请输入" border="{{ false }}" bind:change="onStatisChange" /> | ||
| 34 | + </van-cell-group> | ||
| 35 | + </view> | ||
| 36 | + <view class="pop_fz">{{taskVo.statisticsUnit}}</view> | ||
| 37 | + </view> | ||
| 38 | + </view> | ||
| 39 | + <van-field value="{{ form.taskDesc }}" label="" type="textarea" placeholder="填写内容(如:已完成)" autosize border="{{ false }}" bind:change="onTaskDescChange"/> | ||
| 40 | + <view class="pop_tip"> | ||
| 41 | + <van-uploader accept='image' file-list="{{ fileList }}" deletable="{{ true }}" bind:after-read="afterRead" bind:delete="delFile"> | ||
| 42 | + <view class="tip_item"> | ||
| 43 | + <image class="pop_pic" src="/img/answer/tp1.png" alt="" /> | ||
| 44 | + </view> | ||
| 45 | + </van-uploader> | ||
| 46 | + <!-- <image class="pop_pic" src="/img/answer/tp1.png" alt="" /> --> | ||
| 47 | + </view> | ||
| 48 | + <view class="pop_btn"> | ||
| 49 | + <van-button type="{{form.isRepair == 2? 'warning':'info'}}" block round bindtap="toCardTask">提 交</van-button> | ||
| 50 | + </view> | ||
| 25 | </van-popup> | 51 | </van-popup> |
| 26 | </view> | 52 | </view> |
| 27 | \ No newline at end of file | 53 | \ No newline at end of file |
pages/index/punchDetail/punchDetail.wxss
| 1 | /* pages/index/punchDetail/punchDetail.wxss */ | 1 | /* pages/index/punchDetail/punchDetail.wxss */ |
| 2 | +/* pages/index/achievement/achievement.wxss */ | ||
| 3 | +.btn { | ||
| 4 | + width: 20vw; | ||
| 5 | + height: 20vw; | ||
| 6 | + background-color: aqua; | ||
| 7 | + font-size: 5vw; | ||
| 8 | +} | ||
| 9 | +.line_grey { | ||
| 10 | + width: 90vw; | ||
| 11 | + height: 1px; | ||
| 12 | + background-color: #999; | ||
| 13 | + margin: 10px 5vw 20px; | ||
| 14 | +} | ||
| 15 | +.card { | ||
| 16 | + width: 92vw; | ||
| 17 | + margin-left: 4vw; | ||
| 18 | +} | ||
| 19 | +.card_title { | ||
| 20 | + font-size: 18px; | ||
| 21 | + color: #556191; | ||
| 22 | + margin: 15px 0; | ||
| 23 | +} | ||
| 24 | +.card_flex { | ||
| 25 | + display: flex; | ||
| 26 | +} | ||
| 27 | +.flex_grey { | ||
| 28 | + padding: 7px 10px; | ||
| 29 | + box-sizing: border-box; | ||
| 30 | + margin: 0 5px 10px 0; | ||
| 31 | + font-size: 13px; | ||
| 32 | + background-color: #F4F4F4; | ||
| 33 | + color: #666666; | ||
| 34 | + border-radius: 3px; | ||
| 35 | +} | ||
| 36 | +.card_context { | ||
| 37 | + font-size: 16px; | ||
| 38 | + margin: 10px 0; | ||
| 39 | +} | ||
| 40 | +.grey_font { | ||
| 41 | + font-size: 14px; | ||
| 42 | + color: #999999; | ||
| 43 | + margin: 20px 0; | ||
| 44 | +} | ||
| 45 | +.grey_font_bottom { | ||
| 46 | + margin-top: 5px; | ||
| 47 | +} | ||
| 48 | +.btn_box { | ||
| 49 | + display: flex; | ||
| 50 | + justify-content: space-around; | ||
| 51 | + position: fixed; | ||
| 52 | + bottom: 50px; | ||
| 53 | + width: 100vw; | ||
| 54 | +} | ||
| 55 | +.pop_title { | ||
| 56 | + font-size: 18px; | ||
| 57 | + font-weight: bold; | ||
| 58 | + text-align: center; | ||
| 59 | + margin: 20px 0; | ||
| 60 | +} | ||
| 61 | +.pop_flex { | ||
| 62 | + display: flex; | ||
| 63 | + justify-content: space-between; | ||
| 64 | + align-items: center; | ||
| 65 | + padding: 0 20px; | ||
| 66 | + box-sizing: border-box; | ||
| 67 | +} | ||
| 68 | +.pop_cell { | ||
| 69 | + width: 40vw; | ||
| 70 | + display: flex; | ||
| 71 | + align-items: center; | ||
| 72 | +} | ||
| 73 | +.pop_fz { | ||
| 74 | + width: 70px; | ||
| 75 | +} | ||
| 76 | +.pop_btn { | ||
| 77 | + position: absolute; | ||
| 78 | + bottom: 30px; | ||
| 79 | + width: 90vw; | ||
| 80 | + margin: 0 5vw; | ||
| 81 | +} | ||
| 82 | +.pop_tip { | ||
| 83 | + position: absolute; | ||
| 84 | + bottom: 90px; | ||
| 85 | + width: 90vw; | ||
| 86 | + margin: 0 5vw; | ||
| 87 | +} | ||
| 88 | +.pop_pic { | ||
| 89 | + width: 70px; | ||
| 90 | + height: 30px; | ||
| 91 | +} | ||
| 2 | \ No newline at end of file | 92 | \ No newline at end of file |
pages/index/rank/rank.js
| 1 | // pages/index/rank/rank.js | 1 | // pages/index/rank/rank.js |
| 2 | +import request from '../../../api/request.js' | ||
| 3 | +import moment from 'moment'; | ||
| 2 | Page({ | 4 | Page({ |
| 3 | 5 | ||
| 4 | /** | 6 | /** |
| 5 | * 页面的初始数据 | 7 | * 页面的初始数据 |
| 6 | */ | 8 | */ |
| 7 | data: { | 9 | data: { |
| 10 | + rankList: [], | ||
| 11 | + dayTime: '', | ||
| 12 | + user: { | ||
| 13 | + id: '', | ||
| 14 | + userName: '', | ||
| 15 | + nickname: '', | ||
| 16 | + phone: "", | ||
| 17 | + token: "", | ||
| 18 | + headImg: '' | ||
| 19 | + }, | ||
| 20 | + selfData: { | ||
| 21 | + id: 0, | ||
| 22 | + isOneSelf: 0, | ||
| 23 | + signDayNum: 0, | ||
| 24 | + signPercentage: "", | ||
| 25 | + signRecordNum: 0, | ||
| 26 | + userId: 0 | ||
| 27 | + } | ||
| 8 | }, | 28 | }, |
| 9 | 29 | ||
| 30 | + //排行榜列表 | ||
| 31 | + getRankList() { | ||
| 32 | + request({ | ||
| 33 | + url: `/wx/task/getSignRank`, | ||
| 34 | + method: 'post', | ||
| 35 | + data: { | ||
| 36 | + "page": 1, | ||
| 37 | + "pageSize": 999, | ||
| 38 | + "userId": wx.getStorageSync("userInfo_id") | ||
| 39 | + }, | ||
| 40 | + }).then(res => { | ||
| 41 | + if (res.code == 0) { | ||
| 42 | + this.setData({ | ||
| 43 | + rankList: res.rows | ||
| 44 | + }) | ||
| 45 | + console.log(this.data.rankList) | ||
| 46 | + } else { | ||
| 47 | + wx.showToast({ | ||
| 48 | + title: res.msg, | ||
| 49 | + icon: 'none', | ||
| 50 | + duration: 1500 | ||
| 51 | + }) | ||
| 52 | + } | ||
| 53 | + }) | ||
| 54 | + }, | ||
| 55 | + //去打卡 | ||
| 56 | + toOpen() { | ||
| 57 | + wx.navigateTo({ | ||
| 58 | + url: '/pages/index/index', | ||
| 59 | + }) | ||
| 60 | + }, | ||
| 61 | + //获取个人 | ||
| 62 | + getSelf() { | ||
| 63 | + request({ | ||
| 64 | + url: `/wx/task/getOneSelf`, | ||
| 65 | + method: 'get', | ||
| 66 | + data: { | ||
| 67 | + "userId": wx.getStorageSync("userInfo_id") | ||
| 68 | + }, | ||
| 69 | + }).then(res => { | ||
| 70 | + if (res.code == 0) { | ||
| 71 | + this.setData({ | ||
| 72 | + selfData: res.data | ||
| 73 | + }) | ||
| 74 | + } else { | ||
| 75 | + wx.showToast({ | ||
| 76 | + title: res.msg, | ||
| 77 | + icon: 'none', | ||
| 78 | + }) | ||
| 79 | + } | ||
| 80 | + }) | ||
| 81 | + }, | ||
| 10 | /** | 82 | /** |
| 11 | * 生命周期函数--监听页面加载 | 83 | * 生命周期函数--监听页面加载 |
| 12 | */ | 84 | */ |
| 13 | onLoad(options) { | 85 | onLoad(options) { |
| 14 | - | 86 | + |
| 15 | }, | 87 | }, |
| 16 | // 统一返回 | 88 | // 统一返回 |
| 17 | handleBack() { | 89 | handleBack() { |
| 18 | wx.navigateBack() | 90 | wx.navigateBack() |
| 19 | }, | 91 | }, |
| 20 | - /** | ||
| 21 | - * 用户点击右上角分享 | ||
| 22 | - */ | ||
| 23 | - onShareAppMessage() { | ||
| 24 | - | 92 | + onShow() { |
| 93 | + this.setData({ | ||
| 94 | + 'user': wx.getStorageSync('userInfo') | ||
| 95 | + }) | ||
| 96 | + this.setData({ | ||
| 97 | + "dayTime": moment(new Date().getTime()).format('YYYY-MM-DD') | ||
| 98 | + }) | ||
| 99 | + this.getSelf() | ||
| 100 | + this.getRankList() | ||
| 25 | } | 101 | } |
| 26 | }) | 102 | }) |
| 27 | \ No newline at end of file | 103 | \ No newline at end of file |
pages/index/rank/rank.json
| 1 | { | 1 | { |
| 2 | "usingComponents": { | 2 | "usingComponents": { |
| 3 | - "van-icon": "@vant/weapp/icon/index" | 3 | + "van-icon": "@vant/weapp/icon/index", |
| 4 | + "van-button": "@vant/weapp/button/index" | ||
| 4 | }, | 5 | }, |
| 5 | "navigationStyle": "custom" | 6 | "navigationStyle": "custom" |
| 6 | } | 7 | } |
| 7 | \ No newline at end of file | 8 | \ No newline at end of file |
pages/index/rank/rank.wxml
| 1 | <!--pages/index/rank/rank.wxml--> | 1 | <!--pages/index/rank/rank.wxml--> |
| 2 | -<view class="punch_detail"> | ||
| 3 | - <!-- 顶部统一返回 --> | ||
| 4 | - <view class="navigation_back" bindtap="handleBack"> | ||
| 5 | - <van-icon name="arrow-left" /> | ||
| 6 | - </view> | ||
| 7 | - <image class="temporary" src="/img/_rank.png" mode="widthFix" alt="" /> | 2 | +<!-- <view class="rank" style="background-image: url('https://szyundisk.oss-cn-hangzhou.aliyuncs.com/null/5f055580-1341-4c52-9154-c3b125c1107a.png')"> --> |
| 3 | +<view class="rank" style="background-image: url('https://szyundisk.oss-cn-hangzhou.aliyuncs.com/AdmissionsManageSys/54ec1f3f-dbb4-4660-ba24-4a6731e88def.png')"> | ||
| 4 | + <view class="rank_time">更新时间:{{dayTime}}</view> | ||
| 5 | + <view class="white_box"> | ||
| 6 | + <view class="title_box"> | ||
| 7 | + <view class="title_pic"> | ||
| 8 | + <image class="pic" src="{{user.headImg}}" alt="" /> | ||
| 9 | + {{user.userName != null ? user.userName : user.nickname}} | ||
| 10 | + </view> | ||
| 11 | + <view class="red_title">已坚持{{selfData.signDayNum}}天</view> | ||
| 12 | + <view class="red_title">{{selfData.signRecordNum}}次</view> | ||
| 13 | + </view> | ||
| 14 | + <view class="grey_title"> | ||
| 15 | + <view class="table_L"> | ||
| 16 | + <view>排名</view> | ||
| 17 | + <view>姓名</view> | ||
| 18 | + </view> | ||
| 19 | + <view>打卡数</view> | ||
| 20 | + </view> | ||
| 8 | 21 | ||
| 22 | + <view class="table_item" wx:for="{{ rankList }}" wx:key="index" wx:for-item="value"> | ||
| 23 | + <view class="table_L"> | ||
| 24 | + <image wx:if="{{index == 0}}" class="tem_pic" src="/img/answer/1.png" alt="" /> | ||
| 25 | + <image wx:if="{{index == 1}}" class="tem_pic" src="/img/answer/2.png" alt="" /> | ||
| 26 | + <image wx:if="{{index == 2}}" class="tem_pic" src="/img/answer/3.png" alt="" /> | ||
| 27 | + <view class="tem_pic" wx:if="{{index != 0 && index != 1 && index != 2}}">{{index + 1}}</view> | ||
| 28 | + <view>{{value.userName}}</view> | ||
| 29 | + </view> | ||
| 30 | + <view class="table_R"> | ||
| 31 | + <view class="grey_R">已坚持{{value.signDayNum}}天</view> | ||
| 32 | + <view>{{value.signRecordNum}}</view> | ||
| 33 | + </view> | ||
| 34 | + </view> | ||
| 35 | + </view> | ||
| 36 | + | ||
| 37 | + <view class="btn"> | ||
| 38 | + <van-button type="info" block round bindtap="toOpen">去打卡</van-button> | ||
| 39 | + </view> | ||
| 9 | </view> | 40 | </view> |
| 10 | \ No newline at end of file | 41 | \ No newline at end of file |
pages/index/rank/rank.wxss
| 1 | /* pages/index/rank/rank.wxss */ | 1 | /* pages/index/rank/rank.wxss */ |
| 2 | +.rank { | ||
| 3 | + position: absolute; | ||
| 4 | + width: 100vw; | ||
| 5 | + min-height: 100vh; | ||
| 6 | + background-size: 100% 100%; | ||
| 7 | + padding: 0 5vw; | ||
| 8 | + box-sizing: border-box; | ||
| 9 | +} | ||
| 10 | +.rank_time { | ||
| 11 | + font-size: 4.4vw; | ||
| 12 | + color: #fff; | ||
| 13 | + opacity: 0.8; | ||
| 14 | + margin-top: 125px; | ||
| 15 | + margin-left: 2vw; | ||
| 16 | +} | ||
| 17 | +.white_box{ | ||
| 18 | + width: 90vw; | ||
| 19 | + min-height: 72vh; | ||
| 20 | + margin-top: 40px; | ||
| 21 | + background-color: #fff; | ||
| 22 | + border-radius: 4vw; | ||
| 23 | + padding: 7vw 5vw; | ||
| 24 | + box-sizing: border-box; | ||
| 25 | +} | ||
| 26 | +.title_box { | ||
| 27 | + display: flex; | ||
| 28 | + justify-content: space-between; | ||
| 29 | + align-items: center; | ||
| 30 | + font-size: 3.9vw; | ||
| 31 | + font-weight: bold; | ||
| 32 | + padding: 30px 5vw; | ||
| 33 | + box-sizing: border-box; | ||
| 34 | + border-radius: 5vw; | ||
| 35 | + box-shadow: 1px 1px 1px 1px rgb(207, 206, 206); | ||
| 36 | +} | ||
| 37 | +.title_pic { | ||
| 38 | + display: flex; | ||
| 39 | + align-items: center; | ||
| 40 | +} | ||
| 41 | +.pic { | ||
| 42 | + width: 25px; | ||
| 43 | + height: 25px; | ||
| 44 | + border-radius: 25px; | ||
| 45 | + margin-right: 7px; | ||
| 46 | +} | ||
| 47 | +.red_title { | ||
| 48 | + color: #FD676A; | ||
| 49 | +} | ||
| 50 | +.grey_title { | ||
| 51 | + margin: 30px 0; | ||
| 52 | + font-size: 4.5vw; | ||
| 53 | + color: #999; | ||
| 54 | + display: flex; | ||
| 55 | + justify-content: space-between; | ||
| 56 | +} | ||
| 57 | +.table_L{ | ||
| 58 | + width: 28vw; | ||
| 59 | + display: flex; | ||
| 60 | + justify-content: space-between; | ||
| 61 | + align-items: center; | ||
| 62 | +} | ||
| 63 | +.L_box { | ||
| 64 | + width: 50px; | ||
| 65 | +} | ||
| 66 | + | ||
| 67 | +.table_item { | ||
| 68 | + margin: 20px 0; | ||
| 69 | + font-size: 4vw; | ||
| 70 | + color: #333; | ||
| 71 | + display: flex; | ||
| 72 | + justify-content: space-between; | ||
| 73 | + align-items: center; | ||
| 74 | +} | ||
| 75 | +.table_R { | ||
| 76 | + width: 45vw; | ||
| 77 | + display: flex; | ||
| 78 | + justify-content: space-between; | ||
| 79 | + align-items: center; | ||
| 80 | +} | ||
| 81 | +.grey_R { | ||
| 82 | + color:#999; | ||
| 83 | + font-size: 3.9vw; | ||
| 84 | +} | ||
| 85 | +.tem_pic { | ||
| 86 | + width: 22px; | ||
| 87 | + height: 28px; | ||
| 88 | + text-align: center; | ||
| 89 | +} | ||
| 90 | +.btn { | ||
| 91 | + position: fixed; | ||
| 92 | + bottom: 50px; | ||
| 93 | + width: 82vw; | ||
| 94 | + margin-left: 4vw; | ||
| 95 | +} | ||
| 2 | \ No newline at end of file | 96 | \ No newline at end of file |
pages/login/codeLogin/codeLogin.js
| 1 | // pages/login/codeLogin/codeLogin.js | 1 | // pages/login/codeLogin/codeLogin.js |
| 2 | -var app = getApp(); | 2 | +// var app = getApp(); |
| 3 | +var api = 'https://proxy.shunzhi.net/'; | ||
| 4 | +var api_card = 'https://proxy.shunzhi.net/card/'; | ||
| 5 | +var appid = 'wx186236fdcd93edcc'; | ||
| 3 | var util = require('../../../utils/md5.js') | 6 | var util = require('../../../utils/md5.js') |
| 4 | import request from '../../../api/request.js' | 7 | import request from '../../../api/request.js' |
| 5 | Page({ | 8 | Page({ |
| @@ -21,6 +24,7 @@ Page({ | @@ -21,6 +24,7 @@ Page({ | ||
| 21 | path: '', //登录后跳转页面 | 24 | path: '', //登录后跳转页面 |
| 22 | modelShow: false, //完善信息 | 25 | modelShow: false, //完善信息 |
| 23 | phone: '', //getUserInfo获取到的手机号 | 26 | phone: '', //getUserInfo获取到的手机号 |
| 27 | + openId: '' | ||
| 24 | }, | 28 | }, |
| 25 | onLoad: function (options) { | 29 | onLoad: function (options) { |
| 26 | console.log('登录页options:', options) | 30 | console.log('登录页options:', options) |
| @@ -69,20 +73,25 @@ Page({ | @@ -69,20 +73,25 @@ Page({ | ||
| 69 | }) | 73 | }) |
| 70 | } | 74 | } |
| 71 | request({ | 75 | request({ |
| 72 | - url: `h5/user/Oneclicklogin`, | ||
| 73 | - method: 'get', | 76 | + url: `/wx/app/oneClickLogin/`+ appid, |
| 77 | + method: 'post', | ||
| 74 | data: { | 78 | data: { |
| 75 | "encryptedData": this.data.encryptedData, | 79 | "encryptedData": this.data.encryptedData, |
| 76 | - "session_key": this.data.session_key, | 80 | + "sessionKey": this.data.session_key, |
| 77 | "iv": this.data.iv, | 81 | "iv": this.data.iv, |
| 82 | + "openId": this.data.openId | ||
| 78 | }, | 83 | }, |
| 79 | }).then(res => { | 84 | }).then(res => { |
| 80 | - if (res.success) { | 85 | + if (res.code == 0) { |
| 81 | if (res.data) { | 86 | if (res.data) { |
| 82 | this.setData({ | 87 | this.setData({ |
| 83 | phone: res.data.phone | 88 | phone: res.data.phone |
| 84 | }, () => { | 89 | }, () => { |
| 85 | - this.getUserInfo() | 90 | + wx.setStorageSync('userInfo', res.data) |
| 91 | + wx.setStorageSync('userInfo_id', res.data.id) | ||
| 92 | + wx.switchTab({ | ||
| 93 | + url: '/pages/mine/index', | ||
| 94 | + }) | ||
| 86 | }) | 95 | }) |
| 87 | } else { | 96 | } else { |
| 88 | wx.showToast({ | 97 | wx.showToast({ |
| @@ -107,36 +116,39 @@ Page({ | @@ -107,36 +116,39 @@ Page({ | ||
| 107 | } | 116 | } |
| 108 | }, | 117 | }, |
| 109 | getUserInfo() { | 118 | getUserInfo() { |
| 110 | - let that = this | ||
| 111 | - request({ | ||
| 112 | - url: `h5/user/getuserInfoNew`, | ||
| 113 | - method: 'get', | ||
| 114 | - data: { | ||
| 115 | - // PhoneName: '13355752969' | ||
| 116 | - PhoneName: this.data.phone | ||
| 117 | - }, | ||
| 118 | - }).then((res) => { | ||
| 119 | - if (res.success) { | ||
| 120 | - if (res.data) { | ||
| 121 | - wx.setStorageSync('userInfo', res.data) | ||
| 122 | - wx.setStorageSync('showModal', '') | 119 | + // let that = this |
| 120 | + // request({ | ||
| 121 | + // url: `h5/user/getuserInfoNew`, | ||
| 122 | + // method: 'get', | ||
| 123 | + // data: { | ||
| 124 | + // // PhoneName: '13355752969' | ||
| 125 | + // PhoneName: this.data.phone | ||
| 126 | + // }, | ||
| 127 | + // }).then((res) => { | ||
| 128 | + // if (res.success) { | ||
| 129 | + // if (res.data) { | ||
| 130 | + // wx.setStorageSync('userInfo', res.data) | ||
| 131 | + // wx.setStorageSync('showModal', '') | ||
| 123 | 132 | ||
| 124 | - } | ||
| 125 | - } | ||
| 126 | - }) | 133 | + // } |
| 134 | + // } | ||
| 135 | + // }) | ||
| 127 | }, | 136 | }, |
| 128 | - getOpenId() { | 137 | + getOpenId() { |
| 129 | return request({ | 138 | return request({ |
| 130 | - url: `h5/MyVoluntary/GetOpenId`, | 139 | + url: `/wx/app/getOpenId/wx186236fdcd93edcc`, |
| 131 | method: 'get', | 140 | method: 'get', |
| 132 | data: { | 141 | data: { |
| 133 | code: this.data.loginCode | 142 | code: this.data.loginCode |
| 134 | }, | 143 | }, |
| 135 | }).then(res2 => { | 144 | }).then(res2 => { |
| 136 | - // console.log(res2.data); | ||
| 137 | this.setData({ | 145 | this.setData({ |
| 138 | - session_key: JSON.parse(res2.data).session_key | 146 | + session_key: res2.data.sessionKey |
| 139 | }) | 147 | }) |
| 148 | + this.setData({ | ||
| 149 | + openId: res2.data.openid | ||
| 150 | + }) | ||
| 151 | + console.log(this.data); | ||
| 140 | }) | 152 | }) |
| 141 | }, | 153 | }, |
| 142 | bindUserName: function (e) { | 154 | bindUserName: function (e) { |
| @@ -181,16 +193,17 @@ Page({ | @@ -181,16 +193,17 @@ Page({ | ||
| 181 | wx.showLoading({ | 193 | wx.showLoading({ |
| 182 | title: '请求中', | 194 | title: '请求中', |
| 183 | }) | 195 | }) |
| 184 | - wx.request({ | ||
| 185 | - url: api + 'h5/MyVoluntary/CheckCodeIsRight', | 196 | + wx.request({ |
| 197 | + url: api_card + '/wx/app/loginCode', | ||
| 186 | data: { | 198 | data: { |
| 187 | - captcha: code, | ||
| 188 | - mobile: username | 199 | + code: code, |
| 200 | + phone: username | ||
| 189 | }, | 201 | }, |
| 190 | - method: 'get', | 202 | + method: 'post', |
| 191 | success: (res) => { | 203 | success: (res) => { |
| 192 | wx.hideLoading(); | 204 | wx.hideLoading(); |
| 193 | if (res.data.success) { | 205 | if (res.data.success) { |
| 206 | + console.log(res.data) | ||
| 194 | if (res.data.data) { | 207 | if (res.data.data) { |
| 195 | this.setData({ | 208 | this.setData({ |
| 196 | phone: res.data.data.phone | 209 | phone: res.data.data.phone |
| @@ -306,7 +319,7 @@ Page({ | @@ -306,7 +319,7 @@ Page({ | ||
| 306 | } | 319 | } |
| 307 | }, | 320 | }, |
| 308 | getPhoneNumber(e) { | 321 | getPhoneNumber(e) { |
| 309 | - // console.log(e.detail) | 322 | + console.log(e.detail) |
| 310 | if (e.detail.errMsg == 'getPhoneNumber:ok') { | 323 | if (e.detail.errMsg == 'getPhoneNumber:ok') { |
| 311 | this.setData({ | 324 | this.setData({ |
| 312 | encryptedData: e.detail.encryptedData, | 325 | encryptedData: e.detail.encryptedData, |
| @@ -315,7 +328,6 @@ Page({ | @@ -315,7 +328,6 @@ Page({ | ||
| 315 | this.login() | 328 | this.login() |
| 316 | }) | 329 | }) |
| 317 | } | 330 | } |
| 318 | - | ||
| 319 | }, | 331 | }, |
| 320 | //去查看协议 | 332 | //去查看协议 |
| 321 | toProtocol() { | 333 | toProtocol() { |
| @@ -331,7 +343,7 @@ Page({ | @@ -331,7 +343,7 @@ Page({ | ||
| 331 | }, | 343 | }, |
| 332 | goIndex() { | 344 | goIndex() { |
| 333 | wx.switchTab({ | 345 | wx.switchTab({ |
| 334 | - url: '/pages/index/index', | 346 | + url: '/pages/index/rank/rank', |
| 335 | }) | 347 | }) |
| 336 | }, | 348 | }, |
| 337 | 349 |
pages/login/codeLogin/codeLogin.wxss
| @@ -0,0 +1,167 @@ | @@ -0,0 +1,167 @@ | ||
| 1 | +// pages/login/loginNew/loginNew.js | ||
| 2 | +import request from '../../../api/request.js' | ||
| 3 | +var appid = 'wx186236fdcd93edcc'; | ||
| 4 | +Page({ | ||
| 5 | + | ||
| 6 | + /** | ||
| 7 | + * 页面的初始数据 | ||
| 8 | + */ | ||
| 9 | + data: { | ||
| 10 | + checked: true, | ||
| 11 | + session_key: '', | ||
| 12 | + openId: '', | ||
| 13 | + encryptedData: '', | ||
| 14 | + iv: '', | ||
| 15 | + phone: '' | ||
| 16 | + }, | ||
| 17 | + //多选框 | ||
| 18 | + onChange(e) { | ||
| 19 | + this.setData({ | ||
| 20 | + checked: e.detail | ||
| 21 | + }) | ||
| 22 | + }, | ||
| 23 | + //获取session_key | ||
| 24 | + getOpenId() { | ||
| 25 | + return request({ | ||
| 26 | + url: `/wx/app/getOpenId/wx186236fdcd93edcc`, | ||
| 27 | + method: 'get', | ||
| 28 | + data: { | ||
| 29 | + code: this.data.loginCode | ||
| 30 | + }, | ||
| 31 | + }).then(res2 => { | ||
| 32 | + this.setData({ | ||
| 33 | + session_key: res2.data.sessionKey | ||
| 34 | + }) | ||
| 35 | + this.setData({ | ||
| 36 | + openId: res2.data.openid | ||
| 37 | + }) | ||
| 38 | + console.log(this.data); | ||
| 39 | + }) | ||
| 40 | + }, | ||
| 41 | + getPhoneNumber(e) { | ||
| 42 | + console.log('?') | ||
| 43 | + if(!this.data.checked) { | ||
| 44 | + return wx.showToast({title: '请先阅读并同意用户协议和隐私协议',icon: 'none'}) | ||
| 45 | + } | ||
| 46 | + console.log(e.detail) | ||
| 47 | + if (e.detail.errMsg == 'getPhoneNumber:ok') { | ||
| 48 | + this.setData({ | ||
| 49 | + encryptedData: e.detail.encryptedData, | ||
| 50 | + iv: e.detail.iv, | ||
| 51 | + }, () => { | ||
| 52 | + this.login() | ||
| 53 | + }) | ||
| 54 | + } | ||
| 55 | + }, | ||
| 56 | + login() { | ||
| 57 | + if (!this.data.encryptedData || !this.data.session_key || !this.data.iv) { | ||
| 58 | + wx.showToast({ | ||
| 59 | + title: '一键登陆失败,请重试', | ||
| 60 | + icon: 'none', | ||
| 61 | + duration: 2000 | ||
| 62 | + }) | ||
| 63 | + } | ||
| 64 | + request({ | ||
| 65 | + url: `/wx/app/oneClickLogin/`+ appid, | ||
| 66 | + method: 'post', | ||
| 67 | + data: { | ||
| 68 | + "encryptedData": this.data.encryptedData, | ||
| 69 | + "sessionKey": this.data.session_key, | ||
| 70 | + "iv": this.data.iv, | ||
| 71 | + "openId": this.data.openId | ||
| 72 | + }, | ||
| 73 | + }).then(res => { | ||
| 74 | + if (res.code == 0) { | ||
| 75 | + if (res.data) { | ||
| 76 | + this.setData({ | ||
| 77 | + phone: res.data.phone | ||
| 78 | + }, () => { | ||
| 79 | + wx.setStorageSync('userInfo', res.data) | ||
| 80 | + wx.setStorageSync('userInfo_id', res.data.id) | ||
| 81 | + if(res.data.hasRecord == 1) { | ||
| 82 | + wx.switchTab({ | ||
| 83 | + url: '/pages/index/rank/rank', | ||
| 84 | + }) | ||
| 85 | + }else { | ||
| 86 | + wx.switchTab({ | ||
| 87 | + url: '/pages/mine/index', | ||
| 88 | + }) | ||
| 89 | + } | ||
| 90 | + }) | ||
| 91 | + } else { | ||
| 92 | + wx.showToast({ | ||
| 93 | + title: '一键登陆失败,请重试', | ||
| 94 | + icon: 'none', | ||
| 95 | + duration: 2000 | ||
| 96 | + }) | ||
| 97 | + } | ||
| 98 | + } | ||
| 99 | + }) | ||
| 100 | + }, | ||
| 101 | + /** | ||
| 102 | + * 生命周期函数--监听页面加载 | ||
| 103 | + */ | ||
| 104 | + onLoad() { | ||
| 105 | + wx.login({ | ||
| 106 | + success: (res) => { | ||
| 107 | + if (res.code) { | ||
| 108 | + this.setData({ | ||
| 109 | + loginCode: res.code | ||
| 110 | + }) | ||
| 111 | + this.getOpenId() | ||
| 112 | + } else { | ||
| 113 | + console.log('登录失败!' + res.errMsg) | ||
| 114 | + } | ||
| 115 | + } | ||
| 116 | + }) | ||
| 117 | + }, | ||
| 118 | + | ||
| 119 | + /** | ||
| 120 | + * 生命周期函数--监听页面初次渲染完成 | ||
| 121 | + */ | ||
| 122 | + onReady() { | ||
| 123 | + | ||
| 124 | + }, | ||
| 125 | + | ||
| 126 | + /** | ||
| 127 | + * 生命周期函数--监听页面显示 | ||
| 128 | + */ | ||
| 129 | + onShow() { | ||
| 130 | + | ||
| 131 | + }, | ||
| 132 | + | ||
| 133 | + /** | ||
| 134 | + * 生命周期函数--监听页面隐藏 | ||
| 135 | + */ | ||
| 136 | + onHide() { | ||
| 137 | + | ||
| 138 | + }, | ||
| 139 | + | ||
| 140 | + /** | ||
| 141 | + * 生命周期函数--监听页面卸载 | ||
| 142 | + */ | ||
| 143 | + onUnload() { | ||
| 144 | + | ||
| 145 | + }, | ||
| 146 | + | ||
| 147 | + /** | ||
| 148 | + * 页面相关事件处理函数--监听用户下拉动作 | ||
| 149 | + */ | ||
| 150 | + onPullDownRefresh() { | ||
| 151 | + | ||
| 152 | + }, | ||
| 153 | + | ||
| 154 | + /** | ||
| 155 | + * 页面上拉触底事件的处理函数 | ||
| 156 | + */ | ||
| 157 | + onReachBottom() { | ||
| 158 | + | ||
| 159 | + }, | ||
| 160 | + | ||
| 161 | + /** | ||
| 162 | + * 用户点击右上角分享 | ||
| 163 | + */ | ||
| 164 | + onShareAppMessage() { | ||
| 165 | + | ||
| 166 | + } | ||
| 167 | +}) | ||
| 0 | \ No newline at end of file | 168 | \ No newline at end of file |
| @@ -0,0 +1,8 @@ | @@ -0,0 +1,8 @@ | ||
| 1 | +{ | ||
| 2 | + "usingComponents": { | ||
| 3 | + "van-button": "@vant/weapp/button/index", | ||
| 4 | + "van-checkbox": "@vant/weapp/checkbox/index", | ||
| 5 | + "van-checkbox-group": "@vant/weapp/checkbox-group/index" | ||
| 6 | + }, | ||
| 7 | + "navigationBarTitleText": "登录" | ||
| 8 | +} | ||
| 0 | \ No newline at end of file | 9 | \ No newline at end of file |
| @@ -0,0 +1,23 @@ | @@ -0,0 +1,23 @@ | ||
| 1 | +<!--pages/login/loginNew/loginNew.wxml--> | ||
| 2 | +<view> | ||
| 3 | + <view class="box"> | ||
| 4 | + <view class="img_box"> | ||
| 5 | + <image class="pic" src="/img/login_img.png" alt="" /> | ||
| 6 | + </view> | ||
| 7 | + <view class="box_title">Hey</view> | ||
| 8 | + <view class="box_grey">欢迎使用自主学习之旅~</view> | ||
| 9 | + </view> | ||
| 10 | + <view class="fied_box"> | ||
| 11 | + <view> | ||
| 12 | + <van-button type="info" block round open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">登 录</van-button> | ||
| 13 | + </view> | ||
| 14 | + <view class="small_font"> | ||
| 15 | + <van-checkbox value="{{ checked }}" shape="square" bind:change="onChange" icon-size='15'> | ||
| 16 | + <view class="small_font_tip"> | ||
| 17 | + 已同意 <navigator url="../protocol/protocol"><text class="blue_font"> 用户协议 </text></navigator>和<navigator url="../policy/policy"><text class="blue_font"> 隐私协议 </text></navigator> | ||
| 18 | + </view> | ||
| 19 | + </van-checkbox> | ||
| 20 | + </view> | ||
| 21 | + <van-notify id="van-notify" /> | ||
| 22 | + </view> | ||
| 23 | +</view> | ||
| 0 | \ No newline at end of file | 24 | \ No newline at end of file |
| @@ -0,0 +1,46 @@ | @@ -0,0 +1,46 @@ | ||
| 1 | +/* pages/login/loginNew/loginNew.wxss */ | ||
| 2 | +.box { | ||
| 3 | + display: flex; | ||
| 4 | + justify-content: center; | ||
| 5 | + flex-wrap: wrap; | ||
| 6 | +} | ||
| 7 | +.img_box { | ||
| 8 | + width: 60vw; | ||
| 9 | + height: 60vw; | ||
| 10 | + margin: 100px 0 30px; | ||
| 11 | +} | ||
| 12 | +.pic { | ||
| 13 | + width: 100%; | ||
| 14 | + height: 100%; | ||
| 15 | +} | ||
| 16 | +.box_title { | ||
| 17 | + width: 100%; | ||
| 18 | + text-align: center; | ||
| 19 | + margin: 15px 0; | ||
| 20 | + font-weight: bold; | ||
| 21 | +} | ||
| 22 | +.box_grey { | ||
| 23 | + width: 100%; | ||
| 24 | + text-align: center; | ||
| 25 | + color: #999; | ||
| 26 | +} | ||
| 27 | +.fied_box { | ||
| 28 | + position: fixed; | ||
| 29 | + bottom: 40px; | ||
| 30 | + width: 100%; | ||
| 31 | + padding: 0 30px; | ||
| 32 | + box-sizing: border-box; | ||
| 33 | +} | ||
| 34 | +.small_font { | ||
| 35 | + display: flex; | ||
| 36 | + justify-content: center; | ||
| 37 | + font-size: 12px; | ||
| 38 | + margin: 10px 0 0; | ||
| 39 | +} | ||
| 40 | +.small_font_tip { | ||
| 41 | + display: flex; | ||
| 42 | +} | ||
| 43 | +.blue_font { | ||
| 44 | + color: #3578F9; | ||
| 45 | + text-decoration:underline; | ||
| 46 | +} | ||
| 0 | \ No newline at end of file | 47 | \ No newline at end of file |
pages/login/policy/policy.json
pages/login/protocol/protocol.json
pages/mine/index.js
| @@ -6,7 +6,9 @@ Page({ | @@ -6,7 +6,9 @@ Page({ | ||
| 6 | * 页面的初始数据 | 6 | * 页面的初始数据 |
| 7 | */ | 7 | */ |
| 8 | data: { | 8 | data: { |
| 9 | - | 9 | + user_name: '', |
| 10 | + user_phone: '', | ||
| 11 | + user_img: '', | ||
| 10 | }, | 12 | }, |
| 11 | // 打卡记录 | 13 | // 打卡记录 |
| 12 | handleRecord(){ | 14 | handleRecord(){ |
| @@ -14,13 +16,26 @@ Page({ | @@ -14,13 +16,26 @@ Page({ | ||
| 14 | url: '/pages/mine/record/record', | 16 | url: '/pages/mine/record/record', |
| 15 | }) | 17 | }) |
| 16 | }, | 18 | }, |
| 17 | -// 退出登录 | 19 | + // 退出登录 |
| 18 | handleLoginOut(){ | 20 | handleLoginOut(){ |
| 21 | + wx.clearStorage() | ||
| 22 | + wx.clearStorageSync() | ||
| 19 | wx.navigateTo({ | 23 | wx.navigateTo({ |
| 20 | - url: '/pages/login/codeLogin/codeLogin', | 24 | + url: '/pages/login/loginNew/loginNew', |
| 21 | }) | 25 | }) |
| 22 | }, | 26 | }, |
| 23 | /** | 27 | /** |
| 28 | + * 生命周期函数--监听页面加载 | ||
| 29 | + */ | ||
| 30 | + onLoad(options) { | ||
| 31 | + let userInfo = wx.getStorageSync('userInfo') | ||
| 32 | + this.setData({ | ||
| 33 | + "user_name": userInfo.userName || userInfo.nickname, | ||
| 34 | + "user_phone": userInfo.phone, | ||
| 35 | + 'user_img':userInfo.headImg, | ||
| 36 | + }) | ||
| 37 | + }, | ||
| 38 | + /** | ||
| 24 | * 用户点击右上角分享 | 39 | * 用户点击右上角分享 |
| 25 | */ | 40 | */ |
| 26 | onShareAppMessage: function () { | 41 | onShareAppMessage: function () { |
pages/mine/index.wxml
| 1 | -<view class="mine"> | ||
| 2 | - <image class="temporary" src="../../img/_mine.png" mode="widthFix" alt="" /> | ||
| 3 | - <!-- 打卡记录 --> | ||
| 4 | - <text class="temporary_box" style="width: 340rpx;height: 160rpx;position: absolute;top: 340rpx;left: 32rpx;" bindtap="handleRecord"></text> | ||
| 5 | - <!-- 退出登录 --> | ||
| 6 | - <text class="temporary_box" style="width: 340rpx;height: 160rpx;position: absolute;top: 340rpx;right: 32rpx;" bindtap="handleLoginOut"></text> | ||
| 7 | - | 1 | +<view class="mine" style="background-image: url('https://szyundisk.oss-cn-hangzhou.aliyuncs.com/null/89741dbf-cc76-45a6-a3c9-a210eb7deeef.png')"> |
| 2 | + <view class="title"> | ||
| 3 | + <view> | ||
| 4 | + <image class="pic" src="{{user_img}}" alt="" /> | ||
| 5 | + </view> | ||
| 6 | + <view class="title_box"> | ||
| 7 | + <view class="title_name">{{user_name}}</view> | ||
| 8 | + <view class="grey_title">{{user_phone}}</view> | ||
| 9 | + </view> | ||
| 10 | + </view> | ||
| 11 | + <view class="flex_card"> | ||
| 12 | + <view class="card_item" bindtap="handleRecord"> | ||
| 13 | + <view><image class="card_pic" src="/img/answer/dkjl.png" alt="" /></view> | ||
| 14 | + <view class="item_font">创建打卡</view> | ||
| 15 | + </view> | ||
| 16 | + <view class="grey_line"></view> | ||
| 17 | + <view class="card_item" bindtap="handleLoginOut"> | ||
| 18 | + <view><image class="card_pic" src="/img/answer/back.png" alt="" /></view> | ||
| 19 | + <view class="item_font">退出登录</view> | ||
| 20 | + </view> | ||
| 21 | + </view> | ||
| 8 | </view> | 22 | </view> |
pages/mine/index.wxss
| @@ -0,0 +1,59 @@ | @@ -0,0 +1,59 @@ | ||
| 1 | + .mine { | ||
| 2 | + position: absolute; | ||
| 3 | + width: 100vw; | ||
| 4 | + min-height: 40vh; | ||
| 5 | + background-size: 100% 100%; | ||
| 6 | + padding: 140px 5vw 0; | ||
| 7 | + box-sizing: border-box; | ||
| 8 | + } | ||
| 9 | + .title { | ||
| 10 | + display: flex; | ||
| 11 | + } | ||
| 12 | + .pic { | ||
| 13 | + width: 60px; | ||
| 14 | + height: 60px; | ||
| 15 | + border-radius: 60px; | ||
| 16 | + } | ||
| 17 | + .title_box { | ||
| 18 | + margin-left: 20px; | ||
| 19 | + display: flex; | ||
| 20 | + align-content: space-between; | ||
| 21 | + flex-wrap: wrap; | ||
| 22 | + padding: 4px 0; | ||
| 23 | + box-sizing: border-box; | ||
| 24 | + } | ||
| 25 | + .title_name { | ||
| 26 | + font-size: 18px; | ||
| 27 | + font-weight: bold; | ||
| 28 | + } | ||
| 29 | + .grey_title { | ||
| 30 | + width: 100%; | ||
| 31 | + font-size: 14px; | ||
| 32 | + color: #999; | ||
| 33 | + } | ||
| 34 | + .flex_card { | ||
| 35 | + display: flex; | ||
| 36 | + justify-content: space-between; | ||
| 37 | + padding: 20px 50px; | ||
| 38 | + box-sizing: border-box; | ||
| 39 | + box-shadow: 1px 1px 1px 1px rgb(224, 224, 224); | ||
| 40 | + margin: 40px 0; | ||
| 41 | + background-color: #fff; | ||
| 42 | + border-radius: 20px; | ||
| 43 | + } | ||
| 44 | + .card_item { | ||
| 45 | + text-align: center; | ||
| 46 | + } | ||
| 47 | + .card_pic { | ||
| 48 | + width: 30px; | ||
| 49 | + height: 30px; | ||
| 50 | +} | ||
| 51 | +.item_font { | ||
| 52 | + margin-top: 10px; | ||
| 53 | + color:#5A6694 | ||
| 54 | + } | ||
| 55 | + .grey_line { | ||
| 56 | + width: 1px ; | ||
| 57 | + height: 60px; | ||
| 58 | + background-color: #999; | ||
| 59 | + } | ||
| 0 | \ No newline at end of file | 60 | \ No newline at end of file |
pages/mine/record/record.js
| 1 | // pages/index/record/record.js | 1 | // pages/index/record/record.js |
| 2 | +import request from '../../../api/request.js' | ||
| 2 | Page({ | 3 | Page({ |
| 3 | 4 | ||
| 4 | /** | 5 | /** |
| 5 | * 页面的初始数据 | 6 | * 页面的初始数据 |
| 6 | */ | 7 | */ |
| 7 | data: { | 8 | data: { |
| 8 | - tabindex: 1 | 9 | + tabindex: 0, |
| 10 | + showAdd: false, | ||
| 11 | + taskList: [], | ||
| 12 | + | ||
| 13 | + tempList: [ | ||
| 14 | + // {name:'自定义模板',url: '/img/answer/zdy.png'}, | ||
| 15 | + // {name:'英语模板',url: '/img/answer/english.png'}, | ||
| 16 | + // {name:'数学模板',url: '/img/answer/math.png'}, | ||
| 17 | + ] | ||
| 9 | }, | 18 | }, |
| 10 | 19 | ||
| 11 | - /** | ||
| 12 | - * 生命周期函数--监听页面加载 | ||
| 13 | - */ | ||
| 14 | - onLoad(options) { | 20 | + //打卡记录列表 |
| 21 | + getTaskList() { | ||
| 22 | + request({ | ||
| 23 | + url: `/wx/task/cardTaskList`, | ||
| 24 | + method: 'post', | ||
| 25 | + data: { | ||
| 26 | + "oneselfFlag": this.data.tabindex + 1, | ||
| 27 | + "page": 1, | ||
| 28 | + "pageSize": 999, | ||
| 29 | + "userId": wx.getStorageSync("userInfo_id") | ||
| 30 | + }, | ||
| 31 | + }).then(res => { | ||
| 32 | + if (res.code == 0) { | ||
| 33 | + this.setData({ | ||
| 34 | + taskList: res.rows | ||
| 35 | + }) | ||
| 36 | + } else { | ||
| 37 | + wx.showToast({ | ||
| 38 | + title: res.msg, | ||
| 39 | + icon: 'none', | ||
| 40 | + duration: 1500 | ||
| 41 | + }) | ||
| 42 | + } | ||
| 43 | + }) | ||
| 44 | + }, | ||
| 45 | + | ||
| 46 | + //模板列表 | ||
| 47 | + getTempList() { | ||
| 48 | + request({ | ||
| 49 | + url: `/wx/temp/tempList`, | ||
| 50 | + method: 'post', | ||
| 51 | + data: {}, | ||
| 52 | + }).then(res => { | ||
| 53 | + if (res.code == 0) { | ||
| 54 | + this.setData({ | ||
| 55 | + tempList: res.data | ||
| 56 | + }) | ||
| 57 | + } else { | ||
| 58 | + wx.showToast({ | ||
| 59 | + title: res.msg, | ||
| 60 | + icon: 'none', | ||
| 61 | + duration: 1500 | ||
| 62 | + }) | ||
| 63 | + } | ||
| 64 | + }) | ||
| 65 | + }, | ||
| 15 | 66 | ||
| 67 | + //打卡 | ||
| 68 | + toShow(e) { | ||
| 69 | + this.getTempList() | ||
| 70 | + this.setData({ | ||
| 71 | + showAdd: true | ||
| 72 | + }) | ||
| 16 | }, | 73 | }, |
| 17 | - handleTab1() { | 74 | + //关闭 |
| 75 | + closeAdd() { | ||
| 18 | this.setData({ | 76 | this.setData({ |
| 19 | - tabindex: 1 | 77 | + showAdd: false |
| 78 | + }) | ||
| 79 | + }, | ||
| 80 | + //选择模板 | ||
| 81 | + toPunch(e) { | ||
| 82 | + let obj = e.currentTarget.dataset | ||
| 83 | + let id = obj.value ? obj.value.id : 0 | ||
| 84 | + wx.navigateTo({ | ||
| 85 | + url: `../../index/newPunch/newPunch?tempId=${id}` | ||
| 20 | }) | 86 | }) |
| 21 | }, | 87 | }, |
| 22 | - handleTab2() { | 88 | + /** |
| 89 | + * 生命周期函数--监听页面加载 | ||
| 90 | + */ | ||
| 91 | + onLoad(options) { | ||
| 92 | + this.getTaskList() | ||
| 93 | + }, | ||
| 94 | + //切换 | ||
| 95 | + handleTab(e) { | ||
| 23 | this.setData({ | 96 | this.setData({ |
| 24 | - tabindex: 2 | 97 | + tabindex: e.detail.index |
| 25 | }) | 98 | }) |
| 99 | + this.getTaskList() | ||
| 26 | }, | 100 | }, |
| 27 | // 打卡成果 | 101 | // 打卡成果 |
| 28 | - handleAchievement(){ | 102 | + handleAchievement(e) { |
| 29 | wx.navigateTo({ | 103 | wx.navigateTo({ |
| 30 | - url: '/pages/index/achievement/achievement', | 104 | + url: '/pages/index/achievement/achievement?valueId=' + e.currentTarget.dataset.valueid, |
| 31 | }) | 105 | }) |
| 32 | }, | 106 | }, |
| 33 | // 去打卡 | 107 | // 去打卡 |
| 34 | - handleDetail(){ | 108 | + handleDetail(e) { |
| 109 | + let eData = e.currentTarget.dataset | ||
| 35 | wx.navigateTo({ | 110 | wx.navigateTo({ |
| 36 | - url: '/pages/index/punchDetail/punchDetail', | 111 | + url: '/pages/index/punchDetail/punchDetail?valueId=' + eData.valueid, |
| 37 | }) | 112 | }) |
| 38 | }, | 113 | }, |
| 39 | // 统一返回 | 114 | // 统一返回 |
pages/mine/record/record.json
| 1 | { | 1 | { |
| 2 | "usingComponents": { | 2 | "usingComponents": { |
| 3 | - "van-icon": "@vant/weapp/icon/index" | 3 | + "van-icon": "@vant/weapp/icon/index", |
| 4 | + "van-tab": "@vant/weapp/tab/index", | ||
| 5 | + "van-tabs": "@vant/weapp/tabs/index", | ||
| 6 | + "van-popup": "@vant/weapp/popup/index" | ||
| 4 | }, | 7 | }, |
| 5 | - "navigationStyle": "custom" | 8 | + "navigationBarTitleText":"打卡记录" |
| 6 | } | 9 | } |
| 7 | \ No newline at end of file | 10 | \ No newline at end of file |
pages/mine/record/record.wxml
| 1 | <!--pages/index/record/record.wxml--> | 1 | <!--pages/index/record/record.wxml--> |
| 2 | <view class="punch_detail"> | 2 | <view class="punch_detail"> |
| 3 | - <!-- 顶部统一返回 --> | ||
| 4 | - <view class="navigation_back" bindtap="handleBack"> | ||
| 5 | - <van-icon name="arrow-left" /> | 3 | + <view> |
| 4 | + <van-tabs active="{{ tabindex }}" bind:change="handleTab" line-height='0' title-inactive-color='#999' title-active-color='#556191'> | ||
| 5 | + <van-tab title="我发布的"></van-tab> | ||
| 6 | + <van-tab title="我的打卡"></van-tab> | ||
| 7 | + </van-tabs> | ||
| 6 | </view> | 8 | </view> |
| 7 | - <!-- 两个tab --> | ||
| 8 | - <text class="temporary_box" style="width: 320rpx;height: 80rpx;position: absolute;top: 160rpx;left: 32rpx;" bindtap="handleTab1"></text> | ||
| 9 | - <text class="temporary_box" style="width: 320rpx;height: 80rpx;position: absolute;top: 160rpx;right: 32rpx;" bindtap="handleTab2"></text> | ||
| 10 | - <!-- 打卡成果 --> | ||
| 11 | - <text class="temporary_box" wx:if="{{tabindex==1}}" style="width: 700rpx;height: 100rpx;position: absolute;top: 988rpx;left: 32rpx;" bindtap="handleAchievement"></text> | ||
| 12 | - <!-- 打卡成果 --> | ||
| 13 | - <text class="temporary_box" wx:if="{{tabindex==2}}" style="width: 350rpx;height: 100rpx;position: absolute;top: 920rpx;left: 20rpx;" bindtap="handleAchievement"></text> | ||
| 14 | - <!-- 去打卡 --> | ||
| 15 | - <text class="temporary_box" wx:if="{{tabindex==2}}" style="width: 350rpx;height: 100rpx;position: absolute;top: 920rpx;right: 20rpx;" bindtap="handleDetail"></text> | ||
| 16 | - | ||
| 17 | - <image class="temporary" hidden="{{tabindex==2}}" src="/img/_my_punch1.png" mode="widthFix" alt="" /> | ||
| 18 | - <image class="temporary" hidden="{{tabindex==1}}" src="/img/_my_punch2.png" mode="widthFix" alt="" /> | 9 | + <view class="bck"> |
| 10 | + <view class="grey_font">进行中打卡</view> | ||
| 11 | + <view class="card" wx:for="{{taskList}}" wx:key="index" wx:for-item="value"> | ||
| 12 | + <view class="card_title"> | ||
| 13 | + <view class="title_L"> | ||
| 14 | + <image class="title_pic" src="/img/answer/bj.png" alt="" /> | ||
| 15 | + </view> | ||
| 16 | + <view class="title_R"> | ||
| 17 | + <view>{{value.taskTitle}}</view> | ||
| 18 | + <view class="grey_font">开始时间 {{value.startDate}}</view> | ||
| 19 | + </view> | ||
| 20 | + </view> | ||
| 21 | + <view class="day_font" >{{value.taskDesc}}</view> | ||
| 22 | + <!-- <view class="day_font2">已坚持打卡 | ||
| 23 | + <text class="day_font2_large">1/50 </text>天 | ||
| 24 | + </view> --> | ||
| 25 | + <view> | ||
| 26 | + <van-progress percentage="50" color='#3F5EFF' stroke-width="13" pivot-text=' ' /> | ||
| 27 | + </view> | ||
| 28 | + <view class="flex_font"> | ||
| 29 | + <text class="grey_flex">打卡频次:</text> | ||
| 30 | + {{value.taskFrequency}} | ||
| 31 | + </view> | ||
| 32 | + <view class="flex_font" wx:if="{{value.submitCondition != null}}"> | ||
| 33 | + <text class="grey_flex">打卡要求:</text> | ||
| 34 | + {{ value.submitCondition == '无限制' ? '无限制': '需要 '+value.submitCondition}} | ||
| 35 | + </view> | ||
| 36 | + <view class="flex_font"> | ||
| 37 | + <view class="grey_flex">其他:</view> | ||
| 38 | + {{value.allowRepairCard == 1 ? '允许补卡': '不允许补卡'}} | ||
| 39 | + </view> | ||
| 40 | + <view class="grey_line"></view> | ||
| 41 | + <view class="blue_font" wx:if="{{tabindex == 0}}"> | ||
| 42 | + <view bindtap="handleAchievement" data-valueId="{{value.id}}">我的成果</view> | ||
| 43 | + <view class="blue_line"></view> | ||
| 44 | + <view bindtap="handleDetail" data-valueId="{{value.id}}">去打卡</view> | ||
| 45 | + </view> | ||
| 46 | + <view class="blue_font" wx:else> | ||
| 47 | + <view bindtap="handleAchievement" data-valueId="{{value.id}}">打卡成果</view> | ||
| 48 | + </view> | ||
| 49 | + </view> | ||
| 19 | 50 | ||
| 51 | + <view class="blue_tip" bindtap="toShow"> | ||
| 52 | + <image class="img_tip" src="/img/answer/add.png" alt="" /> | ||
| 53 | + </view> | ||
| 54 | + </view> | ||
| 55 | + | ||
| 56 | + <!-- 弹窗 --> | ||
| 57 | + <van-popup show="{{ showAdd }}" round position="bottom" custom-style="height: 60%;" bind:close="closeAdd"> | ||
| 58 | + <view class="pop_card"> | ||
| 59 | + <view class="pop_title">选择模板</view> | ||
| 60 | + <view class="tem_box"> | ||
| 61 | + <view class="tem_item" bindtap="toPunch" > | ||
| 62 | + <image class="tem_pic" src="/img/answer/zdy.png" alt="" /> | ||
| 63 | + <view class="tem_font">自定义模板</view> | ||
| 64 | + </view> | ||
| 65 | + <view class="tem_item" wx:for="{{tempList}}" wx:key="index" wx:for-item="value" bindtap="toPunch" data-value="{{value}}"> | ||
| 66 | + <image class="tem_pic" src="{{value.taskBackground}}" alt="" /> | ||
| 67 | + <view class="tem_font">{{value.taskTitle}}</view> | ||
| 68 | + </view> | ||
| 69 | + </view> | ||
| 70 | + </view> | ||
| 71 | + </van-popup> | ||
| 20 | </view> | 72 | </view> |
| 21 | \ No newline at end of file | 73 | \ No newline at end of file |
pages/mine/record/record.wxss
| 1 | /* pages/index/record/record.wxss */ | 1 | /* pages/index/record/record.wxss */ |
| 2 | +.punch_detail { | ||
| 3 | + position: absolute; | ||
| 4 | + width: 100vw; | ||
| 5 | + height: 100vh; | ||
| 6 | + background-color: #F5F6FA; | ||
| 7 | +} | ||
| 8 | + | ||
| 9 | +.bck { | ||
| 10 | + padding: 20px 4vw; | ||
| 11 | + box-sizing: border-box; | ||
| 12 | +} | ||
| 13 | + | ||
| 14 | +.grey_font { | ||
| 15 | + width: 100%; | ||
| 16 | + color: #999; | ||
| 17 | + font-size: 14px; | ||
| 18 | + margin-bottom: 15px; | ||
| 19 | +} | ||
| 20 | + | ||
| 21 | +/**/ | ||
| 22 | + | ||
| 23 | +.card { | ||
| 24 | + width: 92vw; | ||
| 25 | + background-color: #fff; | ||
| 26 | + border-radius: 8vw; | ||
| 27 | + padding: 8vw; | ||
| 28 | + margin-bottom: 30px; | ||
| 29 | + box-sizing: border-box; | ||
| 30 | + box-shadow: 1px 1px 1px 1px rgb(228, 228, 228); | ||
| 31 | +} | ||
| 32 | + | ||
| 33 | +.card_title { | ||
| 34 | + display: flex; | ||
| 35 | +} | ||
| 36 | + | ||
| 37 | +.title_L { | ||
| 38 | + flex-shrink: 0; | ||
| 39 | + width: 50px; | ||
| 40 | + height: 50px; | ||
| 41 | + margin-right: 15px; | ||
| 42 | +} | ||
| 43 | + | ||
| 44 | +.title_pic { | ||
| 45 | + width: 100%; | ||
| 46 | + height: 100%; | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +.title_R { | ||
| 50 | + height: 65px; | ||
| 51 | + display: flex; | ||
| 52 | + align-content: space-between; | ||
| 53 | + flex-wrap: wrap; | ||
| 54 | + font-size: 4.6vw; | ||
| 55 | +} | ||
| 56 | + | ||
| 57 | +/* .grey_font { | ||
| 58 | + width: 100%; | ||
| 59 | + color: #999; | ||
| 60 | + font-size: 3.8vw; | ||
| 61 | +} */ | ||
| 62 | + | ||
| 63 | +.day_font { | ||
| 64 | + margin: 10px 0 20px; | ||
| 65 | + letter-spacing: 0.2vw; | ||
| 66 | + font-size: 4vw; | ||
| 67 | +} | ||
| 68 | + | ||
| 69 | +.day_font2 { | ||
| 70 | + margin: 20px 0; | ||
| 71 | + letter-spacing: 0.2vw; | ||
| 72 | + font-size: 3.8vw; | ||
| 73 | +} | ||
| 74 | + | ||
| 75 | +.day_font2_large { | ||
| 76 | + font-size: 5.5vw; | ||
| 77 | + font-weight: bold; | ||
| 78 | +} | ||
| 79 | + | ||
| 80 | +.flex_font { | ||
| 81 | + font-size: 3.5vw; | ||
| 82 | + margin: 20px 0; | ||
| 83 | + display: flex; | ||
| 84 | +} | ||
| 85 | + | ||
| 86 | +.grey_flex { | ||
| 87 | + width: 80px; | ||
| 88 | + color: #999; | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +.grey_line { | ||
| 92 | + width: 100%; | ||
| 93 | + height: 1px; | ||
| 94 | + background-color: #EAEAEA; | ||
| 95 | +} | ||
| 96 | + | ||
| 97 | +.blue_font { | ||
| 98 | + display: flex; | ||
| 99 | + justify-content: space-around; | ||
| 100 | + margin-top: 15px; | ||
| 101 | + font-size: 4.1vw; | ||
| 102 | + color: #458EF8; | ||
| 103 | + font-weight: 540; | ||
| 104 | +} | ||
| 105 | + | ||
| 106 | +.blue_line { | ||
| 107 | + width: 1px; | ||
| 108 | + height: 15px; | ||
| 109 | + background-color: #EAEAEA; | ||
| 110 | +} | ||
| 111 | + | ||
| 112 | +.blue_tip { | ||
| 113 | + position: fixed; | ||
| 114 | + bottom: 50px; | ||
| 115 | + right: 3vw; | ||
| 116 | +} | ||
| 117 | + | ||
| 118 | +.img_tip { | ||
| 119 | + width: 70px; | ||
| 120 | + height: 70px; | ||
| 121 | +} | ||
| 122 | + | ||
| 123 | +.pop_card { | ||
| 124 | + padding: 5vw; | ||
| 125 | + box-sizing: border-box; | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + .pop_title { | ||
| 129 | + font-size: 4.8vw; | ||
| 130 | + font-weight: bold; | ||
| 131 | + letter-spacing: 1px; | ||
| 132 | + margin-bottom: 30px; | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + .tem_box { | ||
| 136 | + display: flex; | ||
| 137 | + flex-wrap: wrap; | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + .tem_item { | ||
| 141 | + width: 23vw; | ||
| 142 | + height: 170px; | ||
| 143 | + text-align: center; | ||
| 144 | + margin: 0 3vw 30px; | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + .tem_pic { | ||
| 148 | + width: 23vw; | ||
| 149 | + height: 120px; | ||
| 150 | + border-radius: 10px; | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + .tem_font { | ||
| 154 | + font-size: 3.9vw; | ||
| 155 | + margin-top: 10px; | ||
| 156 | + } | ||
| 2 | \ No newline at end of file | 157 | \ No newline at end of file |