- 重构勘察业务:移除SOP相关表,新增勘察明细表支持建筑/楼层/房间/照片管理 - 新增定时任务人性化频率配置,支持分钟/小时/天/周/月/自定义六种模式 - 新增频率预览接口,支持配置转换为cron表达式与执行时间预览 - 更新系统品牌名称为鑫潼智电,修改全局标题与登录页文案
272 lines
6.7 KiB
TypeScript
272 lines
6.7 KiB
TypeScript
import request from '@/utils/request';
|
|
|
|
// 工单状态:0待指派 1现场勘察中 2待技术复核 3已归档 4预留 5已取消
|
|
export const SURVEY_STATUS = {
|
|
PENDING_ASSIGN: 0,
|
|
SURVEYING: 1,
|
|
PENDING_REVIEW: 2,
|
|
ARCHIVED: 3,
|
|
CANCELED: 5
|
|
};
|
|
|
|
export const SURVEY_STATUS_OPTIONS = [
|
|
{ value: 0, label: '待指派' },
|
|
{ value: 1, label: '现场勘察中' },
|
|
{ value: 2, label: '待技术复核' },
|
|
{ value: 3, label: '已归档' },
|
|
{ value: 5, label: '已取消' }
|
|
];
|
|
|
|
// 优先级:1特急P1 2加急P2 3常规P3
|
|
export const SURVEY_PRIORITY = {
|
|
URGENT: 1,
|
|
EXPEDITED: 2,
|
|
REGULAR: 3
|
|
};
|
|
|
|
export const SURVEY_PRIORITY_OPTIONS = [
|
|
{ value: 1, label: '特急 · P1' },
|
|
{ value: 2, label: '加急 · P2' },
|
|
{ value: 3, label: '常规 · P3' }
|
|
];
|
|
|
|
// 报酬规则(后端 dispatch_price 未配置时的前端兜底展示值)
|
|
export const SURVEY_BASE_FEE = 350;
|
|
export const SURVEY_LOOP_FEE = 5;
|
|
|
|
export interface SurveyOrderCustomer {
|
|
id: number;
|
|
customerNo?: string;
|
|
customerName?: string;
|
|
customerLevel?: string;
|
|
contactPerson?: string;
|
|
contactPhone?: string;
|
|
address?: string;
|
|
city?: string;
|
|
salesmanId?: number;
|
|
}
|
|
|
|
export interface SurveyOrderWorker {
|
|
id: number;
|
|
workerName?: string;
|
|
phone?: string;
|
|
workerTitle?: string;
|
|
rating?: number;
|
|
certInfo?: string;
|
|
certVerified?: boolean;
|
|
completedCount?: number;
|
|
}
|
|
|
|
// 勘察明细:一条 = 建筑 + 楼层 + 房间(可空) + 现场照片
|
|
export interface SurveyOrderDetail {
|
|
id?: number;
|
|
surveyOrderId?: number;
|
|
buildingId?: number | null;
|
|
// 建筑名称(冗余存储,客户拓扑变更后仍可读)
|
|
buildingName?: string | null;
|
|
// 楼层:正数为地上、负数为地下,如 '1' / '-1'
|
|
floorNo?: string | null;
|
|
roomId?: number | null;
|
|
roomName?: string | null;
|
|
// 现场照片对象 key
|
|
photos?: string[];
|
|
// 详情接口附带:照片预签名访问 URL(与 photos 顺序一致)
|
|
photoUrls?: string[];
|
|
remark?: string | null;
|
|
}
|
|
|
|
export interface SurveyOrderInfo {
|
|
id: number;
|
|
surveyNo: string;
|
|
customerId: number;
|
|
customerName?: string;
|
|
customer?: SurveyOrderCustomer;
|
|
surveyor?: string;
|
|
workerId?: number;
|
|
workerName?: string;
|
|
worker?: SurveyOrderWorker;
|
|
workerTitle?: string;
|
|
workerRating?: number;
|
|
workerCertInfo?: string;
|
|
surveyTime?: string;
|
|
priority?: number;
|
|
taskTitle?: string;
|
|
siteLocation?: string;
|
|
source?: string;
|
|
loopSpec?: string;
|
|
loopCount?: number;
|
|
progressDone?: number;
|
|
progressTotal?: number;
|
|
drawingCount?: number;
|
|
salesmanId?: number;
|
|
salesmanName?: string;
|
|
salesmanPhone?: string;
|
|
techContact?: string;
|
|
planStart?: string;
|
|
planEnd?: string;
|
|
expectMinutes?: number;
|
|
expectArrivalAt?: string;
|
|
slaLevel?: string;
|
|
urgeCount?: number;
|
|
lastUrgedAt?: string;
|
|
isDraft?: number;
|
|
estimatedFee?: number | string;
|
|
actualFee?: number | string;
|
|
photos?: string[];
|
|
// 详情附带:现场照片预签名访问 URL(与 photos 顺序一致)
|
|
photoUrls?: string[];
|
|
reviewRemark?: string;
|
|
reviewedAt?: string;
|
|
cancelReason?: string;
|
|
remark?: string;
|
|
status: number;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
created_at?: string;
|
|
updated_at?: string;
|
|
// 详情附带:勘察明细(建筑/楼层/房间 + 现场照片)
|
|
details?: SurveyOrderDetail[];
|
|
}
|
|
|
|
export interface SurveyOrderQuery {
|
|
page?: number;
|
|
pageSize?: number;
|
|
keyword?: string;
|
|
customerId?: number;
|
|
status?: number;
|
|
priority?: number;
|
|
workerId?: number;
|
|
salesmanId?: number;
|
|
planStartDate?: string;
|
|
planEndDate?: string;
|
|
includeDraft?: number;
|
|
}
|
|
|
|
export interface SurveyOrderListResult {
|
|
list: SurveyOrderInfo[];
|
|
total: number;
|
|
page: number;
|
|
pageSize: number;
|
|
}
|
|
|
|
export interface SurveyOrderStats {
|
|
total: number;
|
|
monthGrowth: number;
|
|
pendingAssign: number;
|
|
pendingWarn: number;
|
|
surveying: number;
|
|
onTimeRate: number;
|
|
pendingReview: number;
|
|
avgReviewHours: number;
|
|
archived: number;
|
|
planRate: number;
|
|
priorityCounts: {
|
|
urgent: number;
|
|
expedited: number;
|
|
regular: number;
|
|
};
|
|
}
|
|
|
|
export interface SurveyQuote {
|
|
baseFee: number;
|
|
loopFee: number;
|
|
loopCount: number;
|
|
total: number;
|
|
}
|
|
|
|
export interface SurveyOrderCreateParams {
|
|
customerId: number;
|
|
taskTitle?: string;
|
|
siteLocation?: string;
|
|
priority?: number;
|
|
loopSpec?: string;
|
|
loopCount?: number;
|
|
techContact?: string;
|
|
planStart?: string;
|
|
planEnd?: string;
|
|
expectMinutes?: number;
|
|
slaLevel?: string;
|
|
workerId?: number;
|
|
salesmanId?: number;
|
|
estimatedFee?: number;
|
|
remark?: string;
|
|
source?: string;
|
|
isDraft?: number;
|
|
// 勘察明细(创建/编辑时全量提交,新增/编辑/删除统一走此数组)
|
|
details?: SurveyOrderDetail[];
|
|
}
|
|
|
|
export type SurveyOrderUpdateParams = Partial<SurveyOrderCreateParams>;
|
|
|
|
export interface SurveyOrderAssignParams {
|
|
workerId: number;
|
|
estimatedFee?: number;
|
|
}
|
|
|
|
export interface SurveyOrderBatchAssignParams {
|
|
ids: number[];
|
|
workerId: number;
|
|
}
|
|
|
|
export interface SurveyOrderBatchAssignResult {
|
|
successCount: number;
|
|
failCount: number;
|
|
failIds: number[];
|
|
}
|
|
|
|
export interface SurveyOrderReviewParams {
|
|
// pass 复核通过归档 / reject 驳回退回现场勘察中
|
|
result: 'pass' | 'reject';
|
|
remark?: string;
|
|
}
|
|
|
|
export interface SurveyOrderCancelParams {
|
|
reason?: string;
|
|
}
|
|
|
|
export const surveyOrderApi = {
|
|
getList: (params: SurveyOrderQuery) =>
|
|
request.get<SurveyOrderListResult>('/survey-orders', { params }),
|
|
|
|
// KPI 统计卡
|
|
getStats: () => request.get<SurveyOrderStats>('/survey-orders/stats'),
|
|
|
|
// 报酬测算:基础出场工时费 + 回路数 × 单价
|
|
getQuote: (loopCount: number) =>
|
|
request.get<SurveyQuote>('/survey-orders/quote', { params: { loopCount } }),
|
|
|
|
getDetail: (id: number) =>
|
|
request.get<SurveyOrderInfo>(`/survey-orders/${id}`),
|
|
|
|
create: (data: SurveyOrderCreateParams) =>
|
|
request.post<SurveyOrderInfo>('/survey-orders', data),
|
|
|
|
update: (id: number, data: SurveyOrderUpdateParams) =>
|
|
request.put<SurveyOrderInfo>(`/survey-orders/${id}`, data),
|
|
|
|
// 勘察明细:全量替换(新增/编辑/删除统一提交完整数组)
|
|
saveDetails: (id: number, details: SurveyOrderDetail[]) =>
|
|
request.put<SurveyOrderDetail[]>(`/survey-orders/${id}/details`, { details }),
|
|
|
|
// 指派 / 改派共享电工
|
|
assign: (id: number, data: SurveyOrderAssignParams) =>
|
|
request.put<SurveyOrderInfo>(`/survey-orders/${id}/assign`, data),
|
|
|
|
// 批量指定电工
|
|
batchAssign: (data: SurveyOrderBatchAssignParams) =>
|
|
request.post<SurveyOrderBatchAssignResult>('/survey-orders/batch-assign', data),
|
|
|
|
// 技术复核:通过归档 / 驳回退回现场
|
|
review: (id: number, data: SurveyOrderReviewParams) =>
|
|
request.put<SurveyOrderInfo>(`/survey-orders/${id}/review`, data),
|
|
|
|
// 催办
|
|
urge: (id: number) => request.post<SurveyOrderInfo>(`/survey-orders/${id}/urge`),
|
|
|
|
// 取消工单
|
|
cancel: (id: number, data: SurveyOrderCancelParams) =>
|
|
request.put<SurveyOrderInfo>(`/survey-orders/${id}/cancel`, data),
|
|
|
|
delete: (id: number) => request.delete(`/survey-orders/${id}`)
|
|
};
|