diff --git a/client/src/api/customerEquipment.ts b/client/src/api/customerEquipment.ts new file mode 100644 index 0000000..b9d46a3 --- /dev/null +++ b/client/src/api/customerEquipment.ts @@ -0,0 +1,77 @@ +import request from '@/utils/request'; + +// 客户设备类型:配电间/配电井/配电箱/配电柜 +export const EQUIP_TYPE_OPTIONS = [ + { label: '配电间', value: '配电间' }, + { label: '配电井', value: '配电井' }, + { label: '配电箱', value: '配电箱' }, + { label: '配电柜', value: '配电柜' }, +]; + +export interface CustomerEquipmentNode { + id: number; + equipCode: string; + customerId: number; + equipName: string; + equipType?: string; + parentId?: number | null; + buildingId?: number | null; + floorNo?: string | null; + location?: string; + description?: string; + remark?: string; + photoUrl?: string; + createdAt?: string; + // 树形:子节点(tree 接口返回) + children?: CustomerEquipmentNode[]; +} + +export interface CustomerEquipmentCreateParams { + customerId: number; + equipName: string; + equipType: string; + parentId?: number | null; + buildingId?: number | null; + floorNo?: string | null; + location?: string; + description?: string; + remark?: string; + photoUrl?: string; +} + +export type CustomerEquipmentUpdateParams = Partial; + +export interface CustomerEquipmentQuery { + page?: number; + pageSize?: number; + keyword?: string; + customerId?: number; + equipType?: string; +} + +export interface CustomerEquipmentListResult { + list: CustomerEquipmentNode[]; + total: number; + page: number; + pageSize: number; +} + +export const customerEquipmentApi = { + // 客户设备树(按 parentId 嵌套,根节点 parentId 为空) + getTree: (customerId: number) => + request.get('/customer-equipments/tree', { params: { customerId } }), + + getList: (params: CustomerEquipmentQuery) => + request.get('/customer-equipments', { params }), + + getDetail: (id: number) => + request.get(`/customer-equipments/${id}`), + + create: (data: CustomerEquipmentCreateParams) => + request.post('/customer-equipments', data), + + update: (id: number, data: CustomerEquipmentUpdateParams) => + request.put(`/customer-equipments/${id}`, data), + + delete: (id: number) => request.delete(`/customer-equipments/${id}`) +}; diff --git a/client/src/api/device.ts b/client/src/api/device.ts index d8a1552..ef5b9f2 100644 --- a/client/src/api/device.ts +++ b/client/src/api/device.ts @@ -4,16 +4,16 @@ import request from '@/utils/request'; export interface CustomerEquipment { id: number; - equipmentNo: string; - equipmentName: string; + equipCode: string; + equipName: string; equipType?: string; customerId?: number; - customerName?: string; - building?: string; - floor?: string; + parentId?: number | null; + buildingId?: number | null; + buildingName?: string; + floorNo?: string; location?: string; - photo?: string; - status?: number; + photoUrl?: string; remark?: string; createdAt: string; updatedAt: string; @@ -24,7 +24,7 @@ export interface CustomerEquipmentQuery { pageSize?: number; keyword?: string; customerId?: number; - building?: string; + buildingId?: number; equipType?: string; } @@ -36,26 +36,26 @@ export interface CustomerEquipmentListResult { } export interface CustomerEquipmentCreateParams { - equipmentName: string; + equipName: string; equipType?: string; customerId?: number; - building?: string; - floor?: string; + parentId?: number | null; + buildingId?: number | null; + floorNo?: string; location?: string; - photo?: string; - status?: number; + photoUrl?: string; remark?: string; } export interface CustomerEquipmentUpdateParams { - equipmentName?: string; + equipName?: string; equipType?: string; customerId?: number; - building?: string; - floor?: string; + parentId?: number | null; + buildingId?: number | null; + floorNo?: string; location?: string; - photo?: string; - status?: number; + photoUrl?: string; remark?: string; } diff --git a/client/src/api/surveyOrder.ts b/client/src/api/surveyOrder.ts index b633d7d..53356c0 100644 --- a/client/src/api/surveyOrder.ts +++ b/client/src/api/surveyOrder.ts @@ -57,10 +57,12 @@ export interface SurveyOrderWorker { completedCount?: number; } -// 勘察明细:一条 = 建筑 + 楼层 + 房间(可空) + 现场照片 +// 勘察明细:一条 = 设备节点(优先)+ 现场照片;兼容历史 建筑/楼层/房间 export interface SurveyOrderDetail { id?: number; surveyOrderId?: number; + // 客户设备 ID(→ customer_equipment,勘察明细挂接到设备节点) + equipId?: number | null; buildingId?: number | null; // 建筑名称(冗余存储,客户拓扑变更后仍可读) buildingName?: string | null; @@ -75,6 +77,18 @@ export interface SurveyOrderDetail { remark?: string | null; } +// 客户设备树节点(工单详情附带,勘察明细按设备节点拓扑展示) +// 与 @/api/customerEquipment 的 CustomerEquipmentNode 对齐(equip_code/customer_id/equip_name 必填,equip_type 可空) +export interface SurveyEquipNode { + id: number; + equipCode: string; + customerId: number; + equipName: string; + equipType?: string; + parentId?: number | null; + children?: SurveyEquipNode[]; +} + export interface SurveyOrderInfo { id: number; surveyNo: string; @@ -124,8 +138,10 @@ export interface SurveyOrderInfo { updatedAt?: string; created_at?: string; updated_at?: string; - // 详情附带:勘察明细(建筑/楼层/房间 + 现场照片) + // 详情附带:勘察明细(设备节点/建筑楼层房间 + 现场照片) details?: SurveyOrderDetail[]; + // 详情附带:客户设备树(勘察明细按设备节点拓扑展示) + equipmentTree?: SurveyEquipNode[]; } export interface SurveyOrderQuery { @@ -260,6 +276,9 @@ export const surveyOrderApi = { review: (id: number, data: SurveyOrderReviewParams) => request.put(`/survey-orders/${id}/review`, data), + // 勘察完成:现场勘察中 → 待技术复核 + complete: (id: number) => request.put(`/survey-orders/${id}/complete`), + // 催办 urge: (id: number) => request.post(`/survey-orders/${id}/urge`), diff --git a/client/src/router/index.ts b/client/src/router/index.ts index a4a631a..f9712d4 100644 --- a/client/src/router/index.ts +++ b/client/src/router/index.ts @@ -79,6 +79,18 @@ const routes: RouteRecordRaw[] = [ parentPath: "/customer/visit" } }, + { + path: "customer/visit/survey/create", + name: "CustomerVisitSurveyCreate", + component: () => import("@/views/dispatch/survey/form.vue"), + meta: { + requiresAuth: true, + title: "发起勘察派单", + permission: "customer:visit", + parentTitle: "客户拜访", + parentPath: "/customer/visit" + } + }, { path: "customer/topology", name: "CustomerTopology", @@ -133,18 +145,6 @@ const routes: RouteRecordRaw[] = [ component: () => import("@/views/dispatch/survey/index.vue"), meta: { requiresAuth: true, title: "项目勘察", permission: "project:survey" } }, - { - path: "dispatch/survey/create", - name: "DispatchSurveyCreate", - component: () => import("@/views/dispatch/survey/form.vue"), - meta: { - requiresAuth: true, - title: "新建勘察派单", - permission: "project:survey", - parentTitle: "现场勘察派单", - parentPath: "/dispatch/survey" - } - }, { path: "dispatch/survey/edit/:id", name: "DispatchSurveyEdit", @@ -157,6 +157,18 @@ const routes: RouteRecordRaw[] = [ parentPath: "/dispatch/survey" } }, + { + path: "dispatch/survey/:id/details", + name: "DispatchSurveyDetail", + component: () => import("@/views/dispatch/survey/detail.vue"), + meta: { + requiresAuth: true, + title: "勘察明细", + permission: "project:survey", + parentTitle: "现场勘察派单", + parentPath: "/dispatch/survey" + } + }, { path: "dispatch/install", name: "DispatchInstall", diff --git a/client/src/views/customer/visit/index.vue b/client/src/views/customer/visit/index.vue index 96a4fe4..77bded1 100644 --- a/client/src/views/customer/visit/index.vue +++ b/client/src/views/customer/visit/index.vue @@ -795,10 +795,10 @@ function handleFollow(record: CustomerVisitInfo) { router.push({ name: 'CustomerVisitEdit', params: { id: record.id }, query: { action: 'follow' } }); } -// 一键发起勘察派单:跳转勘察派单页并预填客户(不创建、不回写状态) +// 一键发起勘察派单:跳转两步向导并预填客户(不创建、不回写状态) function handleSurvey(record: CustomerVisitInfo) { if (!record.customerId) return; - router.push({ path: '/dispatch/survey', query: { customerId: String(record.customerId) } }); + router.push({ name: 'CustomerVisitSurveyCreate', query: { customerId: String(record.customerId) } }); } // 查看关联工程 diff --git a/client/src/views/device/equipment/index.vue b/client/src/views/device/equipment/index.vue index d9972f5..fbe1f62 100644 --- a/client/src/views/device/equipment/index.vue +++ b/client/src/views/device/equipment/index.vue @@ -38,11 +38,11 @@
-
@@ -103,12 +103,12 @@ @change="handleTableChange" >