feat(base): 前端基础数据三页与客户评级计算器(人员/产品/客户/评级)

- 人员页:编辑抽屉内区域/计划子表编辑;产品页:类别阈值提示条;
  客户页:归属变更二次确认含「不回溯历史」+变更记录抽屉
- 评级页:五项评分实时出等级(纯前端判定,不落库 #25)+ 等级映射维护抽屉
- 菜单两组:基础数据(8-10)/业务数据(14);金额字符串直出禁 float

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
liuwenxinandClaude Code committed 2026-10-13 12:25:45 +08:00
1 parent 09831dbb7f
commit 5207d14daa
10 files changed
+2518 -1

No files matched your search

+127
View File
@@ -0,0 +1,127 @@
import { request } from './request'
import type { PageData } from './types'
/**
* 客户列表项(对应后端 `CustomerOut`)。
*
* owner_personnel_name 由联表带出:归属人员不可考(被物理删除)时为 null,
* owner_personnel_id 仍保留原值供追溯。
*/
export interface CustomerItem {
id: number
company_name: string
/** 客户公司的负责人姓名(非系统内营销人员) */
owner_name: string
contact_person: string | null
contact_phone: string | null
address: string | null
industry: string | null
/** personal 个人户 / manager_personal 经理个人户 / enterprise 企业户(计提规则锚点) */
customer_type: string
owner_personnel_id: number | null
owner_personnel_name: string | null
remark: string | null
}
export interface CustomerQueryParams {
pageNum?: number
pageSize?: number
/** 公司名称或客户负责人,模糊匹配 */
keyword?: string
customer_type?: string
owner_personnel_id?: number
}
/** 新增客户(owner_personnel_id 为初始归属,可空:先建档后派归属也合法) */
export interface CustomerCreateParams {
company_name: string
owner_name: string
contact_person?: string | null
contact_phone?: string | null
address?: string | null
industry?: string | null
customer_type: string
owner_personnel_id?: number | null
remark?: string | null
}
/**
* 编辑客户:不含归属字段 —— 归属调整统一走 `PUT /{id}/ownership`
* (唯一写归属留痕的入口),编辑表单即使提交归属也会被后端忽略。
*/
export type CustomerUpdateParams = Omit<CustomerCreateParams, 'owner_personnel_id'>
/** 归属变更入参(new_owner_personnel_id 空 = 清空归属) */
export interface CustomerOwnershipParams {
new_owner_personnel_id?: number | null
reason?: string | null
}
/** 归属变更留痕条目(对应后端 `OwnershipChangeLogOut`;姓名可随人员消失,ID 固化) */
export interface OwnershipLogItem {
id: number
customer_id: number
old_owner_personnel_id: number | null
new_owner_personnel_id: number | null
old_owner_name: string | null
new_owner_name: string | null
change_reason: string | null
operator_id: number | null
operator_name: string
create_time: string
}
/** 客户分类下拉项(与后端 `core/constants.py` 的值域一致) */
export const CUSTOMER_TYPE_OPTIONS = [
{ label: '个人户', value: 'personal' },
{ label: '经理个人户', value: 'manager_personal' },
{ label: '企业户', value: 'enterprise' },
] as const
/** 分类编码 → 展示名(表格列展示用,未知编码原样回显) */
export function customerTypeLabel(code: string): string {
return CUSTOMER_TYPE_OPTIONS.find((o) => o.value === code)?.label ?? code
}
/** 分页查询客户(keyword 对公司名称/客户负责人模糊匹配,附归属人员姓名) */
export function listCustomers(params: CustomerQueryParams): Promise<PageData<CustomerItem>> {
return request({ url: '/v1/base/customers', method: 'get', params })
}
/** 新增客户(公司名称+负责人组合唯一,冲突由后端拦截) */
export function createCustomer(data: CustomerCreateParams): Promise<CustomerItem> {
return request({ url: '/v1/base/customers', method: 'post', data })
}
/** 编辑客户档案(不含归属;全量提交) */
export function updateCustomer(
customerId: number,
data: CustomerUpdateParams,
): Promise<CustomerItem> {
return request({ url: `/v1/base/customers/${customerId}`, method: 'put', data })
}
/** 删除客户(物理删除) */
export function deleteCustomer(customerId: number): Promise<null> {
return request({ url: `/v1/base/customers/${customerId}`, method: 'delete' })
}
/** 归属变更(唯一写归属留痕的入口;新旧相同后端报「归属未变化」) */
export function changeOwnership(
customerId: number,
data: CustomerOwnershipParams,
): Promise<CustomerItem> {
return request({ url: `/v1/base/customers/${customerId}/ownership`, method: 'put', data })
}
/** 查某客户的归属变更留痕(分页,按变更时间倒序) */
export function listOwnershipLogs(
customerId: number,
params: { pageNum?: number; pageSize?: number },
): Promise<PageData<OwnershipLogItem>> {
return request({
url: `/v1/base/customers/${customerId}/ownership-logs`,
method: 'get',
params,
})
}