feat(ops): add cleaning work order management module

This commit is contained in:
lzh
2026-01-25 22:33:34 +08:00
parent dac4e33cc6
commit 712cbd5aaf
12 changed files with 6639 additions and 0 deletions

View File

@@ -0,0 +1,128 @@
import { requestClient } from '#/api/request';
export namespace OpsCleaningApi {
/** 保洁员状态枚举 */
export enum CleanerStatus {
BUSY = 'BUSY', // 忙碌
IDLE = 'IDLE', // 空闲
OFFLINE = 'OFFLINE', // 离线
PAUSED = 'PAUSED', // 暂停中
}
/** 通知类型枚举 */
export enum NotifyType {
VIBRATE = 'VIBRATE', // 震动
VOICE = 'VOICE', // 语音
}
/** 升级优先级请求 */
export interface UpgradePriorityReq {
orderId: number; // 工单ID
reason: string; // 升级原因
}
/** 工牌通知请求 */
export interface DeviceNotifyReq {
cleanerId: number; // 保洁员ID
type: NotifyType; // 通知类型
content?: string; // 语音内容(仅语音通知需要)
}
/** 保洁员状态信息 */
export interface CleanerStatusItem {
userId: number; // 用户ID
userName: string; // 用户名称
avatar?: string; // 头像
status: CleanerStatus; // 状态
currentAreaId?: number; // 当前区域ID
currentAreaName?: string; // 当前区域名称
batteryLevel: number; // 电量0-100
lastHeartbeatTime: string; // 最后心跳时间
todayCompletedCount?: number; // 今日完成工单数
todayWorkMinutes?: number; // 今日工作时长(分钟)
}
/** 保洁员状态列表查询参数 */
export interface CleanerListQuery {
areaId?: number; // 区域ID可选
status?: CleanerStatus; // 状态筛选(可选)
}
/** 保洁员状态列表响应 */
export interface CleanerListResp {
list: CleanerStatusItem[];
}
/** 工单时间轴节点 */
export interface TimelineItem {
status: string; // 状态
statusName: string; // 状态名称
time: string; // 时间
operator?: string; // 操作人
description?: string; // 描述
extra?: Record<string, any>; // 额外信息如RSSI值、信标ID等
}
/** 工单时间轴响应 */
export interface OrderTimelineResp {
orderId: number;
currentStatus: string;
timeline: TimelineItem[];
}
/** 保洁员工牌实时状态 */
export interface BadgeRealtimeStatus {
cleanerId: number; // 保洁员ID
deviceId: number; // 设备ID
deviceKey: string; // 设备Key
status: CleanerStatus; // 设备状态
batteryLevel: number; // 电量
lastHeartbeatTime: string; // 最后心跳时间
rssi?: number; // 信号强度
isInArea: boolean; // 是否在区域内
areaId?: number; // 当前区域ID
areaName?: string; // 当前区域名称
}
}
// ==================== 保洁专属接口 ====================
/** 升级工单优先级 (P0 插队) */
export function upgradePriority(data: OpsCleaningApi.UpgradePriorityReq) {
return requestClient.post('/ops/clean/order/upgrade-priority', data);
}
/** 发送工牌通知 (语音/震动) */
export function sendDeviceNotify(data: OpsCleaningApi.DeviceNotifyReq) {
return requestClient.post('/ops/clean/device/notify', data);
}
/** 查询保洁员实时状态列表 */
export function getCleanerStatusList(params?: OpsCleaningApi.CleanerListQuery) {
return requestClient.get<OpsCleaningApi.CleanerListResp>(
'/ops/clean/cleaner/list',
{ params },
);
}
/** 获取工单时间轴 */
export function getOrderTimeline(orderId: number) {
return requestClient.get<OpsCleaningApi.OrderTimelineResp>(
`/ops/clean/order/timeline/${orderId}`,
);
}
/** 获取保洁员工牌实时状态 */
export function getBadgeRealtimeStatus(cleanerId: number) {
return requestClient.get<OpsCleaningApi.BadgeRealtimeStatus>(
`/ops/clean/badge/realtime/${cleanerId}`,
);
}
/** 手动完成工单(兜底操作) */
export function manualCompleteOrder(orderId: number, remark?: string) {
return requestClient.post('/ops/clean/order/manual-complete', {
orderId,
remark,
});
}

View File

