一、先选开始时间
开始时间:今天之前的之间置灰
结束时间:开始时间之前的时间置灰
二、先选结束时间
结束时间:今天时间之前的时间置灰
开始时间: 今天时间之前的时间置灰,结束时间之后的时间置灰
<template>
<div class="app-container">
<!-- 表单 -->
<el-form ref="form" :model="form" :rules="rules" label-width="110px" :disabled="leftToolBar.isView" size="small">
<el-row>
<el-col :span="8">
<el-form-item label="编号" prop="code">
<el-input v-model="form.code" placeholder="编号自动生成" :disabled="true" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="姓名" prop="name_dictText">
<el-input v-model="form.name_dictText" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="部门" prop="departmentCode_dictText">
<el-input v-model="form.departmentCode_dictText" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row style="padding-left:110px;">
<!-- 出差行程 -->
<el-table v-loading="loading" :data="form.journeyList" @selection-change="handleSelectionChange" border stripe :max-height="tableHeight" highlight-current-row @row-click="handleCurrentChange"
@cell-mouse-enter="mousEnter" @cell-mouse-leave="mouseLeave" :row-class-name="tableRowClassName" ref="multipleTable" class="myTable mb20">
<el-table-column label="序号" type="index" align="center" width="55">
<template slot-scope="scope">
<span v-if="!scope.row.showBut">{{
scope.$index + 1
}}</span>
<div v-else>
<i class="el-icon-circle-plus-outline iadd" @click.stop="handleAdd(scope.row)" />
<i class="el-icon-remove-outline irem" @click.stop="handleDelete(scope.row)" />
</div>
</template>
</el-table-column>
<el-table-column label="交通工具" align="center" prop="transport" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
<el-select size="mini" v-model="scope.row.transport" placeholder="请选择交通工具" clearable style="width: 100%" v-show="scope.row.show">
<el-option v-for="dict in travelTransportOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
</el-select>
<span v-show="!scope.row.show">{{ scope.row.transport }}</span>
</template>
</el-table-column>
<el-table-column label="单程往返" align="center" prop="travelType" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
<el-select size="mini" v-model="scope.row.travelType" placeholder="请选择单程往返" clearable style="width: 100%" v-show="scope.row.show">
<el-option v-for="dict in travelTypeOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
</el-select>
<span v-show="!scope.row.show">{{ scope.row.travelType }}</span>
</template>
</el-table-column>
<el-table-column label="出发城市" align="center" prop="startCity" min-width="150" show-overflow-tooltip>
<template slot-scope="scope">
<span v-if="!scope.row.show">{{ scope.row.startCity }}</span>
<el-input v-else v-model="scope.row.startCity" size="mini" placeholder="请输入出发城市" style="width: 100%" />
</template>
</el-table-column>
<el-table-column label="目的城市" align="center" prop="destinationCity" min-width="150" show-overflow-tooltip>
<template slot-scope="scope">
<span v-if="!scope.row.show">{{ scope.row.destinationCity }}</span>
<el-input v-else v-model="scope.row.destinationCity" size="mini" placeholder="请输入目的城市" style="width: 100%" />
</template>
</el-table-column>
<el-table-column label="开始时间" align="center" prop="startTime" min-width="200" show-overflow-tooltip>
<template slot-scope="scope">
<el-form-item prop="startTime" v-show="scope.row.show">
<el-date-picker v-model="scope.row.startTime" type="date" format="yyyy 年 MM 月 dd 日" value-format="yyyy-MM-dd" placeholder="开始时间" size="mini" :picker-options="startTimeOptions"
@change="startTimeStatus(scope.row)" @focus="focusStartTime(scope.row)" />
<el-select v-model="scope.row.startDay" placeholder="请选择" @change="handleChangeStar($event,scope.row)" style="width:80px" size="mini">
<el-option label="上午" value="00:00:00" />
<el-option label="下午" value="12:00:00" />
</el-select>
</el-form-item>
<span v-show="!scope.row.show">{{ parseTime(scope.row.startTime, 'YYYY-MM-DD') }}</span>
</template>
</el-table-column>
<el-table-column label="结束时间" align="center" prop="endTime" min-width="200" show-overflow-tooltip>
<template slot-scope="scope">
<el-form-item prop="endTime" v-show="scope.row.show">
<el-date-picker v-model="scope.row.endTime" size="mini" type="date" format="yyyy 年 MM 月 dd 日" value-format="yyyy-MM-dd" placeholder="结束时间" :picker-options="endTimeOptions"
@change="endTimeStatus(scope.row)" @focus="focusEndTime(scope.row)" />
<el-select v-model="scope.row.endDay" placeholder="请选择" @change="handleChangeEnd($event,scope.row)" style="width:80px" size="mini">
<el-option label="上午" value="11:59:59" />
<el-option label="下午" value="23:59:59" />
</el-select>
</el-form-item>
<span v-show="!scope.row.show">{{ parseTime(scope.row.endTime, 'YYYY-MM-DD') }}</span>
</template>
</el-table-column>
<el-table-column label="天数" align="center" prop="day" min-width="50" show-overflow-tooltip>
<template slot-scope="scope">
<span>{{ scope.row.day }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" min-width="50">
<template slot-scope="scope">
<el-button plain size="mini" type="text" icon="el-icon-edit" @click="handleDetl(scope.row)" v-show="scope.row.id">查看明细
</el-button>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="出差天数" prop="travelDays">
<el-input v-model="form.travelDays" placeholder="出差天数自动计算" :disabled="true" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="预估费用" prop="travelCost">
<el-input v-model="form.travelCost" placeholder="请输入整数或小数(最多两位小数)" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<!-- 明细弹框 -->
<el-dialog :title="oaEmployeeTitle" :visible.sync="isDuration" width="1110px" :before-close="oaTravelDetlCancel" append-to-body v-dialogDrag>
<duration :journeyId="journeyId" :row="row" v-if="isDuration" ref="setDuration">
</duration>
</el-dialog>
</div>
</template>
<script>
import Format from '@/api/form/formRules'
import setEmployee from '@/views/oa/common/setEmployee.vue'
import duration from '@/views/oa/common/duration.vue'
export default {
name: 'OaTravelApplyForm',
components: { setEmployee, duration },
props: {
form: {
type: Object,
},
leftToolBar: {
type: Object,
},
},
data() {
return {
// 弹框类型
setEmployeeType: 0,
// 弹框对应输入框
currentType: null,
//弹框标题
oaEmployeeTitle: '',
//弹框启用标记
oaEmployeeOpen: false,
// 表单校验
rules: {
// code: [
// {
// required: true,
// message: '编号不能为空',
// trigger: 'blur',
// },
// {
// validator: Format.FormValidate.Form().checkRules, //validateInput
// trigger: 'blur',
// },
// ],
name: [
{
required: true,
message: '姓名不能为空',
trigger: 'blur',
},
],
// startTime: [
// {
// required: true,
// message: '开始时间不能为空',
// trigger: 'blur',
// },
// ],
// endTime: [
// {
// required: true,
// message: '结束时间不能为空',
// trigger: 'blur',
// },
// ],
// travelDays: [
// {
// required: true,
// message: '出差天数不能为空',
// trigger: 'blur',
// },
// {
// validator: this.decimal,
// trigger: 'blur',
// },
// ],
// travelLocation: [
// {
// required: true,
// message: '出差地点不能为空',
// trigger: 'blur',
// },
// ],
travelCost: [
{
required: true,
message: '预估费用不能为空',
trigger: 'blur',
},
{
validator: Format.FormValidate.Form().Amount,
trigger: 'blur',
},
],
},
// 行程
// journeyList: [],
//表格高度
tableHeight: 350,
travelTransportOptions: [], // 交通方式
travelTypeOptions: [], // 出差行程类型
row: {},
//选中数组
rows: [],
rowStr: '{}',
//是否是查看详情按钮
isView: false,
//限制起始时间不得超过今天
startTimeOptions: {
disabledDate: (time) => {
let endDateVal = this.overDate
if (endDateVal) {
return (
time.getTime() > new Date(endDateVal).getTime() ||
time.getTime() < Date.now() - 8.64e7
)
} else {
return time.getTime() < Date.now() - 8.64e7
}
},
},
//限制结束时间不得超过今天
endTimeOptions: {
disabledDate: (time) => {
let beginDateVal = this.createDate
if (beginDateVal) {
return time.getTime() <= new Date(beginDateVal).getTime() - 8.64e7
} else {
return time.getTime() < Date.now() - 8.64e7
}
},
},
// 行开始时间和结束时间的比较
overDate: null,
createDate: null,
isDuration: false, // 查看明细
journeyId: null,
row: {},
}
},
created() {
// 交通方式
this.getDicts('oa_travel_transport').then((response) => {
this.travelTransportOptions = response.data
})
// 出差行程类型
this.getDicts('oa_travel_type').then((response) => {
this.travelTypeOptions = response.data
})
this.getList()
},
mounted() {},
methods: {
// 字典翻译
travelTransportFormat(row, column) {
return this.selectDictLabel(this.travelTransportOptions, row.transport)
},
// 字典翻译
travelTypeFormat(row, column) {
return this.selectDictLabel(this.travelTypeOptions, row.travelType)
},
// 表格设置必填样式
tableStyle(obj) {
if (obj.columnIndex === 3) {
return 'star'
}
},
tableRowClassName({ row, rowIndex }) {
//把每一行的索引放进row
row.index = rowIndex
},
getList() {
let that = this
that.loading = false
// 生成空数据
if (!that.isView) {
let obj = {
transport: null, // 交通工具
travelType: null, // 单程/往返
startCity: null, // 出发城市
destinationCity: null, // 目的城市
startTime: null, // 开始时间
endTime: null, // 结束时间
startDay: '00:00:00',
endDay: '11:59:59',
days: null, // 时长
}
that.form.journeyList = that.completeArr(
that.form.journeyList,
JSON.parse(JSON.stringify(obj)),
5
)
that.form.journeyList = that.form.journeyList.map((row) => {
if (row.endTime != null && row.startTime != null) {
// 日期分割处理
row.startDay = row.startTime.substring('11', '19')
row.endDay = row.endTime.substring('11', '19')
row.day = that.diffTime(row.endTime, row.startTime)
// 交通工具和单程往返
that.getDicts('oa_travel_transport').then((response) => {
that.travelTransportOptions = response.data
if (row.transport != null) {
row.transport =
that.travelTransportOptions.find((s) => {
return s.dictValue == row.transport
}).dictLabel || ''
}
})
that.getDicts('oa_travel_type').then((response) => {
that.travelTypeOptions = response.data
if (row.transport != null) {
row.travelType =
that.travelTypeOptions.find((s) => {
return s.dictValue == row.travelType
}).dictLabel || ''
}
})
}
return row
})
console.log(that.form.journeyList)
}
},
//鼠标进入
mousEnter(row, column, cell, event) {
if (!this.isView) {
this.$set(row, 'showBut', true)
this.form.journeyList.splice(1, 0)
}
},
//鼠标离开
mouseLeave(row, column, cell, event) {
if (!this.isView) {
row.showBut = false
this.form.journeyList.splice(1, 0)
}
},
/** 新增行按钮操作 */
handleAdd(row) {
// console.log(row)
this.reset()
this.form.journeyList.splice(
row.index + 1,
0,
JSON.parse(JSON.stringify(this.form))
)
},
/** 删除行按钮操作 */
handleDelete(row) {
if (this.form.journeyList.length > 1) {
this.form.journeyList.splice(row.index, 1)
} else {
this.form.journeyList.splice(row.index, 1)
this.handleAdd(row)
}
},
//改变行状态
changeRow(row) {
if (this.isView) {
return
}
this.row.show = false
this.$set(row, 'show', true)
this.row = row
this.rowStr = JSON.stringify(row)
setTimeout(() => {
if (row.index + 1 == this.form.journeyList.length) {
this.handleAdd(row)
}
}, 10)
this.form.journeyList.splice(1, 0)
},
/** 表单重置 */
reset() {
this.form = {
id: null,
code: null,
name: this.$store.getters.name,
name_dictText: this.$store.getters.nickName,
departmentCode: this.$store.getters.deptId,
departmentCode_dictText: this.$store.getters.deptName,
job: this.$store.getters.posts.map((item) => item.postCode).join(','),
job_dictText: this.$store.getters.posts
.map((item) => item.postName)
.join(','),
travelBy: null,
travelBy_dictText: null,
travelColleagues: null,
travelColleagues_dictText: null,
startTime: null,
endTime: null,
travelDays: null,
travelLocation: null,
vehicle: null,
travelCost: null,
travelReason: null,
travelTrip: null,
travelPlan: null,
instruction: null,
remark: null,
oaTravelApplyStr0: null,
oaTravelApplyStr1: null,
oaTravelApplyStr2: null,
oaTravelApplyStr3: null,
oaTravelApplyStr4: null,
oaTravelApplyStr5: null,
oaTravelApplyStr6: null,
oaTravelApplyStr7: null,
oaTravelApplyStr8: null,
oaTravelApplyStr9: null,
oaTravelApplyStra: null,
oaTravelApplyStrb: null,
oaTravelApplyStrc: null,
oaTravelApplyStrd: null,
oaTravelApplyStre: null,
status: this.$global.status.UN_SUBMIT,
delFlag: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
moduleId: '2370',
corpid: this.$store.getters.corpid,
}
this.resetForm('form')
},
// 多选
handleSelectionChange(val) {
this.rows = val
},
/** 单击行选中 */
handleCurrentChange(row) {
this.$refs.multipleTable.doLayout()
// var condition = row.hasOwnProperty('uuid')
// ? row.uuid == this.row.uuid
// : row.id == this.row.id
// if (!condition) {
this.changeRow(row)
// }
},
// ------------------------------------------
// 选择员工回执
setEmployeeCallback(selection) {
if (this.currentType === 0) {
// 参与人
this.form.travelBy = selection.employeeNumber
this.form.travelBy_dictText = selection.name
this.oaEmployeeOpen = false
} else if (this.currentType === 1) {
// 计划共享至
let codes = selection.map((item) => item.employeeNumber).join(',') // 数组分割成字符串
let names = selection.map((item) => item.name).join(',')
this.form.travelColleagues = codes
this.form.travelColleagues_dictText = names
this.oaEmployeeOpen = false
}
},
// 员工弹框取消事件
oaEmployeeCancel() {
this.oaEmployeeOpen = false
},
// 员工弹框确认
setOaEmployee() {
this.$refs.setEmployee.setEmployeeCallback()
},
// 选择员工事件
setEmployeeClick(type) {
this.$refs.travelByNameLose.blur()
this.$refs.travelColleaguesNameLose.blur()
this.currentType = type
if (type === 0) {
this.oaEmployeeTitle = '选择安排出差人'
this.setEmployeeType = 0
} else if (type === 1) {
this.oaEmployeeTitle = '选择出差同行人'
this.setEmployeeType = 1
}
this.oaEmployeeOpen = true
},
//正数 (包括小数)
decimal(rule, value, callback) {
if (value === undefined || value === null || value === '') {
callback()
}
const re = /^[+]{0,1}(\d+)$|^[+]{0,1}(\d+\.\d+)$/
if (!re.test(value)) {
callback(new Error('请输入非负数的整数或小数'))
} else {
if (value > 100000) {
callback(new Error('数值过大,请重新输入'))
}
callback()
}
},
// --------------------------------------
// 时间开始选择器
startTimeStatus(row) {
this.overDate = row.endTime
this.createDate = row.startTime
this.getRowDate(row)
},
//获取焦点后,开始/完成时间为当前行的开始/完成时间
focusStartTime(row) {
this.overDate = row.endTime
this.createDate = row.startTime
this.getRowDate(row)
},
// 时间结束选择器
endTimeStatus(row) {
this.overDate = row.endTime
this.createDate = row.startTime
this.getRowDate(row)
},
//获取焦点后,开始/完成时间为当前行的开始/完成时间
focusEndTime(row) {
this.overDate = row.endTime
this.createDate = row.startTime
this.getRowDate(row)
},
// 开始时间半天
handleChangeStar(e, row) {
row.startDay = e
this.getRowDate(row)
},
// 结束时间半天
handleChangeEnd(e, row) {
row.endDay = e
this.getRowDate(row)
},
// 时间计算
getRowDate(row) {
if (row.endTime != null && row.startTime != null) {
if (row.endTime.length < 10) {
row.endTime = row.endTime + ' ' + row.endDay
}
if (row.startTime.length < 10) {
row.startTime = row.startTime + ' ' + row.startDay
}
row.day = this.diffTime(row.endTime, row.startTime)
let count = 0
this.form.journeyList.map((s) => {
count += s.day || 0
})
console.log(count)
this.form.travelDays = count
}
},
// 时间计算
diffTime(date1, date2) {
var date3 = new Date(date1).getTime() - new Date(date2).getTime() //时间差的毫秒数
var subMinutes = Math.floor(date3 / (60 * 1000)) //获取总共的分钟差
//计算出相差天数
var days = Math.floor(date3 / (24 * 3600 * 1000))
//计算出小时数
var leave1 = date3 % (24 * 3600 * 1000) //计算天数后剩余的毫秒数
var hours = Math.floor(leave1 / (3600 * 1000))
//计算相差分钟数
var leave2 = leave1 % (3600 * 1000) //计算小时数后剩余的毫秒数
var minutes = Math.floor(leave2 / (60 * 1000))
//计算相差秒数
var leave3 = leave2 % (60 * 1000) //计算分钟数后剩余的毫秒数
var seconds = Math.round(leave3 / 1000)
console.log(
' 相差 ' +
days +
'天 ' +
hours +
'小时 ' +
minutes +
' 分钟' +
seconds +
' 秒'
)
let returnDay = 0
// 0.5天
if (hours < 12) {
returnDay = days + 0.5
} else {
returnDay = days + 1
}
console.log(returnDay)
return returnDay
},
// 查看明细
handleDetl(row) {
this.isDuration = true
this.oaEmployeeTitle = '请假明细'
this.journeyId = row.id
this.row = row
},
// 取消
oaTravelDetlCancel() {
this.isDuration = false
},
},
}
</script>
<style scoped lang="scss">
.myTable {
::v-deep .el-date-editor.el-input,
::v-deep .el-date-editor--date .el-input__inner {
width: 180px;
}
::v-deep .el-form-item__content {
margin-left: 0 !important;
}
}
</style>