Table:

<template>
  <div class="as-details-section">
    <span class="title">任务分解表</span>
    <div class="as-detail-list">
      <el-table
        :data="tableData"
        :row-key="getRowKeys"
        border
        style="width: 100%">
        <el-table-column
          prop="stageName"
          label="阶段"
          width="120">
        </el-table-column>
        <el-table-column
          prop="taskName"
          label="任务"
          width="190">
        </el-table-column>
        <el-table-column
          prop="planStartTime"
          label="计划开始时间"
          className="editable"
          width="120">
          <template slot-scope="{ row, column, $index }">
            <table-date-picker
              v-if="row.isTask && !row.isDisabled"
              v-model="row.planStartTime"
              :valueValid="row.planStartTimeValid"
              :valueEmpty="row.planStartTimeEmpty"
              @change="change(row, column, $index)"
              @blur="onBlur(row, column)">
            </table-date-picker>
            <span v-else class="cell-value">{{row.planStartTime | dateFormat}}</span>
          </template>
        </el-table-column>
        <el-table-column
          prop="planEndTime"
          label="计划结束时间"
          className="editable"
          width="120">
          <template slot-scope="{ row, column, $index }">
            <table-date-picker
              v-if="row.isTask && !row.isDisabled"
              v-model="row.planEndTime"
              :valueValid="row.planEndTimeValid"
              :valueEmpty="row.planEndTimeEmpty"
              isEndDate
              @change="change(row, column, $index)"
              @blur="onBlur(row, column)">
            </table-date-picker>
            <span v-else class="cell-value">{{row.planEndTime | dateFormat}}</span>
          </template>
        </el-table-column>
        <el-table-column
          prop="actualStartTime"
          label="实际开始"
          className="editable"
          width="120">
          <template slot-scope="{ row, column, $index }">
            <table-date-picker
              v-if="row.isTask && !row.isDisabled"
              v-model="row.actualStartTime"
              :valueValid="row.actualStartTimeValid"
              :valueEmpty="row.actualStartTimeEmpty"
              :disabled="row.isActualDisabled"
              :pickerOptions="pickerOptions"
              @change="changeRealDate(row, column, $index)">
            </table-date-picker>
            <span v-else class="cell-value">{{row.actualStartTime | dateFormat}}</span>
          </template>
        </el-table-column>
        <el-table-column
          prop="actualEndTime"
          label="实际结束"
          className="editable"
          width="120">
          <template slot-scope="{ row, column, $index }">
            <table-date-picker
              v-if="row.isTask && !row.isDisabled"
              v-model="row.actualEndTime"
              :valueValid="row.actualEndTimeValid"
              :valueEmpty="row.actualEndTimeEmpty"
              :disabled="row.isActualDisabled"
              :pickerOptions="pickerOptions"
              isEndDate
              @change="changeRealDate(row, column, $index)">
            </table-date-picker>
            <span v-else class="cell-value">{{row.actualEndTime | dateFormat}}</span>
          </template>
        </el-table-column>
        <el-table-column
          prop="projectWbsTaskResourceList"
          label="资源及投入比例"
          min-width="200">
          <template slot-scope="{ row, column, $index }">
            <table-person-picker
              v-if="row.isTask && !row.isDisabled"
              v-model="row.projectWbsTaskResourceList"
              :projectWbsTrackId="row.id"
              :valueEmpty="row.projectWbsTaskResourceListEmpty"
              @change="percentChange(row, column, $index)"
              @blur="onBlur(row, column)"
            ></table-person-picker>
            <span v-else class="cell-value">{{ resourceFormat(row.projectWbsTaskResourceList) }}</span>
          </template>
        </el-table-column>
        <el-table-column
          prop="planWorkHour"
          label="预计工时(天)"
          width="120">
        </el-table-column>
        <el-table-column
          prop="actualWorkHour"
          label="实际工时(天)"
          width="120">
        </el-table-column>
        <el-table-column
          prop="planWorkDay"
          label="预计工期(天)"
          width="120">
        </el-table-column>
        <el-table-column
          prop="actualWorkDay"
          label="实际工期(天)"
          width="120">
        </el-table-column>
      </el-table>
    </div>
    <el-dialog
      title="流转确认"
      :visible.sync="dialogVisible"
      :close-on-click-modal="false"
      width="400px">
      <el-row v-if="!isShowRollback">确认要流转至下一阶段吗?</el-row>
      <el-row v-else>确认要流转至下一阶段吗?</el-row>
      <span slot="footer" class="dialog-footer">
        <el-button v-if="!isShowRollback" @click="dialogVisible = false">取 消</el-button>
        <el-button v-if="isShowRollback" @click="promoteProject(true)">回滚至2分</el-button>
        <el-button type="primary" @click="promoteProject()">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

TablePersonPicker:

