hn_ldlz/ldlz-H5/pages/qj/index.vue

803 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<page-meta :page-font-size="$store.state.vuex_fontsize+'px'" :root-font-size="$store.state.vuex_fontsize+'px'"></page-meta>
<view>
<view class="qj-box">
<view class="uni-padding-wrap uni-common-mt">
<uni-segmented-control :current="current" :values="items" style-type="text" @clickItem="onClickItem"
activeColor="#00b27b" />
</view>
</view>
<view class="qjtx" v-if="current === 0">
<u--form labelPosition="left" :model="leaveInfo" ref="form1" :rules="rules">
<u-form-item label="请假类型" prop="leaveTypeName" borderBottom @click="showType = true; hideKeyboard()" ref="item1"
labelWidth="100">
<u--input @click="showType = true; hideKeyboard()" v-model="leaveInfo.leaveTypeName"
placeholder="请选择请假类型"></u--input>
<u-icon slot="right" name="arrow-right"></u-icon>
</u-form-item>
<u-form-item label="请假日期" prop="startEndTime" labelWidth="100" borderBottom
@click="showCalendar = true; hideKeyboard()">
<u--input v-model="leaveInfo.startEndTime" @click="showType = true; hideKeyboard()"
placeholder="请选择请假日期"></u--input>
<u-icon slot="right" name="arrow-right"></u-icon>
</u-form-item>
<u-form-item label="请假事由" prop="reason" borderBottom ref="item3" labelWidth="100">
<u--textarea placeholder="根据xx安排,参加xx" v-model="leaveInfo.reason" count></u--textarea>
</u-form-item>
<u-form-item label="请假时长" prop="leaveDays" borderBottom labelWidth="100">
<u--input v-model="leaveInfo.leaveDays" placeholder="0" disabled></u--input>
</u-form-item>
<u-form-item label="请假前需履职天数" prop="lzDaysBeforeLeave" borderBottom labelWidth="100">
<u--input v-model="leaveInfo.lzDaysBeforeLeave" placeholder="0" disabled></u--input>
</u-form-item>
<u-form-item label="请假后需履职天数" prop="lzDaysAfterLeave" borderBottom labelWidth="100">
<u--input v-model="leaveInfo.lzDaysAfterLeave" placeholder="0" disabled></u--input>
</u-form-item>
<u-form-item label="审批人" prop="approverName" borderBottom @click="showApprover = true; hideKeyboard()"
ref="item1" labelWidth="100">
<u--input @click="showApprover = true; hideKeyboard()" v-model="leaveInfo.approverName"
placeholder="请选择审批人"></u--input>
<u-icon slot="right" name="arrow-right"></u-icon>
</u-form-item>
<u-form-item label="上传附件" borderBottom labelWidth="100">
<u-upload accept="file" :previewFullImage="false" :fileList="fileInfo" @afterRead="afterRead"
@delete="deletePic" multiple :maxCount="9">
</u-upload>
</u-form-item>
</u--form>
<u-button type="primary" text="提交请假" customStyle="margin-top: 50px" @click="submit"
style="margin: 30px auto; width: 50%;background-color:#00b27b;border-color:#00b27b;"></u-button>
<!-- <u-button type="error" text="重置" customStyle="margin-top: 10px" @click="reset"></u-button> -->
<u-action-sheet :show="showType" :actions="actions" title="请选择类型" @close="showType = false" @select="typeSelect">
</u-action-sheet>
<u-action-sheet :show="showApprover" :actions="actionsApprover" title="请选择审批人" @close="showApprover = false"
@select="approverSelect">
</u-action-sheet>
<u-calendar :show="showCalendar" :minDate="minDate" :allowSameDay="true" mode="range" @confirm="calendarConfirm"
@close="calendarClose" startText="起" endText="止" confirmDisabledText="请选择结束日期"
:formatter="formatter"></u-calendar>
</view>
<view class="qjjl" v-if="current === 1">
<view style="width: 100%;margin-top: 10px;display: flex;justify-content: space-around;">
<picker mode="selector" :range="years" @change="onYearChange" style="width: 49%;">
<view class="picker" style="width: 100%;">
<view>
{{selectedYear}}
</view>
<u-icon name="arrow-down"></u-icon>
</view>
</picker>
<picker mode="selector" :range="months" @change="onMonthChange" style="width: 49%;">
<view class="picker" style="width: 100%;">
<view>
{{selectedMonth}}
</view>
<u-icon name="arrow-down"></u-icon>
</view>
</picker>
</view>
<view class="u-page">
<u-list @scrolltolower="scrolltolower">
<u-list-item v-for="(item, index) in leaveList" :key="index">
<view class="leave-one">
<view class="leave-one-top">
<view style="display: flex;width: 65%;">
<u-icon name="account-fill" size="22" color="#00b27b"></u-icon>
<view class="top-left">{{item.nickName}}的请假</view>
</view>
<view class="top-right">{{item.createTime.substr(0,10)}}</view>
</view>
<view class="leave-one-content">
<view>请假类型:{{item.leaveTypeName}}</view>
<view style="display: flex;justify-content: space-between;">
<view style="display: flex;">
<u-icon name="calendar-fill" size="18" color="#333333"></u-icon>
<view>{{item.startTime}}~{{item.endTime}}</view>
</view>
<view style="color: #666;">{{item.leaveCnt}}天</view>
</view>
<view style="display: flex;justify-content: space-between;" v-if="item.status==0">
<view style="color:#5AD8A6;display: flex;">
<u-icon v-if="item.approverStatus==2" name="close-circle" size="18" color="#ff5500"></u-icon>
<u-icon v-else name="checkmark-circle" size="18" color="#5AD8A6"></u-icon>
<view v-if="item.approverStatus==2" style="color:#ff5500;">{{item.statusName}}</view>
<view v-else>{{item.statusName}}</view>
</view>
<view style="display: flex;">
<view class="btns" v-if="isShow(item.startTime)" @click="cancelLeave(item)">撤销
</view>
<view class="btns" v-else @click="js(item)">结束</view>
<view class="btns" v-if="isShow(item.startTime)" @click="editLeave(item)">修改
</view>
</view>
</view>
<view v-else>
<view style="color: #aaa;display: flex;">
<u-icon name="checkmark-circle" size="14" color="#aaa"></u-icon>
<view>{{item.statusName}}</view>
</view>
</view>
</view>
</view>
</u-list-item>
</u-list>
</view>
</view>
<view class="qjjl" v-if="current === 2">
<view style="width: 100%;margin-top: 10px;display: flex;justify-content: space-around;">
<picker mode="selector" :range="years" @change="onYearChange" style="width: 49%;">
<view class="picker" style="width: 100%;">
<view>
{{selectedYear}}
</view>
<u-icon name="arrow-down"></u-icon>
</view>
</picker>
<picker mode="selector" :range="months" @change="onMonthChange" style="width: 49%;">
<view class="picker" style="width: 100%;">
<view>
{{selectedMonth}}
</view>
<u-icon name="arrow-down"></u-icon>
</view>
</picker>
</view>
<view class="u-page">
<u-list @scrolltolower="scrolltolower">
<u-list-item v-for="(item, index) in leaveList" :key="index">
<view class="leave-one">
<view class="leave-one-top">
<view style="display: flex;width: 65%;">
<u-icon name="account-fill" size="22" color="#00b27b"></u-icon>
<view class="top-left">{{item.nickName}}的请假</view>
</view>
<view class="top-right">{{item.createTime.substr(0,10)}}</view>
</view>
<view class="leave-one-content">
<view>请假类型{{item.leaveTypeName}}</view>
<view style="display: flex;justify-content: space-between;">
<view style="display: flex;">
<u-icon name="calendar-fill" size="18" color="#333333"></u-icon>
<view>{{item.startTime}}~{{item.endTime}}</view>
</view>
<view style="color: #666;">{{item.leaveCnt}}</view>
</view>
<view style="display: flex;justify-content: space-between;" v-if="item.status==0">
<view style="color:#5AD8A6;display: flex;">
<u-icon v-if="item.approverStatus==2" name="close-circle" size="18" color="#ff5500"></u-icon>
<u-icon v-else name="checkmark-circle" size="18" color="#5AD8A6"></u-icon>
<view v-if="item.approverStatus==2" style="color:#ff5500;">{{item.statusName}}</view>
<view v-else>{{item.statusName}}</view>
</view>
<view style="display: flex;">
<view class="btns" v-if="item.approverStatus==0" @click="approveLeave(item,1)">同意
</view>
<view class="btns" style="background-color: #ff5500;" v-if="item.approverStatus==0"
@click="approveLeave(item,2)">拒绝
</view>
</view>
</view>
<view v-else>
<view style="color: #aaa;display: flex;">
<u-icon name="checkmark-circle" size="14" color="#aaa"></u-icon>
<view>{{item.statusName}}</view>
</view>
</view>
</view>
</view>
</u-list-item>
</u-list>
</view>
</view>
</view>
</template>
<script>
import {
baseUrl
} from '../../config.js'
import {
getToken
} from '@/utils/auth'
import {
getLeaveTypeList,
getUserLdlzDetail,
leaveLogList,
addLeave,
editLeave,
cancelLeave,
endLeaveInfo,
endLeave,
getApproverList,
approveLeave
} from '@/api/leave.js'
export default {
data() {
const d = new Date()
const year = d.getFullYear()
let month = d.getMonth() + 1
month = month < 10 ? `0${month}` : month
return {
selectedYear: new Date().getFullYear() + '年', // 默认选中的年份
years: [], // 年份数组
selectedMonth: '全部月', // 默认选中的年份
months: ["全部月"], // 年份数组
items: ['请假填写', '请假记录', '请假审批'],
current: 1,
disabled1: false,
showCalendar: false,
minDate: `${year}-${month}-01`,
leaveInfo: {
leaveTypeName: "",
startEndTime: "",
reason: "",
leaveDays: "",
lzDaysBeforeLeave: "",
lzDaysAfterLeave: "",
startTime: "",
endTime: "",
approverId: "",
approverName: ""
},
showType: false,
actions: [],
rules: {
leaveTypeName: {
type: 'string',
min: 2,
required: true,
message: '请选择请假类型',
trigger: ['change']
},
startEndTime: {
type: 'string',
min: 2,
required: true,
message: '请选择请假日期',
trigger: ['change']
},
reason: {
type: 'string',
min: 2,
required: true,
message: '请选择请假日期',
trigger: ['change']
},
approverName: {
type: 'string',
// min: 2,
required: true,
message: '请选择审批人',
trigger: ['change']
},
},
leaveList: [],
pageNum: 1,
total: 0,
// 附件
fileInfo: [],
showApprover: false,
actionsApprover: [],
leaveApprover: [],
}
},
onLoad(option) {
this.current = parseInt(option.current)
this.getLeaveTypeList();
this.getApproverList();
this.leaveLogList();
// 初始化年份数组
for (let i = new Date().getFullYear(); i >= 2010; i--) {
this.years.push(i + '年');
}
// 初始化月份数组
for (let i = 1; i < 13; i++) {
this.months.push(i + '月');
}
},
methods: {
isShow(startTime) {
const date = new Date(startTime);
const today = new Date();
console.log(date.getTime() > today.getTime());
if (date.getTime() > today.getTime()) {
return true;
} else {
return false
}
},
onYearChange(e) {
// 选中年份变更时触发
this.selectedYear = this.years[e.detail.value];
this.pageNum = 1
this.leaveList = []
this.leaveLogList()
},
onMonthChange(e) {
// 选中年份变更时触发
this.selectedMonth = this.months[e.detail.value];
this.pageNum = 1
this.leaveList = []
this.leaveLogList()
},
scrolltolower() {
if (this.total > this.pageNum * 10) {
this.pageNum++
this.leaveLogList()
}
},
//请假记录
leaveLogList() {
var params = {}
params.pageNum = this.pageNum
if (this.selectedMonth == '全部月') {
params.startTime = this.selectedYear.replace("年", "-01-01")
params.endTime = this.selectedYear.replace("年", "-12-31")
} else {
params.startTime = this.selectedYear.replace("年", "-") + this.selectedMonth.replace("月", "-01")
params.endTime = this.selectedYear.replace("年", "-") + this.selectedMonth.replace("月", "-31")
}
if (this.current == 1) {
params.userId = this.$store.getters.userId;
} else if (this.current == 2) {
params.approverId = this.$store.getters.userId;
}
leaveLogList(params).then(res => {
this.total = res.total
console.log(res)
res.rows.forEach(e => {
this.leaveList.push(e)
})
})
},
//查询请假类型
getLeaveTypeList() {
this.actions = []
getLeaveTypeList().then(res => {
res.rows.forEach(e => {
this.actions.push({
name: e.dictLabel,
id: e.dictCode
})
})
})
},
//查询请假类型
getApproverList() {
this.actionsApprover = []
getApproverList().then(res => {
res.data.forEach(e => {
this.actionsApprover.push({
name: e.nickName,
id: e.userId
})
})
})
},
//获取需要履职的天数
getUserLdlzDetail(params) {
getUserLdlzDetail(params).then(res => {
if (res.code == 200) {
// var num = 0
// Object.keys(res.data).forEach(function(key) {
// var value = res.data[key];
// if (value.xclz_num) {
// console.log(value)
// // 现场履职+班组履职
// num += parseInt(value.xclz_num) + parseInt(value.bzlz_num)
// }
// });
// 后端接口获取数据 24.5.28
this.$set(this.leaveInfo, 'leaveDays', res.data.leaveDays)
this.$set(this.leaveInfo, 'lzDaysBeforeLeave', res.data.lzDaysBeforeLeave)
this.$set(this.leaveInfo, 'lzDaysAfterLeave', res.data.lzDaysAfterLeave)
// this.leaveInfo.lzDaysBeforeLeave = num
//计算请假后需要履职的天数
// this.leaveInfo.lzDaysAfterLeave = parseInt(this.leaveInfo.lzDaysBeforeLeave) - parseInt(this
// .leaveInfo.leaveDays)
// if (this.leaveInfo.lzDaysAfterLeave < 0) {
// this.leaveInfo.lzDaysAfterLeave = 0
// }
} else {
uni.$u.toast(res.msg)
}
})
},
onClickItem(e) {
if (this.current !== e.currentIndex) {
this.current = e.currentIndex
}
if (this.current == 1) {
this.pageNum = 1
this.leaveList = []
this.leaveLogList()
} else if (this.current == 2) {
this.pageNum = 1
this.leaveList = []
this.leaveLogList()
} else {
this.leaveInfo = {
leaveTypeName: "",
startEndTime: "",
reason: "",
leaveDays: "",
lzDaysBeforeLeave: "",
lzDaysAfterLeave: "",
startTime: "",
endTime: "",
approverId: "",
approverName: ""
}
this.fileInfo = [];
}
},
typeSelect(e) {
console.log(e)
this.leaveInfo.leaveTypeId = e.id
this.leaveInfo.leaveTypeName = e.name
},
approverSelect(e) {
console.log(e)
this.leaveInfo.approverId = e.id
this.leaveInfo.approverName = e.name
},
formatter(day) {
const d = new Date()
let month = d.getMonth() + 1
const date = d.getDate()
return day
},
calendarConfirm(e) {
this.showCalendar = false
this.leaveInfo.startEndTime = `${e[0]} / ${e[e.length - 1]}`
this.leaveInfo.startTime = this.leaveInfo.startEndTime.split(" / ")[0]
this.leaveInfo.endTime = this.leaveInfo.startEndTime.split(" / ")[1]
// //计算请假天数
// this.getDaysBetweenDates(this.leaveInfo.startTime,this.leaveInfo.endTime)
//获取请假前需要履职天数
this.getUserLdlzDetail({
userId: this.$store.state.user.userId,
startDate: this.leaveInfo.startTime,
endDate: this.leaveInfo.endTime
})
this.$refs.form1.validateField('startEndTime')
},
calendarClose() {
this.showCalendar = false
this.$refs.form1.validateField('startEndTime')
},
// getDaysBetweenDates(date1, date2) {
// const oneDay = 24 * 60 * 60 * 1000; // 一天的毫秒数
// const firstDate = new Date(date1);
// const secondDate = new Date(date2);
// const diffDays = Math.round(Math.abs((firstDate - secondDate) / oneDay))+1;
// this.leaveInfo.leaveDays=diffDays
// },
submit() {
// 如果有错误会在catch中返回报错信息数组校验通过则在then中返回true
console.log(this.leaveInfo)
this.$refs.form1.validate().then(res => {
this.leaveInfo.fileInfo = JSON.stringify(this.fileInfo)
if (this.leaveInfo.id) {
editLeave(this.leaveInfo).then(res => {
if (res.code == 200) {
uni.$u.toast('修改成功')
setTimeout(() => {
this.onClickItem({
currentIndex: 1
})
}, 1000)
}
})
} else {
addLeave(this.leaveInfo).then(res => {
console.log(res)
if (res.code == 200) {
uni.$u.toast('请假成功')
setTimeout(() => {
this.onClickItem({
currentIndex: 1
})
}, 1000)
}
})
}
}).catch(errors => {
uni.$u.toast('校验失败')
})
},
reset() {
// const validateList = ['userInfo.name', 'userInfo.type', 'radiovalue1', 'checkboxValue1', 'intro',
// 'hotel', 'code', 'userInfo.birthday'
// ]
this.$refs.form1.clearValidate()
// setTimeout(() => {
// this.$refs.form1.clearValidate(validateList)
// // 或者使用 this.$refs.form1.clearValidate()
// }, 10)
},
hideKeyboard() {
uni.hideKeyboard()
},
cancelLeave(item) {
uni.showModal({
title: '提示',
content: '确定取消请假吗?',
success: (res) => {
if (res.confirm) {
cancelLeave(item.id).then(res => {
if (res.code == 200) {
this.pageNum = 1
this.leaveList = []
this.leaveLogList()
uni.$u.toast('已撤销')
}
})
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
},
js() {
endLeaveInfo().then(res => {
uni.showModal({
title: '提示',
content: res.msg,
confirmColor: "#00aa7c",
success: (res) => {
if (res.confirm) {
endLeave().then(res => {
this.pageNum = 1;
this.leaveList = [];
this.leaveLogList();
uni.$u.toast('停止成功')
})
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
})
},
//修改请假
editLeave(item) {
this.current = 0
this.leaveInfo = item,
this.leaveInfo.startEndTime = this.leaveInfo.startTime + " / " + this.leaveInfo.endTime
this.fileInfo = JSON.parse(item.fileInfo);
this.getUserLdlzDetail({
userId: this.$store.state.user.userId,
startDate: this.leaveInfo.startTime,
endDate: this.leaveInfo.endTime
})
},
approveLeave(item, approverStatus) {
uni.showModal({
title: '提示',
content: approverStatus == 1 ? '确定要同意该请假吗?' : '确定要拒绝该请假吗?',
confirmColor: "#00aa7c",
success: (res) => {
if (res.confirm) {
approveLeave({
id: item.id,
approverStatus: approverStatus,
approverComment: approverStatus == 1 ? '同意' : '不同意'
}).then(res => {
this.pageNum = 1;
this.leaveList = [];
this.leaveLogList();
uni.$u.toast('操作成功')
})
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
},
// 删除图片
deletePic(event) {
this.fileInfo.splice(event.index, 1)
},
// 新增图片
async afterRead(event) {
// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file)
let fileListLen = this.fileInfo.length
lists.map((item) => {
this.fileInfo.push({
...item,
status: 'uploading',
message: '上传中'
})
})
for (let i = 0; i < lists.length; i++) {
const result = await this.uploadFilePromise(lists[i].url)
console.log("result>>", result);
let item = this.fileInfo[fileListLen]
this.fileInfo.splice(fileListLen, 1, Object.assign(item, {
status: 'success',
message: '',
url: result
}))
fileListLen++
}
},
uploadFilePromise(url) {
return new Promise((resolve, reject) => {
let a = uni.uploadFile({
url: baseUrl + '/common/upload', // 仅为示例,非真实的接口地址
filePath: url,
name: 'file',
header: {
Authorization: 'Bearer ' + getToken()
},
formData: {
user: 'test'
},
success: (res) => {
if (res.data) {
let imgUrl = JSON.parse(res.data).fileName;
setTimeout(() => {
resolve(imgUrl)
}, 1000)
}
}
});
})
},
}
}
</script>
<style lang="scss" scoped>
uni-page-body {
height: 100%;
padding: 5px;
}
.picker {
background-color: #ffffff;
box-sizing: border-box;
border: #e4e4e4 solid 1px;
border-radius: 10rpx;
width: 165px;
height: 35px;
font-size: 13px;
line-height: 13px;
padding-left: 10px;
padding-right: 10px;
display: flex;
justify-content: space-between;
}
.qj-box {
background-color: white;
border-radius: 10rpx;
margin-top: 2px;
}
.qjtx {
padding: 10px;
}
.leave-one {
background-color: #ffffff;
box-sizing: border-box;
border: #f2f2f2 solid 1px;
border-radius: 2rpx;
margin-top: 10px;
padding: 5px 10px;
.leave-one-top {
display: flex;
justify-content: space-between;
border-bottom: #f2f2f2 solid 1px;
padding: 8px 15px;
.top-left {
color: #00b27b;
font-weight: bold;
font-size: 15px;
}
.top-right {
width: 35%;
color: #999999;
font-size:13px;
margin-top: 4px;
text-align: right;
}
}
.leave-one-content {
padding: 0 15px;
font-size: 14px;
color: #333333;
line-height: 25px;
.btns {
text-align: center;
background-color: #00b27b;
color: #fff;
width: 35px;
border-radius: 8rpx;
margin-left: 10px;
height: 20px;
line-height: 20px;
}
}
}
.picker{
display: flex;
// justify-content: center;
align-items: center;
}
::v-deep .segmented-control__text {
font-size: 16px;
}
::v-deep .u-input__content__field-wrapper__field{
font-size: 15px !important;
}
::v-deep .u-text__value{
font-size: 18px !important;
}
::v-deep .u-button__text{
font-size:14px !important;
}
</style>