WXL
2025-12-30 ed62678cd16042506bad5e5f75665a822f2d5717
src/views/OfficeRelated/checkingIn/checkingInInfo.vue
@@ -4,12 +4,18 @@
    <el-card class="employee-info-card">
      <div class="employee-header">
        <div class="employee-basic">
          <el-avatar :size="60" :src="employeeInfo.avatar" class="employee-avatar">
          <el-avatar
            :size="60"
            :src="employeeInfo.avatar"
            class="employee-avatar"
          >
            {{ employeeInfo.name.charAt(0) }}
          </el-avatar>
          <div class="employee-details">
            <h3>{{ employeeInfo.name }}</h3>
            <p class="employee-department">{{ employeeInfo.department }} · {{ employeeInfo.position }}</p>
            <p class="employee-department">
              {{ employeeInfo.department }} · {{ employeeInfo.position }}
            </p>
            <p class="employee-contact">
              <span>工号: {{ employeeInfo.employeeId }}</span>
              <span>电话: {{ employeeInfo.phone }}</span>
@@ -36,13 +42,6 @@
    <!-- 选项卡 -->
    <el-card>
      <el-tabs v-model="activeTab">
        <el-tab-pane label="日历视图" name="calendar">
          <attendance-calendar
            :attendance-data="attendanceData"
            :business-trip-data="businessTripData"
          />
        </el-tab-pane>
        <el-tab-pane label="出勤记录" name="attendanceList">
          <personal-attendance-table
            :data="attendanceData"
@@ -56,7 +55,12 @@
            :loading="loading"
          />
        </el-tab-pane>
        <el-tab-pane label="日历视图" name="calendar">
          <attendance-calendar
            :attendance-data="attendanceData"
            :business-trip-data="businessTripData"
          />
        </el-tab-pane>
        <el-tab-pane label="统计报表" name="report">
          <personal-attendance-report
            :stats="employeeStats"
@@ -69,15 +73,13 @@
</template>
<script>
  import { generateMockData } from './mockData'
import AttendanceCalendar from './components/AttendanceCalendar.vue'
import PersonalAttendanceTable from './components/PersonalAttendanceTable.vue'
import PersonBusiness from './components/PersonBusiness.vue'
import PersonalAttendanceReport from './components/PersonalAttendanceReport.vue'
import AttendanceCalendar from "./components/AttendanceCalendar.vue";
import PersonalAttendanceTable from "./components/PersonalAttendanceTable.vue";
import PersonBusiness from "./components/PersonBusiness.vue";
import PersonalAttendanceReport from "./components/PersonalAttendanceReport.vue";
export default {
  name: 'AttendanceDetail',
  name: "AttendanceDetail",
  components: {
    AttendanceCalendar,
    PersonalAttendanceTable,
@@ -86,15 +88,15 @@
  },
  data() {
    return {
       activeTab: 'calendar',
      activeTab: "calendar",
      loading: false,
      employeeInfo: {
        name: '张三',
        department: 'OPO项目部',
        position: '项目经理',
        employeeId: 'OPO001',
        phone: '138-1234-5678',
        avatar: ''
        name: "",
        department: "",
        position: "",
        employeeId: "",
        phone: "",
        avatar: ""
      },
      employeeStats: {
        attendanceRate: 0,
@@ -105,137 +107,120 @@
      },
      attendanceData: [],
      businessTripData: []
    }
    };
  },
  created() {
        this.loadMockData()
    this.getEmployeeInfo()
    this.loadAttendanceData()
    this.getEmployeeInfo();
    this.loadAttendanceData();
  },
  methods: {
    getEmployeeInfo() {
      const { employeeId, employeeName } = this.$route.query
      const { employeeId, employeeName } = this.$route.query;
      // 模拟员工信息
      this.employeeInfo = {
        name: employeeName || '张三',
        department: 'OPO项目部',
        position: '项目经理',
        employeeId: employeeId || 'OPO001',
        phone: '138****1234',
        avatar: ''
      }
    },
 loadMockData() {
      this.loading = true
      // 模拟异步加载
      setTimeout(() => {
        const mockData = generateMockData()
        this.attendanceData = mockData.attendanceData
        this.businessTripData = mockData.businessTripData
        this.calculateStats()
        this.loading = false
      }, 500)
        name: employeeName || "张三",
        department: "OPO项目部",
        position: "项目经理",
        employeeId: employeeId || "OPO001",
        phone: "138****1234",
        avatar: ""
      };
    },
    calculateStats() {
      const totalDays = 31 // 12月有31天
      const attendanceDays = this.attendanceData.filter(item =>
        item.status === 'present' || item.status === 'late'
      ).length
      const lateTimes = this.attendanceData.filter(item =>
        item.status === 'late'
      ).length
      // 计算出差总天数
      const businessTripDays = this.businessTripData.reduce((total, trip) => {
        const start = new Date(trip.startDate)
        const end = new Date(trip.endDate)
        const days = Math.ceil((end - start) / (1000 * 60 * 60 * 24)) + 1
        return total + days
      }, 0)
      // 计算总工作时长
      const totalWorkHours = this.attendanceData.reduce((total, item) => {
        return total + (item.workHours || 0)
      }, 0)
      this.employeeStats = {
        attendanceRate: Math.round((attendanceDays / totalDays) * 100),
        workHours: totalWorkHours.toFixed(1),
        businessTripDays: businessTripDays,
        lateTimes: lateTimes,
        leaveEarlyTimes: this.attendanceData.filter(item =>
          item.status === 'leaveEarly'
        ).length
      }
    },
    async loadAttendanceData() {
      this.loading = true
      this.loading = true;
      try {
        await new Promise(resolve => setTimeout(resolve, 500))
        await new Promise(resolve => setTimeout(resolve, 500));
        // 生成个人考勤模拟数据
        this.attendanceData = this.generatePersonalAttendanceData()
        this.businessTripData = this.generatePersonalBusinessTripData()
        this.calculateStats()
        this.attendanceData = this.generatePersonalAttendanceData();
        this.businessTripData = this.generatePersonalBusinessTripData();
        this.calculateStats();
      } catch (error) {
        console.error('加载数据失败:', error)
        console.error("加载数据失败:", error);
      } finally {
        this.loading = false
        this.loading = false;
      }
    },
    generatePersonalAttendanceData() {
      const data = []
      const currentMonth = 12 // 12月
      const data = [];
      const currentMonth = 12; // 12月
      for (let day = 1; day <= 31; day++) {
        if (Math.random() > 0.2) { // 80%的出勤率
        if (Math.random() > 0.2) {
          // 80%的出勤率
          data.push({
            id: day,
            date: `2024-${currentMonth.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`,
            checkIn: `08:${String(Math.floor(Math.random() * 30)).padStart(2, '0')}`,
            checkOut: `18:${String(Math.floor(Math.random() * 30)).padStart(2, '0')}`,
            status: Math.random() > 0.1 ? '正常' : '迟到',
            date: `2024-${currentMonth
              .toString()
              .padStart(2, "0")}-${day.toString().padStart(2, "0")}`,
            checkIn: `08:${String(Math.floor(Math.random() * 30)).padStart(
              2,
              "0"
            )}`,
            checkOut: `18:${String(Math.floor(Math.random() * 30)).padStart(
              2,
              "0"
            )}`,
            status: Math.random() > 0.1 ? "正常" : "迟到",
            workHours: (8 + Math.random() * 2).toFixed(1)
          })
          });
        }
      }
      return data
      return data;
    },
    generatePersonalBusinessTripData() {
      return [
        {
          id: 1,
          tripNumber: 'BT202412001',
          startCity: '北京',
          endCity: '上海',
          startDate: '2024-12-05',
          endDate: '2024-12-08',
          tripNumber: "BT202412001",
          startCity: "北京",
          endCity: "上海",
          startDate: "2024-12-05",
          endDate: "2024-12-08",
          distance: 1200,
          purpose: '客户会议',
          status: '已完成'
          purpose: "客户会议",
          status: "已完成"
        },
        {
          id: 2,
          tripNumber: 'BT202412002',
          startCity: '北京',
          endCity: '广州',
          startDate: '2024-12-15',
          endDate: '2024-12-18',
          tripNumber: "BT202412002",
          startCity: "北京",
          endCity: "广州",
          startDate: "2024-12-15",
          endDate: "2024-12-18",
          distance: 1900,
          purpose: '项目调研',
          status: '已完成'
          purpose: "项目调研",
          status: "已完成"
        }
      ]
      ];
    },
    calculateStats() {
      const totalDays = 31;
      const attendanceDays = this.attendanceData.length;
      this.employeeStats = {
        attendanceRate: Math.round((attendanceDays / totalDays) * 100),
        workHours: this.attendanceData
          .reduce((sum, item) => sum + parseFloat(item.workHours), 0)
          .toFixed(1),
        businessTripDays: this.businessTripData.reduce((sum, item) => {
          const start = new Date(item.startDate);
          const end = new Date(item.endDate);
          return sum + Math.ceil((end - start) / (1000 * 60 * 60 * 24)) + 1;
        }, 0),
        lateTimes: this.attendanceData.filter(item => item.status === "迟到")
          .length,
        leaveEarlyTimes: this.attendanceData.filter(
          item => item.status === "早退"
        ).length
      };
    }
  }
}
};
</script>
<style scoped>