front/src/api/customer/index.ts
zzh abfca7a21a feat: add H5 customer center, marketing admin, and employee profile UX
Ship customer portal and marketing pages, user edit drawer with employee archive, IDE employee numbers, channel config refactor, and related nginx/route updates.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-26 23:44:02 +08:00

202 lines
6.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 客户管理 API(文档:GET/POST /customer/*,admin 同源)
*/
import { axiosInstance } from '@/api/rbac'
import { assertBusinessOk, omsUrl, parseListPayload, unwrapData } from '@/api/oms/common'
export type CustomerStatus = 0 | 1 | 2
export type CustomerGroup = 0 | 1 | 2 | 3 | 4 | 5
export interface CustomerDto {
id?: string | number
parentCustomerId?: number | null
userId?: number
customerCode?: string
customerName?: string
wechatAvatar?: string
wechatAvatarUrl?: string
wechatNickname?: string
email?: string
phone?: string
balance?: number
accountBalance?: number
totalQuota?: number
usedQuota?: number
status?: CustomerStatus
remark?: string
createTime?: string
createdAt?: string
createBy?: string
createdBy?: string
updateTime?: string
updateBy?: string
salesman?: string | number
salesPerson?: string | number
customerService?: string | number
customerGroup?: CustomerGroup
memberLevelId?: number | null
memberLevelName?: string
lastLoginIp?: string
lastOnlineIp?: string
lastLoginTime?: string
lastOnlineTime?: string
role?: string | number
}
export interface CustomerListParams {
page?: number
pageSize?: number
keyword?: string
status?: number
customerGroup?: number
salesman?: string
customerService?: string
}
export interface CustomerPagedResult {
items: CustomerDto[]
total: number
}
function mapUpdateBody(id: string | number, data: Partial<CustomerDto>) {
return {
id,
customerCode: data.customerCode,
customerName: data.customerName,
wechatAvatar: data.wechatAvatarUrl ?? data.wechatAvatar,
wechatNickname: data.wechatNickname,
email: data.email,
phone: data.phone,
balance: data.accountBalance ?? data.balance,
totalQuota: data.totalQuota,
usedQuota: data.usedQuota,
status: data.status,
role: data.role,
remark: data.remark,
salesman: data.salesman ?? data.salesPerson,
customerService: data.customerService,
customerGroup: data.customerGroup,
memberLevelId: data.memberLevelId,
}
}
export interface CustomerServiceAdvisorDto {
name?: string
wechatId?: string
wechatQrCode?: string
}
export const CustomerService = {
async getList(params: CustomerListParams): Promise<CustomerPagedResult> {
const res = await axiosInstance.get(omsUrl('/customer/list'), { params })
return parseListPayload(res.data)
},
async getById(id: string | number): Promise<CustomerDto> {
const res = await axiosInstance.get(omsUrl('/customer/get'), { params: { id } })
return unwrapData<CustomerDto>(res.data)
},
async getServiceAdvisor(): Promise<CustomerServiceAdvisorDto> {
const res = await axiosInstance.get(omsUrl('/customer/service-advisor'))
return unwrapData<CustomerServiceAdvisorDto>(res.data)
},
async createSub(
data: Partial<CustomerDto> & { password?: string; permissions?: string[] }
): Promise<void> {
const body = {
customerCode: data.customerCode,
customerName: data.customerName,
wechatAvatar: data.wechatAvatarUrl ?? data.wechatAvatar,
wechatNickname: data.wechatNickname,
phone: data.phone,
email: data.email,
password: data.password,
balance: data.accountBalance ?? data.balance ?? 0,
totalQuota: data.totalQuota ?? 0,
usedQuota: data.usedQuota ?? 0,
status: data.status ?? 1,
remark: data.remark,
salesman: data.salesman ?? data.salesPerson,
customerService: data.customerService,
customerGroup: data.customerGroup ?? 0,
memberLevelId: data.memberLevelId,
permissions: data.permissions ?? [],
}
const r = await axiosInstance.post(omsUrl('/customer/sub/create'), body)
assertBusinessOk(r.data)
},
async create(data: Partial<CustomerDto> & { password?: string; inviteCode?: string }): Promise<void> {
const body = {
customerCode: data.customerCode || undefined,
customerName: data.customerName,
wechatAvatar: data.wechatAvatarUrl ?? data.wechatAvatar,
wechatNickname: data.wechatNickname,
phone: data.phone,
email: data.email,
password: data.password,
balance: data.accountBalance ?? data.balance,
totalQuota: data.totalQuota,
usedQuota: data.usedQuota,
status: data.status ?? 1,
role: data.role,
remark: data.remark,
salesman: data.salesman ?? data.salesPerson,
customerService: data.customerService,
customerGroup: data.customerGroup ?? 0,
memberLevelId: data.memberLevelId,
inviteCode: data.inviteCode?.trim() || undefined,
}
const r = await axiosInstance.post(omsUrl('/customer/create'), body)
assertBusinessOk(r.data)
},
async update(id: string | number, data: Partial<CustomerDto>): Promise<void> {
const r = await axiosInstance.post(omsUrl('/customer/update'), mapUpdateBody(id, data))
assertBusinessOk(r.data)
},
async delete(id: string | number): Promise<void> {
const r = await axiosInstance.post(omsUrl('/customer/delete'), { id })
assertBusinessOk(r.data)
},
async resetPassword(id: string | number, newPassword: string): Promise<void> {
const r = await axiosInstance.post(omsUrl('/customer/reset-password'), { id, newPassword })
assertBusinessOk(r.data)
},
async omsLogin(customerId: string | number): Promise<{
accessToken: string
refreshToken?: string | null
expiresIn?: number
}> {
const r = await axiosInstance.post(omsUrl('/rbac/auth/customer-oms-login'), {
customerId: Number(customerId),
})
const data = unwrapData<any>(r.data)
return {
accessToken: data.accessToken ?? data.AccessToken ?? '',
refreshToken: data.refreshToken ?? data.RefreshToken ?? null,
expiresIn: data.expiresIn ?? data.ExpiresIn,
}
},
buildCustomerSsoUrl(result: {
accessToken: string
refreshToken?: string | null
}): string {
const params = new URLSearchParams({
sso: '1',
accessToken: result.accessToken,
})
if (result.refreshToken) {
params.set('refreshToken', result.refreshToken)
}
return `${window.location.origin}/?${params.toString()}`
},
}