| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671 |
- <template>
- <div>
- <el-form ref="form" :model="form">
- <el-button
- v-if="dialogType !== 'view'"
- type="primary"
- icon="el-icon-plus"
- class="ele-btn-icon"
- style="margin-bottom: 5px"
- @click="handleAddInfo"
- >
- 新增项目阶段
- </el-button>
- <el-button
- v-if="dialogType !== 'view'"
- type="primary"
- class="ele-btn-icon"
- style="margin-bottom: 5px"
- @click="save"
- >
- 保存
- </el-button>
- <el-button
- v-if="dialogType !== 'view'"
- type="primary"
- class="ele-btn-icon"
- style="margin-bottom: 5px"
- @click="updateFn"
- >
- 确认修改
- </el-button>
- <!-- 数据表格 -->
- <ele-pro-table
- ref="table"
- :columns="columns"
- :datasource="form.datasource"
- :needPage="false"
- :toolkit="[]"
- :minHeight="100"
- tool-class="ele-toolbar-form"
- >
- <template v-slot:action="{ row, $index }">
- <el-popconfirm
- class="ele-action"
- title="确定要删除此信息吗?"
- @confirm="handleDelInfo(row, $index)"
- >
- <template v-slot:reference>
- <el-link type="danger" :underline="false" icon="el-icon-delete">
- 删除
- </el-link>
- </template>
- </el-popconfirm>
- <el-link
- v-if="row.id"
- type="primary"
- :underline="false"
- icon="el-icon-edit"
- @click="editFn(row, $index)"
- >
- 修改
- </el-link>
- </template>
- <template v-slot:name="{ row, $index }" v-if="dialogType !== 'view'">
- <el-form-item
- :prop="'datasource.' + $index + '.name'"
- :rules="{
- required: true,
- message: '请选择',
- trigger: ['blur', 'change']
- }"
- >
- <el-input
- v-model="row.name"
- clearable
- :disabled="row.isEdit"
- ></el-input>
- </el-form-item>
- </template>
- <template v-slot:content="{ row, $index }" v-if="dialogType !== 'view'">
- <el-form-item :prop="'datasource.' + $index + '.content'">
- <el-input v-model="row.content" clearable></el-input>
- </el-form-item>
- </template>
- <template
- v-slot:planStartDate="{ row, $index }"
- v-if="dialogType !== 'view'"
- >
- <el-form-item
- :prop="'datasource.' + $index + '.planStartDate'"
- :rules="{
- required: true,
- message: '请选择',
- trigger: ['blur', 'change']
- }"
- >
- <el-date-picker
- style="width: 100%"
- :disabled="row.isEdit || dialogType == 'view'"
- v-model="row.planStartDate"
- :picker-options="{
- disabledDate: (time) => {
- return (
- row.isEdit &&
- row.planEndDate &&
- time.getTime() > new Date(row.planEndDate)
- );
- }
- }"
- type="date"
- placeholder="选择日期"
- >
- </el-date-picker>
- </el-form-item>
- </template>
- <template
- v-slot:planEndDate="{ row, $index }"
- v-if="dialogType !== 'view'"
- >
- <el-form-item
- :prop="'datasource.' + $index + '.planEndDate'"
- :rules="{
- required: true,
- message: '请选择',
- trigger: ['blur', 'change']
- }"
- >
- <el-date-picker
- style="width: 100%"
- :disabled="row.isEdit || dialogType == 'view'"
- :picker-options="{
- disabledDate: (time) => {
- return (
- row.planStartDate &&
- time.getTime() < new Date(row.planStartDate)
- );
- }
- }"
- v-model="row.planEndDate"
- type="date"
- placeholder="选择日期"
- >
- </el-date-picker>
- </el-form-item>
- </template>
- <template
- v-slot:responsibleUserId="{ row, $index }"
- v-if="dialogType !== 'view'"
- >
- <el-form-item :prop="'datasource.' + $index + '.responsibleUserId'">
- <el-select
- v-model="row.responsibleUserId"
- collapse-tags
- filterable
- placeholder="请选择"
- style="width: 100%"
- clearable
- size="medium"
- :disabled="row.isEdit || dialogType == 'view'"
- @change="(val) => personChange(val, $index)"
- >
- <el-option
- v-for="item in userList"
- :key="item.id"
- :label="item.name"
- :value="item.id"
- >
- </el-option>
- </el-select>
- </el-form-item>
- </template>
- <template
- v-slot:responsibleDeptId="{ row, $index }"
- v-if="dialogType !== 'view'"
- >
- <el-form-item :prop="'datasource.' + $index + '.responsibleDeptId'">
- <ele-tree-select
- :disabled="dialogType == 'view'"
- clearable
- :data="deptTreeList"
- :ref="'deptTreeRef' + $index"
- v-model="row.responsibleDeptId"
- valueKey="id"
- labelKey="name"
- placeholder="请选择"
- @change="(id) => changeDeptInfo(id, $index)"
- default-expand-all
- />
- </el-form-item>
- </template>
- <template
- v-slot:isMilepost="{ row, $index }"
- v-if="dialogType !== 'view'"
- >
- <el-form-item>
- <el-select v-model="row.isMilepost">
- <el-option label="否" :value="0" />
- <el-option label="是" :value="1" />
- </el-select>
- </el-form-item>
- </template>
- <template
- v-slot:milepost="{ row, $index }"
- v-if="dialogType !== 'view'"
- >
- <el-form-item>
- <el-input v-model="row.milepost" clearable></el-input>
- </el-form-item>
- </template>
- <template v-slot:isOverTime="{ row }">
- <el-tag v-if="row.isOverTime == 0" type="success">正常</el-tag>
- <el-tag v-else type="danger">超时</el-tag>
- </template>
- <template v-slot:proportion="{ row }">
- <el-input
- type="number"
- :min="0"
- :max="100"
- v-model="row.proportion"
- :disabled="dialogType == 'view'"
- >
- </el-input>
- </template>
- <template v-slot:speedPercent="{ row }">
- <el-progress
- :stroke-width="20"
- text-color="#606266"
- :text-inside="true"
- :percentage="row.speedPercent || 0"
- :color="customColorMethod"
- ></el-progress>
- </template>
- <template v-slot:remark="{ row, $index }" v-if="dialogType !== 'view'">
- <el-form-item>
- <el-input
- type="textarea"
- v-model="row.remark"
- clearable
- :disabled="row.isEdit"
- ></el-input>
- </el-form-item>
- </template>
- <template v-slot:headerRequired="{ column }">
- <span class="is-required">{{ column.label }}</span>
- </template>
- </ele-pro-table>
- </el-form>
- </div>
- </template>
- <script>
- import { mapGetters } from 'vuex';
- import { getByCode } from '@/api/system/dictionary-data';
- import fileUpload from '@/components/upload/fileUpload.vue';
- import { getFile } from '@/api/system/file';
- import PersonSelect from '@/components/CommomSelect/person-select.vue';
- import { proStatusEnum } from '@/enum/dict';
- import { listOrganizations } from '@/api/system/organization';
- // import { deepClone } from '@/utils';
- import { deepClone } from '@/components/FormGenerator/utils/index';
- import {
- projectsstageSave,
- projectsstageSaveBatch,
- projectsGetByIdDetailsAPI,
- projectsStageUpdateAPI,
- projectsStageDeleteAPI
- } from '@/api/project-manage';
- export default {
- name: 'stageInfoTable',
- components: {
- PersonSelect,
- fileUpload
- },
- props: {
- responsibleDeptId: {
- type: String
- },
- dialogForm: {
- type: Object,
- default: () => {
- return {
- ...this.form
- };
- }
- },
- dialogType: {
- type: String,
- default: ''
- },
- deptList: {
- type: Array,
- default: () => {
- return [];
- }
- },
- userList: {
- type: Array,
- default: () => {
- return [];
- }
- },
- deptTreeList: {
- type: Array,
- default: () => {
- return [];
- }
- }
- },
- watch: {
- userList: {
- handler(val) {
- console.log(val);
- },
- deep: true
- },
- dialogForm: {
- handler(val) {
- this.form.datasource = deepClone(this.dialogForm.stageList) || [];
- this.form.datasource.forEach((item) => {
- this.$set(item, 'isEdit', true);
- });
- this.$nextTick(async () => {
- if (this.dialogType === 'view') return;
- this.form.datasource.forEach((item) => {
- this.$set(item, 'isEdit', true);
- });
- });
- },
- deep: true
- },
- deptList: {
- handler(newValue, oldValue) {
- console.log('bianhua');
- console.log(newValue, oldValue);
- },
- deep: true
- }
- },
- data() {
- return {
- editIndex: undefined, //当前修改数据的下标
- form: {
- datasource: []
- },
- responceUserList: [],
- addFlag: false
- };
- },
- computed: {
- columns() {
- let list = [
- {
- columnKey: 'index',
- label: '序号',
- type: 'index',
- width: 55,
- align: 'center',
- showOverflowTooltip: true,
- fixed: 'left'
- },
- {
- prop: 'name',
- label: '阶段名称',
- align: 'center',
- showOverflowTooltip: true,
- minWidth: 120,
- slot: 'name',
- headerSlot: 'headerRequired'
- },
- // {
- // prop: 'responsibleDeptName',
- // label: '负责部门',
- // align: 'center',
- // showOverflowTooltip: true,
- // minWidth: 130,
- // slot: 'responsibleDeptId',
- // headerSlot: 'headerRequired',
- // },
- {
- prop: 'responsibleUserNames',
- label: '负责人',
- align: 'center',
- showOverflowTooltip: true,
- minWidth: 200,
- slot: 'responsibleUserId',
- headerSlot: 'headerRequired'
- },
- {
- prop: 'planStartDate',
- label: '开始时间',
- align: 'center',
- showOverflowTooltip: true,
- minWidth: 170,
- slot: 'planStartDate',
- headerSlot: 'headerRequired'
- },
- {
- prop: 'planEndDate',
- label: '结束时间',
- align: 'center',
- showOverflowTooltip: true,
- minWidth: 170,
- slot: 'planEndDate',
- headerSlot: 'headerRequired'
- },
- {
- prop: 'realStartTime',
- label: '实际开始时间',
- align: 'center',
- showOverflowTooltip: true,
- minWidth: 170
- },
- {
- prop: 'realEndTime',
- label: '实际结束时间',
- align: 'center',
- showOverflowTooltip: true,
- minWidth: 170
- },
- {
- prop: 'remark',
- label: '备注',
- align: 'center',
- showOverflowTooltip: true,
- minWidth: 160,
- slot: 'remark'
- },
- {
- prop: 'isOverTime',
- label: '是否超时',
- align: 'center',
- showOverflowTooltip: true,
- minWidth: 100,
- slot: 'isOverTime'
- },
- // {
- // prop: 'proportion',
- // label: '权重占比(%)',
- // align: 'center',
- // showOverflowTooltip: true,
- // minWidth: 110,
- // slot: 'proportion'
- // },
- {
- prop: 'speedPercent',
- label: '进度',
- align: 'center',
- showOverflowTooltip: true,
- minWidth: 150,
- slot: 'speedPercent'
- },
- {
- prop: 'status',
- label: '状态',
- align: 'center',
- showOverflowTooltip: true,
- minWidth: 130,
- formatter: (_row, _column, cellValue) => {
- return proStatusEnum[cellValue].label;
- }
- }
- ];
- let action = [
- {
- columnKey: 'action',
- slot: 'action',
- label: '操作',
- resizable: false,
- minWidth: 180,
- align: 'center',
- showOverflowTooltip: true,
- fixed: 'right'
- }
- ];
- this.dialogType === 'view'
- ? (list = [...list])
- : (list = [...list, ...action]);
- return list;
- }
- },
- methods: {
- // 选择负责人部门
- changeDeptInfo(id, index) {
- console.log(id, index);
- const info = this.deptList.find((e) => e.id == id) || {};
- this.$set(
- this.form.datasource[index],
- 'responsibleDeptName',
- info.name
- );
- this.$set(this.form.datasource[index], 'responsibleUserId', '');
- this.$set(this.form.datasource[index], 'responsibleUserName', '');
- // this.getUserList(id, index);
- },
- // 获取人员数据
- getUserList(groupId, index) {
- // if (groupId) {
- // this.$refs['directorRef' + index].getList({groupId});
- // }
- },
- personChange(val, index) {
- const info = this.userList.find((e) => e.id == val) || {};
- console.log(val, info, index);
- console.log(this.dialogForm);
- this.$set(
- this.form.datasource[index],
- 'responsibleUserName',
- info.name
- );
- // this.$set(
- // this.form.datasource[index],
- // 'responsibleDeptName',
- // this.dialogForm.responsibleDeptName
- // );
- },
- // personChange(val, index) {
- //
- // // this.$set(this.form.datasource[index], 'responsibleUserName', info.name);
- // },
- downloadFile(file) {
- getFile({ objectName: file.storePath }, file.name);
- },
- //新增计划数据
- handleAddInfo() {
- this.addFlag = true;
- this.$nextTick(() => {
- this.form.datasource.push({
- projectId: localStorage.getItem('projectId'),
- milepost: '',
- isMilepost: 0,
- responsibleUserList: [],
- responsibleUserId: '',
- responsibleDeptId: this.responsibleDeptId,
- responsibleDeptName: this.dialogForm.responsibleDeptName,
- planStartDate: '',
- planEndDate: '',
- name: '',
- content: '',
- status: 0,
- isOverTime: 0,
- speedPercent: 0,
- remark: ''
- });
- console.log(this.form.datasource);
- });
- },
- //
- clearData() {
- this.form.datasource.forEach((item, index) => {
- this.$set(this.form.datasource[index], 'milepost', '');
- this.$set(this.form.datasource[index], 'isMilepost', 0);
- this.$set(this.form.datasource[index], 'isOverTime', 0);
- this.$set(this.form.datasource[index], 'speedPercent', 0);
- this.$set(this.form.datasource[index], 'responsibleUserId', '');
- this.$set(this.form.datasource[index], 'responsibleUserName', '');
- this.$set(this.form.datasource[index], 'responsibleDeptId', '');
- this.$set(this.form.datasource[index], 'responsibleDeptName', '');
- this.$set(this.form.datasource[index], 'planStartDate', '');
- this.$set(this.form.datasource[index], 'planEndDate', '');
- this.$set(this.form.datasource[index], 'name', '');
- this.$set(this.form.datasource[index], 'content', '');
- });
- },
- //删除关联信息数据
- async handleDelInfo(row, index) {
- if (!row.id) {
- this.form.datasource.splice(index, 1);
- return;
- }
- const res = await projectsStageDeleteAPI([row.id]);
- this.init();
- },
- customColorMethod(percentage) {
- if (percentage < 30) {
- return '#909399';
- } else if (percentage < 70) {
- return '#e6a23c';
- } else {
- return '#67c23a';
- }
- },
- async save() {
- let form = await this.getTableValidate();
- let saveForm = form.filter((item) => !item.id);
- console.log(form);
- const res = await projectsstageSaveBatch(saveForm);
- if (res) {
- this.init();
- }
- },
- getTableValidate() {
- return new Promise((resolve, reject) => {
- // if (this.form.datasource.length == 0) return this.$message.warning('')
- this.$refs.form.validate((valid) => {
- if (!valid) {
- this.$message.warning('有必填项未填,请检查');
- reject('有必填项未填,请检查');
- } else {
- resolve(this.form.datasource);
- }
- });
- });
- },
- init() {
- this.$nextTick(async () => {
- const res = await projectsGetByIdDetailsAPI(
- localStorage.getItem('projectId')
- );
- console.log(res);
- this.form.datasource = res.allStageList || [];
- this.form.datasource.forEach((item) => {
- this.$set(item, 'isEdit', true);
- });
- console.log(this.form);
- });
- // projectsGetByIdDetailsAPI
- // this.form.datasource=
- },
- editFn(row, index) {
- console.log('xiugai', index, this.form.datasource);
- this.$nextTick(() => {
- this.$set(this.form.datasource[index], 'isEdit', false);
- });
- },
- async updateFn() {
- let form = await this.getTableValidate();
- let findItem = form.find((item) => !item.id);
- console.log(findItem);
- if (findItem) {
- this.$message('请先保存新增的数据');
- return;
- }
- let updateForm = form.filter((item) => !item.isEdit);
- console.log(updateForm);
- // const res = await projectsStageUpdateAPI(updateForm[0]);
- for (const item of updateForm) {
- await projectsStageUpdateAPI(item);
- }
- this.init();
- // const res = await projectsStageUpdateAPI(saveForm);
- // if (res) {
- // this.init();
- // }
- }
- },
- created() {
- this.init();
- }
- };
- </script>
- <style scoped lang="scss">
- :deep(.el-form-item) {
- margin-bottom: 0;
- }
- </style>
|