<template>
|
<div class="page">
|
<el-form :inline="true" class="search-form" @submit.prevent="doSearch">
|
<el-form-item label="角色名称">
|
<el-input v-model="filters.roleName" placeholder="请输入角色名称" clearable style="width: 160px" />
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" native-type="submit">搜索</el-button>
|
<el-button @click="resetSearch">重置</el-button>
|
</el-form-item>
|
<el-form-item class="push-right">
|
<el-button v-permission="'sys:roles:create'" type="primary" @click="goCreate">新增</el-button>
|
</el-form-item>
|
</el-form>
|
|
<div class="table-wrap">
|
<el-table :data="rows" v-loading="loading" stripe height="100%">
|
<el-table-column label="序号" width="64" type="index" :index="indexMethod" />
|
<el-table-column prop="roleName" label="角色名称" min-width="140" show-overflow-tooltip />
|
<el-table-column label="关联账号数" width="120" align="center">
|
<template #default="{ row }">{{ row.userCount }}</template>
|
</el-table-column>
|
<el-table-column label="创建时间" width="170">
|
<template #default="{ row }">
|
{{ formatTime(row.createTime) }}
|
</template>
|
</el-table-column>
|
<el-table-column prop="remark" label="备注" min-width="160" show-overflow-tooltip />
|
<el-table-column label="操作" width="200" fixed="right">
|
<template #default="{ row }">
|
<div class="table-ops">
|
<el-button v-permission="'sys:roles:detail'" type="primary" link @click="goDetail(row)">详情</el-button>
|
<el-button v-permission="'sys:roles:update'" type="primary" link @click="goEdit(row)">编辑</el-button>
|
<el-button
|
v-permission="'sys:roles:delete'"
|
type="primary"
|
link
|
:disabled="row.userCount > 0"
|
@click="confirmDelete(row)"
|
>
|
删除
|
</el-button>
|
</div>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
|
<el-pagination
|
class="main-pager"
|
background
|
layout="sizes, prev, pager, next"
|
:total="total"
|
:page-size="size"
|
:page-sizes="[10, 20, 50, 100]"
|
v-model:current-page="page"
|
@current-change="load"
|
@size-change="onSizeChange"
|
/>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import { onMounted, reactive, ref } from "vue";
|
import { useRouter } from "vue-router";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
import http from "../api/http";
|
|
type RoleRow = {
|
id: number;
|
uuid: string;
|
roleName: string;
|
remark?: string;
|
userCount: number;
|
createTime?: string;
|
};
|
|
const router = useRouter();
|
const loading = ref(false);
|
const rows = ref<RoleRow[]>([]);
|
const page = ref(1);
|
const size = ref(10);
|
const total = ref(0);
|
|
const filters = reactive({
|
roleName: "",
|
});
|
|
function indexMethod(idx: number) {
|
return (page.value - 1) * size.value + idx + 1;
|
}
|
|
function formatTime(v: unknown) {
|
if (v == null || v === "") return "—";
|
const s = String(v);
|
return s.length >= 19 ? s.slice(0, 19).replace("T", " ") : s;
|
}
|
|
function buildQueryParams() {
|
return {
|
page: page.value,
|
size: size.value,
|
roleName: filters.roleName?.trim() || undefined,
|
};
|
}
|
|
async function load() {
|
loading.value = true;
|
try {
|
const { data } = await http.get("/sys/role-manage", { params: buildQueryParams() });
|
rows.value = (data.result || []) as RoleRow[];
|
total.value = Number(data.total) || 0;
|
} catch (e: unknown) {
|
ElMessage.error(e instanceof Error ? e.message : "加载失败");
|
} finally {
|
loading.value = false;
|
}
|
}
|
|
function doSearch() {
|
page.value = 1;
|
load();
|
}
|
|
function resetSearch() {
|
filters.roleName = "";
|
page.value = 1;
|
load();
|
}
|
|
function onSizeChange(nextSize: number) {
|
size.value = nextSize;
|
page.value = 1;
|
load();
|
}
|
|
function goCreate() {
|
router.push({ name: "role-create" });
|
}
|
|
function goDetail(row: RoleRow) {
|
router.push({ name: "role-detail", params: { id: row.id }, query: { uuid: row.uuid } });
|
}
|
|
function goEdit(row: RoleRow) {
|
router.push({ name: "role-edit", params: { id: row.id }, query: { uuid: row.uuid } });
|
}
|
|
function confirmDelete(row: RoleRow) {
|
if (row.userCount > 0) return;
|
ElMessageBox.confirm("删除为逻辑删除,且将解除该角色与菜单的关联,是否继续?", "确认删除", {
|
confirmButtonText: "删除",
|
cancelButtonText: "取消",
|
type: "warning",
|
})
|
.then(async () => {
|
try {
|
await http.delete(`/sys/role-manage/${row.id}`, { params: { uuid: row.uuid } });
|
ElMessage.success("已删除");
|
load();
|
} catch (e: unknown) {
|
ElMessage.error(e instanceof Error ? e.message : "操作失败");
|
}
|
})
|
.catch(() => {});
|
}
|
|
onMounted(load);
|
</script>
|
|
<style scoped>
|
.search-form {
|
margin-bottom: 12px;
|
display: flex;
|
flex-wrap: wrap;
|
align-items: center;
|
gap: 4px 0;
|
flex: none;
|
}
|
.push-right {
|
margin-left: auto;
|
}
|
.page {
|
display: flex;
|
flex-direction: column;
|
height: calc(100vh - 190px);
|
min-height: 420px;
|
}
|
.table-wrap {
|
flex: 1;
|
min-height: 0;
|
}
|
.main-pager {
|
margin-top: 12px;
|
justify-content: flex-end;
|
flex: none;
|
}
|
</style>
|