236 lines
7.7 KiB
Plaintext
236 lines
7.7 KiB
Plaintext
import { supa } from '@/utils/supabaseService.uts'
|
||
import type { AkReqResponse } from '@/uni_modules/ak-req/interface.uts'
|
||
|
||
// Admin 用户管理相关类型定义
|
||
export type AdminUserItem = {
|
||
id: string
|
||
auth_id: string
|
||
username: string
|
||
email: string
|
||
role: string
|
||
profile_status?: number
|
||
real_name?: string
|
||
credit_score?: number
|
||
verification_status?: number
|
||
created_at: string
|
||
updated_at: string
|
||
balance: number // 固定 0
|
||
is_member: boolean
|
||
member_plan_name?: string
|
||
member_end_date?: string
|
||
}
|
||
|
||
export type AdminUserDetail = {
|
||
id: string
|
||
auth_id: string
|
||
username: string
|
||
email: string
|
||
role: string
|
||
profile_status?: number
|
||
real_name?: string
|
||
credit_score?: number
|
||
verification_status?: number
|
||
preferences?: UTSJSONObject
|
||
emergency_contact?: string
|
||
service_areas?: UTSJSONObject
|
||
created_at: string
|
||
updated_at: string
|
||
balance: number // 固定 0
|
||
is_member: boolean
|
||
member_info?: {
|
||
plan_name: string
|
||
plan_code: string
|
||
billing_period: string
|
||
price: number
|
||
features: UTSJSONObject
|
||
status: string
|
||
start_date: string
|
||
end_date?: string
|
||
next_billing_date?: string
|
||
auto_renew: boolean
|
||
}
|
||
addresses?: Array<{
|
||
id: string
|
||
receiver_name: string
|
||
receiver_phone: string
|
||
province: string
|
||
city: string
|
||
district: string
|
||
address_detail: string
|
||
postal_code?: string
|
||
is_default: boolean
|
||
label?: string
|
||
latitude?: number
|
||
longitude?: number
|
||
delivery_instructions?: string
|
||
business_hours?: string
|
||
status: number
|
||
created_at: string
|
||
updated_at: string
|
||
}>
|
||
}
|
||
|
||
export type AdminUserListParams = {
|
||
page?: number
|
||
limit?: number
|
||
search?: string
|
||
role?: string
|
||
status?: number
|
||
is_member?: boolean
|
||
}
|
||
|
||
export type AdminUserListResponse = {
|
||
total: number
|
||
page: number
|
||
limit: number
|
||
has_more: boolean
|
||
items: Array<AdminUserItem>
|
||
}
|
||
|
||
/**
|
||
* Admin 用户管理服务
|
||
* 封装对 admin 用户管理相关 RPC 的调用
|
||
* 符合项目规范:页面/组件不得直接访问 supabase client,必须通过 services
|
||
*/
|
||
export class AdminUserService {
|
||
/**
|
||
* 获取用户列表(分页+筛选)
|
||
* @param params 查询参数
|
||
* @returns Promise<AdminUserListResponse>
|
||
*/
|
||
static async getUserList(params: AdminUserListParams = {}): Promise<AdminUserListResponse> {
|
||
try {
|
||
const rpcParams = {
|
||
p_page: params.page ?? 1,
|
||
p_limit: params.limit ?? 20,
|
||
p_search: params.search ?? null,
|
||
p_role: params.role ?? null,
|
||
p_status: params.status ?? null,
|
||
p_is_member: params.is_member ?? null
|
||
} as UTSJSONObject
|
||
|
||
const response = await supa.rpc('rpc_admin_user_list', rpcParams)
|
||
|
||
if (response.error != null) {
|
||
throw new Error(`RPC 调用失败: ${response.error.message}`)
|
||
}
|
||
|
||
const data = response.data as UTSJSONObject
|
||
return {
|
||
total: data.getNumber('total') ?? 0,
|
||
page: data.getNumber('page') ?? 1,
|
||
limit: data.getNumber('limit') ?? 20,
|
||
has_more: data.getBoolean('has_more') ?? false,
|
||
items: (data.getArray('items') as Array<UTSJSONObject>)?.map(item => ({
|
||
id: item.getString('id') ?? '',
|
||
auth_id: item.getString('auth_id') ?? '',
|
||
username: item.getString('username') ?? '',
|
||
email: item.getString('email') ?? '',
|
||
role: item.getString('role') ?? '',
|
||
profile_status: item.getNumber('profile_status'),
|
||
real_name: item.getString('real_name'),
|
||
credit_score: item.getNumber('credit_score'),
|
||
verification_status: item.getNumber('verification_status'),
|
||
created_at: item.getString('created_at') ?? '',
|
||
updated_at: item.getString('updated_at') ?? '',
|
||
balance: item.getNumber('balance') ?? 0,
|
||
is_member: item.getBoolean('is_member') ?? false,
|
||
member_plan_name: item.getString('member_plan_name'),
|
||
member_end_date: item.getString('member_end_date')
|
||
})) ?? []
|
||
}
|
||
} catch (error) {
|
||
console.error('[AdminUserService] getUserList error:', error)
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取用户详情
|
||
* @param userId 用户ID(ak_users.id)
|
||
* @returns Promise<AdminUserDetail | null>
|
||
*/
|
||
static async getUserDetail(userId: string): Promise<AdminUserDetail | null> {
|
||
try {
|
||
const response = await supa.rpc('rpc_admin_user_detail', { p_user_id: userId } as UTSJSONObject)
|
||
|
||
if (response.error != null) {
|
||
throw new Error(`RPC 调用失败: ${response.error.message}`)
|
||
}
|
||
|
||
const data = response.data as UTSJSONObject
|
||
if (data == null) {
|
||
return null
|
||
}
|
||
|
||
// 解析会员信息
|
||
let memberInfo: any = null
|
||
const memberInfoObj = data.getJSONObject('member_info')
|
||
if (memberInfoObj != null) {
|
||
memberInfo = {
|
||
plan_name: memberInfoObj.getString('plan_name') ?? '',
|
||
plan_code: memberInfoObj.getString('plan_code') ?? '',
|
||
billing_period: memberInfoObj.getString('billing_period') ?? '',
|
||
price: memberInfoObj.getNumber('price') ?? 0,
|
||
features: memberInfoObj.getJSONObject('features') ?? {},
|
||
status: memberInfoObj.getString('status') ?? '',
|
||
start_date: memberInfoObj.getString('start_date') ?? '',
|
||
end_date: memberInfoObj.getString('end_date'),
|
||
next_billing_date: memberInfoObj.getString('next_billing_date'),
|
||
auto_renew: memberInfoObj.getBoolean('auto_renew') ?? false
|
||
}
|
||
}
|
||
|
||
// 解析地址列表
|
||
let addresses: any[] = []
|
||
const addressesArray = data.getArray('addresses') as Array<UTSJSONObject>
|
||
if (addressesArray != null) {
|
||
addresses = addressesArray.map(addr => ({
|
||
id: addr.getString('id') ?? '',
|
||
receiver_name: addr.getString('receiver_name') ?? '',
|
||
receiver_phone: addr.getString('receiver_phone') ?? '',
|
||
province: addr.getString('province') ?? '',
|
||
city: addr.getString('city') ?? '',
|
||
district: addr.getString('district') ?? '',
|
||
address_detail: addr.getString('address_detail') ?? '',
|
||
postal_code: addr.getString('postal_code'),
|
||
is_default: addr.getBoolean('is_default') ?? false,
|
||
label: addr.getString('label'),
|
||
latitude: addr.getNumber('latitude'),
|
||
longitude: addr.getNumber('longitude'),
|
||
delivery_instructions: addr.getString('delivery_instructions'),
|
||
business_hours: addr.getString('business_hours'),
|
||
status: addr.getNumber('status') ?? 1,
|
||
created_at: addr.getString('created_at') ?? '',
|
||
updated_at: addr.getString('updated_at') ?? ''
|
||
}))
|
||
}
|
||
|
||
return {
|
||
id: data.getString('id') ?? '',
|
||
auth_id: data.getString('auth_id') ?? '',
|
||
username: data.getString('username') ?? '',
|
||
email: data.getString('email') ?? '',
|
||
role: data.getString('role') ?? '',
|
||
profile_status: data.getNumber('profile_status'),
|
||
real_name: data.getString('real_name'),
|
||
credit_score: data.getNumber('credit_score'),
|
||
verification_status: data.getNumber('verification_status'),
|
||
preferences: data.getJSONObject('preferences'),
|
||
emergency_contact: data.getString('emergency_contact'),
|
||
service_areas: data.getJSONObject('service_areas'),
|
||
created_at: data.getString('created_at') ?? '',
|
||
updated_at: data.getString('updated_at') ?? '',
|
||
balance: data.getNumber('balance') ?? 0,
|
||
is_member: data.getBoolean('is_member') ?? false,
|
||
member_info: memberInfo,
|
||
addresses: addresses
|
||
}
|
||
} catch (error) {
|
||
console.error('[AdminUserService] getUserDetail error:', error)
|
||
throw error
|
||
}
|
||
}
|
||
}
|
||
|
||
export default AdminUserService |