feat(client): A3 客户与行业目录(两级行业、客户组、字段审批)
背景:A3 需把行业 / 客户 / 客户组 / 客户级字段立为资产根节点;用户确认两级行业树与混搭 UI(行业 B / 客户列表 A / 详情 A / 新建 B / 客户组 B / 字段 A)。 改动: - 新增 ADR-002,行业改为两级树,客户挂末级行业;同步 PRD / 技术架构 / 开发计划。 - 新增 client 模块:industries / customers / customer-groups / customer-fields 接口、真实 PrismaCustomerDirectory、客户状态机与客户转交、客户组数据范围解析、跨客户 404。 - 新增迁移与幂等种子(电商/金融两级行业、2 客户、1 客户组、4 条字段)。 - 前端新增行业/客户/客户组/字段审批页面与路由、导航更名(客户管理 / 行业管理 / 客户组),复用现有 token。 - 补充 shared 契约单测、client 集成用例、A3 浏览器 e2e。 影响面:client 模块与 client 表、shared 契约、web 路由/导航、ScopeContext 数据范围、OpenAPI 与种子;A1 客户转交占位由 client 实现替换。 回滚:回滚本提交;数据库保留新增表或按报告执行 down SQL;CUSTOMER_DIRECTORY 可切回空集实现。 验证:format:check / lint / typecheck / test 全绿(shared 131 / api 90 / web 125,共 346);test:int 5 文件 39 条;A3 e2e 1/1;build 8/8;真实浏览器六页验证通过。
This commit is contained in:
1 parent
8626996bb1
commit
140dc386c1
54 files changed
+9018
-147
No files matched your search
@@ -0,0 +1,236 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { useAuthStore } from '@/stores/auth-store';
|
||||
|
||||
import { setUnauthorizedHandler } from './client';
|
||||
import {
|
||||
applyCustomerField,
|
||||
applyIndustryPack,
|
||||
approveCustomerField,
|
||||
createCustomer,
|
||||
createCustomerGroup,
|
||||
createIndustry,
|
||||
deleteCustomerGroup,
|
||||
deleteIndustry,
|
||||
fetchCustomerDetail,
|
||||
fetchCustomerFieldList,
|
||||
fetchCustomerFields,
|
||||
fetchCustomerGroupDetail,
|
||||
fetchCustomerGroupList,
|
||||
fetchCustomerList,
|
||||
fetchIndustryDetail,
|
||||
fetchIndustryList,
|
||||
setCustomerGroups,
|
||||
setCustomerStatus,
|
||||
setIndustryStatus,
|
||||
transferCustomer,
|
||||
updateCustomer,
|
||||
updateCustomerGroup,
|
||||
updateCustomerGroupMembers,
|
||||
updateIndustry,
|
||||
} from './customers';
|
||||
|
||||
const ID = '01HZZZZZZZZZZZZZZZZZZZZZZ1';
|
||||
const ID2 = '01HZZZZZZZZZZZZZZZZZZZZZZ2';
|
||||
const NOW = '2026-11-03T10:00:00.000Z';
|
||||
|
||||
const jsonResponse = (body: unknown, status = 200): Response =>
|
||||
new Response(status === 204 ? null : JSON.stringify(body), {
|
||||
status,
|
||||
headers: status === 204 ? undefined : { 'Content-Type': 'application/json' },
|
||||
});
|
||||
|
||||
const industryNode = {
|
||||
id: ID,
|
||||
parentId: null,
|
||||
level: 1,
|
||||
name: '电商',
|
||||
sortOrder: 10,
|
||||
status: 'active',
|
||||
remark: '',
|
||||
customerCount: 1,
|
||||
assetCount: 0,
|
||||
updatedAt: NOW,
|
||||
};
|
||||
const industryTree = { ...industryNode, children: [] };
|
||||
const industryDetail = {
|
||||
...industryNode,
|
||||
parentName: null,
|
||||
references: {
|
||||
childCount: 0,
|
||||
activeChildCount: 0,
|
||||
customerCount: 1,
|
||||
customers: [],
|
||||
assetCount: 0,
|
||||
},
|
||||
};
|
||||
|
||||
const customerSummary = {
|
||||
id: ID,
|
||||
name: '花间集',
|
||||
shortName: 'HJ',
|
||||
industryId: ID,
|
||||
industryName: '服饰鞋包',
|
||||
industryPath: '电商 / 服饰鞋包',
|
||||
status: 'active',
|
||||
ownerUserId: ID2,
|
||||
ownerName: '陈默',
|
||||
groups: [],
|
||||
baseFieldCount: 1,
|
||||
genFieldCount: 1,
|
||||
updatedAt: NOW,
|
||||
};
|
||||
const customerDetail = {
|
||||
...customerSummary,
|
||||
contactName: '林晓',
|
||||
contactPhone: '138****2210',
|
||||
preferences: { naming: '', directory: '', specs: [], taboo: [] },
|
||||
baseFields: [{ key: '门店', value: '沪-001' }],
|
||||
fields: [],
|
||||
remark: null,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const groupSummary = {
|
||||
id: ID,
|
||||
name: '电商核心组',
|
||||
description: '',
|
||||
memberCount: 0,
|
||||
updatedAt: NOW,
|
||||
};
|
||||
const groupDetail = { ...groupSummary, members: [] };
|
||||
const field = {
|
||||
id: ID,
|
||||
customerId: ID2,
|
||||
name: '活动编码',
|
||||
code: 'campaign_code',
|
||||
type: 'text',
|
||||
options: [],
|
||||
purpose: '检索',
|
||||
entersGeneration: true,
|
||||
status: 'pending',
|
||||
applicantName: '陈默',
|
||||
approverName: null,
|
||||
appliedAt: NOW,
|
||||
approvedAt: null,
|
||||
rejectReason: null,
|
||||
};
|
||||
const fieldListItem = {
|
||||
...field,
|
||||
customerName: '花间集',
|
||||
customerShortName: 'HJ',
|
||||
industryPath: '电商 / 服饰鞋包',
|
||||
};
|
||||
|
||||
function lastCall(): { url: string; init: RequestInit | undefined } {
|
||||
const fetchMock = vi.mocked(globalThis.fetch);
|
||||
const call = fetchMock.mock.calls.at(-1);
|
||||
const input = call?.[0];
|
||||
const url =
|
||||
typeof input === 'string' ? input : input instanceof URL ? input.href : (input?.url ?? '');
|
||||
return { url, init: call?.[1] };
|
||||
}
|
||||
|
||||
function lastBody(): unknown {
|
||||
const body = lastCall().init?.body;
|
||||
return typeof body === 'string' ? (JSON.parse(body) as unknown) : undefined;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
window.localStorage.clear();
|
||||
useAuthStore.getState().clearSession();
|
||||
setUnauthorizedHandler(null);
|
||||
useAuthStore.getState().setSession({
|
||||
accessToken: 'token',
|
||||
user: { id: ID2, name: '陈默', account: 'chen.mo' },
|
||||
permissions: ['customer:read'],
|
||||
});
|
||||
});
|
||||
|
||||
describe('客户与行业接口封装', () => {
|
||||
it('行业:列表 / 详情 / 新建 / 更新 / 状态 / 删除', async () => {
|
||||
vi.spyOn(globalThis, 'fetch')
|
||||
.mockResolvedValueOnce(jsonResponse({ items: [industryTree], next_cursor: null }))
|
||||
.mockResolvedValueOnce(jsonResponse(industryDetail))
|
||||
.mockResolvedValueOnce(jsonResponse(industryDetail, 201))
|
||||
.mockResolvedValueOnce(jsonResponse(industryDetail))
|
||||
.mockResolvedValueOnce(jsonResponse(industryDetail))
|
||||
.mockResolvedValueOnce(jsonResponse(undefined, 204));
|
||||
|
||||
await fetchIndustryList({ keyword: '电商', limit: 100 });
|
||||
expect(lastCall().url).toContain('/industries?keyword=');
|
||||
await fetchIndustryDetail(ID);
|
||||
await createIndustry({ name: '电商', sortOrder: 10, remark: '' });
|
||||
expect(lastBody()).toEqual({ name: '电商', sortOrder: 10, remark: '' });
|
||||
await updateIndustry(ID, { name: '电商2' });
|
||||
await setIndustryStatus(ID, { status: 'disabled' });
|
||||
await deleteIndustry(ID);
|
||||
expect(lastCall().url).toContain(`/industries/${ID}`);
|
||||
});
|
||||
|
||||
it('客户:列表 / 详情 / 新建 / 更新 / 状态 / 转交 / 组 / 资产包', async () => {
|
||||
vi.spyOn(globalThis, 'fetch')
|
||||
.mockResolvedValueOnce(jsonResponse({ items: [customerSummary], next_cursor: null }))
|
||||
.mockResolvedValueOnce(jsonResponse(customerDetail))
|
||||
.mockResolvedValueOnce(jsonResponse(customerDetail, 201))
|
||||
.mockResolvedValueOnce(jsonResponse(customerDetail))
|
||||
.mockResolvedValueOnce(jsonResponse(customerDetail))
|
||||
.mockResolvedValueOnce(jsonResponse(customerDetail))
|
||||
.mockResolvedValueOnce(jsonResponse(customerDetail))
|
||||
.mockResolvedValueOnce(jsonResponse({}, 200));
|
||||
|
||||
await fetchCustomerList({ status: 'active', limit: 100 });
|
||||
expect(lastCall().url).toContain('/customers?status=active');
|
||||
await fetchCustomerDetail(ID);
|
||||
await createCustomer({
|
||||
industryId: ID,
|
||||
name: '花间集',
|
||||
shortName: 'HJ',
|
||||
ownerUserId: ID2,
|
||||
});
|
||||
await updateCustomer(ID, { shortName: 'HJ2' });
|
||||
await setCustomerStatus(ID, { status: 'paused' });
|
||||
await transferCustomer(ID, { ownerUserId: ID2 });
|
||||
await setCustomerGroups(ID, { groupIds: [ID] });
|
||||
await applyIndustryPack(ID);
|
||||
expect(lastCall().url).toContain(`/customers/${ID}/apply-industry-pack`);
|
||||
});
|
||||
|
||||
it('客户组:列表 / 详情 / 新建 / 更新 / 成员 / 删除', async () => {
|
||||
vi.spyOn(globalThis, 'fetch')
|
||||
.mockResolvedValueOnce(jsonResponse({ items: [groupSummary], next_cursor: null }))
|
||||
.mockResolvedValueOnce(jsonResponse(groupDetail))
|
||||
.mockResolvedValueOnce(jsonResponse(groupDetail, 201))
|
||||
.mockResolvedValueOnce(jsonResponse(groupDetail))
|
||||
.mockResolvedValueOnce(jsonResponse(groupDetail))
|
||||
.mockResolvedValueOnce(jsonResponse(undefined, 204));
|
||||
|
||||
await fetchCustomerGroupList();
|
||||
await fetchCustomerGroupDetail(ID);
|
||||
await createCustomerGroup({ name: '电商核心组', description: '' });
|
||||
await updateCustomerGroup(ID, { description: '说明' });
|
||||
await updateCustomerGroupMembers(ID, { addCustomerIds: [ID2], removeCustomerIds: [] });
|
||||
await deleteCustomerGroup(ID);
|
||||
});
|
||||
|
||||
it('客户字段:审批队列 / 客户字段 / 申请 / 审批', async () => {
|
||||
vi.spyOn(globalThis, 'fetch')
|
||||
.mockResolvedValueOnce(jsonResponse({ items: [fieldListItem], next_cursor: null }))
|
||||
.mockResolvedValueOnce(jsonResponse([field]))
|
||||
.mockResolvedValueOnce(jsonResponse(field, 201))
|
||||
.mockResolvedValueOnce(jsonResponse(field));
|
||||
|
||||
await fetchCustomerFieldList({ status: 'pending', limit: 100 });
|
||||
await fetchCustomerFields(ID);
|
||||
await applyCustomerField(ID, {
|
||||
name: '活动编码',
|
||||
code: 'campaign_code',
|
||||
type: 'text',
|
||||
options: [],
|
||||
purpose: '检索',
|
||||
entersGeneration: true,
|
||||
});
|
||||
await approveCustomerField(ID, { decision: 'approve' });
|
||||
expect(lastCall().url).toContain(`/customer-fields/${ID}/approve`);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,277 @@
|
||||
import {
|
||||
type ApplyCustomerFieldInput,
|
||||
applyCustomerFieldInputSchema,
|
||||
type ApproveCustomerFieldInput,
|
||||
approveCustomerFieldInputSchema,
|
||||
type CreateCustomerGroupInput,
|
||||
createCustomerGroupInputSchema,
|
||||
type CreateCustomerInput,
|
||||
createCustomerInputSchema,
|
||||
type CreateIndustryInput,
|
||||
createIndustryInputSchema,
|
||||
type CustomerDetail,
|
||||
customerDetailSchema,
|
||||
type CustomerField,
|
||||
type CustomerFieldListItem,
|
||||
customerFieldListItemSchema,
|
||||
type CustomerFieldListQuery,
|
||||
customerFieldSchema,
|
||||
type CustomerGroupDetail,
|
||||
customerGroupDetailSchema,
|
||||
type CustomerGroupListQuery,
|
||||
type CustomerGroupSummary,
|
||||
customerGroupSummarySchema,
|
||||
type CustomerListQuery,
|
||||
type CustomerSummary,
|
||||
customerSummarySchema,
|
||||
type IndustryDetail,
|
||||
industryDetailSchema,
|
||||
type IndustryListQuery,
|
||||
type IndustryTreeItem,
|
||||
industryTreeItemSchema,
|
||||
listResponseSchema,
|
||||
type SetCustomerGroupsInput,
|
||||
setCustomerGroupsInputSchema,
|
||||
type SetCustomerStatusInput,
|
||||
setCustomerStatusInputSchema,
|
||||
type SetIndustryStatusInput,
|
||||
setIndustryStatusInputSchema,
|
||||
type TransferCustomerInput,
|
||||
transferCustomerInputSchema,
|
||||
type UpdateCustomerGroupInput,
|
||||
updateCustomerGroupInputSchema,
|
||||
type UpdateCustomerGroupMembersInput,
|
||||
updateCustomerGroupMembersInputSchema,
|
||||
type UpdateCustomerInput,
|
||||
updateCustomerInputSchema,
|
||||
type UpdateIndustryInput,
|
||||
updateIndustryInputSchema,
|
||||
} from '@lingxi/shared';
|
||||
|
||||
import { request } from './client';
|
||||
import { ENDPOINTS } from './endpoints';
|
||||
|
||||
const industryListResponseSchema = listResponseSchema(industryTreeItemSchema);
|
||||
const customerListResponseSchema = listResponseSchema(customerSummarySchema);
|
||||
const groupListResponseSchema = listResponseSchema(customerGroupSummarySchema);
|
||||
const fieldListResponseSchema = listResponseSchema(customerFieldListItemSchema);
|
||||
|
||||
function searchParams(entries: Record<string, string | number | undefined>): string {
|
||||
const params = new URLSearchParams();
|
||||
for (const [key, value] of Object.entries(entries)) {
|
||||
if (value !== undefined && value !== '') params.set(key, String(value));
|
||||
}
|
||||
const search = params.toString();
|
||||
return search === '' ? '' : `?${search}`;
|
||||
}
|
||||
|
||||
export async function fetchIndustryList(
|
||||
query: Partial<IndustryListQuery> = {},
|
||||
): Promise<{ items: IndustryTreeItem[]; next_cursor: string | null }> {
|
||||
const payload: unknown = await request(
|
||||
`${ENDPOINTS.industries}${searchParams({
|
||||
keyword: query.keyword,
|
||||
status: query.status,
|
||||
parent_id: query.parent_id,
|
||||
limit: query.limit,
|
||||
cursor: query.cursor,
|
||||
})}`,
|
||||
);
|
||||
return industryListResponseSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function fetchIndustryDetail(id: string): Promise<IndustryDetail> {
|
||||
const payload: unknown = await request(ENDPOINTS.industry(id));
|
||||
return industryDetailSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function createIndustry(input: CreateIndustryInput): Promise<IndustryDetail> {
|
||||
const body = createIndustryInputSchema.parse(input);
|
||||
const payload: unknown = await request(ENDPOINTS.industries, { method: 'POST', body });
|
||||
return industryDetailSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function updateIndustry(
|
||||
id: string,
|
||||
input: UpdateIndustryInput,
|
||||
): Promise<IndustryDetail> {
|
||||
const body = updateIndustryInputSchema.parse(input);
|
||||
const payload: unknown = await request(ENDPOINTS.industry(id), { method: 'PATCH', body });
|
||||
return industryDetailSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function setIndustryStatus(
|
||||
id: string,
|
||||
input: SetIndustryStatusInput,
|
||||
): Promise<IndustryDetail> {
|
||||
const body = setIndustryStatusInputSchema.parse(input);
|
||||
const payload: unknown = await request(ENDPOINTS.industryStatus(id), { method: 'PATCH', body });
|
||||
return industryDetailSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function deleteIndustry(id: string): Promise<void> {
|
||||
await request<unknown>(ENDPOINTS.industry(id), { method: 'DELETE' });
|
||||
}
|
||||
|
||||
export async function fetchCustomerList(
|
||||
query: Partial<CustomerListQuery> = {},
|
||||
): Promise<{ items: CustomerSummary[]; next_cursor: string | null }> {
|
||||
const payload: unknown = await request(
|
||||
`${ENDPOINTS.customers}${searchParams({
|
||||
keyword: query.keyword,
|
||||
industry_id: query.industry_id,
|
||||
status: query.status,
|
||||
owner_user_id: query.owner_user_id,
|
||||
group_id: query.group_id,
|
||||
limit: query.limit,
|
||||
cursor: query.cursor,
|
||||
})}`,
|
||||
);
|
||||
return customerListResponseSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function fetchCustomerDetail(id: string): Promise<CustomerDetail> {
|
||||
const payload: unknown = await request(ENDPOINTS.customer(id));
|
||||
return customerDetailSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function createCustomer(input: CreateCustomerInput): Promise<CustomerDetail> {
|
||||
const body = createCustomerInputSchema.parse(input);
|
||||
const payload: unknown = await request(ENDPOINTS.customers, { method: 'POST', body });
|
||||
return customerDetailSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function updateCustomer(
|
||||
id: string,
|
||||
input: UpdateCustomerInput,
|
||||
): Promise<CustomerDetail> {
|
||||
const body = updateCustomerInputSchema.parse(input);
|
||||
const payload: unknown = await request(ENDPOINTS.customer(id), { method: 'PATCH', body });
|
||||
return customerDetailSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function setCustomerStatus(
|
||||
id: string,
|
||||
input: SetCustomerStatusInput,
|
||||
): Promise<CustomerDetail> {
|
||||
const body = setCustomerStatusInputSchema.parse(input);
|
||||
const payload: unknown = await request(ENDPOINTS.customerStatus(id), { method: 'PATCH', body });
|
||||
return customerDetailSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function transferCustomer(
|
||||
id: string,
|
||||
input: TransferCustomerInput,
|
||||
): Promise<CustomerDetail> {
|
||||
const body = transferCustomerInputSchema.parse(input);
|
||||
const payload: unknown = await request(ENDPOINTS.customerTransfer(id), { method: 'POST', body });
|
||||
return customerDetailSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function setCustomerGroups(
|
||||
id: string,
|
||||
input: SetCustomerGroupsInput,
|
||||
): Promise<CustomerDetail> {
|
||||
const body = setCustomerGroupsInputSchema.parse(input);
|
||||
const payload: unknown = await request(ENDPOINTS.customerGroups(id), { method: 'PUT', body });
|
||||
return customerDetailSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function applyIndustryPack(id: string): Promise<void> {
|
||||
await request<unknown>(ENDPOINTS.customerApplyPack(id), { method: 'POST' });
|
||||
}
|
||||
|
||||
export async function fetchCustomerGroupList(
|
||||
query: Partial<CustomerGroupListQuery> = {},
|
||||
): Promise<{ items: CustomerGroupSummary[]; next_cursor: string | null }> {
|
||||
const payload: unknown = await request(
|
||||
`${ENDPOINTS.customerGroupsList}${searchParams({ keyword: query.keyword, limit: query.limit, cursor: query.cursor })}`,
|
||||
);
|
||||
return groupListResponseSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function fetchCustomerGroupDetail(id: string): Promise<CustomerGroupDetail> {
|
||||
const payload: unknown = await request(ENDPOINTS.customerGroup(id));
|
||||
return customerGroupDetailSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function createCustomerGroup(
|
||||
input: CreateCustomerGroupInput,
|
||||
): Promise<CustomerGroupDetail> {
|
||||
const body = createCustomerGroupInputSchema.parse(input);
|
||||
const payload: unknown = await request(ENDPOINTS.customerGroupsList, { method: 'POST', body });
|
||||
return customerGroupDetailSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function updateCustomerGroup(
|
||||
id: string,
|
||||
input: UpdateCustomerGroupInput,
|
||||
): Promise<CustomerGroupDetail> {
|
||||
const body = updateCustomerGroupInputSchema.parse(input);
|
||||
const payload: unknown = await request(ENDPOINTS.customerGroup(id), { method: 'PATCH', body });
|
||||
return customerGroupDetailSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function updateCustomerGroupMembers(
|
||||
id: string,
|
||||
input: UpdateCustomerGroupMembersInput,
|
||||
): Promise<CustomerGroupDetail> {
|
||||
const body = updateCustomerGroupMembersInputSchema.parse(input);
|
||||
const payload: unknown = await request(ENDPOINTS.customerGroupMembers(id), {
|
||||
method: 'POST',
|
||||
body,
|
||||
});
|
||||
return customerGroupDetailSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function deleteCustomerGroup(id: string): Promise<void> {
|
||||
await request<unknown>(ENDPOINTS.customerGroup(id), { method: 'DELETE' });
|
||||
}
|
||||
|
||||
export async function fetchCustomerFieldList(
|
||||
query: Partial<CustomerFieldListQuery> = {},
|
||||
): Promise<{ items: CustomerFieldListItem[]; next_cursor: string | null }> {
|
||||
const payload: unknown = await request(
|
||||
`${ENDPOINTS.customerFields}${searchParams({
|
||||
customer_id: query.customer_id,
|
||||
status: query.status,
|
||||
limit: query.limit,
|
||||
cursor: query.cursor,
|
||||
})}`,
|
||||
);
|
||||
return fieldListResponseSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function fetchCustomerFields(customerId: string): Promise<CustomerField[]> {
|
||||
const payload: unknown = await request(ENDPOINTS.customerFieldsOf(customerId));
|
||||
const schema = listResponseSchema(customerFieldSchema);
|
||||
// 后端该接口返回数组;列表信封仅用于 /customer-fields
|
||||
if (Array.isArray(payload)) {
|
||||
return payload.map((item) => customerFieldSchema.parse(item));
|
||||
}
|
||||
return schema.parse(payload).items;
|
||||
}
|
||||
|
||||
export async function applyCustomerField(
|
||||
customerId: string,
|
||||
input: ApplyCustomerFieldInput,
|
||||
): Promise<CustomerField> {
|
||||
const body = applyCustomerFieldInputSchema.parse(input);
|
||||
const payload: unknown = await request(ENDPOINTS.customerFieldsOf(customerId), {
|
||||
method: 'POST',
|
||||
body,
|
||||
});
|
||||
return customerFieldSchema.parse(payload);
|
||||
}
|
||||
|
||||
export async function approveCustomerField(
|
||||
id: string,
|
||||
input: ApproveCustomerFieldInput,
|
||||
): Promise<CustomerField> {
|
||||
const body = approveCustomerFieldInputSchema.parse(input);
|
||||
const payload: unknown = await request(ENDPOINTS.customerFieldApprove(id), {
|
||||
method: 'POST',
|
||||
body,
|
||||
});
|
||||
return customerFieldSchema.parse(payload);
|
||||
}
|
||||
@@ -28,4 +28,28 @@ export const ENDPOINTS = {
|
||||
roles: '/roles',
|
||||
role: (roleId: string): string => `/roles/${encodeURIComponent(roleId)}`,
|
||||
permissions: '/permissions',
|
||||
// A3 client
|
||||
industries: '/industries',
|
||||
industry: (industryId: string): string => `/industries/${encodeURIComponent(industryId)}`,
|
||||
industryStatus: (industryId: string): string =>
|
||||
`/industries/${encodeURIComponent(industryId)}/status`,
|
||||
customers: '/customers',
|
||||
customer: (customerId: string): string => `/customers/${encodeURIComponent(customerId)}`,
|
||||
customerStatus: (customerId: string): string =>
|
||||
`/customers/${encodeURIComponent(customerId)}/status`,
|
||||
customerTransfer: (customerId: string): string =>
|
||||
`/customers/${encodeURIComponent(customerId)}/transfer`,
|
||||
customerGroups: (customerId: string): string =>
|
||||
`/customers/${encodeURIComponent(customerId)}/groups`,
|
||||
customerApplyPack: (customerId: string): string =>
|
||||
`/customers/${encodeURIComponent(customerId)}/apply-industry-pack`,
|
||||
customerGroupsList: '/customer-groups',
|
||||
customerGroup: (groupId: string): string => `/customer-groups/${encodeURIComponent(groupId)}`,
|
||||
customerGroupMembers: (groupId: string): string =>
|
||||
`/customer-groups/${encodeURIComponent(groupId)}/members`,
|
||||
customerFields: '/customer-fields',
|
||||
customerFieldsOf: (customerId: string): string =>
|
||||
`/customers/${encodeURIComponent(customerId)}/fields`,
|
||||
customerFieldApprove: (fieldId: string): string =>
|
||||
`/customer-fields/${encodeURIComponent(fieldId)}/approve`,
|
||||
} as const;
|
||||
+706
-37
@@ -177,26 +177,6 @@ export interface paths {
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/users/{id}/transfer-customers': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/**
|
||||
* 客户转交(占位)
|
||||
* @description A3 客户模块落地前返回 42201
|
||||
*/
|
||||
post: operations['UsersController_transferCustomers'];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/departments/tree': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -366,6 +346,287 @@ export interface paths {
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/industries': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/** 两级行业树(一级 → 二级) */
|
||||
get: operations['IndustriesController_list'];
|
||||
put?: never;
|
||||
/** 新建一级 / 二级行业 */
|
||||
post: operations['IndustriesController_create'];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/industries/{id}': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/** 行业详情与引用(子行业 / 客户 / 资产) */
|
||||
get: operations['IndustriesController_detail'];
|
||||
put?: never;
|
||||
post?: never;
|
||||
/** 删除行业(仅无子行业 / 客户 / 资产时) */
|
||||
delete: operations['IndustriesController_remove'];
|
||||
options?: never;
|
||||
head?: never;
|
||||
/** 更新行业名称 / 排序 / 备注(层级与上级不可变) */
|
||||
patch: operations['IndustriesController_update'];
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/industries/{id}/status': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
/** 停用 / 启用行业(有启用子行业时禁止停用) */
|
||||
patch: operations['IndustriesController_setStatus'];
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/customers': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/** 客户列表(游标分页 + 行业 / 状态 / 负责人 / 客户组筛选) */
|
||||
get: operations['CustomersController_list'];
|
||||
put?: never;
|
||||
/** 新建客户(简称必填;行业必须为末级行业) */
|
||||
post: operations['CustomersController_create'];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/customers/{id}': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/** 客户详情(跨客户访问统一 404) */
|
||||
get: operations['CustomersController_detail'];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
/** 更新客户档案(所属行业不可改;暂停 / 结束只读) */
|
||||
patch: operations['CustomersController_update'];
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/customers/{id}/status': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
/** 客户状态:在服务 ⇄ 暂停 → 结束(结束不可逆) */
|
||||
patch: operations['CustomersController_setStatus'];
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/customers/{id}/transfer': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/** 变更客户负责人(写审计) */
|
||||
post: operations['CustomersController_transfer'];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/customers/{id}/groups': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
/** 设置客户所属客户组(覆盖式) */
|
||||
put: operations['CustomersController_setGroups'];
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/customers/{id}/apply-industry-pack': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/** 套用行业资产包(B0 批次提供;当前返回业务提示) */
|
||||
post: operations['CustomersController_applyIndustryPack'];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/users/{id}/transfer-customers': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/** 把用户名下客户转交给另一负责人 */
|
||||
post: operations['CustomerTransferController_transfer'];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/customer-groups': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/** 客户组列表(授权与数据范围最小单位) */
|
||||
get: operations['CustomerGroupsController_list'];
|
||||
put?: never;
|
||||
/** 新建客户组 */
|
||||
post: operations['CustomerGroupsController_create'];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/customer-groups/{id}': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/** 客户组详情与成员 */
|
||||
get: operations['CustomerGroupsController_detail'];
|
||||
put?: never;
|
||||
post?: never;
|
||||
/** 删除客户组(被角色数据范围引用时拒绝) */
|
||||
delete: operations['CustomerGroupsController_remove'];
|
||||
options?: never;
|
||||
head?: never;
|
||||
/** 更新客户组名称 / 说明 */
|
||||
patch: operations['CustomerGroupsController_update'];
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/customer-groups/{id}/members': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/** 批量添加 / 移除成员(幂等) */
|
||||
post: operations['CustomerGroupsController_updateMembers'];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/customer-fields': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/** 字段审批队列(待审批 / 已生效 / 已驳回) */
|
||||
get: operations['CustomerFieldsController_list'];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/customer-fields/{id}/approve': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/** 审批客户级字段(通过 / 驳回;驳回原因必填) */
|
||||
post: operations['CustomerFieldsController_approve'];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
'/api/v1/customers/{id}/fields': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/** 客户级字段列表(基础字段在 customers.custom_fields) */
|
||||
get: operations['CustomerFieldsOfCustomerController_list'];
|
||||
put?: never;
|
||||
/** 申请客户级字段(进入生成字段需审批;每客户 ≤ 5) */
|
||||
post: operations['CustomerFieldsOfCustomerController_apply'];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
'/health': {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -684,23 +945,6 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
UsersController_transferCustomers: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
DepartmentsController_tree: {
|
||||
parameters: {
|
||||
query?: {
|
||||
@@ -890,6 +1134,431 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
IndustriesController_list: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
IndustriesController_create: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
201: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
IndustriesController_detail: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
IndustriesController_remove: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
204: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
IndustriesController_update: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
IndustriesController_setStatus: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomersController_list: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomersController_create: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
201: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomersController_detail: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomersController_update: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomersController_setStatus: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomersController_transfer: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomersController_setGroups: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomersController_applyIndustryPack: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomerTransferController_transfer: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomerGroupsController_list: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomerGroupsController_create: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
201: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomerGroupsController_detail: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomerGroupsController_remove: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
204: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomerGroupsController_update: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomerGroupsController_updateMembers: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomerFieldsController_list: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomerFieldsController_approve: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomerFieldsOfCustomerController_list: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
CustomerFieldsOfCustomerController_apply: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
201: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
HealthController_check: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
|
||||
@@ -13,4 +13,17 @@ export const queryKeys = {
|
||||
roleList: (query: RoleListQueryInput) => ['roles', 'management', query] as const,
|
||||
role: (roleId: string) => ['roles', 'detail', roleId] as const,
|
||||
permissions: ['permissions'] as const,
|
||||
// A3 client
|
||||
industries: ['industries'] as const,
|
||||
industryList: (query: object) => ['industries', 'list', query] as const,
|
||||
industry: (industryId: string) => ['industries', 'detail', industryId] as const,
|
||||
customers: ['customers'] as const,
|
||||
customerList: (query: object) => ['customers', 'list', query] as const,
|
||||
customer: (customerId: string) => ['customers', 'detail', customerId] as const,
|
||||
customerFieldsOf: (customerId: string) => ['customers', 'fields', customerId] as const,
|
||||
customerGroups: ['customer-groups'] as const,
|
||||
customerGroupList: (query: object) => ['customer-groups', 'list', query] as const,
|
||||
customerGroup: (groupId: string) => ['customer-groups', 'detail', groupId] as const,
|
||||
customerFields: (query: object) => ['customer-fields', 'list', query] as const,
|
||||
customerFieldsRoot: ['customer-fields'] as const,
|
||||
};
|
||||
Reference in new issue
Block a user