添加团队列表排序功能并移除冗余API端点
* feat(用户管理): 添加用户列表排序功能并优化文档解析计数逻辑 * feat(团队管理): 添加团队列表排序功能并移除冗余API端点
This commit is contained in:
parent
42ce701834
commit
c17f8b844d
|
@ -10,9 +10,11 @@ def get_teams():
|
||||||
current_page = int(request.args.get('currentPage', 1))
|
current_page = int(request.args.get('currentPage', 1))
|
||||||
page_size = int(request.args.get('size', 10))
|
page_size = int(request.args.get('size', 10))
|
||||||
team_name = request.args.get('name', '')
|
team_name = request.args.get('name', '')
|
||||||
|
sort_by = request.args.get("sort_by", "create_time")
|
||||||
|
sort_order = request.args.get("sort_order", "desc")
|
||||||
|
|
||||||
# 调用服务函数获取分页和筛选后的团队数据
|
# 调用服务函数获取分页和筛选后的团队数据
|
||||||
teams, total = get_teams_with_pagination(current_page, page_size, team_name)
|
teams, total = get_teams_with_pagination(current_page, page_size, team_name, sort_by, sort_order)
|
||||||
|
|
||||||
# 返回符合前端期望格式的数据
|
# 返回符合前端期望格式的数据
|
||||||
return jsonify({
|
return jsonify({
|
||||||
|
@ -52,44 +54,6 @@ def get_team(team_id):
|
||||||
"message": f"获取团队详情失败: {str(e)}"
|
"message": f"获取团队详情失败: {str(e)}"
|
||||||
}), 500
|
}), 500
|
||||||
|
|
||||||
@teams_bp.route('', methods=['POST'])
|
|
||||||
def create_team_route():
|
|
||||||
"""创建团队的API端点"""
|
|
||||||
try:
|
|
||||||
data = request.json
|
|
||||||
team_id = create_team(team_data=data)
|
|
||||||
return jsonify({
|
|
||||||
"code": 0,
|
|
||||||
"data": {"id": team_id},
|
|
||||||
"message": "团队创建成功"
|
|
||||||
})
|
|
||||||
except Exception as e:
|
|
||||||
return jsonify({
|
|
||||||
"code": 500,
|
|
||||||
"message": f"创建团队失败: {str(e)}"
|
|
||||||
}), 500
|
|
||||||
|
|
||||||
@teams_bp.route('/<string:team_id>', methods=['PUT'])
|
|
||||||
def update_team_route(team_id):
|
|
||||||
"""更新团队的API端点"""
|
|
||||||
try:
|
|
||||||
data = request.json
|
|
||||||
success = update_team(team_id=team_id, team_data=data)
|
|
||||||
if success:
|
|
||||||
return jsonify({
|
|
||||||
"code": 0,
|
|
||||||
"message": f"团队 {team_id} 更新成功"
|
|
||||||
})
|
|
||||||
else:
|
|
||||||
return jsonify({
|
|
||||||
"code": 404,
|
|
||||||
"message": f"团队 {team_id} 不存在或更新失败"
|
|
||||||
}), 404
|
|
||||||
except Exception as e:
|
|
||||||
return jsonify({
|
|
||||||
"code": 500,
|
|
||||||
"message": f"更新团队失败: {str(e)}"
|
|
||||||
}), 500
|
|
||||||
|
|
||||||
@teams_bp.route('/<string:team_id>', methods=['DELETE'])
|
@teams_bp.route('/<string:team_id>', methods=['DELETE'])
|
||||||
def delete_team_route(team_id):
|
def delete_team_route(team_id):
|
||||||
|
|
|
@ -110,11 +110,11 @@ def reset_password_route(user_id):
|
||||||
if success:
|
if success:
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"code": 0,
|
"code": 0,
|
||||||
"message": f"用户密码重置成功"
|
"message": "用户密码重置成功"
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
# service 层可能因为用户不存在或其他原因返回 False
|
# service 层可能因为用户不存在或其他原因返回 False
|
||||||
return jsonify({"code": 404, "message": f"用户未找到或密码重置失败"}), 404
|
return jsonify({"code": 404, "message": "用户未找到或密码重置失败"}), 404
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# 统一处理异常
|
# 统一处理异常
|
||||||
return jsonify({
|
return jsonify({
|
||||||
|
|
|
@ -3,7 +3,7 @@ from datetime import datetime
|
||||||
from utils import generate_uuid
|
from utils import generate_uuid
|
||||||
from database import DB_CONFIG
|
from database import DB_CONFIG
|
||||||
|
|
||||||
def get_teams_with_pagination(current_page, page_size, name=''):
|
def get_teams_with_pagination(current_page, page_size, name='', sort_by="create_time",sort_order="desc"):
|
||||||
"""查询团队信息,支持分页和条件筛选"""
|
"""查询团队信息,支持分页和条件筛选"""
|
||||||
try:
|
try:
|
||||||
conn = mysql.connector.connect(**DB_CONFIG)
|
conn = mysql.connector.connect(**DB_CONFIG)
|
||||||
|
@ -18,10 +18,18 @@ def get_teams_with_pagination(current_page, page_size, name=''):
|
||||||
params.append(f"%{name}%")
|
params.append(f"%{name}%")
|
||||||
|
|
||||||
# 组合WHERE子句
|
# 组合WHERE子句
|
||||||
where_sql = " AND ".join(where_clauses) if where_clauses else "1=1"
|
where_sql = "WHERE " + (" AND ".join(where_clauses) if where_clauses else "1=1")
|
||||||
|
|
||||||
|
# 验证排序字段
|
||||||
|
valid_sort_fields = ["name", "create_time", "create_date"]
|
||||||
|
if sort_by not in valid_sort_fields:
|
||||||
|
sort_by = "create_time"
|
||||||
|
|
||||||
|
# 构建排序子句
|
||||||
|
sort_clause = f"ORDER BY {sort_by} {sort_order.upper()}"
|
||||||
|
|
||||||
# 查询总记录数
|
# 查询总记录数
|
||||||
count_sql = f"SELECT COUNT(*) as total FROM tenant t WHERE {where_sql}"
|
count_sql = f"SELECT COUNT(*) as total FROM tenant t {where_sql}"
|
||||||
cursor.execute(count_sql, params)
|
cursor.execute(count_sql, params)
|
||||||
total = cursor.fetchone()['total']
|
total = cursor.fetchone()['total']
|
||||||
|
|
||||||
|
@ -41,10 +49,8 @@ def get_teams_with_pagination(current_page, page_size, name=''):
|
||||||
(SELECT COUNT(*) FROM user_tenant ut WHERE ut.tenant_id = t.id AND ut.status = 1) as member_count
|
(SELECT COUNT(*) FROM user_tenant ut WHERE ut.tenant_id = t.id AND ut.status = 1) as member_count
|
||||||
FROM
|
FROM
|
||||||
tenant t
|
tenant t
|
||||||
WHERE
|
|
||||||
{where_sql}
|
{where_sql}
|
||||||
ORDER BY
|
{sort_clause}
|
||||||
t.create_date DESC
|
|
||||||
LIMIT %s OFFSET %s
|
LIMIT %s OFFSET %s
|
||||||
"""
|
"""
|
||||||
cursor.execute(query, params + [page_size, offset])
|
cursor.execute(query, params + [page_size, offset])
|
||||||
|
@ -155,9 +161,6 @@ def get_team_members(team_id):
|
||||||
# 格式化结果
|
# 格式化结果
|
||||||
formatted_members = []
|
formatted_members = []
|
||||||
for member in results:
|
for member in results:
|
||||||
# 将 role 转换为前端需要的格式
|
|
||||||
role = "管理员" if member["role"] == "owner" else "普通成员"
|
|
||||||
|
|
||||||
formatted_members.append({
|
formatted_members.append({
|
||||||
"userId": member["user_id"],
|
"userId": member["user_id"],
|
||||||
"username": member["nickname"],
|
"username": member["nickname"],
|
||||||
|
|
|
@ -27,7 +27,7 @@ def get_users_with_pagination(current_page, page_size, username='', email='', so
|
||||||
where_sql = "WHERE " + (" AND ".join(where_clauses) if where_clauses else "1=1")
|
where_sql = "WHERE " + (" AND ".join(where_clauses) if where_clauses else "1=1")
|
||||||
|
|
||||||
# 验证排序字段
|
# 验证排序字段
|
||||||
valid_sort_fields = ["name", "size", "type", "create_time", "create_date"]
|
valid_sort_fields = ["name", "email", "create_time", "create_date"]
|
||||||
if sort_by not in valid_sort_fields:
|
if sort_by not in valid_sort_fields:
|
||||||
sort_by = "create_time"
|
sort_by = "create_time"
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,11 @@ export interface TableRequestData {
|
||||||
/** 查询参数:邮箱 */
|
/** 查询参数:邮箱 */
|
||||||
email?: string
|
email?: string
|
||||||
/** 查询参数:团队名称 */
|
/** 查询参数:团队名称 */
|
||||||
name?: string // 添加 name 属性
|
name?: string
|
||||||
|
/** 排序字段 */
|
||||||
|
sort_by: string
|
||||||
|
/** 排序方式 */
|
||||||
|
sort_order: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TableData {
|
export interface TableData {
|
||||||
|
|
|
@ -41,6 +41,12 @@ const searchData = reactive({
|
||||||
name: ""
|
name: ""
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 排序状态
|
||||||
|
const sortData = reactive({
|
||||||
|
sortBy: "create_date",
|
||||||
|
sortOrder: "desc" // 默认排序顺序 (最新创建的在前)
|
||||||
|
})
|
||||||
|
|
||||||
// 存储多选的表格数据
|
// 存储多选的表格数据
|
||||||
const multipleSelection = ref<TeamData[]>([])
|
const multipleSelection = ref<TeamData[]>([])
|
||||||
|
|
||||||
|
@ -50,7 +56,9 @@ function getTableData() {
|
||||||
getTableDataApi({
|
getTableDataApi({
|
||||||
currentPage: paginationData.currentPage,
|
currentPage: paginationData.currentPage,
|
||||||
size: paginationData.pageSize,
|
size: paginationData.pageSize,
|
||||||
name: searchData.name
|
name: searchData.name,
|
||||||
|
sort_by: sortData.sortBy,
|
||||||
|
sort_order: sortData.sortOrder
|
||||||
}).then(({ data }) => {
|
}).then(({ data }) => {
|
||||||
paginationData.total = data.total
|
paginationData.total = data.total
|
||||||
tableData.value = data.list.map((item: any) => ({
|
tableData.value = data.list.map((item: any) => ({
|
||||||
|
@ -213,6 +221,25 @@ function handleRemoveMember(member: TeamMember) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 处理表格排序变化事件(只允许正序和倒序切换)
|
||||||
|
* @param {object} sortInfo 排序信息对象,包含 prop 和 order
|
||||||
|
* @param {string} sortInfo.prop 排序的字段名
|
||||||
|
* @param {string | null} sortInfo.order 排序的顺序 ('ascending', 'descending', null)
|
||||||
|
*/
|
||||||
|
function handleSortChange({ prop }: { prop: string, order: string | null }) {
|
||||||
|
// 如果点击的是同一个字段,则切换排序顺序
|
||||||
|
if (sortData.sortBy === prop) {
|
||||||
|
// 当前为正序则切换为倒序,否则切换为正序
|
||||||
|
sortData.sortOrder = sortData.sortOrder === "asc" ? "desc" : "asc"
|
||||||
|
} else {
|
||||||
|
// 切换字段时,默认正序
|
||||||
|
sortData.sortBy = prop
|
||||||
|
sortData.sortOrder = "asc"
|
||||||
|
}
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
// 监听分页参数的变化
|
// 监听分页参数的变化
|
||||||
watch([() => paginationData.currentPage, () => paginationData.pageSize], getTableData, { immediate: true })
|
watch([() => paginationData.currentPage, () => paginationData.pageSize], getTableData, { immediate: true })
|
||||||
</script>
|
</script>
|
||||||
|
@ -237,13 +264,13 @@ watch([() => paginationData.currentPage, () => paginationData.pageSize], getTabl
|
||||||
|
|
||||||
<el-card v-loading="loading" shadow="never">
|
<el-card v-loading="loading" shadow="never">
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper">
|
||||||
<el-table :data="tableData" @selection-change="handleSelectionChange">
|
<el-table :data="tableData" @selection-change="handleSelectionChange" @sort-change="handleSortChange">
|
||||||
<el-table-column type="selection" width="50" align="center" />
|
<el-table-column type="selection" width="50" align="center" />
|
||||||
<el-table-column prop="name" label="团队名称" align="center" />
|
<el-table-column prop="name" label="团队名称" align="center" sortable="custom"/>
|
||||||
<el-table-column prop="ownerName" label="负责人" align="center" />
|
<el-table-column prop="ownerName" label="负责人" align="center" sortable="custom"/>
|
||||||
<el-table-column prop="memberCount" label="成员数量" align="center" />
|
<el-table-column prop="memberCount" label="成员数量" align="center" sortable="custom"/>
|
||||||
<el-table-column prop="createTime" label="创建时间" align="center" />
|
<el-table-column prop="createTime" label="创建时间" align="center" sortable="custom"/>
|
||||||
<el-table-column prop="updateTime" label="更新时间" align="center" />
|
<el-table-column prop="updateTime" label="更新时间" align="center" sortable="custom"/>
|
||||||
<el-table-column fixed="right" label="操作" width="220" align="center">
|
<el-table-column fixed="right" label="操作" width="220" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button type="success" text bg size="small" :icon="UserFilled" @click="handleManageMembers(scope.row)">
|
<el-button type="success" text bg size="small" :icon="UserFilled" @click="handleManageMembers(scope.row)">
|
||||||
|
|
|
@ -162,7 +162,6 @@ const sortData = reactive({
|
||||||
sortOrder: "desc" // 默认排序顺序 (最新创建的在前)
|
sortOrder: "desc" // 默认排序顺序 (最新创建的在前)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// 存储多选的表格数据
|
// 存储多选的表格数据
|
||||||
const multipleSelection = ref<TableData[]>([])
|
const multipleSelection = ref<TableData[]>([])
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue