From f139457e3c9a38e31d64290de1a9c6510919a64d Mon Sep 17 00:00:00 2001 From: fengyuan_yang <1976974459@qq.com> Date: Tue, 8 Sep 2026 17:41:06 +0800 Subject: [PATCH] =?UTF-8?q?2026-09-08=20=E9=A1=B9=E7=9B=AE=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E5=A2=9E=E5=8A=A0oa=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/project/project.js | 4 + .../processManagement/processBindingInfo.vue | 6 + .../com_projectInfo-add-or-update.vue | 261 ++++++++++++++++-- .../project/projectInfo/projectInfo.vue | 223 ++++++++++++++- 4 files changed, 465 insertions(+), 29 deletions(-) diff --git a/src/api/project/project.js b/src/api/project/project.js index b381d75..563378c 100644 --- a/src/api/project/project.js +++ b/src/api/project/project.js @@ -64,3 +64,7 @@ export const queryUsernameByRoleSuperFlag = (data) => createAPI(`/project/site/u export const projectInfoSearchByAnyField = data => createAPI(`/project/projectInfoSearch/any`,'Post',data) export const projectPartSearchByAnyField = data => createAPI(`/project/part/any`,'Post',data) +export const issueProjectInfo = data => createAPI(`/project/issue`,'Post',data) +export const submitProjectInfo = data => createAPI(`/project/submit`,'Post',data) +export const getProjectApprovalList = data => createAPI(`/project/approvalList`,'Post',data) + diff --git a/src/views/modules/processManagement/processBindingInfo.vue b/src/views/modules/processManagement/processBindingInfo.vue index f8b79aa..1749a0c 100644 --- a/src/views/modules/processManagement/processBindingInfo.vue +++ b/src/views/modules/processManagement/processBindingInfo.vue @@ -1337,6 +1337,12 @@ passTable: [], addTable: [] } + } else if (row.menuId === '101002001') { // 项目信息 + this.queryTableParam = { + tableType: 'plm_project_info', + passTable: [], + addTable: ['plm_project_team'] + } } else { return } diff --git a/src/views/modules/project/projectInfo/com_projectInfo-add-or-update.vue b/src/views/modules/project/projectInfo/com_projectInfo-add-or-update.vue index 964d32d..128379d 100644 --- a/src/views/modules/project/projectInfo/com_projectInfo-add-or-update.vue +++ b/src/views/modules/project/projectInfo/com_projectInfo-add-or-update.vue @@ -10,40 +10,42 @@ - + - + - + - + - 项目经理 + 项目经理 + 项目经理 - 项目审批人 + 项目审批人 + 项目审批人 - 客户 - + 客户 + @@ -65,37 +67,51 @@ - + - + - + - + - + - + - 项目权限 - + 项目权限 + - {{'确定'}} + {{'确定'}} {{'关闭'}} + 同意 + 驳回 + + + + + + + + + + + 确定 + 取消 @@ -248,6 +264,7 @@ searchUserRoll, searchSelectionUserRole, saveProjectInfo, + submitProjectInfo, } from "@/api/project/project.js" import Chooselist from '@/views/modules/common/Chooselist' import DictDataSelect from "../../sys/dict-data-select.vue"; @@ -255,6 +272,8 @@ } from "@/api/customer/customerInformation"; import item from "../../code/item.vue"; import {queryUsernameByRoleSuperFlag} from "../../../../api/project/project"; + import {getNodeAuthority, checkSuperAdmin} from "@/api/changeManagement/changeManagement" + import {isAuth} from "../../../../utils"; export default { @@ -281,6 +300,17 @@ managerFlag:false, userRoleFlag:false, ownerFlag:false, + submitModalFlag:false, + submitLoading:false, + rejectOpinion:'', + nodeAuthorityLoaded: true, + plmProjectAuthorityArr: [], + plmProjectTeamAuthorityArr: [], + menuId: '101002001', + authSubmit: false, + authReject: false, + superAdmin: false, + createBy2: this.$store.state.user.name, operatorList:[], dataForm: { id: 0, @@ -313,6 +343,11 @@ userRoleList:[], productSet:'', projectAmount:'', + status:'草稿', + stepId: 10, + rejectFlag: 'N', + createBy2: '', + isReject: 'N' }, userRoleForm:{ username:'', @@ -374,7 +409,12 @@ } }, created () { - + this.menuId = (this.$route.meta && this.$route.meta.menuId) || this.menuId + this.authSubmit = isAuth(this.menuId + ':submit') + this.authReject = isAuth(this.menuId + ':reject') + checkSuperAdmin().then(({data}) => { + this.superAdmin = !!(data && data.superAdmin) + }) }, watch:{ userRoleFlag(newVal,oldVal){ @@ -544,6 +584,7 @@ this.dataForm.projectOwnerList=data.rows }) this.searchUserRollAll(); + this.loadNodeAuthority(this.dataForm.site, this.dataForm.stepId || 10) } }) } else { // 项目新增 @@ -578,7 +619,15 @@ userRoleList: [], productSet: '', projectAmount: '', + status: '草稿', + stepId: 10, + rejectFlag: 'N', + createBy2: '', + isReject: 'N' } + this.plmProjectAuthorityArr = [] + this.plmProjectTeamAuthorityArr = [] + this.nodeAuthorityLoaded = true // 默认插入当前用户 this.addRollForUsername(this.$store.state.user.name,this.$store.state.user.userDisplay) // this.searchUserRollAll(); @@ -658,13 +707,6 @@ return this.projectManagerList.includes(item.operatorId); }) projectManagerName=selectionManagerList.map(item => item.operatorName).join(';'); - // for (let i = 0; i < this.projectManagerList.length; i++) { - // let select= this.operatorList.filter(item => item.operatorId === this.projectManagerList[i]) - // if(select.length > 0){ - // projectManagerName+=select[0].operatorName+';' - // this.addRollForUsername(select[0].operatorId,select[0].operatorName); - // } - // } for (let i = 0; i < selectionManagerList.length; i++) { let row = selectionManagerList[i] this.addRollForUsername(row.operatorId,row.operatorName) @@ -702,8 +744,6 @@ this.dataForm.projectOwnerName = projectOwnerName this.dataForm.projectOwnerList=JSON.parse(JSON.stringify(this.projectOwnerList)); this.ownerFlag=false - - }, addRollForUsername(username,userDisplay){ if(this.dataForm.userRoleList.length>0) { @@ -910,6 +950,173 @@ this.$refs.saveForm.resetFields(); }, + isCurrentApprover () { + return this.superAdmin || (this.dataForm.createBy2 && String(this.dataForm.createBy2).split(';').includes(this.createBy2)) + }, + canSaveAction () { + if (this.dataForm.status === '已完成') { + return false + } + if (!this.dataForm.status || this.dataForm.status === '草稿') { + return true + } + return this.dataForm.status === '审批中' && this.isCurrentApprover() + }, + canAgreeAction () { + return this.authSubmit && this.isCurrentApprover() && this.dataForm.status === '审批中' + }, + canRejectAction () { + return this.authReject && this.isCurrentApprover() && this.dataForm.status === '审批中' && this.dataForm.isReject === 'Y' + }, + projectFieldFlag (fieldId) { + if (!this.plmProjectAuthorityArr || this.plmProjectAuthorityArr.length === 0) { + return this.dataForm.id ? 'N' : 'Y' + } + let target = this.plmProjectAuthorityArr.find(item => item.fieldId === fieldId) + return target ? target.updateFlag : 'N' + }, + isProjectFieldDisabled (fieldId) { + if (this.dataForm.status === '已完成') { + return true + } + if (!this.dataForm.id) { + return false + } + return this.projectFieldFlag(fieldId) === 'N' + }, + plmProjectTeamArrFlag (fieldId) { + if (!this.plmProjectTeamAuthorityArr) { + return 'N' + } + let arr = this.plmProjectTeamAuthorityArr.filter(a => a.fieldId === fieldId) + if (arr.length > 0) { + return arr[0].updateFlag + } + return 'N' + }, + isProjectTeamFieldDisabled (fieldId) { + if (this.dataForm.status === '已完成') { + return true + } + if (!this.dataForm.id || this.dataForm.status === '草稿') { + return false + } + return this.plmProjectTeamArrFlag(fieldId) === 'N' + }, + loadNodeAuthority (site, stepId) { + if (!site || stepId === null || stepId === undefined || !this.menuId) { + this.plmProjectAuthorityArr = [] + this.plmProjectTeamAuthorityArr = [] + this.nodeAuthorityLoaded = true + return Promise.resolve() + } + this.nodeAuthorityLoaded = false + return getNodeAuthority({ + site: site, + stepId: stepId, + menuId: this.menuId + }).then(({data}) => { + if (data && data.code === 0 && data.rows) { + this.plmProjectAuthorityArr = data.rows.plm_project_info || [] + this.plmProjectTeamAuthorityArr = data.rows.plm_project_team || [] + } else { + this.plmProjectAuthorityArr = [] + this.plmProjectTeamAuthorityArr = [] + } + this.nodeAuthorityLoaded = true + }).catch(() => { + this.plmProjectAuthorityArr = [] + this.plmProjectTeamAuthorityArr = [] + this.nodeAuthorityLoaded = true + }) + }, + validateSubmitRequiredFields () { + if (this.plmProjectAuthorityArr) { + for (let i = 0; i < this.plmProjectAuthorityArr.length; i++) { + const fieldConfig = this.plmProjectAuthorityArr[i] + if (fieldConfig.required !== 'Y') { + continue + } + const value = this.dataForm[fieldConfig.fieldId] + if (value === null || value === undefined || String(value).trim() === '') { + this.$message.warning((fieldConfig.fieldName || fieldConfig.fieldId) + '不能为空!') + return false + } + } + } + if (this.plmProjectTeamAuthorityArr) { + for (let i = 0; i < this.plmProjectTeamAuthorityArr.length; i++) { + const fieldConfig = this.plmProjectTeamAuthorityArr[i] + if (fieldConfig.required !== 'Y') { + continue + } + const value = this.dataForm[fieldConfig.fieldId] + if (!value || value.length === 0) { + this.$message.warning((fieldConfig.fieldName || fieldConfig.fieldId) + '不能为空!') + return false + } + } + } + return true + }, + agreeSubmit () { + if (!this.canAgreeAction()) { + this.$message.warning('当前状态不允许同意') + return + } + this.$confirm('确认同意该项目?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + this.submitProject('Y') + }) + }, + openRejectModal () { + if (!this.canRejectAction()) { + this.$message.warning('当前状态不允许驳回') + return + } + this.rejectOpinion = '' + this.submitModalFlag = true + }, + rejectSubmit () { + if (!this.rejectOpinion || !this.rejectOpinion.trim()) { + this.$message.warning('请填写驳回意见') + return + } + this.submitProject('N') + }, + submitProject (nodeConclusion) { + if (!this.nodeAuthorityLoaded) { + this.$message.warning('节点权限加载中,请稍后重试') + return + } + if (nodeConclusion === 'Y' && !this.validateSubmitRequiredFields()) { + return + } + this.submitLoading = true + submitProjectInfo({ + ...this.dataForm, + nodeConclusion: nodeConclusion, + rejectOpinion: this.rejectOpinion, + menuId: this.menuId + }).then(({data}) => { + this.submitLoading = false + if (data && data.code === 0) { + this.$message.success(nodeConclusion === 'Y' ? '同意成功' : '驳回成功') + this.submitModalFlag = false + this.visible = false + this.$emit('refreshDataList', this.dataForm.projectId) + } else { + this.$message.error((data && data.msg) || '提交失败') + } + }).catch(err => { + this.submitLoading = false + this.$message.error((err && err.message) || '提交失败') + }) + }, + updateDataForm (val) { this.dataForm.projectId = val; }, diff --git a/src/views/modules/project/projectInfo/projectInfo.vue b/src/views/modules/project/projectInfo/projectInfo.vue index 38fdfde..d467cbe 100644 --- a/src/views/modules/project/projectInfo/projectInfo.vue +++ b/src/views/modules/project/projectInfo/projectInfo.vue @@ -18,6 +18,26 @@ + + + + + + + + + + + + + + + + @@ -43,6 +63,7 @@ {{ '导出' }} 搜索 + 流程关闭 @@ -64,8 +86,10 @@ 新增 修改 删除 + 下达 + +
+ + + +
@@ -268,6 +297,9 @@ + + + @@ -398,7 +430,9 @@ getProjectUserRole, addContact, deleteContact, - queryCustomerContact + queryCustomerContact, + issueProjectInfo, + getProjectApprovalList } from "@/api/project/project.js" import { getChangeRecordByPartNo, // 查询变更记录 @@ -411,6 +445,7 @@ import technicalSpecification from "./com_project_technicalSpecification"; import DictDataSelect from "../../sys/dict-data-select.vue"; import ChangeRecord from "./com_project_change_record.vue"; + import ApprovalInformation from "../../changeManagement/approvalInformation.vue"; import OssComponents from "../../oss/ossComponents.vue"; import toolApply from "./com_project_toolApplyCation.vue"; import { Divider } from 'element-ui'; @@ -428,7 +463,8 @@ import {proofingInformationSearch} from "../../../../api/proofing/proofingInformation"; import {testInformationList} from "../../../../api/test/testInformation"; import {searchProjectToolApplyDetail} from "../../../../api/tool/toolApply"; - import {technicalSpecificationListSearch} from "../../../../api/sampleManagement/technicalSpecificationList"; + import {technicalSpecificationListSearch, getNodeList} from "../../../../api/sampleManagement/technicalSpecificationList"; + import {checkSuperAdmin, closeProcess} from "@/api/changeManagement/changeManagement" /*組件*/ export default { components: { @@ -439,6 +475,7 @@ CustomerInfo, OssComponents, ChangeRecord, + ApprovalInformation, DictDataSelect, Chooselist, AddOrUpdate, @@ -467,6 +504,12 @@ filterVisible:false, isFilterSearch: false, filterSearchData: {}, + nodeOptions: [], + approvalList: [], + dataListSelections: [], + menuId: '101002001', + authIssue: false, + superAdmin: false, searchData:{ page: 1, limit: 100, @@ -480,6 +523,10 @@ customerId:'', customerName:'', userName:this.$store.state.user.name, + status:'', + currentApprover:'', + nodeId:'', + menuId: this.$route.meta.menuId || '101002001', }, contactChooseFlag:false, currentRow:'', @@ -561,6 +608,60 @@ fixed: '', columnWidth: 200 }, + { + userId: this.$store.state.user.name, + functionId: 101002001, + serialNumber: '101002001Table1Status', + tableId: "101002001Table1", + tableName: "项目信息主表", + columnProp: "status", + headerAlign: "center", + align: "center", + columnLabel: "单据状态", + columnHidden: false, + columnImage: false, + columnSortable: false, + sortLv: 0, + status: true, + fixed: '', + columnWidth: 100 + }, + { + userId: this.$store.state.user.name, + functionId: 101002001, + serialNumber: '101002001Table1NodeName', + tableId: "101002001Table1", + tableName: "项目信息主表", + columnProp: "nodeName", + headerAlign: "center", + align: "left", + columnLabel: "当前节点", + columnHidden: false, + columnImage: false, + columnSortable: false, + sortLv: 0, + status: true, + fixed: '', + columnWidth: 140 + }, + { + userId: this.$store.state.user.name, + functionId: 101002001, + serialNumber: '101002001Table1CurrentApprover', + tableId: "101002001Table1", + tableName: "项目信息主表", + columnProp: "currentApprover", + headerAlign: "center", + align: "left", + columnLabel: "当前节点审批人", + columnHidden: false, + columnImage: false, + columnSortable: false, + sortLv: 0, + status: true, + fixed: '', + columnWidth: 130 + }, { userId: this.$store.state.user.name, functionId: 101002001, @@ -988,6 +1089,9 @@ productSet:'', projectAmount:'', finalCustomerId:'', + status:'', + nodeName:'', + currentApprover:'', }, customerData:{ site: '', @@ -1315,6 +1419,11 @@ } }, mounted() { + this.menuId = (this.$route.meta && this.$route.meta.menuId) || this.menuId + this.searchData.menuId = this.menuId + this.authIssue = this.isAuth(this.menuId + ':issue') + this.checkSuperAdmin() + this.fetchNodeOptions() this.$nextTick(() => { //this.height = window.innerHeight - 520; this.height = window.innerHeight / 2 - 50 @@ -1445,6 +1554,7 @@ this.searchData.limit = this.pageSize this.searchData.page = this.pageIndex this.searchData.userId = this.$store.state.user.id + this.searchData.menuId = this.menuId projectInfoSearch(this.searchData).then(({data}) => { if (data.code == 0) { this.dataList1 = data.page.list @@ -1471,6 +1581,7 @@ limit: 10, } this.refreshCurrentTabTable (); + this.loadApprovalList(row); customerInformationSearchForCheck(inData).then(({data}) => { if (data.code == 0) { if(data.page.list.length>0){ @@ -1990,6 +2101,10 @@ } getProjectUserRole(inData).then(({data}) => { if(data.row.superFlag==='Y'||data.row.deleteFlag==='Y') { + if (row.status && row.status !== '草稿') { + this.$message.warning('仅草稿状态的单据允许删除') + return + } this.$confirm(`确定删除当前记录?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', @@ -2035,6 +2150,110 @@ } }, + fetchNodeOptions () { + if (!this.searchData.site || !this.menuId) { + this.nodeOptions = [] + return + } + getNodeList({ + site: this.searchData.site, + menuId: this.menuId + }).then(({data}) => { + if (data && data.code === 0 && Array.isArray(data.rows)) { + this.nodeOptions = data.rows + .filter(item => item && item.nodeId) + .map(item => ({ + id: item.nodeId, + name: item.nodeName + })) + } else { + this.nodeOptions = [] + } + }).catch(() => { + this.nodeOptions = [] + }) + }, + checkSuperAdmin () { + checkSuperAdmin().then(({data}) => { + this.superAdmin = !!(data && data.superAdmin) + }) + }, + dataListSelectionChange (val) { + this.dataListSelections = val || [] + }, + loadApprovalList (row) { + if (!row || !row.site || !row.projectId) { + this.approvalList = [] + return + } + getProjectApprovalList({ + site: row.site, + menuId: this.menuId, + documentNo: row.projectId + }).then(({data}) => { + this.approvalList = (data && data.code === 0) ? (data.rows || []) : [] + }).catch(() => { + this.approvalList = [] + }) + }, + issueModal (row) { + if (!this.authIssue) { + this.$message.warning('没有下达权限') + return + } + if (!row || row.status !== '草稿') { + this.$message.warning('仅草稿状态的单据允许下达') + return + } + this.$confirm('确认下达该项目?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + issueProjectInfo({ + site: row.site, + projectId: row.projectId, + menuId: this.menuId + }).then(({data}) => { + if (data && data.code === 0) { + this.$message.success('下达成功') + this.search() + } else { + this.$message.error((data && data.msg) || '下达失败') + } + }).catch(err => { + this.$message.error((err && err.message) || '下达失败') + }) + }).catch(() => {}) + }, + closeProcessModal () { + const approvedRows = (this.dataListSelections || []).filter(item => item && item.status === '审批中' && item.projectId) + if (!approvedRows.length) { + this.$message.warning('请勾选状态为"审批中"的单据!') + return + } + this.$confirm(`确定关闭这 ${approvedRows.length} 条项目单据的OA流程?关闭后状态将变为"草稿"。`, '流程关闭', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + closeProcess({ + site: this.$store.state.user.site, + documentNos: approvedRows.map(row => row.projectId), + documentType: 'PROJECT' + }).then(({data}) => { + if (data && data.code === 0) { + this.$message.success('流程关闭成功') + this.search() + } else { + this.$message.error((data && data.msg) || '流程关闭失败') + } + }).catch(err => { + this.$message.error((err && err.message) || '流程关闭失败') + }) + }).catch(() => {}) + }, + projectInfoSearchByAnyField(params){ params.no = this.pageIndex params.size = this.pageSize