Browse Source

LY 专项培养

ly 3 years ago
parent
commit
bfb7c6e3a3

+ 9 - 1
master/src/main/java/com/ruoyi/project/approve/damain/DevProcess.java

@@ -34,8 +34,8 @@ public class DevProcess {
 
 
     /** 隐患申请对象 */
     /** 隐患申请对象 */
     private TApproveDanger tApprove;
     private TApproveDanger tApprove;
-
     private TApprove specApprove;
     private TApprove specApprove;
+    private Object approveObject;
     private TApproveSpecModify approveSpecModify;
     private TApproveSpecModify approveSpecModify;
     /** 是否结束 */
     /** 是否结束 */
     private boolean isEnd;
     private boolean isEnd;
@@ -120,6 +120,14 @@ public class DevProcess {
         this.approveSpecModify = approveSpecModify;
         this.approveSpecModify = approveSpecModify;
     }
     }
 
 
+    public Object getApproveObject() {
+        return approveObject;
+    }
+
+    public void setApproveObject(Object approveObject) {
+        this.approveObject = approveObject;
+    }
+
     @Override
     @Override
     public String toString() {
     public String toString() {
         return "DevProcess{" +
         return "DevProcess{" +

+ 10 - 0
master/src/main/java/com/ruoyi/project/approve/damain/DevTask.java

@@ -52,6 +52,8 @@ public class DevTask {
     /** 隐患申请对象 */
     /** 隐患申请对象 */
     private TApproveDanger tApprove;
     private TApproveDanger tApprove;
 
 
+    private Object approveObject;
+
     /** 申请对象 */
     /** 申请对象 */
     private TApprove specApprove;
     private TApprove specApprove;
     private TApproveSpecModify ApproveSpecModify;
     private TApproveSpecModify ApproveSpecModify;
@@ -125,6 +127,14 @@ public class DevTask {
         this.specApprove = specApprove;
         this.specApprove = specApprove;
     }
     }
 
 
+    public Object getApproveObject() {
+        return approveObject;
+    }
+
+    public void setApproveObject(Object approveObject) {
+        this.approveObject = approveObject;
+    }
+
     public String getApNo() {
     public String getApNo() {
         return apNo;
         return apNo;
     }
     }

+ 6 - 0
master/src/main/java/com/ruoyi/project/ehs/controller/TApproveDangerController.java

@@ -379,6 +379,12 @@ public class TApproveDangerController extends BaseController
                     devProcess.setApNo(approve.getApNo());
                     devProcess.setApNo(approve.getApNo());
                     devProcess.setApName(user.getNickName());
                     devProcess.setApName(user.getNickName());
                     devProcess.setApproveSpecModify(approve);
                     devProcess.setApproveSpecModify(approve);
+                }else if (pi.getProcessDefinitionName().equals("专项培训计划审核")){
+                    TStApprove approve = tStApproveService.selectTStApproveById(Long.parseLong(pi.getBusinessKey()));
+                    SysUser user = sysUserService.selectUserById(approve.getUserId());
+                    devProcess.setApNo(approve.getApNo());
+                    devProcess.setApName(user.getNickName());
+                    devProcess.setApproveObject(approve);
                 }else {
                 }else {
                     TApproveDanger approveDanger = tApproveDangerService.selectTApproveDangerById(Long.parseLong(pi.getBusinessKey()));
                     TApproveDanger approveDanger = tApproveDangerService.selectTApproveDangerById(Long.parseLong(pi.getBusinessKey()));
                     SysUser user = sysUserService.selectUserById(approveDanger.getRecorderId());
                     SysUser user = sysUserService.selectUserById(approveDanger.getRecorderId());

+ 830 - 0
ui/src/views/approve/approveDetail/specTrainingPlan-detaill.vue

@@ -0,0 +1,830 @@
+<template>
+  <el-dialog
+    width="1500px"
+    :title="!this.taskForm.taskId == '' ? $t('处理') : $t('详情')"
+    :visible.sync="visible">
+    <el-form :model="taskForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="" label-width="80px">
+      <el-form-item label="年度计划">
+        <el-table  :data="yearplanList"  border>
+          <el-table-column label="培训员工编号" align="center" prop="staffId" :show-overflow-tooltip="true"/>
+          <el-table-column label="培训员工" align="center"  prop="staffName" :show-overflow-tooltip="true"/>
+          <el-table-column label="年度培训标题" align="center" prop="name" :show-overflow-tooltip="true"/>
+          <el-table-column label="年份" align="center" prop="planYear" width="100">
+          </el-table-column>
+          <el-table-column label="部门" align="center" prop="deptName" :show-overflow-tooltip="true"/>
+        </el-table>
+      </el-form-item>
+      <el-form-item label="计划列表">
+        <div class="barchart">
+        <el-table
+          :data="planList"
+          border
+          style="width: 100%">
+          <el-table-column label="培训员工编号"  align="center" prop="staffId" :show-overflow-tooltip="true"/>
+          <el-table-column label="培训员工" align="center"  prop="staffName" :show-overflow-tooltip="true"/>
+          <el-table-column label="培训内容"  align="center" prop="plantName" :show-overflow-tooltip="true"/>
+          <el-table-column label="开始日期"  align="center" prop="startDate" width="100">
+            <template slot-scope="scope">
+              <span>{{ parseTime(scope.row.startDate, '{y}-{m}-{d}') }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="结束日期"  align="center" prop="endDate" width="100">
+            <template slot-scope="scope">
+              <span>{{ parseTime(scope.row.endDate, '{y}-{m}-{d}') }}</span>
+            </template>
+          </el-table-column>
+<!--          <el-table-column label="学时"  align="center" prop="classHour" :show-overflow-tooltip="true"/>-->
+          <el-table-column label="具体内容"  align="center" prop="classContent" :show-overflow-tooltip="true"/>
+          <el-table-column :label="$t('申请状态')" align="center"  prop="approveStatus" :show-overflow-tooltip="true">
+            <template slot-scope="scope">
+              <el-tag
+                :type="approveStatusType(scope.row.approveStatus)"
+                disable-transitions>{{approveStatusFormat(scope.row)}}</el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="创建人"  align="center" prop="createBy" :show-overflow-tooltip="true"/>
+          <el-table-column label="创建时间"  align="center" prop="createdate" width="130">
+            <template slot-scope="scope">
+              <span>{{ parseTime(scope.row.createdate, '{y}-{m}-{d}  {h}:{i}') }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="修改人"  align="center" prop="updateBy" :show-overflow-tooltip="true"/>
+          <el-table-column label="修改时间"  align="center" prop="updatedate" width="130">
+            <template slot-scope="scope">
+              <span>{{ parseTime(scope.row.updatedate, '{y}-{m}-{d}  {h}:{i}') }}</span>
+            </template>
+          </el-table-column>
+          <!-- 渲染时间(年|月) -->
+          <el-table-column
+            v-if="IsShowyear"
+            v-for="(item, index) in showMonths"
+            :label="item.year"
+            prop="showMonths"
+            align="center"
+            :key="index"
+          >
+            <el-table-column
+              v-for="(it, index1) in item.months"
+              :label="it.str"
+              prop="str"
+              min-width="30"
+              style="padding: 0; margin: 0;"
+              align="center"
+              :key="index1"
+            >
+              <template slot-scope="scope" class="progressCon">
+                <div v-if="getCellDateWidth > 0">
+                  <div
+                    v-if="index === 0 && index1 === 0 && scope.$index % 2 === 0"
+                    class="progressUpon"
+                    :style="{width:optimizeCalcWidth(scope.row),left:optimizeCalcLeft(scope.row)}"
+                  ></div>
+                  <div
+                    v-else-if="index === 0 && index1 === 0 && scope.$index % 2 !== 0"
+                    class="progressDownon"
+                    :style="{width:optimizeCalcWidth(scope.row),left:optimizeCalcLeft(scope.row)}"
+                  ></div>
+                </div>
+                <div v-else>
+                  <div
+                    v-if="scope.$index % 2 === 0"
+                    :class="scope.row.beginTimeStamp <= it.endTimeStamp && scope.row.endTimeStamp >= it.beginTimeStamp ? 'progressUpon' : '' "
+                    :style="{width:scope.row.beginTimeStamp <= it.endTimeStamp && scope.row.endTimeStamp >= it.beginTimeStamp ? calcwidth(scope.row,it) : '0px',left:scope.row.beginTimeStamp <= it.endTimeStamp && scope.row.endTimeStamp >= it.beginTimeStamp ? calcLeft(scope.row,it) : '0px'}"
+                  ></div>
+                  <div v-else
+                       :class="scope.row.beginTimeStamp <= it.endTimeStamp && scope.row.endTimeStamp >= it.beginTimeStamp  ? 'progressDownon' : '' "
+                       :style="{width:scope.row.beginTimeStamp <= it.endTimeStamp && scope.row.endTimeStamp >= it.beginTimeStamp ? calcwidth(scope.row,it) : '0px',left:scope.row.beginTimeStamp <= it.endTimeStamp && scope.row.endTimeStamp >= it.beginTimeStamp ? calcLeft(scope.row,it) : '0px'}"
+                  ></div>
+                </div>
+              </template>
+            </el-table-column>
+          </el-table-column>
+        </el-table>
+        </div>
+      </el-form-item>
+      <el-row>
+
+      </el-row>
+      <el-form-item :label="$t('申请时间')"  prop="creattime">
+        <el-input v-model="dataForm.creattime" disabled></el-input>
+      </el-form-item>
+
+    </el-form>
+    <div>
+      <span>{{$t('流转详情')}}</span>
+      <el-table :data="historyList" border v-loading="historyLoading" style="width: 100%;">
+        <el-table-column prop="taskName" header-align="center" align="center" :label="$t('流程进度')"></el-table-column>
+        <el-table-column prop="userName" header-align="center" align="center" :label="$t('姓名')"></el-table-column>
+        <el-table-column prop="taskCreateTime" header-align="center" align="center" :label="$t('开始时间')"></el-table-column>
+        <el-table-column prop="taskEndTime" header-align="center" align="center" :label="$t('结束时间')"></el-table-column>
+        <el-table-column prop="comment" header-align="center" align="center" :label="$t('审批意见')"></el-table-column>
+      </el-table>
+    </div>
+
+
+  </el-dialog>
+</template>
+
+<script>
+  import {getToken} from "@/utils/auth";
+
+  import {getStapproveInfo, handleApprove} from "@/api/training/spec/stapprove";
+  import {getHistorylist} from "@/api/ehs/approvedanger";
+  import {addPlan, getPlan, updatePlan} from "@/api/training/spec/plan";
+
+  export default {
+  name: "spec-training-plan",
+  components: {},
+  data() {
+    return {
+      loading: true,
+      // 总条数
+      total: 0,
+      // 是否显示弹出层
+      open: false,
+      title: "",
+      approvedangerList: [],
+      showMonths:[],
+      minDay:"", // 最小日期
+      maxDay:"", // 最大日期
+      IsShowyear:true, // 显示年|月 、 月|日
+      // 学员列表
+      successorOptions: [],
+      approveStatusOptions: [],
+      recordVisible: false,
+      // 遮罩层
+      historyLoading: false,
+      //流转列表
+      historyList: [],
+      visible: false,
+      planList: [],
+      yearplanList: [],
+      dataList: [],
+      fileTips: '',
+      showDelay: false,
+      submitDisabled: false,
+      dataListLoading:true,
+      taskName: '',
+      dataForm: {
+        id: 0,
+        userId: '',
+        devId: '',
+        devType: '',
+        approveType: '',
+        content: '',
+        fileUrls: '',
+        reUrls: '',
+        status: '',
+        creattime: '',
+        plantCode: '',
+        unit: '',
+        devname: '',
+        devno: '',
+        files: [],
+        delayDate: '',
+        delayReason: '',
+        delayMeasure: '',
+        delayNotice: ''
+      },
+      taskForm: {
+        comment: '',
+        taskId: '',
+        files: '',
+        govDate: '',
+        govFileList: []
+      },
+      // 查询参数
+      queryParams: {
+        processId: null,
+      },
+      doc: {
+        file: "",
+        // 是否显示弹出层(报告附件)
+        open: false,
+        // 弹出层标题(报告附件)
+        title: "",
+        // 是否禁用上传
+        isUploading: false,
+        // 是否更新已经存在的用户数据
+        updateSupport: 0,
+        // 报告附件上传位置编号
+        ids: 0,
+        // 设置上传的请求头部
+        headers: { Authorization: "Bearer " + getToken() },
+        // 上传的地址
+        url: process.env.VUE_APP_BASE_API + "/sems/specfile/uploadFile",
+        commonfileList: null,
+        pType: 'traning',
+        pId: null
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+      },
+      dataRule: {
+        approveType: [
+          { required: true, message: this.$t('approveType') + this.$t('notEmpty'), trigger: 'blur' }
+        ],
+        content: [
+          { required: true, message: this.$t('content') + this.$t('notEmpty'), trigger: 'blur' }
+        ]
+      },
+      downloadAction: process.env.VUE_APP_BASE_API +'/sems/approve/exportPDF',
+      approveOption: [],
+      devTypeOption: [],
+      belong: '',
+      fileList: [],
+    };
+  },
+  watch: {
+    // 根据名称筛选部门树
+    deptName(val) {
+      this.$refs.tree.filter(val);
+    }
+  },
+  computed:{
+      // 获取最小日期-月开始时间戳
+      minDayTimeStamp() {
+        if(this.IsShowyear){
+          return this.showMonths[0].months[0].beginTimeStamp
+        }else{
+          return this.showMonths[0].days[0].daysArr[0].timestamp
+        }
+      },
+      // 获取最大日期时间戳
+      maxDayTimeStamp() {
+        let Length = this.showMonths.length // 年有多少个
+        // 如果显示年|月 与 月|日 是不同的
+        if(this.IsShowyear){
+          let monthsLength = this.showMonths[Length - 1].months.length  //月有多少个
+          return this.showMonths[Length - 1].months[monthsLength - 1].endTimeStamp
+        }else{
+          let daysLength = this.showMonths[Length - 1].days.length
+          let daysarrLength = this.showMonths[Length - 1].days[daysLength - 1].daysArr.length  //天有多少个
+          return this.showMonths[Length - 1].days[daysLength - 1].daysArr[daysarrLength - 1].timestamp + 86400000  //+86400000 是因为时间戳都是0点这样+1天的时间戳,就表示最晚一天的最后的时间
+        }
+      },
+      // 最大日期与最小日期的时间戳差
+      maxAndminDayTimeStamp() {
+        return this.maxDayTimeStamp - this.minDayTimeStamp
+      },
+      // 获取日期单元格宽度 => 如果返回0则只用之前第一版的计算方法
+      getCellDateWidth() {
+        let num = 0 // 获取日期单元格数量
+        if(this.IsShowyear){
+          // 月数量
+          for(let i = 0;i < this.showMonths.length;i++){
+            num += this.showMonths[i].months.length
+          }
+        }else{
+          // 天数量
+          for(let i = 0;i < this.showMonths.length;i++){
+            for(let j = 0;j < this.showMonths[i].days.length;j++){
+              num += this.showMonths[i].days[j].daysArr.length
+            }
+          }
+        }
+
+        // 每个单元格最小30宽度
+        let MaxWidth = window.screen.width
+        let CellNum = MaxWidth / 30 > 0 ? MaxWidth / 30  : 0
+        if(num >= CellNum){ // 页面宽 / 单元格最小宽度 = 最多放下的值
+          return num * 30
+        }else{
+          // 单元格的值,就不能是最小值30了
+          // 需要获取dom的宽度,在进行计算,但是dom还未渲染完成,因此这里就不考虑了,直接只用第一版的方法动态计算
+          // TODO
+          return 0
+        }
+
+      }
+    },
+  created() {
+    this.getDicts("spec_training_approve_status").then(response => {
+      this.approveStatusOptions = response.data;
+    });
+  },
+  methods: {
+    init (id, taskId, processId,taskName) {
+      this.dataForm.processId = processId
+      this.taskName = taskName
+      this.taskForm.taskId = taskId
+      this.dataForm.id = id || 0
+      this.visible = true
+      this.queryParams.processId = processId;
+      getHistorylist(this.queryParams).then(response => {
+        this.historyList = response.rows;
+        this.historyLoading = false
+      });
+      getStapproveInfo(id).then(response => {
+        this.taskForm.businessKey = response.data.id
+        this.dataForm.creattime = response.data.creattime
+        this.planList = response.data.planList
+        this.yearplanList = [response.data.yearplan]
+        this.setrowspans() // 设置合并
+        this.getChartTitle() // 渲染的信息
+        this.$nextTick(() => {
+          this.$refs.planTable.doLayout(); // 解决表格错位
+        });
+      });
+
+    },
+      // 申请状态字典翻译
+    approveStatusFormat(row, column) {
+      return this.selectDictLabel(this.approveStatusOptions, row.approveStatus);
+    },
+    approveStatusType (type) {
+      if (type == 0) {
+        return 'danger'
+      }else if (type == 1) {
+        return 'success'
+      }else if (type == 2) {
+        return 'danger'
+      }else {
+        return 'info'
+      }
+    },
+    // 取消按钮
+    cancel() {
+      this.visible = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        userId: null,
+        devId: null,
+        devType: null,
+        approveType: null,
+        content: null,
+        fileUrls: null,
+        reUrls: null,
+        status: 0,
+        creattime: null,
+        endtime: null,
+        processId: null,
+        govDate: null,
+        delayDate: null,
+        delayReason: null,
+        delayMeasure: null,
+        delayNotice: null,
+        apNo: null,
+        checkDate: null,
+        reportId: null,
+        monthId: null,
+        delFlag: null,
+        deptId: null
+      };
+      this.resetForm("form");
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      const id = row.id || this.ids
+      getPlan(id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "修改培训计划";
+      });
+    },
+    /** 提交按钮 */
+    // 表单提交
+    dataFormSubmit (val) {
+      this.submitDisabled = true
+      console.log(this.taskForm.govFileList)
+      this.dataForm.files = []
+      if (this.taskForm.govFileList.length > 0) {
+        for (let i = 0; i < this.taskForm.govFileList.length; i++) {
+          let obj = {}
+          obj.fileName = this.taskForm.govFileList[i].response.fileName
+          obj.fileUrl = this.taskForm.govFileList[i].response.url
+          this.dataForm.files.push(obj)
+        }
+      }
+      this.taskForm.condition = val
+      this.taskForm.govFiles = this.dataForm.files
+      handleApprove(this.taskForm).then(response => {
+        this.submitDisabled = false
+        this.msgSuccess(this.$t('处理成功'));
+        this.visible = false;
+        this.$emit('refreshDataList')
+      });
+      this.$nextTick(function () {
+        this.taskForm.comment = ''
+      })
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updatePlan(this.form).then(response => {
+              this.msgSuccess("修改成功");
+              this.open = false;
+              getStapproveInfo(this.dataForm.id).then(response => {
+                this.taskForm.businessKey = response.data.id
+                this.dataForm.creattime = response.data.creattime
+                this.planList = response.data.planList
+                this.yearplanList = [response.data.yearplan]
+                this.setrowspans() // 设置合并
+                this.getChartTitle() // 渲染的信息
+                this.$nextTick(() => {
+                  this.$refs.planTable.doLayout(); // 解决表格错位
+                });
+              });
+            });
+          }
+        }
+      });
+    },
+    /** 取消按钮 */
+    cancel2() {
+      this.open = false;
+      this.reset();
+    },
+    optimizeCalcWidth(val) {
+      let SumNum = this.maxAndminDayTimeStamp
+      let diffNum = this.IsShowyear ? val.endTimeStamp - val.beginTimeStamp : val.endTimeStamp + 84600000 - val.beginTimeStamp  // 结束日期 - 开始日期
+      let rate = Math.round(diffNum / SumNum * 10000) / 100.00 //得到百分比
+      let widthPx = this.getCellDateWidth * rate / 100.00
+      return widthPx + 'px'
+    },
+    optimizeCalcLeft(val) {
+      let SumNum = this.maxAndminDayTimeStamp
+      let diffNum = val.beginTimeStamp - this.minDayTimeStamp // 开始日期 - 整个月开始日期
+      let rate = Math.round(diffNum / SumNum * 10000) / 100.00 //得到百分比
+      let leftPx = this.getCellDateWidth * rate / 100.00
+      return leftPx + 'px'
+    },
+    // 计算图表的Left
+    calcLeft(val,date) {
+      // 如果本月的最大时间戳都没有结束时间长,那么就可判断
+      if(val.endTimeStamp > date.endTimeStamp){
+        // 如果本月开始日期小于开始日期
+        if(val.beginTimeStamp > date.beginTimeStamp){
+          // 进行判断
+          let diffNum = date.endTimeStamp - val.beginTimeStamp
+          let SumNum = date.endTimeStamp - date.beginTimeStamp
+          let rate =  100 - Math.round(diffNum / SumNum * 10000) / 100.00
+          // 位置判断
+          return rate+"%"
+        }
+      }else if(val.endTimeStamp > date.beginTimeStamp && val.endTimeStamp < date.endTimeStamp){
+        // 进行判断
+        if(val.beginTimeStamp > date.beginTimeStamp){
+          // 都在一个单元格中
+          let diffNum = val.beginTimeStamp - date.beginTimeStamp
+          let SumNum = date.endTimeStamp - date.beginTimeStamp
+          let rate =  Math.round(diffNum / SumNum * 10000) / 100.00
+          // 位置判断
+          return rate+"%"
+        }
+      }
+      return '0px'
+    },
+    // 计算图表的Width
+    calcwidth(val,date) {
+      if(this.IsShowyear){
+        // 如果是 年|月
+        // 1. 如果本月的最大时间戳都没有结束时间长,那么就可设置100%
+        // 2. 如果本月的最小时间戳比结束时间长,那么设置0
+        // 3. 如果本月的最小时间戳没有结束时间长,那么进行判断
+        if(val.endTimeStamp > date.endTimeStamp){
+          // 如果本月开始日期小于开始日期
+          if(val.beginTimeStamp > date.beginTimeStamp){
+            // 进行判断
+            let diffNum = val.beginTimeStamp - date.beginTimeStamp
+            let SumNum = date.endTimeStamp - date.beginTimeStamp
+            let rate = Math.round(diffNum / SumNum * 10000) / 100.00
+            return 'calc('+ rate +'% + 2px)' // 结束时间超过本月最大时间戳直接+2px
+          }
+          return 'calc(100% + 2px)'
+        }else if(val.endTimeStamp < date.beginTimeStamp){
+          return '0px'
+        }else if(val.endTimeStamp > date.beginTimeStamp && val.endTimeStamp <= date.endTimeStamp){
+          // 进行判断
+          if(val.beginTimeStamp > date.beginTimeStamp){
+            // 都在一个单元格中
+            let SumNum = date.endTimeStamp - date.beginTimeStamp // 全月多少数
+            let diffNum = val.endTimeStamp - val.beginTimeStamp // 过程多少数
+            diffNum = diffNum === 0 ?  86400000 : diffNum
+            let rate = Math.round(diffNum / SumNum * 10000) / 100.00
+            return 'calc('+ rate +'%)'
+          }else{
+            // 不在一个单元格中,则不需要判断任何信息
+            let diffNum = val.endTimeStamp - date.beginTimeStamp
+            let SumNum = date.endTimeStamp - date.beginTimeStamp
+            let rate = Math.round(diffNum / SumNum * 10000) / 100.00
+            return 'calc('+ rate +'%)'
+          }
+        }
+      }else{
+        // 如果是 月|日
+        // 1.如果开始时间大于 天的时间戳,则为0
+        // 2.如果结束时间小于 天的时间戳,则为100%
+        if(val.beginTimeStamp > date.timestamp){
+          return '0px'
+        }else if(val.beginTimeStamp < date.timestamp && val.endTimeStamp > date.timestamp){
+          return 'calc(100% + 2px)'
+        }
+      }
+      return '0px'
+    },
+    //获得数据相同的行数(网络复制)
+    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+      if (columnIndex === 0) {
+        return {
+          rowspan: row.rowspan,
+          colspan: 1
+        };
+      }
+    },
+    // 根据id去分组(网络复制)
+    setrowspans() {
+      // 先给所有的数据都加一个v.rowspan = 1
+      this.planList.forEach(v => {
+        v.rowspan = 1;
+      });
+      // 双层循环
+      for (let i = 0; i < this.planList.length; i++) {
+        // 内层循环,上面已经给所有的行都加了v.rowspan = 1
+        // 这里进行判断
+        // 如果当前行的id和下一行的id相等
+        // 就把当前v.rowspan + 1
+        // 下一行的v.rowspan - 1
+        for (let j = i + 1; j < this.planList.length; j++) {
+          //此处可根据相同字段进行合并,此处是根据的id
+          if (this.planList[i].id === this.planList[j].id) {
+            this.planList[i].rowspan++;
+            this.planList[j].rowspan--;
+          }
+        }
+        // 这里跳过已经重复的数据
+        i = i + this.planList[i].rowspan - 1;
+      }
+    },
+    // 渲染表格头,首先是年月,如2018年11月
+    getChartTitle(startDate, endDate){
+      var chartTable = this.planList;
+      // 准备日期,为了防止多次赋值属性,导致计算属性重新计算,决定只赋值一次
+      let maxDayParams = "",minDayParams = ""
+
+      for(var i = 0; i < chartTable.length; i++){
+
+        var StartDate = chartTable[i].startDate;
+        var EndDate = chartTable[i].endDate;
+        var mainObj = chartTable[i];
+
+
+        // 计划日期
+        maxDayParams === "" ? maxDayParams = EndDate : ''
+        minDayParams === "" ? minDayParams = StartDate : ""
+        maxDayParams = this.compareDate(EndDate,maxDayParams,true)
+        minDayParams = this.compareDate(StartDate,minDayParams,false)
+        var days = this.GetNumberOfDays(StartDate,EndDate) // 计算工期
+        this.planList[i].days = days + 1 // 加一是因为没算结算当天
+        // 记录时间戳
+        this.planList[i].beginTimeStamp = this.getTimeStamp(StartDate)
+        this.planList[i].endTimeStamp = this.getTimeStamp(EndDate)
+
+      }
+      this.minDay = minDayParams
+      this.maxDay = maxDayParams
+      console.log("小:"+this.minDay)
+      console.log("大:"+this.maxDay)
+
+      this.getYearArr()
+      console.log(this.showMonths)
+
+    },
+
+    // 获取需要的格式的年月日信息
+    getYearArr(){
+      // 如果有一个日期相差超过366天,按照年,不超过则按天
+      var days = this.GetNumberOfDays(this.minDay,this.maxDay)
+      if(days >= 365){
+        //需要记录月份
+        this.IsShowyear = true
+      }else{
+        //需要记录天数
+        this.IsShowyear = true
+      }
+      // 获取需要格式的年月信息
+      let yearArr = []; // 存年
+
+      let minYear = new Date(this.minDay).getFullYear();
+      let maxYear = new Date(this.maxDay).getFullYear();
+      // 保存年
+      if(minYear === maxYear){
+        yearArr.push({
+          year: minYear+"",
+          months: [],        // 放月的数组
+          days: []
+        })
+      }else{
+        for(let i = minYear;i <= maxYear;i++){
+          yearArr.push({
+            year: i+"",
+            months: [],        // 放月的数组
+            days: []
+          })
+        }
+      }
+      // 保存月
+      for(let i = 0;i < yearArr.length;i++){
+        let minMonth = 1
+        if(i === 0){
+          minMonth = new Date(this.minDay).getMonth() + 1;
+        }
+        // 1.eg:2016年9月 至 2019年01月
+        // 2.如果只有一个年,那么月份就是最小月到最大月
+        if(yearArr.length > 1){
+          // 如果是最后一年,那么就要判断是否到最后一个月
+          if(yearArr.length - 1 === i){
+            let maxMonth = new Date(this.maxDay).getMonth() + 1;
+            let _maxDay = new Date(this.maxDay).getDate() // 最大日期 天数
+            let j = 1
+            while(j <= maxMonth){
+              let monthsDays = this.getLastDay(yearArr[i].year, j); // 获取月份一共有多少天
+              let timestampstr = this.getTimeStamp(yearArr[i].year +"-"+  (j > 9 ? j : '0'+j) + "-" + monthsDays)
+              let timestampstr1 = this.getTimeStamp(yearArr[i].year +"-"+  (j > 9 ? j : '0'+j) + "-01")
+              yearArr[i].months.push({str:j+"月",num:j,endTimeStamp:timestampstr,beginTimeStamp:timestampstr1});// 记录最大最小的时间戳
+              // 如果显示月|天 才用记录天
+              if(!this.IsShowyear){
+                yearArr[i].days[yearArr[i].days.length] = {year: "",month: "",daysArr: {}}
+                yearArr[i].days[yearArr[i].days.length - 1].year = yearArr[i].year    // 赋值年
+                yearArr[i].days[yearArr[i].days.length - 1].month = j;    // 赋值月
+                yearArr[i].days[yearArr[i].days.length - 1].daysArr = []
+                // 如果结束月,不是到本月最后一天,而是截止到最
+                if(j === maxMonth){
+                  monthsDays = _maxDay
+                }
+                for(let k = 1; k <= monthsDays; k++){
+                  timestampstr = this.getTimeStamp(yearArr[i].year +"-"+  (j > 9 ? j : '0'+j) + "-" + (k > 9 ? k : '0'+k))
+                  yearArr[i].days[yearArr[i].days.length - 1].daysArr.push({day: k+"",timestamp:timestampstr});// 赋值天
+                }
+              }
+              j++
+            }
+          }else{
+            if(i === 0){
+              let j = minMonth
+              let _minDay = new Date(this.minDay).getDate() // 最小日期 天数
+
+              while(j <= 12){
+                let monthsDays = this.getLastDay(yearArr[i].year, j); // 获取月份一共有多少天
+                let timestampstr = this.getTimeStamp(yearArr[i].year +"-"+  (j > 9 ? j : '0'+j) + "-" + monthsDays)
+                let timestampstr1 = this.getTimeStamp(yearArr[i].year +"-"+  (j > 9 ? j : '0'+j) + "-01")
+                yearArr[i].months.push({str:j+"月",num:j,endTimeStamp:timestampstr,beginTimeStamp:timestampstr1});// 记录最大最小的时间戳
+                // 如果显示月|天 才用记录天
+                if(!this.IsShowyear){
+                  yearArr[i].days[yearArr[i].days.length] = {year: "",month: "",daysArr: {}}
+                  yearArr[i].days[yearArr[i].days.length - 1].year = yearArr[i].year    // 赋值月
+                  yearArr[i].days[yearArr[i].days.length - 1].month = j     // 赋值月
+                  yearArr[i].days[yearArr[i].days.length - 1].daysArr = []
+                  for(let k = 1; k <= monthsDays; k++){
+                    // 如果开始月,就不从1日开始,而是从最开始的日期那天开始算起
+                    if(k === 1 && j === minMonth){
+                      k = _minDay
+                    }
+                    timestampstr = this.getTimeStamp(yearArr[i].year +"-"+  (j > 9 ? j : '0'+j) + "-" + (k > 9 ? k : '0'+k))
+                    yearArr[i].days[yearArr[i].days.length - 1].daysArr.push({day: k+"",timestamp:timestampstr});// 赋值天
+                  }
+                }
+                j++
+              }
+            }else{
+              let j = 1
+              while(j <= 12){
+                let monthsDays = this.getLastDay(yearArr[i].year, j); // 获取月份一共有多少天
+                let timestampstr = this.getTimeStamp(yearArr[i].year +"-"+  (j > 9 ? j : '0'+j) + "-" + monthsDays)
+                let timestampstr1 = this.getTimeStamp(yearArr[i].year +"-"+  (j > 9 ? j : '0'+j) + "-01")
+                yearArr[i].months.push({str:j+"月",num:j,endTimeStamp:timestampstr,beginTimeStamp:timestampstr1});// 记录最大最小的时间戳
+                // 如果显示月|天 才用记录天
+                if(!this.IsShowyear){
+                  yearArr[i].days[yearArr[i].days.length] = {year: "",month: "",daysArr: {}}
+                  yearArr[i].days[yearArr[i].days.length - 1].year = yearArr[i].year    // 赋值年
+                  yearArr[i].days[yearArr[i].days.length - 1].month = j // 赋值月
+                  yearArr[i].days[yearArr[i].days.length - 1].daysArr = []
+                  for(let k = 1; k <= monthsDays; k++){
+                    timestampstr = this.getTimeStamp(yearArr[i].year +"-"+  (j > 9 ? j : '0'+j) + "-" + (k > 9 ? k : '0'+k))
+                    yearArr[i].days[yearArr[i].days.length - 1].daysArr.push({day: k+"",timestamp:timestampstr});// 赋值天
+                  }
+                }
+                j++
+              }
+            }
+
+          }
+        }else{
+          // 如果只有一年那么没有必要判断是否记录天
+          let maxMonth = new Date(this.maxDay).getMonth() + 1;
+          let _minMonth = minMonth
+          let _minDay = new Date(this.minDay).getDate() // 最小日期 天数
+          let _maxDay = new Date(this.maxDay).getDate() // 最大日期 天数
+          while(_minMonth <= maxMonth){
+            let monthsDays = this.getLastDay(yearArr[i].year, _minMonth); // 获取月份一共有多少天
+            let timestampstr = this.getTimeStamp(yearArr[i].year +"-"+  (_minMonth > 9 ? _minMonth : '0'+_minMonth) + "-" + monthsDays)
+            let timestampstr1 = this.getTimeStamp(yearArr[i].year +"-"+  (_minMonth > 9 ? _minMonth : '0'+_minMonth) + "-01")
+            yearArr[i].months.push({str:_minMonth+"月",num:_minMonth,endTimeStamp:timestampstr,beginTimeStamp:timestampstr1});// 记录最大最小的时间戳
+            yearArr[i].days[yearArr[i].days.length] = {year: "",month: "",daysArr: {}}
+            yearArr[i].days[yearArr[i].days.length - 1].year = yearArr[i].year     // 赋值月
+            yearArr[i].days[yearArr[i].days.length - 1].month = _minMonth    // 赋值月
+            yearArr[i].days[yearArr[i].days.length - 1].daysArr = []
+            // 如果结束月,不是到本月最后一天,而是截止到最
+            if(_minMonth === maxMonth){
+              monthsDays = _maxDay
+            }
+            for(let k = 1; k <= monthsDays; k++){
+              // 如果开始月,就不从1日开始,而是从最开始的日期那天开始算起
+              if(k === 1 && _minMonth === minMonth){
+                k = _minDay
+              }
+              timestampstr = this.getTimeStamp(yearArr[i].year +"-"+  (_minMonth > 9 ? _minMonth : '0'+_minMonth) + "-" + (k > 9 ? k : '0'+k))
+              yearArr[i].days[yearArr[i].days.length - 1].daysArr.push({day: k+"",timestamp:timestampstr});// 赋值天
+            }
+            _minMonth++
+          }
+        }
+      }
+      this.showMonths = yearArr
+
+    },
+
+    // 获取月的最后一天
+    getLastDay(myyear, mymonth){
+      var new_date = new Date(myyear, mymonth, 0);
+      return new_date.getDate();
+    },
+
+    // 获得天数
+    GetNumberOfDays(date1,date2){
+      //date1:开始日期,date2结束日期
+      var a1 = Date.parse(new Date(date1));
+      var a2 = Date.parse(new Date(date2));
+      var day = parseInt((a2-a1)/ 86400000);//核心:时间戳相减,然后除以天数
+      return day
+    },
+    // 时间比较 true 比大
+    compareDate(dateTime1,dateTime2,condition = true)
+    {
+      var formatDate1 = new Date(dateTime1)
+      var formatDate2 = new Date(dateTime2)
+      if(formatDate1 >= formatDate2)
+      {
+        return condition ? dateTime1 : dateTime2
+      }
+      else
+      {
+        return condition ? dateTime2 : dateTime1
+      }
+    },
+    // 获取时间戳
+    getTimeStamp(val){
+      return new Date(val).getTime()
+    },
+}
+}
+
+
+</script>
+
+<style>
+
+/* 单元格padding */
+.barchart .el-table--border th:first-child .cell, .el-table--border td:first-child .cell{
+  padding: 0px;
+}
+.barchart .el-table th > .cell{
+  padding: 0px;
+}
+/* 单元格高度 */
+.barchart .el-table--medium th,.barchart  .el-table--medium td {
+  padding: 0px 0px !important;
+  height: 25px !important;
+}
+.barchart .progressCon{
+  padding: 0;
+  margin: 0;
+  position: relative;
+}
+.barchart .progressUpon{
+  background: rgb(38, 84, 124);
+  height: 1em;
+  /* width: calc(100% + 2px); // +2是因为边框线为2px*/
+  z-index: 2;
+  position: absolute;
+  top: 25%;
+  left:0px
+}
+.barchart .progressDownon{
+  background: rgb(255,209,102);
+  height: 1em;
+  /* width: calc(100% + 2px); // +2是因为边框线为2px*/
+  z-index: 2;
+  position: absolute;
+  top: 25%;
+  left:0px
+}
+</style>

