主页面
<template>
<!-- 内容区域 -->
<div class="sal-rpt-unit-grant">
<!-- 单位头部开始 -->
<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">
<el-button-group>
<el-button type="primary" size="mini" @click="handleRefresh">刷新</el-button>
<el-button type="primary" size="mini" @click="handleExport">导出</el-button>
</el-button-group>
</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="mr1 mt5" style="font-size:12px;">
月份:
<el-select v-model="currentMo" filterable placeholder="请选择" size="mini" class="ml1 fl"
style="width: 60px;" @change="handleMoChange">
<el-option
v-for="item in fromMoOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</span>
<span class="mr1 mt5" style="font-size:12px;">
至
<el-select v-model="toMo" filterable placeholder="请选择" size="mini" class="ml1 fl"
style="width: 60px;" @change="handleMoChange">
<el-option
v-for="item in toMoOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</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 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>
<!-- 右表表格结束 -->
<iframe ref="xlsxIframe" :src="PUBLIC_PATH + 'static/lib/xlsx/index.html' " style="display:none"></iframe>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import { PUBLIC_PATH } from '@/assets/js/constant';
import { GET_LOGIN_INFO, GET_CONTEXT_AGY_ACB } from '@/store/login';
import { getMadInfo } from '@/mixin/agy';
import { innerHeight, getEnumerate, download } from '@/mixin/page';
import fetch from '@/config/fetch';
import util from '@/assets/js/util';
const handsontable = () => import(/*webpackChunkName: 'async_vendors/handsontable-pro' */ 'handsontable-pro');
const fileSaver = () => import(/* webpackChunkName: 'async_vendors/file-saver' */ 'file-saver');
import 'handsontable/dist/handsontable.full.css';
import tableview from '../sal-pub/tableview';
import sal from '../sal-pub/sal';
import { hasView } from '@/mixin/system';
import { CONTEXT_PATH } from '@/assets/js/constant';
var tableData = [];
var ff = [];
export default {
name: 'SAL_RPT_UNIT_GRANT',
mixins: [innerHeight],
data() {
return {
query: {
//查询表格的参数
agy: {
madCode: '',
madName: '',
},
isEnabled: 1,
keyword: '',
code: '', //部门code
},
filterText: '',
treeDataBm: [], //部门树的数据
tableData: [],
searchText: '',
isFullScreen: false,
hot: null,
deptPrintHots: null,
salTypeData: [],
currentYear: null,
currentMo: null,
toMo: null,
currentSalType: {},
currentSalTypeCode: null,//单选工资类别
cellRender: null,
nestedHeaders:[], //放合并数据,不能被注释掉
yearData: null,
currentSchema: null,
madDataMap: {},
sTypeCode: [],
mad: {}, //调用$set添加属性
currentSalItemCode: [],
deptCodes: [],
headerDatas: [],
tableList: [],
PUBLIC_PATH,
dongtaijiyibiaotou: [],
itemTableList: [], //二级表头 其中 一级表头为unitGrantCode + unitGrantName ,二级表头为unitGrantCode不为空的工资项(itemCode,itemName)
};
},
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 = '';
this.resetParam();
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);
}
},
/**
*页面初始化
*1.发放表取历史数据,计算表取当前数据
*2.先取年度,再取月份和类别,最后取工资数据
*/
getPageInfo() {
//从工资项和公式中获取到已经分好组的工资项
this.getSalTypeYear();
this.getItemTabelData();
this.getTableData();
},
//递归获取最后一个子节点
getLastChild(data) {
if (data.children && data.children.length !== 0) {
this.getLastChild(data.children[0]);
} else {
//默认值选中的值,和右侧的状态
data.heightLight = 'heightLight';
this.query.code = data.madCode;
}
},
//获取部门
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,
});
});
},
filterNode(value, data) {
//部门树需要的数据
if (!value) {
return true;
}
return data.madName.indexOf(value) !== -1;
},
nodeClick(data) {
this.query.code = data.madCode;
},
async init() {
await this.initResource();
//部门
this.getTreeBmMethod();
//搜索框监听
this.initListener();
this.initCellRender();
this.getPageInfo();
// this.tableFilterMoData();
},
//handsontable表格配置
initHandsontable() {
this.destroyHots();
let container = document.getElementById('calcTable');
let sheet = {};
sheet.colHeaders = true;
sheet.tableHeight = this.tableHeight;
sheet.colWidths = 100; //设置所有列宽为150像素
sheet.fixedColumnsLeft = 150; //固定几列
sheet.columns = this.getTableColumns(this.tableList, true); //this.tableList控制表头
sheet.cellRender = this.cellRender;
sheet.nestedHeaders = this.getNestedHeaders();
sheet.data = this.tableFilterData;
this.hot = new this.Handsontable(
container,
tableview.getHotUnitSetting(sheet)
);
$('[id=hot-display-license-info]').remove();
},
//构建表头
getNestedHeaders(){
let result = [];
let table1 = [];
let staticHeader = ['工资月份','单位编码','单位名称','姓名','身份证号','工资卡号','工资卡开户银行'];
_.forEach(staticHeader,o=>{
ff.push(o);
let headerContainer = {};
headerContainer.label = o;
headerContainer.colspan = 1;
table1.push(headerContainer);
});
let typeCodeList = [];//存放工资类别的集合
_.forEach(this.salTypeData,o=>{
typeCodeList.push(o.typeCode)
})
typeCodeList = _.uniqWith(typeCodeList, _.isEqual);
let typeCodeIndex = [];//工资类别的下标
typeCodeIndex = _.findLastIndex(typeCodeList, o=> {
return o == this.currentSalTypeCode;
})
let aa = _.groupBy(this.itemTableList, 'typeCode');
let bb = _.map(aa,(k,v)=>{
if(v == this.currentSalTypeCode){
return k;
}
});
let cc = _.find(bb,o=>{
return o !== undefined;
})
let obj = _.groupBy(cc, 'unitGrantName');
_.forEach(obj, (v, k)=> {
let col = {}
col.label = k;
col.colspan = v.length;
table1.push(col);
this.dongtaijiyibiaotou.push(col);
});
result.push(table1);
let tables2 = [' ',' ',' ',' ',' ',' ',' '];
_.forEach(obj,(v,k)=>{
_.forEach(v,j=>{
tables2.push(j.itemName);
ff.push(j.itemName)
})
})
result.push(tables2);
ff = _.uniqWith(ff, _.isEqual);
return result;
},
//千分位显示数据
getTableColumns(itemList) { //itemList里面放的是表头
let columns = [];
_.forEach(itemList, 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;
},
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);
},
//控制月份
handleMoChange(v) {
this.getSalTypeData();
},
handleFadeToggle() {
this.isFullScreen = !this.isFullScreen;
this.reRenderHot();
},
//点击左右小手,控制报表是否全屏显示
getActiveHot() {
return this.hot;
},
reRenderHot() {
tableview.reRenderHot(this.getActiveHot());
},
//获取年
getSalTypeYear() {
this.$loading();
fetch.get('/sal/type/his/getYear', {
params: {
agyCode: sal.getAgyCode(this.query.agy.madCode),
mofDivCode: this.GET_LOGIN_INFO.mofDivCode
},
}).then(({ 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),
mofDivCode: this.GET_LOGIN_INFO.mofDivCode,
year: this.currentYear, //需要写活
}).then(({ data }) =>{
this.$loadingClose();
this.salTypeData = data;
//如果是没有设置单位自发工资项的类别,就不显示这个工资类别
this.salTypeData = _.filter(this.salTypeData ,o=>{
return _.indexOf(this.sTypeCode,o.typeCode) !== -1;
})
this.initSalType();
}).catch(({ msg }) => {
this.$loadingClose();
this.$message({
type: 'error',
message: msg,
});
});
},
//单选工资类别改变
handleTypeChange(v) {
ff = [];
this.typeCode = v;
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.getTableData();//写上这个方法后,该方法可以使用这个单选工资类别改变的方法
},
handleItemChange(v, flag) {
this.currentSalItemCode = v;
this.getTableData(); //忘记了为什么要加这一个
},
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';
}
};
},
handleCheckChange() {
this.reLoadData();
},
//刷新的方法
handleRefresh() {
this.resetParam();
this.getPageInfo();
},
handleExport(){
let searchItemName = [];
_.forEach(this.salTypeItemFilterData,o=>{
if(o.itemCode == this.currentSalItemCode){
searchItemName = o.itemName;
}
})
let params = {
agyCode: this.query.agy.madCode,
fiscal: sal.getFiscal(this.query.agy.madCode, this.GET_LOGIN_INFO.fiscal),
year: this.currentYear,
typeCode: this.typeCode,
mofDivCode: this.GET_LOGIN_INFO.mofDivCode,
itemName: searchItemName,
toMo: this.toMo,
fromMo: this.currentMo,
}
let url =
CONTEXT_PATH +
'/sal/paydata/his/exportGrant?url=' +
encodeURIComponent(JSON.stringify(params));
download(url);
},
reLoadData() {
if (this.hot) {
this.hot.loadData(this.tableFilterData);
}
},
handleSearchClear() {
this.reLoadData();
},
destroyHots() {
if (this.hot) {
this.hot.destroy();
this.hot = null;
}
},
destroyTableData() {
tableData = null;
},
handleYearChange() {
this.resetParam();
this.getSalTypeData();
},
resetParam() {
this.currentSalType = {};
this.currentSalTypeCode = null;
this.currentMo = null;
this.toMo= null;
},
initSalType() {
if (this.salTypeData.length == 0) {
this.resetParam();
return;
}
//过滤启用的,及字段名转为驼峰
_.forEach(this.salTypeData, function (o) {
o.itemList = _.filter(o.itemList, function (item) {
return item.isEnabled === 1;
});
_.forEach(o.itemList, function (item) {
item.itemCode = tableview.toHump(item.itemCode);
});
});
//月份下拉框
if (this.currentMo == null && this.fromMoOptions.length > 0) {
this.currentMo = this.fromMoOptions[0].value;
}
if(this.toMo == null && this.toMoOptions.length > 0){
this.toMo = this.toMoOptions[0].value;
}
//设置默认值
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);
},
tableFilterMoData() {
//部门、搜索框、工资类别过滤。
let checkNodes = this.$refs.tree2.getCheckedNodes(false, true); //部门
// debugger
let searchTextArray = [];
let searchTextUpper = [];
let tmp = _.split(_.trim(this.searchText), ' ');
_.forEach(tmp, function (o) {
if (_.trim(o) == '') {
return;
}
searchTextArray.push(o); //push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。
searchTextUpper.push(_.toUpper(o));
});
let searchTextFlag = searchTextArray.length > 0 ? true : false;
let filterData = _.filter(tableData, (o) => {
let b = o.salTypeCode === this.currentSalTypeCode;
if (!b) {
return false;
}
if (checkNodes.length > 0) {
let f = _.find(checkNodes, function (s) {
return s.madCode == o.departmentCode;
});
b = f ? true : false;
}
if (!b) {
return false;
}
if (searchTextFlag) {
for (let i = 0; i < searchTextArray.length; i++) {
//人员代码,名称, 拼音简拼,大写
if (
o.empCode.indexOf(searchTextArray[i]) != -1 ||
o.empName.indexOf(searchTextArray[i]) != -1
) {
b = true;
break;
} else {
b = false;
}
}
}
return b;
});
let cloneData = _.cloneDeep(filterData);
let datas = [];
_.forEach(cloneData, function (o) {
let map = {};
_.forEach(this.nestedHeaders, function (f) {
let a = f.code;
if (!map[f.code]) {
map[f.code] = o[a];
}
});
datas.push(map);
});
return datas;
},
//从工资项和公式表里面获取分好组的工资项作为动态表头 获取工资项数据
getItemTabelData(){
this.$loading();
fetch.get('/sal/type/item/his/list', {
params: {
agyCode: sal.getAgyCode(this.query.agy.madCode),
fiscal: sal.getFiscal(this.query.agy.madCode, this.GET_LOGIN_INFO.fiscal),
typeCode: this.typeCode,
year: this.currentYear,
isEnabled: 1,
mofDivCode: this.GET_LOGIN_INFO.mofDivCode,
}
}).then(({data}) => {
this.$loadingClose();
this.itemTableList = _.filter(data,o =>{
if(o.unitGrantCode != null){
return data;
}
});
_.forEach(this.itemTableList,h=>{
if(_.indexOf(this.sTypeCode,h.typeCode)){
this.sTypeCode.push(h.typeCode);
}
})
this.getTableData();
}).catch(({msg}) => {
this.$loadingClose();
this.$message({
type: 'error',
message:msg
});
});
},
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;
}
}
}
}
}
});
},
// 获取本年所有工资历史数据:
getTableData() {
this.$loading();
let field = "card_id as cardId,max(emp_name) as empName,max(agy_code) as agyCode,max(emp_code) as empCode,max(department_name) as departmentName,max(department_code) as departmentCode,agy_name as agyName,mo as mo";
let param = "card_id,emp_name,agy_name,mo,emp_code,agy_code,department_code,department_name";
fetch.post('/sal/paydata/his/sumlist', {
agyCode: sal.getAgyCode(this.query.agy.madCode),
fiscal: sal.getFiscal(this.query.agy.madCode, this.GET_LOGIN_INFO.fiscal),
mofDivCode: this.GET_LOGIN_INFO.mofDivCode,
typeCode: this.currentSalTypeCode,
year: this.currentYear,//年度下拉框不显示了,不清楚是不是这个地方的原因,也可能是缓存一下就好了
fromMo: this.currentMo,
toMo: this.toMo,
field: field,
param: param
}).then(({data}) => {
this.$loadingClose();
tableData = data;
let tables = [];
tables.push(
{ name: '工资月份', data: 'mo', type: 'text', readOnly: true },
{ name: '单位编码', data: 'agyCode', type: 'text', readOnly: true },
{ name: '单位名称', data: 'agyName', type: 'text', readOnly: true },
{ name: '姓名', data: 'empName', type: 'text', readOnly: true },
{ name: '身份证号', data: 'cardId', type: 'text', readOnly: true },
{ name: '工资卡号', data: 'empBankAcc', type: 'text', readOnly: true },
{ name: '工资卡开户银行', data: 'accBankName', type:'text',readOnly: true},
);
this.getNestedHeaders();
for(let aa of this.dongtaijiyibiaotou){
for (let key of this.itemTableList){
//key.typeCode === this.currentSalTypeCode控制页面上只显示当前工资类别的表头
if(aa.label === key.unitGrantName && key.typeCode === this.currentSalTypeCode){
tables.push(
{name: key.itemName, data: key.itemCode, type:'numeric',readOnly: true}
)
}
}
}
tables = _.uniqWith(tables, _.isEqual); //去重
this.tableList = tables;
this.initHandsontable(); //一开始没有在页面上显示就是因为没有加上这一步
}).catch(({msg}) => {
this.$loadingClose();
this.$message({
type: 'error',
message: msg
});
});
},
isSystemPermission() {
return sal.isSystemPermission(this.query.agy.madCode);
},
},
computed:{
...mapGetters([GET_LOGIN_INFO, GET_CONTEXT_AGY_ACB]),
tableHeight() {
return this.innerHeight - 150;
},
fromMoOptions(){
let that = this;
let salTypeData = _.filter(this.salTypeData, (o) =>{
return o.year == that.currentYear;
});
let moOptions = [];
_.forEach(_.uniq(_.map(_.orderBy(salTypeData, ['mo'], ['desc']), 'mo')), (i) =>{
moOptions.push({label: i + '月', value: i});
});
if(this.toMo != null){
moOptions = _.filter(moOptions, (o) =>{
return o.value <= that.toMo;
});
}
return moOptions;
},
toMoOptions(){
let that = this;
let salTypeData = _.filter(this.salTypeData, (o) =>{
return o.year == that.currentYear;
});
let moOptions = [];
_.forEach(_.uniq(_.map(_.orderBy(salTypeData, ['mo'], ['desc']), 'mo')), (i) =>{
moOptions.push({label: i + '月', value: i});
});
if(this.currentMo != null){
moOptions = _.filter(moOptions, (o) =>{
return o.value >= that.currentMo;
});
}
return moOptions;
},
tableFilterData() {
//部门、搜索框、工资类别过滤。
let checkNodes = this.$refs.tree2.getCheckedNodes(false, true); //部门
let filterData = tableview.filterTableData(tableData, checkNodes, this.currentSalTypeCode, this.searchText);
return filterData;
},
//监听工资类别
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;
},
},
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;
}
}
#calcTable{
overflow: inherit !important;
}
::v-deep .hanson-table{
.ht_master{
overflow: inherit !important;
}
}
</style>
辅助页面
<el-table-column prop="unitGrantCode" width="120" label="单位自发分类">
<template slot-scope="scope">
<el-select size="mini" style="width: 100px" v-model="scope.row.unitGrantCode" @change="handleUnitChange(scope.row)" clearable>
<el-option
v-for="item in expecoAdd"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<span v-if="scope.row.unitGrantCode">
{{scope.row.unitGrantCode}} {{scope.row.unitGrantName}}
</span>
</template>
</el-table-column>
expecoAdd: [],
//单位自发分类的点击事件,将页面上的值赋值给数据库中的字段
handleUnitChange(row){
_.forEach(this.expecoAdd,o=>{
if(row.unitGrantCode == o.value){
row.unitGrantName = o.label;
}
});
},
mounted() {
getMadInfo(this.query.agy.madCode).then((res = {}) => {
let exAdd = _.filter(res.EXPECO,o => {
if(o.code === '30101' || o.code == '30102' || o.code == '30107' || o.code == '30199' || o.code == '30239' || o.code == '30309'){
return o.code + o.name;
}
});
this.expecoAdd = exAdd.map((item) => {
return {
label:item.name,
value:item.code
}
})
});
this.initTableSort();
this.getStandardData();
this.getTableData();
}
后端导出全部
/**
* 单位自发工资表导出excel 导出全部
*/
public void exportGrant(HttpServletRequest request, Map<String, Object> params, HttpServletResponse response) {
//获取参数
String agyCode = params.get("agyCode").toString();
Integer fiscal = Integer.parseInt(params.get("fiscal").toString());
Integer year = Integer.parseInt(params.get("year").toString());
Integer toMo = Integer.parseInt(params.get("toMo").toString());
Integer currentMo = Integer.parseInt(params.get("fromMo").toString());
//第一步,创建一个Workbook,对应一个Excel文件
HSSFWorkbook wb = new HSSFWorkbook();
//查询历史类别数据
SalTypeHis salTypeHis = new SalTypeHis();
salTypeHis.setAgyCode(agyCode);
salTypeHis.setFiscal(fiscal);
//需要获取到月份区间
List<SalTypeHisVO> salTypeHisVOS = new ArrayList<>();//获取了历史工资项
Map<String, SalTypeHisVO> typeMap = new HashMap<>();
List<String> sheetNames = new ArrayList<>();
for (SalTypeHisVO vo : salTypeHisService.selectVO(salTypeHis)) {
if (vo.getMo() >= currentMo && vo.getMo() <= toMo) {
if (typeMap.get(vo.getTypeCode()) == null) {
salTypeHisVOS.add(vo);
typeMap.put(vo.getTypeCode(), vo);
sheetNames.add(vo.getTypeName());
}
}
}
List<String> typeCodes = new ArrayList<>();
for (SalTypeHisVO vo : salTypeHisVOS) {
if (vo.getTaxType() != 3) {
typeCodes.add(vo.getTypeCode());
}
}
for(int x = 0;x<sheetNames.size();x++) {
//第二步,在Workbook中添加一个sheet,对应Excel文件中的sheet
HSSFSheet sheet = wb.createSheet(sheetNames.get(x)); //设置表格列宽度为10个字节
sheet.setDefaultColumnWidth(15);
//第三步,设置样式以及字体样式
HSSFCellStyle headerStyle = createHeadCellStyle(wb);
HSSFCellStyle contentStyle = createContentCellStyle(wb);//居右
//需要获取到表格列数固定的是7 动态的表头长度需要 agyCode fiscal typeCode为条件
//从sal_type_item_his表中查询出来unitGrantCode不为空的数据
SalTypeItem salTypeItemHis = new SalTypeItem();
salTypeItemHis.setAgyCode(agyCode);
salTypeItemHis.setFiscal(fiscal);
salTypeItemHis.setYear(year);
salTypeItemHis.setIsEnabled(1);
salTypeItemHis.setTypeCode(typeCodes.get(x));
Integer tableSize = 0;
List<SalTypeItem> salTypeItemHisList = salTypeItemService.getList(salTypeItemHis);
Integer tableL = 0;
List<String> unitGrantNames = new ArrayList<>();
List<String> finalOneHeader = new ArrayList<>();
String[] row_second = {"工资月份", "单位编码", "单位名称", "姓名", "身份证号", "工资卡号", "工资卡开户银行"};
for (int y = 0; y < row_second.length; y++) {
finalOneHeader.add(row_second[y]);
//将动态的一级表头放到数组表头中
unitGrantNames.add(row_second[y]);
}
Map<String, String> inUnitGrantNames = new HashMap<>();
for (int j = 0; j < salTypeItemHisList.size(); j++) {
if (salTypeItemHisList.get(j).getUnitGrantCode() != null) {
//获取到当前工资类别中二级表头中一级表头的个数和名称,需要对一级表头进行去重
if (salTypeItemHisList.get(j).getUnitGrantName() != null && !unitGrantNames.contains(salTypeItemHisList.get(j).getUnitGrantName())) {
unitGrantNames.add(salTypeItemHisList.get(j).getUnitGrantName());
}
//key为二级表头,value为一级表头
inUnitGrantNames.put(salTypeItemHisList.get(j).getItemName(), salTypeItemHisList.get(j).getUnitGrantName());
tableL++;
}
}
//获取相同的一级表头下,二级表头的个数 结果 (测试 2 非测试 3)
Map<String, Integer> finalInNames = new HashMap<>();
for (Map.Entry<String, String> entry : inUnitGrantNames.entrySet()) {
if (finalInNames.containsKey(entry.getValue())) {
finalInNames.put(entry.getValue(), finalInNames.get(entry.getValue()) + 1);
} else {
finalInNames.put(entry.getValue(), 1);
}
}
tableSize = tableL + 7; //获取到表格的长度
//查询出当前页面的所有数据
SalPayDataHis salPayDataHis = new SalPayDataHis();
salPayDataHis.setAgyCode(agyCode);
salPayDataHis.setFiscal(fiscal);
salPayDataHis.setSalTypeCode(typeCodes.get(x));
List<SalPayDataHis> salPayDataList = new ArrayList<>();
for (SalPayDataHis newSalPayDataHis : salPayDataHisService.list(salPayDataHis)) {
if (newSalPayDataHis.getMo() >= currentMo && newSalPayDataHis.getMo() <= toMo) {
salPayDataList.add(newSalPayDataHis);
}
}
//第四步,创建标题 ,合并标题单元格
// 行号
int rowNum = 0;
//第一行
HSSFRow row2 = sheet.createRow(rowNum++);
List<String> newYiName = new ArrayList<>();
for (int q = 7; q < unitGrantNames.size(); q++) {
newYiName.add(unitGrantNames.get(q));
}
// 合并
sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 0));
sheet.addMergedRegion(new CellRangeAddress(0, 1, 1, 1));
sheet.addMergedRegion(new CellRangeAddress(0, 1, 2, 2));
sheet.addMergedRegion(new CellRangeAddress(0, 1, 3, 3));
sheet.addMergedRegion(new CellRangeAddress(0, 1, 4, 4));
sheet.addMergedRegion(new CellRangeAddress(0, 1, 5, 5));
sheet.addMergedRegion(new CellRangeAddress(0, 1, 6, 6));
Integer firstNum = 6;
Integer lastNum = 6;
//给动态的一级表头合并单元格
for (int w = 0; w < newYiName.size(); w++) {
for (String num : finalInNames.keySet()) {
if (newYiName.get(w).equals(num)) {
if (w == 0) {
firstNum = firstNum + 1;
} else {
firstNum = lastNum + 1;
}
//需要和表头对应
lastNum = finalInNames.get(num) + lastNum;
Integer cal = lastNum - firstNum;
finalOneHeader.add(num);
//避免其他单元格被占据多列单元格的覆盖
if (cal != 0) {
for (int v = 0; v < cal; v++) {
finalOneHeader.add(" ");
}
}
if (firstNum != lastNum) {
sheet.addMergedRegion(new CellRangeAddress(0, 0, firstNum, lastNum));
}
break;
}
}
}
for (int k = 0; k < finalOneHeader.size(); k++) {
//创建一个单元格
HSSFCell cell = row2.createCell(k);
//创建一个内容对象
HSSFRichTextString text = new HSSFRichTextString(finalOneHeader.get(k));
//将内容对象的文字内容写入到单元格中
cell.setCellValue(text);
cell.setCellStyle(headerStyle);
}
//第三行
HSSFRow row3 = sheet.createRow(1);
String[] row_third = {"", "", "", "", "", "", ""};
List<String> newErHead = new ArrayList<>();
for (int b = 0; b < row_third.length; b++) {
newErHead.add(row_third[b]);
}
for (int s = 7; s < unitGrantNames.size(); s++) {
for (String key : inUnitGrantNames.keySet()) {
if (unitGrantNames.get(s).equals(inUnitGrantNames.get(key))) {
newErHead.add(key);
}
}
}
for (int g = 0; g < newErHead.size(); g++) {
//创建一个单元格
HSSFCell cell = row3.createCell(g);
//创建一个内容对象
HSSFRichTextString text = new HSSFRichTextString(newErHead.get(g));
//将内容对象的文字内容写入到单元格中
cell.setCellValue(text);
cell.setCellStyle(headerStyle);
}
//获取到工资项名称,匹配到工资项编码,然后进行工资项的动态数据绑定
//查询授权工资项
List<String> newErCode = new ArrayList<>();
for (int l = 7; l < newErHead.size(); l++) {
for (int r = 0; r < salTypeItemHisList.size(); r++) {
if (newErHead.get(l).equals(salTypeItemHisList.get(r).getItemName())) {
newErCode.add(salTypeItemHisList.get(r).getItemCode());
break;
}
}
}
//绑定数据
for (int t = 0; t < salPayDataList.size(); t++) {
//创建一行
HSSFRow row4 = sheet.createRow(t + 2);
row4.setRowStyle(contentStyle);
row4.createCell(0).setCellValue(salPayDataList.get(t).getMo());
row4.createCell(1).setCellValue(salPayDataList.get(t).getAgyCode());
row4.createCell(2).setCellValue(salPayDataList.get(t).getAgyName());
row4.createCell(3).setCellValue(salPayDataList.get(t).getEmpName());
row4.createCell(4).setCellValue(salPayDataList.get(t).getCardId());
row4.createCell(5).setCellValue(salPayDataList.get(t).getBankAcc());
row4.createCell(6).setCellValue(salPayDataList.get(t).getEmpBankAcc());
//获取到工资项名称,匹配到工资项编码,然后进行工资项的动态数据绑定
for (int p = 0; p < newErCode.size(); p++) {
BigDecimal data = getProperty(salPayDataList.get(t), newErCode.get(p));
if (p == 0) {
row4.createCell(7).setCellValue(data.toString());
} else {
row4.createCell(7 + p).setCellValue(data.toString());
}
}
}
}
try {
//准备将Excel的输出流通过response输出到页面下载
//八进制输出流
response.setContentType("application/octet-stream");
response.setCharacterEncoding("utf-8");
//这后面可以设置导出Excel的名称,此例中名为student.xls(解决文件名称乱码问题)
response.setHeader("content-disposition", "attachment;filename=" + new String("工资项汇总表".getBytes(), "ISO8859-1") + ".xlsx" );
//刷新缓冲
response.flushBuffer();
//workbook将Excel写入到response的输出流中,供页面下载
wb.write(response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
/*
*通过属性名获取到属性值
* */
public static BigDecimal getProperty(SalPayDataHis salPayDataHis, String value) {
BigDecimal bigDecimal = new BigDecimal(BigInteger.ZERO);
try{
// 获取Bean的某个属性的描述符
PropertyDescriptor proDescriptor = new PropertyDescriptor(value, SalPayDataHis.class);
// 获得用于读取属性值的方法
Method readMethod = proDescriptor.getReadMethod();
// 读取属性值
bigDecimal = (BigDecimal)readMethod.invoke(salPayDataHis);
}catch (Exception e){
e.printStackTrace();
}
return bigDecimal;
}
/**
* 创建内容样式
*
* @param wb
* @return
*/
private static HSSFCellStyle createContentCellStyle1(HSSFWorkbook wb) {
HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
cellStyle.setAlignment(HorizontalAlignment.LEFT);// 水平居左
cellStyle.setWrapText(true);// 设置自动换行
cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
cellStyle.setBorderLeft(BorderStyle.THIN); //左边框
cellStyle.setBorderRight(BorderStyle.THIN); //右边框
cellStyle.setBorderTop(BorderStyle.THIN); //上边框
// 生成12号字体
HSSFFont font = wb.createFont();
font.setColor((short) 8);
font.setFontHeightInPoints((short) 12);
cellStyle.setFont(font);
return cellStyle;
}