中航光电热表web
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

670 lines
25 KiB

<template>
<el-dialog :append-to-body="false" :title="title" :model-value="openShow" width="80%" @close="handleClose" fullscreen>
<!-- 单个 Form 包裹所有内容基础信息 + 表格 -->
<el-form ref="addForm" :model="addForm" :rules="addRules" label-width="100px" label-position="right">
<!-- 项目基础信息表单 -->
<el-row>
<el-col :span="8">
<el-form-item label="项目名称:" prop="projectName">
<el-input :disabled="isDetail" v-model="addForm.projectName"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="项目类型:" prop="bcId">
<el-select :disabled="isDetail" v-model="addForm.bcId" clearable filterable>
<el-option v-for="(item, index) in projectType" :key="index" :label="item.dictValue"
:value="item.dictKey"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="制单部门:" prop="touchingDeptId">
<el-select :disabled="isDetail" v-model="addForm.touchingDeptId" clearable filterable
@change="deptChange()">
<el-option v-for="(item, index) in deplList" :key="index" :label="item.deptName"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="项目背景:" prop="projectBackcloth">
<el-input :disabled="isDetail" type="textarea" v-model="addForm.projectBackcloth"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="项目目标:" prop="projectTarget">
<el-input :disabled="isDetail" type="textarea" v-model="addForm.projectTarget"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="预期效果:" prop="desiredResult">
<el-input :disabled="isDetail" type="textarea" v-model="addForm.desiredResult"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="项目负责人:" prop="projectHeadId">
<jhSelect v-model="addForm.projectHeadId" placeholder="请搜索选择" api-url="/blade-system/user/page"
echo-api="/blade-system/user/page" echoParamsKey="ids" echo-method="get" api-method="get"
list-key="records" total-key="total" label-key="realName" value-key="id" search-key="realName"
:debounce-time="500" @change="projectHeadChange" :title="title" :disabled="isDetail" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="成员名称:" prop="memberName">
<jhSelect v-model="addForm.memberName" placeholder="请搜索选择" api-url="/blade-system/user/page"
echo-api="/blade-system/user/page" echoParamsKey="ids" api-method="get" list-key="records"
total-key="total" label-key="realName" value-key="id" search-key="realName" multiple :debounce-time="500"
:title="title" :disabled="isDetail" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="项目支持人:" prop="projectSupportMan">
<jhSelect v-model="addForm.projectSupportMan" placeholder="请搜索选择" api-url="/blade-system/user/page"
echo-api="/blade-system/user/page" echoParamsKey="ids" api-method="get" list-key="records"
total-key="total" label-key="realName" value-key="id" search-key="realName" :debounce-time="500"
:title="title" :disabled="isDetail" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="项目开始时间:" prop="projectStartTime" label-width="110px">
<el-date-picker :disabled="isDetail" style="width: 100%" v-model="addForm.projectStartTime" type="date"
placeholder="选择日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="项目结束预期时间:" prop="projectDesiredEnd" label-width="130px">
<el-date-picker :disabled="isDetail" style="width: 100%" v-model="addForm.projectDesiredEnd" type="date"
placeholder="选择日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD"></el-date-picker>
</el-form-item>
</el-col>
</el-row>
<!-- 里程碑表格操作 -->
<div style="margin: 10px 0" v-if="!isDetail">
<el-button type="primary" @click="handleOpenDialog">插入一行</el-button>
<el-button type="danger" @click="delTable">删除选中行</el-button>
</div>
<!-- 全局错误提示 -->
<div v-if="formError" class="error-message" style="color: #f56c6c; margin-bottom: 10px">
{{ formError }}
</div>
<!-- 里程碑表格 -->
<el-table :data="addForm.stoneList" ref="detailTable" border @select="selectChange" class="table_project"
:cell-class-name="tableCellClassName">
<el-table-column type="selection"></el-table-column>
<el-table-column prop="paIndex" width="80" label="序号"></el-table-column>
<el-table-column align="center" :width="isDetail || isStatusEdit ? '120' : ''" label="里程碑计划">
<template #header>
<span><i style="color: red">*</i>里程碑计划</span>
</template>
<template #default="scope">
<template v-if="!isDetail">
<el-form-item label-width="0" :prop="`stoneList[${scope.$index}].milestonePlan`"
:rules="addRules.milestonePlan">
<el-input v-model="scope.row.milestonePlan" placeholder="请输入里程碑计划"></el-input>
</el-form-item>
</template>
<template v-else>
<span>{{ scope.row.milestonePlan }}</span>
</template>
</template>
</el-table-column>
<el-table-column align="center" :width="isDetail || isStatusEdit ? '120' : ''" label="里程碑负责人"
prop="milestoneManId">
<template #header>
<span><i style="color: red">*</i>里程碑负责人</span>
</template>
<template #default="scope">
<template v-if="!isDetail">
<el-form-item label-width="0" :prop="`stoneList[${scope.$index}].milestoneManId`"
:rules="addRules.milestoneManId">
<jhSelect v-model="scope.row.milestoneManId" placeholder="请搜索选择" api-url="/blade-system/user/page"
echo-api="/blade-system/user/page" echoParamsKey="ids" api-method="get" list-key="records"
total-key="total" label-key="realName" value-key="id" search-key="realName" :debounce-time="500"
@change="(val, item) => handleStoneListChange(val, item, scope.$index, scope.row)" :title="title"
:disabled="isDetail" />
</el-form-item>
</template>
<template v-else>
<span>{{ scope.row.milestoneMan }}</span>
</template>
</template>
</el-table-column>
<el-table-column align="center" :width="isDetail || isStatusEdit ? '120' : ''" label="里程碑输出物"
prop="outputMaterial">
<template #header>
<span><i style="color: red">*</i>里程碑输出物</span>
</template>
<template #default="scope">
<template v-if="!isDetail">
<el-form-item label-width="0" :prop="`stoneList[${scope.$index}].outputMaterial`"
:rules="addRules.outputMaterial">
<el-input v-model="scope.row.outputMaterial" placeholder="请输入里程碑输出物"></el-input>
</el-form-item>
</template>
<template v-else>
<span>{{ scope.row.outputMaterial }}</span>
</template>
</template>
</el-table-column>
<el-table-column align="center" :width="isDetail || isStatusEdit ? '180' : ''" label="里程碑节点"
prop="milestoneNode">
<template #header>
<span><i style="color: red">*</i>里程碑节点</span>
</template>
<template #default="scope">
<template v-if="!isDetail">
<el-form-item label-width="0" :prop="`stoneList[${scope.$index}].milestoneNode`"
:rules="addRules.milestoneNode">
<el-date-picker v-model="scope.row.milestoneNode" type="date" placeholder="选择日期时间" style="width: 100%"
format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
</el-form-item>
</template>
<template v-else>
<span>{{ scope.row.milestoneNode ? scope.row.milestoneNode.substring(0, 10) : '' }}</span>
</template>
</template>
</el-table-column>
<!-- 详情页专属列 -->
<el-table-column v-if="isDetail || isStatusEdit" align="center" label="执行类型" prop="executeType"
:width="isDetail ? '120' : ''">
<template #default="scope">
{{ executeTypeFn(scope.row.executeType) }}
</template>
</el-table-column>
<el-table-column v-if="isDetail || isStatusEdit" align="center" label="延期时间" prop="delayTime"
:width="isDetail || isStatusEdit ? '120' : ''">
<template #default="scope">
{{ scope.row.delayTime ? scope.row.delayTime.substring(0, 10) : '' }}
</template>
</el-table-column>
<el-table-column v-if="isDetail || isStatusEdit" align="center" label="核查结果" prop="checkResult"
:width="isDetail || isStatusEdit ? '120' : ''">
<template #default="scope">
<div v-if="scope.row.executeType == '3'">
<span v-if="scope.row.checkResult === 0">未核查</span>
<span v-else-if="scope.row.checkResult === 1">已核查</span>
<span v-else-if="scope.row.checkResult === 2">已核准</span>
</div>
<div v-else>-</div>
</template>
</el-table-column>
<el-table-column v-if="isDetail || isStatusEdit" align="center" label="核查人" prop="checkMan"
:width="isDetail || isStatusEdit ? '120' : ''"></el-table-column>
<el-table-column v-if="isDetail || isStatusEdit" align="center" label="评价等级" prop="gradeTitle"
:width="isDetail || isStatusEdit ? '120' : ''">
</el-table-column>
<el-table-column v-if="isDetail || isStatusEdit" align="center" label="评价人" prop="gradeMan"
:width="isDetail || isStatusEdit ? '120' : ''">
<template #default="scope">
{{ scope.row.gradeTitle == '待评价' ? '' : scope.row.gradeMan }}
</template>
</el-table-column>
<el-table-column v-if="isDetail || isStatusEdit" width="200" align="center" label="业务领导评价" prop="evaluate"
:width="isDetail || isStatusEdit ? '120' : ''"></el-table-column>
<el-table-column v-if="isDetail || isStatusEdit" align="center" label="附件"
:width="isDetail || isStatusEdit ? '120' : ''">
<template #default="scope">
<el-button type="text" v-if="scope.row.attachList.length > 0"
@click="attachListDown(scope.row)">附件</el-button>
</template>
</el-table-column>
</el-table>
</el-form>
<!-- 弹窗底部按钮 -->
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose" :loading="loadingShow">取 消</el-button>
<el-button v-if="title != '详情'" type="primary" @click="handleSubmitForm" :loading="loadingShow"> </el-button>
</span>
</template>
</el-dialog>
</template>
<script>
import {
addProcess,
getProcessDetail,
getDeplList,
updateProcess,
} from '@/api/flowManagement/index';
import { getRoleUserList } from '@/api/processManagement/taskDispatch';
import { getDictionary } from '@/api/system/dict';
import jhSelect from '@/components/jh-select/index.vue';
export default {
name: 'AddDialog',
components: { jhSelect },
props: {
title: {
type: String,
required: true,
default: '',
},
visible: {
type: Boolean,
required: true,
default: false,
},
rowItem: {
type: Object,
required: true,
default: () => ({}),
},
},
data() {
return {
loadingShow: false,
formError: '',
addRules: {
projectName: [{ required: true, message: '请填写项目名称', trigger: ['blur', 'submit'] }],
bcId: [{ required: true, message: '请选择项目类型', trigger: ['change', 'submit'] }],
touchingDept: [
{ required: true, message: '请选择制单部门', trigger: ['change', 'submit'] },
],
projectBackcloth: [
{ required: true, message: '请填写项目背景', trigger: ['blur', 'submit'] },
],
projectTarget: [{ required: true, message: '请填写项目目标', trigger: ['blur', 'submit'] }],
desiredResult: [{ required: true, message: '请填写预期效果', trigger: ['blur', 'submit'] }],
projectHeadId: [
{ required: true, message: '请选择项目负责人', trigger: ['change', 'submit'] },
],
memberName: [{ required: true, message: '请选择成员名称', trigger: ['change', 'submit'] }],
projectSupportMan: [
{ required: true, message: '请选择项目支持人', trigger: ['change', 'submit'] },
],
projectStartTime: [
{ required: true, message: '请选择项目开始时间', trigger: ['change', 'submit'] },
],
projectDesiredEnd: [
{ required: true, message: '请选择项目结束预期时间', trigger: ['change', 'submit'] },
],
stoneList: [
{
required: true,
message: '请至少添加一行里程碑数据',
trigger: 'submit',
type: 'array',
},
{
validator: (rule, value, callback) => {
if (value.length === 0) {
callback(new Error('请至少添加一行里程碑数据'));
} else {
callback();
}
},
trigger: 'submit',
},
],
// 里程碑数组项字段校验
milestonePlan: [
{ required: true, message: '请填写里程碑计划', trigger: ['blur', 'submit'] },
],
milestoneManId: [
{ required: true, message: '请选择里程碑负责人', trigger: ['change', 'submit'] },
],
outputMaterial: [
{ required: true, message: '请输入里程碑输出物', trigger: ['blur', 'submit'] },
],
milestoneNode: [
{ required: true, message: '请选择里程碑节点', trigger: ['change', 'submit'] },
],
},
memberList: [], //人员列表
projectType: [], //项目类型
deplList: [], //部门列表
openShow: false,
addForm: {
stoneList: [],
projectHeadId: null,
},
executeResultList: [], // 执行类型
};
},
computed: {
// 判断是否为详情页
isDetail() {
return this.title === '详情';
},
// 判断是否是审批之后和已完成之前的修改
isStatusEdit() {
return this.rowItem.approvalStatus != 8 && this.rowItem.approvalStatus != 1 && this.rowItem.approvalStatus != 2 && this.title == '修改';
},
},
mounted() {
this.openShow = this.visible;
this.getDeplLists();
this.getDictionary();
if (this.title === '详情' || this.title === '修改') {
this.getDetails();
this.getExecuteResultList();
}
},
methods: {
attachListDown(row) {
window.open(row.attachList[0]);
},
// 动态添加类名
tableCellClassName({ row, column, rowIndex, columnIndex }) {
if (row.checkResult == 1 || row.checkResult == 2) {
return 'highlight-row';
}
return '';
},
executeTypeFn(type) {
const item = this.executeResultList.find(item => item.dictKey === type);
return item ? item.dictValue : '';
},
getExecuteTypeText(type) {
const item = this.executeResultList.find(item => item.dictKey === type);
return item ? item.dictValue : '';
},
handleStoneListChange(val, item, index, row) {
if (item) {
// 假设你需要将姓名存到 milestoneMan 字段用于提交或展示
// row.milestoneManId =val;
row.milestoneMan = item.realName;
} else {
// 如果 val 为空,说明是清除操作
if (!val) {
row.milestoneMan = '';
}
}
},
// 制单部门名称
deptChange() {
let sel = this.deplList.filter(item => item.id == this.addForm.touchingDeptId)[0];
this.addForm.touchingDept = sel.deptName;
},
// 项目负责人
projectHeadChange(value, item) {
if (item != undefined) {
this.addForm.projectHead = item.realName;
}
},
// 获取部门列表
getDeplLists() {
getDeplList().then(res => {
let data = res.data.data;
data.forEach(item => {
if (item.deptName == '热表分厂') {
console.log(item.children, 'item.deptName');
this.deplList = item.children || [];
}
});
});
},
// 获取项目类型 getDictionary
getDictionary() {
getDictionary({ code: 'flow_project_type' }).then(res => {
this.projectType = res.data.data;
});
},
// 获取执行类型字典
getExecuteResultList() {
getDictionary({ code: 'flow_project_executeResult' }).then(res => {
this.executeResultList = res.data.data;
});
},
// 获取详情数据
getDetails() {
getProcessDetail(this.rowItem.id).then(res => {
this.$nextTick(() => {
let data = res.data.data;
Object.assign(this.addForm, data);
const records = res.data.data;
this.addForm.stoneList = records.stoneList.map(item => {
item.executeTypeText = this.getExecuteTypeText(item.executeType);
return item;
});
// 安全地处理 memberName 回显
if (res.data.data.memberName) {
this.addForm.memberName = String(res.data.data.memberName)
.split(',')
.map(id => id.trim())
.filter(Boolean);
} else {
this.addForm.memberName = [];
}
this.$forceUpdate();
});
});
},
handleClose(type) {
this.formError = '';
this.openShow = false;
this.$emit('close ', type);
},
selectChange(list, row) {
row._select = !row._select;
},
// 删除选中行
delTable() {
const selectedRows = this.addForm.stoneList.filter(row => row._select);
if (selectedRows.length === 0) {
this.$message.warning('请至少选择一行数据进行删除');
return;
}
const hasUnchecked = selectedRows.some(row => row.checkResult !== 0);
if (hasUnchecked) {
// 存在未核查数据,进行二次提醒
this.$confirm('确认删除执行中的里程碑?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
this.addForm.stoneList = this.addForm.stoneList.filter(row => !row._select);
})
.catch(() => {
// 用户取消,不做操作
});
} else {
this.addForm.stoneList = this.addForm.stoneList.filter(row => !row._select);
}
},
// 插入里程碑行
handleOpenDialog() {
const newRow = {
id: null,
fmProjectApplication: {},
attachList: [], // 附件列表默认空数组
paId: 0,
paIndex: `${(this.addForm.stoneList?.length || 0) + 1}`,
milestonePlan: '',
outputMaterial: '',
milestoneNode: '',
milestoneManId: '',
evolve: '',
lastPlan: '',
grade: null,
score: 0,
executeResult: 0,
executeType: '',
delayTime: '',
checkResult: 0,
checkMan: '',
checkTime: '',
gradeMan: '',
evaluate: '',
okTime: '',
delayDate: false,
fileId: '',
};
if (!this.addForm.stoneList) this.addForm.stoneList = [];
this.addForm.stoneList.push(newRow);
// this.$emit('open-dialog', newRow); // 通知父组件
},
// 删除里程碑行
handleDelTable(index) {
this.$confirm('确定删除该条数据么?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
this.addForm.stoneList.splice(index, 1);
this.$message.success('删除成功');
this.$emit('del-table', index); // 通知父组件
})
.catch(() => { });
},
formatSubmitData(form) {
const submitData = JSON.parse(JSON.stringify(form));
if (Array.isArray(submitData.memberName)) {
submitData.memberName = submitData.memberName.map(item => String(item)).join(',');
}
submitData.stoneList = submitData.stoneList.map((row, index) => {
const { fmProjectApplication, attachList, paIndex, ...validData } = row;
validData.paIndex = index + 1
validData.milestoneNode = validData.milestoneNode + ' 00:00:00';
return validData;
});
return submitData;
},
// 提交
async handleSubmitForm() {
this.formError = '';
if (this.addForm.stoneList.length === 0) {
return this.$message.error('立项申请数据不能为空!');
}
console.log(9999999, this.addForm);
this.$refs.addForm.validate((isValid, invalidFields) => {
if (!isValid) {
this.formError = '存在未完善的字段,请检查红色提示';
this.$nextTick(() => {
const firstError = document.querySelector('.el-form-item.is-error');
if (firstError) {
firstError.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
});
return;
}
this.loadingShow = true;
const submitData = this.formatSubmitData(this.addForm);
submitData.projectStartTime = submitData.projectStartTime + ' 00:00:00';
submitData.projectDesiredEnd = submitData.projectDesiredEnd + ' 00:00:00';
console.log(this.title, 'this.title');
if (this.title === '修改') {
if (this.isStatusEdit) {
this.$confirm('确定要保存修改过的数据吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
updateProcess({
...submitData,
})
.then(res => {
this.$message.success('提交成功');
this.handleClose(true);
this.loadingShow = false;
})
.catch(err => {
this.loadingShow = false;
});
})
.catch(() => { });
} else {
if (this.rowItem.approvalStatus == 2) {
this.rowItem.approvalStatus = 0;
}
updateProcess({
...submitData,
approvalStatus: this.isStatusEdit ? this.rowItem.approvalStatus : 1,
})
.then(res => {
this.$message.success('修改成功');
this.handleClose(true);
this.loadingShow = false;
})
.catch(err => {
this.loadingShow = false;
});
}
} else {
addProcess({
...submitData,
approvalStatus: this.isStatusEdit ? this.rowItem.approvalStatus : 1,
})
.then(res => {
this.$message.success('提交成功');
this.handleClose(true);
this.loadingShow = false;
})
.catch(err => {
this.loadingShow = false;
});
}
});
},
},
};
</script>
<style lang="scss" scoped>
// 优化表单字段样式
:deep(.el-table .el-form-item) {
margin-bottom: 0; // 去掉默认边距
}
// 错误提示样式优化
:deep(.table_project .el-form-item__error) {
font-size: 12px;
white-space: nowrap;
z-index: 10;
background: #fff;
padding: 2px 4px;
border: 1px solid #f56c6c;
border-radius: 4px;
}
.el-table__row {
height: 80px !important;
}
.el-table__cell {
vertical-align: middle !important;
}
.error-message {
font-size: 14px;
line-height: 1.5;
}
:deep(.el-table .el-table__body .el-table__cell) {
height: 50px !important;
padding: 0 !important;
line-height: 50px !important;
}
/* 高亮行样式 */
:deep(.highlight-row) {
background-color: rgba(40, 167, 69, 0.5) !important;
/* 浅绿色背景,可根据需求修改 */
// color: #67c23a;
}
</style>