@@ -0,0 +1,190 @@
import type { PageParam, PageResult } from '@vben/request';
import { requestClient } from '#/api/request';
export namespace OpsOrderCenterApi {
/** 工单类型枚举 */
export enum OrderType {
CLEAN = 'CLEAN', // 保洁
REPAIR = 'REPAIR', // 维修
SECURITY = 'SECURITY', // 安保
}
/** 工单状态枚举 */
export enum OrderStatus {
ARRIVED = 'ARRIVED', // 已到岗
CANCELLED = 'CANCELLED', // 已取消
COMPLETED = 'COMPLETED', // 已完成
CONFIRMED = 'CONFIRMED', // 已确认
DISPATCHED = 'DISPATCHED', // 已推送
PAUSED = 'PAUSED', // 已暂停
PENDING = 'PENDING', // 待分配
QUEUED = 'QUEUED', // 排队中
}
/** 保洁类型枚举 */
export enum CleaningType {
DEEP = 'DEEP', // 深度
EMERGENCY = 'EMERGENCY', // 应急
ROUTINE = 'ROUTINE', // 日常
}
/** 优先级枚举 (0=P0紧急, 1=P1重要, 2=P2普通) */
export enum Priority {
P0 = 0, // 紧急
P1 = 1, // 重要
P2 = 2, // 普通
}
/** 触发来源枚举 */
export enum TriggerSource {
IOT_BEACON = 'IOT_BEACON', // 蓝牙信标
MANUAL = 'MANUAL', // 手动创建
PEOPLE_FLOW = 'PEOPLE_FLOW', // 客流阈值
}
/** 工单查询参数 */
export interface OrderPageQuery extends PageParam {
orderType?: OrderType; // 工单类型
status?: OrderStatus | OrderStatus[]; // 工单状态(支持多选)
priority?: Priority; // 优先级
areaId?: number; // 区域ID
assigneeId?: number; // 执行人ID
orderCode?: string; // 工单编号(模糊搜索)
title?: string; // 标题(模糊搜索)
createTime?: string[]; // 创建时间范围
}
/** 保洁扩展信息 */
export interface CleaningExtInfo {
cleaningType?: CleaningType; // 作业类型
expectedDuration?: number; // 预计时长(分钟)
arrivedTime?: string; // 到岗时间
totalPauseSeconds?: number; // 暂停总秒数
difficultyLevel?: number; // 难度等级
isAuto?: number; // 是否自动创建 (1=自动, 0=手动)
}
/** 工单列表项 */
export interface OrderItem {
id: number;
orderCode: string; // 工单编号
title: string; // 工单标题
orderType: OrderType; // 工单类型
status: OrderStatus; // 工单状态
priority: Priority; // 优先级
areaId?: number; // 区域ID
location?: string; // 位置描述
assigneeId?: number; // 执行人ID
assigneeName?: string; // 执行人姓名
createTime: string; // 创建时间
extInfo?: CleaningExtInfo; // 保洁扩展信息
}
/** 工单详情 */
export interface OrderDetail extends OrderItem {
description?: string; // 工单描述
triggerSource?: TriggerSource; // 触发来源
triggerDeviceId?: number; // 触发设备ID
triggerDeviceKey?: string; // 触发设备Key
triggerRule?: string; // 触发规则
startTime?: string; // 开始时间(到岗时间)
endTime?: string; // 结束时间
remark?: string; // 备注
}
/** 统计数据 - 按类型和状态分组 */
export interface OrderStats {
[orderType: string]: {
[status: string]: number;
};
}
/** 快速统计数据 */
export interface QuickStats {
pendingCount: number; // 待分配数量
inProgressCount: number; // 进行中数量
completedTodayCount: number; // 今日完成数量
onlineCleanerCount: number; // 在线保洁员数量
}
/** 分配工单请求 */
export interface AssignOrderReq {
orderId: number; // 工单ID
assigneeId: number; // 执行人ID
remark?: string; // 备注
}
/** 暂停工单请求 */
export interface PauseOrderReq {
orderId: number; // 工单ID
userId: number; // 操作人ID
reason: string; // 暂停原因
}
/** 恢复工单请求 */
export interface ResumeOrderReq {
orderId: number; // 工单ID
userId: number; // 操作人ID
}
/** 取消工单请求 */
export interface CancelOrderReq {
id: number; // 工单ID
reason: string; // 取消原因
}
}
// ==================== 工单查询接口 ====================
/** 分页查询工单 */
export function getOrderPage(params: OpsOrderCenterApi.OrderPageQuery) {
return requestClient.get<PageResult<OpsOrderCenterApi.OrderItem>>(
'/ops/order-center/page',
{ params },
);
}
/** 查询工单详情 */
export function getOrderDetail(id: number) {
return requestClient.get<OpsOrderCenterApi.OrderDetail>(
`/ops/order-center/detail/${id}`,
);
}
/** 获取统计数据 */
export function getOrderStats(groupBy?: 'status' | 'type') {
return requestClient.get<OpsOrderCenterApi.OrderStats>(
'/ops/order-center/stats',
{ params: { groupBy } },
);
}
/** 获取快速统计数据(用于顶部统计栏) */
export function getQuickStats() {
return requestClient.get<OpsOrderCenterApi.QuickStats>(
'/ops/order-center/quick-stats',
);
}
// ==================== 工单操作接口 ====================
/** 重新分配/派单 */
export function assignOrder(data: OpsOrderCenterApi.AssignOrderReq) {
return requestClient.post('/ops/order/assign', data);
}
/** 暂停工单 */
export function pauseOrder(data: OpsOrderCenterApi.PauseOrderReq) {
return requestClient.post('/ops/order/pause', data);
}
/** 恢复工单 */
export function resumeOrder(data: OpsOrderCenterApi.ResumeOrderReq) {
return requestClient.post('/ops/order/resume', data);
}
/** 取消工单 */
export function cancelOrder(data: OpsOrderCenterApi.CancelOrderReq) {
return requestClient.post('/ops/order/cancel', data);
}