|
|
@@ -0,0 +1,190 @@
|
|
|
+<template>
|
|
|
+ <basic-container>
|
|
|
+ <avue-crud
|
|
|
+ v-bind="bindVal"
|
|
|
+ v-on="onEvent"
|
|
|
+ v-model="form"
|
|
|
+ :page.sync="page"
|
|
|
+ :before-open="handleBeforeOpen"
|
|
|
+ :header-cell-style="headerCellStyle"
|
|
|
+ :span-method="spanMethod"
|
|
|
+ >
|
|
|
+ <template slot="menuLeft">
|
|
|
+ <el-button
|
|
|
+ type="warning"
|
|
|
+ size="small"
|
|
|
+ plain
|
|
|
+ icon="el-icon-download"
|
|
|
+ @click="handleExport"
|
|
|
+ >
|
|
|
+ 导出
|
|
|
+ </el-button>
|
|
|
+ <print-table-btn @click="printTable" />
|
|
|
+
|
|
|
+ <div style="display: flex; align-items: center;">
|
|
|
+ <year-month-select v-model="params.yearAndMonth" :showAllYear="false"></year-month-select>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ </avue-crud>
|
|
|
+
|
|
|
+ <WideTablePrinter
|
|
|
+ ref="printWideTable"
|
|
|
+ :columns="wideTableColumns"
|
|
|
+ :data="data"
|
|
|
+ :print-title="printTitle"
|
|
|
+ :rows-per-page="30"
|
|
|
+ :default-landscape="true"
|
|
|
+ />
|
|
|
+ </basic-container>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import YearMonthSelect from "@/components/year-month-select";
|
|
|
+import {exportBlob} from "@/api/common";
|
|
|
+import {getToken} from "@/util/auth";
|
|
|
+import {downloadXls} from "@/util/util";
|
|
|
+import { deepClone, getMonthDatesWithMarkers } from "@/util/util";
|
|
|
+import moment from "moment";
|
|
|
+import ChineseHoliday from "@chnlib/chinese-holiday";
|
|
|
+
|
|
|
+
|
|
|
+export default window.$crudCommon({
|
|
|
+ components: {
|
|
|
+ YearMonthSelect,
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ params: {
|
|
|
+ yearAndMonth: moment(new Date()).format('YYYYMM'),
|
|
|
+ },
|
|
|
+ defaultColumns: [],
|
|
|
+
|
|
|
+ wideTableColumns: [],
|
|
|
+ printTitle: "",
|
|
|
+ };
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ 'params.yearAndMonth'(newVal) {
|
|
|
+ this.refreshTableCol(newVal);
|
|
|
+ this.page.currentPage = 1;
|
|
|
+ this.getList(this.page);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async created() {
|
|
|
+ this.defaultColumns = deepClone(this.option.column);
|
|
|
+ this.refreshTableCol(this.params.yearAndMonth);
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ this.option.column = deepClone(this.defaultColumns);
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ loadData() {},
|
|
|
+ spanMethod({ row, column, rowIndex, columnIndex }) {
|
|
|
+ let fields = ["xm", "number", "idCard", "personnelType"];
|
|
|
+ let cellValue = row[column.property];
|
|
|
+ if (cellValue && fields.includes(column.property)) {
|
|
|
+ let prevRow = this.data[rowIndex - 1];
|
|
|
+ let nextRow = this.data[rowIndex + 1];
|
|
|
+ if (prevRow && prevRow[column.property] === cellValue) {
|
|
|
+ return { rowspan: 0, colspan: 0 };
|
|
|
+ } else {
|
|
|
+ let countRowspan = 1;
|
|
|
+ while (nextRow && nextRow[column.property] === cellValue) {
|
|
|
+ nextRow = this.data[++countRowspan + rowIndex];
|
|
|
+ }
|
|
|
+ if (countRowspan > 1) {
|
|
|
+ row.hbFlag = true;
|
|
|
+ return { rowspan: countRowspan, colspan: 1 };
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ refreshTableCol(yearAndMonth) {
|
|
|
+ let yearMonth = moment(yearAndMonth).format("YYYY-MM").split("-");
|
|
|
+ const monthDays = getMonthDatesWithMarkers(Number(yearMonth[0]), Number(yearMonth[1]));
|
|
|
+
|
|
|
+ let newColumns = deepClone(this.defaultColumns);
|
|
|
+
|
|
|
+ monthDays.forEach((item) => {
|
|
|
+ let col = {
|
|
|
+ prop: moment(item.dateString).format('yyyyMMDD'),
|
|
|
+ label: item.dayName + "" + item.day.toString(),
|
|
|
+ type: 'number',
|
|
|
+ precision: 1,
|
|
|
+ min: 0,
|
|
|
+ width: 45,
|
|
|
+ align: 'center',
|
|
|
+ isWorkDay: ChineseHoliday.isWorkday(item.dateString),
|
|
|
+ showOverflowTooltip: true,
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!ChineseHoliday.isWorkday(item.dateString)) {
|
|
|
+ col.labelClassName = 'red';
|
|
|
+ col.labelClassName = 'red';
|
|
|
+ }
|
|
|
+ newColumns.push(col);
|
|
|
+ });
|
|
|
+ newColumns.push({
|
|
|
+ prop: "hj",
|
|
|
+ label: "合计",
|
|
|
+ width: 60,
|
|
|
+ align: 'center',
|
|
|
+ showOverflowTooltip: true,
|
|
|
+ display: false,
|
|
|
+ }, {
|
|
|
+ prop: "gsfpl",
|
|
|
+ label: "工时分配率",
|
|
|
+ width: 60,
|
|
|
+ align: 'center',
|
|
|
+ showOverflowTooltip: true,
|
|
|
+ display: false,
|
|
|
+ });
|
|
|
+
|
|
|
+ this.option.column = newColumns;
|
|
|
+ },
|
|
|
+ handleExport() {
|
|
|
+ exportBlob(`/api/kd-scientific/attendance/export?${this.website.tokenHeader}=${getToken()}`, this.params).then(res => {
|
|
|
+ downloadXls(res.data, `${this.params.yearAndMonth}研发工时分配表.xlsx`);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 打印表格
|
|
|
+ * @param isLandscape 是否横向打印
|
|
|
+ */
|
|
|
+ printTable(isLandscape) {
|
|
|
+ this.wideTableColumns = this.$refs.crud.columnOption;
|
|
|
+ this.printTitle = `${this.params.yearAndMonth}研发工时分配表.xlsx`;
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.printWideTable.printTable(isLandscape);
|
|
|
+ })
|
|
|
+ },
|
|
|
+ headerCellStyle ({ column }) {
|
|
|
+ let color = column.labelClassName ? 'red' : 'rgba(0,0,0,.85)';
|
|
|
+ return {
|
|
|
+ color
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+}, {
|
|
|
+ // 模块路径
|
|
|
+ name: 'yfCostManage/yfCostStatistics/yfWorkHoursAllocationList',
|
|
|
+ res: ({ data }) => {
|
|
|
+ let newList = [];
|
|
|
+ data.records.forEach((item) => {
|
|
|
+ let objData = {
|
|
|
+ ...item,
|
|
|
+ id: item.unicode,
|
|
|
+ monthlyHours: (item.monthlyHours || 0).toFixed(1),
|
|
|
+ monthlyDays: (item.monthlyDays || 0).toFixed(1)
|
|
|
+ };
|
|
|
+ item.dailyAttendances.forEach(hourItem => {
|
|
|
+ objData[hourItem.workDate] = (hourItem.workHours || 0).toFixed(1);
|
|
|
+ });
|
|
|
+ newList.push(objData);
|
|
|
+ });
|
|
|
+ data.records = newList;
|
|
|
+ return data;
|
|
|
+ },
|
|
|
+});
|
|
|
+</script>
|