MonthlyCalendar.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. import { ref, watchEffect, nextTick } from 'vue';
  2. import { GetMyTaskDailyDistribution, GetMyTaskMonthDistribution } from '@/api/user';
  3. import { useRoute } from 'vue-router/composables';
  4. import dayjs from 'dayjs';
  5. export const weekList = [
  6. {
  7. name: '日',
  8. label: 'Sun'
  9. },
  10. {
  11. name: '一',
  12. label: 'Mon'
  13. },
  14. {
  15. name: '二',
  16. label: 'Tue'
  17. },
  18. {
  19. name: '三',
  20. label: 'Wed'
  21. },
  22. {
  23. name: '四',
  24. label: 'Thu'
  25. },
  26. {
  27. name: '五',
  28. label: 'Fri'
  29. },
  30. {
  31. name: '六',
  32. label: 'Sat'
  33. }
  34. ];
  35. export const monthList = ref([
  36. {
  37. name: '01月',
  38. label: 'Jan',
  39. month: '01'
  40. },
  41. {
  42. name: '02月',
  43. label: 'Feb',
  44. month: '02'
  45. },
  46. {
  47. name: '03月',
  48. label: 'Mar',
  49. month: '03'
  50. },
  51. {
  52. name: '04月',
  53. label: 'Apr',
  54. month: '04'
  55. },
  56. {
  57. name: '05月',
  58. label: 'May',
  59. month: '05'
  60. },
  61. {
  62. name: '06月',
  63. label: 'Jun',
  64. month: '06'
  65. },
  66. {
  67. name: '07月',
  68. label: 'Jul',
  69. month: '07'
  70. },
  71. {
  72. name: '08月',
  73. label: 'Aug',
  74. month: '08'
  75. },
  76. {
  77. name: '09月',
  78. label: 'Sep',
  79. month: '09'
  80. },
  81. {
  82. name: '10月',
  83. label: 'Oct',
  84. month: '10'
  85. },
  86. {
  87. name: '11月',
  88. label: 'Nov',
  89. month: '11'
  90. },
  91. {
  92. name: '12月',
  93. label: 'Dec',
  94. month: '12'
  95. }
  96. ]);
  97. // 日历显示模式
  98. export const modeList = [
  99. {
  100. type: 'DAY',
  101. name: 'Key311'
  102. },
  103. {
  104. type: 'MONTH',
  105. name: 'Key310'
  106. }
  107. ];
  108. /**
  109. * 日历方法
  110. * @param {Emits} emits
  111. */
  112. export function useMonthlyCalendar(emits) {
  113. const route = useRoute();
  114. const dateSta = route.query.dateStamp;
  115. let dateStamp = dateSta ? new Date(dateSta) : new Date();
  116. let focusDate = ref(dateStamp.getDate()); // 选中的当前日期
  117. let focusMonth = ref(0); // 选中的当前月份
  118. let curYear = ref(dateStamp.getFullYear()); // 当前年份
  119. let curMonth = ref(dateStamp.getMonth() + 1); // 当前月份
  120. const DAY = modeList[0].type;
  121. const MONTH = modeList[1].type;
  122. let calendar = ref([]); // 日历数组
  123. let taskMonthDistribution = ref({}); // 任务每月分布
  124. watchEffect(() => {
  125. GetMyTaskMonthDistribution({ year_stamp: curYear.value }).then(({ status, ...data }) => {
  126. if (status !== 1) return;
  127. const taskMonthArr = {};
  128. for (const [key, value] of Object.entries(data)) {
  129. taskMonthArr[key.slice(5)] = value;
  130. }
  131. taskMonthDistribution.value = taskMonthArr;
  132. });
  133. });
  134. // 得到当前日历任务每日分布
  135. let date = ref(`${dateStamp.getFullYear()}-${dateStamp.getMonth() + 1}`);
  136. let taskDailyDistribution = ref({}); // 任务每日分布
  137. watchEffect(() => {
  138. curYear.value = dayjs(date.value).year();
  139. curMonth.value = dayjs(date.value).month() + 1;
  140. focusMonth.value = dayjs(date.value).month();
  141. GetMyTaskDailyDistribution({ month_stamp: date.value }).then(({ status, ...data }) => {
  142. if (status !== 1) return;
  143. const taskDailyArr = {};
  144. for (const [key, value] of Object.entries(data)) {
  145. taskDailyArr[key.slice(5)] = value;
  146. }
  147. taskDailyDistribution.value = taskDailyArr;
  148. });
  149. });
  150. const taskDailyClass = new Map([
  151. [0, ''],
  152. [1, 'has-task'],
  153. [2, 'task-completed']
  154. ]);
  155. // 得到日历每日样式
  156. function getTaskDailyClass(month, day) {
  157. const date = `${month < 10 ? '0' : ''}${month}-${day < 10 ? '0' : ''}${day}`;
  158. return date in taskDailyDistribution.value ? taskDailyClass.get(taskDailyDistribution.value[date]) : '';
  159. }
  160. // 得到日历每月样式
  161. function getTaskMonthClass(month) {
  162. return month in taskMonthDistribution.value ? taskDailyClass.get(taskMonthDistribution.value[month]) : '';
  163. }
  164. // 得到日历所需数组
  165. function getDateArr() {
  166. const daysInMonth = dayjs(date.value).daysInMonth();
  167. const dayOfWeek = dayjs(`${date.value}-1`).day();
  168. const curMonth = dayjs(date.value).month();
  169. const curYear = dayjs(date.value).year();
  170. const lastDays = dayjs(curMonth === 0 ? `${curYear - 1}-12` : `${curYear}-${curMonth}`).daysInMonth();
  171. const cDate = new Date();
  172. const curDate = cDate.getDate();
  173. const isThisMonth = curMonth === cDate.getMonth() && curYear === cDate.getFullYear();
  174. let arr = [];
  175. // 是否有上个月
  176. for (let i = 0; i < dayOfWeek; i++) {
  177. arr[i] = {
  178. key: `last-${i}`,
  179. month: (curMonth === 0 ? 11 : curMonth - 1) + 1,
  180. day: lastDays - dayOfWeek + i + 1,
  181. isCurMonth: false,
  182. isToday: false
  183. };
  184. }
  185. // 本月
  186. for (let j = 1; j <= daysInMonth; j++) {
  187. arr[j + dayOfWeek - 1] = {
  188. key: `cur-${j}`,
  189. month: curMonth + 1,
  190. day: j,
  191. isCurMonth: true,
  192. isToday: j === curDate && isThisMonth
  193. };
  194. }
  195. if (arr.length === 35) return (calendar.value = arr);
  196. // 下月
  197. let next = (arr.length < 35 ? 35 : 42) - dayOfWeek - daysInMonth;
  198. for (let k = 1; k <= next; k++) {
  199. arr.push({
  200. key: `next-${k}`,
  201. month: (curMonth === 11 ? 1 : curMonth + 1) + 1,
  202. day: k,
  203. isCurMonth: false,
  204. isToday: false
  205. });
  206. }
  207. calendar.value = arr;
  208. }
  209. getDateArr();
  210. // 返回今天
  211. function backToday() {
  212. const curDate = new Date();
  213. date.value = `${curDate.getFullYear()}-${curDate.getMonth() + 1}`;
  214. focusDate.value = curDate.getDate();
  215. focusMonth.value = curDate.getMonth();
  216. emits('changeDate');
  217. getDateArr();
  218. }
  219. /**
  220. * 日历模式切换
  221. */
  222. let time_unit = ref(modeList[0].type); // 当前日历模式
  223. let calendarStyle = ref(''); // 日历样式
  224. // 根据日历模式切换样式
  225. watchEffect(() => {
  226. if (time_unit.value === DAY) {
  227. return (calendarStyle.value = `40px repeat(${calendar.value.length > 35 ? 6 : 5}, 1fr) / repeat(7, 1fr)`);
  228. }
  229. if (time_unit.value === MONTH) return (calendarStyle.value = `repeat(4, 1fr) / repeat(3, 1fr)`);
  230. });
  231. // 月份向前或向后
  232. function changeMonth(type) {
  233. const curMonth = dayjs(date.value).month();
  234. const curYear = dayjs(date.value).year();
  235. if (type === 'pre' && time_unit.value === DAY) {
  236. date.value = curMonth === 0 ? `${curYear - 1}-12` : `${curYear}-${curMonth}`;
  237. }
  238. if (type === 'pre' && time_unit.value === MONTH) {
  239. date.value = `${curYear - 1}-${curMonth + 1}`;
  240. }
  241. if (type === 'next' && time_unit.value === DAY) {
  242. date.value = curMonth === 11 ? `${curYear + 1}-1` : `${curYear}-${curMonth + 2}`;
  243. }
  244. if (type === 'next' && time_unit.value === MONTH) {
  245. date.value = `${curYear + 1}-${curMonth + 1}`;
  246. }
  247. nextTick(() => {
  248. emits('changeDate');
  249. });
  250. getDateArr();
  251. }
  252. /**
  253. * 改变显示方式 日/月
  254. */
  255. function changeMenu(type) {
  256. time_unit.value = type;
  257. emits('changeTimeUnit');
  258. }
  259. // 日模式 -> 选择日期
  260. function selectDate(number, isCurMonth) {
  261. if (time_unit.value === DAY) {
  262. focusDate.value = number;
  263. }
  264. if (!isCurMonth) {
  265. return changeMonth(number < 7 ? 'next' : 'pre');
  266. }
  267. emits('changeDate');
  268. }
  269. // 月模式 -> 选择月份
  270. function selectMonth(number) {
  271. date.value = `${curYear.value}-${number + 1}`;
  272. focusMonth.value = number;
  273. nextTick(() => {
  274. emits('changeDate');
  275. });
  276. getDateArr();
  277. }
  278. return {
  279. DAY,
  280. MONTH,
  281. time_unit,
  282. curYear,
  283. curMonth,
  284. focusDate,
  285. calendarStyle,
  286. calendar,
  287. taskDailyDistribution,
  288. taskMonthDistribution,
  289. focusMonth,
  290. getTaskDailyClass,
  291. getTaskMonthClass,
  292. backToday,
  293. changeMonth,
  294. changeMenu,
  295. selectDate,
  296. selectMonth
  297. };
  298. }