ref: 数据列表组件封装
This commit is contained in:
parent
85a38a0840
commit
f3bb9d3253
@ -20,11 +20,6 @@ async def login(auth_data: LoginForm) -> Response[LoginResult]:
|
||||
return Response(code=400, msg="账号或密码错误")
|
||||
|
||||
|
||||
async def about() -> Response:
|
||||
"""关于"""
|
||||
pass
|
||||
|
||||
|
||||
async def websocket(ws: WebSocket):
|
||||
await ws.accept()
|
||||
try:
|
||||
|
@ -4,14 +4,8 @@ from fastapi import Query
|
||||
|
||||
from core.utils import list_to_tree
|
||||
from dbhelper.menu import get_menu
|
||||
from dbhelper.role import (
|
||||
del_role,
|
||||
get_role,
|
||||
get_role_menus,
|
||||
get_roles,
|
||||
new_role,
|
||||
put_role,
|
||||
)
|
||||
from dbhelper.role import (del_role, get_role, get_role_menus, get_roles,
|
||||
new_role, put_role)
|
||||
from schemas import ListAll, Response, RoleIn, RoleInfo, RoleQuery, RoleRead
|
||||
|
||||
|
||||
|
@ -2,15 +2,8 @@ from fastapi import Depends, Query
|
||||
from starlette.requests import Request
|
||||
|
||||
from core.security import check_token, get_password_hash
|
||||
from dbhelper.user import (
|
||||
del_user,
|
||||
get_user,
|
||||
get_user_info,
|
||||
get_users,
|
||||
insert_user,
|
||||
put_user,
|
||||
select_role,
|
||||
)
|
||||
from dbhelper.user import (del_user, get_user, get_user_info, get_users,
|
||||
insert_user, put_user, select_role)
|
||||
from schemas import Response, UserAdd, UserInfo, UserPut, UserQuery, UserRead
|
||||
from schemas.common import ListAll
|
||||
|
||||
|
BIN
backend/mini.db
BIN
backend/mini.db
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -2,25 +2,12 @@ from typing import Any, Callable, get_type_hints
|
||||
|
||||
from fastapi import Depends, routing
|
||||
|
||||
from controller.common import about, login, websocket
|
||||
from controller.common import login, websocket
|
||||
from controller.menu import menu_add, menu_arr, menu_del, menu_put
|
||||
from controller.role import (
|
||||
role_add,
|
||||
role_arr,
|
||||
role_del,
|
||||
role_has_menu,
|
||||
role_put,
|
||||
role_query,
|
||||
)
|
||||
from controller.user import (
|
||||
user_add,
|
||||
user_arr,
|
||||
user_del,
|
||||
user_info,
|
||||
user_list,
|
||||
user_put,
|
||||
user_select_role,
|
||||
)
|
||||
from controller.role import (role_add, role_arr, role_del, role_has_menu,
|
||||
role_put, role_query)
|
||||
from controller.user import (user_add, user_arr, user_del, user_info,
|
||||
user_list, user_put, user_select_role)
|
||||
from core.security import check_permissions
|
||||
|
||||
|
||||
@ -121,11 +108,10 @@ class Route(routing.APIRoute):
|
||||
|
||||
|
||||
has_perm = {"dependencies": [Depends(check_permissions)]}
|
||||
# has_perm = {}
|
||||
has_perm = {}
|
||||
|
||||
routes = [
|
||||
Route.post("/login", endpoint=login, tags=["公共"], summary="登录"),
|
||||
Route.get("/about", endpoint=about, tags=["公共"], summary="关于", **has_perm),
|
||||
# 用户管理
|
||||
Route.get("/user", endpoint=user_arr, tags=["用户管理"], summary="用户列表", **has_perm),
|
||||
Route.post("/user", endpoint=user_add, tags=["用户管理"], summary="用户新增", **has_perm),
|
||||
|
@ -91,8 +91,6 @@ params = [
|
||||
component="/setting/about/about.vue",
|
||||
pid=2,
|
||||
identifier=None,
|
||||
api="/about",
|
||||
method="GET",
|
||||
).dict(),
|
||||
),
|
||||
# 按钮
|
||||
|
36
frontend/src/components/table/conf.js
Normal file
36
frontend/src/components/table/conf.js
Normal file
@ -0,0 +1,36 @@
|
||||
import { ref } from 'vue'
|
||||
|
||||
// 菜单类型映射
|
||||
export const menuType = {
|
||||
0: '目录',
|
||||
1: '菜单',
|
||||
2: '按钮'
|
||||
}
|
||||
|
||||
// 请求方法颜色映射
|
||||
export const methodColor = {
|
||||
GET: '#61AFFE',
|
||||
POST: '#49CC90',
|
||||
DELETE: '#F93E3E',
|
||||
PUT: '#FCA130'
|
||||
}
|
||||
|
||||
export const tableTree = () => {
|
||||
// 1.适配菜单表格
|
||||
// 展开行 https://blog.csdn.net/weixin_52691965/article/details/120494451
|
||||
const expandedRowKeys = ref([])
|
||||
const expand = (expanded, record) => {
|
||||
if (expandedRowKeys.value.length > 0) {
|
||||
let index = expandedRowKeys.value.indexOf(record.id)
|
||||
if (index > -1) {
|
||||
expandedRowKeys.value.splice(index, 1)
|
||||
} else {
|
||||
expandedRowKeys.value.splice(0, expandedRowKeys.value.length)
|
||||
expandedRowKeys.value.push(record.id)
|
||||
}
|
||||
} else {
|
||||
expandedRowKeys.value.push(record.id)
|
||||
}
|
||||
}
|
||||
return expand
|
||||
}
|
123
frontend/src/components/table/table.vue
Normal file
123
frontend/src/components/table/table.vue
Normal file
@ -0,0 +1,123 @@
|
||||
<script setup>
|
||||
import { menuType, methodColor, tableTree } from './conf'
|
||||
|
||||
/**接受父组件传递过来的值 */
|
||||
defineProps({
|
||||
// 列配置
|
||||
columns: {
|
||||
type: Array,
|
||||
require: true,
|
||||
default: () => []
|
||||
},
|
||||
// 数据源
|
||||
dataSource: {
|
||||
type: Array,
|
||||
require: true,
|
||||
default: () => []
|
||||
},
|
||||
// 分页器配置 非必须
|
||||
pagination: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
// 默认不要分页器
|
||||
hideOnSinglePage: true
|
||||
})
|
||||
},
|
||||
// 页面名称小写-主要用于权限校验
|
||||
pageName: {
|
||||
type: String,
|
||||
default: 'user'
|
||||
},
|
||||
listTitle: {
|
||||
type: String
|
||||
}
|
||||
})
|
||||
|
||||
// 子组件事件, 父组件可通过 @updateClick进行绑定
|
||||
const emits = defineEmits(['createClick', 'updateClick', 'deleteClick'])
|
||||
|
||||
// 事件
|
||||
const createEvent = () => {
|
||||
console.log('点击了 table组件 新增 -> 向父组件传递')
|
||||
emits('createClick')
|
||||
}
|
||||
|
||||
const updateEvent = (record) => {
|
||||
console.log('点击了 table组件 更新 -> 向父组件传递', record)
|
||||
emits('updateClick', record)
|
||||
}
|
||||
|
||||
const deleteEvent = (record) => {
|
||||
console.log('点击了 table组件 删除-> 向父组件传递', record)
|
||||
emits('deleteClick', record)
|
||||
}
|
||||
|
||||
const expand = tableTree()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="list">
|
||||
<a-card :title="listTitle"
|
||||
><template #extra>
|
||||
<a-button type="primary" v-per="`${pageName}:create`" @click="createEvent">
|
||||
<template #icon>
|
||||
<component :is="$loadIconCpn('PlusOutlined')"></component>
|
||||
</template>
|
||||
新增</a-button
|
||||
>
|
||||
</template>
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:scroll="{ y: 'calc(100vh - 300px)' }"
|
||||
:data-source="dataSource"
|
||||
:pagination="pagination"
|
||||
:row-key="(record) => record.id"
|
||||
@expand="expand"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<!-- 适配菜单表格 -->
|
||||
<template v-if="column.key === 'meta'">
|
||||
<component :is="$loadIconCpn(record.meta?.icon)"></component>
|
||||
</template>
|
||||
<template v-if="column.key === 'type'">
|
||||
{{ menuType[record.type] }}
|
||||
</template>
|
||||
<template v-if="column.key === 'method'">
|
||||
<template v-if="record.method">
|
||||
<a-tag :color="methodColor[record.method]">{{ record.method }}</a-tag>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 一般表格 -->
|
||||
<template v-if="column.key === 'status'">
|
||||
<a-tag :color="record.status !== 9 ? 'green' : 'red'">
|
||||
{{ record.status !== 9 ? '正常' : '删除' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'created'">
|
||||
{{ $formatTime(record.created) }}
|
||||
</template>
|
||||
<template v-else-if="column.key === 'modified'">
|
||||
{{ $formatTime(record.modified) }}
|
||||
</template>
|
||||
|
||||
<template v-else-if="column.key === 'action'">
|
||||
<span>
|
||||
<a v-per="`${pageName}:update`" @click="updateEvent(record)">编辑</a>
|
||||
<a-divider type="vertical" />
|
||||
<template v-if="record.status !== 9">
|
||||
<a v-per="`${pageName}:delete`" @click="deleteEvent(record)">删除</a>
|
||||
</template>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.list {
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
@ -72,11 +72,3 @@ export const menuType = {
|
||||
1: '菜单',
|
||||
2: '按钮'
|
||||
}
|
||||
|
||||
// 请求方法颜色映射
|
||||
export const methodColor = {
|
||||
GET: '#61AFFE',
|
||||
POST: '#49CC90',
|
||||
DELETE: '#F93E3E',
|
||||
PUT: '#FCA130'
|
||||
}
|
||||
|
@ -1,35 +1,17 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { PlusOutlined } from '@ant-design/icons-vue'
|
||||
|
||||
import { columns, menuType, methodColor } from './conf'
|
||||
import { columns } from './conf'
|
||||
import { getMenus } from '@/service/menu'
|
||||
|
||||
import Table from '@/components/table/table.vue'
|
||||
|
||||
// 列表数据
|
||||
const dataSource = ref([])
|
||||
|
||||
getMenus().then((res) => (dataSource.value = res.data))
|
||||
|
||||
// 菜单类型隐射
|
||||
|
||||
// 展开行 https://blog.csdn.net/weixin_52691965/article/details/120494451
|
||||
const expandedRowKeys = ref([])
|
||||
|
||||
const zi = (expanded, record) => {
|
||||
if (expandedRowKeys.value.length > 0) {
|
||||
let index = expandedRowKeys.value.indexOf(record.id)
|
||||
if (index > -1) {
|
||||
expandedRowKeys.value.splice(index, 1)
|
||||
} else {
|
||||
expandedRowKeys.value.splice(0, expandedRowKeys.value.length)
|
||||
expandedRowKeys.value.push(record.id)
|
||||
}
|
||||
} else {
|
||||
expandedRowKeys.value.push(record.id)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 新增
|
||||
const addClick = () => {
|
||||
console.log('点击')
|
||||
}
|
||||
@ -46,58 +28,16 @@ const delClick = () => {
|
||||
|
||||
<template>
|
||||
<div class="user">
|
||||
<!-- 列表 -->
|
||||
<div class="data">
|
||||
<a-card title="菜单列表"
|
||||
><template #extra>
|
||||
<a-button type="primary" v-per="'role:create'" @click="addClick">
|
||||
<template #icon><plus-outlined /></template>
|
||||
新增</a-button
|
||||
>
|
||||
</template>
|
||||
|
||||
<!-- 数据 -->
|
||||
<a-table
|
||||
<Table
|
||||
:columns="columns"
|
||||
:scroll="{ x: 1600, y: 'calc(100vh - 380px)' }"
|
||||
:data-source="dataSource"
|
||||
:pagination="{
|
||||
hideOnSinglePage: true
|
||||
}"
|
||||
:row-key="(record) => record.id"
|
||||
@expand="zi"
|
||||
page-name="menu"
|
||||
list-title="菜单列表"
|
||||
@create-click="addClick"
|
||||
@update-click="putClick"
|
||||
@delete-click="delClick"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'meta'">
|
||||
<component :is="$loadIconCpn(record.meta?.icon)"></component>
|
||||
</template>
|
||||
<template v-if="column.key === 'type'">
|
||||
{{ menuType[record.type] }}
|
||||
</template>
|
||||
<template v-if="column.key === 'method'">
|
||||
<template v-if="record.method">
|
||||
<a-tag :color="methodColor[record.method]">{{ record.method }}</a-tag>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'created'">
|
||||
{{ $formatTime(record.created) }}
|
||||
</template>
|
||||
<template v-else-if="column.key === 'modified'">
|
||||
{{ $formatTime(record.modified) }}
|
||||
</template>
|
||||
<template v-else-if="column.key === 'action'">
|
||||
<span>
|
||||
<a v-per="'role:update'" @click="putClick(record)">编辑</a>
|
||||
<a-divider type="vertical" />
|
||||
<template v-if="record.status !== 9">
|
||||
<a v-per="'role:delete'" @click="delClick(record)">删除</a>
|
||||
</template>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
</div>
|
||||
</Table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, watch } from 'vue'
|
||||
|
||||
import { PlusOutlined } from '@ant-design/icons-vue'
|
||||
import Table from '@/components/table/table.vue'
|
||||
|
||||
import { getRoles, queryRole, delRole, putRole, addRole } from '@/service/role'
|
||||
import { getMenus } from '@/service/menu'
|
||||
@ -126,7 +125,8 @@ const onCancel = () => {
|
||||
// 点击编辑弹modal事件
|
||||
const putClick = (record) => {
|
||||
putVisible.value = !putVisible.value
|
||||
getPutModalData(record.id)
|
||||
console.log(record, '父组件')
|
||||
getPutModalData(record)
|
||||
}
|
||||
|
||||
const getPutModalData = (record) => {
|
||||
@ -214,49 +214,17 @@ watch(
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
<!-- 列表 -->
|
||||
<div class="data">
|
||||
<a-card title="角色列表"
|
||||
><template #extra>
|
||||
<a-button type="primary" v-per="'role:create'" @click="addClick">
|
||||
<template #icon><plus-outlined /></template>
|
||||
新增</a-button
|
||||
>
|
||||
</template>
|
||||
|
||||
<!-- 数据 -->
|
||||
<a-table
|
||||
<Table
|
||||
:columns="columns"
|
||||
:scroll="{ y: 'calc(100vh - 460px)' }"
|
||||
:data-source="dataSource"
|
||||
:pagination="pagination"
|
||||
page-name="role"
|
||||
list-title="角色列表"
|
||||
@create-click="addClick"
|
||||
@update-click="putClick"
|
||||
@delete-click="delClick"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'status'">
|
||||
<a-tag :color="record.status !== 9 ? 'green' : 'red'">
|
||||
{{ record.status !== 9 ? '正常' : '删除' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'created'">
|
||||
{{ $formatTime(record.created) }}
|
||||
</template>
|
||||
<template v-else-if="column.key === 'modified'">
|
||||
{{ $formatTime(record.modified) }}
|
||||
</template>
|
||||
<template v-else-if="column.key === 'action'">
|
||||
<span>
|
||||
<a v-per="'role:update'" @click="putClick(record)">编辑</a>
|
||||
<a-divider type="vertical" />
|
||||
<template v-if="record.status !== 9">
|
||||
<a v-per="'role:delete'" @click="delClick(record)">删除</a>
|
||||
</template>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
</div>
|
||||
|
||||
</Table>
|
||||
<!-- 新增 -->
|
||||
<a-modal
|
||||
v-model:visible="addVisible"
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
|
||||
import { PlusOutlined } from '@ant-design/icons-vue'
|
||||
import Table from '@/components/table/table.vue'
|
||||
|
||||
import { getUsers, queryUser, delUser, addUser, getUserInfo, putUser } from '@/service/user'
|
||||
import { getRoles } from '@/service/role'
|
||||
@ -207,48 +207,17 @@ const onCancelPut = () => {
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
<!-- 列表 -->
|
||||
<div class="data">
|
||||
<a-card title="用户列表"
|
||||
><template #extra>
|
||||
<a-button type="primary" v-per="'user:create'" @click="addClick">
|
||||
<template #icon><plus-outlined /></template>
|
||||
新增</a-button
|
||||
>
|
||||
</template>
|
||||
|
||||
<!-- 数据 -->
|
||||
<a-table
|
||||
<Table
|
||||
:columns="columns"
|
||||
:scroll="{ y: 'calc(100vh - 460px)' }"
|
||||
:data-source="dataSource"
|
||||
:pagination="pagination"
|
||||
page-name="user"
|
||||
list-title="用户列表"
|
||||
@create-click="addClick"
|
||||
@update-click="putClick"
|
||||
@delete-click="delClick"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'status'">
|
||||
<a-tag :color="record.status !== 9 ? 'green' : 'red'">
|
||||
{{ record.status !== 9 ? '正常' : '删除' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'created'">
|
||||
{{ $formatTime(record.created) }}
|
||||
</template>
|
||||
<template v-else-if="column.key === 'modified'">
|
||||
{{ $formatTime(record.modified) }}
|
||||
</template>
|
||||
<template v-else-if="column.key === 'action'">
|
||||
<span>
|
||||
<a v-per="'user:update'" @click="putClick(record)">编辑</a>
|
||||
<a-divider type="vertical" />
|
||||
<template v-if="record.status !== 9">
|
||||
<a v-per="'user:delete'" @click="delClick(record)">删除</a>
|
||||
</template>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
</div>
|
||||
</Table>
|
||||
|
||||
<!-- 新增 用户-->
|
||||
<a-modal
|
||||
@ -320,7 +289,4 @@ const onCancelPut = () => {
|
||||
padding: 24px;
|
||||
background: #fff;
|
||||
}
|
||||
.data {
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user