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