init: UserBaseFront (frontend)
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
<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) {
|
||||
Message.error(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>
|
||||
Reference in New Issue
Block a user