综合办公系统
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

util.js 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. import CALENDAR from './calendar.js'
  2. class Calendar {
  3. constructor({
  4. date,
  5. selected,
  6. startDate,
  7. endDate,
  8. range,
  9. multiple,
  10. allowSameDay
  11. } = {}) {
  12. // 当前日期
  13. this.date = this.getDate(new Date()) // 当前初入日期
  14. // 打点信息
  15. this.selected = selected || [];
  16. // 范围开始
  17. this.startDate = startDate
  18. // 范围结束
  19. this.endDate = endDate
  20. this.range = range
  21. this.multiple = multiple
  22. this.allowSameDay = allowSameDay
  23. // 多选状态
  24. this.cleanRangeStatus()
  25. // 范围状态
  26. this.cleanMultipleStatus()
  27. // 每周日期
  28. this.weeks = {}
  29. // this._getWeek(this.date.fullDate)
  30. }
  31. /**
  32. * 设置日期
  33. * @param {Object} date
  34. */
  35. setDate(date, status) {
  36. if (this.range && status == 'init') {
  37. this.cleanRangeStatus();
  38. if (Array.isArray(date)) {
  39. this.rangeStatus.before = date[0];
  40. this.rangeStatus.after = date.length > 1 ? date[date.length - 1] : '';
  41. if (this.rangeStatus.after && this.dateCompare(this.rangeStatus.before, this.rangeStatus.after)) {
  42. this.rangeStatus.data = this.geDateAll(this.rangeStatus.before, this.rangeStatus.after)
  43. }
  44. this.selectDate = this.getDate(date[0])
  45. this._getWeek(this.selectDate.fullDate)
  46. } else {
  47. this.selectDate = this.getDate(date)
  48. this.rangeStatus.before = this.selectDate.fullDate;
  49. this._getWeek(this.selectDate.fullDate)
  50. }
  51. } else if (this.multiple && status == 'init') {
  52. this.cleanMultipleStatus();
  53. if (Array.isArray(date)) {
  54. this.multipleStatus.data = date;
  55. this.selectDate = this.getDate(date[0])
  56. this._getWeek(this.selectDate.fullDate)
  57. } else {
  58. this.selectDate = this.getDate(date)
  59. this.multipleStatus.data = [this.selectDate.fullDate];
  60. this._getWeek(this.selectDate.fullDate)
  61. }
  62. } else {
  63. if (Array.isArray(date)) {
  64. this.selectDate = this.getDate(date[0])
  65. this._getWeek(this.selectDate.fullDate)
  66. } else {
  67. this.selectDate = this.getDate(date)
  68. this._getWeek(this.selectDate.fullDate)
  69. }
  70. }
  71. }
  72. /**
  73. * 清理多选状态
  74. */
  75. cleanRangeStatus() {
  76. this.rangeStatus = {
  77. before: '',
  78. after: '',
  79. data: []
  80. }
  81. }
  82. /**
  83. * 清理多选状态
  84. */
  85. cleanMultipleStatus() {
  86. this.multipleStatus = {
  87. data: []
  88. }
  89. }
  90. /**
  91. * 重置开始日期
  92. */
  93. resetSatrtDate(startDate) {
  94. // 范围开始
  95. this.startDate = startDate
  96. }
  97. /**
  98. * 重置结束日期
  99. */
  100. resetEndDate(endDate) {
  101. // 范围结束
  102. this.endDate = endDate
  103. }
  104. /**
  105. * 获取任意时间
  106. */
  107. getDate(date, AddDayCount = 0, str = 'day') {
  108. if (!date) {
  109. date = new Date()
  110. }
  111. if (typeof date !== 'object') {
  112. date = date.replace(/-/g, '/')
  113. }
  114. const dd = new Date(date)
  115. switch (str) {
  116. case 'day':
  117. dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
  118. break
  119. case 'month':
  120. if (dd.getDate() === 31 && AddDayCount > 0) {
  121. dd.setDate(dd.getDate() + AddDayCount)
  122. } else {
  123. const preMonth = dd.getMonth()
  124. dd.setMonth(preMonth + AddDayCount) // 获取AddDayCount天后的日期
  125. const nextMonth = dd.getMonth()
  126. // 处理 pre 切换月份目标月份为2月没有当前日(30 31) 切换错误问题
  127. if (AddDayCount < 0 && preMonth !== 0 && nextMonth - preMonth > AddDayCount) {
  128. dd.setMonth(nextMonth + (nextMonth - preMonth + AddDayCount))
  129. }
  130. // 处理 next 切换月份目标月份为2月没有当前日(30 31) 切换错误问题
  131. if (AddDayCount > 0 && nextMonth - preMonth > AddDayCount) {
  132. dd.setMonth(nextMonth - (nextMonth - preMonth - AddDayCount))
  133. }
  134. }
  135. break
  136. case 'year':
  137. dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期
  138. break
  139. }
  140. const y = dd.getFullYear()
  141. const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
  142. const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
  143. return {
  144. fullDate: y + '-' + m + '-' + d,
  145. year: y,
  146. month: m,
  147. date: d,
  148. day: dd.getDay()
  149. }
  150. }
  151. /**
  152. * 获取上月剩余天数
  153. */
  154. _getLastMonthDays(firstDay, full) {
  155. let dateArr = []
  156. for (let i = firstDay; i > 0; i--) {
  157. const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate()
  158. dateArr.push({
  159. date: beforeDate,
  160. month: full.month - 1,
  161. lunar: this.getlunar(full.year, full.month - 1, beforeDate),
  162. disable: true
  163. })
  164. }
  165. return dateArr
  166. }
  167. /**
  168. * 获取本月天数
  169. */
  170. _currentMonthDys(dateData, full) {
  171. let dateArr = []
  172. let fullDate = this.date.fullDate
  173. for (let i = 1; i <= dateData; i++) {
  174. let nowDate = full.year + '-' + (full.month < 10 ? full.month : full.month) + '-' + (i < 10 ? '0' + i : i)
  175. // 是否今天
  176. let isDay = fullDate === nowDate
  177. // 获取打点信息
  178. let info = this.selected && this.selected.find((item) => {
  179. if (this.dateEqual(nowDate, item.date)) {
  180. return item
  181. }
  182. })
  183. // 日期禁用
  184. let disableBefore = true
  185. let disableAfter = true
  186. if (this.startDate) {
  187. // let dateCompBefore = this.dateCompare(this.startDate, fullDate)
  188. // disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate)
  189. disableBefore = this.dateCompare(this.startDate, nowDate)
  190. }
  191. if (this.endDate) {
  192. // let dateCompAfter = this.dateCompare(fullDate, this.endDate)
  193. // disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate)
  194. disableAfter = this.dateCompare(nowDate, this.endDate)
  195. }
  196. let ranges = this.rangeStatus.data
  197. let checked = false
  198. let rangesStatus = -1
  199. if (this.range) {
  200. if (ranges) {
  201. rangesStatus = ranges.findIndex((item) => {
  202. return this.dateEqual(item, nowDate)
  203. })
  204. }
  205. if (rangesStatus !== -1) {
  206. checked = true
  207. }
  208. }
  209. let multiples = this.multipleStatus.data
  210. let checked_multiple = false
  211. let multiplesStatus = -1
  212. if (this.multiple) {
  213. if (multiples) {
  214. multiplesStatus = multiples.findIndex((item) => {
  215. return this.dateEqual(item, nowDate)
  216. })
  217. }
  218. if (multiplesStatus !== -1) {
  219. checked_multiple = true
  220. }
  221. }
  222. let data = {
  223. fullDate: nowDate,
  224. year: full.year,
  225. date: i,
  226. range: this.range ? checked : false,
  227. multiple: this.multiple ? checked_multiple : false,
  228. beforeRange: this.dateEqual(this.rangeStatus.before, nowDate),
  229. afterRange: this.dateEqual(this.rangeStatus.after, nowDate),
  230. dateEqual: this.range && checked && this.dateEqual(this.rangeStatus.before, this.rangeStatus.after),
  231. month: full.month,
  232. lunar: this.getlunar(full.year, full.month, i),
  233. disable: !(disableBefore && disableAfter),
  234. isDay
  235. }
  236. if (info) {
  237. data.extraInfo = info
  238. }
  239. dateArr.push(data)
  240. }
  241. return dateArr
  242. }
  243. /**
  244. * 获取下月天数
  245. */
  246. _getNextMonthDays(surplus, full) {
  247. let dateArr = []
  248. for (let i = 1; i < surplus + 1; i++) {
  249. dateArr.push({
  250. date: i,
  251. month: Number(full.month) + 1,
  252. lunar: this.getlunar(full.year, Number(full.month) + 1, i),
  253. disable: true
  254. })
  255. }
  256. return dateArr
  257. }
  258. /**
  259. * 获取当前日期详情
  260. * @param {Object} date
  261. */
  262. getInfo(date) {
  263. if (!date) {
  264. date = new Date()
  265. } else if (Array.isArray(date)) {
  266. date = date[0]
  267. }
  268. const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate)
  269. return dateInfo
  270. }
  271. /**
  272. * 比较时间大小
  273. */
  274. dateCompare(startDate, endDate) {
  275. // 计算截止时间
  276. startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
  277. // 计算详细项的截止时间
  278. endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
  279. if (startDate <= endDate) {
  280. return true
  281. } else {
  282. return false
  283. }
  284. }
  285. /**
  286. * 比较时间是否相等
  287. */
  288. dateEqual(before, after) {
  289. // 计算截止时间
  290. before = new Date(before.replace('-', '/').replace('-', '/'))
  291. // 计算详细项的截止时间
  292. after = new Date(after.replace('-', '/').replace('-', '/'))
  293. if (before.getTime() - after.getTime() === 0) {
  294. return true
  295. } else {
  296. return false
  297. }
  298. }
  299. /**
  300. * 比较after时间是否大于before时间
  301. */
  302. dateAfterLgBefore(before, after) {
  303. // 计算截止时间
  304. before = new Date(before.replace('-', '/').replace('-', '/'))
  305. // 计算详细项的截止时间
  306. after = new Date(after.replace('-', '/').replace('-', '/'))
  307. if (after.getTime() - before.getTime() > 0) {
  308. return true
  309. } else {
  310. return false
  311. }
  312. }
  313. /**
  314. * 获取日期范围内所有日期
  315. * @param {Object} begin
  316. * @param {Object} end
  317. */
  318. geDateAll(begin, end) {
  319. var arr = []
  320. var ab = begin.split('-')
  321. var ae = end.split('-')
  322. var db = new Date()
  323. db.setFullYear(ab[0], ab[1] - 1, ab[2])
  324. var de = new Date()
  325. de.setFullYear(ae[0], ae[1] - 1, ae[2])
  326. var unixDb = db.getTime() - 24 * 60 * 60 * 1000
  327. var unixDe = de.getTime() - 24 * 60 * 60 * 1000
  328. for (var k = unixDb; k <= unixDe;) {
  329. k = k + 24 * 60 * 60 * 1000
  330. arr.push(this.getDate(new Date(parseInt(k))).fullDate)
  331. }
  332. return arr
  333. }
  334. /**
  335. * 计算阴历日期显示
  336. */
  337. getlunar(year, month, date) {
  338. return CALENDAR.solar2lunar(year, month, date)
  339. }
  340. /**
  341. * 设置打点
  342. */
  343. setSelectInfo(data, value) {
  344. this.selected = value
  345. this._getWeek(data)
  346. }
  347. /**
  348. * 获取多选状态
  349. */
  350. setMultiple(fullDate) {
  351. if (!this.multiple) return
  352. let multiples = this.multipleStatus.data;
  353. const findIndex = multiples.findIndex(item => this.dateEqual(fullDate, item));
  354. if (findIndex < 0) {
  355. this.multipleStatus.data = this.multipleStatus.data.concat([fullDate]);
  356. } else {
  357. this.multipleStatus.data.splice(findIndex, 1);
  358. }
  359. this._getWeek(fullDate)
  360. }
  361. /**
  362. * 获取范围状态
  363. */
  364. setRange(fullDate) {
  365. let {
  366. before,
  367. after
  368. } = this.rangeStatus
  369. if (!this.range) return
  370. if (before && after) {
  371. this.cleanRangeStatus();
  372. this.rangeStatus.before = fullDate
  373. } else {
  374. if (!before) {
  375. this.rangeStatus.before = fullDate
  376. } else {
  377. if (this.allowSameDay && this.dateEqual(before, fullDate)) {
  378. this.rangeStatus.after = fullDate
  379. } else if (!this.dateAfterLgBefore(this.rangeStatus.before, fullDate)) {
  380. this.cleanRangeStatus();
  381. this.rangeStatus.before = fullDate
  382. this._getWeek(fullDate)
  383. return;
  384. }
  385. this.rangeStatus.after = fullDate
  386. if (this.dateCompare(this.rangeStatus.before, this.rangeStatus.after)) {
  387. this.rangeStatus.data = this.geDateAll(this.rangeStatus.before, this.rangeStatus.after);
  388. } else {
  389. this.rangeStatus.data = this.geDateAll(this.rangeStatus.after, this.rangeStatus.before);
  390. }
  391. }
  392. }
  393. this._getWeek(fullDate)
  394. }
  395. /**
  396. * 获取每周数据
  397. * @param {Object} dateData
  398. */
  399. _getWeek(dateData) {
  400. const {
  401. year,
  402. month
  403. } = this.getDate(dateData)
  404. let firstDay = new Date(year, month - 1, 1).getDay()
  405. let currentDay = new Date(year, month, 0).getDate()
  406. let dates = {
  407. lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天
  408. currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数
  409. nextMonthDays: [], // 下个月开始几天
  410. weeks: []
  411. }
  412. let canlender = []
  413. const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length)
  414. dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData))
  415. canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays)
  416. let weeks = {}
  417. // 拼接数组 上个月开始几天 + 本月天数+ 下个月开始几天
  418. for (let i = 0; i < canlender.length; i++) {
  419. if (i % 7 === 0) {
  420. weeks[parseInt(i / 7)] = new Array(7)
  421. }
  422. weeks[parseInt(i / 7)][i % 7] = canlender[i]
  423. }
  424. this.canlender = canlender
  425. this.weeks = weeks
  426. }
  427. //静态方法
  428. // static init(date) {
  429. // if (!this.instance) {
  430. // this.instance = new Calendar(date);
  431. // }
  432. // return this.instance;
  433. // }
  434. }
  435. export default Calendar