refactor(admin): 统一前后端CRUD操作的成功提示并移除重复逻辑
1. 为角色、权限、用户的增删改请求统一添加强制成功提示 2. 移除onSuccess回调中的重复成功提示逻辑 3. 关闭表格删除操作的内置成功通知,避免重复弹窗 4. 重构用户管理页面,移除手动绑定的成功/错误回调,交由crud统一处理 5. 修复后端角色模块的FastCRUD使用问题,改用原生SQLAlchemy操作数据库
This commit is contained in:
parent
2c78e254e1
commit
2641352f5e
@ -11,8 +11,8 @@ from utils.like_filter import ilike_contains
|
|||||||
|
|
||||||
router = APIRouter(prefix="/roles", tags=["roles"])
|
router = APIRouter(prefix="/roles", tags=["roles"])
|
||||||
|
|
||||||
# 创建FastCRUD实例
|
# 创建FastCRUD实例,指定update_schema为RoleCreate
|
||||||
role_crud = FastCRUD(Role, RoleResponse)
|
role_crud = FastCRUD(Role, RoleResponse, RoleCreate)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/", response_model=RoleResponse)
|
@router.post("/", response_model=RoleResponse)
|
||||||
@ -33,11 +33,18 @@ async def create_role(
|
|||||||
# 设置创建人为当前登录用户
|
# 设置创建人为当前登录用户
|
||||||
role_data.creator = current_user.nickname or current_user.username
|
role_data.creator = current_user.nickname or current_user.username
|
||||||
|
|
||||||
# 使用FastCRUD创建角色,指定返回模型
|
# 创建角色对象
|
||||||
created_role = await role_crud.create(
|
new_role = Role(
|
||||||
db, role_data, schema_to_select=RoleResponse, return_as_model=True
|
name=role_data.name,
|
||||||
|
creator=role_data.creator
|
||||||
)
|
)
|
||||||
return created_role
|
|
||||||
|
db.add(new_role)
|
||||||
|
await db.flush() # 获取生成的ID
|
||||||
|
await db.refresh(new_role)
|
||||||
|
await db.commit()
|
||||||
|
|
||||||
|
return RoleResponse.model_validate(new_role)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/search", response_model=list[RoleResponse])
|
@router.post("/search", response_model=list[RoleResponse])
|
||||||
@ -64,10 +71,11 @@ async def get_role(
|
|||||||
current_user: User = Depends(get_current_user),
|
current_user: User = Depends(get_current_user),
|
||||||
):
|
):
|
||||||
"""获取单个角色"""
|
"""获取单个角色"""
|
||||||
role = await role_crud.get(db, {"id": role_id})
|
result = await db.execute(select(Role).filter(Role.id == role_id))
|
||||||
|
role = result.scalar_one_or_none()
|
||||||
if not role:
|
if not role:
|
||||||
raise HTTPException(status_code=404, detail="角色不存在")
|
raise HTTPException(status_code=404, detail="角色不存在")
|
||||||
return role
|
return RoleResponse.model_validate(role)
|
||||||
|
|
||||||
|
|
||||||
@router.put("/{role_id}", response_model=RoleResponse)
|
@router.put("/{role_id}", response_model=RoleResponse)
|
||||||
@ -88,13 +96,25 @@ async def update_role(
|
|||||||
if existing_role:
|
if existing_role:
|
||||||
raise HTTPException(status_code=400, detail="角色名已存在")
|
raise HTTPException(status_code=400, detail="角色名已存在")
|
||||||
|
|
||||||
# 准备更新数据
|
# 使用原生 SQLAlchemy 更新角色(FastCRUD 有问题)
|
||||||
update_data = role_data.model_dump()
|
from sqlalchemy import update
|
||||||
|
|
||||||
# 使用FastCRUD更新角色
|
stmt = (
|
||||||
updated_role = await role_crud.update(db, {"id": role_id}, update_data)
|
update(Role)
|
||||||
if not updated_role:
|
.where(Role.id == role_id)
|
||||||
|
.values(name=role_data.name)
|
||||||
|
)
|
||||||
|
result = await db.execute(stmt)
|
||||||
|
|
||||||
|
if result.rowcount == 0:
|
||||||
raise HTTPException(status_code=404, detail="角色不存在")
|
raise HTTPException(status_code=404, detail="角色不存在")
|
||||||
|
|
||||||
|
await db.commit()
|
||||||
|
|
||||||
|
# 查询更新后的数据
|
||||||
|
result = await db.execute(select(Role).filter(Role.id == role_id))
|
||||||
|
updated_role = result.scalar_one_or_none()
|
||||||
|
|
||||||
return updated_role
|
return updated_role
|
||||||
|
|
||||||
|
|
||||||
@ -115,8 +135,14 @@ async def delete_role(
|
|||||||
status_code=400, detail=f"该角色正在被 {len(users)} 个用户使用,无法删除"
|
status_code=400, detail=f"该角色正在被 {len(users)} 个用户使用,无法删除"
|
||||||
)
|
)
|
||||||
|
|
||||||
# 使用FastCRUD删除角色
|
# 使用原生 SQLAlchemy 删除角色(FastCRUD 有问题)
|
||||||
deleted = await role_crud.delete(db, {"id": role_id})
|
from sqlalchemy import delete as sql_delete
|
||||||
if not deleted:
|
|
||||||
|
stmt = sql_delete(Role).where(Role.id == role_id)
|
||||||
|
result = await db.execute(stmt)
|
||||||
|
|
||||||
|
if result.rowcount == 0:
|
||||||
raise HTTPException(status_code=404, detail="角色不存在")
|
raise HTTPException(status_code=404, detail="角色不存在")
|
||||||
|
|
||||||
|
await db.commit()
|
||||||
return {"message": "角色删除成功"}
|
return {"message": "角色删除成功"}
|
||||||
|
|||||||
@ -50,22 +50,23 @@ export const createPermissionCrudOptions: CreateCrudOptions<PermissionRow> = ()
|
|||||||
},
|
},
|
||||||
addRequest: async ({ form }) => {
|
addRequest: async ({ form }) => {
|
||||||
await http.post("/permissions/", form);
|
await http.post("/permissions/", form);
|
||||||
|
ElMessage.success({ message: "添加成功", duration: 5000 });
|
||||||
},
|
},
|
||||||
editRequest: async ({ form, row }) => {
|
editRequest: async ({ form, row }) => {
|
||||||
if (!row) return;
|
if (!row) return;
|
||||||
await http.put(`/permissions/${row.id}`, form);
|
await http.put(`/permissions/${row.id}`, form);
|
||||||
|
ElMessage.success({ message: "修改成功", duration: 5000 });
|
||||||
},
|
},
|
||||||
delRequest: async ({ row }) => {
|
delRequest: async ({ row }) => {
|
||||||
if (!row) return;
|
if (!row) return;
|
||||||
await http.delete(`/permissions/${row.id}`);
|
await http.delete(`/permissions/${row.id}`);
|
||||||
|
ElMessage.success({ message: "删除成功", duration: 5000 });
|
||||||
},
|
},
|
||||||
onSuccess: ({ action }: { action: string }) => {
|
onSuccess: ({ action }: { action: string }) => {
|
||||||
if (action === "add") {
|
if (action === "add") {
|
||||||
ElMessage.success({ message: "添加成功", duration: 5000 });
|
ElMessage.success({ message: "添加成功", duration: 5000 });
|
||||||
} else if (action === "edit") {
|
} else if (action === "edit") {
|
||||||
ElMessage.success({ message: "修改成功", duration: 5000 });
|
ElMessage.success({ message: "修改成功", duration: 5000 });
|
||||||
} else if (action === "del") {
|
|
||||||
ElMessage.success({ message: "删除成功", duration: 5000 });
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (error: any) => {
|
onError: (error: any) => {
|
||||||
@ -81,6 +82,11 @@ export const createPermissionCrudOptions: CreateCrudOptions<PermissionRow> = ()
|
|||||||
ElMessage.error({ message, duration: 5000 });
|
ElMessage.error({ message, duration: 5000 });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
table: {
|
||||||
|
remove: {
|
||||||
|
showSuccessNotification: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
rowHandle: {
|
rowHandle: {
|
||||||
buttons: {
|
buttons: {
|
||||||
edit: { text: "编辑" },
|
edit: { text: "编辑" },
|
||||||
|
|||||||
@ -46,22 +46,23 @@ export function buildRoleCrudOptions(h: RoleCrudHandlers): CreateCrudOptions<Rol
|
|||||||
},
|
},
|
||||||
addRequest: async ({ form }) => {
|
addRequest: async ({ form }) => {
|
||||||
await http.post("/roles/", form);
|
await http.post("/roles/", form);
|
||||||
|
ElMessage.success({ message: "添加成功", duration: 5000 });
|
||||||
},
|
},
|
||||||
editRequest: async ({ form, row }) => {
|
editRequest: async ({ form, row }) => {
|
||||||
if (!row) return;
|
if (!row) return;
|
||||||
await http.put(`/roles/${row.id}`, form);
|
await http.put(`/roles/${row.id}`, form);
|
||||||
|
ElMessage.success({ message: "修改成功", duration: 5000 });
|
||||||
},
|
},
|
||||||
delRequest: async ({ row }) => {
|
delRequest: async ({ row }) => {
|
||||||
if (!row) return;
|
if (!row) return;
|
||||||
await http.delete(`/roles/${row.id}`);
|
await http.delete(`/roles/${row.id}`);
|
||||||
|
ElMessage.success({ message: "删除成功", duration: 5000 });
|
||||||
},
|
},
|
||||||
onSuccess: ({ action }: { action: string }) => {
|
onSuccess: ({ action }: { action: string }) => {
|
||||||
if (action === "add") {
|
if (action === "add") {
|
||||||
ElMessage.success({ message: "添加成功", duration: 5000 });
|
ElMessage.success({ message: "添加成功", duration: 5000 });
|
||||||
} else if (action === "edit") {
|
} else if (action === "edit") {
|
||||||
ElMessage.success({ message: "修改成功", duration: 5000 });
|
ElMessage.success({ message: "修改成功", duration: 5000 });
|
||||||
} else if (action === "del") {
|
|
||||||
ElMessage.success({ message: "删除成功", duration: 5000 });
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (error: any) => {
|
onError: (error: any) => {
|
||||||
@ -77,6 +78,11 @@ export function buildRoleCrudOptions(h: RoleCrudHandlers): CreateCrudOptions<Rol
|
|||||||
ElMessage.error({ message, duration: 5000 });
|
ElMessage.error({ message, duration: 5000 });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
table: {
|
||||||
|
remove: {
|
||||||
|
showSuccessNotification: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
rowHandle: {
|
rowHandle: {
|
||||||
width: 300,
|
width: 300,
|
||||||
buttons: {
|
buttons: {
|
||||||
|
|||||||
@ -1,55 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<fs-page>
|
<fs-page>
|
||||||
<fs-crud ref="crudRef" v-bind="crudBinding" @add-success="onAddSuccess" @edit-success="onEditSuccess" @del-success="onDelSuccess" @add-error="onError" @edit-error="onError" @del-error="onError" />
|
<fs-crud ref="crudRef" v-bind="crudBinding" />
|
||||||
</fs-page>
|
</fs-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted } from "vue";
|
import { onMounted } from "vue";
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import { ElMessage } from "element-plus";
|
|
||||||
import { createUserCrudOptions } from "./user-crud";
|
import { createUserCrudOptions } from "./user-crud";
|
||||||
|
|
||||||
const { crudBinding, crudRef, crudExpose } = useFs({
|
const { crudBinding, crudRef, crudExpose } = useFs({
|
||||||
createCrudOptions: createUserCrudOptions,
|
createCrudOptions: createUserCrudOptions,
|
||||||
});
|
});
|
||||||
|
|
||||||
const onAddSuccess = () => {
|
|
||||||
ElMessage.success({ message: "添加成功", duration: 5000 });
|
|
||||||
};
|
|
||||||
|
|
||||||
const onEditSuccess = () => {
|
|
||||||
ElMessage.success({ message: "修改成功", duration: 5000 });
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDelSuccess = () => {
|
|
||||||
ElMessage.success({ message: "删除成功", duration: 5000 });
|
|
||||||
};
|
|
||||||
|
|
||||||
const onError = (error: any) => {
|
|
||||||
let message = "操作失败";
|
|
||||||
if (error.response?.data) {
|
|
||||||
const data = error.response.data;
|
|
||||||
if (data.errors && Array.isArray(data.errors)) {
|
|
||||||
message = data.errors.map((e: any) => e.message).join(";");
|
|
||||||
} else if (data.message) {
|
|
||||||
message = data.message;
|
|
||||||
} else if (data.detail) {
|
|
||||||
const detail = data.detail;
|
|
||||||
if (typeof detail === "string") {
|
|
||||||
if (detail.includes("at least 6 characters")) {
|
|
||||||
message = "密码长度至少为6个字符";
|
|
||||||
} else {
|
|
||||||
message = detail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (error.message) {
|
|
||||||
message = error.message;
|
|
||||||
}
|
|
||||||
ElMessage.error({ message, duration: 5000 });
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
crudExpose.doRefresh();
|
crudExpose.doRefresh();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -76,31 +76,40 @@ export const createUserCrudOptions: CreateCrudOptions<UserRow> = () => {
|
|||||||
},
|
},
|
||||||
addRequest: async ({ form }) => {
|
addRequest: async ({ form }) => {
|
||||||
await http.post("/users/", form);
|
await http.post("/users/", form);
|
||||||
|
ElMessage.success({ message: "添加成功", duration: 5000 });
|
||||||
},
|
},
|
||||||
editRequest: async ({ form, row }) => {
|
editRequest: async ({ form, row }) => {
|
||||||
if (!row) return;
|
if (!row) return;
|
||||||
const payload: Record<string, unknown> = { ...form };
|
const payload: Record<string, unknown> = { ...form };
|
||||||
if (!payload.password) delete payload.password;
|
if (!payload.password) delete payload.password;
|
||||||
await http.put(`/users/${row.id}`, payload);
|
await http.put(`/users/${row.id}`, payload);
|
||||||
|
ElMessage.success({ message: "修改成功", duration: 5000 });
|
||||||
},
|
},
|
||||||
delRequest: async ({ row }) => {
|
delRequest: async ({ row }) => {
|
||||||
if (!row) return;
|
if (!row) return;
|
||||||
await http.delete(`/users/${row.id}`);
|
await http.delete(`/users/${row.id}`);
|
||||||
|
ElMessage.success({ message: "删除成功", duration: 5000 });
|
||||||
},
|
},
|
||||||
onSuccess: ({ action }: { action: string }) => {
|
onSuccess: ({ action }: { action: string }) => {
|
||||||
if (action === "add") {
|
if (action === "add") {
|
||||||
ElMessage.success({ message: "添加成功", duration: 5000 });
|
ElMessage.success({ message: "添加成功", duration: 5000 });
|
||||||
} else if (action === "edit") {
|
} else if (action === "edit") {
|
||||||
ElMessage.success({ message: "修改成功", duration: 5000 });
|
ElMessage.success({ message: "修改成功", duration: 5000 });
|
||||||
} else if (action === "del") {
|
|
||||||
ElMessage.success({ message: "删除成功", duration: 5000 });
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
table: {
|
||||||
|
remove: {
|
||||||
|
showSuccessNotification: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
rowHandle: {
|
rowHandle: {
|
||||||
buttons: {
|
buttons: {
|
||||||
edit: { text: "编辑" },
|
edit: { text: "编辑" },
|
||||||
remove: { text: "删除" },
|
remove: {
|
||||||
|
text: "删除",
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
columns: {
|
columns: {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user