This commit is contained in:
2026-08-12 16:58:52 +08:00
parent a44fd5f235
commit 16c5ed6301
13 changed files with 254 additions and 73 deletions
+25 -6
View File
@@ -19,7 +19,7 @@ import StatusBadge from '@/shared/components/StatusBadge.vue'
import DataTable, { type DataTableColumn } from '@/shared/components/DataTable.vue'
import QueryToolbar, { type QueryField, type QueryModel } from '@/shared/components/QueryToolbar.vue'
import AdminPage from '@/shared/components/AdminPage.vue'
import AppDrawer from '@/shared/components/AppDrawer.vue'
import AppDialog from '@/shared/components/AppDialog.vue'
import FormSection from '@/shared/components/FormSection.vue'
import ListPageLayout from '@/shared/components/ListPageLayout.vue'
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
@@ -259,11 +259,30 @@ onMounted(loadRoles)
</section>
</ListPageLayout>
<AppDrawer v-model="editorOpen" :title="form.id ? '配置角色' : '新增角色'" size="760px" class="business-drawer editor-drawer" :modal="false" :confirm-loading="saving" confirm-text="保存角色" :show-confirm="form.id ? canEdit || canGrant : canCreate" @confirm="saveRole">
<el-form ref="formRef" :model="form" :rules="formRules" label-position="top" class="drawer-form">
<FormSection title="基本信息" description="维护角色名称、编码和职责说明。"><div class="form-grid two-cols"><el-form-item label="角色名称" prop="name" required><el-input v-model="form.name" :disabled="Boolean(form.id) && !canEdit" placeholder="如:订单运营专员" maxlength="64" /></el-form-item><el-form-item label="角色编码" prop="code" required><el-input v-model="form.code" :disabled="Boolean(form.id)" placeholder="如:ORDER_OPERATOR" maxlength="64" /></el-form-item></div><el-form-item label="角色说明"><el-input v-model="form.description" :disabled="Boolean(form.id) && !canEdit" type="textarea" :rows="2" placeholder="说明该角色的工作范围" maxlength="200" show-word-limit /></el-form-item></FormSection>
<FormSection v-if="canGrant" title="菜单与操作权限" :description="`保存时按后端契约全量替换当前角色权限;当前 ${form.permissionIds.length} 项授权。`"><el-tree ref="treeRef" class="permission-tree" :data="permissionTree" node-key="id" show-checkbox check-strictly default-expand-all :props="{ label: 'name', children: 'children' }" @check="syncPermissionIds"><template #default="{ data }"><div class="permission-node"><span>{{ data.name }}</span><code>{{ data.code }}</code></div></template></el-tree></FormSection>
<AppDialog v-model="editorOpen" :title="form.id ? '配置角色' : '新增角色'" width="min(860px, calc(100vw - 28px))" class="role-editor-dialog" :confirm-loading="saving" confirm-text="保存角色" :show-confirm="form.id ? canEdit || canGrant : canCreate" destroy-on-close @confirm="saveRole">
<el-form ref="formRef" :model="form" :rules="formRules" label-position="top" class="role-editor-form">
<div class="role-editor-layout">
<FormSection title="基本信息" description="维护角色名称、编码和职责说明。" class="role-editor-basic">
<el-form-item label="角色名称" prop="name" required><el-input v-model="form.name" :disabled="Boolean(form.id) && !canEdit" placeholder="如:订单运营专员" maxlength="64" /></el-form-item>
<el-form-item label="角色编码" prop="code" required><el-input v-model="form.code" :disabled="Boolean(form.id)" placeholder="如:ORDER_OPERATOR" maxlength="64" /></el-form-item>
<el-form-item label="角色说明"><el-input v-model="form.description" :disabled="Boolean(form.id) && !canEdit" type="textarea" :rows="3" placeholder="说明该角色的工作范围" maxlength="200" show-word-limit /></el-form-item>
</FormSection>
<FormSection v-if="canGrant" title="菜单与操作权限" :description="`保存时按后端契约全量替换当前角色权限;当前 ${form.permissionIds.length} 项授权。`" class="role-editor-permissions"><el-tree ref="treeRef" class="permission-tree" :data="permissionTree" node-key="id" show-checkbox check-strictly default-expand-all :props="{ label: 'name', children: 'children' }" @check="syncPermissionIds"><template #default="{ data }"><div class="permission-node"><span>{{ data.name }}</span><code>{{ data.code }}</code></div></template></el-tree></FormSection>
</div>
</el-form>
</AppDrawer>
</AppDialog>
</AdminPage>
</template>
<style scoped>
.role-editor-layout { display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.3fr); gap: 20px; }
.role-editor-permissions { min-width: 0; padding-left: 20px; border-left: 1px solid var(--cc-border); }
.permission-tree { max-height: 380px; overflow-y: auto; }
:global(.role-editor-dialog) { max-height: min(760px, calc(100vh - 32px)); display: flex; flex-direction: column; }
:global(.role-editor-dialog .el-dialog__body) { min-height: 0; overflow-y: auto; }
:global(.role-editor-dialog .el-dialog__footer) { flex: 0 0 auto; }
@media (max-width: 720px) {
.role-editor-layout { grid-template-columns: minmax(0, 1fr); }
.role-editor-permissions { padding-top: 18px; padding-left: 0; border-top: 1px solid var(--cc-border); border-left: 0; }
}
</style>