You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

502 lines
12 KiB

  1. <template>
  2. <div class="month-container">
  3. <div class="month-top">
  4. <div class="m-btn-wrap">
  5. <span @click="handleShowLastMonth">上一月</span>
  6. <span @click="handleShowToday"> 当月 </span>
  7. <span @click="handleShowNextMonth">下一月</span>
  8. </div>
  9. <span class="m-today-date"> {{ year }}年{{ month > 9 ? month : `0${month}` }}月</span>
  10. <!-- <div class="m-card-status">
  11. <div v-for="sta in cardStatus">
  12. <span class="square" :style="{background:sta.color}"></span>
  13. <span class="title">{{ sta.title }}</span>
  14. </div>
  15. </div> -->
  16. </div>
  17. <div class="m-date-wrap">
  18. <ul class="m-week">
  19. <li>日</li>
  20. <li>一</li>
  21. <li>二</li>
  22. <li>三</li>
  23. <li>四</li>
  24. <li>五</li>
  25. <li>六</li>
  26. </ul>
  27. <ul class="m-day">
  28. <li v-for="(myDay,index) in days"
  29. :class="{'m-isActive':myDay.isActive,'m-isCurToday':myDay.isCurToday}"
  30. :key="index" @click="handleChooseCard(myDay)">
  31. <span class="m-date" :class="{'m-isCurMonth':myDay.isNextMonth||myDay.isLastMonth}">
  32. {{ myDay.day }}
  33. </span>
  34. <slot :row="myDay"></slot>
  35. <!-- <template v-for="(plan,i) in myDay.planList">
  36. <div v-if="i<hasNumExpend&&!myDay.isExpend" :key="`plan${i}`" @click="handleDetail(plan)"
  37. class="m-card-default"
  38. :style="{background: cardStatus[plan.status].color}">
  39. <slot name="card" :row="plan"></slot>
  40. </div>
  41. <div v-if="myDay.isExpend" :key="`plan${i}`" @click="handleDetail(plan)"
  42. class="m-card-default"
  43. :style="{background: cardStatus[plan.status].color}">
  44. <slot name="card" :row="plan"></slot>
  45. </div>
  46. </template> -->
  47. <div class="w_expand" v-if="myDay.planList.length>hasNumExpend&&!myDay.isExpend" @click="handleExpand(myDay)">展开
  48. </div>
  49. <div class="w_shrink" v-if="myDay.planList.length>hasNumExpend&&myDay.isExpend"
  50. @click="handleExpand(myDay)">收缩
  51. </div>
  52. </li>
  53. </ul>
  54. </div>
  55. <div class="m-card-status1">
  56. <div v-for="sta in cardStatus">
  57. <span class="square" :style="{background:sta.color}"></span>
  58. <span class="title">{{ sta.title }}</span>
  59. </div>
  60. </div>
  61. </div>
  62. </template>
  63. <script>
  64. import {getCurDay} from "./MyTools";
  65. export default {
  66. name: 'monthSchedule',
  67. props: {
  68. //日程数据
  69. scheduleList: {
  70. type: Array,
  71. default:()=>[]
  72. },
  73. //是否展开,默认不展开
  74. isExpend:{
  75. type: Boolean,
  76. default:false
  77. },
  78. //多少进行展开
  79. hasNumExpend:{
  80. type: Number,
  81. default:2
  82. },
  83. //卡片状态
  84. cardStatus: {
  85. type: Object,
  86. default: () => {
  87. return {
  88. 1: {
  89. title: '已过期',
  90. color: '#9CADADB7'
  91. },
  92. 2: {
  93. title: '进行中',
  94. color: '#FF6200'
  95. },
  96. 3: {
  97. title: '未开始',
  98. color: '#3291F8'
  99. },
  100. }
  101. }
  102. }
  103. },
  104. data() {
  105. return {
  106. year: '',//年
  107. month: '',//月
  108. days: [],//日期
  109. endTime: null,
  110. startTime: null,
  111. monthValue: '',
  112. }
  113. },
  114. methods: {
  115. //展开与缩放操作
  116. handleExpand (row) {
  117. row.isExpend = !row.isExpend
  118. },
  119. changeMonth() {
  120. const date = this.monthValue && this.monthValue.split('-').map(Number) || []
  121. if (date.length === 0) {
  122. return
  123. }
  124. this.year = date[0];
  125. this.month = date[1]
  126. this.days = [];
  127. this.pushDays();
  128. },
  129. //得到当前年这个月分有多少天
  130. getDays(Y, M) {
  131. return new Date(Y, M, 0).getDate();
  132. },
  133. //得到当前年,这个月的一号是周几
  134. getWeek(Y, M) {
  135. let now = new Date()
  136. now.setFullYear(this.year)
  137. now.setMonth(this.month - 1)
  138. now.setDate(1);
  139. return now.getDay();
  140. },
  141. /**
  142. * 获取本月日期
  143. */
  144. pushDays() {
  145. console.log(this.getDays(this.year, this.month))
  146. //将这个月多少天加入数组days
  147. for (let i = 1; i <= this.getDays(this.year, this.month); i++) {
  148. const _day = `${i > 9 ? i : '0' + i}`, _month = `${this.month > 9 ? this.month : '0' + this.month}`,
  149. date = `${this.year}-${_month}-${_day}`;
  150. this.days.push({
  151. day: _day,//
  152. date,
  153. isExpend:this.isExpend,
  154. planList:this.scheduleList.filter(item => item.date === date),
  155. isCurMonth: true,
  156. month: _month,
  157. year: `${this.year}`,
  158. timestamp: new Date(date).getTime(),//转换时间戳
  159. })
  160. }
  161. this.getLastMonthDays()
  162. this.getNextMonthDays()
  163. },
  164. /**
  165. * 获取下个月的日期
  166. */
  167. getNextMonthDays() {
  168. const month = this.month < 12 ? this.month + 1 : 1,
  169. year = this.month < 12 ? this.year : this.year + 1,
  170. len = 42 - this.getDays(this.year, this.month) - this.getWeek(this.year, this.month)
  171. //将下个月要显示的天数加入days
  172. for (let i = 1; i <= len; i++) {
  173. const _day = `${i > 9 ? i : '0' + i}`, _month = `${month > 9 ? month : '0' + month}`,
  174. date = `${year}-${_month}-${_day}`;
  175. this.days.push({
  176. day: _day,
  177. date,
  178. isExpend:this.isExpend,
  179. month: _month,
  180. year: `${year}`,
  181. planList: this.scheduleList.filter(item => item.date === date),
  182. isNextMonth: true,
  183. timestamp: new Date(date).getTime()
  184. })
  185. }
  186. },
  187. /**
  188. * 获取上个月的日期
  189. */
  190. getLastMonthDays() {
  191. const month = this.month > 1 ? this.month - 1 : this.year > 1970 ? 12 : 1,
  192. year = this.month > 1 ? this.year : this.year > 1970 ? this.year - 1 : 1970,
  193. len = this.getWeek(this.year, this.month),
  194. lastMonthDays = this.getDays(this.year, this.month - 1)
  195. //将上个月要显示的天数加入days
  196. for (let i = 0; i < len; i++) {
  197. const _month = month > 9 ? `${month}` : `0${month}`,
  198. date = `${year}-${_month}-${lastMonthDays - i}`;
  199. this.days.unshift({
  200. day: `${lastMonthDays - i}`,
  201. date,
  202. month: _month,
  203. year: `${year}`,
  204. isExpend:this.isExpend,
  205. planList: this.scheduleList.filter(item => item.date === date),
  206. isLastMonth: true,
  207. timestamp: new Date(date).getTime(),
  208. })
  209. }
  210. },
  211. /**
  212. * 获取日期数据
  213. */
  214. getDate() {
  215. let now = new Date();
  216. this.year = now.getFullYear();
  217. this.month = now.getMonth() + 1;
  218. this.pushDays();
  219. },
  220. /**
  221. * 下个月
  222. */
  223. handleShowNextMonth() {
  224. if (this.month < 12) {
  225. this.month = this.month + 1;
  226. } else {
  227. this.month = this.month = 1;
  228. this.year = this.year + 1;
  229. }
  230. this.dealCurDay();
  231. const dateObj = {
  232. date: `${this.year}-${this.month}`,
  233. timestamp: new Date(`${this.year}-${this.month}`).getTime()
  234. }
  235. this.$emit('changeMonth', dateObj)
  236. },
  237. /**
  238. * 当天
  239. */
  240. handleShowToday() {
  241. let now = new Date();
  242. this.year = now.getFullYear();
  243. this.month = now.getMonth() + 1;
  244. this.dealCurDay();
  245. const dateObj = {
  246. date: `${this.year}-${this.month}`,
  247. timestamp: new Date(`${this.year}-${this.month}`).getTime()
  248. }
  249. this.$emit('changeMonth', dateObj)
  250. },
  251. /**
  252. * 处理当天数据
  253. */
  254. dealCurDay() {
  255. this.days = [];
  256. const curDate = getCurDay()
  257. this.pushDays();
  258. this.days.forEach(item => {
  259. item.isCurToday = item.date === curDate
  260. })
  261. },
  262. /**
  263. * 上个月
  264. */
  265. handleShowLastMonth() {
  266. this.days = [];
  267. if (this.month > 1) {
  268. this.month = this.month - 1;
  269. this.dealCurDay();
  270. } else if (this.year > 1970) {
  271. this.month = 12;
  272. this.year = this.year - 1;
  273. this.dealCurDay();
  274. } else {
  275. this.dealCurDay();
  276. return new Error('只能查1970以后的月份')
  277. }
  278. const dateObj = {
  279. date: `${this.year}-${this.month}`,
  280. timestamp: new Date(`${this.year}-${this.month}`).getTime()
  281. }
  282. this.$emit('changeMonth', dateObj)
  283. },
  284. /**
  285. * 选择日期卡片详情
  286. * @param row
  287. */
  288. handleChooseCard(row = {}) {
  289. this.$emit('chooseEntireCard', row)
  290. },
  291. /**
  292. * 查看单个日程详情
  293. */
  294. handleDetail(row) {
  295. this.$emit('handleDetail', row)
  296. },
  297. },
  298. mounted() {
  299. this.getDate();
  300. this.handleShowToday()
  301. },
  302. }
  303. </script>
  304. <style>
  305. ul {
  306. list-style: none;
  307. }
  308. .month-container {
  309. width: 100%;
  310. border: 1px solid #ddd;
  311. padding: 20px;
  312. box-sizing: border-box;
  313. }
  314. .month-top {
  315. width: 100%;
  316. display: flex;
  317. justify-content: space-between;
  318. align-items: center;
  319. padding: 1% 0;
  320. box-sizing: border-box;
  321. }
  322. .month-top .m-btn-wrap {
  323. width: 200px;
  324. display: flex;
  325. justify-content: space-around;
  326. color: #409EFF;
  327. }
  328. .month-top .m-btn-wrap > span {
  329. cursor: pointer;
  330. display: flex;
  331. justify-content: center;
  332. align-items: center;
  333. font-size: 15px;
  334. }
  335. .month-top .m-card-status {
  336. display: flex;
  337. width: 20%;
  338. justify-content: flex-end;
  339. }
  340. .month-top .m-card-status > div {
  341. flex: 1;
  342. display: flex;
  343. padding: 0 2%;
  344. white-space: nowrap;
  345. line-height: 20px;
  346. box-sizing: border-box;
  347. }
  348. .month-top .m-card-status > div .square {
  349. display: flex;
  350. width: 16px;
  351. height: 16px;
  352. border-radius: 4px;
  353. box-sizing: border-box;
  354. }
  355. .month-top .m-card-status > div .title {
  356. display: flex;
  357. align-items: center;
  358. line-height: 16px;
  359. margin-left: 4px;
  360. font-size: 14px;
  361. }
  362. .m-date-wrap {
  363. width: 100%;
  364. height: auto;
  365. }
  366. .m-date-wrap .m-week {
  367. width: 100%;
  368. height: 40px;
  369. margin: 0;
  370. line-height: 40px;
  371. display: flex;
  372. flex-direction: row;
  373. font-size: 16px;
  374. background: #EAEDF2;
  375. box-sizing: border-box;
  376. padding-left: 0%;
  377. }
  378. .m-date-wrap .m-week > li {
  379. width: 14.28%;
  380. padding-left: 1%;
  381. box-sizing: border-box;
  382. text-align: center;
  383. }
  384. .m-date-wrap .m-day {
  385. width: 100%;
  386. display: flex;
  387. flex-direction: row;
  388. padding: 0;
  389. margin: 0;
  390. font-size: 14px;
  391. flex-wrap: wrap;
  392. box-sizing: border-box;
  393. }
  394. .m-day .m-date{
  395. cursor: pointer;
  396. }
  397. .m-date-wrap .m-day > li {
  398. width: 14.28%;
  399. padding: 1%;
  400. min-height: 40px;
  401. box-sizing: border-box;
  402. border: 1px solid #ddd;
  403. }
  404. .m-date-wrap .m-day > li .m-card-default {
  405. cursor: pointer;
  406. width: 100%;
  407. min-height: 60px;
  408. border-radius: 8px;
  409. display: flex;
  410. margin: 6% 0;
  411. flex-direction: column;
  412. justify-content: space-around;
  413. white-space: nowrap;
  414. color: #fff;
  415. background: #FF6200;
  416. padding: 2% 4%;
  417. box-sizing: border-box;
  418. }
  419. .m-card-default span{
  420. overflow: hidden;
  421. text-overflow: ellipsis;
  422. }
  423. .m-date-wrap .m-day > li:nth-child(n+8) {
  424. border-top: none;
  425. }
  426. .m-date-wrap .m-day > li:nth-child(n+1) {
  427. border-right: none;
  428. }
  429. .m-date-wrap .m-day > li:nth-child(7n) {
  430. border-right: 1px solid #ddd
  431. }
  432. .m-isCurMonth {
  433. background: #fff;
  434. color: #c0c4cc;
  435. }
  436. /* .m-isCurToday {
  437. background: #ECF5FF;
  438. color: #FF2525;
  439. } */
  440. .m-isActive {
  441. background: #ECF5FF;
  442. color: #409EFF;
  443. }
  444. .w_expand, .w_shrink {
  445. color: #0A98D5;
  446. cursor: pointer;
  447. width: 100%;
  448. padding: 2% 0;
  449. display: flex;
  450. justify-content: center;
  451. align-items: center;
  452. box-sizing: border-box;
  453. }
  454. .m-card-status1{
  455. display: flex;
  456. }
  457. .m-card-status1 > div{
  458. padding: 4px;
  459. }
  460. .m-card-status1 .square{
  461. display: inline-block;
  462. margin-right: 4px;
  463. border-radius: 50%;
  464. width: 10px;
  465. height: 10px;
  466. }
  467. </style>