feat: ship OA drafts/badges, role dual-track, and test-env deploy tooling.
Add approval instance drafts with menu badges, dual-track user/role read model and role bound names, form-designer outline docs, and bare-metal test deploy scripts. Ignore local test-server credential file. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
7af53fc344
commit
de22678c87
56 files changed
+11861
-6082
No files matched your search
@@ -72,7 +72,46 @@
|
||||
min-width="140"
|
||||
align="center"
|
||||
header-align="center"
|
||||
/>
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
class="no-auto-icon"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleView(row)"
|
||||
>
|
||||
{{ row.roleName || '-' }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="拥有用户"
|
||||
min-width="180"
|
||||
align="center"
|
||||
header-align="center"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<span class="role-bound-names-cell">{{
|
||||
(row.boundUserNames || []).length
|
||||
? (row.boundUserNames || []).join('、')
|
||||
: '—'
|
||||
}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="关联职位"
|
||||
min-width="160"
|
||||
align="center"
|
||||
header-align="center"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<span class="role-bound-names-cell">{{
|
||||
(row.boundPostNames || []).length
|
||||
? (row.boundPostNames || []).join('、')
|
||||
: '—'
|
||||
}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="dataScope"
|
||||
label="数据权限"
|
||||
@@ -1054,6 +1093,15 @@
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.role-bound-names-cell {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
line-height: 1.45;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.role-dialog-form,
|
||||
.data-scope-form {
|
||||
:deep(.el-form-item) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<section class="panel">
|
||||
<div class="flex gap-4">
|
||||
<!-- 左侧:组织树 -->
|
||||
<div class="user-dept-aside w-[280px] shrink-0 border-r border-[var(--mint-border)] pr-4">
|
||||
<div class="user-dept-aside w-[200px] shrink-0 border-r border-[var(--mint-border)] pr-4">
|
||||
<!-- 标题与搜索同处 panel-top:避免标题栏底边与独立输入框之间出现不可控的视觉断层 -->
|
||||
<div class="panel-top user-dept-aside__head">
|
||||
<h2>组织</h2>
|
||||
@@ -131,7 +131,14 @@
|
||||
<template #default="{ row }">
|
||||
<div class="user-nick-cell">
|
||||
<el-avatar :size="24" :src="resolveUserAvatarFromInfo(row)" />
|
||||
<span class="user-nick-cell__name">{{ row.nickName }}</span>
|
||||
<el-button
|
||||
class="user-nick-cell__name no-auto-icon"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleView(row)"
|
||||
>
|
||||
{{ row.nickName || '-' }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -146,6 +153,26 @@
|
||||
{{ formatUserDeptDisplay(row) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="职位"
|
||||
min-width="140"
|
||||
align="left"
|
||||
header-align="left"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<span class="user-multi-label-cell">{{ formatUserPostDisplay(row) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="角色"
|
||||
min-width="160"
|
||||
align="left"
|
||||
header-align="left"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<span class="user-multi-label-cell">{{ formatUserEffectiveRoleDisplay(row) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="phoneNo"
|
||||
label="手机号"
|
||||
@@ -357,22 +384,6 @@
|
||||
<el-option label="停用" value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="角色" style="grid-column: 1 / -1">
|
||||
<el-select
|
||||
v-model="formData.roleIds"
|
||||
multiple
|
||||
filterable
|
||||
placeholder="请选择角色"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in roleOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="职位" style="grid-column: 1 / -1">
|
||||
<el-select
|
||||
v-model="formData.postIds"
|
||||
@@ -511,15 +522,28 @@
|
||||
return deptPathLabelMap.value.get(id) || row.deptName || '—'
|
||||
}
|
||||
|
||||
function formatUserRoleDisplay(row: Api.User.UserItem) {
|
||||
const ids = row.roleIds || []
|
||||
if (!ids.length) return '—'
|
||||
function formatRoleIdsDisplay(ids: string[] | undefined | null) {
|
||||
if (!ids?.length) return '—'
|
||||
const labels = ids
|
||||
.map((id) => roleOptions.value.find((o) => o.value === id)?.label)
|
||||
.filter((name): name is string => Boolean(name))
|
||||
return labels.length ? labels.join('、') : '—'
|
||||
}
|
||||
|
||||
function formatUserEffectiveRoleDisplay(row: Api.User.UserItem) {
|
||||
const names = row.effectiveRoleNames || []
|
||||
if (names.length) return names.join('、')
|
||||
return formatRoleIdsDisplay(row.effectiveRoleIds)
|
||||
}
|
||||
|
||||
function formatUserDirectRoleDisplay(row: Api.User.UserItem) {
|
||||
return formatRoleIdsDisplay(row.roleIds)
|
||||
}
|
||||
|
||||
function formatUserPostInheritedRoleDisplay(row: Api.User.UserItem) {
|
||||
return formatRoleIdsDisplay(row.postInheritedRoleIds)
|
||||
}
|
||||
|
||||
function formatUserPostDisplay(row: Api.User.UserItem) {
|
||||
const ids = row.postIds || []
|
||||
if (!ids.length) return '—'
|
||||
@@ -558,7 +582,6 @@
|
||||
status: '1',
|
||||
orderNum: 0,
|
||||
remark: '',
|
||||
roleIds: [] as string[],
|
||||
postIds: [] as string[]
|
||||
})
|
||||
|
||||
@@ -667,7 +690,6 @@
|
||||
formData.status = '1'
|
||||
formData.orderNum = 0
|
||||
formData.remark = ''
|
||||
formData.roleIds = []
|
||||
formData.postIds = []
|
||||
supervisorUserOptions.value = []
|
||||
editingId.value = null
|
||||
@@ -708,7 +730,6 @@
|
||||
formData.status = detail.status || '1'
|
||||
formData.orderNum = detail.orderNum ?? 0
|
||||
formData.remark = detail.remark || ''
|
||||
formData.roleIds = detail.roleIds ? [...detail.roleIds] : []
|
||||
formData.postIds = detail.postIds ? [...detail.postIds] : []
|
||||
if (formData.supervisorUserId) {
|
||||
await remoteSearchSupervisorUsers(detail.nickName || '')
|
||||
@@ -744,7 +765,6 @@
|
||||
status: formData.status,
|
||||
orderNum: formData.orderNum,
|
||||
remark: formData.remark?.trim() || undefined,
|
||||
roleIds: [...formData.roleIds],
|
||||
postIds: [...formData.postIds]
|
||||
})
|
||||
} else {
|
||||
@@ -763,7 +783,6 @@
|
||||
status: formData.status,
|
||||
orderNum: formData.orderNum,
|
||||
remark: formData.remark?.trim() || undefined,
|
||||
roleIds: formData.roleIds.length ? formData.roleIds : undefined,
|
||||
postIds: formData.postIds.length ? formData.postIds : undefined
|
||||
})
|
||||
}
|
||||
@@ -882,7 +901,9 @@
|
||||
value: row.status === '1' ? '正常' : '停用',
|
||||
tagType: row.status === '1' ? 'success' : 'info'
|
||||
},
|
||||
{ label: '角色', value: formatUserRoleDisplay(row), span: true },
|
||||
{ label: '有效角色', value: formatUserEffectiveRoleDisplay(row), span: true },
|
||||
{ label: '直接绑定角色', value: formatUserDirectRoleDisplay(row), span: true },
|
||||
{ label: '职位继承角色', value: formatUserPostInheritedRoleDisplay(row), span: true },
|
||||
{ label: '职位', value: formatUserPostDisplay(row), span: true },
|
||||
{ label: '创建时间', value: row.createTime },
|
||||
{ label: '备注', value: row.remark, span: true }
|
||||
@@ -964,9 +985,24 @@
|
||||
}
|
||||
|
||||
&__name {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
justify-content: flex-start;
|
||||
padding: 0;
|
||||
height: auto;
|
||||
font-size: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
/* 职位 / 角色多项用顿号分隔,列宽不足时自然换行 */
|
||||
.user-multi-label-cell {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
line-height: 1.5;
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user