|
@@ -0,0 +1,403 @@
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref,nextTick } from "vue";
|
|
|
+import { router } from '@/router'
|
|
|
+import { ArrowLeft,ArrowRight } from '@element-plus/icons-vue'
|
|
|
+import moment from "moment";
|
|
|
+import $ from "jquery"
|
|
|
+
|
|
|
+import { interactiveInterface } from '@/api/api'
|
|
|
+import { businessTripInterence } from "@/api/api.js";
|
|
|
+import {bussinessTripH} from './hooks/bussinessTripH'
|
|
|
+import tripApproveDia from "./components/tripApproveDia.vue";
|
|
|
+import tripApplicationDia from './components/tripApplicationDia.vue'
|
|
|
+
|
|
|
+const bussinessTripCom=bussinessTripH()
|
|
|
+
|
|
|
+const userList = ref([])
|
|
|
+const users = ref([])
|
|
|
+
|
|
|
+const selectUser=(value)=>{
|
|
|
+ getTableData()
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+const daysArr=['周一','周二','周三','周四','周五','周六','周日']
|
|
|
+const tableDayColumns=ref('')
|
|
|
+const datalist=ref([])
|
|
|
+
|
|
|
+const getWeekDays=(weeknum,dateList)=>{
|
|
|
+ // dateList 日期数组 weeknum 周数
|
|
|
+ let arrList=[]
|
|
|
+ for (let i = 0; i < weeknum; i++) {
|
|
|
+ arrList[i]=[]
|
|
|
+ if(dateList && dateList.length>0){
|
|
|
+ // 有数据返回 能拿到后端返回的日期数组
|
|
|
+ for (let j = 0; j < 7; j++) {
|
|
|
+ let momentItem=moment(dateList[(i*7+j)])
|
|
|
+ arrList[i].push(momentItem.format('MM/DD')+daysArr[momentItem.weekday()])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return arrList;
|
|
|
+}
|
|
|
+//去往研究员日历
|
|
|
+const toResearchCalendar=(date,researcher)=>{
|
|
|
+ let params={date:date,researcherId:researcher.AdminId,researcherName:researcher.RealName,}
|
|
|
+ sessionStorage.setItem('businessToResearcherParams',JSON.stringify(params))
|
|
|
+ let routeData = router.resolve({ path: '/researcherCalendar'});
|
|
|
+ window.open(routeData.href, '_blank');
|
|
|
+}
|
|
|
+
|
|
|
+const detailItem=ref({})
|
|
|
+//详情弹窗
|
|
|
+const approvalDiaShow=ref(false)
|
|
|
+//申请弹窗
|
|
|
+const detailDiaShow=ref(false)
|
|
|
+//审批弹窗
|
|
|
+const applicationDiaShow=ref(false)
|
|
|
+
|
|
|
+// 出差详情
|
|
|
+const businessDetail=(data)=>{
|
|
|
+ if(data.Status=='' || data.BusinessApplyId==0) return
|
|
|
+ businessTripInterence.getTripDetail({BusinessApplyId:data.BusinessApplyId}).then(res=>{
|
|
|
+ if(res.Ret == 200){
|
|
|
+ detailItem.value=res.Data || {}
|
|
|
+ if(data.Status=='待审批'){
|
|
|
+ approvalDiaShow.value=true
|
|
|
+ }else if(data.Status=='已通过'){
|
|
|
+ detailDiaShow.value=true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const approve=()=>{
|
|
|
+ getTableData();
|
|
|
+}
|
|
|
+const application=()=>{
|
|
|
+ getTableData();
|
|
|
+}
|
|
|
+
|
|
|
+/* 获取所有用户列表 */
|
|
|
+const getAllUser=()=>{
|
|
|
+ interactiveInterface.allUserList().then(res => {
|
|
|
+ if(res.Ret !== 200) return
|
|
|
+ userList.value = res.Data.List||[]
|
|
|
+ })
|
|
|
+}
|
|
|
+/* 获取表格数据 */
|
|
|
+const getTableData=()=>{
|
|
|
+ let param={
|
|
|
+ AdminId:users.value ? users.value.join(',') : '',
|
|
|
+ WeekQuery:bussinessTripCom.weekQuery.value,
|
|
|
+ BaseQueryDate:bussinessTripCom.BaseDate.value
|
|
|
+ }
|
|
|
+ businessTripInterence.getTripCalendar(param).then((res) => {
|
|
|
+ if (res.Ret !== 200) return;
|
|
|
+ bussinessTripCom.BaseDate.value = res.Data.BaseDate
|
|
|
+ const Data = res.Data.GroupList || []
|
|
|
+
|
|
|
+ //处理数据结构
|
|
|
+ let tempData=Data.filter(it => it.AdminList && it.AdminList.length > 0)
|
|
|
+ tempData.forEach((item)=>{
|
|
|
+ item.showDetail=true
|
|
|
+ })
|
|
|
+ // 取出出差表所有的日期
|
|
|
+ let weekDateList = tempData[0]?tempData[0].AdminList[0].BusinessTripList.map(item => item.WeekDate):[]
|
|
|
+ // 获取表格头文本
|
|
|
+ tableDayColumns.value= getWeekDays(2,weekDateList)
|
|
|
+ datalist.value = tempData;
|
|
|
+ nextTick(()=>{
|
|
|
+ $("table")
|
|
|
+ .find("td")
|
|
|
+ .css({ width: '6.25%' });
|
|
|
+ $("table")
|
|
|
+ .find(".thead-rs")
|
|
|
+ .css({ width: '6.25%' });
|
|
|
+ })
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+getAllUser()
|
|
|
+getTableData()
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div class="trip-container">
|
|
|
+ <div class="trip-top">
|
|
|
+ <el-cascader
|
|
|
+ v-model="users" :options="userList" collapse-tags
|
|
|
+ size="large"
|
|
|
+ :props="{
|
|
|
+ label: 'RealName',
|
|
|
+ value: 'AdminId',
|
|
|
+ children: 'ChildrenList',
|
|
|
+ emitPath: false,
|
|
|
+ multiple: true
|
|
|
+ }"
|
|
|
+ style="width: 240px;"
|
|
|
+ :show-all-levels="false" clearable filterable
|
|
|
+ @change="selectUser" placeholder="请选择用户"
|
|
|
+ >
|
|
|
+ </el-cascader>
|
|
|
+ <div class="center">
|
|
|
+ <el-button type="primary" @click="bussinessTripCom.toogelDate(1,getTableData)" style="width: 140px;" size="large">
|
|
|
+ <el-icon :size="14" style="margin-right: 4px;"><ArrowLeft /></el-icon>
|
|
|
+ 上两周
|
|
|
+ </el-button>
|
|
|
+ <el-button type="primary" @click="bussinessTripCom.toogelDate(0,getTableData)" style="width: 140px;" size="large">本期</el-button>
|
|
|
+ <el-button type="primary" @click="bussinessTripCom.toogelDate(2,getTableData)" style="width: 140px;" size="large">
|
|
|
+ 下两周
|
|
|
+ <el-icon :size="14" style="margin-left: 4px;"><ArrowRight /></el-icon>
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ <el-button type="primary" @click="applicationDiaShow=true" style="height: 40px;width: 100px;">添加申请</el-button>
|
|
|
+ </div>
|
|
|
+ <div class="table-cont">
|
|
|
+ <div class="table-body-wrapper" style="max-height: calc(100vh - 240px);overflow: auto;">
|
|
|
+ <table>
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <td :rowspan="2" class="thead-rs">分组</td>
|
|
|
+ <td :rowspan="2" class="thead-rs">用户</td>
|
|
|
+ <td :colspan="7" v-for="item in bussinessTripCom.tableTheadColumns.value" :key="item" class="head-column">
|
|
|
+ {{ item }}
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <template v-for="item in [0,1]">
|
|
|
+ <td :key="item +'_'+ ind" v-for="(it,ind) in tableDayColumns[item]" >
|
|
|
+ {{ it }}
|
|
|
+ </td>
|
|
|
+ </template>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <template v-if="datalist.length>0">
|
|
|
+ <tbody v-for="item in datalist" :key="item.GroupId">
|
|
|
+ <template v-if="item.AdminList.length">
|
|
|
+ <tr>
|
|
|
+ <td :rowspan="item.AdminList.length + 1" class="thead-rs" style="cursor: pointer;"
|
|
|
+ @click="item.showDetail = !item.showDetail" >{{ item.GroupName }}
|
|
|
+ <i :class="item.showDetail?'el-icon-arrow-down':'el-icon-arrow-up'" v-show="item.AdminList.length>1"></i>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ <tr v-for="rs in item.showDetail?item.AdminList:item.AdminList.slice(0,1)" :key="rs.AdminId">
|
|
|
+ <td class="thead-rs">{{ rs.RealName }}</td>
|
|
|
+ <td :key="data_key+'_0'" v-for="(data,data_key) in rs.BusinessTripList.filter(it => it.WeekType == 'current')"
|
|
|
+ style="position: relative;">
|
|
|
+ <img src="../../assets/img/icons/television.png" v-if="item.GroupId==1 && data.City&&data.Reason==='路演'"
|
|
|
+ @click="toResearchCalendar(data.WeekDate,rs)"
|
|
|
+ class="view-researcher-icon"/>
|
|
|
+ <span style="cursor: pointer;" :style="{color:data.Status=='待审批'?'#FF8A00':'#666666'}"
|
|
|
+ @click="businessDetail(data)">{{ data.City }}</span>
|
|
|
+ <img src="../../assets/img/approve_wait.png" v-show="data.Status=='待审批'" @click="businessDetail(data)"
|
|
|
+ class="wait-approve-icon"/>
|
|
|
+ </td>
|
|
|
+ <td :key="data_key+'_1'" v-for="(data,data_key) in rs.BusinessTripList.filter(it => it.WeekType == 'next')"
|
|
|
+ style="position: relative;">
|
|
|
+ <img src="../../assets/img/icons/television.png" v-if="item.GroupId==1 && data.City&&data.Reason==='路演'"
|
|
|
+ @click="toResearchCalendar(data.WeekDate,rs)"
|
|
|
+ class="view-researcher-icon"/>
|
|
|
+ <span style="cursor: pointer;" :style="{color:data.Status=='待审批'?'#FF8A00':'#666666'}"
|
|
|
+ @click="businessDetail(data)">{{ data.City }}</span>
|
|
|
+ <img src="../../assets/img/approve_wait.png" v-show="data.Status=='待审批'" @click="businessDetail(data)"
|
|
|
+ class="wait-approve-icon" />
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ </template>
|
|
|
+ </tbody>
|
|
|
+ </template>
|
|
|
+ </table>
|
|
|
+ <template v-if="datalist.length==0">
|
|
|
+ <div class="table-data-empty">
|
|
|
+ 暂无信息
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <el-dialog
|
|
|
+ title="出差详情"
|
|
|
+ :modal-append-to-body="false"
|
|
|
+ v-model="detailDiaShow"
|
|
|
+ width="380px"
|
|
|
+ >
|
|
|
+ <div class="detail-box">
|
|
|
+ <div class="detail-date">
|
|
|
+ {{ moment(detailItem.ArriveDate).format('MM.DD') }}({{daysArr[moment(detailItem.ArriveDate).weekday()]}})--
|
|
|
+ {{ moment(detailItem.ReturnDate).format('MM.DD') }}({{daysArr[moment(detailItem.ReturnDate).weekday()]}})
|
|
|
+ </div>
|
|
|
+ <div class="detail-item">
|
|
|
+ <div class="detail-item-label">申请人:</div>
|
|
|
+ {{ detailItem.ApplyRealName }}
|
|
|
+ </div>
|
|
|
+ <div class="detail-item">
|
|
|
+ <div class="detail-item-label">目的地:</div>
|
|
|
+ {{ detailItem.Province+' '+detailItem.City }}
|
|
|
+ </div>
|
|
|
+ <div class="detail-item">
|
|
|
+ <div class="detail-item-label"> 出差事由:</div>
|
|
|
+ {{ detailItem.Reason }}
|
|
|
+ </div>
|
|
|
+ <div class="detail-item">
|
|
|
+ <div class="detail-item-label">交通工具:</div>
|
|
|
+ {{ detailItem.Transportation && detailItem.Transportation.indexOf('其他')!=-1?
|
|
|
+ detailItem.Transportation.substring(detailItem.Transportation.indexOf('-')+1):detailItem.Transportation }}
|
|
|
+ </div>
|
|
|
+ <div class="detail-item" style="line-height: 20px;" v-show="detailItem.PeerPeopleName">
|
|
|
+ <div class="detail-item-label">同行人:</div>
|
|
|
+ {{ detailItem.PeerPeopleName }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ <tripApproveDia :approveItem="detailItem" v-model:dialogShow="approvalDiaShow" @approveSuccess="approve"></tripApproveDia>
|
|
|
+ <tripApplicationDia v-model:dialogShow="applicationDiaShow" :reapply="{}" :userList="JSON.parse(JSON.stringify(userList))" @applicationSuccess="application"></tripApplicationDia>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+* {
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+.trip-container {
|
|
|
+ min-height: calc(100vh - 110px);
|
|
|
+ height: auto;
|
|
|
+ background-color: #fff;
|
|
|
+ box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
|
|
|
+ border-radius: 4px;
|
|
|
+ padding: 30px;
|
|
|
+ .trip-top {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ gap: 30px;
|
|
|
+ .center{
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: nowrap;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .frequency-cont {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 30px;
|
|
|
+ .frequency-ul {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ li {
|
|
|
+ width: 110px;
|
|
|
+ height: 40px;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 40px;
|
|
|
+ border: 1px solid #B3D8FF;
|
|
|
+ background: #ECF5FF;
|
|
|
+ color: #409EFF;
|
|
|
+ border-radius: 4px;
|
|
|
+ cursor: pointer;
|
|
|
+ margin-right: 20px;
|
|
|
+ &.act {
|
|
|
+ background: #409EFF;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .table-cont {
|
|
|
+ .table-body-wrapper {
|
|
|
+ max-height: calc(100vh - 340px);
|
|
|
+ overflow-y: scroll;
|
|
|
+ overflow-x: auto;
|
|
|
+ border-bottom: 1px solid #dcdfe6;
|
|
|
+ border-top: 1px solid #dcdfe6;
|
|
|
+ .table-data-empty{
|
|
|
+ color: #666666;
|
|
|
+ height: 530px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ border-left: 1px solid #DCDFE6;
|
|
|
+ border-right: 1px solid #DCDFE6;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ table {
|
|
|
+ width: 100%;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #666;
|
|
|
+ thead{
|
|
|
+ position: sticky;
|
|
|
+ top: 0;
|
|
|
+ z-index: 1;
|
|
|
+ left: 0;
|
|
|
+ border-left: 1px solid #dcdfe6;
|
|
|
+ border-right: 1px solid #dcdfe6;
|
|
|
+ td{
|
|
|
+ border: none;
|
|
|
+ outline-color: #dcdfe6;
|
|
|
+ outline-style: solid;
|
|
|
+ outline-width: 0.5px;
|
|
|
+ background-color:#EBEEF5!important ;
|
|
|
+ color: #333333;
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ td,
|
|
|
+ th {
|
|
|
+ min-width: 35px;
|
|
|
+ // word-break: break-all;
|
|
|
+ border: 1px solid #dcdfe6;
|
|
|
+ height: 45px;
|
|
|
+ text-align: center;
|
|
|
+ background-color: #fff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .head-column {
|
|
|
+ background-color: #F0F2F5;
|
|
|
+ }
|
|
|
+
|
|
|
+ .data-cell{
|
|
|
+ color: #409EFF;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+
|
|
|
+ .thead-sticky {
|
|
|
+ position: sticky;
|
|
|
+ top: 0;
|
|
|
+ }
|
|
|
+ .view-researcher-icon{
|
|
|
+ height: 12px;
|
|
|
+ position: absolute;
|
|
|
+ cursor: pointer;
|
|
|
+ left: 4px;
|
|
|
+ top: 4px;
|
|
|
+ }
|
|
|
+ .wait-approve-icon{
|
|
|
+ height: 35px;
|
|
|
+ position: absolute;
|
|
|
+ cursor: pointer;
|
|
|
+ right: 0;
|
|
|
+ top: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .detail-box{
|
|
|
+ padding:0 0 15px 40px;
|
|
|
+ .detail-item{
|
|
|
+ font-size: 16px;
|
|
|
+ color: #333333;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ display: flex;
|
|
|
+ .detail-item-label{
|
|
|
+ min-width: 80px;
|
|
|
+ text-align: right;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .detail-date{
|
|
|
+ margin-bottom: 14px;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #333333;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|