forked from liweijie/education
校历
This commit is contained in:
@@ -74,7 +74,7 @@
|
||||
:data-key="cellKey(wIdx, col.colIndex)"
|
||||
@dblclick="onCellDblClick(wIdx, col)"
|
||||
>
|
||||
<span v-if="getEvent(wIdx, col.colIndex)" class="sce-event-name" :class="{ 'is-bold': getEvent(wIdx, col.colIndex).bold }">{{ getEvent(wIdx, col.colIndex).name }}</span>
|
||||
<span v-if="getEvent(wIdx, col.colIndex) && getEvent(wIdx, col.colIndex).name" class="sce-event-name" :class="{ 'is-bold': getEvent(wIdx, col.colIndex).bold }">{{ getEvent(wIdx, col.colIndex).name }}</span>
|
||||
<span v-else class="sce-date-num">{{ dateNumberOf(wIdx, col.dayIndex) }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -134,6 +134,8 @@ export default {
|
||||
// 学期日期范围
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
// 日历渲染起点(学期当周周一)
|
||||
calendarStart: null,
|
||||
totalWeeks: 0,
|
||||
dateRangeText: '',
|
||||
weeks: [],
|
||||
@@ -248,6 +250,7 @@ export default {
|
||||
if (kx && jx) {
|
||||
this.startDate = new Date(kx.replace(/-/g, '/'))
|
||||
this.endDate = new Date(jx.replace(/-/g, '/'))
|
||||
this.calendarStart = null
|
||||
this.buildWeeks()
|
||||
}
|
||||
this.loadXqxlbEvents()
|
||||
@@ -292,10 +295,10 @@ export default {
|
||||
},
|
||||
// 根据假期记录反推时间格位置(jqsj 日期 + courseClass 节次),与列是否可见无关
|
||||
locateXqxlb(item) {
|
||||
if (!this.startDate || !item.jqsj) return null
|
||||
if (!this.calendarStart || !item.jqsj) return null
|
||||
const d = new Date(String(item.jqsj).slice(0, 10).replace(/-/g, '/'))
|
||||
if (isNaN(d.getTime())) return null
|
||||
const offset = Math.round((d - this.startDate) / (24 * 3600 * 1000))
|
||||
const offset = Math.round((d - this.calendarStart) / (24 * 3600 * 1000))
|
||||
if (offset < 0) return null
|
||||
const wIdx = Math.floor(offset / 7)
|
||||
const dayIndex = offset % 7
|
||||
@@ -315,13 +318,22 @@ export default {
|
||||
if (s === '1112') return 'late'
|
||||
return null
|
||||
},
|
||||
// 获取日期所在周的周一(周一为一周起点)
|
||||
getMonday(d) {
|
||||
const date = new Date(d)
|
||||
const day = date.getDay() // 0=周日,1=周一,...,6=周六
|
||||
const diff = date.getDate() - day + (day === 0 ? -6 : 1)
|
||||
date.setDate(diff)
|
||||
return date
|
||||
},
|
||||
buildWeeks() {
|
||||
if (!this.startDate || !this.endDate) return
|
||||
const start = new Date(this.startDate)
|
||||
const start = this.getMonday(new Date(this.startDate))
|
||||
const end = new Date(this.endDate)
|
||||
this.calendarStart = start
|
||||
const days = Math.round((end - start) / (24 * 3600 * 1000)) + 1
|
||||
this.totalWeeks = Math.ceil(days / 7)
|
||||
this.dateRangeText = fmtDate(start) + ' 到 ' + fmtDate(end)
|
||||
this.dateRangeText = fmtDate(new Date(this.startDate)) + ' 到 ' + fmtDate(new Date(this.endDate))
|
||||
const weeks = []
|
||||
for (let w = 0; w < this.totalWeeks; w++) {
|
||||
const wkStart = new Date(start)
|
||||
@@ -355,21 +367,18 @@ export default {
|
||||
},
|
||||
// 单元格内显示的日期数字(如 0703)
|
||||
dateNumberOf(wIdx, dayIndex) {
|
||||
if (!this.startDate) return ''
|
||||
const d = new Date(this.startDate)
|
||||
d.setDate(this.startDate.getDate() + wIdx * 7 + dayIndex)
|
||||
if (!this.calendarStart) return ''
|
||||
const d = new Date(this.calendarStart)
|
||||
d.setDate(this.calendarStart.getDate() + wIdx * 7 + dayIndex)
|
||||
return pad2(d.getMonth() + 1) + pad2(d.getDate())
|
||||
},
|
||||
cellClass(wIdx, col) {
|
||||
const classes = []
|
||||
// 星期交替背景(单双日不同底色)
|
||||
if (col.dayIndex % 2 === 0) classes.push('sce-cell-odd')
|
||||
else classes.push('sce-cell-even')
|
||||
if (this.selectedKeys.includes(this.cellKey(wIdx, col.colIndex))) classes.push('is-selected')
|
||||
const ev = this.getEvent(wIdx, col.colIndex)
|
||||
if (ev) {
|
||||
classes.push('has-event')
|
||||
if (!ev.schedulable) classes.push('no-schedule')
|
||||
// 可排课的全部白色;不可排课且事件名非空才标红
|
||||
if (ev && ev.name && !ev.schedulable) {
|
||||
classes.push('no-schedule')
|
||||
}
|
||||
return classes
|
||||
},
|
||||
@@ -467,8 +476,9 @@ export default {
|
||||
return
|
||||
}
|
||||
const name = this.toolbar.eventName.trim()
|
||||
// 空名称时按清除处理
|
||||
if (!name) {
|
||||
this.$message.warning('请输入事件名称')
|
||||
this.deleteEvent()
|
||||
return
|
||||
}
|
||||
const keys = [...this.selectedKeys]
|
||||
@@ -492,16 +502,20 @@ export default {
|
||||
return
|
||||
}
|
||||
const keys = [...this.selectedKeys]
|
||||
keys.forEach(key => {
|
||||
this.$delete(this.events, key)
|
||||
this.persistDeleteEvents(keys).then(({ ok, fail }) => {
|
||||
if (fail === 0) {
|
||||
keys.forEach(key => {
|
||||
this.$delete(this.events, key)
|
||||
})
|
||||
this.selectedKeys = []
|
||||
}
|
||||
})
|
||||
this.$message.success('已删除 ' + keys.length + ' 个时间格事件')
|
||||
},
|
||||
absorbEvent() {
|
||||
// 吸取:取选择中第一个有事件的格
|
||||
// 吸取:取选择中第一个事件名非空的格
|
||||
let target = null
|
||||
for (const key of this.selectedKeys) {
|
||||
if (this.events[key]) { target = this.events[key]; break }
|
||||
if (this.events[key] && this.events[key].name) { target = this.events[key]; break }
|
||||
}
|
||||
if (!target) {
|
||||
this.$message.warning('所选时间格中无事件可吸取')
|
||||
@@ -517,7 +531,7 @@ export default {
|
||||
},
|
||||
onCellDblClick(wIdx, col) {
|
||||
const ev = this.getEvent(wIdx, col.colIndex)
|
||||
if (ev) {
|
||||
if (ev && ev.name) {
|
||||
this.toolbar.eventName = ev.name
|
||||
this.toolbar.bold = !!ev.bold
|
||||
this.toolbar.schedulable = !!ev.schedulable
|
||||
@@ -561,12 +575,35 @@ export default {
|
||||
return { ok: ok, fail: fail }
|
||||
})
|
||||
},
|
||||
// 批量删除选中格事件
|
||||
persistDeleteEvents(keys) {
|
||||
const tasks = keys
|
||||
.filter(key => this.events[key])
|
||||
.map(key => {
|
||||
const payload = this.buildXqxlbPayload(key, this.events[key])
|
||||
if (!payload) return Promise.resolve(false)
|
||||
payload.delFlag = 1
|
||||
return updateXqxlb(payload)
|
||||
.then(() => true)
|
||||
.catch(() => false)
|
||||
})
|
||||
return Promise.all(tasks).then(results => {
|
||||
const ok = results.filter(r => r === true).length
|
||||
const fail = results.length - ok
|
||||
if (fail > 0) {
|
||||
this.$message.error(fail + ' 个事件删除失败,请检查后端接口')
|
||||
} else if (ok > 0) {
|
||||
this.$message.success('已删除 ' + ok + ' 个时间格事件')
|
||||
}
|
||||
return { ok: ok, fail: fail }
|
||||
})
|
||||
},
|
||||
// 构造 xqxlb 提交数据
|
||||
buildXqxlbPayload(key, ev) {
|
||||
const pos = this.parseCellKey(key)
|
||||
if (!pos) return null
|
||||
const d = new Date(this.startDate)
|
||||
d.setDate(this.startDate.getDate() + pos.wIdx * 7 + pos.dayIndex)
|
||||
const d = new Date(this.calendarStart)
|
||||
d.setDate(this.calendarStart.getDate() + pos.wIdx * 7 + pos.dayIndex)
|
||||
return {
|
||||
delFlag: 0,
|
||||
bh: ev.bh || undefined,
|
||||
@@ -722,14 +759,20 @@ export default {
|
||||
background: #fff;
|
||||
transition: background 0.15s;
|
||||
|
||||
.sce-date-num { color: #c0c4cc; }
|
||||
.sce-event-name {
|
||||
display: block;
|
||||
line-height: 1;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
// 星期交替底色:周一/三/五/日为浅绿,周二/四/六为白,便于区分星期
|
||||
&.sce-cell-odd { background: #eef6f1; }
|
||||
&.sce-cell-even { background: #ffffff; }
|
||||
&.has-event { background: #e6f4ea; }
|
||||
&.has-event .sce-event-name { color: #00663e; font-weight: 500; }
|
||||
&.has-event .sce-event-name.is-bold { font-weight: 700; }
|
||||
.sce-date-num {
|
||||
display: block;
|
||||
font-size: 10px;
|
||||
color: #c0c4cc;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
// 可排课白色,不可排课且有事件标红
|
||||
&.no-schedule { background: #fde2e2; }
|
||||
|
||||
&.is-selected {
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
class="cal-cell"
|
||||
:class="cellClass(wIdx, col)"
|
||||
>
|
||||
<template v-if="getEvent(wIdx, col.colIndex)">
|
||||
<template v-if="getEvent(wIdx, col.colIndex) && getEvent(wIdx, col.colIndex).name">
|
||||
<span class="cal-event-name">{{ getEvent(wIdx, col.colIndex).name }}</span>
|
||||
</template>
|
||||
<span v-else-if="showDate" class="cal-date-num">{{ dateNumberOf(wIdx, col.dayIndex) }}</span>
|
||||
@@ -102,6 +102,8 @@ export default {
|
||||
// 学期日期范围
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
// 日历渲染起点(学期当周周一)
|
||||
calendarStart: null,
|
||||
totalWeeks: 0,
|
||||
dateRangeText: '',
|
||||
weeks: [],
|
||||
@@ -173,6 +175,7 @@ export default {
|
||||
if (!this.nd) return
|
||||
this.startDate = null
|
||||
this.endDate = null
|
||||
this.calendarStart = null
|
||||
getSemester(this.nd)
|
||||
.then(res => {
|
||||
const data = res.data || res || {}
|
||||
@@ -215,10 +218,10 @@ export default {
|
||||
},
|
||||
// 根据假期记录反推时间格 key(jqsj 日期 + courseClass 节次)
|
||||
locateXqxlb(item) {
|
||||
if (!this.startDate || !item.jqsj) return null
|
||||
if (!this.calendarStart || !item.jqsj) return null
|
||||
const d = new Date(String(item.jqsj).slice(0, 10).replace(/-/g, '/'))
|
||||
if (isNaN(d.getTime())) return null
|
||||
const offset = Math.round((d - this.startDate) / (24 * 3600 * 1000))
|
||||
const offset = Math.round((d - this.calendarStart) / (24 * 3600 * 1000))
|
||||
if (offset < 0) return null
|
||||
const wIdx = Math.floor(offset / 7)
|
||||
const dayIndex = offset % 7
|
||||
@@ -240,13 +243,22 @@ export default {
|
||||
if (s === '1112') return 'late'
|
||||
return null
|
||||
},
|
||||
// 获取日期所在周的周一(周一为一周起点)
|
||||
getMonday(d) {
|
||||
const date = new Date(d)
|
||||
const day = date.getDay() // 0=周日,1=周一,...,6=周六
|
||||
const diff = date.getDate() - day + (day === 0 ? -6 : 1)
|
||||
date.setDate(diff)
|
||||
return date
|
||||
},
|
||||
buildWeeks() {
|
||||
if (!this.startDate || !this.endDate) return
|
||||
const start = new Date(this.startDate)
|
||||
const start = this.getMonday(new Date(this.startDate))
|
||||
const end = new Date(this.endDate)
|
||||
this.calendarStart = start
|
||||
const days = Math.round((end - start) / (24 * 3600 * 1000)) + 1
|
||||
this.totalWeeks = Math.ceil(days / 7)
|
||||
this.dateRangeText = fmtDate(start) + ' 到 ' + fmtDate(end)
|
||||
this.dateRangeText = fmtDate(new Date(this.startDate)) + ' 到 ' + fmtDate(new Date(this.endDate))
|
||||
const weeks = []
|
||||
for (let w = 0; w < this.totalWeeks; w++) {
|
||||
const wkStart = new Date(start)
|
||||
@@ -276,20 +288,17 @@ export default {
|
||||
},
|
||||
// 单元格内显示的日期数字(如 0703)
|
||||
dateNumberOf(wIdx, dayIndex) {
|
||||
if (!this.startDate) return ''
|
||||
const d = new Date(this.startDate)
|
||||
d.setDate(this.startDate.getDate() + wIdx * 7 + dayIndex)
|
||||
if (!this.calendarStart) return ''
|
||||
const d = new Date(this.calendarStart)
|
||||
d.setDate(this.calendarStart.getDate() + wIdx * 7 + dayIndex)
|
||||
return pad2(d.getMonth() + 1) + pad2(d.getDate())
|
||||
},
|
||||
cellClass(wIdx, col) {
|
||||
const classes = []
|
||||
// 星期交替背景(单双日不同底色)
|
||||
if (col.dayIndex % 2 === 0) classes.push('cal-cell-odd')
|
||||
else classes.push('cal-cell-even')
|
||||
const ev = this.getEvent(wIdx, col.colIndex)
|
||||
if (ev) {
|
||||
classes.push('has-event')
|
||||
if (!ev.schedulable) classes.push('no-schedule')
|
||||
// 可排课的全部白色;不可排课且事件名非空才标红
|
||||
if (ev && ev.name && !ev.schedulable) {
|
||||
classes.push('no-schedule')
|
||||
}
|
||||
return classes
|
||||
},
|
||||
@@ -339,7 +348,7 @@ export default {
|
||||
html += '<td>' + week.rangeText + '</td>'
|
||||
this.visibleColumns.forEach(col => {
|
||||
const ev = this.getEvent(wIdx, col.colIndex)
|
||||
if (ev) {
|
||||
if (ev && ev.name) {
|
||||
const remark = ev.remark && ev.remarkShow ? '(' + ev.remark + ')' : ''
|
||||
html += '<td>' + ev.name + remark + '</td>'
|
||||
} else if (this.showDate) {
|
||||
@@ -466,13 +475,20 @@ export default {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
|
||||
.cal-date-num { color: #c0c4cc; }
|
||||
.cal-event-name {
|
||||
display: block;
|
||||
line-height: 1;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
// 星期交替底色:周一/三/五/日为浅绿,周二/四/六为白
|
||||
&.cal-cell-odd { background: #eef6f1; }
|
||||
&.cal-cell-even { background: #ffffff; }
|
||||
&.has-event { background: #e6f4ea; }
|
||||
&.has-event .cal-event-name { color: #00663e; font-weight: 500; }
|
||||
.cal-date-num {
|
||||
display: block;
|
||||
font-size: 10px;
|
||||
color: #c0c4cc;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
// 可排课白色,不可排课且有事件标红
|
||||
&.no-schedule { background: #fde2e2; }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user