luoyb
2025-09-23 7fc325910b74e0426ffa2bad7f2daddf5eea114b
合同到期提醒模块
1个文件已添加
553 ■■■■■ 已修改文件
src/views/remind/contract.vue 553 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/remind/contract.vue
New file
@@ -0,0 +1,553 @@
<template>
  <div style="background-color: #fff;height: 100%;">
    <el-container>
      <el-header :height="headerHeight">
        <el-row style="margin-bottom: 10px;">
          <el-col :span="15">
            <h3 class="bu-tian-jia-title">合同到期提醒</h3>
          </el-col>
        </el-row>
      </el-header>
      <el-main style="height: 85%;">
        <el-row style="margin: 10px 0 10px 0;">
          <el-col :span="24">
            <el-button type="primary" class="hr-but-all" @click="showDcyg(0)">导出EXCEL</el-button>
          </el-col>
        </el-row>
        <el-table
          ref="multipleTable"
          :data="contractList"
          :cell-style="{padding:'7px 0','text-align':'center'}"
          :header-cell-style="{'height':'5.3vh','background-color':'#e6e6e6','text-align':'center'}"
          stripe
          border
          style="width: 100%;color: #000;"
          @sort-change="changeSort"
        >
          <el-table-column show-overflow-tooltip fixed="left" label="操作" width="120">
            <template v-slot="scope">
              <span
                style="color: #a00515;display: inline-block;width: 40%;cursor: pointer"
                @click="goOn(scope.row)"
              >续签</span>
              <span
                style="color: #a00515;display: inline-block;width: 40%;cursor: pointer"
                @click="discontinue(scope.row)"
              >不续签</span>
            </template>
          </el-table-column>
          <el-table-column show-overflow-tooltip prop="empNumb" label="员工编号" />
          <el-table-column show-overflow-tooltip prop="allDeptName" label="部门(护卫点)" width="300" />
          <el-table-column show-overflow-tooltip prop="jobName" label="岗位" width="80" />
          <el-table-column show-overflow-tooltip prop="empName" label="姓名" width="100" />
          <el-table-column show-overflow-tooltip prop="certificateNumb" label="身份证号码" width="160" />
          <el-table-column show-overflow-tooltip prop="signingDate" label="合同签订日期" width="110" />
          <el-table-column show-overflow-tooltip prop="endDate" label="合同结束日期" width="110" />
          <el-table-column show-overflow-tooltip prop="contractPeriod" label="合同期限(年)" width="110" />
          <el-table-column show-overflow-tooltip prop="diffDay" label="到期提醒" width="120">
            <template v-slot="scope">
              <span v-if="scope.row.diffDay===0">到期</span>
              <span v-else>{{ scope.row.diffDay }}天后到期</span>
            </template>
          </el-table-column>
          <el-table-column show-overflow-tooltip prop="transactor" label="合同办理人" width="100" />
          <el-table-column show-overflow-tooltip prop="remark" label="备注" width="160" />
        </el-table>
        <pagination
          v-show="total>0"
          style="text-align: right;width: 98%;"
          :total="total"
          :page.sync="pagination.num"
          :limit.sync="pagination.size"
          @pagination="search"
        />
      </el-main>
    </el-container>
    <el-dialog title="合同信息" :visible.sync="dialogShowContract" width="50%">
      <el-form
        ref="contractForm"
        :model="contractForm"
        :rules="contractRules"
        label-position="right"
        label-width="120px"
      >
        <el-row>
          <el-col :span="12">
            <el-form-item label="姓名" prop="empName">
              <el-input v-model="contractForm.empName" />
            </el-form-item>
            <el-form-item label="身份证号码" prop="certificateNumb">
              <el-input
                v-model="contractForm.certificateNumb"
              />
            </el-form-item>
            <el-form-item label="性别" this-emp-base-info-form="sex">
              <el-select v-model="contractForm.sex" placeholder="请选择性别">
                <el-option
                  v-for="dict in sexOptions"
                  :key="dict.dicItemCode"
                  :label="dict.dicItemName"
                  :value="dict.dicItemCode"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="合同签订日期" prop="signingDate">
              <el-date-picker
                v-model="contractForm.signingDate"
                value-format="yyyy-MM-dd"
                type="date"
                placeholder="选择日期"
              />
            </el-form-item>
            <el-form-item label="合同状态" prop="contractStatus">
              <el-select
                v-model="contractForm.contractStatus"
                placeholder="请选择合同状态"
              >
                <el-option
                  v-for="dict in contractStatusOptions"
                  :key="dict.dicItemCode"
                  :label="dict.dicItemName"
                  :value="dict.dicItemCode"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="合同办理人" prop="transactor">
              <el-input v-model="contractForm.transactor" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="员工编号" prop="empNumb">
              <el-input v-model="contractForm.empNumb" />
            </el-form-item>
            <el-form-item label="部门(护卫点)" prop="allDeptName">
              <el-input v-model="contractForm.allDeptName" />
            </el-form-item>
            <el-form-item label="岗位" prop="jobName">
              <el-input v-model="contractForm.jobName" />
            </el-form-item>
            <el-form-item label="合同结束日期" prop="endDate">
              <el-date-picker
                v-model="contractForm.endDate"
                value-format="yyyy-MM-dd"
                type="date"
                placeholder="选择日期"
              />
            </el-form-item>
            <el-form-item label="合同期限(年)" prop="contractPeriod">
              <el-input v-model="contractForm.contractPeriod" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="备注" prop="remark">
              <el-input v-model="contractForm.remark" type="textarea" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="putContractInfo('contractForm')">保 存</el-button>
        <el-button @click="dialogIsShow()">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import Pagination from '@/components/Pagination'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { dateDifference } from '@/utils/myUtil'
