赞
踩
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));
- }
- },

效果图:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。