+ 10 - 3
ui/src/views/approve/taskdone/index.vue

@@ -53,7 +53,7 @@
     <process-img v-if="processImgVisible" ref="processImg" @refreshDataList="getList"></process-img>
     <process-img v-if="processImgVisible" ref="processImg" @refreshDataList="getList"></process-img>
     <add-or-update v-if="specDealVisible" ref="specDeal" @refreshDataList="getList"></add-or-update>
     <add-or-update v-if="specDealVisible" ref="specDeal" @refreshDataList="getList"></add-or-update>
     <spec-modify v-if="specModifyDealVisible" ref="specModifyDeal" @refreshDataList="getList"></spec-modify>
     <spec-modify v-if="specModifyDealVisible" ref="specModifyDeal" @refreshDataList="getList"></spec-modify>
-
+    <spec-training-plan v-if="specTrainingPlanVisible" ref="specTrainingPlan" @refreshDataList="getList"></spec-training-plan>
   </div>
   </div>
 </template>
 </template>
 
 
@@ -66,11 +66,11 @@
   import "@riophae/vue-treeselect/dist/vue-treeselect.css";
   import "@riophae/vue-treeselect/dist/vue-treeselect.css";
   import ProcessImg from "../processImg/index";
   import ProcessImg from "../processImg/index";
   import SpecModify from '../approveDetail/specModify-detail';
   import SpecModify from '../approveDetail/specModify-detail';
