Files
fe-manage/src/views/lecturer/MonthlyStatistics.vue
2024-12-17 11:19:50 +08:00

1054 lines
26 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- 讲师费月度统计详情页面 -->
<template>
<div class="MonthlyStatistics">
<!-- 搜索框及按钮 -->
<!-- <a-layout-header style="background: white;color: black; font-size: 20px ;">
<span>讲师费月度统计详情</span>
<router-link to="/LecturerFeeStatistics" class="goback">
<span class="return"></span>
<router-link class="returntext" to="/LecturerFeeStatistics" style="line-height:47px ">
返回
</router-link>
</router-link>
</a-layout-header> -->
<div class="header">
<div class="headerTitle">讲师费月度统计详情</div>
<router-link to="/LecturerFeeStatistics">
<img
style="width: 29px; height: 29px; cursor: pointer"
src="../../assets/images/basicinfo/close.png"
/>
</router-link>
</div>
<!-- <a-divider style="height: 1px; background-color: #b7b8b7 ;margin: 0;" /> -->
<div class="filter">
<a-form layout="inline" >
<a-form-item class="select">
<a-input v-model:value="searchParam.name" style="width: 235px; height: 40px; border-radius: 8px"
placeholder="请输入工号/讲师姓名进行检索" allowClear showSearch
v-on:keydown.enter="enterPressHadlerSearch">
</a-input>
</a-form-item>
<!-- <a-form-item class="select">
<a-select style="width: 230px" v-model:value="searchParam.payrollPlaceId" placeholder="发薪地"
:options="PlaceOfPayList" allowClear showSearch
v-on:keydown.enter="enterPressHadlerSearch"/>
</a-form-item> -->
<a-form-item class="select " >
<!-- <a-tree-select style="width: 230px"
:fieldNames="{
children: 'children',
label: 'name',
value: 'code',
}"
allow-clear
:getPopupContainer="triggerNode => triggerNode.parentNode || document.body"
v-model:value="searchParam.courseTypeId"
show-search
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
placeholder="请选择内容分类"
tree-default-expand-all
:tree-data="sysTypeOptions"
v-on:keydown.enter="enterPressHadlerSearch">
</a-tree-select> -->
<a-select style="width: 235px" placeholder="请选择培训发生组织" v-model:value="searchParam.trainOrgId"
:options="getOrganizationList">
</a-select>
</a-form-item>
<div style="display: flex; margin-bottom: 20px">
<a-button @click="searchSubmit()" type="primary" class="resetbtn">查询 </a-button>
<!-- <div class="btn btn1" @click="searchReset" style="background:rgba(64, 158, 255, 0);" > -->
<!-- <div class="search"></div> -->
<a-button class="resetbtn " @click="searchReset">重置</a-button>
</div>
</a-form>
<div style="width: 100%;"></div>
<div style="display: flex; margin-bottom: 20px">
<a-button class="resetbtn" @click="handleFeeMonthly" type="primary"><UploadOutlined/>导出
</a-button>
</div>
<!-- 表格 -->
<div style="padding: 10px 0">
<a-table :header-cell-style="{ 'text-align': 'center' }" style="border: 1px solid #f2f6fe" :columns="columns"
:data-source="tableData" :loading="tableLoading" :scroll="{ x: 600}" :pagination="false">
<template #bodyCell="{ record, column }">
<template v-if="column.key === 'operation'">
<a-space >
<a-button type="link" @click="() => handleLook(record, String(record.courseform))">查看</a-button>
</a-space>
</template>
</template>
</a-table>
</div>
</div>
<!-- 翻页 -->
<div class="tableBox ">
<div style="float: right;">
<a-pagination
v-if="tableDataTotal > 10"
:showSizeChanger="true"
:showQuickJumper="false"
:hideOnSinglePage="true"
:pageSize="searchParam.pageSize"
:current="searchParam.pageNo"
:total="tableDataTotal"
class="pagination"
@change="changePagination"
/>
</div>
</div>
<!-- 抽屉 -->
<a-drawer class="largeDrawerInside" v-model:visible="opendrawer" placement="right"
@closa="cancelTeachingDialog" :maskClosable="true" width="60%" :title="false">
<div style="padding:24px;">
<div class="headers" style="margin-top:-24px;">
<div class="headerTitle">查看详情</div>
<img
style="width: 29px; height: 29px; cursor: pointer"
src="@/assets/images/basicinfo/close.png"
@click="cancelTeachingDialog"
/>
</div>
<a-form layout="inline">
<a-form-item class="select">
<a-input @pressEnter="searchSubmitdrawer" v-model:value="drawer.name" style="width: 260px; height: 40px; border-radius: 8px"
placeholder="请输入课程名称进行搜索" allowClear showSearch>
</a-input>
</a-form-item>
<a-form-item class="select ">
<a-range-picker format="YYYY-MM-DD"
valueFormat="YYYY-MM-DD" style="width: 260px; height: 40px; margin-bottom: 20px; border-radius: 8px" v-model:value="drawer.drawersearchdate" separator="至"
:placeholder="[' 开始时间', ' 结束时间']" @change="searchTimeChange" />
</a-form-item>
<div style="display: flex; margin-bottom: 20px">
<a-button @click="searchSubmitdrawer()" type="primary" class="resetbtn">查询 </a-button>
<a-button class="resetbtn " @click="searchResetdrawer">重置</a-button>
</div>
</a-form>
<!-- <span>讲师费发放情况</span> -->
<a-table :scroll="{ x: 'max-content'}" :header-cell-style="{ 'text-align': 'center' }" style="border: 1px solid #f2f6fe" :columns="column" :data-source="tableDatas" :loading="tableLoadings" :pagination="false">
<template #bodyCell="{ record, column }">
</template>
</a-table>
<div :style="{
position: 'absolute',
right: 0,
bottom: 0,
width: '100%',
borderTop: '1px solid #e9e9e9',
padding: '10px 16px',
background: '#fff',
textAlign: 'right',
zIndex: 1,
}">
<a-button class="drabtn" @click="cancelTeachingDialog">取消</a-button>
<a-button class="drabtn" type="primary" @click="cancelTeachingDialog" :loading="buttonLoading">返回
</a-button>
</div>
</div>
</a-drawer>
</div>
</template>
<script lang="jsx">
import { reactive, toRefs, ref, watch,computed } from "vue";
import { useStore } from "vuex";
import { useRouter,useRoute } from "vue-router";
import {
UploadOutlined,
} from '@ant-design/icons-vue';
import { getPayRollPlace,expenseSummaryById ,queryDetailId} from "../../api/Lecturer";
import { getOrganization } from "../../api/Teaching";
import ProjectManager from "@/components/project/ProjectManagerNew";
import {queryTeacherFeeMonthly} from "../../api/lecturerFeeStatistics";
import {CostDetails} from "../lecturer/CostDetails.vue"
// import * as api from '@/api/Lecturer'
export default {
name: "MonthlyStatistics",
components: {
UploadOutlined,//图标--导出,
ProjectManager,CostDetails
},
setup() {
const router=useRouter();
const route = useRoute();
const { query: { id }} = useRoute();
const state = reactive({
tableLoadings: false,
opendrawer:false,
id,
summaryDate: null,
resbgTxt: null,
tableDataTotal: -1,//table列表总条数,
tableDataFeeDetailTotal: -1, // 二级列表总条数
currentPage2: 1,
pageSize2: 10,
pageSize: 10,
teacherdialog: false,
teacherdialoga: false,
teacherdialogtitle: null,
searchdate: null, //选择时间
startTime: null, //开始时间
endTime: null, //结束时间
searchParam: {
pageNo: "1",
pageSize: "10",
name: '',
payrollPlaceId: null,
departId: null,
summaryDate:null,
id: route.query.id,
// trainOrgId: '',
},
name:null,
drawer: {
name: '',
drawersearchdate: [],
pageNo: '1',
pageSize: '10',
endTime: '',
startTime: '',
}
})
watch(
)
const endOrg = (val) => {
if(val){
const parts = val.split('/');
const reversedParts = parts.reverse();
return reversedParts.join('/');
}
}
//获取内容分类
const store = useStore();
const sysTypeOptions = computed(() => store.state.content_type);
const columns = ref([
{
title: '讲师名称',
dataIndex: 'name',
key: 'name',
ellipsis: true,
align: "center",
width: 160,
},
{
title: '讲师工号',
dataIndex: 'userNo',
key: 'userNo',
align: "center",
ellipsis: true,
width: 160,
},
{
title: '所属组织 ',
dataIndex: 'orgName',
key: 'orgName',
ellipsis: true,
align: "center",
width: 200,
customRender: ({text})=>{
return endOrg(text)
}
},
{
title: '发薪地',
dataIndex: 'payrollPlace',
key: 'payrollPlace',
ellipsis: true,
align: "center",
width: 160,
},
{
title: '授课时长(系统 ) ',
dataIndex: 'teachingSystem',
key: 'teachingSystem',
ellipsis: true,
align: "center",
width: 160,
},
{
title: '授课时长(录入) ',
dataIndex: 'teachingEnter',
key: 'teachingEnter',
ellipsis: true,
align: "center",
width: 160,
},
{
title: '开发课程时长 ',
dataIndex: 'expense',
key: 'expense',
ellipsis: true,
align: "center",
width: 160,
},
{
title: '计划费用 ',
dataIndex: 'expense',
key: 'expense',
ellipsis: true,
align: "center",
width: 160,
},
{
title: '应发费用 ',
dataIndex: 'payableExpense',
key: 'payableExpense',
ellipsis: true,
align: "center",
width: 160,
},
{
title: '操作 ',
dataIndex: 'operation',
key: 'operation',
ellipsis: true,
align: "center",
fixed: "right",
width: 160,
scopedSlots: { customRender: "action" },
},
])
//列表数据
const tableData = ref([
])
// 搜索
const searchSubmit = () => {
state.searchParam.pageNo = 1;
getTableDate();
};
const PlaceOfPayList = ref([
])
//获取讲师发薪地列表
const PlaceOfPayLista = () => {
getPayRollPlace().then((res) => {
if (res.data.code === 200) {
let arr = res.data.data;
let array = [];
arr.map((value) => {
let obj = {
value: value.id,
label: value.name,
};
array.push(obj);
});
PlaceOfPayList.value = array;
}
console.log("获取发薪地", PlaceOfPayList);
})
}
// PlaceOfPayLista()
// List接口数据
const getTableDate = (obj) => {
state.tableLoading = true
expenseSummaryById(state.searchParam)
.then((res) => {
console.log(res,'resssss')
tableData.value = res.data.data
state.tableDataTotal = Number(res.data.data.total);
state.tableLoading = false
})
};
getTableDate()
//获取所属组织
const getOrganizationList = ref([
// { value: 0, systemName: "讲师体系" },
]);
//获取所属组织
const getOrganizationLista = () => {
// console.log('getOrganizationList')
getOrganization().then((res) => {
if (res.data.code === 200) {
let arr = res.data.data.records;
let array = [];
arr?.map((value) => {
let obj = {
value: value.id,
label: value.affiliationName,
};
array.push(obj);
});
getOrganizationList.value = array;
}
})
}
getOrganizationLista()
//表格内查看数据操作
const handleLook = (record) => {
state.drawer={
name: '',
drawersearchdate: [],
pageNo: '1',
pageSize: '10',
endTime: '',
startTime: '',
id: record.id,
}
state.opendrawer=true
searchSubmitdrawer()
}
const searchTimeChange = (e) => {
console.log(e,'eeeee')
if(e){
state.drawer.startTime = e[0]
state.drawer.endTime = e[1]
}else{
state.drawer.startTime = ''
state.drawer.endTime = ''
}
}
const changePagination = (page, pageSize) => {
state.searchParam.pageNo = page;
// state.pageNo = page;
state.searchParam.pageSize = pageSize;
getTableDate();
};
// 导出
const handleFeeMonthly = () => {
window.open(
`${process.env.VUE_APP_BASE_API}/admin/export/exportTeacherSummary?
&name=${state.searchParam.name ? state.searchParam.name : ""}
&billId=${state.searchParam.payrollPlaceId ? state.searchParam.payrollPlaceId : ""}
&trainOrgId=${state.searchParam.trainOrgId || ''}`)
}
//重置
const searchReset = () => {
state.searchParam = {
pageNo: "1",
pageSize: "10",
id: route.query.id,
name : '',
payrollPlaceId: null,
departId: '',
summaryDate:'',
// trainOrgId: '',
};
getTableDate();
};
//二级页面重置
const searchResetdrawer =()=>{
const id = state.drawer.id
state.drawer={
name: '',
drawersearchdate: [],
pageNo: '1',
pageSize: '10',
endTime: '',
startTime: '',
id,
}
searchSubmitdrawer()
}
//二级页面查询
const searchSubmitdrawer=()=>{
state.tableLoadings = true
const params = {
summaryId: state.drawer.id,
name: state.drawer.name,
endTime: state.drawer.endTime,
startTime: state.drawer.startTime,
}
queryDetailId(params).then(res=>{
console.log(res,'resss')
tableDatas.value = res.data.data
state.tableLoadings = false
})
}
const tableDatas = ref([])
const column = ref([
{
title: '讲师姓名 ',
dataIndex: 'name',
key: 'name',
ellipsis: true,
align: "center",
width: 100,
},
{
title: '讲师工号',
dataIndex: 'userNo',
key: 'userNo',
align: "center",
ellipsis: true,
width: 100,
},
{
title: '课程名称 ',
dataIndex: 'courseName',
key: 'courseName',
ellipsis: true, align: "center",
width: 120,
},
{
title: '课程类型 ',
dataIndex: ' courseType',
key: ' courseType',
ellipsis: true, align: "center",
width: 120,
customRender: (value) => {
return (
<div>
{String(value.record.courseType)
? {
"0": "在线课",
"1": "面授课",
"2": "课程开发",
"3": "作业员入模培训",
"4": "其他",
}[value.record.courseType + ""]
: "-"}
</div>
)
}
},
{
title: '授课时长 ',
dataIndex: 'teachingTime',
key: 'teachingTime',
ellipsis: true, align: "center",
width: 120,
},
{
title: '授课时间',
dataIndex: 'teachingDate',
key: 'teachingDate',
ellipsis: true,
align: "center",
width: 120,
scopedSlots: { customRender: "teacherOrg" },
},
{
title: '讲师体系',
dataIndex: 'tsystemName',
key: 'tsystemName',
ellipsis: true, align: "center",
width: 120,
},
{
title: '讲师级别 ',
dataIndex: 'tlevelName',
key: 'tlevelName',
ellipsis: true, align: "center",
width: 120,
},
{
title: '讲师发薪地 ',
dataIndex: 'payrollPlace',
key: 'payrollPlace',
ellipsis: true,
align: "center",
width: 120,
},
{
title: '基准课酬 ',
dataIndex: 'levelPay',
key: 'levelPay',
ellipsis: true, align: "center",
width: 100,
},
{
title: '计划费用 ',
dataIndex: 'expense',
key: 'expense',
ellipsis: true,
align: "center",
width: 100,
},
{
title: '应发费用 ',
dataIndex: 'payableExpense',
key: 'payableExpense',
ellipsis: true,
align: "center",
width: 100,
},
])
//取消按钮 清空输入的数据
const cancelTeachingDialog = () => {
state.opendrawer = false
state.drawer={
name: '',
drawersearchdate: [],
pageNo: '1',
pageSize: '10',
endTime: '',
startTime: '',
}
};
//回车
const enterPressHadlerSearch = e => {
  console.log("e",e);
    if (e.keyCode === 13) {
      searchSubmit()
    }
};
return {
...toRefs(state),
tableDatas,
column,
enterPressHadlerSearch,
cancelTeachingDialog,
searchReset,
handleFeeMonthly,
handleLook,
changePagination,
searchTimeChange,
searchSubmitdrawer,
getTableDate,
searchSubmit,
tableData,
columns,
PlaceOfPayList,
PlaceOfPayLista,
getOrganizationList,
getOrganizationLista,
searchResetdrawer,
sysTypeOptions,
endOrg,
}
},
};
</script>
<style lang="scss" scoped >
.MonthlyStatistics {
.header {
padding: 0px 32px;
height: 73px;
border-bottom: 1px solid #e8e8e8;
display: flex;
justify-content: space-between;
align-items: center;
// background-color: red;
// margin-bottom: 20px;
flex-shrink: 0;
.headerTitle {
font-size: 18px;
font-weight: 600;
color: #333333;
line-height: 25px;
// margin-left: 24px;
}
}
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
.filter {
margin-left: 38px;
margin-right: 38px;
margin-top: 30px;
// display: flex;
// justify-content: space-between;
// flex-wrap: wrap;
.select {
margin-right: 20px;
margin-bottom: 20px;
}
}
}
.select .ant-picker {
width: 410px !important;
}
.headers {
height: 73px;
border-bottom: 1px solid #e8e8e8;
display: flex;
justify-content: space-between;
align-items: center;
// background-color: red;
margin-bottom: 20px;
flex-shrink: 0;
.headerTitle {
font-size: 18px;
font-weight: 600;
color: #333333;
line-height: 25px;
// margin-left: 24px;
}
}
.addTimeBox {
position: relative;
display: flex;
align-items: center;
.addTime {
position: absolute;
z-index: 10;
margin-left: 10px;
color: rgba(0, 0, 0, 0.4);
}
}
//导出按钮icon
.daochu {
width: 16px;
height: 18px;
background-image: url("../../assets/images/coursewareManage/export1.png");
}
//弹窗内详情样式
.display1 {
display: inline-block;
width: 200px;
}
// .display0{
// display:inline-block ;
// width:200px ;
// text-align:center }
//弹窗内确认取消按钮布局
.del_btnbox {
display: flex;
margin: 30px auto;
justify-content: center;
.del_btn {
width: 100px;
height: 40px;
background: rgba(64, 158, 255, 0);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
cursor: pointer;
.btnText {
font-size: 14px;
font-weight: 400;
line-height: 40px;
}
}
.btn1 {
border: 1px solid rgba(64, 158, 255, 1);
color: #4ea6ff;
margin-right: 14px;
}
.btn2 {
background-color: #4ea6ff;
color: #ffffff;
}
}
.ant-table-cell-fix-right {
width: 300px !important;
}
.ant-table-tbody>tr>td {
text-align: center;
}
.ExternalTeaching {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
.filter {
margin-left: 38px;
margin-right: 38px;
margin-top: 30px;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.select {
margin-right: 20px;
margin-bottom: 20px;
}
}
}
.delete {
z-index: 9999;
width: 424px;
background: #ffffff;
box-shadow: 0px 1px 35px 0px rgba(118, 136, 166, 0.21);
border-radius: 4px;
position: absolute;
left: 30%;
top: 10%;
// transform: translate(-50%, -50%);
.del_header {
position: absolute;
width: calc(100%);
height: 40px;
background: linear-gradient(rgba(78, 166, 255, 0.2) 0%,
rgba(78, 166, 255, 0) 100%);
}
.del_main {
width: 100%;
position: relative;
.header {
display: flex;
align-items: center;
padding-top: 20px;
padding-left: 26px;
font-size: 16px;
.del-icon {
width: 16px;
height: 16px;
margin-right: 10px;
background-image: url(@/assets/images/coursewareManage/notice.png);
background-size: 100% 100%;
}
.icon {
width: 16px;
height: 16px;
margin-right: 10px;
background-image: url(@/assets/images/coursewareManage/QR.png);
background-size: 100% 100%;
}
.close_exit {
position: absolute;
right: 42px;
cursor: pointer;
width: 20px;
height: 20px;
background-image: url(@/assets/images/coursewareManage/close.png);
background-size: 100% 100%;
}
}
.body {
width: 100%;
margin: 34px auto 56px auto;
display: flex;
justify-content: center;
align-items: center;
}
.del_btnbox {
display: flex;
margin: 30px auto;
justify-content: center;
.del_btn {
width: 100px;
height: 40px;
background: rgba(64, 158, 255, 0);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 14px;
flex-shrink: 0;
cursor: pointer;
.btnText {
font-size: 14px;
font-weight: 400;
line-height: 40px;
}
}
.btn1 {
border: 1px solid rgba(64, 158, 255, 1);
color: #4ea6ff;
}
.btn2 {
background-color: #4ea6ff;
color: #ffffff;
}
}
}
}
.CreatePath {
.out {
z-index: 9999;
display: block;
position: absolute;
top: 90px;
width: 1080px !important;
height: 650px;
overflow: auto;
background-color: #fff;
box-shadow: 0 0 10px rgba(118, 136, 166, 0.21);
left: 50%;
top: 300px;
transform: translate(-50%, -50%);
.top {
width: 100%;
height: 68px;
background: linear-gradient(rgba(78, 166, 255, 0.2) 0%,
rgba(78, 166, 255, 0) 100%);
display: flex;
align-items: center;
.topimg {
width: 18px;
height: 18px;
margin-left: 27px;
margin-top: -2px;
}
.topc {
color: #000000;
font-size: 16px;
margin-left: 8px;
}
}
.mid {
width: 100%;
height: 100%;
background-color: #fff;
display: flex;
flex-direction: column;
align-items: center;
.d {
// margin-top: 8px;
// color: #ff4e4e;
margin-left: -5px;
}
}
}
}
//添加样式
.langbtn {
height: 40px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 14px;
flex-shrink: 0;
cursor: pointer;
}
// 重置样式
.resetbtn {
width: 100px;
height: 40px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 14px;
flex-shrink: 0;
cursor: pointer;
}
//展开收起样式
.moreidbtn {
border: none;
color: #4ea6ff;
width: 80px
}
//小竖线
.line {
float: left;
width: 3px;
height: 25px;
background: #4ea6ff;
border-radius: 30%;
margin-right: 5px;
}
//抽屉功能
.drawaer // /* 改变所有 a-tree-select 输入框的高度 */
// ::v-deep .ant-select:not(.ant-select-customize-input) .ant-select-selector{
// height: 40px;
// line-height: 40px;
// border-radius: 8px
// /* 确保文字垂直居中 */
// }
::v-deep .ant-select-single:not(.ant-select-customize-input) .ant-select-selector {
height: 40px !important;
line-height: 40px;
border-radius: 8px
}
// 抽屉内样式
.draitem {
width: 100%;
height: 40px !important;
border-radius: 8px;
line-height: 40px;
}
.drabtn {
height: 40px;
width: 80px;
border-radius: 8px;
margin-right: 20px
}
::v-deep .ant-select:not(.ant-select-customize-input) .ant-select-selector{
border-radius:8px;
height:40px;
}
.ant-col-12{
height:90px;
}
.goback {
float: right;
padding-right: 70px;
//padding-top: 37px;
position: relative;
.return {
display: inline-block;
width: 42px;
height: 42px;
margin-top: 17px;
margin-right: 10px;
background-image: url("../../assets/images/projectadd/return.png");
}
.returntext {
display: inline-block;
position: absolute;
top: 12px;
color: #4ea6ff;
font-size: 14px;
}
}
tableBox {
padding-bottom: 20px;
margin: 20px 38px 30px;
::v-deep .ant-select-dropdown{
display: inline-block;
}
::v-deep .ant-select-selection-item{
margin-left: 3px;
}
::v-deep .ant-pagination-options-size-changer.ant-select{
width: 84px;
}
.pa {
width: 100%;
display: flex;
justify-content: right;
}
}
</style>