<template>
  <div class="table-date-picker">
    <div class="cell-content-wrap">
      <span class="cell-content">{{displayValue}}</span>
      <i
        class="el-icon-edit-outline"
        style="float: right"
      ></i>
    </div>
  </div>
</template>

<script>
import TablePersonPickerDialog from '@/components/projectManagement/TablePersonPickerDialog'

export default {
  name: 'TablePersonPicker',
  model: {
    prop: 'value',
    event: 'change'
  },
  props: {
    value: {
      type: Array,
      default() {
        return [];
      }
    },
    valueValid: {
      type: Boolean,
      default() {
        return true;
      }
    },
    valueEmpty: {
      type: Boolean,
      default() {
        return false;
      }
    },
    disabled: {
      type: Boolean,
      default() {
        return false;
      }
    },
    projectWbsTrackId: {
      type: String,
      default() {
        return null;
      }
    }
  },
  data() {
    return {
      newValue: [],
      displayValue: '',
      pencentArr: []
    };
  },
  mounted() {
    // 点击表格td,编辑状态,输入框获取焦点
    this.$el.parentNode.parentNode.onclick = () => {
      if (!this.disabled) {
        this.showDialog();
      }
    }
  },
  methods: {
    showDialog() {
      this.$utils.create(TablePersonPickerDialog, {
        context: this,
        keyName: this.id,
        deliveryDept: this.options,
        value: this.value
      });
    },
    confirm(data) {
      this.pencentArr = data;
      this.displayValue = this.formatDisaplyValue();
      this.$emit('change', this.pencentArr);
    },
    getItemById(personId) {
      let item = null;
      // 新增人员
      for (const obj of this.data) {
        if (obj.personId === personId) {
          item = obj;
          break;
        }
      }
      return item;
    },
    formatDisaplyValue() {
      const displayArr = [];
      for (const item of this.pencentArr) {
        displayArr.push(`${item.personLabel}(${item.inputPercentage}%)`)
      }
      return displayArr.join(',');
    },
    formatOptions() {
      const optons = [];
      let option = null;
      for (const item of this.$store.state.DICT_DATA.delivery_dept) {
        option = {
          id: item.dictValue,
          personLabel: item.dictName,
          disabled: true
        };
        optons.push(option);
      }
      return optons;
    }
  },
  created() {
    this.options = this.formatOptions();
    let template = null;
    for (const item of this.value) {
      this.newValue.push(item.personId);
      template = {
        personId: item.personId,
        projectWbsTrackId: this.projectWbsTrackId,
        inputPercentage: item.inputPercentage,
        personLabel: item.personLabel
      };
      this.pencentArr.push(template);
    }
    this.displayValue = this.formatDisaplyValue();
  },
  watch: {
    valueEmpty() {
      if (this.valueEmpty) {
        this.$el.parentNode.parentNode.style.background = '#FEF0F0';
      } else {
        this.$el.parentNode.parentNode.style.background = 'none';
      }
    },
    valueValid() {
      if (!this.valueValid) {
        this.$el.parentNode.parentNode.style.background = '#FEF0F0';
      } else {
        this.$el.parentNode.parentNode.style.background = 'none';
      }
    }
  }
};
</script>
<style scoped lang="scss">
.table-date-picker {
  display: flex;
  flex-flow: row;
  align-items: center;
  .cell-content-wrap {
      display: flex;
      flex-flow: row;
      align-items: center;
      i {
        color: #20a0ff;
        margin-left: 8px;
        cursor: pointer;
      }
  }
  .cell-content {
    padding: 0 8px;
    flex: 1;
  }
}
</style>

输入校验:


    /**
     * 表格预计开始时间和预计结束时间注册事件
     */
    change(row, column, $index) {
      const { property } = column;
      const value = row[property];
      if ((!value || value === '') && value !== 0) {
        row[`${property}Empty`] = true;
      } else {
        row[`${property}Empty`] = false;
        // 时间发生变化,往下开始计算时间
        this.calculatePlanDate(row, column, $index);
        // 计算预计工时和预计工期
        this.caculatePlanData();
        // 任务预计开始时间小于任务结束时间
        const isValid = this.validateDate(row.planStartTime, row.planEndTime);
        if (!isValid) {
          this.$message.error('预计结束时间必须大于等于预计开始时间!');
        }
        // 任务的预计开始时间大于上一个阶段的结束时间
        const isStartDateValid = this.validateTaskStartDate(row, property, $index);
        if (!isStartDateValid) {
          this.$message.error('任务的预计开始时间和预计结束时间必须大于上一个阶段的预计结束时间');
        }
        if (isValid && isStartDateValid) {
          row[`${property}Valid`] = true;
        } else {
          row[`${property}Valid`] = false;
        }
        this.$set(this.tableData, $index, Object.assign({}, row));
      }
    },

效果图:

 

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