| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- <template>
- <el-form ref="form" :model="formModel" :rules="facultyRules">
- <mx-table :prop-defines="facultyTableDefines" :rows="formModel.rows">
- <template #batch="{key, label, prop}">
- <el-popover :ref="key" trigger="click" width="520">
- <div class="fx-column">
- <div class="fx-row fx-cen-cen f16">批量设置</div>
- <el-button-group class="mt20">
- <el-button type="primary" size="mini" @click="handleCheckAll">全选</el-button>
- <el-button type="primary" size="mini" @click="handleCheckReverse">反选</el-button>
- </el-button-group>
- <el-checkbox-group multiple v-model="batchData.subjectIds" class="mt3">
- <el-checkbox v-for="(sub,i) in rows" :key="i" :label="sub.subjectId">{{ sub.subjectName }}
- </el-checkbox>
- </el-checkbox-group>
- <div class="fx-row fx-bet-cen mt20">
- <el-input-number v-model="batchData.inputValue" :min="0" style="width: 120px"></el-input-number>
- <div class="fx-row fx-end-cen fx-1">
- <el-button size="small" @click="handleBatchCancel(key)">取消</el-button>
- <el-button type="primary" size="small" @click="handleBatchConfirm(key)">批量设置</el-button>
- </div>
- </div>
- </div>
- <el-button slot="reference" type="text">
- <span class="f-fff">{{ label }}</span>
- <i class="el-icon-caret-bottom f-fff"></i>
- </el-button>
- </el-popover>
- </template>
- <template #input="{row, key, label, $index, prop}">
- <el-form-item :prop="`rows[${$index}].${key}`" :rules="facultyRules[key]"
- class="form-item-readonly form-item-inner-error">
- <el-input-number v-model="row[key]" :min="0" :disabled="!!prop.disabled || row==sum"
- @change="handleInputChanged(key, row)&&$emit('change')"
- style="width: 120px"></el-input-number>
- </el-form-item>
- </template>
- </mx-table>
- </el-form>
- </template>
- <script>
- export default {
- name: 'faculty-forms',
- props: {
- rows: {
- type: Array,
- default: () => []
- }
- },
- data() {
- return {
- sum: { subjectName: '合计' },
- batchData: {
- subjectIds: [],
- inputValue: 0
- }
- }
- },
- computed: {
- formModel() {
- // fields - use demo field trigger
- this.rows.forEach((row) => this.handleInputChanged('teacherCount', row, false))
- this.rows.forEach((row) => this.handleInputChanged('levelClassesCount', row, false))
- // summary
- this.calculateSummary()
- // rebuild
- return {
- rows: [...this.rows, this.sum]
- }
- },
- facultyTableDefines() {
- return {
- subjectName: {
- label: '科目'
- },
- classesCountPrev: {
- label: '原周课时数',
- slot: 'input',
- slotHeader: 'batch',
- minWidth: '130px'
- },
- teacherCount: {
- label: '单科老师数量',
- slot: 'input',
- slotHeader: 'batch',
- minWidth: '130px'
- },
- teacherClassesCount: {
- label: '老师周课时数',
- slot: 'input',
- slotHeader: 'batch',
- minWidth: '130px'
- },
- classesCount: {
- label: '单科总课时数',
- slot: 'input',
- minWidth: '130px',
- disabled: true
- },
- levelClassesCount: {
- label: '等级考课时数',
- slot: 'input',
- slotHeader: 'batch',
- minWidth: '130px'
- },
- qualifiedClassesCount: {
- label: '合格考课时数',
- slot: 'input',
- slotHeader: 'batch',
- minWidth: '130px'
- }
- }
- },
- facultyRules() {
- const excludeFiles = ['subjectName', 'classesCount']
- const commonValidator = (rule, value, callback) => {
- const arrField = rule.field.split('.')
- let index = arrField.first()
- index = index.slice(index.indexOf('[') + 1, -1) * 1
- const field = arrField.last()
- const faculty = this.formModel.rows[index]
- const required = faculty['isOffical']
- if (required && !(value > 0)) {
- const displayName = this.facultyTableDefines[field]?.label || key
- return callback(displayName + '须>0')
- }
- callback()
- }
- const rules = {}
- Object.keys(this.facultyTableDefines).forEach(key => {
- if (!excludeFiles.includes(key)) {
- rules[key] = { validator: commonValidator }
- }
- })
- return rules
- }
- },
- methods: {
- handleCheckAll() {
- this.batchData.subjectIds = this.rows.map(s => s.subjectId)
- },
- handleCheckReverse() {
- this.batchData.subjectIds = this.rows
- .filter(s => !this.batchData.subjectIds.includes(s.subjectId))
- .map(s => s.subjectId)
- },
- handleBatchCancel(key) {
- this.$refs[key].doClose()
- },
- handleBatchConfirm(key) {
- if (!this.batchData.subjectIds.length) {
- this.msgError('批量设置必须至少选中1个科目')
- return
- }
- const toSetVal = this.batchData.inputValue
- const toSetSubjects = this.batchData.subjectIds
- this.rows.filter(r => toSetSubjects.includes(r.subjectId))
- .forEach(row => {
- row[key] = toSetVal
- this.handleInputChanged(key, row, false)
- })
- this.calculateSummary()
- this.handleBatchCancel(key)
- this.$emit('change')
- },
- handleInputChanged(key, row, calcSum = true) {
- // auto calc
- const helpFields = ['teacherCount', 'teacherClassesCount']
- const linkedField = 'classesCount'
- if (helpFields.includes(key)) {
- row[linkedField] = row.teacherCount * row.teacherClassesCount
- }
- // auto copy
- const equalFields = ['levelClassesCount', 'qualifiedClassesCount']
- if (equalFields.includes(key) && row['isFixed']) {
- const otherKeys = equalFields.filter(k => k != key)
- otherKeys.forEach(k => row[k] = row[key])
- }
- // auto sum
- if (calcSum) this.calculateSummary()
- return true
- },
- calculateSummary() {
- const excludeFiles = ['subjectName']
- Object.keys(this.facultyTableDefines).forEach(key => {
- if (!excludeFiles.includes(key)) {
- this.sum[key] = this.rows.sum(r => r[key])
- }
- })
- },
- validate() {
- console.log('faculty-forms validate')
- return this.$refs.form.validate()
- }
- }
- }
- </script>
- <style scoped>
- /deep/ .form-item-inner-error .el-form-item__error {
- left: 2px;
- bottom: 2px;
- top: auto;
- z-index: 2;
- }
- /deep/ .el-table__body tr:last-child,
- /deep/ .el-table__body tr:last-child:hover > td {
- font-weight: 600;
- background-color: #FDEAE1;
- }
- </style>
|