-
+  import SpecTrainingPlan from '../approveDetail/specTrainingPlan-detaill';
   export default {
   export default {
     name: "Taskdone",
     name: "Taskdone",
     components: {
     components: {
-      Treeselect, AddOrUpdate,ProcessImg,SpecModify
+      Treeselect, AddOrUpdate,ProcessImg,SpecModify,SpecTrainingPlan
     },
     },
     data() {
     data() {
       return {
       return {
@@ -79,6 +79,7 @@
         processImgVisible: false,
         processImgVisible: false,
         specDealVisible: false,
         specDealVisible: false,
         specModifyDealVisible: false,
         specModifyDealVisible: false,
+        specTrainingPlanVisible: false,
         // 选中数组
         // 选中数组
         ids: [],
         ids: [],
         // 非单个禁用
         // 非单个禁用
@@ -184,6 +185,12 @@
             console.log(row.taskName)
             console.log(row.taskName)
             this.$refs.specModifyDeal.init(row.approveSpecModify.id, row.taskId, row.processId,row.taskName)
             this.$refs.specModifyDeal.init(row.approveSpecModify.id, row.taskId, row.processId,row.taskName)
           })
           })
+        }else if (row.processName == "专项培训计划审核"){
+          this.specTrainingPlanVisible = true
+          this.$nextTick(() => {
+            console.log(row.taskName)
+            this.$refs.specTrainingPlan.init(row.approveObject.id, row.taskId, row.processId,row.taskName)
+          })
         }else {
         }else {
           this.approveInfo = row;
           this.approveInfo = row;
           this.infoTaskName = row.taskName;
           this.infoTaskName = row.taskName;