|
|
@@ -0,0 +1,164 @@
|
|
|
+<script setup>
|
|
|
+import dayjs from 'dayjs';
|
|
|
+import { ref } from 'vue';
|
|
|
+import { Page, useVbenModal } from '@vben/common-ui';
|
|
|
+import { Button, Card, Tag, Space, Popconfirm, message } from "ant-design-vue";
|
|
|
+import { useVbenForm } from '#/adapter/form';
|
|
|
+import { $t } from "@vben/locales";
|
|
|
+import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
|
|
+import { getRoleList, deleteRole, getRoleInfo, updateRoleInfo, createRole } from "#/api/user/user_role";
|
|
|
+
|
|
|
+import RoleModal from './role_info.vue';
|
|
|
+
|
|
|
+const gridOptions = {
|
|
|
+ border: true,
|
|
|
+ stripe: true,
|
|
|
+ checkboxConfig: {
|
|
|
+ highlight: true,
|
|
|
+ },
|
|
|
+ columns: [
|
|
|
+ { fixed: 'left', title: '序号', type: 'seq', width: 60 },
|
|
|
+ { field: 'id', title: '角色ID', width: 80 },
|
|
|
+ { field: 'role_name', title: '角色名称', width: 150 },
|
|
|
+ { field: 'privileges', title: '权限', slots: { default: 'privileges' } },
|
|
|
+ { field: 'create_time', title: '创建时间', width: 180 },
|
|
|
+ { field: 'update_time', title: '更新时间', width: 180 },
|
|
|
+ { fixed: 'right', title: '操作', width: 120, slots: { default: 'action' } },
|
|
|
+ ],
|
|
|
+ exportConfig: {},
|
|
|
+ keepSource: true,
|
|
|
+ proxyConfig: {
|
|
|
+ ajax: {
|
|
|
+ query: async ({ page }) => {
|
|
|
+ try {
|
|
|
+ const res = await getRoleList();
|
|
|
+ return {
|
|
|
+ total: res.total,
|
|
|
+ items: res.list
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取角色列表失败:', error);
|
|
|
+ return {
|
|
|
+ total: 0,
|
|
|
+ items: []
|
|
|
+ };
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ rowConfig: {
|
|
|
+ isHover: true,
|
|
|
+ },
|
|
|
+ pagerConfig: {
|
|
|
+ enabled: false,
|
|
|
+ },
|
|
|
+ toolbarConfig: {
|
|
|
+ custom: true,
|
|
|
+ export: true,
|
|
|
+ refresh: true,
|
|
|
+ zoom: true,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
+const [Grid, gridApi] = useVbenVxeGrid({
|
|
|
+ gridOptions,
|
|
|
+});
|
|
|
+
|
|
|
+const [Modal, modalApi] = useVbenModal({
|
|
|
+ connectedComponent: RoleModal,
|
|
|
+ onBeforeClose() {
|
|
|
+ const { formData } = modalApi.getData();
|
|
|
+ if (!formData) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (formData.id) {
|
|
|
+ updateRoleInfo(formData)
|
|
|
+ .then(res => {
|
|
|
+ message.success('编辑角色成功');
|
|
|
+ gridApi.reload();
|
|
|
+ })
|
|
|
+ .catch(err => {
|
|
|
+ message.error('编辑角色失败');
|
|
|
+ console.error('编辑角色失败:', err);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ createRole(formData)
|
|
|
+ .then(res => {
|
|
|
+ message.success('新增角色成功');
|
|
|
+ gridApi.reload();
|
|
|
+ })
|
|
|
+ .catch(err => {
|
|
|
+ message.error('新增角色失败');
|
|
|
+ console.error('新增角色失败:', err);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+});
|
|
|
+
|
|
|
+// 新增角色
|
|
|
+const addRole = () => {
|
|
|
+ modalApi.setState({ title: '新增角色' })
|
|
|
+ .open();
|
|
|
+};
|
|
|
+
|
|
|
+// 编辑角色
|
|
|
+const editRole = (row) => {
|
|
|
+ modalApi.setData({ formData: row })
|
|
|
+ .setState({ title: '编辑角色' })
|
|
|
+ .open();
|
|
|
+};
|
|
|
+
|
|
|
+// 处理删除角色
|
|
|
+const handleDelete = async (row) => {
|
|
|
+ try {
|
|
|
+ await deleteRole({ id: row.id });
|
|
|
+ message.success('删除成功');
|
|
|
+ gridApi.reload();
|
|
|
+ } catch (error) {
|
|
|
+ message.error('删除失败');
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <Page>
|
|
|
+ <Card>
|
|
|
+ <div class="vp-raw w-full">
|
|
|
+ <Grid>
|
|
|
+ <template #toolbar-actions>
|
|
|
+ <Button type="primary" @click="addRole">新增角色</Button>
|
|
|
+ </template>
|
|
|
+ <template #privileges="{ row }">
|
|
|
+ <div class="flex flex-wrap gap-1">
|
|
|
+ <Tag v-for="privilege in row.privileges" :key="privilege" color="blue" size="small">
|
|
|
+ {{ privilege }}
|
|
|
+ </Tag>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template #action="{ row }">
|
|
|
+ <Space>
|
|
|
+ <Button type="link" size="small" @click="editRole(row)">编辑</Button>
|
|
|
+ <Popconfirm
|
|
|
+ title="确定要删除这个角色吗?"
|
|
|
+ @confirm="handleDelete(row)"
|
|
|
+ ok-text="确定"
|
|
|
+ cancel-text="取消"
|
|
|
+ >
|
|
|
+ <Button type="link" size="small" danger>删除</Button>
|
|
|
+ </Popconfirm>
|
|
|
+ </Space>
|
|
|
+ </template>
|
|
|
+ </Grid>
|
|
|
+ </div>
|
|
|
+ </Card>
|
|
|
+ <Modal />
|
|
|
+ </Page>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.ant-card {
|
|
|
+ margin-bottom: 16px;
|
|
|
+}
|
|
|
+</style>
|