fix:修改权限管理相关内容

This commit is contained in:
大黑 2025-12-22 09:07:53 +08:00
parent 6119956bd4
commit 3e4253d9a9
20 changed files with 2469 additions and 272008 deletions

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,139 +0,0 @@
{
"entry": "index.js",
"copyAssets": ["public/custom/apaas-custom-mydemo"],
"router": {
"apaas-custom-modalContorl":{
"name": "apaas-custom-modalContorl",
"path": "apaas-custom-modalContorl",
"meta": {
"title": "模板管理"
}
},
"apaas-custom-selfEnginedata":{
"name": "apaas-custom-selfEnginedata",
"path": "apaas-custom-selfEnginedata",
"meta": {
"title": "玉柴发动机数据"
}
},
"apaas-custom-otherEnginedata":{
"name": "apaas-custom-otherEnginedata",
"path": "apaas-custom-otherEnginedata",
"meta": {
"title": "竞品发动机数据"
}
},
"apaas-custom-checkData":{
"name": "apaas-custom-checkData",
"path": "apaas-custom-checkData",
"meta": {
"title": "数据检查"
}
},
"apaas-custom-report":{
"name": "apaas-custom-report",
"path": "apaas-custom-report",
"meta": {
"title": "对标报告"
}
},
"apaas-custom-reportDetail":{
"name": "apaas-custom-reportDetail",
"path": "apaas-custom-reportDetail",
"meta": {
"title": "报告详情"
}
},
"apaas-custom-reportCheck":{
"name": "apaas-custom-reportCheck",
"path": "apaas-custom-reportCheck",
"meta": {
"title": "报告检查"
}
},
"apaas-custom-modelDetail":{
"name": "apaas-custom-modelDetail",
"path": "apaas-custom-modelDetail",
"meta": {
"title": "系统参数管理"
}
},
"apaas-custom-engineDetail":{
"name": "apaas-custom-engineDetail",
"path": "apaas-custom-engineDetail",
"meta": {
"title": "发动机参数详情"
}
},
"apaas-custom-approvalManagement":{
"name": "apaas-custom-approvalManagement",
"path": "apaas-custom-approvalManagement",
"meta": {
"title": "模板审批管理"
}
},
"apaas-custom-toDoList":{
"name": "apaas-custom-toDoList",
"path": "apaas-custom-toDoList",
"meta": {
"title": "数据待办"
}
},
"apaas-custom-myDone":{
"name": "apaas-custom-myDone",
"path": "apaas-custom-myDone",
"meta": {
"title": "我的已办"
}
},
"apaas-custom-mySend":{
"name": "apaas-custom-mySend",
"path": "apaas-custom-mySend",
"meta": {
"title": "我发起的"
}
},
"apaas-custom-selfEngineCheck":{
"name": "apaas-custom-selfEngineCheck",
"path": "apaas-custom-selfEngineCheck",
"meta": {
"title": "玉柴发动机审核"
}
},
"apaas-custom-otherEngineCheck":{
"name": "apaas-custom-otherEngineCheck",
"path": "apaas-custom-otherEngineCheck",
"meta": {
"title": "竞品发动机审核"
}
},
"apaas-custom-managerData":{
"name": "apaas-custom-managerData",
"path": "apaas-custom-managerData",
"meta": {
"title": "责任人管理"
}
},
"apaas-custom-fillerData":{
"name": "apaas-custom-fillerData",
"path": "apaas-custom-fillerData",
"meta": {
"title": "填写人管理"
}
},
"apaas-custom-permissionManagement":{
"name": "apaas-custom-permissionManagement",
"path": "apaas-custom-permissionManagement",
"meta": {
"title": "权限管理"
}
}
},
"customWidgetList": [
{
"code": "mydemo",
"text": "mydemo"
}
],
"outputName": "apaas-custom-mydemo"
}

View File

