vue 使用表格 和moment 画出日历 要能填写备注 顶部是星期几

<template>
  <div class="attendance-statistics">
    <div class="calendar-container">
      <div class="calendar-header">
        <a-button type="primary" @click="handleAdd()">新增</a-button>
        <div class="calendar-nav">
          <button @click="prevMonth">〈</button>
          <span>{{ currentDate.format('YYYY-MM') }}</span>
          <button @click="nextMonth">〉</button>
        </div>
      </div>

      <div class="calendar-table">
        <!-- 星期标题行 -->
        <div class="week-header" style="height: 40px">
          <div v-for="(day, index) in weekDays" :key="index" class="week-day">
            {{ day }}
          </div>
        </div>

        <!-- 日期网格 -->
        <div class="date-grid">
          <div v-for="(date, index) in datesInMonth" :key="index" class="date-cell" :class="{
            'today': isToday(date),
            'other-month': !isSameMonth(date)
          }">
            <!-- 日期显示 -->
            <div class="date-display">
              <div>{{ date.date() }}</div>
              <div style="color: #878C9A;">{{ chineseDays[parseInt(moment(date).lunar().format('DD'), 10) - 1] }}</div>
            </div>

            <!-- 班次信息 -->
            <div class="shift-info">
              <div v-for="(shift, shiftIndex) in getShiftsForDate(date)" :key="shiftIndex" class="shift-item"
                :class="getShiftClass(shift.type)">
                <div class="shift-time">{{ shift.startTime }}</div>
                <div class="shift-name">{{ shift.name }}</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import moment from 'moment'
import 'moment-lunar';

export default {
  name: 'shiftConfiguration',
  components: { },
  data() {
    return {
      url: {
        list: '/clockSchedule/scheduleList',
        // exportXlsUrl: '/clock/exportList',
      },

      currentDate: moment(),
      weekDays: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
      chineseDays: ['初一', '初二', '初三', '初四', '初五', '初六',
        '初七', '初八', '初九', '初十', '十一', '十二',
        '十三', '十四', '十五', '十六', '十七', '十八',
        '十九', '二十', '廿一', '廿二', '廿三', '廿四',
        '廿五', '廿六', '廿七', '廿八', '廿九', '三十'],
      shifts: [
        { date: '2025-6-5', time: '早班08:00-14:59', name: '章三,里斯', type: 'normal' },
        { date: '2025-6-1', time: '中班08:00-14:59', name: '章三', type: 'normal' },
        { date: '2024-11-30', time: '晚班08:00-14:59', name: '章三', type: 'normal' },
      ],
    }
  },
  mounted() {
   // this.getList()
  },
  computed: {
    datesInMonth() {
      const startOfMonth = this.currentDate.clone().startOf('month');
      const endOfMonth = this.currentDate.clone().endOf('month');

      const dates = [];
      let current = startOfMonth.clone();

      // 添加前一个月的几天(为了显示完整的星期)
      while (current.day() !== 0) {
        current.subtract(1, 'day');
      }

      // 添加整个月份的日期
      while (current <= endOfMonth) {
        dates.push(current.clone());
        current.add(1, 'day');
      }

      return dates;
    }
  },
  methods: {
    moment,
    prevMonth() {
      this.currentDate = this.currentDate.clone().subtract(1, 'month');
    },
    nextMonth() {
      this.currentDate = this.currentDate.clone().add(1, 'month');
    },
    isToday(date) {
      return date.isSame(moment(), 'day');
    },
    isSameMonth(date) {
      return date.isSame(this.currentDate, 'month');
    },
    getShiftsForDate(date) {
      return this.shifts.filter(shift =>
        moment(shift.scheduleDate).isSame(date, 'day')
      );
    },
    getShiftClass(type) {
      const classes = {
        正常: 'shift-normal',
        异常: 'shift-abnormal',
        缺卡: 'shift-missing',
        未来: 'shift-future'
      };
      return classes[type] || '';
    },

    // 获取班次列表
    getList() {
      getAction(this.url.list).then((res) => {
        if (res.success) {
          this.shifts = res.data
        } else {
          this.$message.error(res.message)
        }
      })
    },

    openClassConfigModal() {
      this.$refs.classConfigModal.add()
      this.$refs.classConfigModal.title = '班别配置'
      this.$refs.classConfigModal.disableSubmit = false
    },
    openCheckMethodModal(record) {
      this.$refs.checkMethodModal.add()
      this.$refs.checkMethodModal.title = '打卡方式'
      this.$refs.checkMethodModal.disableSubmit = false
    },
  },
}
</script>
<style lang="less" scoped>
.attendance-statistics {
  height: calc(100% - 60px - 116px);
  background: #ffffff;
  box-shadow: 0px 3px 6px 1px rgba(51, 97, 250, 0.1);
  border-radius: 8px;
  padding: 14px;
  flex: 1;
  overflow: hidden;
  overflow-y: auto;

  .calendar-container {
    .calendar-header {
      margin-bottom: 16px;
      display: flex;

      .calendar-nav {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 10px;
      }

      .calendar-nav button {
        background: none;
        border: none;
        font-size: 16px;
        cursor: pointer;
      }
    }

    .calendar-table {
      border: 1px solid #EFF0F2;
      border-radius: 4px;
      overflow: hidden;

      .week-header {
        display: grid;
        grid-template-columns: repeat(7, 1fr);
        background: #F2F5FF;
        border-bottom: 1px solid #EFF0F2;
        font-weight: 500;
        font-size: 14px;
        color: #212633;
        font-family: @fontMedium;

        .week-day {
          padding: 10px;
          text-align: center;
          font-weight: bold;
          border-right: 1px solid #EFF0F2;
        }

        .week-day:last-child {
          border-right: none;
        }
      }
    }
  }

  .date-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);

    .date-cell {
      padding: 8px 12px;
      border-right: 1px solid #EFF0F2;
      border-bottom: 1px solid #EFF0F2;
      min-height: 132px;
    }

    .date-cell.other-month {
      background-color: #fafafa;
      color: #ccc;
    }

    .date-cell.today .date-display {
      color: #1890ff;
      font-weight: bold;
    }

    .date-display {
      margin-bottom: 6px;
      display: flex;
      align-items: center;
      justify-content: space-between;

      font-weight: 500;
      font-size: 14px;
      color: #212633;
    }
  }




  .shift-info {
    margin-bottom: 8px;
  }

  .shift-item {
    padding: 4px;
    margin-bottom: 4px;
    border-radius: 4px;
    font-size: 12px;
  }

  .shift-normal {
    background-color: #c0d2fd;
  }

  .shift-abnormal {
    background-color: #fae7b3;
  }

  .shift-missing {
    background-color: #f8bebe;
  }

  .shift-future {
    background-color: #e4e5e9;
  }

  .shift-time {
    font-size: 11px;
    color: #666;
  }

  .shift-name {
    font-weight: bold;
  }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值