Commit 681481ac by ningjihai

跨天外出,请假

parent 95a3248a
import request from '../../common/utils/request'
/**
* 考勤-请假列表
* pageNum=1&pageSize=4&reason=1001
* @param {{
* pageNum: number
* pageSize: number
* reason: number | string 搜索关键字
* }} data
* @returns
*/
export function getCrossDayOutRequestlist(data) {
return request({
url: '/attendance/attMobile/getCrossDayOutRequestlist',
method: 'get',
params: data
})
}
/**
* 考勤-请假新增
* @param {object} data 申请数据
* @param {strgin} data.leaveType 请假类型
* @param {strgin} data.backTime 开始时间
* @param {strgin} data.endTime 结束时间
* @param {strgin} data.duration 请假时长(小时)
* @param {strgin} data.agentName 代理人
* @param {strgin} data.reason 请假事由
* @param {strgin} data.fileList 请假事由
* @returns
*/
export function addCrossDayOutRequest(data) {
return request({
url: '/attendance/attMobile/addCrossDayOutRequest',
method: 'post',
data: data
})
}
/**
* 考勤-请假新增
* @param {object} data 申请数据
* @param {strgin} data.id 请假类型
* @param {strgin} data.auditStatus 1暂存 2审核中
* @param {strgin} data.leaveType 请假类型
* @param {strgin} data.backTime 开始时间
* @param {strgin} data.endTime 结束时间
* @param {strgin} data.duration 请假时长(小时)
* @param {strgin} data.agentName 代理人
* @param {strgin} data.reason 请假事由
* @param {strgin} data.fileList 请假事由
* @returns
*/
export function updateCrossDayOutRequest(data) {
return request({
url: '/attendance/attMobile/updateCrossDayOutRequest',
method: 'post',
data: data
})
}
/**
* 考勤-销假申请
* @param {{
* leaveRequestId: string
* backTime: string
* remark: string
* }} data
* @returns
*/
export function addLeaveRequestBack(data) {
return request({
url: '/attendance/attMobile/addLeaveRequestBack',
method: 'post',
data: data
})
}
/**
* 考勤-请假详情
* @param {string} leaveRequestId id
* @returns
*/
export function getCrossDayOutRequestDetail(leaveRequestId) {
return request({
url: `/attendance/attMobile/getCrossDayOutRequestDetail/${leaveRequestId}`,
method: 'get'
})
}
/**
* 考勤-销假详情
* @param {string} leaveRequestBackId id
* @returns
*/
export function getLeaveRequrstBack(leaveRequestBackId) {
return request({
url: `/attendance/attMobile/getLeaveRequrstBack/${leaveRequestBackId}`,
method: 'get'
})
}
// 预计算请假天数(后端精确计算,按班次与节假日排除非工作日)
export function precomputeLeaveDays(params) {
return request({
url: '/attendance/leaveRequest/precompute',
method: 'post',
data: params
})
}
export function getRestTime() {
return request({
url: '/attendance/leaveRequest/getRestTime',
method: 'get'
})
}
\ No newline at end of file
...@@ -9,6 +9,7 @@ import AttendanceOverTimeForLeaveDetailFlow from './modules/attendance/overTimeF ...@@ -9,6 +9,7 @@ import AttendanceOverTimeForLeaveDetailFlow from './modules/attendance/overTimeF
import AttendanceAbnormalOvertimeDetailFlow from './modules/attendance/abnormalOvertime/modules/DetailFlow.vue' import AttendanceAbnormalOvertimeDetailFlow from './modules/attendance/abnormalOvertime/modules/DetailFlow.vue'
import AttendanceCardSignDetailFlow from './modules/attendance/cardSign/modules/DetailFlow.vue' import AttendanceCardSignDetailFlow from './modules/attendance/cardSign/modules/DetailFlow.vue'
import AttendanceOutsideDetailFlow from './modules/attendance/outside/modules/DetailFlow.vue' import AttendanceOutsideDetailFlow from './modules/attendance/outside/modules/DetailFlow.vue'
import AttendanceOutRequestDetailFlow from './modules/attendance/outRequest/modules/DetailFlow.vue'
import AttendanceDayOffDetailFlow from './modules/attendance/dayOff/modules/DetailFlow.vue' import AttendanceDayOffDetailFlow from './modules/attendance/dayOff/modules/DetailFlow.vue'
import PersonnelResignationDetailFlow from './modules/personnel/resignation/modules/DetailFlow.vue' import PersonnelResignationDetailFlow from './modules/personnel/resignation/modules/DetailFlow.vue'
import PersonnelEmployeesChanges from './modules/personnel/employeesChanges/modules/DetailFlow.vue' import PersonnelEmployeesChanges from './modules/personnel/employeesChanges/modules/DetailFlow.vue'
...@@ -225,6 +226,11 @@ function onApprove() { ...@@ -225,6 +226,11 @@ function onApprove() {
<AttendanceAbnormalOvertimeDetailFlow v-if="optionType === 'abnormalOvertime'" :id="id" :instanceId="instanceId" /> <AttendanceAbnormalOvertimeDetailFlow v-if="optionType === 'abnormalOvertime'" :id="id" :instanceId="instanceId" />
<AttendanceCardSignDetailFlow v-if="optionType === 'cardSign'" :id="id" :instanceId="instanceId" /> <AttendanceCardSignDetailFlow v-if="optionType === 'cardSign'" :id="id" :instanceId="instanceId" />
<AttendanceOutsideDetailFlow v-if="optionType === 'outside'" :id="id" :instanceId="instanceId" /> <AttendanceOutsideDetailFlow v-if="optionType === 'outside'" :id="id" :instanceId="instanceId" />
<AttendanceOutRequestDetailFlow v-if="optionType === 'outRequest'" :id="id" :instanceId="instanceId" />
<AttendanceDayOffDetailFlow v-if="optionType === 'dayOff'" :id="id" :instanceId="instanceId" /> <AttendanceDayOffDetailFlow v-if="optionType === 'dayOff'" :id="id" :instanceId="instanceId" />
<PersonnelResignationDetailFlow v-if="optionType === 'resignation'" :id="id" :instanceId="instanceId" /> <PersonnelResignationDetailFlow v-if="optionType === 'resignation'" :id="id" :instanceId="instanceId" />
<PersonnelEmployeesChanges v-if="optionType === 'employeesChanges'" :id="id" :instanceId="instanceId" /> <PersonnelEmployeesChanges v-if="optionType === 'employeesChanges'" :id="id" :instanceId="instanceId" />
......
<script setup lang="ts">
import { ref, reactive, computed, watch,onMounted, onUnmounted } from 'vue'
import { storeToRefs } from 'pinia'
import { onLoad } from '@dcloudio/uni-app'
import useUserStore from '@/store/modules/user'
import { addCrossDayOutRequest, updateCrossDayOutRequest, getCrossDayOutRequestDetail,precomputeLeaveDays,getRestTime } from '@/api/attendance/outRequest'
import { selectEmployeesDetailByCode } from '@/api/user'
import { parseTime, selectDictLabel } from '../../common/utils/ruoyi'
import { useDict } from '../../common/utils/dict'
import UploadImage from '../../components/Upload/UploadImage.vue'
const { request_leave_type, breast_feed_type } = useDict('request_leave_type', 'breast_feed_type')
const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore)
const dateFormat = {
'year': '年',
'month': '月',
'day': '日',
'hour': '时',
'minute': '分'
}
const formRef = ref()
const detail = ref<any>({})
const form = reactive<any>({
id: '', // 修改编辑
auditStatus: '0', // 状态
userName: userInfo.value.nickName,
employeesCode: userInfo.value.userCode,
beginTime: '', // 结束时间
startHalf: 'AM',
startHalfLabel: '上午',
endHalf: 'PM',
endHalfLabel: '下午',
beginTimeStamp: '',
endTimeStamp: '',
endTime: '', // 结束时间
duringTime: '', // 跨天外出时长(小时)
reason: '', // 出差事由
agentName: '', // 代理人
urgentHandingOfAffairs: '', // 岗位紧急处理事务
fileList: [] // 图片
})
const startHalf = ref('')
const endHalf = ref('')
const HalfColumns = ref([
[
{
value: 'AM',
label: '上午'
},
{
value: 'PM',
label: '下午'
}
]
])
const loading = ref(false)
const activeTabStart = ref(0)
const activeTabEnd = ref(0)
const now = new Date()
const nowStamp = now.getTime()
const beginDate = ref(parseTime(now, '{y}-{m}-{d}').split('-')) // 绑定picker选择开始日期
const beginTime = ref(parseTime(now, '{h}:{i}').split(':')) // 绑定picker选择开始时间
const endDate = ref<string[]>([]) // 绑定picker选择结束日期
const endTime = ref<string[]>([]) // 绑定picker选择结束时间
const minDateEnd = computed(() => new Date(new Date(beginDate.value.join('/') + ' ' + beginTime.value.join(':'))).getTime() + 1000 * 60 * 30)
const show = reactive({
beginTime: false,
endTime: false,
})
onMounted(()=>{
console.log('userinfo',userInfo.value)
})
function computeDuringDays() {
try {
if (!form.beginTime || !form.endTime) {
return
}
// use backend precompute for accurate result
const beginDate = String(form.beginTime).split(' ')[0]
const endDate = String(form.endTime).split(' ')[0]
const params = {
employeesCode: userInfo.value.userCode,
beginDate: beginDate,
startHalf: form.startHalf || 'AM',
endDate: endDate,
endHalf: form.endHalf || 'PM'
}
precomputeLeaveDays(params).then(res => {
if (res && res.data != null) {
form.duringTime = Number(res.data)
}
}).catch(err => {
console.error('precomputeLeaveDays error', err)
})
} catch (e) {
console.error('computeDuringDays error', e)
}
}
watch(() => [form.beginTime, form.startHalf, form.endTime, form.endHalf], () => {
computeDuringDays()
})
function formatterDate(type, option) {
option.text += dateFormat[type]
return option
}
function formatterTime(type, option) {
option.text += dateFormat[type]
return option
}
const beginDateStr = ref('')
const beginTimeStr = ref('')
const endDateStr = ref('') // 用于日期选择器
const endTimeStr = ref('')
const formatter = (type, value) =>{
if (type === 'year') {
return `${value}年`
}
if (type === 'month') {
return `${value}月`
}
if (type === 'day') {
return `${value}日`
}
if (type === 'hour') {
return `${value}时`
}
if (type === 'minute') {
return `${value}分`
}
return value
}
onLoad((option) => {
if (option.id) {
uni.showLoading({
title: '请稍等...'
});
getCrossDayOutRequestDetail(option.id).then(res => {
uni.hideLoading();
const data = res.data
form.id = data.id
// form.auditStatus = data.auditStatus
// form.leaveType = data.leaveType
// form.breastFeedType = data.breastFeedType
form.beginTime = data.beginTime
form.endTime = data.endTime
// if (isBreastFeed.value) {
// form.beginTime = form.beginTime.replace(/\s.*$/, '')
// form.endTime = form.endTime.replace(/\s.*$/, '')
// }
form.duringTime = data.duringTime
form.agentName = data.agentName
form.reason = data.reason
form.fileList = data.fileList || []
beginDate.value = parseTime(data.beginTime, '{y}-{m}-{d}').split('-')
beginTime.value = parseTime(data.beginTime, '{h}:{i}').split(':')
endDate.value = parseTime(data.endTime, '{y}-{m}-{d}').split('-')
endTime.value = parseTime(data.endTime, '{h}:{i}').split(':')
beginDateStr.value = beginDate.value.join('-')
beginTimeStr.value = beginTime.value.join(':')
endDateStr.value = endDate.value.join('-')
endTimeStr.value = endTime.value.join(':')
})
}
})
// 过滤开始时间 时分
function filterTimeBegin(type, options, values) {
return type === 'minute' ? options.filter(option => Number(option.value) % 30 === 0) : options
}
// 过滤结束时间 时分
function filterTimeEnd(type, options, values) {
const begin = new Date(beginDate.value.join('/') + ' ' + beginTime.value.join(':')).getTime()
// 小时
if (type === 'hour') {
return options.filter(option => {
const end = new Date(endDate.value.join('/') + ' ' + option.value + ':30').getTime()
return end > begin
})
}
// 分
return options.filter(option => {
if (!values[0]) return false
const end = new Date(endDate.value.join('/') + ' ' + values[0] + ':' + option.value).getTime()
return end >= begin + 1000 * 60 * 30 && Number(option.value) % 30 === 0
})
}
onUnmounted(() => {
uni.hideLoading()
})
// 获取用户个人信息
selectEmployeesDetailByCode({
employeesCode: userInfo.value.userCode
}).then(res => {
detail.value = res.data || {}
})
// 选择跨天外出开始日期时间 - 确认
function onConfirmBegin() {
// 更新数组值
beginDate.value = beginDateStr.value.split('-')
beginTime.value = beginTimeStr.value.split(':')
form.beginTime = `${beginDateStr.value}${' ' + beginTimeStr.value}`
show.beginTime = false
activeTabStart.value = 0
if (form.beginTime >= form.endTime) {
form.endTime = ''
endDateStr.value = parseTime(minDateEnd.value, '{y}-{m}-{d}')
endTimeStr.value = ''
}
}
// 选择跨天外出结束日期时间 - 确认
function onConfirmEnd() {
endDate.value = endDateStr.value.split('-')
endTime.value = endTimeStr.value.split(':')
// 更新表单数据
form.endTime = `${endDateStr.value}${' ' + endTimeStr.value}`
show.endTime = false
activeTabEnd.value = 0
}
// 校验失败
function onFailed(e) {
console.log('error', e)
}
// 校验结果
function onSubmit(e) {
formRef.value?.validate().then(() => {
loading.value = true
uni.showLoading({
title: '提交中...'
})
const requstData = JSON.parse(JSON.stringify(form))
if (form.fileList.length) {
requstData.fileList = requstData.fileList.map(item => ({
url: item.url,
name: item.name,
fileSize: item.fileSize,
fileType: item.fileType
}))
}
// if (isBreastFeed.value) {
requstData.beginTime += ' 00:00'
requstData.endTime += ' 00:00'
// }
console.log('requstData',requstData)
// return
const requestMethod = form.id ? updateCrossDayOutRequest : addCrossDayOutRequest
requestMethod(requstData).then(res => {
console.log(123123,res)
if(res.code === 200){
uni.showToast({title: res.msg})
loading.value = false
setTimeout(() => {
uni.navigateBack({delta: 1})
}, 1000)
}else{
uni.showToast({title: res.msg,icon: 'none'})
loading.value = false
}
}).catch(() => {
uni.hideLoading()
loading.value = false
})
})
}
// 新增的变量
const activeBeginTab = ref(0) // 0-日期,1-时间
const activeEndTab = ref(0) // 0-日期,1-时间
const beginTimeRef:any = ref(null)
// 修改打开开始时间选择器的方法
function openBeginPicker() {
beginTimeRef.value.open()
activeBeginTab.value = 0
}
const endTimeRef:any = ref(null)
// 修改打开结束时间选择器的方法
function openEndPicker() {
endTimeRef.value.open()
activeEndTab.value = 0
}
// 点击提交
function onClickSubmit() {
formRef.value?.validate().then(() => {
onSubmit({errors: null})
}).catch(err => {
onFailed(err)
})
}
const leaveTypeRef:any = ref(null)
// const showLeaveType = ()=>{
// leaveTypeRef.value.open()
// }
const confirmBeginTime = (e)=>{
console.log(e)
form.beginTime =timestampToTime(e.value)
}
const confirmEndTime = (e)=>{
console.log(e)
form.endTime =timestampToTime(e.value)
}
function timestampToTime(timestamp) {
const date = new Date(timestamp); // 时间戳转 Date 对象
const year = date.getFullYear(); // 年
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月(补零)
const day = String(date.getDate()).padStart(2, '0'); // 日(补零)
const hours = String(date.getHours()).padStart(2, '0'); // 时(补零)
const minutes = String(date.getMinutes()).padStart(2, '0'); // 分(补零)
const seconds = String(date.getSeconds()).padStart(2, '0'); // 秒(补零)
return `${year}-${month}-${day}`;
}
const startHalfRef:any = ref(null)
const showStartHalf = ()=>{
startHalfRef?.value.open()
}
const onConfirmStartHalf = (e:any)=>{
console.log(e)
form.endHalf = e.value[0].value
form.endHalfLabel = e.value[0].label
}
const endHalfRef:any = ref(null)
const showEndHalf = ()=>{
endHalfRef?.value.open()
}
const onConfirmEndHalf = (e:any)=>{
console.log(e)
form.endHalf = e.value[0].value
form.endHalfLabel = e.value[0].label
}
</script>
<template>
<div class="container full float-bottom">
<div class="container__body">
<div class="container__card flex form-card-container">
<uv-form ref="formRef" labelWidth="140" label-position="top" label :model="form">
<!-- 开始时间 -->
<uv-form-item customStyle="padding: 20rpx 32rpx;" label="开始日期" prop="beginTime" required @click="openBeginPicker">
<uv-input
v-model="form.beginTime"
disabled
placeholder="点击选择开始日期"
border="bottom"
disabledColor="#fff"
/>
<template v-slot:right>
<uv-icon name="arrow-right"></uv-icon>
</template>
</uv-form-item>
<uv-datetime-picker ref="beginTimeRef" :formatter="formatter" v-model="form.beginTimeStamp" mode="date" @confirm="confirmBeginTime">
</uv-datetime-picker>
<uv-form-item customStyle="padding: 20rpx 32rpx;" label="开始上午/下午" prop="startHalf" required @click="showStartHalf">
<uv-input
v-model="form.startHalfLabel"
disabled
placeholder="选择跨天外出类型"
border="bottom"
disabledColor="#fff"
/>
<template v-slot:right>
<uv-icon name="arrow-right"></uv-icon>
</template>
</uv-form-item>
<uv-picker
ref="startHalfRef"
v-model="startHalf"
:columns="HalfColumns"
keyName="label"
@confirm="onConfirmStartHalf"
/>
<!-- 结束时间 -->
<uv-form-item customStyle="padding: 20rpx 32rpx;" label="结束日期" prop="endTime" required @click="openEndPicker">
<uv-input
v-model="form.endTime"
disabled
placeholder="点击选择结束日期"
border="bottom"
disabledColor="#fff"
/>
<template v-slot:right>
<uv-icon name="arrow-right"></uv-icon>
</template>
</uv-form-item>
<uv-datetime-picker ref="endTimeRef" :formatter="formatter" v-model="form.endTimeStamp" mode="date" @confirm="confirmEndTime">
</uv-datetime-picker>
<uv-form-item customStyle="padding: 20rpx 32rpx;" label="结束上午/下午" prop="endHalf" required @click="showEndHalf">
<uv-input
v-model="form.endHalfLabel"
disabled
placeholder="选择跨天外出类型"
border="bottom"
disabledColor="#fff"
/>
<template v-slot:right>
<uv-icon name="arrow-right"></uv-icon>
</template>
</uv-form-item>
<uv-picker
ref="endHalfRef"
v-model="endHalf"
:columns="HalfColumns"
keyName="label"
@confirm="onConfirmEndHalf"
/>
<!-- 跨天外出时长(小时) -->
<uv-form-item customStyle="padding: 20rpx 32rpx;" label="跨天外出时长(天)" prop="duringTime" required>
<uv-input
v-model="form.duringTime"
disabled
border="bottom"
/>
</uv-form-item>
<!-- 代理人 -->
<!-- <uv-form-item customStyle="padding: 20rpx 32rpx;" label="代理人" prop="agentName" required>
<uv-input
v-model="form.agentName"
placeholder="请输入代理人"
border="bottom"
/>
</uv-form-item> -->
<!-- 跨天外出事由 -->
<uv-form-item customStyle="padding: 20rpx 32rpx;" label="事由" prop="reason" required>
<uv-textarea
v-model="form.reason"
placeholder="请输入事由"
maxlength="300"
count
border="bottom"
/>
</uv-form-item>
<!-- 岗位紧急处理事务 -->
<!-- <uv-form-item customStyle="padding: 20rpx 32rpx;" label="岗位紧急处理事务" prop="urgentHandingOfAffairs" required>
<uv-textarea
v-model="form.urgentHandingOfAffairs"
placeholder="请输入岗位紧急处理事务"
maxlength="500"
count
border="bottom"
/>
</uv-form-item> -->
<!-- 图片上传 -->
<uv-form-item customStyle="padding: 20rpx 32rpx;" label="图片" prop="uploader" >
<UploadImage v-model="form.fileList" />
</uv-form-item>
</uv-form>
</div>
</div>
<uv-button
:loading="loading"
class="button-submit float-bottom"
shape="circle"
color="linear-gradient(to bottom, #4773FC, #6D9BFD)"
customStyle="margin-top: 200rpx"
@click="onSubmit">提交</uv-button>
</div>
</template>
<style lang="scss" scoped>
.container {
padding: 20rpx;
box-sizing: border-box;
}
</style>
\ No newline at end of file
<script setup lang="ts" name="LeaveDetail">
import { ref } from 'vue'
// import { useRoute } from 'vue-router'
import DetailFlow from './modules/DetailFlow.vue'
import { onLoad } from '@dcloudio/uni-app'
// const route = useRoute()
const id = ref('')
const instanceId = ref('')
onLoad((option) => {
console.log('option',option)
id.value = option.id
instanceId.value = option.instanceId
// console.log(route.query)
})
</script>
<template>
<div class="container full">
<div class="container__body">
<div class="container__card flex">
<DetailFlow v-if="id && instanceId" :id="id" :instance-id="instanceId" />
</div>
</div>
</div>
</template>
<style lang="less" scoped>
</style>
<script setup lang="ts" name="LeaveList">
import { ref } from 'vue'
// import { useRouter } from 'vue-router'
// import { showConfirmDialog, showSuccessToast } from 'vant'
import { useUserStore } from '@/store/modules/user'
import { getCrossDayOutRequestlist } from '@/api/attendance/outRequest'
import { revokeProcess } from '@/api/flowEngine/flowInterface'
import { useDict } from '../../common/utils/dict'
import PullList from '../../components/List/PullList.vue'
import LeaveListItem from './modules/LeaveListItem.vue'
import customFab from '@/components/customFab.vue'
const { audit_status, request_leave_type } = useDict('audit_status', 'request_leave_type')
// console.log(audit_status)
const userStore = useUserStore()
// const router = useRouter()
const pullListRef = ref<InstanceType<typeof PullList>>()
const queryParams = ref({
pageNum: 1,
pageSize: 5,
reason: ''
// employeesCode: userInfo.value.userCode
})
// 请求方法,传入PullList组件,需返回{rows: [], total: number}
function onRequest(query?: any, isRefresh?: boolean): Promise<{rows: any[], total: number}> {
return getCrossDayOutRequestlist(query)
}
// 跨天外出详情
function onClickItem(item) {
console.log('123')
// 已退回 和 已撤回
if (['5', '6'].includes(item.auditStatus)) {
uni.navigateTo({
url:'/attendance/outRequest/add?id=' + item.id,
})
return
}
console.log('123')
uni.navigateTo({
url:'/attendance/outRequest/detail?id=' + item.id + '&instanceId=' + item.instanceId
})
}
// // 销假
// function onClose(item) {
// // router.push({ path: '/attendance/leave/close',
// // query: {
// // id: item.id,
// // beginTime: item.beginTime,
// // endTime: item.endTime,
// // leaveType: item.leaveType
// // }
// // })
// uni.navigateTo({
// url:'/attendance/leave/close?id=' + item.id + '&beginTime=' + item.beginTime + '&endTime=' + item.endTime + '&leaveType=' + item.leaveType
// })
// }
// 撤办
function onRevoke(item) {
uni.showModal({
title: '撤办',
content: `隔天外出:${item.reason},确认撤办吗?`,
success: (res) => {
if (res.confirm) {
return new Promise((resolve, reject) => {
revokeProcess({
instanceId: item.instanceId
}).then(() => {
uni.showToast({
title: '撤办成功',
icon: 'success'
})
setTimeout(() => {
resolve(true)
pullListRef.value?.refresh()
}, 500)
}).catch(() => {
reject(false)
})
})
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
// 点击添加
function onClickAdd() {
uni.navigateTo({
url:'/attendance/outRequest/add',
})
}
function handleSearchChange(e) {
queryParams.value.reason = e.detail // 手动更新数据:ml-citation{ref="2,8" data="citationList"}
}
function onSearch() {
pullListRef.value?.refresh()
}
</script>
<template>
<div class="query-wrap">
<div class="search-pad">
<van-search
:value="queryParams.reason"
@change="handleSearchChange"
shape="round"
placeholder="请输入搜索关键词"
useActionSlot
@search="onSearch"
@clear="onSearch">
<template #action>
<div class="search-btn" @click="onSearch">搜索</div>
</template>
</van-search>
</div>
</div>
<!-- </div> -->
<PullList ref="pullListRef" v-model:query-string="queryParams" :isFixed="false" zHeight="80vh" :request-method="onRequest">
<template #default="{ item, index }">
<div style="padding: 0 30rpx;" >
<LeaveListItem
:item="item"
:user-info="userStore.userInfo"
:audit_status="audit_status"
:request_leave_type="request_leave_type"
@revoke.stop="onRevoke"
@tap="onClickItem(item)" />
</div>
<!-- @close.stop="onClose" -->
</template>
</PullList>
<customFab icon @click="onClickAdd" />
</template>
<style lang="less" scoped>
.search-pad {
padding: 30rpx;
box-sizing: border-box;
}
:deep(.van-search) {
position: relative;
z-index: 1;
padding: 20rpx;
// min-height: 4.4rem;
border-radius:24rpx;
box-shadow: 0 4rpx 40rpx rgba(64, 103, 251, 0.14);
// overflow: hidden;
}
.search-btn {
padding: 0 16.6rpx;
}
</style>
<script setup lang="ts" name="LeaveDetailFlow">
/* 跨天外出详情 */
import { ref, reactive, computed, onMounted } from 'vue'
import { parseTime } from '/common/utils/ruoyi'
import { getFlowChart } from '@/api/flowEngine/flowInterface'
import { getCrossDayOutRequestDetail } from '@/api/attendance/outRequest'
import { selectDictLabel } from '@/common/utils/ruoyi'
import { useDict } from '@/common/utils/dict'
import FlowTimeline from '@/components/Flow/FlowTimeline.vue'
// const router = useRouter()
const props = defineProps<{
id: string
instanceId: string
}>()
const { request_leave_type, breast_feed_type } = useDict('request_leave_type', 'breast_feed_type')
const detail = ref<any>({})
const detailClose = ref<any>({})
const nodeData = ref<any>()
const activeTab = ref('')
getCrossDayOutRequestDetail(props.id).then(res => {
detail.value = res.data
})
getFlowChart({ instanceId: props.instanceId }).then(res => {
nodeData.value = res.data
})
// 预览
function onPreview(index) {
// showImagePreview({
// images: detail.value.fileList.map(item => item.url),
// startPosition: index
// })
uni.previewImage({
urls:detail.value.fileList.map(item => item.url),
current:index
})
}
// 点击销假列表
function onDetailClose(item) {
// router.push({
// path: '/attendance/leave/close-detail',
// query: {
// id: item.id,
// instanceId: item.instanceId
// }
// })
uni.navigateTo({
url:'/attendance/leave/close-detail?id=' + item.id + '&instanceId=' + item.instanceId
})
}
</script>
<template>
<div class="container__card flex">
<van-cell-group>
<van-cell title="开始日期" :value="parseTime(detail.beginTime, '{y}-{m}-{d}')" />
<van-cell title="开始上午/下午" :value="detail.startHalf === 'AM' ? '上午' : '下午'" />
<van-cell title="结束日期" :value="parseTime(detail.endTime, '{y}-{m}-{d}')" />
<van-cell title="结束上午/下午" :value="detail.startHalf === 'PM' ? '上午' : '下午'" />
<van-cell title="跨天外出时长">
{{ detail.duringTime }}
</van-cell>
<!-- <van-cell title="代理人" :value="detail.agentName" /> -->
<van-cell title="跨天外出事由" :value="detail.reason" />
<!-- <van-cell title="岗位紧急处理事务" :value="detail.urgentHandingOfAffairs || '无'" /> -->
<van-grid
v-if="detail.fileList?.length"
:border="false"
:column-num="3"
class="grid">
<template v-for="(item, index) in detail.fileList" :key="index">
<van-grid-item>
<van-image :src="item.url" @click="onPreview(index)" />
</van-grid-item>
</template>
</van-grid>
</van-cell-group>
<FlowTimeline :node-data="nodeData" />
</div>
</template>
<style lang="less" scoped>
.grid {
:deep(.van-image) {
position: relative;
width: 100%;
height: 0;
padding-bottom: 100%;
border-radius: 0.6rem;
box-shadow: 0.2rem 0.2rem 0.5rem rgba(0,0,0,0.5);
overflow: hidden;
.van-image__img {
position: absolute;
object-fit: cover;
}
}
}
:deep(.van-cell) {
.van-cell__title {
margin-right: 1rem;
flex: none;
}
.van-cell__value {
display: flex;
justify-content: flex-end;
color: var(--van-cell-text-color);
overflow: hidden;
span {
text-align: justify;
}
}
}
:deep(.tag-label) {
font-size: 1.4rem;
}
.list {
}
</style>
<script setup lang="ts" name="LeaveListItem">
import { ref, reactive, computed, onMounted } from 'vue'
import { parseTime } from '../../../common/utils/ruoyi'
const emit = defineEmits<{
'close': [item: any]
'revoke': [item: any]
}>()
const props = defineProps<{
item: any
audit_status: any
request_leave_type: any
userInfo: any
}>()
const now = new Date().getTime()
// 已销假状态
const hasLeaved = computed(() => {
const endTime = new Date(props.item.endTime.replace(/-/g, '/')).getTime() + 1000 * 3600 * 24 * 7
return now >= endTime || props.item.backAudit === '3'
})
function onClose() {
emit('close', props.item)
}
function onRevoke() {
emit('revoke', props.item)
}
</script>
<template>
<div class="list-item">
<div class="list-item__top">
<div class="list-item__top-title">
<div class="list-item__top-title-firstword">{{ props.userInfo.nickName.substr(0, 1) }}</div>
<div class="list-item__top-title-label">{{ props.userInfo.nickName }}提交的跨天外出申请</div>
</div>
<div class="list-item__top-time">{{ parseTime(props.item.createTime, '{y}-{m}-{d}') }}</div>
</div>
<div class="list-item__address">
跨天外出类型:<DictTag :tag="false" :options="request_leave_type" :value="props.item.leaveType ?? ''" />
</div>
<div class="list-item__date">开始日期:{{ parseTime(props.item.beginTime, '{y}-{m}-{d}') }}</div>
<!-- <div class="list-item__date">结束时间:{{ props.item.businessTripStatus === '2' ? props.item.realEndTime : props.item.endTime }}</div> -->
<div class="list-item__date">结束日期:{{ parseTime(props.item.endTime, '{y}-{m}-{d}') }}</div>
<div class="list-item__days">跨天外出时长:{{ props.item.duringTime }}</div>
<div class="list-item__detail">
<div>跨天外出事由:</div>
<div class="list-item__detail-content">{{ props.item.reason }}</div>
</div>
<van-divider style="margin: 0.8rem 0;" />
<div class="list-item__status">
<DictTag :options="props.audit_status" :value="props.item.auditStatus" />
<uv-button
v-if="props.item.auditStatus === '2'"
type="primary"
size="small"
beautify
@tap.stop="onRevoke">撤办</uv-button>
<!-- <template v-if="props.item.auditStatus === '3'">
<uv-button
v-if="!hasLeaved"
type="primary"
size="small"
beautify
@tap.stop="onClose">销假</uv-button>
<div v-else>已销假</div>
</template> -->
</div>
</div>
</template>
<style lang="less" scoped>
@marginTop: 16rpx; /* 0.8rem × 20 = 16rpx */
.list-item {
margin-top: 24rpx; /* 1.2rem × 20 = 24rpx */
background-color: #fff;
border-radius: 24rpx;
padding: 32rpx 36rpx 16rpx; /* 1.6rem×20=32rpx | 1.8rem×20=36rpx | @marginTop=16rpx */
font-size: 28rpx;
box-shadow:0 4rpx 40rpx rgba(64, 103, 251, 0.14);
}
.list-item__top {
display: flex;
justify-content: space-between;
align-items: center;
}
.list-item__top-title {
flex: 1;
display: flex;
align-items: center;
overflow: hidden;
}
.list-item__top-title-firstword {
display: flex;
justify-content: center;
align-items: center;
margin-right: 12rpx; /* 保留原rem单位(非用户要求转换的数值) */
width: 52rpx; /* 2.6rem × 20 = 52rpx */
height: 52rpx; /* 2.6rem × 20 = 52rpx */
font-size: 20rpx; /* 保留原rem单位(非用户要求转换的数值) */
color: #fff;
background-color: #007aff;
border-radius: 12rpx; /* 保留原rem单位(非用户要求转换的数值) */
}
.list-item__top-label {
flex: 1;
overflow: hidden;
font-size: 28rpx; /* 1.4rem × 20 = 28rpx */
color: #333;
font-weight: bold;
white-space: nowrap;
text-overflow: ellipsis;
}
.list-item__top-time {
margin-left: 12rpx; /* 保留原rem单位(非用户要求转换的数值) */
color: #999;
font-size: 24rpx; /* 1.2rem × 20 = 24rpx */
}
.list-item__address {
display: flex;
margin-top: 16rpx; /* @marginTop=16rpx */
color: #999;
}
.list-item__date {
margin-top: 16rpx; /* @marginTop=16rpx */
display: flex;
justify-content: space-between;
color: #999;
}
.list-item__date-item {
white-space: nowrap;
}
.list-item__date-item:last-child {
margin-left: 20rpx; /* 保留原rem单位(非用户要求转换的数值) */
}
.list-item__days {
margin-top: 16rpx; /* @marginTop=16rpx */
color: #999;
}
.list-item__detail {
margin-top: 16rpx; /* @marginTop=16rpx */
display: flex;
color: #999;
}
.list-item__detail-content {
flex: 1;
overflow: hidden;
word-break: break-all;
}
.list-item__status {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 16rpx; /* @marginTop=16rpx */
position: relative;
}
.list-item__top-title-label{
flex: 1;
overflow: hidden;
font-size: 28rpx;
color: #333;
font-weight: bold;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>
++ "b/approve/modules/attendance/outRequest/\350\267\250\345\244\251\345\244\226\345\207\272"
...@@ -8,19 +8,51 @@ const form = reactive({ ...@@ -8,19 +8,51 @@ const form = reactive({
backTime: '', // 结束时间 backTime: '', // 结束时间
differHour: '', // 提前返回时长(小时) differHour: '', // 提前返回时长(小时)
remark: '', // 备注 remark: '', // 备注
leaveRequestId: '' // 请假ID leaveRequestId: '', // 请假ID
backTimeHalfLabel: '下午',
backTimeHalf: 'PM'
}) })
const loading = ref(false) const loading = ref(false)
const backTimeStamp = ref(0) const backTimeStamp = ref(0)
const leaveType = ref('')
onLoad((options) => { onLoad((options) => {
if (options.id) { if (options.id) {
form.leaveRequestId = options.id form.leaveRequestId = options.id
} }
if(options.leaveType){
leaveType.value = options.leaveType
}
}) })
const backTimeHalf = ref('PM')
const backTimeHalfRef = ref()
const HalfColumns = ref([
[
{
value: 'AM',
label: '上午'
},
{
value: 'PM',
label: '下午'
}
]
])
const showBackTimeHalf = ()=>{
backTimeHalfRef?.value.open()
}
const onConfirmBackTimeHalf = (e: any) => {
console.log(e)
form.backTimeHalf = e.value[0].value
form.backTimeHalfLabel = e.value[0].label
}
const formatter = (type, value) => { const formatter = (type, value) => {
if (type === 'year') { if (type === 'year') {
...@@ -58,6 +90,13 @@ function timestampToTime(timestamp: number) { ...@@ -58,6 +90,13 @@ function timestampToTime(timestamp: number) {
function onSubmit() { function onSubmit() {
formRef.value?.validate().then(() => { formRef.value?.validate().then(() => {
loading.value = true loading.value = true
form.backTime = form.backTimeHalf === 'AM' ? form.backTime + ' 12:00' : form.backTime + ' 17:00'
uni.showLoading({ title: '提交中...' }) uni.showLoading({ title: '提交中...' })
addLeaveRequestBack(form).then(res => { addLeaveRequestBack(form).then(res => {
...@@ -102,11 +141,11 @@ const showBackTimePickerRef = () =>{ ...@@ -102,11 +141,11 @@ const showBackTimePickerRef = () =>{
<view class="container__card flex"> <view class="container__card flex">
<uv-form ref="formRef" labelWidth="140" label-position="top" :model="form" :rules="rules"> <uv-form ref="formRef" labelWidth="140" label-position="top" :model="form" :rules="rules">
<!-- 结束时间选择 --> <!-- 结束时间选择 -->
<uv-form-item label="结束日期" prop="backTime" required @click="showBackTimePickerRef"> <uv-form-item label="销假时间" prop="backTime" required @click="showBackTimePickerRef">
<uv-input <uv-input
v-model="form.backTime" v-model="form.backTime"
disabled disabled
placeholder="点击选择结束日期" placeholder="点击选择销假时间"
border="bottom" border="bottom"
disabledColor="#fff" disabledColor="#fff"
...@@ -120,17 +159,40 @@ const showBackTimePickerRef = () =>{ ...@@ -120,17 +159,40 @@ const showBackTimePickerRef = () =>{
<uv-datetime-picker <uv-datetime-picker
ref="backTimeRef" ref="backTimeRef"
v-model="backTimeStamp" v-model="backTimeStamp"
mode="datetime" mode="date"
:formatter="formatter" :formatter="formatter"
@confirm="onConfirmBackTime" @confirm="onConfirmBackTime"
/> />
<uv-form-item label="开始上午/下午" prop="backTimeHalf" required @click="showBackTimeHalf">
<uv-input
v-model="form.backTimeHalfLabel"
disabled
placeholder="选择请假类型"
border="bottom"
disabledColor="#fff"
/>
<template v-slot:right>
<uv-icon name="arrow-right"></uv-icon>
</template>
</uv-form-item>
<uv-picker
ref="backTimeHalfRef"
v-model="backTimeHalf"
:columns="HalfColumns"
keyName="label"
@confirm="onConfirmBackTimeHalf"
/>
<!-- 提前返回时长 --> <!-- 提前返回时长 -->
<uv-form-item label="提前返回时长(小时)" prop="differHour" required> <uv-form-item v-if="leaveType === '8' || leaveType === '9'" label="未使用请假时长(天)" prop="differHour" required>
<uv-input <uv-input
v-model="form.differHour" v-model="form.differHour"
type="number" type="number"
placeholder="请输入提前返回时长(小时)" placeholder="请输入提前返回时长()"
border="bottom" border="bottom"
/> />
</uv-form-item> </uv-form-item>
......
...@@ -16,7 +16,7 @@ function onClickItem(item) { ...@@ -16,7 +16,7 @@ function onClickItem(item) {
<template> <template>
<div class="list"> <div class="list">
<template v-for="(item, index) in props.list" :key="index"> <!-- <template v-for="(item, index) in props.list" :key="index">
<div class="list-item" @click="onClickItem(item)"> <div class="list-item" @click="onClickItem(item)">
<div class="list-item-title"> <div class="list-item-title">
<div class="list-item-title-label">申请时间:</div> <div class="list-item-title-label">申请时间:</div>
...@@ -35,39 +35,43 @@ function onClickItem(item) { ...@@ -35,39 +35,43 @@ function onClickItem(item) {
<div class="list-item-remark-content">{{ item.remark }}</div> <div class="list-item-remark-content">{{ item.remark }}</div>
</div> </div>
</div> </div>
</template> </template> -->
<div class="list-item" v-for="(item, index) in props.list" :key="index" @click="onClickItem(item)">
<van-cell-group >
<van-cell title="申请时间:" :value="item.applyTime" />
<van-cell title="申请时间:" :value="item.backTime" />
<van-cell title="提前返回天数:" :value="item.differHour" />
<van-cell title="备注:" :value="item.remark" />
</van-cell-group>
</div>
<van-empty v-if="!props.list?.length" description="暂无数据" /> <van-empty v-if="!props.list?.length" description="暂无数据" />
</div> </div>
</template> </template>
<style lang="less" scoped> <style lang="less" scoped>
.list { .list-item{
padding: var(--container-pd); margin-top: 50rpx;
&-item { }
margin-bottom: var(--container-pd);
padding: var(--container-pd);
border-radius: 24rpx; :deep(.van-cell) {
box-shadow: 0 4rpx 40rpx rgba(64, 103, 251, 0.14); .van-cell__title {
&-title { margin-right: 1rem;
display: flex; flex: none;
align-items: center; }
margin-bottom: 0.6rem; .van-cell__value {
&-value { display: flex;
color: var(--van-gray-7); justify-content: flex-end;
} color: var(--van-cell-text-color);
} overflow: hidden;
&-remark { span {
display: flex; text-align: justify;
justify-content: space-between;
&-label {
width: 7rem;
text-align: right;
}
&-content {
flex: 1;
overflow: hidden;
color: var(--van-gray-7);
}
} }
} }
} }
......
<script setup lang="ts">
import { ref, reactive, computed, watch,onMounted, onUnmounted } from 'vue'
import { storeToRefs } from 'pinia'
import { onLoad } from '@dcloudio/uni-app'
import useUserStore from '@/store/modules/user'
import { addCrossDayOutRequest, updateCrossDayOutRequest, getCrossDayOutRequestDetail,precomputeLeaveDays,getRestTime } from '@/api/attendance/outRequest'
import { selectEmployeesDetailByCode } from '@/api/user'
import { parseTime, selectDictLabel } from '../../common/utils/ruoyi'
import { useDict } from '../../common/utils/dict'
import UploadImage from '../../components/Upload/UploadImage.vue'
const { request_leave_type, breast_feed_type } = useDict('request_leave_type', 'breast_feed_type')
const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore)
const dateFormat = {
'year': '年',
'month': '月',
'day': '日',
'hour': '时',
'minute': '分'
}
const formRef = ref()
const detail = ref<any>({})
const form = reactive<any>({
id: '', // 修改编辑
auditStatus: '0', // 状态
userName: userInfo.value.nickName,
employeesCode: userInfo.value.userCode,
beginTime: '', // 结束时间
startHalf: 'AM',
startHalfLabel: '上午',
endHalf: 'PM',
endHalfLabel: '下午',
beginTimeStamp: '',
endTimeStamp: '',
endTime: '', // 结束时间
duringTime: '', // 跨天外出时长(小时)
reason: '', // 出差事由
agentName: '', // 代理人
urgentHandingOfAffairs: '', // 岗位紧急处理事务
fileList: [] // 图片
})
const startHalf = ref('')
const endHalf = ref('')
const HalfColumns = ref([
[
{
value: 'AM',
label: '上午'
},
{
value: 'PM',
label: '下午'
}
]
])
const loading = ref(false)
const activeTabStart = ref(0)
const activeTabEnd = ref(0)
const now = new Date()
const nowStamp = now.getTime()
const beginDate = ref(parseTime(now, '{y}-{m}-{d}').split('-')) // 绑定picker选择开始日期
const beginTime = ref(parseTime(now, '{h}:{i}').split(':')) // 绑定picker选择开始时间
const endDate = ref<string[]>([]) // 绑定picker选择结束日期
const endTime = ref<string[]>([]) // 绑定picker选择结束时间
const minDateEnd = computed(() => new Date(new Date(beginDate.value.join('/') + ' ' + beginTime.value.join(':'))).getTime() + 1000 * 60 * 30)
const show = reactive({
beginTime: false,
endTime: false,
})
onMounted(()=>{
console.log('userinfo',userInfo.value)
})
function computeDuringDays() {
try {
if (!form.beginTime || !form.endTime) {
return
}
// use backend precompute for accurate result
const beginDate = String(form.beginTime).split(' ')[0]
const endDate = String(form.endTime).split(' ')[0]
const params = {
employeesCode: userInfo.value.userCode,
beginDate: beginDate,
startHalf: form.startHalf || 'AM',
endDate: endDate,
endHalf: form.endHalf || 'PM'
}
precomputeLeaveDays(params).then(res => {
if (res && res.data != null) {
form.duringTime = Number(res.data)
}
}).catch(err => {
console.error('precomputeLeaveDays error', err)
})
} catch (e) {
console.error('computeDuringDays error', e)
}
}
watch(() => [form.beginTime, form.startHalf, form.endTime, form.endHalf], () => {
computeDuringDays()
})
function formatterDate(type, option) {
option.text += dateFormat[type]
return option
}
function formatterTime(type, option) {
option.text += dateFormat[type]
return option
}
const beginDateStr = ref('')
const beginTimeStr = ref('')
const endDateStr = ref('') // 用于日期选择器
const endTimeStr = ref('')
const formatter = (type, value) =>{
if (type === 'year') {
return `${value}年`
}
if (type === 'month') {
return `${value}月`
}
if (type === 'day') {
return `${value}日`
}
if (type === 'hour') {
return `${value}时`
}
if (type === 'minute') {
return `${value}分`
}
return value
}
onLoad((option) => {
if (option.id) {
uni.showLoading({
title: '请稍等...'
});
getCrossDayOutRequestDetail(option.id).then(res => {
uni.hideLoading();
const data = res.data
form.id = data.id
// form.auditStatus = data.auditStatus
// form.leaveType = data.leaveType
// form.breastFeedType = data.breastFeedType
form.beginTime = data.beginTime
form.endTime = data.endTime
// if (isBreastFeed.value) {
// form.beginTime = form.beginTime.replace(/\s.*$/, '')
// form.endTime = form.endTime.replace(/\s.*$/, '')
// }
form.duringTime = data.duringTime
form.agentName = data.agentName
form.reason = data.reason
form.fileList = data.fileList || []
beginDate.value = parseTime(data.beginTime, '{y}-{m}-{d}').split('-')
beginTime.value = parseTime(data.beginTime, '{h}:{i}').split(':')
endDate.value = parseTime(data.endTime, '{y}-{m}-{d}').split('-')
endTime.value = parseTime(data.endTime, '{h}:{i}').split(':')
beginDateStr.value = beginDate.value.join('-')
beginTimeStr.value = beginTime.value.join(':')
endDateStr.value = endDate.value.join('-')
endTimeStr.value = endTime.value.join(':')
})
}
})
// 过滤开始时间 时分
function filterTimeBegin(type, options, values) {
return type === 'minute' ? options.filter(option => Number(option.value) % 30 === 0) : options
}
// 过滤结束时间 时分
function filterTimeEnd(type, options, values) {
const begin = new Date(beginDate.value.join('/') + ' ' + beginTime.value.join(':')).getTime()
// 小时
if (type === 'hour') {
return options.filter(option => {
const end = new Date(endDate.value.join('/') + ' ' + option.value + ':30').getTime()
return end > begin
})
}
// 分
return options.filter(option => {
if (!values[0]) return false
const end = new Date(endDate.value.join('/') + ' ' + values[0] + ':' + option.value).getTime()
return end >= begin + 1000 * 60 * 30 && Number(option.value) % 30 === 0
})
}
onUnmounted(() => {
uni.hideLoading()
})
// 获取用户个人信息
selectEmployeesDetailByCode({
employeesCode: userInfo.value.userCode
}).then(res => {
detail.value = res.data || {}
})
// 选择跨天外出开始日期时间 - 确认
function onConfirmBegin() {
// 更新数组值
beginDate.value = beginDateStr.value.split('-')
beginTime.value = beginTimeStr.value.split(':')
form.beginTime = `${beginDateStr.value}${' ' + beginTimeStr.value}`
show.beginTime = false
activeTabStart.value = 0
if (form.beginTime >= form.endTime) {
form.endTime = ''
endDateStr.value = parseTime(minDateEnd.value, '{y}-{m}-{d}')
endTimeStr.value = ''
}
}
// 选择跨天外出结束日期时间 - 确认
function onConfirmEnd() {
endDate.value = endDateStr.value.split('-')
endTime.value = endTimeStr.value.split(':')
// 更新表单数据
form.endTime = `${endDateStr.value}${' ' + endTimeStr.value}`
show.endTime = false
activeTabEnd.value = 0
}
// 校验失败
function onFailed(e) {
console.log('error', e)
}
// 校验结果
function onSubmit(e) {
formRef.value?.validate().then(() => {
loading.value = true
uni.showLoading({
title: '提交中...'
})
const requstData = JSON.parse(JSON.stringify(form))
if (form.fileList.length) {
requstData.fileList = requstData.fileList.map(item => ({
url: item.url,
name: item.name,
fileSize: item.fileSize,
fileType: item.fileType
}))
}
// if (isBreastFeed.value) {
requstData.beginTime += ' 00:00'
requstData.endTime += ' 00:00'
// }
console.log('requstData',requstData)
// return
const requestMethod = form.id ? updateCrossDayOutRequest : addCrossDayOutRequest
requestMethod(requstData).then(res => {
console.log(123123,res)
if(res.code === 200){
uni.showToast({title: res.msg})
loading.value = false
setTimeout(() => {
uni.navigateBack({delta: 1})
}, 1000)
}else{
uni.showToast({title: res.msg,icon: 'none'})
loading.value = false
}
}).catch(() => {
uni.hideLoading()
loading.value = false
})
})
}
// 新增的变量
const activeBeginTab = ref(0) // 0-日期,1-时间
const activeEndTab = ref(0) // 0-日期,1-时间
const beginTimeRef:any = ref(null)
// 修改打开开始时间选择器的方法
function openBeginPicker() {
beginTimeRef.value.open()
activeBeginTab.value = 0
}
const endTimeRef:any = ref(null)
// 修改打开结束时间选择器的方法
function openEndPicker() {
endTimeRef.value.open()
activeEndTab.value = 0
}
// 点击提交
function onClickSubmit() {
formRef.value?.validate().then(() => {
onSubmit({errors: null})
}).catch(err => {
onFailed(err)
})
}
const leaveTypeRef:any = ref(null)
// const showLeaveType = ()=>{
// leaveTypeRef.value.open()
// }
const confirmBeginTime = (e)=>{
console.log(e)
form.beginTime =timestampToTime(e.value)
}
const confirmEndTime = (e)=>{
console.log(e)
form.endTime =timestampToTime(e.value)
}
function timestampToTime(timestamp) {
const date = new Date(timestamp); // 时间戳转 Date 对象
const year = date.getFullYear(); // 年
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月(补零)
const day = String(date.getDate()).padStart(2, '0'); // 日(补零)
const hours = String(date.getHours()).padStart(2, '0'); // 时(补零)
const minutes = String(date.getMinutes()).padStart(2, '0'); // 分(补零)
const seconds = String(date.getSeconds()).padStart(2, '0'); // 秒(补零)
return `${year}-${month}-${day}`;
}
const startHalfRef:any = ref(null)
const showStartHalf = ()=>{
startHalfRef?.value.open()
}
const onConfirmStartHalf = (e:any)=>{
console.log(e)
form.endHalf = e.value[0].value
form.endHalfLabel = e.value[0].label
}
const endHalfRef:any = ref(null)
const showEndHalf = ()=>{
endHalfRef?.value.open()
}
const onConfirmEndHalf = (e:any)=>{
console.log(e)
form.endHalf = e.value[0].value
form.endHalfLabel = e.value[0].label
}
</script>
<template>
<div class="container full float-bottom">
<div class="container__body">
<div class="container__card flex form-card-container">
<uv-form ref="formRef" labelWidth="140" label-position="top" label :model="form">
<!-- 选择类型 -->
<!-- <uv-form-item customStyle="padding: 20rpx 32rpx;" label="跨天外出类型" prop="leaveType" required @click="showLeaveType">
<uv-input
v-model="leaveTypeName"
disabled
placeholder="选择跨天外出类型"
border="bottom"
disabledColor="#fff"
/>
<template v-slot:right>
<uv-icon name="arrow-right"></uv-icon>
</template>
</uv-form-item> -->
<!--
<uv-picker
ref="leaveTypeRef"
v-model="show.leaveType"
:columns="[request_leave_type]"
keyName="label"
@confirm="onConfirmLeaveType"
@close="show.leaveType = false"
/> -->
<!-- 选择哺乳假类型 -->
<!-- 开始时间 -->
<uv-form-item customStyle="padding: 20rpx 32rpx;" label="开始日期" prop="beginTime" required @click="openBeginPicker">
<uv-input
v-model="form.beginTime"
disabled
placeholder="点击选择开始日期"
border="bottom"
disabledColor="#fff"
/>
<template v-slot:right>
<uv-icon name="arrow-right"></uv-icon>
</template>
</uv-form-item>
<uv-datetime-picker ref="beginTimeRef" :formatter="formatter" v-model="form.beginTimeStamp" mode="date" @confirm="confirmBeginTime">
</uv-datetime-picker>
<uv-form-item customStyle="padding: 20rpx 32rpx;" label="开始上午/下午" prop="startHalf" required @click="showStartHalf">
<uv-input
v-model="form.startHalfLabel"
disabled
placeholder="选择跨天外出类型"
border="bottom"
disabledColor="#fff"
/>
<template v-slot:right>
<uv-icon name="arrow-right"></uv-icon>
</template>
</uv-form-item>
<uv-picker
ref="startHalfRef"
v-model="startHalf"
:columns="HalfColumns"
keyName="label"
@confirm="onConfirmStartHalf"
/>
<!-- 结束时间 -->
<uv-form-item customStyle="padding: 20rpx 32rpx;" label="结束日期" prop="endTime" required @click="openEndPicker">
<uv-input
v-model="form.endTime"
disabled
placeholder="点击选择结束日期"
border="bottom"
disabledColor="#fff"
/>
<template v-slot:right>
<uv-icon name="arrow-right"></uv-icon>
</template>
</uv-form-item>
<uv-datetime-picker ref="endTimeRef" :formatter="formatter" v-model="form.endTimeStamp" mode="date" @confirm="confirmEndTime">
</uv-datetime-picker>
<uv-form-item customStyle="padding: 20rpx 32rpx;" label="结束上午/下午" prop="endHalf" required @click="showEndHalf">
<uv-input
v-model="form.endHalfLabel"
disabled
border="bottom"
disabledColor="#fff"
/>
<template v-slot:right>
<uv-icon name="arrow-right"></uv-icon>
</template>
</uv-form-item>
<uv-picker
ref="endHalfRef"
v-model="endHalf"
:columns="HalfColumns"
keyName="label"
@confirm="onConfirmEndHalf"
/>
<!-- 跨天外出时长(小时) -->
<uv-form-item customStyle="padding: 20rpx 32rpx;" label="跨天外出时长(天)" prop="duringTime" required>
<uv-input
v-model="form.duringTime"
disabled
placeholder="跨天外出时长(天)"
border="bottom"
/>
</uv-form-item>
<!-- 代理人 -->
<!-- <uv-form-item customStyle="padding: 20rpx 32rpx;" label="代理人" prop="agentName" required>
<uv-input
v-model="form.agentName"
placeholder="请输入代理人"
border="bottom"
/>
</uv-form-item> -->
<!-- 跨天外出事由 -->
<uv-form-item customStyle="padding: 20rpx 32rpx;" label="事由" prop="reason" required>
<uv-textarea
v-model="form.reason"
placeholder="请输入事由"
maxlength="300"
count
border="bottom"
/>
</uv-form-item>
<!-- 岗位紧急处理事务 -->
<!-- <uv-form-item customStyle="padding: 20rpx 32rpx;" label="岗位紧急处理事务" prop="urgentHandingOfAffairs" required>
<uv-textarea
v-model="form.urgentHandingOfAffairs"
placeholder="请输入岗位紧急处理事务"
maxlength="500"
count
border="bottom"
/>
</uv-form-item> -->
<!-- 图片上传 -->
<uv-form-item customStyle="padding: 20rpx 32rpx;" label="图片" prop="uploader" >
<UploadImage v-model="form.fileList" />
</uv-form-item>
</uv-form>
</div>
</div>
<uv-button
:loading="loading"
class="button-submit float-bottom"
shape="circle"
color="linear-gradient(to bottom, #4773FC, #6D9BFD)"
customStyle="margin-top: 200rpx"
@click="onSubmit">提交</uv-button>
</div>
</template>
<style lang="scss" scoped>
.container {
padding: 20rpx;
box-sizing: border-box;
}
</style>
\ No newline at end of file
<script setup lang="ts" name="LeaveDetail">
import { ref } from 'vue'
// import { useRoute } from 'vue-router'
import DetailFlow from './modules/DetailFlow.vue'
import { onLoad } from '@dcloudio/uni-app'
// const route = useRoute()
const id = ref('')
const instanceId = ref('')
onLoad((option) => {
console.log('option',option)
id.value = option.id
instanceId.value = option.instanceId
// console.log(route.query)
})
</script>
<template>
<div class="container full">
<div class="container__body">
<div class="container__card flex">
<DetailFlow v-if="id && instanceId" :id="id" :instance-id="instanceId" />
</div>
</div>
</div>
</template>
<style lang="less" scoped>
</style>
<script setup lang="ts" name="LeaveList">
import { ref } from 'vue'
// import { useRouter } from 'vue-router'
// import { showConfirmDialog, showSuccessToast } from 'vant'
import { useUserStore } from '@/store/modules/user'
import { getCrossDayOutRequestlist } from '@/api/attendance/outRequest'
import { revokeProcess } from '@/api/flowEngine/flowInterface'
import { useDict } from '../../common/utils/dict'
import PullList from '../../components/List/PullList.vue'
import LeaveListItem from './modules/LeaveListItem.vue'
import customFab from '@/components/customFab.vue'
const { audit_status, request_leave_type } = useDict('audit_status', 'request_leave_type')
// console.log(audit_status)
const userStore = useUserStore()
// const router = useRouter()
const pullListRef = ref<InstanceType<typeof PullList>>()
const queryParams = ref({
pageNum: 1,
pageSize: 5,
reason: ''
// employeesCode: userInfo.value.userCode
})
// 请求方法,传入PullList组件,需返回{rows: [], total: number}
function onRequest(query?: any, isRefresh?: boolean): Promise<{rows: any[], total: number}> {
return getCrossDayOutRequestlist(query)
}
// 跨天外出详情
function onClickItem(item) {
console.log('123')
// 已退回 和 已撤回
if (['5', '6'].includes(item.auditStatus)) {
uni.navigateTo({
url:'/attendance/outRequest/add?id=' + item.id,
})
return
}
console.log('123')
uni.navigateTo({
url:'/attendance/outRequest/detail?id=' + item.id + '&instanceId=' + item.instanceId
})
}
// // 销假
// function onClose(item) {
// // router.push({ path: '/attendance/leave/close',
// // query: {
// // id: item.id,
// // beginTime: item.beginTime,
// // endTime: item.endTime,
// // leaveType: item.leaveType
// // }
// // })
// uni.navigateTo({
// url:'/attendance/leave/close?id=' + item.id + '&beginTime=' + item.beginTime + '&endTime=' + item.endTime + '&leaveType=' + item.leaveType
// })
// }
// 撤办
function onRevoke(item) {
uni.showModal({
title: '撤办',
content: `隔天外出:${item.reason},确认撤办吗?`,
success: (res) => {
if (res.confirm) {
return new Promise((resolve, reject) => {
revokeProcess({
instanceId: item.instanceId
}).then(() => {
uni.showToast({
title: '撤办成功',
icon: 'success'
})
setTimeout(() => {
resolve(true)
pullListRef.value?.refresh()
}, 500)
}).catch(() => {
reject(false)
})
})
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
// 点击添加
function onClickAdd() {
uni.navigateTo({
url:'/attendance/outRequest/add',
})
}
function handleSearchChange(e) {
queryParams.value.reason = e.detail // 手动更新数据:ml-citation{ref="2,8" data="citationList"}
}
function onSearch() {
pullListRef.value?.refresh()
}
</script>
<template>
<div class="query-wrap">
<div class="search-pad">
<van-search
:value="queryParams.reason"
@change="handleSearchChange"
shape="round"
placeholder="请输入搜索关键词"
useActionSlot
@search="onSearch"
@clear="onSearch">
<template #action>
<div class="search-btn" @click="onSearch">搜索</div>
</template>
</van-search>
</div>
</div>
<!-- </div> -->
<PullList ref="pullListRef" v-model:query-string="queryParams" :isFixed="false" zHeight="80vh" :request-method="onRequest">
<template #default="{ item, index }">
<div style="padding: 0 30rpx;" >
<LeaveListItem
:item="item"
:user-info="userStore.userInfo"
:audit_status="audit_status"
:request_leave_type="request_leave_type"
@revoke.stop="onRevoke"
@tap="onClickItem(item)" />
</div>
<!-- @close.stop="onClose" -->
</template>
</PullList>
<customFab icon @click="onClickAdd" />
</template>
<style lang="less" scoped>
.search-pad {
padding: 30rpx;
box-sizing: border-box;
}
:deep(.van-search) {
position: relative;
z-index: 1;
padding: 20rpx;
// min-height: 4.4rem;
border-radius:24rpx;
box-shadow: 0 4rpx 40rpx rgba(64, 103, 251, 0.14);
// overflow: hidden;
}
.search-btn {
padding: 0 16.6rpx;
}
</style>
<script setup lang="ts" name="LeaveDetailFlow">
/* 跨天外出详情 */
import { ref, reactive, computed, onMounted } from 'vue'
import { parseTime } from '/common/utils/ruoyi'
import { getFlowChart } from '@/api/flowEngine/flowInterface'
import { getCrossDayOutRequestDetail } from '@/api/attendance/outRequest'
import { selectDictLabel } from '@/common/utils/ruoyi'
import { useDict } from '../../../common/utils/dict'
import FlowTimeline from '../../../components/Flow/FlowTimeline.vue'
// const router = useRouter()
const props = defineProps<{
id: string
instanceId: string
}>()
const { request_leave_type, breast_feed_type } = useDict('request_leave_type', 'breast_feed_type')
const detail = ref<any>({})
const detailClose = ref<any>({})
const nodeData = ref<any>()
const activeTab = ref('')
getCrossDayOutRequestDetail(props.id).then(res => {
detail.value = res.data
})
getFlowChart({ instanceId: props.instanceId }).then(res => {
nodeData.value = res.data
})
// 预览
function onPreview(index) {
// showImagePreview({
// images: detail.value.fileList.map(item => item.url),
// startPosition: index
// })
uni.previewImage({
urls:detail.value.fileList.map(item => item.url),
current:index
})
}
// 点击销假列表
function onDetailClose(item) {
// router.push({
// path: '/attendance/leave/close-detail',
// query: {
// id: item.id,
// instanceId: item.instanceId
// }
// })
uni.navigateTo({
url:'/attendance/leave/close-detail?id=' + item.id + '&instanceId=' + item.instanceId
})
}
</script>
<template>
<div class="container__card flex">
<van-cell-group>
<van-cell title="开始日期" :value="parseTime(detail.beginTime, '{y}-{m}-{d}')" />
<van-cell title="开始上午/下午" :value="detail.startHalf === 'AM' ? '上午' : '下午'" />
<van-cell title="结束日期" :value="parseTime(detail.endTime, '{y}-{m}-{d}')" />
<van-cell title="结束上午/下午" :value="detail.startHalf === 'PM' ? '上午' : '下午'" />
<van-cell title="跨天外出时长">
{{ detail.duringTime }}
</van-cell>
<!-- <van-cell title="代理人" :value="detail.agentName" /> -->
<van-cell title="跨天外出事由" :value="detail.reason" />
<!-- <van-cell title="岗位紧急处理事务" :value="detail.urgentHandingOfAffairs || '无'" /> -->
<van-grid
v-if="detail.fileList?.length"
:border="false"
:column-num="3"
class="grid">
<template v-for="(item, index) in detail.fileList" :key="index">
<van-grid-item>
<van-image :src="item.url" @click="onPreview(index)" />
</van-grid-item>
</template>
</van-grid>
</van-cell-group>
<FlowTimeline :node-data="nodeData" />
</div>
</template>
<style lang="less" scoped>
.grid {
:deep(.van-image) {
position: relative;
width: 100%;
height: 0;
padding-bottom: 100%;
border-radius: 0.6rem;
box-shadow: 0.2rem 0.2rem 0.5rem rgba(0,0,0,0.5);
overflow: hidden;
.van-image__img {
position: absolute;
object-fit: cover;
}
}
}
:deep(.van-cell) {
.van-cell__title {
margin-right: 1rem;
flex: none;
}
.van-cell__value {
display: flex;
justify-content: flex-end;
color: var(--van-cell-text-color);
overflow: hidden;
span {
text-align: justify;
}
}
}
:deep(.tag-label) {
font-size: 1.4rem;
}
.list {
}
</style>
<script setup lang="ts" name="LeaveListItem">
import { ref, reactive, computed, onMounted } from 'vue'
import { parseTime } from '../../../common/utils/ruoyi'
const emit = defineEmits<{
'close': [item: any]
'revoke': [item: any]
}>()
const props = defineProps<{
item: any
audit_status: any
request_leave_type: any
userInfo: any
}>()
const now = new Date().getTime()
// 已销假状态
const hasLeaved = computed(() => {
const endTime = new Date(props.item.endTime.replace(/-/g, '/')).getTime() + 1000 * 3600 * 24 * 7
return now >= endTime || props.item.backAudit === '3'
})
function onClose() {
emit('close', props.item)
}
function onRevoke() {
emit('revoke', props.item)
}
</script>
<template>
<div class="list-item">
<div class="list-item__top">
<div class="list-item__top-title">
<div class="list-item__top-title-firstword">{{ props.userInfo.nickName.substr(0, 1) }}</div>
<div class="list-item__top-title-label">{{ props.userInfo.nickName }}提交的跨天外出申请</div>
</div>
<div class="list-item__top-time">{{ parseTime(props.item.createTime, '{y}-{m}-{d}') }}</div>
</div>
<!-- <div class="list-item__address">
跨天外出类型:<DictTag :tag="false" :options="request_leave_type" :value="props.item.leaveType ?? ''" />
</div> -->
<div class="list-item__date">开始日期:{{ parseTime(props.item.beginTime, '{y}-{m}-{d}') }}</div>
<!-- <div class="list-item__date">结束时间:{{ props.item.businessTripStatus === '2' ? props.item.realEndTime : props.item.endTime }}</div> -->
<div class="list-item__date">结束日期:{{ parseTime(props.item.endTime, '{y}-{m}-{d}') }}</div>
<div class="list-item__days">跨天外出时长:{{ props.item.duringTime }}</div>
<div class="list-item__detail">
<div>跨天外出事由:</div>
<div class="list-item__detail-content">{{ props.item.reason }}</div>
</div>
<van-divider style="margin: 0.8rem 0;" />
<div class="list-item__status">
<DictTag :options="props.audit_status" :value="props.item.auditStatus" />
<uv-button
v-if="props.item.auditStatus === '2'"
type="primary"
size="small"
beautify
@tap.stop="onRevoke">撤办</uv-button>
<!-- <template v-if="props.item.auditStatus === '3'">
<uv-button
v-if="!hasLeaved"
type="primary"
size="small"
beautify
@tap.stop="onClose">销假</uv-button>
<div v-else>已销假</div>
</template> -->
</div>
</div>
</template>
<style lang="less" scoped>
@marginTop: 16rpx; /* 0.8rem × 20 = 16rpx */
.list-item {
margin-top: 24rpx; /* 1.2rem × 20 = 24rpx */
background-color: #fff;
border-radius: 24rpx;
padding: 32rpx 36rpx 16rpx; /* 1.6rem×20=32rpx | 1.8rem×20=36rpx | @marginTop=16rpx */
font-size: 28rpx;
box-shadow:0 4rpx 40rpx rgba(64, 103, 251, 0.14);
}
.list-item__top {
display: flex;
justify-content: space-between;
align-items: center;
}
.list-item__top-title {
flex: 1;
display: flex;
align-items: center;
overflow: hidden;
}
.list-item__top-title-firstword {
display: flex;
justify-content: center;
align-items: center;
margin-right: 12rpx; /* 保留原rem单位(非用户要求转换的数值) */
width: 52rpx; /* 2.6rem × 20 = 52rpx */
height: 52rpx; /* 2.6rem × 20 = 52rpx */
font-size: 20rpx; /* 保留原rem单位(非用户要求转换的数值) */
color: #fff;
background-color: #007aff;
border-radius: 12rpx; /* 保留原rem单位(非用户要求转换的数值) */
}
.list-item__top-label {
flex: 1;
overflow: hidden;
font-size: 28rpx; /* 1.4rem × 20 = 28rpx */
color: #333;
font-weight: bold;
white-space: nowrap;
text-overflow: ellipsis;
}
.list-item__top-time {
margin-left: 12rpx; /* 保留原rem单位(非用户要求转换的数值) */
color: #999;
font-size: 24rpx; /* 1.2rem × 20 = 24rpx */
}
.list-item__address {
display: flex;
margin-top: 16rpx; /* @marginTop=16rpx */
color: #999;
}
.list-item__date {
margin-top: 16rpx; /* @marginTop=16rpx */
display: flex;
justify-content: space-between;
color: #999;
}
.list-item__date-item {
white-space: nowrap;
}
.list-item__date-item:last-child {
margin-left: 20rpx; /* 保留原rem单位(非用户要求转换的数值) */
}
.list-item__days {
margin-top: 16rpx; /* @marginTop=16rpx */
color: #999;
}
.list-item__detail {
margin-top: 16rpx; /* @marginTop=16rpx */
display: flex;
color: #999;
}
.list-item__detail-content {
flex: 1;
overflow: hidden;
word-break: break-all;
}
.list-item__status {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 16rpx; /* @marginTop=16rpx */
position: relative;
}
.list-item__top-title-label{
flex: 1;
overflow: hidden;
font-size: 28rpx;
color: #333;
font-weight: bold;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>
++ "b/attendance/outRequest/\350\267\250\345\244\251\345\244\226\345\207\272"
...@@ -187,7 +187,35 @@ ...@@ -187,7 +187,35 @@
"custom-button": "view" "custom-button": "view"
} }
} }
},
{
"path": "outRequest/list",
"style": {
"navigationBarTitleText": "跨天外出申请记录",
"componentPlaceholder": {
"custom-button": "view"
}
}
},{
"path": "outRequest/add",
"style": {
"navigationBarTitleText": "跨天外出申请",
"componentPlaceholder": {
"custom-button": "view"
}
}
},{ },{
"path": "outRequest/detail",
"style": {
"navigationBarTitleText": "跨天外出详情",
"componentPlaceholder": {
"custom-button": "view"
}
}
},
{
"path": "outside/list", "path": "outside/list",
"style": { "style": {
"navigationBarTitleText": "当日外出申请记录", "navigationBarTitleText": "当日外出申请记录",
......
...@@ -93,13 +93,13 @@ const processCode = { ...@@ -93,13 +93,13 @@ const processCode = {
provide('process_group', process_group) provide('process_group', process_group)
provide('states', states) provide('states', states)
provide('onDetail', (approveCardData: any, type: string) => { provide('onDetail', (approveCardData: any, type: string) => {
console.log(approveCardData, type) // console.log(approveCardData, type)
const matchedKey = Object.keys(processCode).find(key => const matchedKey = Object.keys(processCode).find(key =>
approveCardData.processCode.includes(key) approveCardData.processCode.includes(key)
) )
if(matchedKey){ if(matchedKey){
console.log(matchedKey) console.log('matchedKey',matchedKey)
console.log('approveCardData',approveCardData)
const page = { const page = {
'trip': '/attendance/trip/detail', 'trip': '/attendance/trip/detail',
'leave': '/attendance/leave/detail', 'leave': '/attendance/leave/detail',
...@@ -118,12 +118,41 @@ provide('onDetail', (approveCardData: any, type: string) => { ...@@ -118,12 +118,41 @@ provide('onDetail', (approveCardData: any, type: string) => {
'employeesDisciplinary': '/personnel/employeesDisciplinary/detail', 'employeesDisciplinary': '/personnel/employeesDisciplinary/detail',
'useCarApply': '/carUse/apply/detail' 'useCarApply': '/carUse/apply/detail'
} }
// 待办 // 待办
if (type === '1') { if (type === '1') {
uni.navigateTo({ console.log('待办')
url:'/approve/detail?type=' + processCode[matchedKey] + '&id=' + approveCardData.businessId + '&instanceId=' + approveCardData.instanceId + '&taskId=' + approveCardData.taskId + '&userId=' + approveCardData.userId + '&userName=' + approveCardData.userName + '&beginTime=' + approveCardData.beginTime + '&endTime=' + approveCardData.endTime if(matchedKey === 'waichushenqing' && approveCardData.businessTable.includes("t_att_out_request")){
}) uni.navigateTo({
url:'/approve/detail?type=' + 'outRequest' + '&id=' + approveCardData.businessId + '&instanceId=' + approveCardData.instanceId + '&taskId=' + approveCardData.taskId + '&userId=' + approveCardData.userId + '&userName=' + approveCardData.userName + '&beginTime=' + approveCardData.beginTime + '&endTime=' + approveCardData.endTime
})
}else{
uni.navigateTo({
url:'/approve/detail?type=' + processCode[matchedKey] + '&id=' + approveCardData.businessId + '&instanceId=' + approveCardData.instanceId + '&taskId=' + approveCardData.taskId + '&userId=' + approveCardData.userId + '&userName=' + approveCardData.userName + '&beginTime=' + approveCardData.beginTime + '&endTime=' + approveCardData.endTime
})
}
} else { } else {
if(matchedKey === 'waichushenqing' && approveCardData.businessTable.includes("t_att_out_request")){
let instanceId = approveCardData.instanceId
// 已发
if (type === '3') {
instanceId = approveCardData.id
}
// 抄送
if (type === '4') {
instanceId = approveCardData.ruId
}
uni.navigateTo({
url: '/attendance/outRequest/detail'+ '?id=' + approveCardData.businessId + '&instanceId=' + instanceId + '&beginTime=' + approveCardData.beginTime + '&endTime=' + approveCardData.endTime
})
}else{
let instanceId = approveCardData.instanceId let instanceId = approveCardData.instanceId
// 已发 // 已发
if (type === '3') { if (type === '3') {
...@@ -136,6 +165,9 @@ provide('onDetail', (approveCardData: any, type: string) => { ...@@ -136,6 +165,9 @@ provide('onDetail', (approveCardData: any, type: string) => {
uni.navigateTo({ uni.navigateTo({
url: page[processCode[matchedKey]] + '?id=' + approveCardData.businessId + '&instanceId=' + instanceId + '&beginTime=' + approveCardData.beginTime + '&endTime=' + approveCardData.endTime url: page[processCode[matchedKey]] + '?id=' + approveCardData.businessId + '&instanceId=' + instanceId + '&beginTime=' + approveCardData.beginTime + '&endTime=' + approveCardData.endTime
}) })
}
} }
}else{ }else{
uni.showToast({ uni.showToast({
......
...@@ -110,7 +110,12 @@ const partList = ref([ ...@@ -110,7 +110,12 @@ const partList = ref([
name: '当日外出申请', name: '当日外出申请',
type: 'waichushenqing', type: 'waichushenqing',
url: lizhishenqing url: lizhishenqing
} },
{
name: '跨天外出申请',
type: 'outRequest',
url: lizhishenqing
},
] ]
}, },
{ {
...@@ -320,6 +325,12 @@ function handleNavPageXitem(val:any) { ...@@ -320,6 +325,12 @@ function handleNavPageXitem(val:any) {
url: '/attendance/outside/list' url: '/attendance/outside/list'
}) })
break break
case 'outRequest': //跨天
uni.navigateTo({
url: '/attendance/outRequest/list'
})
break
// 人事 // 人事
case 'lizhishenqing': // 离职申请 case 'lizhishenqing': // 离职申请
uni.navigateTo({ uni.navigateTo({
...@@ -650,7 +661,11 @@ onMounted(() => { ...@@ -650,7 +661,11 @@ onMounted(() => {
&:nth-child(5n - 1) { &:nth-child(5n - 1) {
margin-right: 0; margin-right: 0;
} }
&:nth-child(8){
margin-right: 0;
}
} }
} }
} }
&-icon { &-icon {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论