教学任务书填报
This commit is contained in:
@@ -0,0 +1,502 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:visible="visible"
|
||||
:title="`教研室任务书填报${taskName ? ':' + taskName : ''}`"
|
||||
width="96%"
|
||||
top="4vh"
|
||||
:close-on-click-modal="false"
|
||||
@update:visible="val => $emit('update:visible', val)"
|
||||
@open="handleOpen"
|
||||
>
|
||||
<!-- ==================== 工具栏:合班 / 拆班 ==================== -->
|
||||
<div class="tb-toolbar">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
icon="el-icon-connection"
|
||||
:disabled="frozen || selection.length < 2"
|
||||
@click="handleMerge"
|
||||
>手动合班({{ selection.length }})</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
icon="el-icon-s-grid"
|
||||
:disabled="frozen || !selection.length"
|
||||
@click="handleMergeByPreset"
|
||||
>按预设合班({{ selection.length }})</el-button>
|
||||
<el-button
|
||||
type="warning"
|
||||
size="small"
|
||||
icon="el-icon-scissors"
|
||||
:disabled="frozen || !selection.length"
|
||||
@click="handleSplit"
|
||||
>拆班</el-button>
|
||||
<el-button size="small" icon="el-icon-refresh" @click="loadRows">刷新</el-button>
|
||||
<span v-if="frozen" class="tb-frozen-tip">教学任务未发布或已结束,当前只读</span>
|
||||
<span class="tb-tip">合班规则:科目、学时、课类型、成绩分制必须相同;同合班行同色连显</span>
|
||||
</div>
|
||||
|
||||
<!-- ==================== 任务书行表格 ==================== -->
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="rows"
|
||||
border
|
||||
stripe
|
||||
max-height="540"
|
||||
class="tb-table"
|
||||
@selection-change="val => selection = val"
|
||||
>
|
||||
<template slot="empty">
|
||||
<span>无数据!</span>
|
||||
</template>
|
||||
<el-table-column type="selection" width="42" align="center" :selectable="row => !frozen" />
|
||||
<el-table-column prop="kcmc" label="课程" min-width="150" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="xydmc" label="学员队" min-width="150" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="klx" label="课类型" width="80" align="center" />
|
||||
<el-table-column prop="xs" label="学时" width="60" align="center" />
|
||||
<el-table-column prop="zks" label="周课时" width="65" align="center" />
|
||||
<el-table-column prop="cjfz" label="成绩分制" width="80" align="center" />
|
||||
<el-table-column label="责任教员" width="110" align="center">
|
||||
<template slot-scope="{ row }">{{ row.jyxm || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="场地" width="130" align="center" show-overflow-tooltip>
|
||||
<template slot-scope="{ row }">{{ row.jsmc || row.jsbh || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="kcxh" label="课次" width="60" align="center" />
|
||||
<el-table-column label="合班" width="86" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<el-tag v-if="row.bz2 && row.bz2 !== 0" size="small" :color="groupColor(row.bz2)" class="tb-group-tag">
|
||||
组{{ row.bz2 }}
|
||||
</el-tag>
|
||||
<span v-else class="tb-unmerged">未合班</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="jysmc" label="教研室" width="120" align="center" show-overflow-tooltip />
|
||||
<el-table-column label="计划教员" width="100" align="center">
|
||||
<template slot-scope="{ row }">{{ row.jysjhjyxm || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="jysjhbz" label="排课建议" min-width="120" align="center" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="210" align="center" fixed="right">
|
||||
<template slot-scope="{ row }">
|
||||
<el-button type="text" size="small" :disabled="frozen" @click="openTeacher(row)">指定教员</el-button>
|
||||
<el-button type="text" size="small" :disabled="frozen" @click="openRoom(row)">指定场地</el-button>
|
||||
<el-button type="text" size="small" :disabled="frozen" @click="openFill(row)">填报</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div slot="footer">
|
||||
<el-button @click="$emit('update:visible', false)">关 闭</el-button>
|
||||
</div>
|
||||
|
||||
<!-- ==================== 指定教员子对话框 ==================== -->
|
||||
<el-dialog
|
||||
:visible.sync="teacherDialog.visible"
|
||||
title="指定责任教员"
|
||||
width="480px"
|
||||
append-to-body
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form label-width="110px">
|
||||
<el-form-item label="指定方式">
|
||||
<el-radio-group v-model="teacherDialog.mode" @change="loadTeacherOptions">
|
||||
<el-radio label="unit">责任单位教员</el-radio>
|
||||
<el-radio label="academy">全院教员</el-radio>
|
||||
<el-radio label="plan">应用教研室计划教员</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="teacherDialog.mode !== 'plan'" label="教员">
|
||||
<el-select
|
||||
v-model="teacherDialog.jybh"
|
||||
filterable
|
||||
placeholder="请选择教员"
|
||||
style="width: 100%"
|
||||
:loading="teacherDialog.loading"
|
||||
>
|
||||
<el-option
|
||||
v-for="t in teacherDialog.teachers"
|
||||
:key="t.jybh"
|
||||
:label="`${t.jyxm || t.jybh}${t.jysmc ? '(' + t.jysmc + ')' : ''}`"
|
||||
:value="t.jybh"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-else label="计划教员">
|
||||
<span>{{ teacherDialog.planTeacherName || '(该行没有教研室计划教员)' }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="teacherDialog.row && teacherDialog.row.bz2 && teacherDialog.row.bz2 !== 0" label="同步范围">
|
||||
<span class="tb-tip">该行已合班(组{{ teacherDialog.row.bz2 }}),保存后同组其它行同步</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer">
|
||||
<el-button @click="teacherDialog.visible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="saving" @click="submitTeacher">确定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- ==================== 指定场地子对话框 ==================== -->
|
||||
<el-dialog
|
||||
:visible.sync="roomDialog.visible"
|
||||
title="指定场地"
|
||||
width="480px"
|
||||
append-to-body
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form label-width="110px">
|
||||
<el-form-item label="场地类型">
|
||||
<el-radio-group v-model="roomDialog.useSpecial">
|
||||
<el-radio :label="true">班次专用教室</el-radio>
|
||||
<el-radio :label="false">其它教室</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="!roomDialog.useSpecial" label="教室">
|
||||
<el-select
|
||||
v-model="roomDialog.jsbh"
|
||||
filterable
|
||||
placeholder="请选择教室"
|
||||
style="width: 100%"
|
||||
:loading="roomDialog.loading"
|
||||
>
|
||||
<el-option
|
||||
v-for="c in roomDialog.classrooms"
|
||||
:key="c.jsbh || c.id"
|
||||
:label="c.jsmc"
|
||||
:value="c.jsbh || c.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="roomDialog.row && roomDialog.row.bz2 && roomDialog.row.bz2 !== 0" label="同步范围">
|
||||
<span class="tb-tip">该行已合班(组{{ roomDialog.row.bz2 }}),保存后同组其它行同步</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer">
|
||||
<el-button @click="roomDialog.visible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="saving" @click="submitRoom">确定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- ==================== 填报子对话框 ==================== -->
|
||||
<el-dialog
|
||||
:visible.sync="fillDialog.visible"
|
||||
title="教研室填报"
|
||||
width="520px"
|
||||
append-to-body
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form label-width="110px">
|
||||
<el-form-item label="课程 / 学员队">
|
||||
<span>{{ fillDialog.row ? `${fillDialog.row.kcmc} / ${fillDialog.row.xydmc}` : '' }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="计划教员">
|
||||
<el-select
|
||||
v-model="fillDialog.jysjhjybh"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择教研室计划教员"
|
||||
style="width: 100%"
|
||||
:loading="fillDialog.loading"
|
||||
>
|
||||
<el-option
|
||||
v-for="t in fillDialog.teachers"
|
||||
:key="t.jybh"
|
||||
:label="t.jyxm || t.jybh"
|
||||
:value="t.jybh"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="场地">
|
||||
<el-checkbox v-model="fillDialog.useSpecial" style="margin-right: 12px">班次专用教室</el-checkbox>
|
||||
<el-select
|
||||
v-if="!fillDialog.useSpecial"
|
||||
v-model="fillDialog.jsbh"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择教室"
|
||||
style="width: 260px"
|
||||
:loading="fillDialog.loading"
|
||||
>
|
||||
<el-option
|
||||
v-for="c in fillDialog.classrooms"
|
||||
:key="c.jsbh || c.id"
|
||||
:label="c.jsmc"
|
||||
:value="c.jsbh || c.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="排课建议">
|
||||
<el-input
|
||||
v-model="fillDialog.jysjhbz"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="填写排课建议(教研室计划备注)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer">
|
||||
<el-button @click="fillDialog.visible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="saving" @click="submitFill">保存</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 教研室任务书填报对话框(阶段 4)
|
||||
* 对接 /taskBookFill/*:列表(课程→责任教员→课次排序、合班分组号同色)、
|
||||
* 手动合班 / 按预设合班 / 拆班、责任教员三种指定、场地指定、填报字段。
|
||||
*/
|
||||
import {
|
||||
taskBookList,
|
||||
taskBookMerge,
|
||||
taskBookMergeByPreset,
|
||||
taskBookSplit,
|
||||
taskBookSetTeacher,
|
||||
taskBookSetRoom,
|
||||
taskBookFill
|
||||
} from '@/api/teachBusiness/taskBook'
|
||||
import { listTeacher } from '@/api/teachOffice/teacher'
|
||||
import { listClassroom } from '@/api/teachBusiness/classroom'
|
||||
|
||||
export default {
|
||||
name: 'TaskBookFillDialog',
|
||||
props: {
|
||||
visible: { type: Boolean, default: false },
|
||||
jxrwbh: { type: String, default: '' },
|
||||
taskName: { type: String, default: '' },
|
||||
/** 任务状态:非「已发布/已发布(旧值)」或已结束时只读 */
|
||||
taskStatus: { type: String, default: '' }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
saving: false,
|
||||
rows: [],
|
||||
selection: [],
|
||||
teacherDialog: {
|
||||
visible: false,
|
||||
mode: 'unit',
|
||||
jybh: '',
|
||||
teachers: [],
|
||||
loading: false,
|
||||
row: null
|
||||
},
|
||||
roomDialog: {
|
||||
visible: false,
|
||||
useSpecial: true,
|
||||
jsbh: '',
|
||||
classrooms: [],
|
||||
loading: false,
|
||||
row: null
|
||||
},
|
||||
fillDialog: {
|
||||
visible: false,
|
||||
jysjhjybh: '',
|
||||
jsbh: '',
|
||||
jysjhbz: '',
|
||||
useSpecial: false,
|
||||
teachers: [],
|
||||
classrooms: [],
|
||||
loading: false,
|
||||
row: null
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
frozen() {
|
||||
return this.taskStatus !== '发布' && this.taskStatus !== '已发布'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleOpen() {
|
||||
this.loadRows()
|
||||
},
|
||||
loadRows() {
|
||||
if (!this.jxrwbh) return
|
||||
this.loading = true
|
||||
taskBookList(this.jxrwbh)
|
||||
.then(res => {
|
||||
this.rows = res.data || []
|
||||
this.selection = []
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
/** 合班分组同色:按组号取色相 */
|
||||
groupColor(bz2) {
|
||||
if (!bz2) return ''
|
||||
const hue = (bz2 * 47) % 360
|
||||
return `hsl(${hue}, 65%, 82%)`
|
||||
},
|
||||
reload(after) {
|
||||
return Promise.resolve(after)
|
||||
.then(() => {
|
||||
this.$message.success('操作成功')
|
||||
this.loadRows()
|
||||
})
|
||||
.catch(err => {
|
||||
this.$message.error((err && err.message) || '操作失败')
|
||||
})
|
||||
},
|
||||
handleMerge() {
|
||||
const bhList = this.selection.map(r => r.bh)
|
||||
if (bhList.length < 2) {
|
||||
this.$message.warning('请至少选择两行进行合班')
|
||||
return
|
||||
}
|
||||
this.$confirm(`把选中的 ${bhList.length} 行合成一个班?`, '手动合班', { type: 'warning' })
|
||||
.then(() => this.reload(taskBookMerge(bhList).then(res => {
|
||||
this.$message.info(`已合入编组 ${res.data}`)
|
||||
})))
|
||||
.catch(() => {})
|
||||
},
|
||||
handleMergeByPreset() {
|
||||
const bhList = this.selection.map(r => r.bh)
|
||||
this.$confirm('按课程科目分组、组内按预设编班号合班?', '按预设合班', { type: 'warning' })
|
||||
.then(() => this.reload(taskBookMergeByPreset(bhList).then(res => {
|
||||
const groups = res.data || []
|
||||
this.$message.info(`已形成 ${groups.length} 个合班组`)
|
||||
})))
|
||||
.catch(() => {})
|
||||
},
|
||||
handleSplit() {
|
||||
const bhList = this.selection.map(r => r.bh)
|
||||
this.$confirm(`拆开选中的 ${bhList.length} 行(编组置 0)?`, '拆班', { type: 'warning' })
|
||||
.then(() => this.reload(taskBookSplit(bhList)))
|
||||
.catch(() => {})
|
||||
},
|
||||
// ---------- 指定教员 ----------
|
||||
openTeacher(row) {
|
||||
this.teacherDialog.row = row
|
||||
this.teacherDialog.mode = 'unit'
|
||||
this.teacherDialog.jybh = row.jybh || ''
|
||||
this.teacherDialog.visible = true
|
||||
this.loadTeacherOptions()
|
||||
},
|
||||
loadTeacherOptions() {
|
||||
const row = this.teacherDialog.row
|
||||
if (!row) return
|
||||
const params = this.teacherDialog.mode === 'unit' ? { jysdh: row.jysdh } : {}
|
||||
this.teacherDialog.loading = true
|
||||
listTeacher(params)
|
||||
.then(res => {
|
||||
this.teacherDialog.teachers = (res.data && (res.data.records || res.data.rows || res.data)) || []
|
||||
})
|
||||
.finally(() => {
|
||||
this.teacherDialog.loading = false
|
||||
})
|
||||
},
|
||||
submitTeacher() {
|
||||
const d = this.teacherDialog
|
||||
taskBookSetTeacher({ bh: d.row.bh, mode: d.mode, jybh: d.mode === 'plan' ? undefined : d.jybh })
|
||||
.then(res => {
|
||||
d.visible = false
|
||||
this.reload(Promise.resolve(res))
|
||||
})
|
||||
.catch(err => this.$message.error((err && err.message) || '保存失败'))
|
||||
},
|
||||
// ---------- 指定场地 ----------
|
||||
openRoom(row) {
|
||||
this.roomDialog.row = row
|
||||
this.roomDialog.useSpecial = true
|
||||
this.roomDialog.jsbh = ''
|
||||
this.roomDialog.visible = true
|
||||
if (!this.roomDialog.classrooms.length) {
|
||||
this.roomDialog.loading = true
|
||||
listClassroom({ pageNum: 1, pageSize: 200 })
|
||||
.then(res => {
|
||||
const data = res.data || {}
|
||||
this.roomDialog.classrooms = data.records || data.rows || data.list || []
|
||||
})
|
||||
.finally(() => {
|
||||
this.roomDialog.loading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
submitRoom() {
|
||||
const d = this.roomDialog
|
||||
taskBookSetRoom({ bh: d.row.bh, jsbh: d.jsbh, useSpecial: d.useSpecial })
|
||||
.then(res => {
|
||||
d.visible = false
|
||||
this.reload(Promise.resolve(res))
|
||||
})
|
||||
.catch(err => this.$message.error((err && err.message) || '保存失败'))
|
||||
},
|
||||
// ---------- 填报 ----------
|
||||
openFill(row) {
|
||||
this.fillDialog.row = row
|
||||
this.fillDialog.jysjhjybh = row.jysjhjybh || ''
|
||||
this.fillDialog.jsbh = row.jsbh || ''
|
||||
this.fillDialog.jysjhbz = row.jysjhbz || ''
|
||||
this.fillDialog.useSpecial = false
|
||||
this.fillDialog.visible = true
|
||||
this.fillDialog.loading = true
|
||||
Promise.all([
|
||||
listTeacher({ jysdh: row.jysdh }).catch(() => null),
|
||||
this.roomDialog.classrooms.length
|
||||
? Promise.resolve(null)
|
||||
: listClassroom({ pageNum: 1, pageSize: 200 }).catch(() => null)
|
||||
])
|
||||
.then(([tRes, cRes]) => {
|
||||
if (tRes) this.fillDialog.teachers = (tRes.data && (tRes.data.records || tRes.data.rows || tRes.data)) || []
|
||||
if (cRes) {
|
||||
const data = cRes.data || {}
|
||||
this.roomDialog.classrooms = data.records || data.rows || data.list || []
|
||||
}
|
||||
this.fillDialog.classrooms = this.roomDialog.classrooms
|
||||
})
|
||||
.finally(() => {
|
||||
this.fillDialog.loading = false
|
||||
})
|
||||
},
|
||||
submitFill() {
|
||||
const d = this.fillDialog
|
||||
const base = {
|
||||
bh: d.row.bh,
|
||||
jysjhjybh: d.jysjhjybh || '',
|
||||
jysjhbz: d.jysjhbz || ''
|
||||
}
|
||||
// 专用教室走 setRoom(useSpecial) 才能取到班次专用教室编号;其它教室随 fill 同步
|
||||
const call = d.useSpecial
|
||||
? taskBookFill(base).then(() => taskBookSetRoom({ bh: d.row.bh, jsbh: '', useSpecial: true }))
|
||||
: taskBookFill({ ...base, jsbh: d.jsbh || undefined })
|
||||
call
|
||||
.then(res => {
|
||||
d.visible = false
|
||||
this.reload(Promise.resolve(res))
|
||||
})
|
||||
.catch(err => this.$message.error((err && err.message) || '保存失败'))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tb-toolbar {
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
}
|
||||
.tb-tip {
|
||||
color: #909399;
|
||||
font-size: 12px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
.tb-frozen-tip {
|
||||
color: #e6a23c;
|
||||
font-size: 12px;
|
||||
margin-left: 8px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tb-group-tag {
|
||||
border: none;
|
||||
color: #303133;
|
||||
}
|
||||
.tb-unmerged {
|
||||
color: #c0c4cc;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user