@ -1,10 +0,0 @@
<meta charset="utf-8">
<title>apaas-custom-mydemo demo</title>
<script src="./apaas-custom-mydemo.umd.js"></script>
<link rel="stylesheet" href="./apaas-custom-mydemo.css">
<script>
console.log(apaas-custom-mydemo)
</script>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -413,6 +413,10 @@ export default {
url: '/custom/tcDataQuery/tcDataSelectByPartsNames',
method: 'post'
},
DOWNLOAD_MODEL_QUERY_DATA: {
url: '/custom/tcDataQuery/modelComparisonExport',
method: 'post'
},
GET_MY_SEND_LIST: {
url: '/custom/todoTaskPojo/selectByPageByCreate',
method: 'post'

View File

@ -37,6 +37,13 @@
"title": "对标报告"
}
},
"apaas-custom-reportList":{
"name": "apaas-custom-reportList",
"path": "apaas-custom-reportList",
"meta": {
"title": "报告列表"
}
},
"apaas-custom-reportDetail":{
"name": "apaas-custom-reportDetail",
"path": "apaas-custom-reportDetail",

View File

@ -263,7 +263,7 @@ export default {
}
},
created() {
// this.loadUserSelfRole()
this.loadUserSelfRole()
this.loadData()
},
methods: {

View File

@ -34,13 +34,30 @@
/>
</el-select>
</el-form-item>
<el-form-item v-if="dispatchType === 'update_param'" label="零部件名称:" prop="partsName">
<el-select
v-model="formData.partsName"
placeholder="请选择零部件名称"
clearable
style="width: 100%"
:disabled="!formData.subsystem"
@change="handlePartsNameChange"
>
<el-option
v-for="item in availablePartsNames"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</el-form-item>
<el-form-item label="部门:" prop="department">
<el-select
v-model="formData.department"
placeholder="请选择部门"
clearable
style="width: 100%"
:disabled="!formData.subsystem"
:disabled="!formData.subsystem || (dispatchType === 'update_param' && !formData.partsName)"
@change="handleDepartmentChange"
>
<el-option
@ -53,8 +70,8 @@
</el-form-item>
<el-form-item v-if="dispatchType !== 'update_param'" label="现责任人:">
<el-input
disabled
v-model="formData.currentResponsibleName"
disabled
placeholder="暂无责任人"
readonly
style="width: 100%"
@ -66,7 +83,7 @@
:placeholder="dispatchType === 'update_param' ? '请输入填写人姓名进行搜索' : '请输入责任人姓名进行搜索'"
style="width: 100%"
clearable
:disabled="!formData.department"
:disabled="!formData.department || (dispatchType === 'update_param' && !formData.partsName)"
filterable
remote
reserve-keyword
@ -134,6 +151,7 @@ export default {
submitting: false,
formData: {
subsystem: '',
partsName: '', //
department: '',
currentResponsibleId: '', // ID
currentResponsibleName: '', //
@ -143,6 +161,7 @@ export default {
rowId: '' // rowId
},
subsystemList: [],
availablePartsNames: [], //
availableDepartments: [], //
allManagerData: [], //
departmentTreeData: [], // ID
@ -155,7 +174,7 @@ export default {
return this.dispatchType === 'update_param' ? '批量修改填写人' : '批量修改责任人'
},
formRules() {
return {
const rules = {
subsystem: [
{ required: true, message: '请选择子系统', trigger: 'change' }
],
@ -166,6 +185,13 @@ export default {
{ required: true, message: this.dispatchType === 'update_param' ? '请选择填写人' : '请选择责任人', trigger: 'change' }
]
}
//
if (this.dispatchType === 'update_param') {
rules.partsName = [
{ required: true, message: '请选择零部件名称', trigger: 'change' }
]
}
return rules
}
},
methods: {
@ -189,6 +215,7 @@ export default {
//
this.formData = {
subsystem: '',
partsName: '',
department: '',
currentResponsibleId: '',
currentResponsibleName: '',
@ -197,6 +224,7 @@ export default {
username: '',
rowId: ''
}
this.availablePartsNames = []
this.availableDepartments = []
this.userOptions = []
this.userLoading = false
@ -218,6 +246,7 @@ export default {
this.visible = false
this.formData = {
subsystem: '',
partsName: '',
department: '',
currentResponsibleId: '',
currentResponsibleName: '',
@ -226,6 +255,7 @@ export default {
username: '',
rowId: ''
}
this.availablePartsNames = []
this.availableDepartments = []
this.userOptions = []
this.userLoading = false
@ -274,7 +304,8 @@ export default {
},
//
handleSubsystemChange(subsystem) {
//
//
this.formData.partsName = ''
this.formData.department = ''
this.formData.currentResponsibleId = ''
this.formData.currentResponsibleName = ''
@ -282,12 +313,14 @@ export default {
this.formData.userId = ''
this.formData.userNumber = ''
this.formData.username = ''
this.availablePartsNames = []
this.availableDepartments = []
this.userOptions = []
//
//
if (subsystem) {
// versionData partsName
const departmentSet = new Set()
const currentVersionData = this.versionData[this.currentVersionId] || {}
const partsNameSet = new Set()
const departmentSet = new Set()
// partsName
Object.keys(currentVersionData).forEach((partsName) => {
@ -295,7 +328,65 @@ export default {
//
params.forEach((param) => {
//
if (param.subsystemName === subsystem && param.department) {
if (param.subsystemName === subsystem) {
//
if (this.dispatchType === 'update_param') {
const paramPartsName = param.partsName || partsName
if (paramPartsName && paramPartsName !== '/') {
partsNameSet.add(paramPartsName)
}
}
//
if (param.department) {
departmentSet.add(param.department)
}
}
})
})
//
if (this.dispatchType === 'update_param') {
this.availablePartsNames = Array.from(partsNameSet).sort()
}
//
if (this.dispatchType !== 'update_param') {
//
this.availableDepartments = Array.from(departmentSet).map((dept) => ({
department: dept
}))
}
} else {
this.availablePartsNames = []
this.availableDepartments = []
}
},
//
handlePartsNameChange(partsName) {
//
this.formData.department = ''
this.formData.userId = ''
this.formData.userNumber = ''
this.formData.username = ''
this.availableDepartments = []
this.userOptions = []
//
if (partsName && this.formData.subsystem) {
const departmentSet = new Set()
const currentVersionData = this.versionData[this.currentVersionId] || {}
// partsName
Object.keys(currentVersionData).forEach((dataPartsName) => {
const params = currentVersionData[dataPartsName] || []
//
params.forEach((param) => {
//
const paramPartsName = param.partsName || dataPartsName
if (
param.subsystemName === this.formData.subsystem &&
paramPartsName === partsName &&
param.department
) {
departmentSet.add(param.department)
}
})
@ -348,10 +439,19 @@ export default {
},
//
handleRemoteSearch(query) {
//
if (this.dispatchType === 'update_param') {
if (!this.formData.partsName || !this.formData.department) {
this.userOptions = []
return
}
} else {
//
if (!this.formData.department) {
this.userOptions = []
return
}
}
if (!query || query.trim() === '') {
if (this.formData.userId) {
const selectedOptions = this.userOptions.filter((opt) => opt.userId === this.formData.userId)
@ -461,12 +561,18 @@ export default {
//
if (this.dispatchType === 'update_param') {
//
if (!this.formData.partsName) {
this.$message.warning('请选择零部件名称')
return
}
//
// userNumber 使 userId userNumber
const confirmData = {
subsystem: this.formData.subsystem,
partsName: this.formData.partsName,
department: this.formData.department,
userId: this.formData.userId,
userId: this.formData.userId, // userId
userNumber: this.formData.userNumber || this.formData.userId, // userNumber使 userId
username: this.formData.username || ''
}

View File

@ -1450,9 +1450,9 @@ export default {
//
if (this.dispatchType === 'update_param') {
const { subsystem, department, userId, userNumber, username } = change
console.log(change, 'change', subsystem, department, userId, userNumber, username)
if (!subsystem || !department || !userId) {
const { subsystem, partsName, department, userId, userNumber, username } = change
console.log(change, 'change', subsystem, partsName, department, userId, userNumber, username)
if (!subsystem || !partsName || !department || !userId) {
this.$message({
type: 'warning',
message: '缺少必要参数'
@ -1476,21 +1476,29 @@ export default {
}
// partsName
Object.keys(currentData).forEach((partsName) => {
const params = currentData[partsName] || []
Object.keys(currentData).forEach((dataPartsName) => {
const params = currentData[dataPartsName] || []
//
params.forEach((param, index) => {
// · -
const normalizedParamDept = (param.department || '').replace(/·/g, '-')
// 使param.partsName使dataPartsName
const paramPartsName = param.partsName || dataPartsName
// 使
if (param.subsystemName === subsystem && normalizedParamDept === normalizedDepartment) {
// 使
if (
param.subsystemName === subsystem &&
paramPartsName === partsName &&
normalizedParamDept === normalizedDepartment
) {
//
param.filledBy = userId // IDuserId
param.filledByUserId = userId // userId el-select v-model
//
param.department = department
// 使 Vue.set
this.$set(currentData[partsName], index, param)
this.$set(currentData[dataPartsName], index, param)
//
const rowId = param.id || `${param.subsystemName}-${param.parameterName}`

View File

@ -68,17 +68,20 @@
>
<el-form ref="form" :model="formData" :rules="formRules" label-width="100px">
<el-form-item label="责任部门:" prop="department">
<el-cascader
ref="departmentCascader"
v-model="formData.department"
:options="departmentList"
:props="departmentCascaderProps"
filterable
<el-input
v-model="formData.selectDeptName"
placeholder="请选择责任部门"
clearable
readonly
style="width: 100%"
@change="handleDepartmentChange"
/>
@click.native="handleOpenDepartmentDialog"
>
<i
slot="suffix"
class="el-input__icon el-icon-search"
style="cursor: pointer;"
@click.stop="handleOpenDepartmentDialog"
></i>
</el-input>
</el-form-item>
<el-form-item label="子系统:" prop="subsystem">
<el-select
@ -148,6 +151,45 @@
</el-button>
</div>
</el-dialog>
<!-- 部门选择弹窗 -->
<el-dialog
title="选择责任部门"
:visible.sync="departmentDialogVisible"
width="500px"
:close-on-click-modal="false"
append-to-body
@close="handleDepartmentDialogClose"
>
<el-input
v-model="departmentTreeFilterText"
size="small"
placeholder="请输入部门名称进行搜索"
clearable
class="department-tree-search"
>
<i slot="prefix" class="el-input__icon el-icon-search"></i>
</el-input>
<el-tree
ref="departmentTree"
:data="departmentList"
:props="{ children: 'children', label: 'name' }"
node-key="id"
:filter-node-method="filterDepartmentNode"
highlight-current
:expand-on-click-node="false"
class="department-tree"
@node-click="handleDepartmentNodeClick"
/>
<div slot="footer" class="dialog-footer">
<el-button @click="handleDepartmentDialogClose">
取消
</el-button>
<el-button type="primary" :disabled="!selectedDepartmentId" @click="handleDepartmentDialogConfirm">
确定
</el-button>
</div>
</el-dialog>
</div>
</template>
@ -167,7 +209,7 @@ export default {
dialogMode: 'add', // 'add' 'edit'
currentEditIndex: -1,
formData: {
department: '', // ID
department: '', // ID
subsystem: '', //
partsName: '', //
filler: [], // ID
@ -193,15 +235,11 @@ export default {
departmentList: [],
searchTimer: null, //
currentRequest: null, //
//
departmentCascaderProps: {
value: 'id',
label: 'name',
children: 'children',
checkStrictly: true, //
emitPath: false, // id
multiple: false //
}
departmentDialogVisible: false, //
departmentTreeFilterText: '', //
selectedDepartmentId: '', // ID
selectedDepartmentName: '', //
selectedDepartmentNode: null //
}
},
computed: {
@ -209,6 +247,13 @@ export default {
return this.dialogMode === 'add' ? '新增' : '修改'
}
},
watch: {
departmentTreeFilterText(val) {
if (this.$refs.departmentTree) {
this.$refs.departmentTree.filter(val)
}
}
},
mounted() {
this.loadDepartmentList()
this.loadFillerData()
@ -340,7 +385,7 @@ export default {
if (resp && resp.data) {
result = resp.data.result || resp.data.data || resp.data || []
}
//
//
this.departmentList = this.formatDepartmentTreeData(result)
})
.asyncErrorCatch((err) => {
@ -348,7 +393,7 @@ export default {
this.departmentList = []
})
},
//
//
formatDepartmentTreeData(data) {
if (!Array.isArray(data)) {
return []
@ -457,7 +502,7 @@ export default {
}
this.formData = {
department: row.departmentId || '', // ID
department: row.departmentId || '', // ID
subsystem: subsystemValue, //
partsName: row.partsName || '', //
filler: userIds, //
@ -580,24 +625,69 @@ export default {
}
})
},
//
handleDepartmentChange(value) {
if (value) {
// id
this.formData.selectDeptId = value
//
this.formData.selectDeptName = this.getDepartmentPathName(value)
//
handleOpenDepartmentDialog() {
//
if (this.formData.selectDeptId) {
this.selectedDepartmentId = this.formData.selectDeptId
this.selectedDepartmentName = this.formData.selectDeptName
this.$nextTick(() => {
if (this.$refs.departmentTree) {
this.$refs.departmentTree.setCurrentKey(this.formData.selectDeptId)
}
})
} else {
this.selectedDepartmentId = ''
this.selectedDepartmentName = ''
}
this.departmentTreeFilterText = ''
this.departmentDialogVisible = true
},
//
handleDepartmentDialogClose() {
this.departmentDialogVisible = false
this.departmentTreeFilterText = ''
//
if (this.formData.selectDeptId) {
this.selectedDepartmentId = this.formData.selectDeptId
this.selectedDepartmentName = this.formData.selectDeptName
} else {
this.selectedDepartmentId = ''
this.selectedDepartmentName = ''
this.selectedDepartmentNode = null
}
},
//
handleDepartmentDialogConfirm() {
if (this.selectedDepartmentId && this.selectedDepartmentNode) {
//
this.formData.selectDeptId = this.selectedDepartmentId
this.formData.selectDeptName = this.selectedDepartmentName
this.formData.department = this.selectedDepartmentId
//
this.formData.filler = []
this.formData.fillerName = ''
} else {
//
this.formData.selectDeptId = ''
this.formData.selectDeptName = ''
this.formData.filler = []
this.formData.fillerName = ''
this.fillerPersons = []
this.userOptions = []
//
this.departmentDialogVisible = false
//
this.$nextTick(() => {
if (this.$refs.form) {
this.$refs.form.clearValidate('department')
}
})
}
},
//
handleDepartmentNodeClick(data) {
this.selectedDepartmentId = data.id
this.selectedDepartmentName = this.getDepartmentPathName(data.id)
this.selectedDepartmentNode = data
},
//
filterDepartmentNode(value, data) {
if (!value) return true
return (data.name || '').toLowerCase().includes(value.toLowerCase())
},
// el-select
handleRemoteSearch(query) {
@ -888,4 +978,14 @@ export default {
margin-left: 20px;
text-align: right !important;
}
.department-tree-search {
margin-bottom: 16px;
}
.department-tree {
max-height: 400px;
overflow-y: auto;
border: 1px solid #ebeef5;
border-radius: 4px;
padding: 8px;
}
</style>

View File

@ -25,6 +25,9 @@
已隐藏参数
<span v-if="hiddenParams.length > 0" class="hidden-count">({{ hiddenParams.length }})</span>
</el-button>
<el-button class="download-comparison-data-button" @click="handleDownloadComparisonData">
下载对比数据
</el-button>
</div>
</div>
</div>
@ -132,7 +135,7 @@
<div class="model-select-dialog">
<el-input
v-model="modelSearchText"
placeholder="请输入机型名称搜索"
placeholder="请输入产品型号,状态代号/产品编号,平台,系列搜索"
prefix-icon="el-icon-search"
clearable
class="model-search-input"
@ -469,12 +472,19 @@ export default {
return !addedModelIds.has(modelId)
})
//
// modelNameproductNumberplatformseries
if (this.modelSearchText) {
const searchText = this.modelSearchText.toLowerCase()
filtered = filtered.filter(model => {
const modelName = (model.modelName || model.productFullName || '').toLowerCase()
return modelName.includes(searchText)
const productNumber = (model.productNumber || '').toLowerCase()
const platform = (model.platform || '').toLowerCase()
const series = (model.series || '').toLowerCase()
//
return modelName.includes(searchText) ||
productNumber.includes(searchText) ||
platform.includes(searchText) ||
series.includes(searchText)
})
}
@ -692,6 +702,7 @@ export default {
...api.GET_MODEL_QUERY,
params: {
engineModelID: modelId,
userID: getUserId(),
subsystemParts: subsystemTypes // ["-"]
},
disableSuccessMsg: true
@ -1025,6 +1036,84 @@ export default {
console.log('树数据还未加载完成,等待加载完成后再更新选中状态')
}
},
//
handleDownloadComparisonData() {
// ID
const allSelectedIds = this.comparisonModels.map(item => item.id).filter(id => id)
if (allSelectedIds.length === 0) {
this.$message.warning('请先添加机型')
return
}
//
const { subsystemTypes } = this.getSelectedSubsystemsAndTypes()
const { url, method = 'post', headers = {} } = api.DOWNLOAD_MODEL_QUERY_DATA || {}
const requestConfig = {
url,
method,
data: {
userID: getUserId(),
modelIds: allSelectedIds,
subsystemParts: subsystemTypes
},
responseType: 'blob',
headers,
disableSuccessMsg: true
}
this.$axios(requestConfig)
.then((response) => {
const blobData = response.data
if (!blobData) {
console.log('下载失败,文件内容为空')
return
}
const contentType =
response.headers &&
(response.headers['content-type'] || response.headers['Content-Type'])
if (contentType && contentType.includes('application/json')) {
try {
const reader = new FileReader()
reader.onload = () => {
console.log(`下载失败: ${reader.result}`)
}
reader.readAsText(blobData)
} catch (err) {
console.error('解析下载失败响应异常:', err)
}
return
}
const disposition =
response.headers &&
(response.headers['content-disposition'] || response.headers['Content-Disposition'])
let filename = '对比数据.xlsx'
if (disposition) {
const filenameMatch = /filename\*=UTF-8''([^;]+)|filename="?([^";]+)"?/i.exec(
disposition
)
const matchedName = filenameMatch ? filenameMatch[1] || filenameMatch[2] : ''
if (matchedName) {
try {
filename = decodeURIComponent(matchedName)
} catch (err) {
filename = matchedName
}
}
}
const downloadUrl = window.URL.createObjectURL(blobData)
const link = document.createElement('a')
link.href = downloadUrl
link.download = filename
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(downloadUrl)
console.log('下载开始,请查看浏览器下载列表')
})
.catch((err) => {
console.error('下载失败:', err)
console.log('下载失败,请稍后重试')
})
},
//
updateCheckedKeysByDisplayParams() {
// 使
@ -1549,9 +1638,6 @@ export default {
return
}
//
const restoreCount = keysToRestore.length
// hiddenParams
keysToRestore.forEach(key => {
const index = this.hiddenParams.indexOf(key)

View File

@ -16,21 +16,22 @@
<div class="search-fields">
<div class="search-field">
<span class="field-label">模板名称</span>
<el-autocomplete
<el-select
v-model="searchPanelValue.templateName"
:fetch-suggestions="remoteSearchTemplate"
:loading="templateSelectLoading"
placeholder="请输入模板名称"
placeholder="请选择模板名称"
clearable
filterable
style="width: 220px"
@change="handleSearch"
@select="handleSearch"
@keyup.enter.native="handleSearch"
>
<template slot-scope="{ item }">
<div>{{ item.value }}</div>
</template>
</el-autocomplete>
<el-option
v-for="item in templateOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div class="search-actions">
<el-button type="primary" @click="handleDownloadImportTemplate">
@ -172,6 +173,7 @@
:template-version="currentVersion"
:version-list="versionList"
:detail="currentDetail"
:template-management-permissions="templateManagementPermissions"
class="model-detail-wrapper"
@back="handleBackFromDetail"
/>
@ -260,7 +262,8 @@ export default {
downloadingRowId: '',
tenantId: '1764149921900',
userId: getUserId(),
errorDialogVisible: false
errorDialogVisible: false,
templateManagementPermissions: [] // menuPath "/"
}
},
computed: {
@ -322,11 +325,13 @@ export default {
},
mounted() {
// this.loadUserSelfRole()
this.loadTemplateOptions()
this.loadData()
},
methods: {
//
loadUserSelfRole() {
localStorage.setItem('user_self_role', [])
const request = {
...api.GET_USER_SELF_ROLE,
params: {
@ -343,12 +348,41 @@ export default {
} catch (err) {
console.error('存储权限数据到 localStorage 失败:', err)
}
// user_self_role menuPath "/"
this.filterTemplateManagementPermissions()
}
})
.asyncErrorCatch((err) => {
console.error('获取用户自身角色失败:', err)
})
},
//
filterTemplateManagementPermissions() {
try {
const permissionDataStr = localStorage.getItem('user_self_role')
if (!permissionDataStr) {
this.templateManagementPermissions = []
return
}
const permissionData = JSON.parse(permissionDataStr)
if (!Array.isArray(permissionData)) {
this.templateManagementPermissions = []
return
}
// menuPath "/"
this.templateManagementPermissions = permissionData.filter((perm) => {
return perm.menuPath === '数据录入/模板管理'
})
console.log('模板管理权限数据:', this.templateManagementPermissions)
} catch (err) {
console.error('过滤模板管理权限失败:', err)
this.templateManagementPermissions = []
}
},
//
// menuPath: "/"
// subsystem:
@ -449,6 +483,10 @@ export default {
}
//
this.loadVersionList(row)
//
if (this.templateManagementPermissions.length === 0) {
this.loadUserSelfRole()
}
this.showModelDetail = true
},
loadVersionList(row) {
@ -838,7 +876,7 @@ export default {
},
resetSearch() {
Object.assign(this.searchPanelValue, createDefaultSearch())
this.templateOptions = []
this.handleSearch()
},
handleSearch() {
@ -871,18 +909,14 @@ export default {
console.error('查询失败:', err)
})
},
remoteSearchTemplate(query, callback) {
if (!query) {
callback([])
return
}
//
loadTemplateOptions() {
this.templateSelectLoading = true
const request = {
...api.GET_MODEL_LIST,
params: {
pageNumber: 1,
pageSize: 10,
templateName: query
pageSize: 999
},
disableSuccessMsg: true
}
@ -890,7 +924,7 @@ export default {
.asyncThen((resp) => {
const list = resp.data.result || []
const seen = new Set()
const suggestions = list
const options = list
.map((item) => item.templateName || item.po_name || '')
.filter((name) => {
if (!name || seen.has(name)) {
@ -900,15 +934,16 @@ export default {
return true
})
.map((name) => ({
label: name,
value: name
}))
this.templateOptions = options
this.templateSelectLoading = false
callback(suggestions)
})
.asyncErrorCatch((err) => {
console.error('搜索模板失败:', err)
console.error('加载模板列表失败:', err)
this.templateOptions = []
this.templateSelectLoading = false
callback([])
})
},
// UUID

View File

@ -132,6 +132,7 @@
<span class="deleted-text">已删除</span>
</template>
<template v-else>
<template v-if="canEditOrDeleteRow(row)">
<a
href="javascript:void(0)"
class="el-link el-link--primary"
@ -148,6 +149,7 @@
删除
</a>
</template>
</template>
</div>
</template>
<template slot="empty">
@ -480,6 +482,10 @@ export default {
detail: {
type: Object,
default: () => ({})
},
templateManagementPermissions: {
type: Array,
default: () => []
}
},
data: function() {
@ -595,7 +601,20 @@ export default {
// DRAFT COMPLETED
shouldShowMaintainButton() {
const status = this.currentStatus || (this.detail && this.detail.status) || ''
return (status === 'DRAFT' || status === 'COMPLETE') && this.isLatestVersion
const baseCondition = (status === 'DRAFT' || status === 'COMPLETE') && this.isLatestVersion
if (!baseCondition) {
return false
}
//
const templateName = this.displayTemplateName
if (!templateName || !this.templateManagementPermissions || this.templateManagementPermissions.length === 0) {
return false
}
//
const hasSubsystemPermission = this.templateManagementPermissions.some((perm) => {
return perm.subsystem === templateName
})
return hasSubsystemPermission
},
//
isLatestVersion() {
@ -1050,6 +1069,27 @@ export default {
if (!parameterName) {
return false
}
// 使
if (this.templateManagementPermissions && this.templateManagementPermissions.length > 0) {
const templateName = this.displayTemplateName
const matchedPermissions = this.templateManagementPermissions.filter((perm) => {
// subsystem templateName
if (templateName && perm.subsystem !== templateName) {
return false
}
// parameterName
if (perm.parameterName !== parameterName) {
return false
}
// ""
return perm.parameterPer === '编辑'
})
return matchedPermissions.length > 0
}
// localStorage
try {
const permissionDataStr = localStorage.getItem('user_self_role')
if (!permissionDataStr) {
@ -1089,6 +1129,22 @@ export default {
return false
}
},
//
canEditOrDeleteRow(row) {
if (!row) {
return false
}
// createdBy ID/
if (row.createdBy === getUserId()) {
return true
}
// ""/
const parameterName = row.parameterName
if (parameterName && this.hasParameterEditPermission(parameterName)) {
return true
}
return false
},
loadDepartmentList() {
const request = {
...api.QUERY_ORG_TREE,

View File

@ -136,7 +136,7 @@
<span v-if="data.type === 'subsystem'" class="type-tag subsystem-tag">子系统</span>
<span v-if="data.type === 'parameter'" class="type-tag parameter-tag">参数类型</span> -->
</span>
<span v-if="data.type === 'parameter'" class="permission-checkboxes">
<span v-if="data.type === 'subsystem' || data.type === 'parameter'" class="permission-checkboxes">
<el-checkbox
v-model="data.permissions.view"
size="small"
@ -242,14 +242,18 @@
clearable
:remote-method="queryPersonByDepartment"
:loading="personSearchLoading"
value-key="userId"
value-key="userNumber"
class="person-select"
>
<el-option
v-for="item in personOptions"
:key="item.userId"
:key="item.userNumber"
:label="item.username"
:value="item"
/>
:value="item.userNumber"
>
<span class="username-text">{{ item.username }}</span>
<span class="user-id-text">{{ item.userNumber }}</span>
</el-option>
</el-select>
</el-form-item>
</template>
@ -371,7 +375,7 @@ export default {
menuList: [
'模板管理',
'玉柴发动机数据',
'竞品发动机数据',
'竞品发动机数据'
],
//
personConfigDialogVisible: false,
@ -379,7 +383,7 @@ export default {
personConfigFormData: {
configType: 'person', // 'person' 'department'
department: '', // ID
person: [], // {userId, username}
person: [], // el-select v-model userNumber
selectDeptId: '', // ID使
selectDeptName: '', //
selectDeptIds: [], // ID使
@ -503,10 +507,19 @@ export default {
},
//
validatePermissions(rule, value, callback) {
const hasPermission = this.allParameterNodes.some(node => {
//
const hasParameterPermission = this.allParameterNodes.some(node => {
return node.permissions.view || node.permissions.edit
})
if (!hasPermission) {
//
const hasSubsystemPermission = Object.keys(this.nodeMap).some(nodeId => {
const node = this.nodeMap[nodeId]
return node && node.type === 'subsystem' && node.permissions &&
(node.permissions.view || node.permissions.edit)
})
if (!hasParameterPermission && !hasSubsystemPermission) {
callback(new Error('请至少分配一个权限'))
} else {
callback()
@ -626,6 +639,10 @@ export default {
type: 'subsystem',
menuName: menuNode.label,
subsystem: subsystemNameStr,
permissions: {
view: false,
edit: false
},
children: null, // null
isLeaf: false // el-tree
}
@ -723,6 +740,10 @@ export default {
parameterNodes.forEach(node => {
this.applyPendingPermissionsToNode(node)
})
//
if (parameterNodes.length > 0) {
this.updateSubsystemPermissionFromChildren(parameterNodes[0])
}
})
})
.asyncErrorCatch((err) => {
@ -739,6 +760,15 @@ export default {
// 使 $set
this.$set(this.nodeMap[data.id].permissions, permissionType, data.permissions[permissionType])
}
// /
if (data.type === 'subsystem') {
this.updateSubsystemChildParameters(data, permissionType)
} else if (data.type === 'parameter') {
//
this.updateSubsystemPermissionFromChildren(data)
}
//
this.$nextTick(() => {
if (this.$refs.form) {
@ -746,6 +776,77 @@ export default {
}
})
},
//
updateSubsystemChildParameters(subsystemNode, permissionType) {
const subsystemId = subsystemNode.id
const newValue = subsystemNode.permissions[permissionType]
//
Object.keys(this.nodeMap).forEach(nodeId => {
const node = this.nodeMap[nodeId]
if (node && node.type === 'parameter' && node.id && node.id.startsWith(subsystemId + '-param-')) {
//
if (!node.permissions) {
this.$set(node, 'permissions', { view: false, edit: false })
}
//
this.$set(node.permissions, permissionType, newValue)
}
})
},
//
updateSubsystemPermissionFromChildren(parameterNode) {
if (!parameterNode || !parameterNode.id) {
return
}
//
const subsystemId = parameterNode.id.split('-param-')[0]
const subsystemNode = this.nodeMap[subsystemId]
if (!subsystemNode || subsystemNode.type !== 'subsystem') {
return
}
//
if (!subsystemNode.permissions) {
this.$set(subsystemNode, 'permissions', { view: false, edit: false })
}
//
const childParameterNodes = []
Object.keys(this.nodeMap).forEach(nodeId => {
const node = this.nodeMap[nodeId]
if (node && node.type === 'parameter' && node.id && node.id.startsWith(subsystemId + '-param-')) {
childParameterNodes.push(node)
}
})
if (childParameterNodes.length === 0) {
return
}
//
const allViewSelected = childParameterNodes.every(node => node.permissions && node.permissions.view)
const noneViewSelected = childParameterNodes.every(node => !node.permissions || !node.permissions.view)
//
const allEditSelected = childParameterNodes.every(node => node.permissions && node.permissions.edit)
const noneEditSelected = childParameterNodes.every(node => !node.permissions || !node.permissions.edit)
//
if (allViewSelected) {
this.$set(subsystemNode.permissions, 'view', true)
} else if (noneViewSelected) {
this.$set(subsystemNode.permissions, 'view', false)
}
if (allEditSelected) {
this.$set(subsystemNode.permissions, 'edit', true)
} else if (noneEditSelected) {
this.$set(subsystemNode.permissions, 'edit', false)
}
},
//
loadPermissionData() {
const request = {
@ -802,11 +903,11 @@ export default {
: {
roleName: this.addRoleFormData.roleName,
roleDescription: this.addRoleFormData.roleDescription
}
},
disableSuccessMsg: true
}
this.$request(request)
.asyncThen((resp) => {
this.handleAddRoleDialogClose()
this.loadPermissionData()
})
@ -919,13 +1020,33 @@ export default {
this.$request(request)
.asyncThen((resp) => {
if (resp && resp.data) {
this.personOptions = resp.data
//
let result = []
if (Array.isArray(resp.data)) {
result = resp.data
} else if (resp.data.result && Array.isArray(resp.data.result)) {
result = resp.data.result
} else if (resp.data.data && Array.isArray(resp.data.data)) {
result = resp.data.data
}
// {userId: user.userId, username: user.username, userNumber: user.userNumber}
this.personOptions = result.map((user) => ({
userId: user.userId || user.id,
username: user.username || user.name,
userNumber: user.userNumber || user.userId || user.id
}))
// userNumber
this.personConfigFormData.person = this.personOptions.map(opt => opt.userNumber)
} else {
this.personOptions = []
this.personConfigFormData.person = []
}
})
.asyncErrorCatch((err) => {
console.error('加载人员列表失败:', err)
})
this.personOptions = []
this.personConfigFormData.person = []
})
this.personConfigDialogVisible = true
this.$nextTick(() => {
if (this.$refs.personConfigForm) {
@ -1047,20 +1168,14 @@ export default {
},
// el-select
queryPersonByDepartment(queryString) {
//
if (!queryString || queryString.trim() === '') {
//
if (this.personConfigFormData.person && this.personConfigFormData.person.length > 0) {
const selectedOptions = this.personOptions.filter(opt =>
this.personConfigFormData.person.some(p => p.userId === opt.userId)
// options
const selectedOptions = this.personOptions.filter((opt) =>
this.personConfigFormData.person.includes(opt.userNumber)
)
const missingIds = this.personConfigFormData.person.filter(p =>
!selectedOptions.some(opt => opt.userId === p.userId)
)
if (missingIds.length > 0) {
this.personOptions = [...selectedOptions, ...missingIds]
} else {
this.personOptions = selectedOptions
}
} else {
this.personOptions = []
}
@ -1104,36 +1219,38 @@ export default {
result = respData.data
}
// {userId: user.userId, username: user.username}
// {userId: user.userId, username: user.username, userNumber: user.userNumber}
const users = result
.map(user => ({
.map((user) => ({
userId: user.userId || user.id,
username: user.username || user.name
username: user.username || user.name,
userNumber: user.userNumber || user.userId || user.id
}))
.filter(user => user.userId && user.username) // userId username
.filter((user) => user.userId && user.userNumber) // userId userNumber
// personConfigFormData.person {userId, username}
const existingIds = new Set(
(this.personConfigFormData.person || []).map(p => p.userId)
// personConfigFormData.person userNumber
const existingUserNumbers = new Set(
(this.personConfigFormData.person || []).map(p => p)
)
//
const filteredUsers = users.filter(user => !existingIds.has(user.userId))
const filteredUsers = users.filter(user => !existingUserNumbers.has(user.userNumber))
// options +
const selectedOptions = (this.personOptions || []).filter(opt =>
opt.userId && this.personConfigFormData.person && this.personConfigFormData.person.some(p => p.userId === opt.userId)
const selectedOptions = this.personOptions.filter(
(opt) => opt.userNumber && this.personConfigFormData.person && this.personConfigFormData.person.includes(opt.userNumber)
)
// 使 Map userId
// 使 Map userNumber
const optionsMap = new Map()
//
selectedOptions.forEach(opt => {
if (opt.userId) {
optionsMap.set(opt.userId, opt)
selectedOptions.forEach((opt) => {
if (opt.userNumber) {
optionsMap.set(opt.userNumber, opt)
}
})
//
filteredUsers.forEach(user => {
if (user.userId && !optionsMap.has(user.userId)) {
optionsMap.set(user.userId, user)
filteredUsers.forEach((user) => {
if (user.userNumber && !optionsMap.has(user.userNumber)) {
optionsMap.set(user.userNumber, user)
}
})
this.personOptions = Array.from(optionsMap.values())
@ -1144,8 +1261,8 @@ export default {
console.error('搜索人员失败:', err)
//
if (this.personConfigFormData.person && this.personConfigFormData.person.length > 0) {
const selectedOptions = this.personOptions.filter(opt =>
this.personConfigFormData.person.some(p => p.userId === opt.userId)
const selectedOptions = this.personOptions.filter((opt) =>
this.personConfigFormData.person.includes(opt.userNumber)
)
this.personOptions = selectedOptions
} else {
@ -1218,7 +1335,12 @@ export default {
} else {
// ID
isDept = 0
userOrDeptId = this.personConfigFormData.person.map(p => p.userId || p.id).filter(id => id)
// personConfigFormData.person userNumber userId
userOrDeptId = this.personConfigFormData.person.map(userNumber => {
// personOptions userId
const option = this.personOptions.find(opt => opt.userNumber === userNumber)
return option ? option.userId : null
}).filter(id => id)
if (userOrDeptId.length === 0) {
this.$message.warning('请至少选择一个人员')
this.personConfigSubmitting = false
@ -1240,12 +1362,12 @@ export default {
roleId: this.personConfigFormData.roleId,
userOrDeptIds: userOrDeptId,
isDept: isDept
}
},
disableSuccessMsg: true
}
this.$request(request)
.asyncThen((resp) => {
this.handlePersonConfigDialogClose()
this.loadPermissionData()
})
@ -1305,14 +1427,24 @@ export default {
if (node && node.permissions) {
node.permissions.view = false
node.permissions.edit = false
} else if (node && (node.type === 'subsystem' || node.type === 'parameter')) {
//
this.$set(node, 'permissions', { view: false, edit: false })
}
})
},
// menuPath
// menuPath : "/" -> ""
// menuList menuPath
extractMenuNameFromPath(menuPath) {
if (!menuPath) return ''
// "/"
// menuList
for (const menuName of this.menuList) {
if (menuPath.includes(menuName)) {
return menuName
}
}
// "/"
const parts = menuPath.split('/')
return parts.length > 0 ? parts[parts.length - 1].trim() : menuPath.trim()
},
@ -1320,7 +1452,7 @@ export default {
setPermissionsFromData(permissions) {
// permissions
// { id, menuPath, subsystem, parameterName, parameterId, parameterPer }
// parameterPer "" ""
// parameterPer "" ""1 2
const permArray = Array.isArray(permissions) ? permissions : []
//
@ -1331,33 +1463,74 @@ export default {
//
const processedPerms = permArray.map(perm => {
// menuPath menuList
const menuName = this.extractMenuNameFromPath(perm.menuPath || '')
// parameterPer
let isView = false
let isEdit = false
const parameterPer = perm.parameterPer
if (typeof parameterPer === 'string') {
isView = parameterPer === '查看'
isEdit = parameterPer === '编辑'
} else if (typeof parameterPer === 'number') {
isView = parameterPer === 1
isEdit = parameterPer === 2
}
return {
...perm,
menuName: menuName, //
view: perm.parameterPer === '查看',
edit: perm.parameterPer === '编辑'
view: isView,
edit: isEdit
}
})
// menuNamesubsystemparameterName
//
const parameterPermMap = new Map()
processedPerms.forEach(perm => {
const key = `${perm.menuName || ''}_${perm.subsystem || ''}_${perm.parameterName || ''}`
if (!parameterPermMap.has(key)) {
parameterPermMap.set(key, {
menuName: perm.menuName,
subsystem: perm.subsystem,
parameterName: perm.parameterName,
view: false,
edit: false
})
}
const paramPerm = parameterPermMap.get(key)
if (perm.view) {
paramPerm.view = true
}
if (perm.edit) {
paramPerm.edit = true
}
})
//
parameterPermMap.forEach((paramPerm, key) => {
Object.keys(this.nodeMap).forEach(nodeId => {
const node = this.nodeMap[nodeId]
if (node && node.type === 'parameter') {
// menuPath
const menuMatch = perm.menuName && node.menuName && perm.menuName === node.menuName
const menuMatch = paramPerm.menuName && node.menuName && paramPerm.menuName === node.menuName
// subsystem
const subsystemMatch = perm.subsystem && node.subsystem && perm.subsystem === node.subsystem
const subsystemMatch = paramPerm.subsystem && node.subsystem && paramPerm.subsystem === node.subsystem
// parameterName
const parameterNameMatch = perm.parameterName && (node.parameterName || node.label) &&
perm.parameterName === (node.parameterName || node.label)
const parameterNameMatch = paramPerm.parameterName && (node.parameterName || node.label) &&
paramPerm.parameterName === (node.parameterName || node.label)
if (menuMatch && subsystemMatch && parameterNameMatch) {
// 使 $set
//
if (!node.permissions) {
this.$set(node, 'permissions', { view: false, edit: false })
}
//
const newPermissions = {
view: perm.view || false,
edit: perm.edit || false
view: node.permissions.view || paramPerm.view,
edit: node.permissions.edit || paramPerm.edit
}
this.$set(node, 'permissions', newPermissions)
console.log('设置已加载节点权限:', node.id, node.label, {
@ -1370,6 +1543,23 @@ export default {
})
})
//
this.$nextTick(() => {
Object.keys(this.nodeMap).forEach(nodeId => {
const node = this.nodeMap[nodeId]
if (node && node.type === 'subsystem') {
//
const childParameterNode = Object.keys(this.nodeMap).find(id => {
const childNode = this.nodeMap[id]
return childNode && childNode.type === 'parameter' && childNode.id && childNode.id.startsWith(nodeId + '-param-')
})
if (childParameterNode) {
this.updateSubsystemPermissionFromChildren(this.nodeMap[childParameterNode])
}
}
})
})
console.log('权限数据已保存,待应用权限数量:', this.pendingPermissions.length, '处理后的权限:', processedPerms)
},
//
@ -1399,15 +1589,24 @@ export default {
this.$set(node, 'permissions', { view: false, edit: false })
}
// parameterPer "" ""
// parameterPer "" "" 1 2
let hasView = false
let hasEdit = false
matchingPerms.forEach(perm => {
if (perm.parameterPer === '查看') {
const parameterPer = perm.parameterPer
if (typeof parameterPer === 'string') {
if (parameterPer === '查看') {
hasView = true
} else if (perm.parameterPer === '编辑') {
} else if (parameterPer === '编辑') {
hasEdit = true
}
} else if (typeof parameterPer === 'number') {
if (parameterPer === 1) {
hasView = true
} else if (parameterPer === 2) {
hasEdit = true
}
}
})
// 使 $set
@ -1435,14 +1634,27 @@ export default {
const roleId = this.formData.rowId || ''
const userId = getUserId()
// nodeMap
//
//
Object.keys(this.nodeMap).forEach(nodeId => {
const node = this.nodeMap[nodeId]
if (node && node.type === 'parameter') {
//
const nodePermissions = node.permissions || { view: false, edit: false }
//
const subsystemId = node.id.split('-param-')[0]
const subsystemNode = this.nodeMap[subsystemId]
const subsystemPermissions = subsystemNode && subsystemNode.permissions
? subsystemNode.permissions
: { view: false, edit: false }
//
const shouldCollectView = nodePermissions.view || subsystemPermissions.view
const shouldCollectEdit = nodePermissions.edit || subsystemPermissions.edit
// parameterPer = 1
if (nodePermissions.view) {
if (shouldCollectView) {
permissions.push({
roleId: roleId,
menuName: node.menuName || '',
@ -1452,7 +1664,7 @@ export default {
})
}
// parameterPer = 2
if (nodePermissions.edit) {
if (shouldCollectEdit) {
permissions.push({
roleId: roleId,
menuName: node.menuName || '',
@ -1501,7 +1713,6 @@ export default {
}
this.$request(request)
.asyncThen((resp) => {
this.handleDialogClose()
this.loadPermissionData()
})
@ -1532,7 +1743,6 @@ export default {
this.$request(request)
.asyncThen((resp) => {
this.loadPermissionData()
})
.asyncErrorCatch((err) => {
console.error('删除失败:', err)
@ -1703,4 +1913,30 @@ export default {
.page-content {
width: calc(100% - 80px) !important;
}
.person-select {
width: 100%;
}
::v-deep .person-select {
.el-select-dropdown__item {
display: flex !important;
justify-content: space-between !important;
padding-right: 20px !important;
}
}
.username-text {
color: #303133 !important;
display: inline-block;
text-align: right !important;
}
.user-id-text {
color: #909399 !important;
display: inline-block;
margin-left: 20px;
margin-right: 30px;
text-align: right !important;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,7 @@ import ApaasCustomOtherEnginedata from './custom-page/otherEnginedata.vue'
import ApaasCustomCheckData from './custom-page/checkData.vue'
import ApaasCustomReportCheck from './custom-page/reportCheck.vue'
import ApaasCustomReport from './custom-page/report.vue'
import ApaasCustomReportList from './custom-page/reportList.vue'
import ApaasSelfEngineCheck from './custom-page/selfEngineCheck.vue'
import ApaasOtherEngineCheck from './custom-page/otherEngineCheck.vue'
import ApaasCustomManagerData from './custom-page/managerData.vue'
@ -34,6 +35,7 @@ const install = function(Vue, opts) {
Vue.component('apaas-custom-reportCheck', ApaasCustomReportCheck)
Vue.component('apaas-custom-engineDetail', ApaasCustomEngineDetail)
Vue.component('apaas-custom-report', ApaasCustomReport)
Vue.component('apaas-custom-reportList', ApaasCustomReportList)
Vue.component('apaas-custom-reportDetail', ApaasCustomReportDetail)
Vue.component('apaas-custom-approvalManagement', ApaasCustomApprovalManagement)
Vue.component('apaas-custom-toDoList', ApaasCustomTodoList)