Skip to content

Instantly share code, notes, and snippets.

@wisetc
Created October 8, 2017 01:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wisetc/7c5e38940332161eed04c6474430de02 to your computer and use it in GitHub Desktop.
Save wisetc/7c5e38940332161eed04c6474430de02 to your computer and use it in GitHub Desktop.
某年某月的工作排班信息表
<template lang="pug">
#date-grid
table.date-grid
thead
th 班次\日期
th(v-for="num in colNum" :key="num.$index") {{ num }}
tbody
tr(v-for="(classTime, rowIndex) in classTimeList" :key="rowIndex")
th {{ classTime.name }}
template(v-for="(cell, colIndex) in cells[rowIndex]")
td(v-if="new Date(year, month-1, colIndex+2)>new Date()" :class="{'date-grid__td--highlight': cell.highlight}"
@click="handleClick(cell, colIndex, rowIndex)").date-grid__td--past.m-td {{ mapClassGroup[cell.groupCode] }}
.m-td__ctrl(v-if="cell.highlight")
button.m-td__btn(@click.stop="handleClose(cell, colIndex, rowIndex)")
i.el-icon-close
.md-td__title {{ getCellDate(cell, colIndex, rowIndex) }}
el-select(v-model='form.code' clearable style="width:100%;" size="small"
@change="handleChange(cell, colIndex, rowIndex)")
el-option(v-for="(o, index) in classGroups" :key="index" :label="o.name" :value="o.code")
td(v-else) {{ mapClassGroup[cell.groupCode] }}
el-dialog(:close-on-click-modal='false', size="tiny" title='编辑', :visible.sync='dialog.visible')
el-form(:model='form', ref='form')
el-form-item(label='班次名称', :label-width='dialog.labelWidth', prop='code')
el-select(v-model='form.code' clearable style="width:100%;")
el-option(v-for="(o, index) in classGroups" :key="index" :label="o.name" :value="o.code")
.dialog-footer(slot='footer')
el-button(@click='dialog.visible = false') 取 消
el-button(type='primary', @click='handleSave') 保 存
</template>
<script>
import { listGroupStandard, listClassTime, listClassGroup, updateGroupStandard } from '@/xhr'
export default {
props: {
year: { required: true, type: Number },
month: { required: true, type: Number },
edit: { type: Boolean, default: true }
},
data() {
return {
classTimeList: [],
markList: [],
cells: [],
dialog: {
visible: false,
labelWidth: '70px'
},
form: { code: null },
classGroups: [],
currentCord: null
}
},
computed: {
colNum() {
// Month is 1 based
let { year, month } = this;
let lastMonthLastDay = new Date(year, month, 0);
return lastMonthLastDay.getDate();
},
mapClassGroup() {
return this.classGroups.reduce((x, y) => (
{ ...x, [y.code]: y.name }
), {});
}
},
watch: {
year() {
this.created();
},
month() {
this.created();
}
},
created() {
this.created();
listClassGroup({pageSize: 99999}).then(({data}) => {
this.classGroups = data.data.data
});
},
methods: {
getCellDate(cell, colIndex, rowIndex) {
let { year, month } = this;
let day = colIndex + 1;
let classTime = this.classTimeList[rowIndex].name;
day = day < 10 ? '0' + day : day;
return `${year}-${month}-${day} ${classTime}`
},
localSaveCell() {
let { x, y } = this.currentCord;
this.cells[y][x].groupCode = this.form.code;
this.dialog.visible = false;
},
handleChange(cell, colIndex, rowIndex) {
this.handleSave();
this.handleClose(cell, colIndex, rowIndex);
},
handleClose(cell, colIndex, rowIndex) {
cell.highlight = false;
},
handleSave() {
let { year, month } = this;
let _data = {
classTimeCode: this.classTimeList[this.currentCord.y].code,
groupCode: this.form.code,
// id: null,
workDate: new Date(year, month-1, this.currentCord.x+2).toJSON().slice(0,10) + ' 00:00:00'
}
updateGroupStandard({data: JSON.stringify(_data)}).then(({data}) => {
if (data.code === 1) {
this.localSaveCell();
this.$message.success('保存成功!');
} else {
this.$oops(data.msg, 'update');
}
});
},
handleClick(cell, colIndex, rowIndex) {
this.form.code = cell.groupCode;
this.currentCord = {
x: colIndex,
y: rowIndex
};
this.cells = this.cells.map((array, _rowIndex) =>
array.map((_cell, _colIndex) =>
_colIndex === colIndex && _rowIndex === rowIndex ? ({ ..._cell, highlight: true }) : ({ ..._cell, highlight: false })
)
);return;debugger
this.dialog.visible = true;
},
created() {
this.fetchClassTimeList().then(classTimeList => {
this.classTimeList = classTimeList;
this.fetchMarkList().then(markList => {
this.markList = markList;
this.loadMarkList();
});
});
},
fetchClassTimeList() {
return new Promise((resolve, reject) => {
listClassTime().then(({data}) => {
resolve(data.data.data);
});
});
},
loadMarkList() {
this.cells = this.classTimeList.map((row, rowIndex) =>
Array(this.colNum).fill(null).map((col, colIndex) => this.markCell(colIndex, rowIndex))
)
},
markCell(colIndex, rowIndex) {
let cell = this.markList.find(mark => mark.cord.x === colIndex && mark.cord.y === rowIndex);
return cell ? cell : {}
},
convertToMark(item) {
let { workDate } = item;
let date = new Date(workDate);
let month = date.getMonth(), day = date.getDate();
if (month !== this.month - 1) {
return null;
}
let cord = {};
cord.x = day - 1;
cord.y = this.classTimeList.findIndex(time => time.code === item.classTimeCode);
return { ...item, cord }
},
fetchMarkList() {
return new Promise((resolve, rejct) => {
let { year, month } = this;
listGroupStandard({ pageSize: 99999, year, month }).then(({data}) => {
resolve(data.data.data.map(item => this.convertToMark(item)).filter(mark => mark));
});
})
}
}
}
</script>
<style lang="scss">
.date-grid {
background: #eee;
text-align: center;
border: 1px solid #ccc;
border-collapse: collapse;
th, td {
min-width: 32px;
height: 20px;
border: 1px solid #ccc;
font-size: 14px;
font-weight: normal;
padding: 4px;
}
th {
background: #F5F5F5;
}
td {
font-size: 12px;
}
}
.date-grid__td--past {
background-color: #fff;
cursor: pointer;
}
.date-grid__td--highlight {
background: #80DEEA;
}
.m-td {
position: relative;
}
.m-td__ctrl {
cursor: auto;
background: rgba(100, 100, 100, .66);
width: 150px;
height: 60px;
position: absolute;
z-index: 9;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
display: block;
padding: 8px 4px 4px;
}
.md-td__title {
color: #eee;
font-size: 14px;
margin-bottom: 8px;
}
.m-td__btn {
color: #e8e8dc;
position: absolute;
right: -9px;
top: -9px;
width: 18px;
height: 18px;
padding: 2px;
border-radius: 50%;
font-size: 8px;
background: #f44336;
box-sizing: border-box;
border: none;
outline: none;
cursor: pointer;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment