vue 单页面

2022-11-04  本文已影响0人  wxw_威
因为自己要写一个单页面去完成一个考勤报表计算的需求,所以通过一个html去完成此需求,再次记录遇到的问题(忽略乱七八糟的命名)。

1、下载对应的插件到本地,import引用。
2、前端通过xlsx 导入表格,获取对应的json,计算考勤数据。
3、导出功能以后在完善。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="renderer" content="webkit" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <title>考勤计算</title>
    <!-- https://unpkg.com/element-ui/lib/theme-chalk/index.css -->
    <link rel="stylesheet" href="css/index.css">
    <!-- https://cdn.jsdelivr.net/npm/vue@2.7.10 -->
    <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
    <!-- https://unpkg.com/element-ui/lib/index.js -->
    <script src="js/elementUI.js" type="text/javascript" charset="utf-8"></script>
    <!-- https://unpkg.com/dayjs@1.8.21/dayjs.min.js -->
    <script src="js/dayjs.js" type="text/javascript" charset="utf-8"></script>
    <!-- https://cdn.jsdelivr.net/npm/xlsx@0.16.9/dist/xlsx.full.min.js -->
    <script src="js/xlsx.js" type="text/javascript" charset="utf-8"></script>
    <style>
      #app {
        font-family: Avenir, Helvetica, Arial, sans-serif;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        text-align: center;
        color: #2c3e50;
        display: flex;
      }
      body {
        margin: 0;
      }
      .log {
        display: flex;
        justify-content: center;
        border: 1px solid #F2F2F2;
      }
      p {
        width: 100px;
        margin: 0;
        padding: 8px 4px;
        border-right: 1px solid #F2F2F2;
      }
    </style>
  </head>
  <body>
    <div id="app" style="display: flex;">
      <div style="display: flex;flex-direction: column;">
        <h3>考勤表</h3>
        <el-upload
          class="upload-demo"
          drag
          action
          :auto-upload="false"
          :on-change="uploadImport"
          :limit="1">
          <i class="el-icon-upload"></I>
          <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
          <div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
        </el-upload>
  
        <h3>打卡表</h3>
        <el-upload
          class="upload-demo"
          drag
          action
          :auto-upload="false"
          :on-change="uploadImport2"
          :limit="1">
          <i class="el-icon-upload"></I>
          <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
          <div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
        </el-upload>
  
        <el-button style="margin-top: 32px;" @click="handleCalculate">计算</el-button>
      </div>
      <div style="flex: 1;padding-left: 32px;">
        <h1>log日志</h1>
        <div class="log">
          <p>考勤</p>
          <p style="width: 160px;">职位</p>
          <p>工号</p>
          <p>姓名</p>
          <p style="width: 150px;">时间</p>
          <p style="flex: 1;">备注</p>
        </div>
        <div style="height:calc(100vh - 150px);overflow-y: auto;">
          <div class="log" v-for="(item, index) in resultList">
            <p>{{item.kq}}</p>
            <p style="width: 160px;">职位:{{item.job}}</p>
            <p>{{item.number}}</p>
            <p>{{item.name}}</p>
            <p style="width: 150px;">{{item.time}}</p>
            <p style="flex: 1;">{{item.remark}}</p>
          </div>
        </div>
      </div>
    </div>
    <script type="text/javascript">
      var app = new Vue({
        el: '#app',
        data: {
          kqList: [],
          dkList: [],

          resultList: [],
          defaultTimeString: '',
        },
        methods: {
          handleCalculate() {
            const year = dayjs(this.defaultTimeString).year()
            const month = dayjs(this.defaultTimeString).month() + 1
            const yearMonth = year + '-' + month
            const days = dayjs(yearMonth).daysInMonth()
            this.kqList.forEach((kqItem, kqIndex) => {
              for(let i = 1; i <= days; i++) {
                let day = (i + '').padStart(2, 0)
                let kqTime = yearMonth + '-' + day
                if (['调岗','休', '轮休', '年假', '婚假', '丧假', '育儿假', '病假', '工伤', '产假', '陪产假', '事假', '新员工', '离职', '旷工'].indexOf(kqItem[kqTime]) > -1) {
                  this.printLog(kqItem[kqTime], kqItem['岗位'], kqItem['工号'], kqItem['姓名'], kqTime)
                } else if (kqItem[kqTime] === '早' || kqItem[kqTime] === '双早') {
                  // 默认8h
                  this.calculateTimeLengthWithZao(kqItem, kqTime, 8)
                } else if (kqItem[kqTime].indexOf('早') > -1) {
                  // 包含早
                  let arr = kqItem[kqTime].split('早')
                  this.calculateTimeLengthWithZao(kqItem, kqTime, arr[1])
                } else if (kqItem[kqTime] === '夜' || kqItem[kqTime] === '双夜') {
                  // 默认8h
                  this.calculateTimeLengthWithYe(kqItem, kqTime, 8)
                } else if (kqItem[kqTime].indexOf('夜') > -1) {
                  // 包含夜
                  let arr = kqItem[kqTime].split('夜')
                  this.calculateTimeLengthWithYe(kqItem, kqTime, arr[1])
                }
              }
            })
          },
          // 计算时长  --   夜班
          calculateTimeLengthWithYe(kqItem, kqTime, timeLength) {
            let kqString = kqItem[kqTime]           // 考勤
            let job = kqItem['岗位']
            let userNumber = kqItem['工号']         // 工号
            let userName = kqItem['姓名']           // 姓名
            let remark = ''                         // 备注

            // 上班对象
            let startItem = null
            // 下班对象
            let endItem = null
            // 获取上班打卡记录
            let startSiftArr = []
            startSiftArr = this.dkList.filter((dkItem) => {
              return kqTime == dkItem['打卡日期2'] && kqItem['姓名'] == dkItem['姓名'] && dkItem['员工编码'] == kqItem['工号']
            })

            // 判断是否漏打上班卡
            if (startSiftArr && startSiftArr.length > 0) {
              startSiftArr = this.sortData(startSiftArr)
              let sbTimeArr = startSiftArr.filter((item) => {
                return this.compareDate(item['打卡日期2'] + ' ' + item['打卡时间'], item['打卡日期2'] + ' 12:00:00')
              })
              // startItem = sbTimeArr
              if (sbTimeArr && sbTimeArr.length > 0) {
                startItem = sbTimeArr[0]
              } else {
                return this.printLog(kqString, job, userNumber, userName, kqTime, '漏打上班卡')
                // remark = '漏打上班卡'
              }
            } else {
              return this.printLog(kqString, job, userNumber, userName, kqTime, '漏打上班卡')
              // remark = '漏打上班卡'
            }

            // 获取下班打卡记录
            let endDKDate = dayjs(kqTime).add(1, 'day')
            let endTime = dayjs(endDKDate).format("YYYY-MM-DD")
            let endSiftArr = []
            endSiftArr = this.dkList.filter((dkItem) => {
              return endTime == dkItem['打卡日期2'] && kqItem['姓名'] == dkItem['姓名'] && dkItem['员工编码'] == kqItem['工号']
            })

            // 判断是否漏打下班卡
            if (endSiftArr && endSiftArr.length > 0) {
              endSiftArr = this.sortData(endSiftArr)
              let xbTimeArr = endSiftArr.filter((item) => {
                return this.compareDate(item['打卡日期2'] + ' 12:00:00', item['打卡日期2'] + ' ' + item['打卡时间'])
              })

              if (xbTimeArr && xbTimeArr.length > 0) {
                endItem = xbTimeArr[xbTimeArr.length - 1]
              } else {
                return this.printLog(kqString, job, userNumber, userName, kqTime, '漏打下班卡')
                // remark = remark ? remark + '漏打下班卡' :  '漏打下班卡'
              }
            } else {
              return this.printLog(kqString, job, userNumber, userName, kqTime, '漏打下班卡')
              // remark = remark ? remark + '漏打下班卡' :  '漏打下班卡'
            }
            
            let sjStartTime = startItem['打卡日期2'] + ' ' + startItem['打卡时间']
            let sjEndTime = endItem['打卡日期2'] + ' ' + endItem['打卡时间']

            let gdStartTime = startItem['打卡日期2']
            let gdEndTime = endItem['打卡日期2']

            if (startItem['打卡位置'].indexOf('XX') > -1) {
              gdStartTime = gdStartTime + ' ' + '20:00:00'
            } else {
              gdStartTime = gdStartTime + ' ' + '20:00:00'
            }

            if (endItem['打卡位置'].indexOf('XX') > -1) {
              gdEndTime = gdEndTime + ' ' + '8:00:00'
            } else {
              gdEndTime = gdEndTime + ' ' + '8:00:00'
            }

            if (this.compareDate(sjStartTime, gdStartTime)) {
              // 打卡时间 > 规定时间
              remark = '上班迟到'
            }

            if (this.compareDate(gdEndTime, sjEndTime)) {
              // 下班打卡时间 > 下班规定时间
              remark = remark ? `${remark},下班早退` : '下班早退'
            }

            // 计算工时
            let t1 = new Date(sjStartTime).getTime()
            let t2 = new Date(sjEndTime).getTime()
            let resultV = (t2 - t1 - 1000 * 60 * 60 * 0.5) / (1000 * 60 * 60)
            if (resultV >= parseFloat(timeLength)) {
              remark = remark ? `${remark},满足${timeLength}h` : `满足${timeLength}h`
            } else {
              // 计算缺少的分钟数
              let qsfz = (t2 - t1 - 1000 * 60 * 60 * 0.5 - (1000 * 60 * 60 * timeLength)) / (1000 * 60)
              remark = remark ? `${remark},不满足${timeLength}h(缺少:${(Math.abs(qsfz)).toFixed(2)}分钟)` : `不满足${timeLength}h(缺少:${(Math.abs(qsfz)).toFixed(2)}分钟)`
            }

            this.printLog(kqString, job, userNumber, userName, kqTime, remark)
          },
          // 计算时长  --   早班
          calculateTimeLengthWithZao(kqItem, kqTime, timeLength) {
            let kqString = kqItem[kqTime]           // 考勤
            let job = kqItem['岗位']
            let userNumber = kqItem['工号']         // 工号
            let userName = kqItem['姓名']           // 姓名
            let remark = ''             // 备注

            let siftArr = []
            siftArr = this.dkList.filter((dkItem) => {
              return kqTime == dkItem['打卡日期2'] && kqItem['姓名'] == dkItem['姓名'] && dkItem['员工编码'] == kqItem['工号']
            })
            if (siftArr && siftArr.length > 1) {
              // 排序
              siftArr = this.sortData(siftArr)
              
              // 上班对象
              let startItem = siftArr[0]
              // 下班对象
              let endItem = siftArr[siftArr.length - 1]

              let sjStartTime = startItem['打卡日期2'] + ' ' + startItem['打卡时间']
              let sjEndTime = endItem['打卡日期2'] + ' ' + endItem['打卡时间']

              let gdStartTime = startItem['打卡日期2']
              let gdEndTime = endItem['打卡日期2']
              if (startItem['打卡位置'].indexOf('XX') > -1) {
                gdStartTime = gdStartTime + ' ' + '08:30:00'
              } else {
                gdStartTime = gdStartTime + ' ' + '08:00:00'
              }

              if (endItem['打卡位置'].indexOf('XX') > -1) {
                gdEndTime = gdEndTime + ' ' + '17:00:00'
              } else {
                gdEndTime = gdEndTime + ' ' + '16:30:00'
              }

              if (this.compareDate(sjStartTime, gdStartTime)) {
                // 打卡时间 > 规定时间
                remark = '上班迟到'
              }

              if (this.compareDate(gdEndTime, sjEndTime)) {
                // 下班打卡时间 > 下班规定时间
                remark = remark ? `${remark},下班早退` : '下班早退'
              }

              // 计算工时
              let t1 = new Date(sjStartTime).getTime()
              let t2 = new Date(sjEndTime).getTime()
              let resultV = (t2 - t1 - 1000 * 60 * 60 * 0.5) / (1000 * 60 * 60)
              if (resultV >= parseFloat(timeLength)) {
                remark = remark ? `${remark},满足${timeLength}h` : `满足${timeLength}h`
              } else {
                // 计算缺少的分钟数
                let qsfz = (t2 - t1 - 1000 * 60 * 60 * 0.5 - (1000 * 60 * 60 * timeLength)) / (1000 * 60)
                remark = remark ? `${remark},不满足${timeLength}h(缺少:${(Math.abs(qsfz)).toFixed(2)}分钟)` : `不满足${timeLength}h(缺少:${(Math.abs(qsfz)).toFixed(2)}分钟)`
              }

              this.printLog(kqString, job, userNumber, userName, kqTime, remark)
            } else {
              // 早班 - 只有一个时间的
              this.printLog(kqString, job, userNumber, userName, kqTime, '漏打卡')
            }
          },
          // 按照时间排序
          sortData(arr) {
            arr.sort((a, b) => {
              let obj1 = a['打卡日期2'] + ' ' + a['打卡时间']
              let obj2 = b['打卡日期2'] + ' ' + b['打卡时间']
              let v1 = Math.floor(new Date(obj1).getTime() / 1000)
              let v2 = Math.floor(new Date(obj2).getTime() / 1000)
              return v1 - v2
            })
            return arr
          },
          // 比较时间大小
          compareDate(date1, date2) {
            let _date1 = new Date(date1)
            let _date2 = new Date(date2)
            if (_date1.getTime() > _date2.getTime()) {
              return true
            } else {
              return false
            }
          },
          // 打印日志
          printLog(kq, job, number, name, time, remark='无') {
            console.log('考勤',kq,'职位',job, '工号', number, '姓名', name, '时间', time, '备注', remark)
            this.resultList.push({
              kq,
              job,
              number,
              name,
              time,
              remark
            })
          },
          async uploadImport(file) {
            // 读取文件
            let dataBinary = await this.readFile(file.raw);
            let workBook = XLSX.read(dataBinary, { type: "binary", cellDates: true });
            let workSheet = workBook.Sheets[workBook.SheetNames[0]];
            let data = XLSX.utils.sheet_to_json(workSheet);
            console.log(data)
            this.kqList = data
          },
          async uploadImport2(file) {
            // 读取文件
            let dataBinary = await this.readFile(file.raw);
            let workBook = XLSX.read(dataBinary, { type: "binary", cellDates: true });
            let workSheet = workBook.Sheets[workBook.SheetNames[0]];
            let data = XLSX.utils.sheet_to_json(workSheet);
            data.forEach((item, index) => {
              item['打卡日期2'] = dayjs(dayjs(item['打卡日期']).add(1, 'day').$d).format("YYYY-MM-DD")
              if (index == 1) {
                this.defaultTimeString = item['打卡日期2']
              }
            })
            console.log(data)
            this.dkList = data
          },
          readFile(file) {
            return new Promise(resolve => {
              let reader = new FileReader();
              reader.readAsBinaryString(file);
              reader.onload = ev => { 
                resolve(ev.target.result); 
              }
            })
          }
        }
      })
    </script>
  </body>
</html>

遇到的问题:
1、将elementUI 和对应的css 文件下载本地后,页面出现错误

截屏2022-11-04 下午4.37.45.png
处理:elementUI提供icons.woff,element-icons.ttf 下载路径,通过添加下载,把这两个文件放到对应的css 文件夹下就可以了。
上一篇下一篇

猜你喜欢

热点阅读