refactor: migrate wechat to user attributes and enhance users list
Migrate the hardcoded wechat field to the new extensible user attributes system and improve the users management UI. Migration: - Add migration 019 to move wechat data to user_attribute_values - Remove wechat field from User entity, DTOs, and API contracts - Clean up wechat-related code from backend and frontend UsersView enhancements: - Add text labels to action buttons (Filter Settings, Column Settings, Attributes Config) for better UX - Change status column to show colored dot + Chinese text instead of English text - Add dynamic attribute columns support with batch loading - Add column visibility settings with localStorage persistence - Add filter settings modal for search and filter preferences - Update i18n translations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,7 @@ import type { User, UpdateUserRequest, PaginatedResponse } from '@/types'
|
||||
* List all users with pagination
|
||||
* @param page - Page number (default: 1)
|
||||
* @param pageSize - Items per page (default: 20)
|
||||
* @param filters - Optional filters (status, role, search)
|
||||
* @param filters - Optional filters (status, role, search, attributes)
|
||||
* @param options - Optional request options (signal)
|
||||
* @returns Paginated list of users
|
||||
*/
|
||||
@@ -21,17 +21,32 @@ export async function list(
|
||||
status?: 'active' | 'disabled'
|
||||
role?: 'admin' | 'user'
|
||||
search?: string
|
||||
attributes?: Record<number, string> // attributeId -> value
|
||||
},
|
||||
options?: {
|
||||
signal?: AbortSignal
|
||||
}
|
||||
): Promise<PaginatedResponse<User>> {
|
||||
// Build params with attribute filters in attr[id]=value format
|
||||
const params: Record<string, any> = {
|
||||
page,
|
||||
page_size: pageSize,
|
||||
status: filters?.status,
|
||||
role: filters?.role,
|
||||
search: filters?.search
|
||||
}
|
||||
|
||||
// Add attribute filters as attr[id]=value
|
||||
if (filters?.attributes) {
|
||||
for (const [attrId, value] of Object.entries(filters.attributes)) {
|
||||
if (value) {
|
||||
params[`attr[${attrId}]`] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const { data } = await apiClient.get<PaginatedResponse<User>>('/admin/users', {
|
||||
params: {
|
||||
page,
|
||||
page_size: pageSize,
|
||||
...filters
|
||||
},
|
||||
params,
|
||||
signal: options?.signal
|
||||
})
|
||||
return data
|
||||
|
||||
Reference in New Issue
Block a user