export default {
  components: {
    Pagination
  },
  data() {
    return {
      dialog: {
        isVisible: false,
        title: '',
        type: ''
      },
      sort: {},
      // 总数量
      total: 0,
      // 查询参数
      queryParams: {
        baseKey: ''
      },
      // 分页参数
      pagination: {
        size: 15,
        num: 1
      },
      headerHeight: '30px',
      // 合同列表
      contractList: [],
      // 合同信息
      contractForm: {
        contractId: '',
        empId: '',
        empNumb: '',
        empName: '',
        certificateNumb: '',
        sex: '',
        sexName: '',
        deptId: '',
        deptName: '',
        allDeptName: '',
        JobId: '',
        jobName: '',
        beginDate: '',
        endDate: '',
        contractStatus: '',
        contractPeriod: '',
        transactor: '',
        signingDate: '',
        remark: '',
        createTime: '',
        creator: '',
        modifyTime: '',
        modifier: '',
        delFlag: '',
        empStatus: 0,
        version: '',
        diffDay: 0
      },
      sexOptions: [],
      contractStatusOptions: [],
      dialogShowContract: false,
      contractRules: {
        empName: [{ required: true, message: '请选择员工', trigger: 'change' }],
        signingDate: [{ required: true, validator: this.startDate }],
        contractStatus: [{ required: true, message: '请选择合同状态', trigger: 'change' }],
        transactor: [{ max: 40, message: '长度不超过40个字符', trigger: 'blur' }],
        beginDate: [{ required: true, message: '请选择合同开始日期', trigger: 'change' }],
        endDate: [{ required: true, validator: this.endDate }],
        remark: [{ max: 512, message: '长度不超过512个字符', trigger: 'blur' }]
      }
    }
  },
  mounted() {
    this.fetch()
    this.getDicts('sex').then(response => {
      this.sexOptions = response.data
    })
    this.getDicts('CONTRACTSTATUS').then(response => {
      this.contractStatusOptions = response.data
    })
  },
  methods: {
    search() {
      this.queryParams.baseKey = ''
      this.fetch({
        ...this.queryParams,
        ...this.sort
      })
    },
    fetch(params = {}) {
      const that = this
      params.pageSize = this.pagination.size
      params.pageNum = this.pagination.num
      params.delFlag = 0
      params.empStatus = 0
      this.$get('hr/empContractInfo/remind/list', {
        ...params
      }).then((r) => {
        const data = r.data.data
        that.total = data.total
        that.contractList = data.rows
      })
    },
    changeSort(val) {
      this.sort.field = val.prop
      this.sort.order = val.order
      this.fetch()
    },
    // 续签合同
    goOn(row) {
      this.initContractData(row)
      this.dialogShowContract = true
    },
    dialogIsShow() {
      this.dialogShowContract = false
    },
    // 不续签合同
    discontinue(val) {
      this.initContractData(val)
      this.$post('hr/empContractInfo/remind/not', { ...this.contractForm }).then(() => {
        this.buttonLoading = false
        this.$message({
          message: this.$t('tips.updateSuccess'),
          type: 'success'
        })
        this.cleanContractData()
        this.fetch()
      })
    },
    // 初始化续签合同信息
    initContractData(val) {
      this.cleanContractData()
      this.contractForm.contractId = val.contractId
      this.contractForm.empId = val.empId
      this.contractForm.empNumb = val.empNumb
      this.contractForm.empName = val.empName
      this.contractForm.certificateNumb = val.certificateNumb
      this.contractForm.sex = val.sex
      this.contractForm.deptId = val.deptId
      this.contractForm.deptName = val.deptName
      this.contractForm.allDeptName = val.allDeptName
      this.contractForm.JobId = val.JobId
      this.contractForm.jobName = val.jobName
      this.contractForm.contractStatus = '2'
    },
    // 清除续签合同信息
    cleanContractData() {
      this.contractForm.contractId = ''
      this.contractForm.empId = ''
      this.contractForm.empNumb = ''
      this.contractForm.empName = ''
      this.contractForm.certificateNumb = ''
      this.contractForm.sex = ''
      this.contractForm.deptId = ''
      this.contractForm.deptName = ''
      this.contractForm.allDeptName = ''
      this.contractForm.JobId = ''
      this.contractForm.jobName = ''
      this.contractForm.contractStatus = ''
      this.contractForm.beginDate = ''
      this.contractForm.endDate = ''
      this.contractForm.contractPeriod = 0
      this.contractForm.remark = ''
      this.contractForm.transactor = ''
    },
    // 验证合同签订日期
    startDate(rule, value, callback) {
      // 如果结束日期没选,cb
      if (!this.contractForm.endDate) {
        callback()
      } else {
        // 结束日期有,进行判断
        if (this.compareDate(value, this.contractForm.endDate)) {
          // 如果起始在结束之前
          callback()
        } else {
          callback(new Error('开始日期不能在结束日期之后,请重新选择'))
        }
      }
    },
    // 验证合同结束日期
    endDate(rule, value, callback) {
      // 如果起始日期没选,cb
      if (!this.contractForm.signingDate) {
        callback()
      } else {
        // 起始日期有,进行判断
        if (this.compareDate(this.contractForm.signingDate, value)) {
          // 如果起始在结束之前
          this.contractForm.contractPeriod = dateDifference(this.contractForm.signingDate, this.contractForm.endDate, 'o')
          callback()
        } else {
          callback(new Error('结束日期不能在开始始日期之前,请重新选择'))
        }
      }
    },
    compareDate(start, end) {
      return new Date(end).getTime() > new Date(start).getTime()
    },
    // 续签合同提交
    putContractInfo(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.$post('hr/empContractInfo/remind/continue', { ...this.contractForm }).then(() => {
            this.buttonLoading = false
            this.$message({
              message: this.$t('tips.createSuccess'),
              type: 'success'
            })
            this.cleanContractData()
            this.fetch()
            this.dialogIsShow()
          })
        }
      })
    }
  }
}
</script>
<style lang="scss">
.zzyg-table {
  .el-table th, .el-table td {
    padding: 7px 0;
  }
}
.fj-checkbox {
  .el-checkbox__input.is-checked .el-checkbox__inner {
    border-color: #a32c30;;
    background: #a32c30;;
  }
  .el-checkbox__label {
    color: #000 !important;
  }
}
</style>
<style lang="scss" scoped>
.baseinfo .el-container {
  .el-aside {
    background-color: #fff;
  }
  .el-main {
    background-color: #fff;
  }
}
.el-main {
  height: 600px;
}
.el-autocomplete {
  width: 100%;
}
.el-select {
  width: 100%;
}
.el-aside {
  padding: 20px;
  background: #f3f5f8;
  height: 600px;
  .el-tree {
    height: 100%;
  }
}
.searchTable {
  margin-top: 10px;
  border-collapse: collapse;
  width: 100%;
  tr {
    border-bottom: 1px dashed #d9dadb;
  }
  .td {
    width: 90px;
    text-align: right;
  }
  .td-group {
    padding-left: 20px;
  }
}
.searchTable td,
.searchTable th {
  color: #000;
  height: 50px;
  background-color: #fff;
}
#ygxq table {
  border-collapse: collapse;
  margin: 0 auto;
  text-align: center;
  width: 100%;
  margin-top: 20px;
}
#ygxq table td,
#ygxq table th {
  border: 1px solid #DDDCDC;
  color: #666;
  height: 30px;
}
#ygxq table thead th {
  background-color: #CCE8EB;
  width: 100px;
}
#ygxq table tr:nth-child(odd) {
  background: #fff;
}
#ygxq table tr:nth-child(even) {
  background: #F5FAFA;
}
.tdTitle {
  font-size: 14px;
  font-weight: 700;
  text-align: left;
}
.link_button {
  color: #169BD5;
}
.del_button {
  color: #D9001B;
}
#dcygTable {
  border-collapse: collapse;
  tr {
    width: 100%;
    border-bottom: 1px dashed #ccc;
    > td:nth-child(even) {
      width: 100px;
      text-align: left;
    }
  }
}
#dcygTable td {
  width: 160px;
  text-align: center;
  height: 35px;
  line-height: 35px;
  font-size: 15px;
  font-weight: 400;
}
.search-btn {
  display: inline-block;
  width: 3.64vw;
  height: 3.2vh;
  line-height: 3.2vh;
  text-align: center;
  background-color: #a00515;
  color: #fff;
  margin-left: 1vw;
  box-sizing: border-box;
  cursor: pointer;
  vertical-align: middle;
}
.sup-search-btn {
  display: inline-block;
  width: 5.2vw;
  height: 3.2vh;
  line-height: 3.2vh;
  text-align: center;
  margin-left: 1vw;
  color: #a00515;
  border: 1px solid #a00515;
  box-sizing: border-box;
  cursor: pointer;
  vertical-align: middle;
}
</style>