forked from liweijie/education
多余组件删除
This commit is contained in:
@@ -1,706 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-dialog
|
|
||||||
:visible="dialogVisible"
|
|
||||||
:show-close="false"
|
|
||||||
width="96%"
|
|
||||||
top="3vh"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
:close-on-press-escape="false"
|
|
||||||
class="peidang-dialog"
|
|
||||||
@update:visible="val => dialogVisible = val"
|
|
||||||
>
|
|
||||||
<!-- ==================== 自定义标题栏 ==================== -->
|
|
||||||
<div slot="header">
|
|
||||||
<div class="peidang-titlebar">
|
|
||||||
<i class="el-icon-reading title-icon"></i>
|
|
||||||
<span class="title-text">
|
|
||||||
班次学期配档——{{ semesterName }}——{{ classLabel }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="peidang-body">
|
|
||||||
<!-- ==================== 上半部分:左右分栏 ==================== -->
|
|
||||||
<div class="upper">
|
|
||||||
<!-- 左侧 75%:配档课程编组管理表格 -->
|
|
||||||
<div class="table-area">
|
|
||||||
<el-table
|
|
||||||
ref="tableRef"
|
|
||||||
:data="displayCourses"
|
|
||||||
border
|
|
||||||
stripe
|
|
||||||
highlight-current-row
|
|
||||||
size="small"
|
|
||||||
max-height="240"
|
|
||||||
class="peidang-table"
|
|
||||||
@current-change="handleCurrentChange"
|
|
||||||
>
|
|
||||||
<el-table-column prop="name" label="科目名称" width="100" align="left" header-align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="short" label="简称" width="60" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="planStart" label="计划起始周" width="60" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="actualStart" label="实际起始周" width="60" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="endWeek" label="结束周" width="60" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column label="连排课" width="50" align="center">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<el-checkbox :value="row.continuous" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="priority" label="优先序数" width="50" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="weeklyHours" label="周学时" width="50" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column prop="hours" label="学时" width="50" align="center" show-overflow-tooltip />
|
|
||||||
<el-table-column label="正课时间" width="60" align="center">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<el-checkbox :value="row.scheduleTime" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="已排学时" width="50" align="center">
|
|
||||||
<template slot-scope="{ row }">{{ courseStats(row).scheduled }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="未排学时" width="50" align="center">
|
|
||||||
<template slot-scope="{ row }">{{ courseStats(row).remaining }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="总班次任务数" width="70" align="center">
|
|
||||||
<template slot-scope="{ row }">{{ row.continuous ? 1 : 1 }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="配档编组任务数" width="80" align="center">
|
|
||||||
<template slot-scope="{ row }">{{ row.continuous ? 2 : 1 }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 右侧 25%:配档课程属性设置区 + 优先序数上下移动 -->
|
|
||||||
<div class="prop-area">
|
|
||||||
<div class="prop-title">配档课程属性</div>
|
|
||||||
<el-form label-width="72px" size="small" class="prop-form">
|
|
||||||
<el-form-item label="周学时">
|
|
||||||
<el-input-number v-model="propForm.weeklyHours" :min="1" :max="40" controls-position="right" style="width: 100%" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="起始周次">
|
|
||||||
<el-input-number v-model="propForm.startWeek" :min="startWeek" :max="endWeek" controls-position="right" style="width: 100%" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="结束周次">
|
|
||||||
<el-input-number v-model="propForm.endWeek" :min="startWeek" :max="endWeek" controls-position="right" style="width: 100%" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="连排课">
|
|
||||||
<el-checkbox v-model="propForm.continuous">单科独进</el-checkbox>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="优先序数">
|
|
||||||
<div class="priority-field">
|
|
||||||
<el-input-number v-model="propForm.priority" :min="1" controls-position="right" style="width: 100%" />
|
|
||||||
<el-button type="primary" plain icon="el-icon-arrow-up" @click="handlePriorityUp" />
|
|
||||||
<el-button type="primary" plain icon="el-icon-arrow-down" @click="handlePriorityDown" />
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="配档编组">
|
|
||||||
<el-input v-model="propForm.group" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<el-button type="primary" class="apply-btn" @click="handleApplyProp">应用属性</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ==================== 下半部分:配档显示区域(甘特图) ==================== -->
|
|
||||||
<div class="gantt-area">
|
|
||||||
<div class="gantt-head">
|
|
||||||
<div class="gantt-label-col">
|
|
||||||
<div class="gantt-label">课程 / 周次</div>
|
|
||||||
</div>
|
|
||||||
<div class="gantt-body">
|
|
||||||
<!-- 行1:周次刻度(红色竖线为周刻度) -->
|
|
||||||
<div class="gantt-row">
|
|
||||||
<div
|
|
||||||
v-for="w in weeks"
|
|
||||||
:key="w"
|
|
||||||
class="gantt-cell week-cell"
|
|
||||||
:class="{ 'month-boundary': isMonthBoundary(w) }"
|
|
||||||
>{{ w }}</div>
|
|
||||||
</div>
|
|
||||||
<!-- 行2:本周可安排正课学时 -->
|
|
||||||
<div class="gantt-row info-row">
|
|
||||||
<div
|
|
||||||
v-for="w in weeks"
|
|
||||||
:key="w"
|
|
||||||
class="gantt-cell"
|
|
||||||
:class="{ 'month-boundary': isMonthBoundary(w) }"
|
|
||||||
>可排{{ weeklyCapacity }}</div>
|
|
||||||
</div>
|
|
||||||
<!-- 行3:已安排学时 / 剩余学时 -->
|
|
||||||
<div class="gantt-row info-row">
|
|
||||||
<div
|
|
||||||
v-for="w in weeks"
|
|
||||||
:key="w"
|
|
||||||
class="gantt-cell"
|
|
||||||
:class="{ 'month-boundary': isMonthBoundary(w) }"
|
|
||||||
>
|
|
||||||
<span class="sch">已{{ monthlyScheduled(w) }}</span>
|
|
||||||
<span class="rem">余{{ Math.max(0, weeklyCapacity - monthlyScheduled(w)) }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 课程甘特条 -->
|
|
||||||
<div class="gantt-courses">
|
|
||||||
<div v-for="course in displayCourses" :key="course.id" class="gantt-course">
|
|
||||||
<div class="gantt-label-col">
|
|
||||||
<div class="course-tag" :class="course.continuous ? 'tag-continuous' : 'tag-normal'">
|
|
||||||
<span class="course-name">{{ course.name }}({{ course.short }})</span>
|
|
||||||
<span class="course-hours">
|
|
||||||
已排{{ courseStats(course).scheduled }}
|
|
||||||
<template v-if="courseStats(course).remaining > 0">+{{ courseStats(course).remaining }}</template>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="gantt-body">
|
|
||||||
<div class="gantt-row bar-row">
|
|
||||||
<div
|
|
||||||
v-for="w in weeks"
|
|
||||||
:key="w"
|
|
||||||
class="gantt-cell bar-cell"
|
|
||||||
:class="{
|
|
||||||
'month-boundary': isMonthBoundary(w),
|
|
||||||
'bar-active': w >= course.actualStart && w <= course.endWeek,
|
|
||||||
'bar-continuous': course.continuous,
|
|
||||||
'bar-normal': !course.continuous
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<span v-if="w >= course.actualStart && w <= course.endWeek" class="bar-hours">
|
|
||||||
{{ courseWeekHours(course)[w] || '' }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 底部:本月可安排正课总学时(月刻度) -->
|
|
||||||
<div class="gantt-foot">
|
|
||||||
<div class="gantt-label-col">
|
|
||||||
<div class="gantt-label">本月正课总学时</div>
|
|
||||||
</div>
|
|
||||||
<div class="gantt-body">
|
|
||||||
<div class="gantt-row">
|
|
||||||
<div
|
|
||||||
v-for="w in weeks"
|
|
||||||
:key="w"
|
|
||||||
class="gantt-cell month-cell"
|
|
||||||
:class="{ 'month-boundary': isMonthBoundary(w) }"
|
|
||||||
>
|
|
||||||
<span v-if="bottomCells[w] && isMonthEndWeek(w)" class="month-total">
|
|
||||||
第{{ bottomCells[w].no }}月:可排{{ bottomCells[w].total }}(已排{{ bottomCells[w].scheduled }} + 余{{ bottomCells[w].remaining }})
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ==================== 底部操作 ==================== -->
|
|
||||||
<div slot="footer">
|
|
||||||
<div class="peidang-footer">
|
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
|
||||||
<el-button type="primary" @click="handleConfirm">确定</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'PeidangEditDialog',
|
|
||||||
props: {
|
|
||||||
visible: { type: Boolean, default: false },
|
|
||||||
/** 学年学期名称 */
|
|
||||||
semesterName: { type: String, default: '2017-2018学年第一学期' },
|
|
||||||
/** 班次标签(如 教学五系2016级专业0113班次0417) */
|
|
||||||
classLabel: { type: String, default: '教学五系2016级专业0113班次0417' }
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// ==================== 时间轴参数 ====================
|
|
||||||
/** 该班次开学起始周次 */
|
|
||||||
startWeek: 8,
|
|
||||||
/** 该班次学期结束周次 */
|
|
||||||
endWeek: 32,
|
|
||||||
/** 该班次每周可安排的正课学时时数(去除不能排课学时) */
|
|
||||||
weeklyCapacity: 40,
|
|
||||||
/** 月刻度:每 4 周为一月(8-11 第1月,12-15 第2月...),虚线分隔 */
|
|
||||||
monthBreaks: [12, 16, 20, 24, 28, 32],
|
|
||||||
|
|
||||||
// ==================== 配档课程数据 ====================
|
|
||||||
courses: [
|
|
||||||
// ---- 非连排课(按周学时安排,蓝色,每门独立一组) ----
|
|
||||||
{ id: 'p1', name: '课程科目001', short: '政治', planStart: 8, actualStart: 8, endWeek: 23, continuous: false, priority: 1, weeklyHours: 4, hours: 60, scheduleTime: true, group: '组1' },
|
|
||||||
{ id: 'p2', name: '课程科目002', short: '军事', planStart: 8, actualStart: 8, endWeek: 20, continuous: false, priority: 2, weeklyHours: 4, hours: 48, scheduleTime: true, group: '组2' },
|
|
||||||
{ id: 'p3', name: '课程科目003', short: '战术', planStart: 8, actualStart: 10, endWeek: 21, continuous: false, priority: 3, weeklyHours: 4, hours: 44, scheduleTime: true, group: '组3' },
|
|
||||||
{ id: 'p4', name: '课程科目004', short: '指挥', planStart: 8, actualStart: 12, endWeek: 22, continuous: false, priority: 4, weeklyHours: 4, hours: 40, scheduleTime: true, group: '组4' },
|
|
||||||
// ---- 连排课(单科独进,红色,共为一组) ----
|
|
||||||
{ id: 'p5', name: '课程科目005', short: '综合演练', planStart: 8, actualStart: 8, endWeek: 13, continuous: true, priority: 5, weeklyHours: 20, hours: 100, scheduleTime: true, group: '连排组' },
|
|
||||||
{ id: 'p6', name: '课程科目006', short: '野营拉练', planStart: 14, actualStart: 14, endWeek: 16, continuous: true, priority: 6, weeklyHours: 24, hours: 48, scheduleTime: true, group: '连排组' }
|
|
||||||
],
|
|
||||||
|
|
||||||
// ==================== 表格选中与属性设置 ====================
|
|
||||||
currentCourse: null,
|
|
||||||
propForm: {
|
|
||||||
weeklyHours: 4,
|
|
||||||
startWeek: 8,
|
|
||||||
endWeek: 16,
|
|
||||||
continuous: false,
|
|
||||||
priority: 1,
|
|
||||||
group: ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
dialogVisible: {
|
|
||||||
get() {
|
|
||||||
return this.visible
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.$emit('update:visible', val)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/** 周序列:8 ~ 32 */
|
|
||||||
weeks() {
|
|
||||||
const arr = []
|
|
||||||
for (let w = this.startWeek; w <= this.endWeek; w++) arr.push(w)
|
|
||||||
return arr
|
|
||||||
},
|
|
||||||
/** 月份信息:每月包含的周次与可安排正课学时 */
|
|
||||||
months() {
|
|
||||||
const list = []
|
|
||||||
let mNo = 1
|
|
||||||
let cur = this.startWeek
|
|
||||||
while (cur <= this.endWeek) {
|
|
||||||
const next = this.monthBreaks.find((b) => b > cur)
|
|
||||||
const mEnd = Math.min((next === undefined ? this.endWeek + 1 : next) - 1, this.endWeek)
|
|
||||||
list.push({ no: mNo, start: cur, end: mEnd, total: (mEnd - cur + 1) * this.weeklyCapacity })
|
|
||||||
cur = mEnd + 1
|
|
||||||
mNo++
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
},
|
|
||||||
/** 底部每月汇总行数据:week -> 该月信息(仅月首格展示文字) */
|
|
||||||
bottomCells() {
|
|
||||||
const map = {}
|
|
||||||
this.weeks.forEach((w) => {
|
|
||||||
const m = this.months.find((item) => w >= item.start && w <= item.end)
|
|
||||||
if (!m) return
|
|
||||||
map[w] = {
|
|
||||||
no: m.no,
|
|
||||||
total: m.total,
|
|
||||||
scheduled: this.monthlyScheduled(w),
|
|
||||||
remaining: m.total - this.monthlyScheduled(w)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return map
|
|
||||||
},
|
|
||||||
/** 表格展示顺序:非连排课在前,连排课在后;组内按实际起始周、优先序数排序 */
|
|
||||||
displayCourses() {
|
|
||||||
return [...this.courses].sort((a, b) => {
|
|
||||||
if (a.continuous !== b.continuous) return a.continuous ? 1 : -1
|
|
||||||
if (a.actualStart !== b.actualStart) return a.actualStart - b.actualStart
|
|
||||||
return a.priority - b.priority
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
visible(val) {
|
|
||||||
if (!val) return
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (this.$refs.tableRef) {
|
|
||||||
this.$refs.tableRef.setCurrentRow(this.displayCourses[0])
|
|
||||||
}
|
|
||||||
this.currentCourse = this.displayCourses[0] || null
|
|
||||||
this.syncPropForm()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
/** 是否为月边界列(左侧画虚线) */
|
|
||||||
isMonthBoundary(week) {
|
|
||||||
return this.monthBreaks.includes(week)
|
|
||||||
},
|
|
||||||
/** 是否为某月的结束周(仅月结束列展示文字) */
|
|
||||||
isMonthEndWeek(week) {
|
|
||||||
return this.months.some((m) => m.end === week)
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 某周所有课程已安排学时之和 */
|
|
||||||
monthlyScheduled(week) {
|
|
||||||
return this.courses.reduce((sum, c) => {
|
|
||||||
const map = this.courseWeekHours(c)
|
|
||||||
return sum + (map[week] !== undefined ? map[week] : 0)
|
|
||||||
}, 0)
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 每门课程按周分布的安排学时 */
|
|
||||||
courseWeekHours(course) {
|
|
||||||
const map = {}
|
|
||||||
let remaining = course.hours
|
|
||||||
let w = course.actualStart
|
|
||||||
while (remaining > 0 && w <= course.endWeek) {
|
|
||||||
const h = Math.min(course.weeklyHours, remaining)
|
|
||||||
map[w] = h
|
|
||||||
remaining -= h
|
|
||||||
w++
|
|
||||||
}
|
|
||||||
return map
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 课程计算属性:已排学时 / 未排学时 */
|
|
||||||
courseStats(course) {
|
|
||||||
const map = this.courseWeekHours(course)
|
|
||||||
const scheduled = Object.keys(map).reduce((sum, k) => sum + map[k], 0)
|
|
||||||
return { scheduled, remaining: Math.max(0, course.hours - scheduled) }
|
|
||||||
},
|
|
||||||
|
|
||||||
handleCurrentChange(row) {
|
|
||||||
this.currentCourse = row
|
|
||||||
this.syncPropForm()
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 属性设置表单同步(右侧) */
|
|
||||||
syncPropForm() {
|
|
||||||
if (!this.currentCourse) return
|
|
||||||
this.propForm.weeklyHours = this.currentCourse.weeklyHours
|
|
||||||
this.propForm.startWeek = this.currentCourse.actualStart
|
|
||||||
this.propForm.endWeek = this.currentCourse.endWeek
|
|
||||||
this.propForm.continuous = this.currentCourse.continuous
|
|
||||||
this.propForm.priority = this.currentCourse.priority
|
|
||||||
this.propForm.group = this.currentCourse.group
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 属性设置保存:应用所选课程的配档属性 */
|
|
||||||
handleApplyProp() {
|
|
||||||
if (!this.currentCourse) {
|
|
||||||
this.$message.warning('请先在表格中选择一门课程')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const row = this.currentCourse
|
|
||||||
row.weeklyHours = this.propForm.weeklyHours
|
|
||||||
row.actualStart = this.propForm.startWeek
|
|
||||||
row.endWeek = this.propForm.endWeek
|
|
||||||
row.continuous = this.propForm.continuous
|
|
||||||
row.priority = this.propForm.priority
|
|
||||||
row.group = this.propForm.group
|
|
||||||
this.$message.success('配档属性已应用(前端演示)')
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 优先序数上移:优先序数减 1 */
|
|
||||||
handlePriorityUp() {
|
|
||||||
if (!this.currentCourse) {
|
|
||||||
this.$message.warning('请先在表格中选择一门课程')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (this.currentCourse.priority <= 1) {
|
|
||||||
this.$message.info('已是最高优先序数')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.currentCourse.priority -= 1
|
|
||||||
this.syncPropForm()
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 优先序数下移:优先序数加 1 */
|
|
||||||
handlePriorityDown() {
|
|
||||||
if (!this.currentCourse) {
|
|
||||||
this.$message.warning('请先在表格中选择一门课程')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.currentCourse.priority += 1
|
|
||||||
this.syncPropForm()
|
|
||||||
},
|
|
||||||
|
|
||||||
// ==================== 底部操作 ====================
|
|
||||||
handleConfirm() {
|
|
||||||
this.$emit('confirm')
|
|
||||||
this.dialogVisible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.peidang-dialog {
|
|
||||||
// ========== 自定义标题栏 ==========
|
|
||||||
::v-deep .el-dialog__header {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.peidang-titlebar {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
height: 40px;
|
|
||||||
padding: 0 14px;
|
|
||||||
background: linear-gradient(90deg, #0a246a 0%, #a6caf0 100%);
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
.title-icon {
|
|
||||||
font-size: 18px;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title-text {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #fff;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-dialog__body {
|
|
||||||
padding: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-dialog__footer {
|
|
||||||
padding: 8px 12px;
|
|
||||||
border-top: 1px solid #ebeef5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.peidang-footer {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.peidang-body {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 10px;
|
|
||||||
|
|
||||||
// ========== 上半部分:左右分栏 ==========
|
|
||||||
.upper {
|
|
||||||
display: flex;
|
|
||||||
gap: 10px;
|
|
||||||
|
|
||||||
// 左侧 75%:表格
|
|
||||||
.table-area {
|
|
||||||
flex: 3;
|
|
||||||
min-width: 0;
|
|
||||||
border: 1px solid #ebeef5;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 6px;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.peidang-table {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 右侧 25%:属性设置
|
|
||||||
.prop-area {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 240px;
|
|
||||||
border: 1px solid #ebeef5;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 10px 12px;
|
|
||||||
|
|
||||||
.prop-title {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #303133;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
padding-bottom: 6px;
|
|
||||||
border-bottom: 1px solid #ebeef5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prop-form {
|
|
||||||
.priority-field {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.el-button {
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.apply-btn {
|
|
||||||
width: 100%;
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 下半部分:配档显示区域 ==========
|
|
||||||
.gantt-area {
|
|
||||||
border: 1px solid #ebeef5;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 8px;
|
|
||||||
overflow: auto;
|
|
||||||
max-height: 320px;
|
|
||||||
|
|
||||||
.gantt-head,
|
|
||||||
.gantt-course,
|
|
||||||
.gantt-foot {
|
|
||||||
display: flex;
|
|
||||||
align-items: stretch;
|
|
||||||
min-width: 860px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gantt-label-col {
|
|
||||||
flex-shrink: 0;
|
|
||||||
width: 210px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.gantt-label {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #606266;
|
|
||||||
font-weight: 600;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.gantt-body {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gantt-row {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
.gantt-cell {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 34px;
|
|
||||||
height: 24px;
|
|
||||||
line-height: 24px;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 11px;
|
|
||||||
color: #303133;
|
|
||||||
border-right: 1px solid #ebeef5;
|
|
||||||
border-bottom: 1px solid #ebeef5;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 周刻度:顶部红色竖线
|
|
||||||
.week-cell {
|
|
||||||
font-weight: 600;
|
|
||||||
color: #f56c6c;
|
|
||||||
border-top: 2px solid #f56c6c;
|
|
||||||
background: #fff5f5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info-row .gantt-cell {
|
|
||||||
height: 20px;
|
|
||||||
line-height: 20px;
|
|
||||||
|
|
||||||
.sch {
|
|
||||||
color: #1e6fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rem {
|
|
||||||
color: #e6a23c;
|
|
||||||
margin-left: 2px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 月刻度虚线
|
|
||||||
.month-boundary {
|
|
||||||
border-left: 1px dashed #909399;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 课程条
|
|
||||||
.bar-cell {
|
|
||||||
height: 26px;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.bar-hours {
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bar-active {
|
|
||||||
&.bar-normal {
|
|
||||||
background: #409eff;
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
.bar-hours {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bar-continuous {
|
|
||||||
background: #f56c6c;
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
.bar-hours {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.month-cell {
|
|
||||||
height: 22px;
|
|
||||||
line-height: 22px;
|
|
||||||
|
|
||||||
.month-total {
|
|
||||||
font-size: 11px;
|
|
||||||
color: #606266;
|
|
||||||
font-weight: 600;
|
|
||||||
background: #f4f4f5;
|
|
||||||
border: 1px solid #dcdfe6;
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 0 4px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.gantt-course {
|
|
||||||
.gantt-label-col {
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.course-tag {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 1px;
|
|
||||||
padding: 2px 6px;
|
|
||||||
border-radius: 3px;
|
|
||||||
font-size: 11px;
|
|
||||||
|
|
||||||
&.tag-normal {
|
|
||||||
background: #ecf5ff;
|
|
||||||
border: 1px solid #a0cfff;
|
|
||||||
color: #337ecc;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.tag-continuous {
|
|
||||||
background: #fef0f0;
|
|
||||||
border: 1px solid #fbc4c4;
|
|
||||||
color: #d63031;
|
|
||||||
}
|
|
||||||
|
|
||||||
.course-name {
|
|
||||||
font-weight: 600;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.course-hours {
|
|
||||||
font-size: 10px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.gantt-foot {
|
|
||||||
.gantt-label-col {
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
Reference in New Issue
Block a user