<template>
<!-- 内容区域 -->
<div class="sal-rpt-gzxhzb">
<!-- 单位头部开始 -->
<div class="mt5 fix">
<!-- 单位 -->
<v-agy-select v-model="query.agy"></v-agy-select>
<div class="r">
<span v-if="isSystemPermission()">提示:当前为操作系统级数据权限(单位代码='*')</span>
<slot name="toolbar"></slot>
</div>
</div>
<!-- 单位头部结束 -->
<!-- 部门树和表格开始 -->
<div>
<el-row :gutter="10">
<el-col :span="6" v-show="!isFullScreen">
<!-- 左边搜索框和部门树开始 -->
<div class="left" style="border-radius: 4px;padding: 1px;overflow: auto;height:480px;border:1px solid #ccc;">
<div class="tcontent" style="margin-bottom:10px;">
<el-input placeholder="输入关键字进行过滤" size="small" v-model="filterText">
<el-button slot="append" icon="el-icon-search"></el-button>
</el-input>
<el-tree id="tree" class="filter-tree" :data="treeDataBm" show-checkbox node-key="id" :props="{id: 'madCode',label: 'madName',children: 'children'}" default-expand-all :filter-node-method="filterNode" :check-on-click-node="true" :expand-on-click-node="false" :check-strictly="false" @check-change="handleCheckChange" ref="tree2">
</el-tree>
</div>
</div>
<!-- 左边搜索框和部门树结束 -->
</el-col>
<el-col :span="!isFullScreen ? 18 : 24">
<!-- 右边表格开始 -->
<div class="right bs-bg-color-white p0">
<!-- 右边表格顶部查询条件开始 -->
<div style="border-top-left-radius: 4px;border-top-right-radius: 4px;overflow: auto;height:28px;border:1px solid #ccc;border-right:1px solid #ccc;border-top:1px solid #ccc;border-bottom:1px solid #ccc;">
<span class="ml5 search" style="font-size:12px;float:left">
<span class="mr1 mt5" style="font-size:12px;">
年度:
<el-select v-model="currentYear" filterable placeholder="请选择" size="mini" class="ml1 fl" style="width: 70px;" @change="handleYearChange">
<el-option v-for="item in yearData" :key="item.year" :label="item.year" :value="item.year">
</el-option>
</el-select>
</span>
<span class="ml1">
<span class="ml1" style="font-size:12px;">工资类别:</span>
<el-select v-model="currentSalTypeCode" filterable placeholder="请选择" size="mini" class="ml10 fl" style="width: 120px;left:-10px;" @change="handleTypeChange">
<el-option v-for="item in salTypeFilterData" :key="item.typeCode" :label="item.typeName" :value="item.typeCode">
</el-option>
</el-select>
</span>
<span class="ml1">
<span class="ml1" style="font-size:12px;">工资项:</span>
<el-select v-model="currentSalItemCode" filterable placeholder="请选择" size="mini" class="ml10 fl" style="width: 120px;left:-10px;" @change="handleItemChange">
<el-option v-for="item in salTypeItemFilterData" :key="item.itemCode" :label="item.itemName" :value="item.itemCode">
</el-option>
</el-select>
</span>
<span style="font-size:12px;">检索:</span>
<el-input class="pl1" placeholder="请输入人员代码或名称" id="searchField1" size="mini" @clear="handleSearchClear" v-model="searchText" clearable style="width: 240px;">
</el-input>
</span>
</div>
<!--右边表格顶部查询条件结束 -->
<!--hansonTable区域开始-->
<div class="mt1 hanson-table" style="padding: 0px;overflow: auto;border:1px solid #ccc;border-bottom:1px solid #ccc;border-right:2px solid #ccc;border-top:0px solid #ccc;">
<div id="calcTable">
</div>
</div>
<!--hansonTable区域结束-->
<div class="fix bs-table-foot">
</div>
<div id="deptPrintTable"></div>
</div>
</el-col>
<!-- 小手点击图片开始-->
<div class="bar-line-left">
<span class="pfs-line-border poi bs-background-color-primary" @click.stop="handleFadeToggle"></span>
<span class="pfs-icon1"><i @click.stop="handleFadeToggle" :class="['fa','poi','f28','dn',!isFullScreen ? ' fa-hand-o-left' : 'fa-hand-o-right']"></i></span>
</div>
<!-- 小手点击图片结束 -->
</el-row>
</div>
<!-- 右表表格结束 -->
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import { GET_LOGIN_INFO, GET_CONTEXT_AGY_ACB } from '@/store/login';
import { getMadInfo } from '@/mixin/agy';
import { innerHeight, getEnumerate } from '@/mixin/page';
import fetch from '@/config/fetch';
import util from '@/assets/js/util';
const handsontable = () =>
import(
/*webpackChunkName: 'async_vendors/handsontable-pro' */ 'handsontable-pro'
);
import tableview from '../sal-pub/tableview';
import sal from '../sal-pub/sal';
import { hasView } from '@/mixin/system';
export default {
name: 'SAL_RPT_GZXHZB',
mixins: [innerHeight],
data() {
return {
/*
* 查询表格的参数,不理解
* */
query: {
agy: {
madCode: '',
madName: '',
},
isEnabled: 1, //千分位显示数据的方法用
keyword: '', //监听方法用
code: '', //部门code
},
isFullScreen: false, //是否是全屏,处理淡入淡出切换
filterText: '', //第三页树形值
treeDataBm: [], //部门树的数据
currentYear: null,
yearData: null,
currentSalTypeCode: null,
currentSalItemCode: [],
searchText: '', //搜索文本
//调用$set添加属性,不使用这个的话,前端控制台会报错
/*
* Avoid adding reactive properties to a Vue instance or its root $data at runtime - declare it upfront in the data option.
* */
mad: {},
hot: null, //配置hash表格的时候使用
salTypeData: [],
currentSalType: {}, //工资类别,如果只有方法,但是没有定义这个属性,页面上对应的数据就不会展示出来
}
},
computed: {
...mapGetters([GET_LOGIN_INFO, GET_CONTEXT_AGY_ACB]),
tableHeight() {
return this.innerHeight - 150;
},
/*
* 获取工资类别集合
* */
salTypeFilterData() {
let filterSalType = [];
let that = this;
let map = {};
_.forEach(this.salTypeData, (o) => {
if (!map[o.typeCode]) {
filterSalType.push(o);
map[o.typeCode] = o;
}
});
return filterSalType;
},
/*
* 获取工资项集合
* */
salTypeItemFilterData() {
let filterSalItemCode = [];
let that = this;
let map = {};
_.forEach(this.salTypeData, (o) => {
if (
util.isNotEmpty(this.currentSalTypeCode) &&
this.currentSalTypeCode == o.typeCode
) {
_.forEach(o.itemList, (i) => {
if (i.dataType === 'number' && !map[i.itemCode]) {
filterSalItemCode.push(i);
map[i.itemCode] = i;
}
});
}
});
return filterSalItemCode;
},
},
/* * 钩子函数,一般可以在created函数中调用ajax获取页面初始化所需的数据。
* 钩子的 this 指向调用它的 Vue 实例
* 组件实例创建完成,dom还未生成,仅仅触发一次;
* 只加上这个代码就全面崩溃了
* */
created() {
const { agyCode, agyName } = this.GET_CONTEXT_AGY_ACB;
this.query.agy.madCode = agyCode;
this.query.agy.madName = agyName;
},
/*
* 监听
* */
watch: {
'query.agy'(val) {
this.query.keyword = '';
getMadInfo(val.madCode).then((res = {}) => {
this.$set(this.$data, 'mad', res);
});
this.init();
},
filterText(val) {
this.$refs.tree2.filter(val);
},
},
methods: {
//初始化Handsontable资源
async initResource() {
try {
let Handsontable = await handsontable();
this.Handsontable = Handsontable.default;
return true;
} catch (err) {
return Promise.reject(err);
}
},
/**
* 判断当前单位是否有操作系统级数据权限
* 通过这个可以获取到页面的主框架
*/
isSystemPermission() {
return sal.isSystemPermission(this.query.agy.madCode);
},
async init() {
//使用Handsontable之前首先进行Handsontable类的初始化
await this.initResource();
//部门
await this.getTreeBmMethod();
//搜索框监听
this.initListener();
//初始化表格提交
this.initCellRender();
this.getPageInfo();
},
/*
* 初始化单元格提交
* */
initCellRender() {
let vm = this;
this.cellRender = function (instance,td,row,col,prop,value,cellProperties) {
if ('numeric' == cellProperties.type) {
vm.Handsontable.renderers.NumericRenderer.apply(this, arguments);
if (value == 0) {
td.innerHTML = '';
}
} else {
vm.Handsontable.renderers.TextRenderer.apply(this, arguments);
}
td.style.color = '#000000';
if (cellProperties.readOnly) {
} else {
td.style.backgroundColor = '#00FFFF';
}
};
},
/*
* 搜索框监听
* */
initListener() {
let searchField = document.getElementById('searchField1');
let that = this;
that.Handsontable.dom.addEvent(searchField, 'keyup', function (event) {
debounceFn2(this.value, event);
});
var debounceFn2 = that.Handsontable.helper.debounce(function (value,event) {
that.reLoadData();
},500);
},
/*
* 获取工资项的时候使用
* */
initSalType() {
if (this.salTypeData.length == 0) {
this.resetParam();
return;
}
//设置默认值
if (_.isEmpty(this.currentSalType)) {
this.currentSalType = this.salTypeFilterData[0];
} else {
let v = this.currentSalType.typeCode;
this.currentSalTypeCode = '';
this.currentSalType = _.find(this.salTypeFilterData, function (o) {
return o.typeCode == v;
});
if (!this.currentSalType) {
this.currentSalType = this.salTypeFilterData[0];
}
}
if (this.currentSalType) {
this.currentSalTypeCode = this.currentSalType.typeCode;
} else {
this.currentSalTypeCode = null;
}
this.handleTypeChange(this.currentSalTypeCode);
},
//handsontable表格配置
initHandsontable() {
this.destroyHots();
let colHeaders = headerDatas;
let container = document.getElementById('calcTable');
let sheet = {};
sheet.colHeaders = this.calcHeaders(colHeaders);
sheet.data = this.tableFilterData;
sheet.tableHeight = this.tableHeight;
sheet.colWidths = 80;
sheet.fixedColumnsLeft = 2; //代码和名称
sheet.columns = this.getTableColumns(this.tableList, true);
sheet.cellRender = this.cellRender;
this.hot = new this.Handsontable(
container,
tableview.getHotSetting(sheet)
);
$('[id=hot-display-license-info]').remove();
},
/*
* 处理淡出切换
* */
handleFadeToggle() {
this.isFullScreen = !this.isFullScreen;
this.reRenderHot();
},
/*
* 通过这个获取表格中的数据-----输入关键字进行过滤之后
* */
handleCheckChange() {
this.reLoadData();
},
handleYearChange() {
this.resetParam();
this.getSalTypeData();
},
/*
* 单选工资类别改变
* */
handleTypeChange(v, flag) {
this.currentSalType = _.find(this.salTypeFilterData, function (o) {
return o.typeCode == v;
});
this.currentSalTypeCode = v;
//默认工资项为选中工资类别的第一个工资项
if (this.salTypeItemFilterData.length > 0) {
this.currentSalItemCode = this.salTypeItemFilterData[0].itemCode;
}
this.getSalTypeMo();
},
/*
* 处理工资项的变化
* */
handleItemChange(v, flag) {
this.currentSalItemCode = v;
this.getTableData();
},
/*
* 处理搜索清除
* */
handleSearchClear() {
this.reLoadData();
},
//获取年
getSalTypeYear() {
this.$loading();
fetch
.get('/sal/type/his/getYear', {
params: {
agyCode: sal.getAgyCode(this.query.agy.madCode),
},
})
.then(({ data }) => {
//此处获取到的年份是年:[object Object],[object Object],[object Object],[object Object]年:[object Object],[object Object],[object Object],[object Object]
console.log("年:"+data)
this.$loadingClose();
this.yearData = data;
if (this.yearData.length > 0) {
this.currentYear = this.yearData[0].year;
this.handleYearChange();
}
})
.catch(({ msg }) => {
this.$loadingClose();
this.$message({
type: 'error',
message: msg,
});
});
},
//获取工资类型
getSalTypeData() {
this.$loading();
fetch
.post('/sal/type/his/listVO', {
agyCode: sal.getAgyCode(this.query.agy.madCode),
year: this.currentYear,
})
.then(({ data }) => {
console.log("工资类型"+data)
this.$loadingClose();
this.salTypeData = data;
this.initSalType();
})
.catch(({ msg }) => {
this.$loadingClose();
this.$message({
type: 'error',
message: msg,
});
});
},
/*
* 目前的情况是,只有选中了工资项才会触发这个方法
* */
getTableData() {
console.log("表格数据")
this.$loading();
let url = '/sal/paydata/his/itemCodeLists';
let aa = '';
_.forEach(this.deptCodes, (t) => {
aa += "'" + t + "'" + ',';
});
aa = aa.substring(0, aa.length - 1);
fetch
.post(url, {
agyCode: sal.getAgyCode(this.query.agy.madCode),
year: this.currentYear,
salTypeCode: this.currentSalTypeCode, //工资类别
itemCode: this.currentSalItemCode, //工资项
deptCodes: aa, //部门编码
// mo:this.currentMo, currentMo是月份的第一个月份,后端xml中没有需要月份,但是页面打印的时候数据是空的
})
.then(({ data }) => {
console.log(data) //现在没有数据
this.$loadingClose();
tableData = data;
//通过这个获取表格中的数据????这个方法不就是获取表格中的数据吗?为什么还要调用?
this.handleCheckChange(); //应该说是通过这个获取表格中过滤后的的数据
this.initHandsontable(); //获取表格的配置,在里面配置了表格头,应该是这里出现了问题
/*//这个有什么用,是干什么的?
if (this.hot) {
this.hot.loadData(this.getData()); //getData是过滤数据的,应该是
}*/
})
.catch(({ msg }) => {
this.$loadingClose();
this.$message({
type: 'error',
message: msg,
});
});
},
//获取月份
getSalTypeMo() {
this.$loading();
fetch
.get('/sal/type/his/getMo', {
params: {
//通过 params 设置参数:是即将与请求一起发送的 URL 参数
agyCode: sal.getAgyCode(this.query.agy.madCode),
typeCode: this.currentSalTypeCode,
year: this.currentYear,
},
})
.then(({ data }) => {
console.log("月"+data)
this.$loadingClose();
this.moData = data;
if(this.moData.length > 0){
this.currentMo = this.moData[0].mo;
}
})
.catch(({ msg }) => {
this.$loadingClose();
this.$message({
type: 'error',
message: msg,
});
});
},
//获取部门
getTreeBmMethod() {
this.$loading();
fetch
.post('/mad/department/tree', {
agyCode: sal.getAgyCode(this.query.agy.madCode),
fiscal: sal.getFiscal(
this.query.agy.madCode,
this.GET_LOGIN_INFO.fiscal
),
}).then(({ data }) => {
this.$loadingClose();
if (data.length !== 0) {
this.getLastChild(data[0]);
}
this.treeDataBm = data;
//显示代码+名称
tableview.rebuildMadName(this.treeDataBm);
}).catch(({ msg }) => {
this.$loadingClose();
this.$message({
type: 'error',
message: msg,
});
});
},
/*
* 递归获取最后一个子节点,获取所有的部门
* */
getLastChild(data) {
if (data.children && data.children.length !== 0) {
this.getLastChild(data.children[0]);
} else {
//默认值选中的值,和右侧的状态
data.heightLight = 'heightLight';
this.query.code = data.madCode;
}
},
filterNode(value, data) {
//部门树需要的数据
if (!value) {
return true;
}
return data.madName.indexOf(value) !== -1;
},
/*
* 千分位显示数据,被handsontable表格配置的initHandsontable()方法调用
* */
getTableColumns(itemList) {
let columns = [];
_.forEach(itemList, function (o) {
if (o.isEnabled === 0) {
return;
}
let column = {};
column.data = o.data;
column.name = o.name;
column.readOnly = o.readOnly;
if (o.type == 'numeric') {
column.type = 'numeric';
column.allowInvalid = false;
column.numericFormat = { pattern: '0,0.00' };
column.strict = true;
} else {
column.type = 'text';
column.readOnly = true;
}
columns.push(column);
});
return columns;
},
buildMadDataMap() {
//人员项值集构建代码名称map,基础数据取名称,不再构建。
_.forEach(this.currentSchema.itemList, (o) => {
if (o.getdataType === 1) {
let f = _.find(this.getSchema().empFieldFilterData, function (field) {
return field.fieldCode === o.calcExpression;
});
if (f) {
if (util.isNotEmpty(f.atomCode)) {
if (f.valsetCode == '1') {
if (!this.madDataMap[f.atomCode]) {
let codeMap = {};
let valsetList = getEnumerate(f.atomCode);
_.forEach(valsetList, (row) => {
codeMap[row.code] = row.name;
});
this.madDataMap[f.atomCode] = codeMap;
}
} else if (f.valsetCode == '0') {
if (!this.madDataMap[f.atomCode]) {
let codeMap = {};
_.forEach(this.mad[f.atomCode], (row) => {
codeMap[row.code] = row.name;
});
this.madDataMap[f.atomCode] = codeMap;
}
}
}
}
}
});
},
//不清楚是什么作用,但是加上这个的话,选择部门树时前端控制台不会报错
reLoadData() {
if (this.hot) {
this.hot.loadData(this.tableFilterData);
}
},
/**
*页面初始化
*1.发放表取历史数据,计算表取当前数据
*2.先取年度,再取月份和类别,最后取工资数据
*/
getPageInfo() {
this.getSalTypeYear();
// this.getSalTypeMo();
this.getSalTypeData();
},
/*
* 重新设置参数,加上这个,切换年度的时候前端控制台不报错
* */
resetParam() {
this.currentSalType = {};
this.currentSalTypeCode = null;
},
/**
* 销毁handSonTable
*/
destroyHots() {
if (this.hot) {
this.hot.destroy();
this.hot = null;
}
},
/*
* 重新进入,重新渲染
* */
reRenderHot() {
tableview.reRenderHot(this.getActiveHot());
},
/*
* 点击左右小手,控制报表是否全屏显示
* */
getActiveHot() {
return this.hot;
},
},
mounted: function () {
getMadInfo(this.query.agy.madCode).then((res = {}) => {
this.$set(this.$data, 'mad', res);
});
this.init();
$('.bar-line-left').hover(function (e) {
if (!e) {
e = window.event;
}
e.stopPropagation();
$('.pfs-icon1').find('i').fadeToggle(300);
});
},
beforeDestroy() {
this.destroyHots();
this.destroyTableData();
this.deptPrintHots = null;
},
//系统页签切换后,handsontable表头没显示出来,此页签激活后重新渲染一下
beforeRouteEnter(to, from, next) {
let flag = hasView(to.path); //true打开过的
next((vm) => {
if (flag) {
vm.reRenderHot();
}
});
},
};
</script>
<style lang="scss" scoped>
@import '~@/assets/style/variables.scss';
.dialog-form.new {
width: 60%;
margin-right: 20px;
.el-form-item {
padding-left: 30px;
}
}
.dialog-box-card {
width: 32%;
}
::v-deep .el-card__header {
padding: 10px 20px;
}
::v-deep .el-tree {
.heightLight {
@include bs-color-primary;
}
}
::v-deep .el-date-editor.el-input, .el-date-editor.el-input__inner {
width: 250px;
}
::v-deep .search .el-input__inner {
border: 1px solid #fff;
border-radius: 0;
//border-bottom: 1px solid #ddd;
transition: 0s;
padding-left: 3px;
&:hover {
//border: 1px solid rgba(82,168,236,0.8)!important;
border-bottom: 1px solid rgba(82, 168, 236, 0.8) !important;
//box-shadow: inset 0 1px 1px rgba(0,0,0,0.075), 0 0 8px rgba(82,168,236,0.6);
}
&:focus {
//border: 1px solid rgba(82,168,236,0.8)!important;
border-bottom: 1px solid rgba(82, 168, 236, 0.8) !important;
//box-shadow: inset 0 1px 1px rgba(0,0,0,0.075), 0 0 8px rgba(82,168,236,0.6);
}
}
.form-department {
::v-deep .el-form-item__label {
color: red
}
}
.bar-line-left {
position: fixed;
left: 0;
top: 100px;
z-index: 999;
.pfs-line-border {
display: inline-block;
width: 10px;
height: 30px;
@include bs-background-color-primary;
border-radius: 15px;
}
}
::v-deep .hanson-table{
.ht_master{
overflow: inherit !important;
}
}
</style>
VUE工资项汇总表:主要是看自己添加的备注
最新推荐文章于 2023-06-29 13:22:51 发布