Files
UserhomeFront/src/views/role-authz/RoleManage.vue
T
2026-08-18 23:31:27 +08:00

186 lines
5.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="main-wrapper">
<div class="main-container">
<Alert show-icon>角色管理:在此新增 / 编辑 / 删除业务角色。普通角色关联单一应用,全应用角色作用于全部应用。</Alert>
<div class="toolbar fix">
<Button class="fl" type="text" @click="goAuthz">← 角色授权</Button>
<Button class="fl" type="primary" @click="handleAdd">新增角色</Button>
<Input class="fr" v-model="keyword" placeholder="输入角色名称筛选" search clearable suffix="ios-search"
style="width:240px" @on-search="onSearch" @on-clear="onSearch" />
</div>
<div class="role-grid">
<div v-for="role in filteredRoles" :key="role.id" class="role-card">
<div class="role-card-hd">
<span class="role-card-name">{{ role.name }}</span>
<Tag v-if="role.allAppFlag" color="blue">全应用</Tag>
<Tag v-else color="default">普通</Tag>
</div>
<div class="role-card-sub">{{ role.allAppFlag ? "全部应用" : (role.appName || "-") }}</div>
<div class="role-card-ft">
<span class="act" @click="handleEdit(role)">编辑</span>
<span class="act act-del" @click="handleDelete(role)">删除</span>
</div>
</div>
<div v-if="!filteredRoles.length" class="role-empty">暂无角色</div>
</div>
</div>
<AddRoleContainer ref="addRef" />
<EditRoleContainer ref="editRef" />
</div>
</template>
<script lang="ts" setup>
import { ref, computed } from "vue";
import { useRouter } from "vue-router";
import MyConfirm from "@/components/MyConfirm";
import AddRoleContainer from "./AddRoleContainer.vue";
import EditRoleContainer from "./EditRoleContainer.vue";
defineOptions({ name: "RoleManage" });
const router = useRouter();
const keyword = ref("");
// 非分页:一次性拉全量角色(约 40-50 条),参照 AppCategory 的管理范式
const { data: roleData, send: sendRoles } = useRequest(
Apis.AppRole.roleList({
params: { pageIndex: 1, pageSize: 9999 },
transform: (res: any) => res?.content ?? [],
cacheFor: null,
}),
{ initialData: [] }
);
const allRoles = computed<Array<any>>(() => roleData.value ?? []);
// 名称手动筛选(on-search / on-clear 才触发)
const filteredRoles = computed(() => {
const kw = keyword.value.trim();
if (!kw) return allRoles.value;
return allRoles.value.filter((r: any) => (r.name || "").includes(kw));
});
function onSearch() {
// computed 已响应 keyword
}
const addRef = ref();
function handleAdd() {
addRef.value?.open(() => sendRoles());
}
const editRef = ref();
function handleEdit(row: any) {
editRef.value?.open(row.id, row, () => sendRoles());
}
async function handleDelete(row: any) {
await MyConfirm({
msg: `确定删除角色「${row.name || row.id}」吗?`,
info: "删除后将一并清理其模块授权与用户绑定,不可恢复!",
async onOk() {
try {
await Apis.AppRole.roleDelete({ pathParams: { id: row.id } });
Message.success("删除成功!");
await sendRoles();
} catch (e: any) {
console.warn(e?.message || "删除失败");
}
},
});
}
function goAuthz() {
router.push("/role-authz/list");
}
</script>
<style lang="scss" scoped>
.toolbar {
margin: 12px 0 16px;
}
.role-grid {
display: flex;
flex-wrap: wrap;
gap: 15px;
}
.role-card {
width: 240px;
background: #ffffff;
border: 1px solid #e9e9e9;
border-radius: 2px;
overflow: hidden;
.role-card-hd {
height: 56px;
border-bottom: 1px solid #f0f0f0;
padding: 0 15px;
display: flex;
align-items: center;
gap: 8px;
}
.role-card-name {
font-size: 15px;
font-weight: 500;
color: #272829;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
}
.role-card-sub {
height: 38px;
line-height: 38px;
padding: 0 15px;
color: #888;
font-size: 13px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.role-card-ft {
display: flex;
height: 32px;
line-height: 32px;
background: #f7f7f7;
border-top: 1px solid #e9e9e9;
.act {
flex: 1;
text-align: center;
font-size: 12px;
cursor: pointer;
color: #577afb;
&:hover {
color: #6c91f0;
}
}
.act-del {
color: #ed4014;
&:hover {
color: #f16643;
}
}
}
}
.role-empty {
width: 100%;
text-align: center;
color: #bbb;
padding: 40px 0;
font-size: 13px;
}
</style>