PayrollManagementSystem/frontend/src/api/businesses.ts
liuwenxin 06cdf4141f feat(business): 前端业务/发货/回款管理三页
- 业务页:明细行编辑器、详情抽屉五分区(含状态时间线与毛利润卡片)
- 回款页:业务→发货批次级联指定(可清空)、已核算行禁改禁删
- 金额/比率字符串直出;毛利润卡片注明不含运费口径

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 12:50:10 +08:00

295 lines
9.2 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.

import { request } from './request'
import type { PageData } from './types'
/**
* 业务产品明细行(对应后端 `BusinessItemOut`)。
*
* 数量与金额一律字符串直出 —— 金额红线:不经 float、不 toFixed,
* Decimal 运算收敛在后端 service 层。
*/
export interface BusinessItemRow {
id: number
product_id: number | null
product_name: string
spec_model: string | null
unit: string | null
/** municipal_water 市政水利 / rail_transit 轨道交通 —— 行级折算锚点 */
product_category: string
/** 数字字符串,>0 */
quantity: string
sale_price: string | null
/** 行销售额 = 数量 × 销售单价,后端计算固化 */
sale_amount: string
cost_amount: string | null
guided_price: string | null
remark: string | null
}
/** 业务列表项(对应后端 `BusinessOut`;四个汇总金额均为字符串直出) */
export interface BusinessItem {
id: number
business_no: string
customer_id: number
customer_name: string | null
/** ISO 串(YYYY-MM-DD) */
business_date: string | null
/** 1执行中 2已完成 3已终止 */
status: number
owner_personnel_id: number | null
owner_personnel_name: string | null
assistant_personnel_id: number | null
assistant_personnel_name: string | null
/** 特殊业务标记:1是 0否 */
is_special: number
special_note: string | null
total_sale_amount: string | null
total_cost_amount: string | null
total_ship_amount: string | null
total_received_amount: string | null
total_freight_amount: string | null
remark: string | null
}
/** 业务详情:附产品明细行(编辑弹窗一次回显) */
export interface BusinessDetail extends BusinessItem {
items: BusinessItemRow[]
}
export interface BusinessQueryParams {
pageNum?: number
pageSize?: number
/** 业务编号/公司名称,模糊匹配 */
keyword?: string
status?: number
customer_id?: number
owner_personnel_id?: number
/** 业务日期起(含),ISO 串 */
date_from?: string
/** 业务日期止(含),ISO 串 */
date_to?: string
}
/** 明细行入参(product_id 空 = 自由录入;金额/数量为数字字符串) */
export interface BusinessItemParams {
product_id?: number | null
product_name: string
spec_model?: string | null
unit?: string | null
product_category: string
quantity: string
sale_price?: string | null
cost_amount?: string | null
guided_price?: string | null
remark?: string | null
}
/**
* 创建业务:主表信息 + 明细行(≥1)。
*
* is_special=1 时 special_note 必填(后端校验,前端同步拦截)。
*/
export interface BusinessCreateParams {
customer_id: number
business_date?: string | null
owner_personnel_id?: number | null
assistant_personnel_id?: number | null
is_special?: number
special_note?: string | null
items: BusinessItemParams[]
remark?: string | null
}
/**
* 编辑业务:明细全量替换并重算汇总。
*
* 不含归属字段 —— 归属调整统一走 `PUT /{id}/ownership`(唯一写归属
* 留痕的入口),编辑表单即使提交归属也会被后端忽略。
*/
export interface BusinessUpdateParams {
customer_id: number
business_date?: string | null
is_special?: number
special_note?: string | null
items: BusinessItemParams[]
remark?: string | null
}
/** 状态流转入参:执行中 → 2已完成 / 3已终止;终止时 reason 必填 */
export interface BusinessStatusParams {
status: number
reason?: string | null
}
/** 归属变更入参(新负责/新协助;前后值写入留痕,不回溯历史) */
export interface BusinessOwnershipParams {
new_owner_personnel_id?: number | null
new_assistant_personnel_id?: number | null
reason?: string | null
}
/** 业务归属变更留痕条目(对应后端 `OwnershipChangeLogOut`;姓名可随人员消失,ID 固化) */
export interface OwnershipLogItem {
id: number
business_id: number
old_owner_personnel_id: number | null
new_owner_personnel_id: number | null
old_assistant_personnel_id: number | null
new_assistant_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
}
/** 业务状态流转记录(对应后端 `BusinessStatusLogOut`;创建首条 old=new=1) */
export interface StatusLogItem {
id: number
business_id: number
old_status: number
new_status: number
change_reason: string | null
operator_id: number | null
operator_name: string
create_time: string
}
/** 毛利润视图行(对应后端 `GrossProfitRowOut`);成本缺失行派生列为 null */
export interface GrossProfitRowItem {
item_id: number
product_category: string
product_name: string
spec_model: string | null
quantity: string
sale_amount: string
cost_amount: string | null
profit_amount: string | null
profit_rate: string | null
threshold: string
converted_profit: string | null
missing_reason: string | null
}
/** 按产品类别的毛利润汇总(成本缺失行不计入聚合) */
export interface GrossProfitCategory {
product_category: string
sale_amount: string
cost_amount: string
profit_amount: string
/** 分数字符串原样(如 "997/1000"),不做数值化展示 */
profit_rate: string
threshold: string
converted_profit: string
}
/** 毛利润数据视图(对应后端 `GrossProfitOut`) */
export interface GrossProfitView {
business_id: number
/** 参数取值时点(默认今日),ISO 串 */
as_of: string
rows: GrossProfitRowItem[]
categories: GrossProfitCategory[]
missing_count: number
note: string
}
/** 业务状态下拉项(与后端值域一致;执行中=1 已完成=2 已终止=3) */
export const BUSINESS_STATUS_OPTIONS = [
{ label: '执行中', value: 1 },
{ label: '已完成', value: 2 },
{ label: '已终止', value: 3 },
] as const
/** 状态编码 → 展示名 */
export function businessStatusLabel(status: number): string {
return BUSINESS_STATUS_OPTIONS.find((o) => o.value === status)?.label ?? `状态${status}`
}
/** 状态编码 → 标签类型(三色:执行中 primary / 已完成 success / 已终止 danger) */
export function businessStatusTagType(status: number): 'primary' | 'success' | 'danger' | 'info' {
if (status === 2) return 'success'
if (status === 3) return 'danger'
return 'primary'
}
/** 分页查询业务(编号/公司名称模糊,可按状态/客户/归属/日期范围筛选) */
export function listBusinesses(params: BusinessQueryParams): Promise<PageData<BusinessItem>> {
return request({ url: '/v1/business/businesses', method: 'get', params })
}
/** 创建业务(编号自动生成,写首条状态留痕) */
export function createBusiness(data: BusinessCreateParams): Promise<BusinessItem> {
return request({ url: '/v1/business/businesses', method: 'post', data })
}
/** 业务详情(附产品明细行) */
export function getBusinessDetail(businessId: number): Promise<BusinessDetail> {
return request({ url: `/v1/business/businesses/${businessId}`, method: 'get' })
}
/** 编辑业务(明细全量替换;归属不在此端点调整) */
export function updateBusiness(
businessId: number,
data: BusinessUpdateParams,
): Promise<BusinessItem> {
return request({ url: `/v1/business/businesses/${businessId}`, method: 'put', data })
}
/** 删除业务(有发货或回款记录时后端拒绝,应改为已终止) */
export function deleteBusiness(businessId: number): Promise<null> {
return request({ url: `/v1/business/businesses/${businessId}`, method: 'delete' })
}
/** 状态流转(终态不可再变更;终止必填原因) */
export function changeBusinessStatus(
businessId: number,
data: BusinessStatusParams,
): Promise<BusinessItem> {
return request({ url: `/v1/business/businesses/${businessId}/status`, method: 'put', data })
}
/** 调整负责/协助营销人员(同事务写归属变更留痕) */
export function changeBusinessOwnership(
businessId: number,
data: BusinessOwnershipParams,
): Promise<BusinessItem> {
return request({ url: `/v1/business/businesses/${businessId}/ownership`, method: 'put', data })
}
/** 某业务的归属变更留痕(分页,按变更时间倒序) */
export function listOwnershipLogs(
businessId: number,
params: { pageNum?: number; pageSize?: number },
): Promise<PageData<OwnershipLogItem>> {
return request({
url: `/v1/business/businesses/${businessId}/ownership-logs`,
method: 'get',
params,
})
}
/** 某业务的状态流转时间线(分页,按时间正序,从创建起展示) */
export function listStatusLogs(
businessId: number,
params: { pageNum?: number; pageSize?: number },
): Promise<PageData<StatusLogItem>> {
return request({
url: `/v1/business/businesses/${businessId}/status-logs`,
method: 'get',
params,
})
}
/** 毛利润数据视图(as_of 缺省=今日;阈值按该时点参数快照) */
export function getGrossProfit(
businessId: number,
asOf?: string,
): Promise<GrossProfitView> {
return request({
url: `/v1/business/businesses/${businessId}/gross-profit`,
method: 'get',
params: asOf ? { as_of: asOf } : undefined,
})
}