|
|
|
|
@ -47,7 +47,7 @@ export default {
|
|
|
|
|
type: Array,
|
|
|
|
|
default: () => []
|
|
|
|
|
},
|
|
|
|
|
// 每行高度,单位 rpx
|
|
|
|
|
// 每行高度,单位 rpx
|
|
|
|
|
rowHeightRpx: {
|
|
|
|
|
type: Number,
|
|
|
|
|
default: 140
|
|
|
|
|
@ -76,7 +76,7 @@ export default {
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
FIRST_DOW: 0, // 0=Sunday
|
|
|
|
|
// rpx 单位(仅存数值,使用时拼接 rpx)
|
|
|
|
|
// rpx 单位(仅存数值,使用时拼接 rpx)
|
|
|
|
|
cellHeight: this.rowHeightRpx,
|
|
|
|
|
headerHeight: this.headerHeightRpx,
|
|
|
|
|
weekHeaderHeight: this.weekHeaderHeightRpx,
|
|
|
|
|
@ -214,7 +214,7 @@ export default {
|
|
|
|
|
segs.push({
|
|
|
|
|
...ev,
|
|
|
|
|
weekStartISO: weekStart.toISOString(),
|
|
|
|
|
// 保留本地毫秒时间,避免 ISO/时区转换带来的日期偏移
|
|
|
|
|
// 保留本地毫秒时间,避免 ISO/时区转换带来的日期偏移
|
|
|
|
|
segStartMs: segStart.getTime(),
|
|
|
|
|
segEndMs: segEnd.getTime(),
|
|
|
|
|
startCol,
|
|
|
|
|
@ -226,7 +226,7 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 为每周的分段分配 lane,避免重叠
|
|
|
|
|
// 为每周的分段分配 lane,避免重叠
|
|
|
|
|
const byWeek = {}
|
|
|
|
|
segs.forEach(s => {
|
|
|
|
|
const key = s.weekStartISO
|
|
|
|
|
@ -270,7 +270,7 @@ export default {
|
|
|
|
|
segs.forEach(seg => {
|
|
|
|
|
const segStart = new Date(seg.segStartMs)
|
|
|
|
|
|
|
|
|
|
// 基于 weeks 网格直接定位行列,避免周起始偏差
|
|
|
|
|
// 基于 weeks 网格直接定位行列,避免周起始偏差
|
|
|
|
|
const startStr = `${segStart.getFullYear()}-${this.pad2(segStart.getMonth()+1)}-${this.pad2(segStart.getDate())}`
|
|
|
|
|
let row = 0
|
|
|
|
|
let col = seg.startCol
|
|
|
|
|
@ -288,7 +288,7 @@ export default {
|
|
|
|
|
const leftPct = col * cellWidthPct
|
|
|
|
|
const widthPct = seg.spanCols * cellWidthPct
|
|
|
|
|
const vOffset = (seg.laneIndex || 0) * (this.barHeight + this.barSpacing)
|
|
|
|
|
const innerTopPadding = 8 // 额外内边距,避免贴近格子顶部
|
|
|
|
|
const innerTopPadding = 8 // 额外内边距,避免贴近格子顶部
|
|
|
|
|
const topRpx = (row * this.cellHeight) + this.dateNumberHeight + innerTopPadding + vOffset - 10
|
|
|
|
|
|
|
|
|
|
seg._style = {
|
|
|
|
|
@ -313,14 +313,14 @@ export default {
|
|
|
|
|
formatTitle(title) {
|
|
|
|
|
const raw = (title == null ? '' : String(title)).trim()
|
|
|
|
|
if (!raw) return ''
|
|
|
|
|
// 存在管道分隔(|或|):取最后一段,再去掉右侧附加(- 第二模块)
|
|
|
|
|
// 存在管道分隔(|或|):取最后一段,再去掉右侧附加(- 第二模块)
|
|
|
|
|
if (raw.includes('|') || raw.includes('|')) {
|
|
|
|
|
const pipeParts = raw.split(/[||]/).map(s => s.trim()).filter(Boolean)
|
|
|
|
|
const afterPipe = pipeParts.length ? pipeParts[pipeParts.length - 1] : raw
|
|
|
|
|
const core = afterPipe.split(/\s*[-—–-]\s*/)[0]
|
|
|
|
|
return core.trim()
|
|
|
|
|
}
|
|
|
|
|
// 没有管道,仅有破折号分隔:
|
|
|
|
|
// 没有管道,仅有破折号分隔:
|
|
|
|
|
const dashParts = raw.split(/\s*[-—–-]\s*/).map(s => s.trim()).filter(Boolean)
|
|
|
|
|
if (dashParts.length >= 3) {
|
|
|
|
|
// 典型:前缀 - 主体 - 尾巴 → 取中间段
|
|
|
|
|
@ -388,7 +388,7 @@ export default {
|
|
|
|
|
const s = this.parseDateTime(ev.start_time)
|
|
|
|
|
const e = ev.end_time ? this.parseDateTime(ev.end_time) : this.parseDateTime(ev.start_time)
|
|
|
|
|
s.setHours(0,0,0,0); e.setHours(0,0,0,0)
|
|
|
|
|
// 单天事件才在格子里显示,跨天事件走覆盖层
|
|
|
|
|
// 单天事件才在格子里显示,跨天事件走覆盖层
|
|
|
|
|
const isMulti = ev.end_time && (s.getTime() !== e.getTime())
|
|
|
|
|
if (isMulti) return false
|
|
|
|
|
return d0.getTime() === s.getTime()
|
|
|
|
|
@ -403,7 +403,7 @@ export default {
|
|
|
|
|
const [datePart, timePart = '00:00:00'] = String(dateTimeStr).trim().split(/[T\s]+/)
|
|
|
|
|
const [y, m, d] = datePart.split('-').map(n => parseInt(n, 10))
|
|
|
|
|
const [hh = 0, mm = 0, ss = 0] = timePart.split(':').map(n => parseInt(n, 10))
|
|
|
|
|
// 以本地时间构建,避免不同时区解析成前一天/后一天
|
|
|
|
|
// 以本地时间构建,避免不同时区解析成前一天/后一天
|
|
|
|
|
return new Date(y, (m || 1) - 1, d || 1, hh || 0, mm || 0, ss || 0)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|