zouyu
2026-05-07 b0d4df5f39525ae7fe252e8ee65d85fd71dca721
src/views/performance/attendance/index.vue
@@ -30,12 +30,12 @@
        </div>
      </div>
      <div class="search_thing">
        <el-button size="mini" type="primary" @click="refreshTable()"
          >查 询</el-button
        <el-button icon="el-icon-search" size="mini" type="primary" @click="refreshTable()">查 询</el-button
        >
        <el-button size="mini" @click="resetQuery">重置</el-button>
        <el-button size="mini" type="primary" @click="openAddAttendanceDialog()">手动新增</el-button>
        <el-button size="mini" type="success" @click="openSyncAttendanceDialog()">同步考勤记录</el-button>
        <el-button icon="el-icon-refresh-left" size="mini" @click="resetQuery">重置</el-button>
        <el-button icon="el-icon-plus" size="mini" type="primary" @click="openAddAttendanceDialog()">手动新增</el-button>
        <el-button icon="el-icon-refresh" size="mini" type="success" @click="openSyncAttendanceDialog()">同步考勤记录</el-button>
        <el-button plain icon="el-icon-download" size="mini" type="primary" @click="openAttendanceRecordDialog()">导出</el-button>
      </div>
    </div>
    <div class="container">
@@ -211,21 +211,62 @@
    <el-button type="primary" @click="confirmSyncAttendance">确 定</el-button>
  </span>
    </el-dialog>
    <el-dialog
      title="导出考勤记录"
      :visible.sync="attendanceRecordVisible"
      width="40%">
      <el-row>
        <el-col :span="4">
          <label>统计维度:</label>
        </el-col>
        <el-col :span="20">
            <el-radio-group v-model="reportType" size="mini" disabled>
              <el-radio label="YEAR">年度</el-radio>
              <el-radio label="MONTH">月度</el-radio>
            </el-radio-group>
        </el-col>
      </el-row>
      <el-row style="margin-top:20px">
        <el-col :span="4">
          <label>统计日期:</label>
        </el-col>
        <el-col :span="20">
          <el-date-picker
            size="small"
            v-model="reportDateRange"
            style="width:100%"
            @change="changeReportDateRange"
            type="datetimerange"
            value-format="yyyy-MM-dd HH:mm:ss"
            :default-time="['00:00:00','23:59:59']"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期">
          </el-date-picker>
        </el-col>
      </el-row>
      <span slot="footer" class="dialog-footer">
        <el-button @click="attendanceRecordVisible = false">取 消</el-button>
        <el-button :loading="exportLoading" type="primary" @click="exportStaffAttendanceRecords()">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import StaffClockInRecord from "./components/staffClockInRecord.vue";
import {selectAllUser} from '@/api/system/user'
import {selectUserListByPerformance} from '@/api/system/user'
import {
  pageAttendanceRecord,
  checkDutyDate,
  saveOrUpdateStaffAttendanceTrackingRecord,
  removeStaffAttendanceTrackingRecord,
  syncAttendanceRecord
  syncAttendanceRecord,
  exportStaffAttendanceRecords
} from '@/api/performance/attendance'
import {getDicts} from "@/api/system/dict/data";
import dayjs from 'dayjs';
import {getTimeRange,isOverOneMonth} from "@/utils/date";
import {transformExcel} from '@/utils/file'
export default {
  name: "Attendance",
  components: {
@@ -233,8 +274,12 @@
  },
  data() {
    return {
      reportDateRange:[],
      reportType:"MONTH",
      attendanceRecordVisible:false,
      syncDateRange:[],
      syncAttendanceVisible: false,
      exportLoading: false,
      attendanceForm:{
        workDataId: null,
        offWorkDataId: null,
@@ -299,7 +344,7 @@
    this.selectEnumByCategory()
    this.getUserList()
    this.getTableHeight();
    this.dateRange = this.getTimeRange()
    this.dateRange = getTimeRange()
    this.resizeHandler = this.debounce(() => {
      this.getTableHeight();
    }, 200);
@@ -313,6 +358,41 @@
    window.removeEventListener("resize",this.resizeHandler)
  },
  methods: {
    changeReportDateRange(val){
      //判断时间区间是否超过一个月
      if(val && val.length===2){
        const flag = isOverOneMonth(val[0],val[1]);
        this.reportType = flag?'YEAR':'MONTH'
      }
    },
    openAttendanceRecordDialog (){
      this.reportDateRange = getTimeRange()
      this.$nextTick(()=>{
        this.attendanceRecordVisible = true
      })
    },
    //导出考勤记录
    exportStaffAttendanceRecords(){
      this.exportLoading = true
      let params = {
        attendanceReportType:this.reportType,
      }
      if (this.reportDateRange && this.reportDateRange.length === 2) {
        params.startDate = this.reportDateRange[0];
        params.endDate = this.reportDateRange[1];
      } else {
        params.startDate = "";
        params.endDate = "";
      }
      exportStaffAttendanceRecords({...params}).then(res=>{
        transformExcel(res, "中天耐丝质量考勤汇总.xlsx")
        this.$message.success("导出成功")
      }).catch(error=>{
        console.error(error)
      }).finally(()=>{
        this.exportLoading = false
      })
    },
    getShiftByDic(e) {
      let obj = this.dailyTypeList.find((m) => m.dictValue == e);
      if (obj) {
@@ -332,35 +412,7 @@
        this.dailyTypeList = response.data;
      });
    },
    /**
     * 初始化默认日期范围:近一个月(当前日期 - 30天 至 当前日期)
     */
    getTimeRange(format = 'YYYY-MM-DD HH:mm:ss') {
      // 获取当前时间
      const now = dayjs();
      // 获取当前日期的「日」(1-31)
      const currentDate = now.date();
      let startTime, endTime;
      // 核心逻辑:判断当前日期是否大于25号
      if (currentDate > 25) {
        // ✅ 情况1:当前日>25 → 当月26号 ~ 次月25号
        startTime = now.startOf('month').add(25, 'day'); // 当月1号 +25天 = 26号
        endTime = startTime.add(1, 'month').date(25).hour(23)
          .minute(59)
          .second(59);     // 次月25号(dayjs自动处理跨年)
      } else {
        // ✅ 情况2:当前日≤25 → 上月26号 ~ 当月25号
        startTime = now.subtract(1, 'month').startOf('month').add(25, 'day'); // 上月26号
        endTime = now.date(25).hour(23)
          .minute(59)
          .second(59); // 当月25号
      }
      // 返回格式化后的时间数组
      return [startTime.format(format), endTime.format(format)];
    },
    //同步考勤记录
    confirmSyncAttendance(){
      if(!this.syncDateRange || this.syncDateRange.length<2){
@@ -384,7 +436,10 @@
    },
    //打开同步考勤记录弹框
    openSyncAttendanceDialog(){
      this.syncAttendanceVisible = true
      this.syncDateRange = getTimeRange()
      this.$nextTick(()=>{
        this.syncAttendanceVisible = true
      })
    },
    //删除考勤记录
    confirmRemoveRecord(row){
@@ -567,7 +622,7 @@
    },
    //查询用户列表
    getUserList(){
      selectAllUser().then(res=>{
      selectUserListByPerformance().then(res=>{
        this.userList = res.data
      }).catch(error=>{
        console.error(error)
@@ -575,7 +630,7 @@
    },
    //重置按钮
    resetQuery() {
      this.dateRange = this.getTimeRange();
      this.dateRange = getTimeRange();
      this.queryParams = {
        startDate: "",
        endDate: "",