haoxuan
2024-04-23 ee414c03a6779745ea6e11693cf6f3f61690f399
考勤管理的导入接口联调+考勤管理的下载模版的接口联调
1个文件已删除
2个文件已添加
3个文件已修改
743 ■■■■■ 已修改文件
package.json 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/employeeSalary/attendanceManage.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/style/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/common/uploadImportBtn.vue 518 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/employeeSalary/attendanceManage/components/ImportDialog.vue 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/employeeSalary/attendanceManage/index.vue 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json
File was deleted
src/api/employeeSalary/attendanceManage.js
@@ -24,6 +24,14 @@
    data
  })
}
// 考勤管理 模版
export function getTemplate(data) {
  return request({
    url: "/api-jl/v1/attendance/getTemplate",
    method: "post",
    data
  })
}
// 考勤管理 获取加班规则
export function getAttendanceRule(data) {
  return request({
src/assets/style/index.scss
@@ -150,6 +150,9 @@
.font_weight_700{
  font-weight: 700;
}
.cursor_pinter{
  cursor: pointer;
}
.btn-pager {
  display: flex;
  margin-top: 10px;
src/components/common/uploadImportBtn.vue
New file
@@ -0,0 +1,518 @@
<!--
 文件名:uploadImportBtn.vue
 作者:〈版权〉
 描述:〈描述〉
 修改人:王娜
 修改时间:2019/7/30 17:27
 修改内容:〈修改内容〉
-->
<template>
  <div
    class="upload-import-btn"
    v-loading.fullscreen.lock="importFilesLoading"
    element-loading-text="拼命加载中"
    element-loading-background="rgba(255, 255, 255, 0.5)"
  >
    <div>
      <!--      accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"-->
      <el-upload
        v-model="uploadInformation.message"
        ref="upload"
        class="upload-demo"
        :disabled="disabled"
        :data="uploadData"
        :action="importFileUrl()"
        :on-preview="handlePreview"
        :on-remove="handleRemove"
        :on-change="handleChange"
        :show-file-list="false"
        :on-error="uploadError"
        :auto-upload="false"
      >
        <!-- -->
        <el-button
          class=""
          :disabled="disabled"
          :size="importObj.sizeButton"
          type="primary"
          :icon="importObj.iconButton"
        >
          <span v-if="buttonText">{{ buttonText }}</span>
          <span v-else>上传文件</span>
        </el-button>
        <div v-if="importObj.tip" slot="tip">{{ importObj.tip }}</div>
        <slot name="downButton" />
      </el-upload>
      <div class="oa-file-upload" v-if="isFileListShow && fileRefresh">
        <ul v-show="fileList.length > 0" class="file-list">
          <li v-for="(file, index) in fileList" :key="file.id">
            <div class="left margin_left_5px;">
              <i class="icon el-icon-document"></i>
              <!-- <span class="file-suffix"
                    :class="[file.suffix]">
              </span>-->
            </div>
            <div class="middle">
              <p :title="file.noticeFileName" class="name">
                <span class="ellipsis">{{ file.fileName }}</span>
                <span class="suffix">.{{ file.suffix }}</span>
              </p>
              <p class="size">{{ formatFileSize(file.size) }}</p>
            </div>
            <!--下载按钮-->
            <span class="icon delete" @click.stop="remove(index,true)">
              <i class="el-icon-delete color_red"></i>
            </span>
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>
<script>
import { Message } from "element-ui";
export default {
  name: "uploadImportBtn",
  components: {},
  props: {
    uploadInformation: {
      type: [Object],
      default: () => ({
        message: "设置",
        exportErrExcel: "",
        importLinks: "",
      }),
    },
    wranInfo: {
      type: [Object],
      default: () => ({
        successDialogIconfont: false, //成功的icon
        wranVisible: false,
        content: "错误原因",
        successNumber: "",
        callback: null,
      }),
    },
    uploadErr: {
      type: [Object],
      default: () => ({
        uploadErrNum: "",
        successDialogIconfont: false,
        uploadErrVisible: false,
      }),
    },
    continueImport: {
      type: [Boolean],
    },
    isFileListShow: {
      type: [Boolean],
      default: false,
    },
    // 参数
    name: {
      type: [String],
    },
    uploadUser: {
      type: [String],
    },
    disabled: {
      type: [Boolean],
      default: false,
    },
    queryId: {
      type: [String, Number],
    },
    uploadId: {
      type: [String],
    },
    importObj: {
      type: [Object],
      default: () => ({
        size: 100,
        suffix: "",
        sizeButton: "medium",
        iconButton: "el-icon-plus",
        tip: "",
        num: 0,
      }),
    },
    buttonText: {
      type: [String],
      default: "",
    },
  },
  data() {
    return {
      typeButton: {
        choose: "cancel",
      },
      downLoadHttp: "",
      uploadData: {
        id: "",
      },
      // name: 'food.jpeg',   规定上传文件名
      fileList: [],
      //控制加载
      importFilesLoading: false,
      wranInfos: this.wranInfo,
      uploadErrs: this.uploadErr,
      fd: {},
      number: 0,
      fileListChangeData: [], //change时fileList
      fileRefresh: true,
    };
  },
  created() {},
  watch: {
    //弹框出现恢复fileList
    continueImport(newVal) {
      if (newVal) {
        this.fileList = [];
        this.$parent.$parent.continueImport = false;
      }
    },
  },
  computed: {},
  methods: {
    submitUpload() {
      this.$refs.upload.submit();
    },
    //文件大小
    formatFileSize(val) {
      if (null == val || val == "") {
        return "0 B";
      }
      let unitArr = new Array(
        "B",
        "KB",
        "MB",
        "GB",
        "TB",
        "PB",
        "EB",
        "ZB",
        "YB"
      );
      let index = 0,
        srcsize = parseFloat(val);
      index = Math.floor(Math.log(srcsize) / Math.log(1024));
      let size = srcsize / Math.pow(1024, index);
      //  保留的小数位数
      size = size.toFixed(2);
      return size + unitArr[index];
    },
    // 移除出文件列表
    remove(index, val) {
      if (!val) {
        let filelist = JSON.parse(JSON.stringify(this.fileList));
        for (let i in filelist) {
          if (index == i) {
            this.fileList.splice(i, 1);
          }
        }
        this.$emit("remove", this.fileList);
      } else {
        this.$confirm("确定移除" + this.fileList[index].name + "?", "", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
        })
          .then(() => {
            let filelist = JSON.parse(JSON.stringify(this.fileList));
            for (let i in filelist) {
              if (index == i) {
                this.fileList.splice(i, 1);
              }
            }
            this.$emit("remove", this.fileList);
          })
          .catch(() => {});
      }
    },
    importFileUrl() {
      //'设置上传地址'
      return "";
    },
    handleRemove(file) {
      console.log(file, "handeRemove");
    },
    handlePreview(file) {
      console.log(file, "1111");
    },
    handleChange(file, fileListChange) {
      if (this.fileList.length == 0) {
        fileListChange = [];
      }
      //注解:苹果air xls 获取不到file的type值
      // const suffixName=file.raw.name.split('.')[file.raw.name.split('.').length-1]=='xls';
      // const isJPG = ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet','application/vnd.ms-excel'].indexOf(file.raw.type) >-1||suffixName;
      let isJPG = true;
      let isLt3M;
      if (this.name == "projectDoc") {
        isJPG = true;
        isLt3M = file.size / 1024 / 1024 < 100;
      } else if (this.name == "order") {
        isJPG =
          file.raw.name.split(".")[file.raw.name.split(".").length - 1] ==
          "Dwg";
        isLt3M = file.size / 1024 / 1024 < 20;
      } else if (this.importObj.suffix) {
        isJPG =
          file.raw.name.split(".")[file.raw.name.split(".").length - 1] ==
          this.importObj.suffix;
        isLt3M = file.size / 1024 / 1024 < this.importObj.size;
      }
      if (!isJPG) {
        Message.warning("上传文件只能是" + this.importObj.suffix + "格式!");
        return false;
      } else if (!isLt3M) {
        Message.warning(
          "上传文件大小不能超过 " + this.name == "projectDoc"
            ? 100
            : (this.name == "order" ? 20 : this.importObj.size) + "MB!"
        );
        return false;
      } else if (isJPG && isLt3M) {
        // this.number += 1;
        let filelist = JSON.parse(JSON.stringify(file));
        filelist.fileName = filelist.name.split(".")[0];
        filelist.suffix = filelist.name.split(".")[1];
        filelist.id = filelist.name + "*" + filelist.size + "*" + this.number;
        if (this.importObj.num) {
          if (fileListChange.length > this.importObj.num) {
            Message.warning(
              `当前限制选择 ${this.importObj.num} 个文件,共选择了 ${
                this.fileList.length + 1
              } 个文件`
            );
            return false;
          }
        }
        // else if (this.fileList.length == 0) {
        let fd = new FormData(); // 创建form对象
        fd.append("file", file.raw); // file对象是 beforeUpload参数
        fd.append("name", file.name); // file对象是 beforeUpload参数
        if (this.name == "projectDoc") {
          fd.append("projectID", this.queryId);
          fd.append("uploadUser", this.uploadUser);
          fd.append("uploadId", this.uploadId);
        }
        this.fd = fd;
        this.fileRefresh = false;
        this.$nextTick(() => {
          this.fileList.push(filelist);
          this.$set(this, "fileList", this.fileList);
          this.fileRefresh = true;
        });
        this.confirmUpload(fd, file, {});
        // }
        return false;
      }
    },
    confirmUpload(fd, file) {
      this.importFilesLoading = true;
        this.$emit("fileSuccess", fd, file);
        this.importFilesLoading = false;
    },
    clearFiles() {
      this.$refs.upload.clearFiles();
    },
    handleAvatarSuccess(res, file) {
      // 导入讲师积分 积分模块下积分维护
      if (
        this.uploadInformation.message == "导入讲师积分" ||
        this.uploadInformation.message == "批量导入积分"
      ) {
        this.traningPoint(res, file);
      } else {
        if (res.code == 200) {
          this.$message.success("导入成功!");
          this.$emit("fileSuccess");
        } else {
          this.$emit("fileError");
        }
        // else if (res.code == 70032 || res.code == '70032') {
        //   this.uploadErrs.uploadErrNum = (res.data&&res.data.errSize) ? res.data.errSize : null;
        //   this.uploadErrs.uploadErrVisible = true;
        // }
        //  else{
        //    // this.clearFiles();
        //    this.wranInfos.successDialogIconfont = false;
        //    let ErrorMessage;
        //    if (res.desc == '' || res.desc == '[]') {
        //      ErrorMessage = '';
        //    } else {
        //      ErrorMessage = res.desc;
        //    }
        //    this.wranInfo.content = this.uploadInformation.message + '上传失败,请重试!' + ErrorMessage;
        //    this.wranInfos.wranVisible = true;
        //  }
      }
    },
    //讲师积分的导入
    traningPoint(res) {
      if (res.code == 200) {
        if (res.data > 0) {
          this.uploadErrs.uploadErrNum = res.data ? res.data : null;
          this.uploadErrs.uploadErrVisible = true;
        } else {
          // this.fileList.push(res.data)
          this.wranInfos.successDialogIconfont = true;
          this.wranInfos.content =
            this.uploadInformation.message + "上传成功!是否返回列表页?";
          if (res.data) {
            this.wranInfos.successNumber = res.data.errSize
              ? res.data.errSize
              : "";
          }
          this.wranInfos.wranVisible = true;
        }
      } else {
        // this.clearFiles();
        this.wranInfos.successDialogIconfont = false;
        // let ErrorMessage;
        // if (res.desc == "" || res.desc == "[]") {
          // ErrorMessage = "";
        // } else {
          // ErrorMessage = res.desc;
        // }
        // this.wranInfo.content =
        // this.uploadInformation.message + "上传失败,请重试!" + ErrorMessage;
        // this.wranInfos.wranVisible = true;
      }
    },
    uploadError() {
      this.wranInfos.successDialogIconfont = false;
      this.wranInfos.content =
        this.uploadInformation.message + "上传失败,请重试!";
      this.wranInfos.wranVisible = true;
    },
    //点击确定按钮返回相应的列表页
    confirmImport() {
      this.wranInfos.wranVisible = false;
      this.uploadErrs.uploadErrVisible = false;
    },
    //导入失败时下载失败数据
    cancelErrorExcel() {
      // this.clearFiles();
      this.wranInfos.wranVisible = false;
      this.uploadErrs.uploadErrVisible = false;
    },
    //导入上传失败的excel
    exportErrorExcel() {
      this.uploadErrs.uploadErrVisible = false;
      this.wranInfos.wranVisible = false;
    },
  },
};
</script>
<style scoped>
.choose-btn-icon {
  margin-right: 5px;
  font-size: 16px;
}
.oa-file-upload .file-list {
  align-items: center;
  flex-wrap: wrap;
  margin: 0 0 15px 0;
  overflow: hidden;
}
.oa-file-upload .file-list li {
  min-width: 240px;
  width:calc(100% - 20px);
  height: 60px;
  border: 1px solid #ddd;
  background-color: #f5f5f5;
  float: left;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  color: #333;
  margin: 20px 20px 0 0;
  position: relative;
  border-radius: 3px;
}
.oa-file-upload .file-list .left {
  font-size: 26px;
  color: #c1c1c1;
  width: auto;
  text-align: center;
  line-height: 62px;
  float: left;
}
.oa-file-upload .file-list .right {
  width: 30px;
  float: right;
  cursor: pointer;
  font-size: 26px;
  line-height: 50px;
}
.oa-file-upload .file-list .middle {
  min-width: 100px;
  width: calc(100% - 80px);
  padding: 0 5px;
  line-height: 25px;
  margin-top: 5px;
  text-align: left;
  position: relative;
  float: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.oa-file-upload .file-list p.name {
  display: flex;
  align-items: center;
}
.oa-file-upload .file-list p.name span.ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.oa-file-upload .file-list p.name span.suffix {
  white-space: nowrap;
}
.oa-file-upload .file-list .middle span.size {
  position: absolute;
  bottom: -5px;
}
.oa-file-upload .file-list span.delete {
  position: absolute;
  right: 12px;
  top: 12px;
  cursor: pointer;
  font-size: 26px;
  /* display: none; */
}
.oa-file-upload .file-list li:hover span.delete {
  display: block;
}
.oa-file-upload .handle-btn button {
  border: 0;
}
/*  上传前面的图标*/
.file-suffix {
  width: 40px;
  height: 40px;
  display: inline-block;
  margin: 0 10px;
  margin-top: 11px;
}
</style>
src/views/employeeSalary/attendanceManage/components/ImportDialog.vue
New file
@@ -0,0 +1,157 @@
<template>
  <el-dialog
    :close-on-click-modal="false"
    :visible.sync="isopen"
    width="28rem"
    class="add-event-dialog"
    @close="shutdown"
  >
    <div slot="title" class="tac drawerHeader">{{ title }}</div>
    <div class="dialog-content-box">
      <el-form ref="form" :rules="rules" :model="form" label-width="110px">
        <el-form-item label="上传考勤:" prop="doc" class="down-box">
          <uploadImportBtn
            ref="mychild"
            buttonText="上传"
            name="processModel"
            :isFileListShow="true"
            :continueImport="continueImport"
            :importObj="importObj"
            @fileSuccess="fileSuccess"
            @remove="remove"
          >
        </uploadImportBtn>
        <span class="margin_left_20px cursor_pinter down-btn color_blue" @click="downHttpClick"><i class="el-icon-download"></i>下载模板</span>
        </el-form-item>
      </el-form>
    </div>
    <div slot="footer" class="dialog-footer tac">
      <el-button @click="shutdown">取消</el-button>
      <el-button @click="onSubmit" type="primary">确定</el-button>
    </div>
  </el-dialog>
</template>
<script>
import { attendanceInput,getTemplate } from "@/api/employeeSalary/attendanceManage.js"
import uploadImportBtn from "@/components/common/uploadImportBtn";
import FileSaver from 'file-saver'
export default {
  components: {
    uploadImportBtn,
  },
  props: ["title"],
  data() {
    return {
      form: {
        doc: null,
        doc2: null,
      },
      rules: {
        doc: [{ required: true, message: "请上传", trigger: "change" }],
      },
      isopen: false,
      // 上传
      continueImport: false, //是否继续上传
      continueImport2: false, //是否继续上传
      importObj: {
        suffix: "xlsx",
        size: 20,
        num: 1,
      },
    };
  },
  mounted() {},
  watch: {
    isopen(val) {
      if (val) {
        this.form.doc = null;
        this.form.doc2 = null;
        this.$nextTick(()=>{
          this.$refs.form.resetFields();
        })
      }
    },
  },
  methods: {
    //导入成功
    fileSuccess(fd, file) {
      this.continueImport = true;
      this.form.doc = file;
    },
    shutdown() {
      this.isopen = false;
      this.$refs.mychild.remove(0);
      this.$emit("fileSuccess", this.form);
    },
    remove(){
      this.continueImport = false;
      this.form.doc = null;
      this.$refs.mychild.remove(0);
    },
    downHttpClick(){
      getTemplate({category:13}).then(res=>{
        if (res.code === 200) {
          const fileUrl = res.data[0].fileUrl;
          const downloadLink = document.createElement("a");
          downloadLink.href = fileUrl;
          downloadLink.download = "模板.excel";
          document.body.appendChild(downloadLink);
          downloadLink.click();
          this.$message.success("模板下载成功!");
        }
      });
    },
    onSubmit() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          let fd = new FormData(); // 创建form对象
          fd.append("file", this.form.doc.raw); // file对象是 beforeUpload参数
          // fd.append('file2', this.form.doc2.raw)  // file对象是 beforeUpload参数
          attendanceInput(fd).then((res) => {
            if (res.code == 200) {
              this.$message.success("上传成功!");
              this.shutdown();
            }
          });
        } else {
          this.$message.error("请上传!");
        }
      });
    },
  },
};
</script>
<style lang="scss" scoped>
/* .title {
  font-size: 13px;
  line-height: 18px;
  color: #2a78fb;
} */
.dialog-content-box {
  height: 17rem;
  min-height: 110px;
  overflow: auto;
}
::v-deep .el-select-dropdown__wrap {
  overflow: auto !important;
}
::v-deep .el-select-dropdown {
  position: absolute !important;
  top: 36px !important;
  left: 0px !important;
}
.down-box{
  position:relative;
  .down-btn{
    position:absolute;
    left:90px;
    top:0;
  }
}
</style>
src/views/employeeSalary/attendanceManage/index.vue
@@ -42,6 +42,12 @@
        </div>
      </div>
    </div>
    <ImportDialog
      title="上传文件"
      ref="import"
      @fileSuccess="fileSuccess"
    >
    </ImportDialog>
    <!-- 规则设置 -->
    <RuleSettingDialog ref="RuleSettingDialog" :editRow="editRow"  @closeClick="getData" />
  </div>
@@ -51,13 +57,16 @@
import { getAttendanceList, deleteAttendanceInfo } from "@/api/employeeSalary/attendanceManage.js"
import pageMixin from "@/components/makepager/pager/mixin/pageMixin"
import RuleSettingDialog from  "@/views/employeeSalary/attendanceManage/components/RuleSettingDialog"
import ImportDialog from "@/views/employeeSalary/attendanceManage/components/ImportDialog";
export default {
  name: "attendanceManage",
  props: {
  },
  mixins: [pageMixin],
  components: {
    RuleSettingDialog
    RuleSettingDialog,
    ImportDialog
  },
  data() {
    return {
@@ -170,9 +179,13 @@
      this.pagerOptions.currPage = 1
      this.getData()
    },
    //导入成功
    fileSuccess() {
       this.getData()
    },
    // 导入
    exportClick() {
      this.$refs.import.isopen=true;
    },
     // 同步
     synchClick(){