OA/pages/leaveapplication/index.vue

970 lines
24 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>
<view class="leave_request">
<view class="leave_box">
<view class="" v-for='(fieldValue, fieldKey) in dataobj' :key="fieldKey">
<!-- {{fieldKey}} -->
<!-- {{ fieldValue.title }} - {{ fieldValue.type }} -->
<!-- v-if="fieldValue.type=='select'&& fieldKey!='copy_uids'&&fieldKey!='check_admin_ids'&&fieldKey!='flow_id'&&fieldKey!='name'" -->
<view class="leava_type flex_a_c"
v-if="fieldValue.type=='select'&& fieldKey!='copy_uids'&&fieldKey!='check_admin_ids'&&fieldKey!='flow_id'&&fieldKey!='name'">
<view class="title">{{fieldValue.title}}</view>
<input type="text" v-model="meatelist[fieldKey]" placeholder="请选择" @click="leixin(fieldKey)"
v-if="fieldKey!='name'">
</view>
<view class="leava_type flex_a_c" v-if="fieldKey=='name'&typeId!=6">
<view class="title">{{fieldValue.title}}</view>
<input type="text" v-model="meatelist[fieldKey]" placeholder="请选择" @click="leixiner()">
</view>
<view class=""
v-if="fieldValue.type=='input'&&fieldKey!='end_time'&&fieldKey!='start_time'&&fieldKey!='duration'">
<view class="cont_cell">
<view class="title">{{fieldValue.title}}</view>
<input type="text" v-model="meatelist[fieldKey]" :placeholder="fieldValue.title">
</view>
</view>
<view class="" v-if=" fieldKey=='start_time'">
<view class="cont_cell">
<view class="title">{{ timeData[0].title }}</view>
<input type="text" v-model="timeData[0].time" placeholder="请选择时间" disabled
@click="selectTime(timeData[0])">
</view>
</view>
<view class="" v-if="fieldKey=='end_time'">
<view class="cont_cell">
<view class="title">{{ timeData[1].title }}</view>
<input type="text" v-model="timeData[1].time" placeholder="请选择时间" disabled
@click="selectTime(timeData[1])">
</view>
</view>
<view class="" v-if="fieldKey=='duration'">
<view class="cont_cell">
<view class="title">{{fieldValue.title}}</view>
<input type="text" v-model="manHour" disabled placeholder="请假工时">
</view>
</view>
<view class="" v-if="fieldValue.type=='textarea'">
<view class="cont_cell">
<view class="title">{{fieldValue.title}}</view>
<input type="text" v-model="meatelist[fieldKey]" :placeholder="fieldValue.title">
</view>
</view>
<view class="" v-if="fieldValue.type=='file'">
<block v-for="(item, i) in fileArray" :key="i">
<view class="file flex_a_c_j_sb">
<view class="l_file">
<view class="file_name">{{ item.name }}</view>
<view class="file_size">{{ item.filesize | formatBytes }}</view>
<view class="upload_people">上传人:{{ item.admin_name }}</view>
</view>
<u-icon @click="delImg(i)" name="close-circle" color="#333333" size="28"></u-icon>
</view>
</block>
<view class="upload_box flex_a_c_j_sb">
<view>
<view class="title">选择文件并上传</view>
<view class="text">
上传前请规范命名最大只能上传100M的文件<br />
超过请压缩成多个文件上传。
</view>
</view>
<view class="" style="margin-top: 60rpx;">
<lsjUpload ref="lsjUpload" childId="upload1" :size="10" :option="fileOption" height="200rpx"
style="margin-top: 28rpx;" :debug="false"
:formats="'pdf,txt,zip,rar,jpg,png,mp3,avi,mov,mp4,gif'" :multiple="false" :count="3"
:instantly="true" @change="changeFile" @uploadEnd='onuploadEnd' @progress='onprogre'>
<!-- <view class="change-file">请选择PDF类型的发票</view> -->
<!-- <u-icon name="plus-circle" color="#333333" size="28"
style="margin-top: 40rpx; margin-left: 60rpx;"></u-icon> -->
<u-icon name="plus-circle" color="#333333" size="28"></u-icon>
</lsjUpload>
</view>
</view>
</view>
<!-- <view class="" v-for="(itemValue, itemKey) in fieldValue.item" :key="itemKey">
{{ itemKey }}: {{ itemValue }}
</view> -->
</view>
</view>
<view class="flow_path">
<view class="cont_cell">
<view class="title">选择审批流程:</view>
<input type="text" v-model="flowPath" placeholder="请选择" disabled @click="flowPathShow = true">
</view>
<view class="cont_cell" @click="branchShow = true">
<view class="title">审核人:</view>
<input type="text" v-model="check_admin_name" placeholder="请选择" disabled>
</view>
<view class="cont_cell" @click="branchShow1 = true">
<view class="title">抄送人:</view>
<input type="text" v-model="copy_names" placeholder="请选择" disabled>
</view>
</view>
<view class="bot_btn">
<view class="reset" @click="reset">重置</view>
<view class="submit_btn" @click="submiteBtn">立即提交</view>
</view>
<!-- <u-picker :show="leavaTypeShow" keyName="name" :columns="columns" @cancel="leavaTypeShow = false"
@confirm="leavaType">
</u-picker> -->
<u-action-sheet :show="leavaTypeShow" keyName="name" :actions="columns" title="请选择工作类别"
@close="leavaTypeShow = false" @select="leavaType">
</u-action-sheet>
<!-- 选择审批流程 -->
<u-action-sheet :actions="flowPathSheet" @select="flowPathSelect" title="选择审批流程" :show="flowPathShow"
@close="flowPathShow=false" :closeOnClickOverlay="true" :closeOnClickAction="true">
</u-action-sheet>
<!-- 审核人 -->
<u-picker :show="branchShow" :defaultIndex='defaultIndex' ref="branchRef" :columns="branchColumns"
@confirm="branchConfirm" @change="columnCode" :closeOnClickOverlay="true" @close="branchShowclose"
keyName="name">
</u-picker>
<u-picker :show="branchShow1" :defaultIndex='defaultIndex1' ref="branchRef" :columns="branchColumns1"
@confirm="branchConfirm1" @change="columnCode1" :closeOnClickOverlay="true" @close="branchShowclose1"
keyName="name">
</u-picker>
<u-picker :show="branchShow2" :defaultIndex='defaultIndex2' ref="branchRef" :columns="branchColumns2"
@confirm="branchConfirm2" @change="columnCode2" :closeOnClickOverlay="true" @close="branchShowclose2"
keyName="name">
</u-picker>
<u-picker :show="flag1" :columns="columns3" ref="uPicker4" @cancel="flag1 = false" closeOnClickOverlay
@close="flag1 = false" @confirm="confirm" keyName="title" :defaultIndex=[0,0]>
</u-picker>
<!-- 选择时间 -->
<block v-for="(item,i) in timeData" :key="i">
<u-datetime-picker :show="item.timeShow" v-model="item.timeVal" mode="datetime" :maxDate="1786778555000"
:minDate="timestamp" closeOnClickOverlay @confirm="timeConfirm($event,i)"
@cancel="item.timeShow = false" @close="item.timeShow = false"></u-datetime-picker>
</block>
</view>
</template>
<script>
import {
oaUploads
} from '../../api/upload'
import {
Toast
} from '../../libs/uniApi'
import {
appfield,
getemployee,
userdepartment,
appapprove,
} from '@/api/oa.js'
import {
FILE_URL
} from '@/api/file.js'
import lsjUpload from '@/uni_modules/lsj-upload/components/lsj-upload/lsj-upload.vue'
export default {
components: {
lsjUpload
},
data() {
return {
meatelist: {
},
defaultIndex: [0, 0, 0],
defaultIndex1: [0, 0, 0],
defaultIndex2: [0, 0, 0],
dataobj: {},
timestamp: '', // 当前时间
flowPath: '', // 审批流程
flow_id: '', // 审批流程id
check_admin_name: '', // 审核人
check_admin_ids: '',
copy_names: '', // 抄送人
copy_uids: '', // 抄送人id
manHour: '', // 请假工时
daysNum: '', // 请假天数
content: '', // 请假事由
flowPathShow: false,
flowPathSheet: [],
timeData: [{
title: '开始时间:',
timeShow: false,
timeVal: '', // 时间戳
time: '', // 完整时间
timeDay: '', // 年月日
timeHour: '', // 时分秒
},
{
title: '结束时间:',
timeShow: false,
timeVal: '', // 时间戳
time: '', // 完整时间
timeDay: '', // 年月日
timeHour: '', // 时分秒
}
],
leavaTypeShow: false,
leavaTypeVal: '',
leavaTypeId: '',
leavaTypeId1: '',
leavaTypeId2: '',
leavaTypeId3: '',
columns: [],
// 部门选择 三级级联动
branchShow: false,
branchShow1: false,
branchShow2: false,
branchColumns: [],
branchColumns1: [],
branchColumns2: [],
columns3: [],
isflowDate: true,
flowDate: [],
fileArray: [],
typeId: '',
flag1: false,
datatype: '',
fileOption: {},
files: new Map(),
}
},
onLoad(option) {
this.fileOption = {
url: FILE_URL,
name: 'file',
header: {
token: this.$store.state.app.token
}
},
this.typeId = option.type
if (option.type == 8) {
this.timeData[0].title = '借用日期:'
this.timeData[1].title = '拟归还日期:'
}
this.applist(option.type)
this.getDocumentList()
this.getDocumentList2()
},
onShow() {
// this.getFlow()
// 获取当前时间戳
this.timestamp = Date.parse(new Date());
},
watch: {
timeData: {
handler(newVal, oldVal) {
if (newVal[0].time.length > 0 && newVal[1].time.length > 0) {
const {
leaveDays,
leaveHours
} = this.calculateLeaveDaysAndHours(this.timeData[0].time, this.timeData[1]
.time)
this.manHour = leaveHours + '小时'
this.daysNum = leaveDays + '天'
}
},
deep: true
}
},
methods: {
async getDocumentList2() {
this.columns3 = []
const res = await userdepartment({
tree: 1
})
const deArr = res.data
this.columns3.push(deArr)
},
confirm(e) {
console.log(e)
this.flag1 = false
},
async applist(type) {
let res = await appfield({
type: type
})
this.dataobj = res.data.field
uni.setNavigationBarTitle({
title: res.data.title
})
if (res.data.field.flow_id) {
const detailTypeOptions1 = Object.entries(res.data.field.flow_id.item).map(([id, name]) => ({
id,
name
}));
this.flowPathSheet = detailTypeOptions1
}
},
//获取部门
async getDocumentList() {
const res = await userdepartment()
const deArr = res.data
let codelist = [
[], //顶级部门
[], //次级部门
[] // 负责人
]
codelist[0] = res.data.map((item) => { // 赋值
return {
id: item.id,
name: item.title
}
})
codelist[1] = res.data[0].children.map((item) => { // 赋值
return {
id: item.id,
name: item.title
}
})
let dat = await getemployee({
did: codelist[1][0].id
})
codelist[2] = dat.data.map((item) => {
return {
id: item.id,
name: item.name
}
})
this.$forceUpdate()
this.$nextTick(() => {
this.branchColumns = codelist
this.branchColumns1 = codelist
this.branchColumns2 = codelist
})
},
//监听人员加载数据
async columnCode(e) {
if (e.columnIndex == 1) {
let arr1 = []
let dat = await getemployee({
did: this.branchColumns[e.columnIndex][e.index].id
})
if (dat.data.length > 0) {
const newColumn = dat.data.map((item) => {
return {
id: item.id,
name: item.name
}
})
// 使用 Vue.set 或 this.$set 方法将新数组赋值给 columns3 数组对应位置
this.$set(this.branchColumns, 2, newColumn);
}
}
},
//监听人员加载数据
async columnCode1(e) {
if (e.columnIndex == 1) {
let arr1 = []
let dat = await getemployee({
did: this.branchColumns1[e.columnIndex][e.index].id
})
if (dat.data.length > 0) {
const newColumn = dat.data.map((item) => {
return {
id: item.id,
name: item.name
}
})
// 使用 Vue.set 或 this.$set 方法将新数组赋值给 columns3 数组对应位置
this.$set(this.branchColumns1, 2, newColumn);
}
}
},
async columnCode2(e) {
console.log(e)
if (e.columnIndex == 1) {
let arr1 = []
let dat = await getemployee({
did: this.branchColumns2[e.columnIndex][e.index].id
})
if (dat.data.length > 0) {
const newColumn = dat.data.map((item) => {
return {
id: item.id,
name: item.name
}
})
// 使用 Vue.set 或 this.$set 方法将新数组赋值给 columns3 数组对应位置
this.$set(this.branchColumns2, 2, newColumn);
}
}
},
leixin(e) {
console.log(e)
// this.meatelist[e]==1
this.datatype = e
if (e == 'department_type') {
const detailTypeOptions = Object.entries(this.dataobj.department_type.item).map(([id, name]) => ({
id,
name
}));
this.columns = detailTypeOptions
}
if (e == 'detail_type') {
const detailTypeOptions = Object.entries(this.dataobj.detail_type.item).map(([id, name]) => ({
id,
name
}));
this.columns = detailTypeOptions
}
if (e == 'other_type') {
const detailTypeOptions = Object.entries(this.dataobj.other_type.item).map(([id, name]) => ({
id,
name
}));
this.columns = detailTypeOptions
}
if (e == 'position_type') {
const detailTypeOptions = Object.entries(this.dataobj.position_type.item).map(([id, name]) => ({
id,
name
}));
this.columns = detailTypeOptions
}
// console.log(this.meatelist)
this.leavaTypeShow = true
},
leixiner() {
this.branchShow2 = true
},
branchShowclose() {
this.branchShow = false
},
branchShowclose1() {
this.branchShow1 = false
},
branchShowclose2() {
this.branchShow2 = false
},
selectTime(item) {
item.timeShow = true
},
async branchHandler(e) {
const {
columnIndex,
value,
values, // values为当前变化列的数组内容
index,
// 微信小程序无法将picker实例传出来只能通过ref操作
picker = this.$refs.branchRef
} = e
// 当第一列值发生变化时,变化第二列(后一列)对应的选项
if (columnIndex === 0) {
// picker为选择器this实例变化第二列对应的选项
let res = await getEmployeeAPI({
did: value[0].id
})
if (res.length < 1) {
res[0] = {
name: '无'
}
}
picker.setColumnValues(1, res)
}
},
// 回调参数为包含columnIndex、value、values
branchConfirm(e) {
console.log('confirm', e, e.value[2].name)
this.check_admin_name = e.value[2].name
this.check_admin_ids = e.value[2].id
this.branchShow = false
},
branchConfirm1(e) {
console.log('confirm', e, e.value[2].name)
this.copy_uids += e.value[2].id
this.copy_names += e.value[2].name + ','
this.branchShow1 = false
},
branchConfirm2(e) {
console.log('confirm', e, e.value[2].name)
this.meatelist.uid = e.value[2].id
this.meatelist.name = e.value[2].name
this.branchShow2 = false
},
/** 请假类型 */
leavaType(e) {
console.log(this.meatelist, this.datatype, e)
if (this.datatype == 'department_type') {
this.meatelist.department_type = e.name
this.leavaTypeId = e.id
} else if (this.datatype == 'detail_type') {
this.meatelist.detail_type = e.name
this.leavaTypeId1 = e.id
} else if (this.datatype == 'other_type') {
this.meatelist.other_type = e.name
this.leavaTypeId2 = e.id
} else if (this.datatype == 'position_type') {
this.meatelist.position_type = e.name
this.leavaTypeId3 = e.id
}
console.log(this.leavaTypeId2)
// console.log(this.meatelist,this.datatype, e.name)
// this.meatelist.detail_type = e.name
// // this.leavaTypeVal = e.name
// this.meatelist.department_type = e.name
// this.meatelist.detail_type = e.name
// this.meatelist.other_type = e.name
this.leavaTypeShow = false
},
flowPathSelect(value) {
this.flowPath = value.name
this.flow_id = value.id
},
async getFlow() {
const flow = await getFlowAPI({
type: 1,
flow_cate: 1
})
this.flowPathSheet = flow
},
timeConfirm(e, i) {
this.timeData[i].time = uni.$u.timeFormat(e.value, 'yyyy-mm-dd hh:MM:ss')
this.timeData[i].timeDay = uni.$u.timeFormat(e.value, 'yyyy-mm-dd')
this.timeData[i].timeHour = uni.$u.timeFormat(e.value, 'hh:MM')
this.timeData[i].timeShow = false
},
async submiteBtn() {
console.log(this.leavaTypeId2)
if (this.meatelist.mobile) {
const pattern = /^1[3456789]\d{9}$/;
if (!pattern.test(this.meatelist.mobile)) return Toast('手机号输入错误')
}
let subData;
let subData1;
if (this.typeId == 6 || this.typeId == 7 || this.typeId == 8 || this.typeId == 21) {
let fileIds = [];
this.fileArray.map((item, i) => {
fileIds.push(item.id)
});
subData1 = {
detail_type: this.leavaTypeId1,
content: this.meatelist.content,
check_admin_name: this.check_admin_name,
check_admin_ids: this.check_admin_ids,
flow_id: this.flow_id,
file_ids: fileIds.join(','),
copy_names: this.copy_names,
copy_uids: this.copy_uids,
type: this.typeId,
}
if (this.typeId == 8) {
subData1.start_time = this.timeData[0].timeDay + ' ' + this.timeData[0].timeHour,
subData1.end_time = this.timeData[1].timeDay + ' ' + this.timeData[1].timeHour,
subData1.department_type = this.leavaTypeId
subData1.detail_type = this.leavaTypeId1
subData1.other_type = this.leavaTypeId2
}
if (this.typeId == 21) {
subData1.department_type = this.leavaTypeId
subData1.position_type = this.leavaTypeId3
// console.log(subData1.position_type , this.leavaTypeId3)
}
subData = {
...this.meatelist,
...subData1
}
} else {
let fileIds = [];
this.fileArray.map((item, i) => {
fileIds.push(item.id)
});
subData = {
detail_type: this.leavaTypeId1,
start_time: this.timeData[0].timeDay + ' ' + this.timeData[0].timeHour,
end_time: this.timeData[1].timeDay + ' ' + this.timeData[1].timeHour,
duration: this.manHour,
content: this.meatelist.content,
check_admin_name: this.check_admin_name,
check_admin_ids: this.check_admin_ids,
flow_id: this.flow_id,
file_ids: fileIds.join(','),
copy_names: this.copy_names,
copy_uids: this.copy_uids,
type: this.typeId,
file: ''
}
}
console.log(subData)
try {
const res = await appapprove(subData)
if(res.code==0){
uni.navigateBack({
delta:1
})
}
Toast('提交成功')
} catch (e) {
Toast('提交失败')
}
},
/**
* 某文件上传结束回调(成功失败都回调)
* @param {Object} item 当前上传完成的文件
*/
onuploadEnd(item) {
console.log(`${item.name}已上传结束,上传状态=${item.type}`);
if (item['responseText']) {
this.files.get(item.name).responseText = JSON.parse(item.responseText);
}
// 更新当前窗口状态变化的文件
this.files.set(item.name, item);
let arr1 = this.files.get(item.name).responseText
this.fileArray.push(arr1.data)
// 强制更新视图
this.$forceUpdate();
},
/**
* 上传进度回调
* 如果网页上md文档没有渲染出事件名称onprogre请复制代码的小伙伴自行添加上哈没有哪个事件是只(item)的
* @param {Object} item 当前正在上传的文件
*/
onprogre(item) {
console.log('打印对象', JSON.stringify(this.files.get(item.name)));
// 更新当前状态变化的文件
this.files.set(item.name, item);
// 强制更新视图
this.$forceUpdate();
},
/**
* 文件选择回调
* @param {Object} files 已选择的所有文件Map集合
*/
changeFile(files) {
console.log('当前选择的文件列表:', JSON.stringify([...files.values()]));
// 更新选择的文件
this.files = files
console.log(files.values())
// 强制更新视图
this.$forceUpdate();
},
/**
* 指定上传某个文件
* @param {Object} name 带后缀名的文件名称
*/
resetUpload(name) {
this.$refs.lsjUpload.upload(name);
},
reset() {
this.flowPath = ''
this.flowDate = []
this.leavaTypeVal = ''
this.leavaTypeId = ''
this.leavaTypeId1 = ''
this.leavaTypeId2 = ''
this.leavaTypeId3 = ''
this.meatelist = {}
this.daysNum = ''
this.timeData[0].time = ''
this.timeData[0].time = ''
this.timeData[1].time = ''
this.timeData[1].time = ''
this.manHour = ''
this.content = ''
this.flow_id = ''
this.check_admin_name = ''
this.check_admin_ids = ''
this.copy_names = ''
this.copy_uids = ''
},
delImg(i) {
let that = this
uni.showModal({
title: '删除上传内容吗',
content: '确定删除上传内容吗?',
success: res => {
if (res.confirm) {
that.fileArray.splice(i, 1)
} else if (res.cancel) {
console.log('用户点击取消');
}
}
})
},
/**
* 计算两个时间戳之间相差的小时数
* */
calculateLeaveDaysAndHours(leaveStartTime, leaveEndTime, hoursPerDay = 8) {
const startDate = new Date(leaveStartTime);
const endDate = new Date(leaveEndTime);
// 计算请假天数
const leaveDays = Math.floor((endDate.getTime() - startDate.getTime()) / (24 * 60 * 60 * 1000)) + 1;
// 计算请假总小时数
const leaveHours = leaveDays * hoursPerDay;
// 返回结果
return {
leaveDays,
leaveHours,
};
}
},
filters: {
// 数字转MB
formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 MB';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + ' ' + sizes[i];
}
},
onPullDownRefresh() {
uni.stopPullDownRefresh()
}
}
</script>
<style lang="scss">
.leave_request {
position: relative;
padding-bottom: 100px;
}
.leave_box,
.flow_path {
width: 100%;
padding: 0 28.07rpx;
background: #fff;
margin-bottom: 35.09rpx;
padding-bottom: 28.07rpx;
}
.bot_btn {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
height: 87.72rpx;
>view {
width: 50%;
text-align: center;
line-height: 87.72rpx;
}
.reset {
background-color: #fff;
}
.submit_btn {
color: #fff;
height: 87.72rpx;
background: $theme-oa-color;
}
}
.leava_type {
height: 100rpx;
border-bottom: 1px solid #999;
.title {
font-size: 31.58rpx;
}
}
.cont_cell {
display: flex;
align-items: center;
width: 100%;
min-height: 87.72rpx;
border-bottom: 1px solid #f7f7f7;
.title {
font-size: 31.58rpx;
}
}
// 审批流程
.audit_process {
.process_item {
position: relative;
height: 100%;
margin: 17.54rpx 0;
}
:last-child {
.circle {
&::before {
display: none;
}
}
}
.tag {
font-size: 21.05rpx;
color: #fff;
padding: 0 4px;
margin-left: 10.53rpx;
background-color: #3c9cff;
border-radius: 2px;
}
.verifier {
margin: 17.54rpx 0;
}
}
.circle {
width: 31.58rpx;
height: 31.58rpx;
background-color: #fff;
border: 2px solid #34A853;
border-radius: 50%;
margin: 0 5px;
display: flex;
flex-direction: column;
align-items: center;
&::before {
content: "";
display: block;
position: absolute;
clear: both;
width: 1px;
height: 100%;
background-color: rgba(204, 204, 204, 0.5);
margin: 31.58rpx;
}
}
// 附件
.upload_box {
padding: 17.54rpx;
background-color: #F7F7F7;
border-radius: 4px;
.title {
font-size: 28.07rpx;
}
.text {
margin-top: 7.02rpx;
font-size: 21.05rpx;
color: #999;
}
}
.file_name {
width: 526.32rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.file {
padding: 17.54rpx;
border-radius: 4px;
border: 1px solid #F2F2F2;
margin: 17.54rpx 0;
.file_size {
margin-top: 7.02rpx;
}
.file_size,
.upload_people {
font-size: 21.05rpx;
color: #999;
}
}
</style>