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>
202 lines
6.0 KiB
TypeScript
202 lines
6.0 KiB
TypeScript
/**
|
||
* 客户管理 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()}`
|
||
},
|
||
}
|