util.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. class Calendar {
  2. constructor({
  3. selected,
  4. startDate,
  5. endDate,
  6. range,
  7. } = {}) {
  8. // 当前日期
  9. this.date = this.getDateObj(new Date()) // 当前初入日期
  10. // 打点信息
  11. this.selected = selected || [];
  12. // 起始时间
  13. this.startDate = startDate
  14. // 终止时间
  15. this.endDate = endDate
  16. // 是否范围选择
  17. this.range = range
  18. // 多选状态
  19. this.cleanMultipleStatus()
  20. // 每周日期
  21. this.weeks = {}
  22. this.lastHover = false
  23. }
  24. /**
  25. * 设置日期
  26. * @param {Object} date
  27. */
  28. setDate(date) {
  29. const selectDate = this.getDateObj(date)
  30. this.getWeeks(selectDate.fullDate)
  31. }
  32. /**
  33. * 清理多选状态
  34. */
  35. cleanMultipleStatus() {
  36. this.multipleStatus = {
  37. before: '',
  38. after: '',
  39. data: []
  40. }
  41. }
  42. setStartDate(startDate) {
  43. this.startDate = startDate
  44. }
  45. setEndDate(endDate) {
  46. this.endDate = endDate
  47. }
  48. getPreMonthObj(date){
  49. date = fixIosDateFormat(date)
  50. date = new Date(date)
  51. const oldMonth = date.getMonth()
  52. date.setMonth(oldMonth - 1)
  53. const newMonth = date.getMonth()
  54. if(oldMonth !== 0 && newMonth - oldMonth === 0){
  55. date.setMonth(newMonth - 1)
  56. }
  57. return this.getDateObj(date)
  58. }
  59. getNextMonthObj(date){
  60. date = fixIosDateFormat(date)
  61. date = new Date(date)
  62. const oldMonth = date.getMonth()
  63. date.setMonth(oldMonth + 1)
  64. const newMonth = date.getMonth()
  65. if(newMonth - oldMonth > 1){
  66. date.setMonth(newMonth - 1)
  67. }
  68. return this.getDateObj(date)
  69. }
  70. /**
  71. * 获取指定格式Date对象
  72. */
  73. getDateObj(date) {
  74. date = fixIosDateFormat(date)
  75. date = new Date(date)
  76. return {
  77. fullDate: getDate(date),
  78. year: date.getFullYear(),
  79. month: addZero(date.getMonth() + 1),
  80. date: addZero(date.getDate()),
  81. day: date.getDay()
  82. }
  83. }
  84. /**
  85. * 获取上一个月日期集合
  86. */
  87. getPreMonthDays(amount, dateObj) {
  88. const result = []
  89. for (let i = amount - 1; i >= 0; i--) {
  90. const month = dateObj.month - 1
  91. result.push({
  92. date: new Date(dateObj.year, month, -i).getDate(),
  93. month,
  94. disable: true
  95. })
  96. }
  97. return result
  98. }
  99. /**
  100. * 获取本月日期集合
  101. */
  102. getCurrentMonthDays(amount, dateObj) {
  103. const result = []
  104. const fullDate = this.date.fullDate
  105. for (let i = 1; i <= amount; i++) {
  106. const currentDate = `${dateObj.year}-${dateObj.month}-${addZero(i)}`
  107. const isToday = fullDate === currentDate
  108. // 获取打点信息
  109. const info = this.selected && this.selected.find((item) => {
  110. if (this.dateEqual(currentDate, item.date)) {
  111. return item
  112. }
  113. })
  114. // 日期禁用
  115. let disableBefore = true
  116. let disableAfter = true
  117. if (this.startDate) {
  118. disableBefore = dateCompare(this.startDate, currentDate)
  119. }
  120. if (this.endDate) {
  121. disableAfter = dateCompare(currentDate, this.endDate)
  122. }
  123. let multiples = this.multipleStatus.data
  124. let multiplesStatus = -1
  125. if (this.range && multiples) {
  126. multiplesStatus = multiples.findIndex((item) => {
  127. return this.dateEqual(item, currentDate)
  128. })
  129. }
  130. const checked = multiplesStatus !== -1
  131. result.push({
  132. fullDate: currentDate,
  133. year: dateObj.year,
  134. date: i,
  135. multiple: this.range ? checked : false,
  136. beforeMultiple: this.isLogicBefore(currentDate, this.multipleStatus.before, this.multipleStatus.after),
  137. afterMultiple: this.isLogicAfter(currentDate, this.multipleStatus.before, this.multipleStatus.after),
  138. month: dateObj.month,
  139. disable: (this.startDate && !dateCompare(this.startDate, currentDate)) || (this.endDate && !dateCompare(currentDate,this.endDate)),
  140. isToday,
  141. userChecked: false,
  142. extraInfo: info
  143. })
  144. }
  145. return result
  146. }
  147. /**
  148. * 获取下一个月日期集合
  149. */
  150. _getNextMonthDays(amount, dateObj) {
  151. const result = []
  152. const month = dateObj.month + 1
  153. for (let i = 1; i <= amount; i++) {
  154. result.push({
  155. date: i,
  156. month,
  157. disable: true
  158. })
  159. }
  160. return result
  161. }
  162. /**
  163. * 获取当前日期详情
  164. * @param {Object} date
  165. */
  166. getInfo(date) {
  167. if (!date) {
  168. date = new Date()
  169. }
  170. return this.calendar.find(item => item.fullDate === this.getDateObj(date).fullDate)
  171. }
  172. /**
  173. * 比较时间是否相等
  174. */
  175. dateEqual(before, after) {
  176. before = new Date(fixIosDateFormat(before))
  177. after = new Date(fixIosDateFormat(after))
  178. return before.valueOf() === after.valueOf()
  179. }
  180. /**
  181. * 比较真实起始日期
  182. */
  183. isLogicBefore(currentDate, before, after) {
  184. let logicBefore = before
  185. if (before && after) {
  186. logicBefore = dateCompare(before, after) ? before : after
  187. }
  188. return this.dateEqual(logicBefore, currentDate)
  189. }
  190. isLogicAfter(currentDate, before, after) {
  191. let logicAfter = after
  192. if (before && after) {
  193. logicAfter = dateCompare(before, after) ? after : before
  194. }
  195. return this.dateEqual(logicAfter, currentDate)
  196. }
  197. /**
  198. * 获取日期范围内所有日期
  199. * @param {Object} begin
  200. * @param {Object} end
  201. */
  202. geDateAll(begin, end) {
  203. var arr = []
  204. var ab = begin.split('-')
  205. var ae = end.split('-')
  206. var db = new Date()
  207. db.setFullYear(ab[0], ab[1] - 1, ab[2])
  208. var de = new Date()
  209. de.setFullYear(ae[0], ae[1] - 1, ae[2])
  210. var unixDb = db.getTime() - 24 * 60 * 60 * 1000
  211. var unixDe = de.getTime() - 24 * 60 * 60 * 1000
  212. for (var k = unixDb; k <= unixDe;) {
  213. k = k + 24 * 60 * 60 * 1000
  214. arr.push(this.getDateObj(new Date(parseInt(k))).fullDate)
  215. }
  216. return arr
  217. }
  218. /**
  219. * 获取多选状态
  220. */
  221. setMultiple(fullDate) {
  222. if (!this.range) return
  223. let {
  224. before,
  225. after
  226. } = this.multipleStatus
  227. if (before && after) {
  228. if (!this.lastHover) {
  229. this.lastHover = true
  230. return
  231. }
  232. this.multipleStatus.before = fullDate
  233. this.multipleStatus.after = ''
  234. this.multipleStatus.data = []
  235. this.multipleStatus.fulldate = ''
  236. this.lastHover = false
  237. } else {
  238. if (!before) {
  239. this.multipleStatus.before = fullDate
  240. this.lastHover = false
  241. } else {
  242. this.multipleStatus.after = fullDate
  243. if (dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
  244. this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus
  245. .after);
  246. } else {
  247. this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus
  248. .before);
  249. }
  250. this.lastHover = true
  251. }
  252. }
  253. this.getWeeks(fullDate)
  254. }
  255. /**
  256. * 鼠标 hover 更新多选状态
  257. */
  258. setHoverMultiple(fullDate) {
  259. if (!this.range || this.lastHover) return
  260. const { before } = this.multipleStatus
  261. if (!before) {
  262. this.multipleStatus.before = fullDate
  263. } else {
  264. this.multipleStatus.after = fullDate
  265. if (dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
  266. this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
  267. } else {
  268. this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
  269. }
  270. }
  271. this.getWeeks(fullDate)
  272. }
  273. /**
  274. * 更新默认值多选状态
  275. */
  276. setDefaultMultiple(before, after) {
  277. this.multipleStatus.before = before
  278. this.multipleStatus.after = after
  279. if (before && after) {
  280. if (dateCompare(before, after)) {
  281. this.multipleStatus.data = this.geDateAll(before, after);
  282. this.getWeeks(after)
  283. } else {
  284. this.multipleStatus.data = this.geDateAll(after, before);
  285. this.getWeeks(before)
  286. }
  287. }
  288. }
  289. /**
  290. * 获取每周数据
  291. * @param {Object} dateData
  292. */
  293. getWeeks(dateData) {
  294. const {
  295. year,
  296. month,
  297. } = this.getDateObj(dateData)
  298. const preMonthDayAmount = new Date(year, month - 1, 1).getDay()
  299. const preMonthDays = this.getPreMonthDays(preMonthDayAmount, this.getDateObj(dateData))
  300. const currentMonthDayAmount = new Date(year, month, 0).getDate()
  301. const currentMonthDays = this.getCurrentMonthDays(currentMonthDayAmount, this.getDateObj(dateData))
  302. const nextMonthDayAmount = 42 - preMonthDayAmount - currentMonthDayAmount
  303. const nextMonthDays = this._getNextMonthDays(nextMonthDayAmount, this.getDateObj(dateData))
  304. const calendarDays = [...preMonthDays, ...currentMonthDays, ...nextMonthDays]
  305. const weeks = new Array(6)
  306. for (let i = 0; i < calendarDays.length; i++) {
  307. const index = Math.floor(i / 7)
  308. if(!weeks[index]){
  309. weeks[index] = new Array(7)
  310. }
  311. weeks[index][i % 7] = calendarDays[i]
  312. }
  313. this.calendar = calendarDays
  314. this.weeks = weeks
  315. }
  316. }
  317. function getDateTime(date, hideSecond){
  318. return `${getDate(date)} ${getTime(date, hideSecond)}`
  319. }
  320. function getDate(date) {
  321. date = fixIosDateFormat(date)
  322. date = new Date(date)
  323. const year = date.getFullYear()
  324. const month = date.getMonth()+1
  325. const day = date.getDate()
  326. return `${year}-${addZero(month)}-${addZero(day)}`
  327. }
  328. function getTime(date, hideSecond){
  329. date = fixIosDateFormat(date)
  330. date = new Date(date)
  331. const hour = date.getHours()
  332. const minute = date.getMinutes()
  333. const second = date.getSeconds()
  334. return hideSecond ? `${addZero(hour)}:${addZero(minute)}` : `${addZero(hour)}:${addZero(minute)}:${addZero(second)}`
  335. }
  336. function addZero(num) {
  337. if(num < 10){
  338. num = `0${num}`
  339. }
  340. return num
  341. }
  342. function getDefaultSecond(hideSecond) {
  343. return hideSecond ? '00:00' : '00:00:00'
  344. }
  345. function dateCompare(startDate, endDate) {
  346. startDate = new Date(fixIosDateFormat(startDate))
  347. endDate = new Date(fixIosDateFormat(endDate))
  348. return startDate <= endDate
  349. }
  350. function checkDate(date){
  351. const dateReg = /((19|20)\d{2})(-|\/)\d{1,2}(-|\/)\d{1,2}/g
  352. return date.match(dateReg)
  353. }
  354. const dateTimeReg = /^\d{4}-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])( [0-5]?[0-9]:[0-5]?[0-9]:[0-5]?[0-9])?$/
  355. function fixIosDateFormat(value) {
  356. if (typeof value === 'string' && dateTimeReg.test(value)) {
  357. value = value.replace(/-/g, '/')
  358. }
  359. return value
  360. }
  361. export {Calendar, getDateTime, getDate, getTime, addZero, getDefaultSecond, dateCompare, checkDate, fixIosDateFormat}