|
@@ -0,0 +1,378 @@
|
|
|
+<template>
|
|
|
+ <div class="incomeDetail w-full h-full">
|
|
|
+ <!-- 头部 -->
|
|
|
+ <div class="incomeDetail-header flex-center">
|
|
|
+ <div class="item-center">
|
|
|
+ <i class="fa fa-align-justify" @click.prevent="switchMenu" style="cursor: pointer" />
|
|
|
+ <div class="m-lr">选择月份</div>
|
|
|
+ <el-date-picker size="small" v-model="selectMonth" :editable="false" format="yyyy-MM" value-format="yyyy-MM"
|
|
|
+ @change="retrieveDataAgain" :clearable="false" type="month" placeholder="选择月份" />
|
|
|
+ </div>
|
|
|
+ <div class="item-center">
|
|
|
+ <el-link type="primary" :underline="false" class="ml" @click="bonusDataExport">数据导出</el-link>
|
|
|
+ <el-link type="primary" :underline="false" class="ml" @click="clickOnFundingData">数据上传</el-link>
|
|
|
+ <el-link type="primary" :underline="false" class="ml" href="./upload/员工奖金模板.xlsx"
|
|
|
+ :download="'员工奖金模板' + '.xlsx'">模板下载</el-link>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 表格 -->
|
|
|
+ <div class="incomeDetail-table">
|
|
|
+ <el-table :data="tableList" highlight-current-row v-loading="tableListLoading" ref="tableListRef"
|
|
|
+ @selection-change="deleteSel" :height="300" style="width: 100%;">
|
|
|
+ <el-table-column type="selection" width="80" fixed="left"></el-table-column>
|
|
|
+ <el-table-column prop="jobNumber" label="工号"></el-table-column>
|
|
|
+ <el-table-column prop="userName" label="姓名"></el-table-column>
|
|
|
+ <el-table-column prop="bonusType" label="奖金类型"></el-table-column>
|
|
|
+ <el-table-column prop="totalBonusValue" label="奖金金额(元)"></el-table-column>
|
|
|
+ <el-table-column prop="name" label="分摊月份">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ {{ scope.row.startYM }} - {{ scope.row.endYM }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <div style="padding: 10px 14px;">
|
|
|
+ <el-button size="mini" type="primary" :disabled="deleteSelList.length == 0"
|
|
|
+ @click="batchDeletion">批量删除</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 图表 -->
|
|
|
+ <div class="incomeDetail-echart flex-1">
|
|
|
+ <!-- echarts 图 -->
|
|
|
+ <div class="incomeDetail-echart-echart flex-1" v-loading="echartsLoading">
|
|
|
+ <div id="clearfix" class="echarts-com w-full h-full">
|
|
|
+ <div id="containerEcharts" class="w-full h-full"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 资金数据导入 -->
|
|
|
+ <el-dialog title="资金数据导入" v-if="fundsImportIntoVisable" :visible.sync="fundsImportIntoVisable"
|
|
|
+ customClass="customWidth" width="500px">
|
|
|
+ <div class="importOfFundDataClass">
|
|
|
+ <el-form ref="form" label-width="100px">
|
|
|
+ <el-form-item label="分摊月份">
|
|
|
+ <el-date-picker v-model="sharingMonths" type="monthrange" value-format="yyyy-MM" range-separator="至"
|
|
|
+ start-placeholder="开始月份" end-placeholder="结束月份" :size="'small'" :picker-options="pickerOptions"
|
|
|
+ @change="sharingMonthsChange">
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="奖金类型">
|
|
|
+ <el-cascader v-model="typeOfFundsValue" :options="typeOfFundsArray" :props="{ expandTrigger: 'hover' }"
|
|
|
+ :size="'small'" :show-all-levels="false"></el-cascader>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="导入模板">
|
|
|
+ <el-upload class="upload-demo" :limit="1" :http-request="fundUpload" :size="'small'">
|
|
|
+ <el-button size="small" type="primary" :size="'small'">点击上传</el-button>
|
|
|
+ </el-upload>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+ <span slot="footer" class="dialog-footer">
|
|
|
+ <el-button type="primary" @click="submitFunds()" :loading="dataImportLoading">{{ $t('btn.determine')
|
|
|
+ }}</el-button>
|
|
|
+ </span>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <!-- 数据导出 -->
|
|
|
+ <el-dialog title="数据导出" v-if="dataExportVisable" :visible.sync="dataExportVisable" customClass="customWidth"
|
|
|
+ width="500px">
|
|
|
+ <div class="importOfFundDataClass">
|
|
|
+ <el-form ref="form" label-width="100px">
|
|
|
+ <el-form-item label="导出年份">
|
|
|
+ <el-date-picker v-model="selectYear" type="year" value-format="yyyy" :size="'small'">
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+ <span slot="footer" class="dialog-footer">
|
|
|
+ <el-button type="primary" @click="submitExport()" :loading="dataExportLoading">导出</el-button>
|
|
|
+ </span>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import dayjs from 'dayjs';
|
|
|
+import { fundCascadingPanel, processingChartOptions } from './common'
|
|
|
+export default {
|
|
|
+ components: {},
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ user: JSON.parse(sessionStorage.getItem("user")),
|
|
|
+ permissions: JSON.parse(sessionStorage.getItem("permissions")),
|
|
|
+ selectMonth: dayjs().format('YYYY-MM'),
|
|
|
+ selectYear: dayjs().format('YYYY'),
|
|
|
+ typeOfFundsValue: '',
|
|
|
+ deleteSelList: [],
|
|
|
+ missingFinanceUserList: [],
|
|
|
+ sharingMonths: [],
|
|
|
+ sharingMonthsTwo: [],
|
|
|
+ tableList: [],
|
|
|
+ tableListLoading: false,
|
|
|
+ echartsLoading: false,
|
|
|
+ dataExportLoading: false,
|
|
|
+ dataImportLoading: false,
|
|
|
+ showMissingDialog: false,
|
|
|
+ fundsImportIntoVisable: false,
|
|
|
+ dataExportVisable: false,
|
|
|
+ typeOfFundsArray: fundCascadingPanel,
|
|
|
+ pickerOptions: {
|
|
|
+ disabledDate(time) {
|
|
|
+ return time.getFullYear() > dayjs().format('YYYY');
|
|
|
+ }
|
|
|
+ },
|
|
|
+ importTemplateData: null,
|
|
|
+ echartsData: [],
|
|
|
+ myChart: null,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.retrieveDataAgain()
|
|
|
+ this.scrollFunction()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ retrieveDataAgain() {
|
|
|
+ this.getEchartsData()
|
|
|
+ this.getTableList()
|
|
|
+ },
|
|
|
+ submitExport() {
|
|
|
+ this.http.downloadFile('/contractBonusDetail/exportContractBonus', {
|
|
|
+ year: this.selectYear
|
|
|
+ }, '奖金项目分摊.xlsx', err => {
|
|
|
+ this.$message({
|
|
|
+ message: err,
|
|
|
+ type: 'error'
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ bonusDataExport() {
|
|
|
+ this.selectYear = dayjs().format('YYYY')
|
|
|
+ this.dataExportVisable = true
|
|
|
+ },
|
|
|
+ batchDeletion() {
|
|
|
+ this.$confirm(this.$t(this.$t('doyouwanttodeleteit')), this.$t('other.prompts'), {
|
|
|
+ confirmButtonText: this.$t('btn.determine'),
|
|
|
+ cancelButtonText: this.$t('btn.cancel'),
|
|
|
+ type: 'warning'
|
|
|
+ }).then(() => {
|
|
|
+ const ids = this.deleteSelList.map(item => item.id).join(',')
|
|
|
+ this.postData(`/contractBonusSummary/deleteBonusSummary`, { ids }).then((res) => {
|
|
|
+ this.$message.success('操作成功')
|
|
|
+ this.retrieveDataAgain()
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ sharingMonthsChange(val) {
|
|
|
+ const startData = val[0]
|
|
|
+ const endData = val[1]
|
|
|
+ const dateDetermination = dayjs(startData).isSame(dayjs(endData), 'year');
|
|
|
+ if (!dateDetermination) {
|
|
|
+ this.sharingMonths = JSON.parse(JSON.stringify(this.sharingMonthsTwo))
|
|
|
+ this.$message.warning('请选择同一年的月份')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.sharingMonthsTwo = JSON.parse(JSON.stringify(val))
|
|
|
+ },
|
|
|
+ submitFunds() {
|
|
|
+ if (!this.typeOfFundsValue || this.typeOfFundsValue.length == 0) {
|
|
|
+ this.$message.warning('请选择奖金类型')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!this.importTemplateData) {
|
|
|
+ this.$message.warning('请选择导入模板')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let formData = new FormData();
|
|
|
+ formData.append("startYM", this.sharingMonths[0]);
|
|
|
+ formData.append("endYM", this.sharingMonths[1]);
|
|
|
+ formData.append("bonusType", this.typeOfFundsValue[this.typeOfFundsValue.length - 1]);
|
|
|
+ formData.append("file", this.importTemplateData);
|
|
|
+ this.dataImportLoading = true
|
|
|
+ this.http.uploadFile('/contractBonusDetail/transTemplateData', formData,
|
|
|
+ res => {
|
|
|
+ this.dataImportLoading = false
|
|
|
+ if (res.code == 'ok') {
|
|
|
+ this.fundsImportIntoVisable = false
|
|
|
+ this.$message({
|
|
|
+ message: '操作成功',
|
|
|
+ type: 'success'
|
|
|
+ })
|
|
|
+ this.retrieveDataAgain()
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: res.msg,
|
|
|
+ type: 'error'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }, error => {
|
|
|
+ this.dataImportLoading = false
|
|
|
+ this.$message({
|
|
|
+ message: error,
|
|
|
+ type: 'error'
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ fundUpload(file) {
|
|
|
+ this.importTemplateData = file.file
|
|
|
+ },
|
|
|
+ clickOnFundingData() {
|
|
|
+ this.typeOfFundsValue = ''
|
|
|
+ this.sharingMonths = [dayjs().format('YYYY-MM'), dayjs().format('YYYY-MM')]
|
|
|
+ this.importTemplateData = null
|
|
|
+ this.fundsImportIntoVisable = true
|
|
|
+ },
|
|
|
+ getTableList() {
|
|
|
+ this.tableListLoading = true
|
|
|
+ this.postData(`/contractBonusSummary/getBonusSummary`, { ym: this.selectMonth }).then((res) => {
|
|
|
+ this.tableList = res.data || []
|
|
|
+ }).finally(() => {
|
|
|
+ this.tableListLoading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getEchartsData() {
|
|
|
+ this.echartsLoading = true
|
|
|
+ this.postData(`/contractBonusDetail/getContractBonus`, { year: dayjs(this.selectMonth).format('YYYY') }).then(res => {
|
|
|
+ // this.echartsData = res.data || []
|
|
|
+ this.instantiateChart(res.data || [])
|
|
|
+ }).finally(() => {
|
|
|
+ this.echartsLoading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ instantiateChart(list = []) {
|
|
|
+ const listNew = [...list]
|
|
|
+ if (this.myChart) {
|
|
|
+ this.myChart.dispose();
|
|
|
+ this.myChart = null
|
|
|
+ }
|
|
|
+ this.myChart = echarts.init(document.getElementById("containerEcharts"));
|
|
|
+ const option = processingChartOptions(listNew)
|
|
|
+ // 设置图表
|
|
|
+ this.myChart.resize({
|
|
|
+ // width: this.widthHtval
|
|
|
+ })
|
|
|
+
|
|
|
+ this.myChart.setOption(option, { notMerge: true });
|
|
|
+ },
|
|
|
+ deleteSel(sel) {
|
|
|
+ this.deleteSelList = sel
|
|
|
+ },
|
|
|
+ // 左右滚动
|
|
|
+ scrollFunction() {
|
|
|
+ this.domObj = document.getElementById('clearfix') // 通过id获取要设置的div
|
|
|
+ if (this.domObj.attachEvent) { // IE
|
|
|
+ this.domObj.attachEvent('onmousewheel', this.mouseScroll)
|
|
|
+ } else if (this.domObj.addEventListener) {
|
|
|
+ this.domObj.addEventListener('DOMMouseScroll', this.mouseScroll, false)
|
|
|
+ }
|
|
|
+ this.domObj.onmousewheel = this.domObj.onmousewheel = this.mouseScroll
|
|
|
+ },
|
|
|
+ mouseScroll(event) { // google 浏览器下
|
|
|
+ let detail = event.wheelDelta || event.detail
|
|
|
+ let moveForwardStep = -1
|
|
|
+ let moveBackStep = 1
|
|
|
+ let step = 0
|
|
|
+ step = detail > 0 ? moveForwardStep * 100 : moveBackStep * 100
|
|
|
+ event.preventDefault() // 阻止浏览器默认事件
|
|
|
+ this.domObj.scrollLeft = this.domObj.scrollLeft + step
|
|
|
+ },
|
|
|
+ switchMenu() {
|
|
|
+ this.$emit("switchMenu");
|
|
|
+ },
|
|
|
+ destroyChart() {
|
|
|
+ if (this.myChart) {
|
|
|
+ this.myChart.dispose();
|
|
|
+ this.myChart = null;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async postData(urls, param) {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ this.http.post(urls, { ...param },
|
|
|
+ res => {
|
|
|
+ if (res.code == 'ok') {
|
|
|
+ resolve(res)
|
|
|
+ } else {
|
|
|
+ this.$message({
|
|
|
+ message: res.msg,
|
|
|
+ type: 'error'
|
|
|
+ })
|
|
|
+ reject(res)
|
|
|
+ }
|
|
|
+ resolve(res)
|
|
|
+ },
|
|
|
+ error => {
|
|
|
+ this.$message({
|
|
|
+ message: error,
|
|
|
+ type: "error"
|
|
|
+ });
|
|
|
+ reject(error)
|
|
|
+ }
|
|
|
+ )
|
|
|
+ });
|
|
|
+ },
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ this.destroyChart();
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.incomeDetail {
|
|
|
+ color: #606266;
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .incomeDetail-header {
|
|
|
+ height: 40px;
|
|
|
+ background: #f2f2f2;
|
|
|
+ padding: 10px;
|
|
|
+
|
|
|
+ .incomeDetail-header-const {
|
|
|
+ width: 440px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .incomeDetail-echart {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ padding: 8px;
|
|
|
+
|
|
|
+ .echarts-com {
|
|
|
+ overflow-x: auto;
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.flex-1 {
|
|
|
+ flex: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.ml {
|
|
|
+ margin-left: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.m-lr {
|
|
|
+ margin: 0 12px;
|
|
|
+}
|
|
|
+
|
|
|
+.item-center {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.flex-center {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+.w-full {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.h-full {
|
|
|
+ height: 100%;
|
|
|
+}
|
|
|
+</style>
|