From 712cbd5aafa39e95fb2929564ff9557ca7a63651 Mon Sep 17 00:00:00 2001 From: lzh Date: Sun, 25 Jan 2026 22:33:34 +0800 Subject: [PATCH] feat(ops): add cleaning work order management module --- apps/web-antd/src/api/ops/cleaning/index.ts | 128 ++ .../src/api/ops/order-center/index.ts | 190 ++ .../web-antd/src/router/routes/modules/ops.ts | 40 + .../cleaning/work-order/dashboard/index.vue | 1443 ++++++++++++ .../src/views/ops/cleaning/work-order/data.ts | 363 +++ .../ops/cleaning/work-order/detail/index.vue | 1961 +++++++++++++++++ .../views/ops/cleaning/work-order/index.vue | 823 +++++++ .../work-order/modules/assign-form.vue | 232 ++ .../work-order/modules/cancel-form.vue | 123 ++ .../cleaning/work-order/modules/card-view.vue | 726 ++++++ .../cleaning/work-order/modules/stats-bar.vue | 474 ++++ .../modules/upgrade-priority-form.vue | 136 ++ 12 files changed, 6639 insertions(+) create mode 100644 apps/web-antd/src/api/ops/cleaning/index.ts create mode 100644 apps/web-antd/src/api/ops/order-center/index.ts create mode 100644 apps/web-antd/src/router/routes/modules/ops.ts create mode 100644 apps/web-antd/src/views/ops/cleaning/work-order/dashboard/index.vue create mode 100644 apps/web-antd/src/views/ops/cleaning/work-order/data.ts create mode 100644 apps/web-antd/src/views/ops/cleaning/work-order/detail/index.vue create mode 100644 apps/web-antd/src/views/ops/cleaning/work-order/index.vue create mode 100644 apps/web-antd/src/views/ops/cleaning/work-order/modules/assign-form.vue create mode 100644 apps/web-antd/src/views/ops/cleaning/work-order/modules/cancel-form.vue create mode 100644 apps/web-antd/src/views/ops/cleaning/work-order/modules/card-view.vue create mode 100644 apps/web-antd/src/views/ops/cleaning/work-order/modules/stats-bar.vue create mode 100644 apps/web-antd/src/views/ops/cleaning/work-order/modules/upgrade-priority-form.vue diff --git a/apps/web-antd/src/api/ops/cleaning/index.ts b/apps/web-antd/src/api/ops/cleaning/index.ts new file mode 100644 index 000000000..472c2f947 --- /dev/null +++ b/apps/web-antd/src/api/ops/cleaning/index.ts @@ -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; // 额外信息(如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( + '/ops/clean/cleaner/list', + { params }, + ); +} + +/** 获取工单时间轴 */ +export function getOrderTimeline(orderId: number) { + return requestClient.get( + `/ops/clean/order/timeline/${orderId}`, + ); +} + +/** 获取保洁员工牌实时状态 */ +export function getBadgeRealtimeStatus(cleanerId: number) { + return requestClient.get( + `/ops/clean/badge/realtime/${cleanerId}`, + ); +} + +/** 手动完成工单(兜底操作) */ +export function manualCompleteOrder(orderId: number, remark?: string) { + return requestClient.post('/ops/clean/order/manual-complete', { + orderId, + remark, + }); +} diff --git a/apps/web-antd/src/api/ops/order-center/index.ts b/apps/web-antd/src/api/ops/order-center/index.ts new file mode 100644 index 000000000..a072275f5 --- /dev/null +++ b/apps/web-antd/src/api/ops/order-center/index.ts @@ -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>( + '/ops/order-center/page', + { params }, + ); +} + +/** 查询工单详情 */ +export function getOrderDetail(id: number) { + return requestClient.get( + `/ops/order-center/detail/${id}`, + ); +} + +/** 获取统计数据 */ +export function getOrderStats(groupBy?: 'status' | 'type') { + return requestClient.get( + '/ops/order-center/stats', + { params: { groupBy } }, + ); +} + +/** 获取快速统计数据(用于顶部统计栏) */ +export function getQuickStats() { + return requestClient.get( + '/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); +} diff --git a/apps/web-antd/src/router/routes/modules/ops.ts b/apps/web-antd/src/router/routes/modules/ops.ts new file mode 100644 index 000000000..335af62a4 --- /dev/null +++ b/apps/web-antd/src/router/routes/modules/ops.ts @@ -0,0 +1,40 @@ +import type { RouteRecordRaw } from 'vue-router'; + +const routes: RouteRecordRaw[] = [ + { + path: '/ops', + name: 'OpsCenter', + meta: { + title: '运维中心', + icon: 'lucide:wrench', + keepAlive: true, + hideInMenu: true, + }, + children: [ + // 保洁工单详情 + { + path: 'cleaning/work-order/detail/:id', + name: 'CleaningWorkOrderDetail', + meta: { + title: '工单详情', + activePath: '/ops/cleaning/work-order', + }, + component: () => + import('#/views/ops/cleaning/work-order/detail/index.vue'), + }, + // 保洁工单统计看板 + { + path: 'cleaning/work-order/dashboard', + name: 'CleaningWorkOrderDashboard', + meta: { + title: '统计看板', + activePath: '/ops/cleaning/work-order', + }, + component: () => + import('#/views/ops/cleaning/work-order/dashboard/index.vue'), + }, + ], + }, +]; + +export default routes; diff --git a/apps/web-antd/src/views/ops/cleaning/work-order/dashboard/index.vue b/apps/web-antd/src/views/ops/cleaning/work-order/dashboard/index.vue new file mode 100644 index 000000000..7ed61a43f --- /dev/null +++ b/apps/web-antd/src/views/ops/cleaning/work-order/dashboard/index.vue @@ -0,0 +1,1443 @@ + + + + + diff --git a/apps/web-antd/src/views/ops/cleaning/work-order/data.ts b/apps/web-antd/src/views/ops/cleaning/work-order/data.ts new file mode 100644 index 000000000..7af7d49ca --- /dev/null +++ b/apps/web-antd/src/views/ops/cleaning/work-order/data.ts @@ -0,0 +1,363 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { OpsOrderCenterApi } from '#/api/ops/order-center'; + +/** 状态颜色映射 */ +export const STATUS_COLOR_MAP: Record = { + PENDING: '#8c8c8c', // 灰色 - 待分配 + QUEUED: '#faad14', // 黄色 - 排队中 + DISPATCHED: '#1677ff', // 蓝色 - 已推送 + CONFIRMED: '#13c2c2', // 青色 - 已确认 + ARRIVED: '#52c41a', // 绿色 - 已到岗 + PAUSED: '#fa8c16', // 橙色 - 已暂停 + COMPLETED: '#389e0d', // 深绿 - 已完成 + CANCELLED: '#ff4d4f', // 红色 - 已取消 +}; + +/** 状态文本映射 */ +export const STATUS_TEXT_MAP: Record = { + PENDING: '待分配', + QUEUED: '排队中', + DISPATCHED: '已推送', + CONFIRMED: '已确认', + ARRIVED: '作业中', + PAUSED: '已暂停', + COMPLETED: '已完成', + CANCELLED: '已取消', +}; + +/** 状态图标映射 */ +export const STATUS_ICON_MAP: Record = { + PENDING: 'solar:inbox-line-bold-duotone', // 待分配 + QUEUED: 'solar:clock-circle-bold-duotone', // 排队中 + DISPATCHED: 'solar:transfer-horizontal-bold-duotone', // 已推送 + CONFIRMED: 'solar:check-circle-bold-duotone', // 已确认 + ARRIVED: 'solar:play-circle-bold-duotone', // 作业中 + PAUSED: 'solar:pause-circle-bold-duotone', // 已暂停 + COMPLETED: 'solar:check-read-bold-duotone', // 已完成 + CANCELLED: 'solar:close-circle-bold-duotone', // 已取消 +}; + +/** Tab 快捷筛选配置 */ +export const STATUS_TAB_OPTIONS = [ + { key: 'ALL', label: '全部', statuses: undefined }, + { key: 'PENDING', label: '待处理', statuses: ['PENDING'] }, + { + key: 'IN_PROGRESS', + label: '进行中', + statuses: ['DISPATCHED', 'CONFIRMED', 'ARRIVED', 'QUEUED'], + }, + { key: 'PAUSED', label: '已暂停', statuses: ['PAUSED'] }, + { key: 'COMPLETED', label: '已完成', statuses: ['COMPLETED'] }, + { key: 'CANCELLED', label: '已取消', statuses: ['CANCELLED'] }, +]; + +/** 优先级样式映射 */ +export const PRIORITY_STYLE_MAP: Record< + number, + { + animation: boolean; + bgColor: string; + color: string; + icon: string; + label: string; + } +> = { + 0: { + label: 'P0', + color: '#F44336', + bgColor: '#FFEBEE', + icon: 'lucide:zap', + animation: true, + }, + 1: { + label: 'P1', + color: '#FF9800', + bgColor: '#FFF3E0', + icon: 'lucide:alert-triangle', + animation: false, + }, + 2: { + label: 'P2', + color: '#9E9E9E', + bgColor: '#FAFAFA', + icon: '', + animation: false, + }, +}; + +/** 工单类型选项 */ +export const ORDER_TYPE_OPTIONS = [ + { label: '保洁', value: OpsOrderCenterApi.OrderType.CLEAN }, + { label: '维修', value: OpsOrderCenterApi.OrderType.REPAIR }, + { label: '安保', value: OpsOrderCenterApi.OrderType.SECURITY }, +]; + +/** 工单类型文本映射 */ +export const ORDER_TYPE_TEXT_MAP: Record = { + CLEAN: '保洁', + REPAIR: '维修', + SECURITY: '安保', +}; + +/** 工单类型颜色映射 */ +export const ORDER_TYPE_COLOR_MAP: Record = { + CLEAN: '#52c41a', // 绿色 + REPAIR: '#fa8c16', // 橙色 + SECURITY: '#1890ff', // 蓝色 +}; + +/** 工单状态选项 */ +export const ORDER_STATUS_OPTIONS = [ + { label: '待分配', value: OpsOrderCenterApi.OrderStatus.PENDING }, + { label: '排队中', value: OpsOrderCenterApi.OrderStatus.QUEUED }, + { label: '已推送', value: OpsOrderCenterApi.OrderStatus.DISPATCHED }, + { label: '已确认', value: OpsOrderCenterApi.OrderStatus.CONFIRMED }, + { label: '已到岗', value: OpsOrderCenterApi.OrderStatus.ARRIVED }, + { label: '已暂停', value: OpsOrderCenterApi.OrderStatus.PAUSED }, + { label: '已完成', value: OpsOrderCenterApi.OrderStatus.COMPLETED }, + { label: '已取消', value: OpsOrderCenterApi.OrderStatus.CANCELLED }, +]; + +/** 优先级选项 */ +export const PRIORITY_OPTIONS = [ + { label: 'P0 (紧急)', value: OpsOrderCenterApi.Priority.P0 }, + { label: 'P1 (重要)', value: OpsOrderCenterApi.Priority.P1 }, + { label: 'P2 (普通)', value: OpsOrderCenterApi.Priority.P2 }, +]; + +/** 触发来源选项 */ +export const TRIGGER_SOURCE_OPTIONS = [ + { label: '蓝牙信标', value: OpsOrderCenterApi.TriggerSource.IOT_BEACON }, + { label: '客流阈值', value: OpsOrderCenterApi.TriggerSource.PEOPLE_FLOW }, + { label: '手动创建', value: OpsOrderCenterApi.TriggerSource.MANUAL }, +]; + +/** 触发来源文本映射 */ +export const TRIGGER_SOURCE_TEXT_MAP: Record = { + IOT_BEACON: '蓝牙信标', + PEOPLE_FLOW: '客流阈值', + MANUAL: '手动创建', +}; + +/** 保洁类型选项 */ +export const CLEANING_TYPE_OPTIONS = [ + { label: '日常', value: OpsOrderCenterApi.CleaningType.ROUTINE }, + { label: '深度', value: OpsOrderCenterApi.CleaningType.DEEP }, + { label: '应急', value: OpsOrderCenterApi.CleaningType.EMERGENCY }, +]; + +/** 保洁类型文本映射 */ +export const CLEANING_TYPE_TEXT_MAP: Record = { + ROUTINE: '日常', + DEEP: '深度', + EMERGENCY: '应急', +}; + +/** 列表表格列定义 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'seq', width: 50, title: '序号' }, + { + field: 'orderCode', + title: '工单编号', + minWidth: 180, + showOverflow: true, + }, + { + field: 'title', + title: '工单标题', + minWidth: 180, + showOverflow: true, + }, + { + field: 'orderType', + title: '类型', + width: 80, + align: 'center', + slots: { default: 'orderType' }, + }, + { + field: 'status', + title: '状态', + width: 90, + align: 'center', + slots: { default: 'status' }, + }, + { + field: 'priority', + title: '优先级', + width: 80, + align: 'center', + slots: { default: 'priority' }, + }, + { + field: 'location', + title: '位置', + minWidth: 150, + showOverflow: true, + }, + { + field: 'assigneeName', + title: '执行人', + width: 90, + align: 'center', + slots: { default: 'assignee' }, + }, + { + field: 'createTime', + title: '创建时间', + width: 160, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 200, + fixed: 'right', + align: 'center', + slots: { default: 'actions' }, + }, + ]; +} + +/** 搜索表单Schema */ +export function useSearchFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'orderType', + label: '工单类型', + component: 'Select', + componentProps: { + options: ORDER_TYPE_OPTIONS, + placeholder: '请选择工单类型', + allowClear: true, + }, + }, + { + fieldName: 'status', + label: '工单状态', + component: 'Select', + componentProps: { + options: ORDER_STATUS_OPTIONS, + placeholder: '请选择工单状态', + mode: 'multiple', + allowClear: true, + maxTagCount: 2, + }, + }, + { + fieldName: 'priority', + label: '优先级', + component: 'Select', + componentProps: { + options: PRIORITY_OPTIONS, + placeholder: '请选择优先级', + allowClear: true, + }, + }, + { + fieldName: 'orderCode', + label: '工单编号', + component: 'Input', + componentProps: { + placeholder: '请输入工单编号', + allowClear: true, + }, + }, + { + fieldName: 'title', + label: '工单标题', + component: 'Input', + componentProps: { + placeholder: '请输入标题关键词', + allowClear: true, + }, + }, + ]; +} + +/** 派单表单Schema */ +export function useAssignFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'orderId', + label: '工单ID', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'assigneeId', + label: '执行人', + component: 'Select', + componentProps: { + placeholder: '请选择执行人', + // TODO: 接入保洁员列表API + options: [], + }, + rules: 'required', + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注(选填)', + rows: 3, + }, + }, + ]; +} + +/** 升级优先级表单Schema */ +export function useUpgradePriorityFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'orderId', + label: '工单ID', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'reason', + label: '升级原因', + component: 'Textarea', + componentProps: { + placeholder: '请输入升级为P0紧急工单的原因', + rows: 4, + }, + rules: 'required', + }, + ]; +} + +/** 状态干预表单Schema */ +export function useStatusInterventionFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'orderId', + label: '工单ID', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'reason', + label: '操作原因', + component: 'Textarea', + componentProps: { + placeholder: '请输入操作原因', + rows: 4, + }, + rules: 'required', + }, + ]; +} diff --git a/apps/web-antd/src/views/ops/cleaning/work-order/detail/index.vue b/apps/web-antd/src/views/ops/cleaning/work-order/detail/index.vue new file mode 100644 index 000000000..2e3aa88cc --- /dev/null +++ b/apps/web-antd/src/views/ops/cleaning/work-order/detail/index.vue @@ -0,0 +1,1961 @@ + + + + + diff --git a/apps/web-antd/src/views/ops/cleaning/work-order/index.vue b/apps/web-antd/src/views/ops/cleaning/work-order/index.vue new file mode 100644 index 000000000..a8549162b --- /dev/null +++ b/apps/web-antd/src/views/ops/cleaning/work-order/index.vue @@ -0,0 +1,823 @@ + + + + + diff --git a/apps/web-antd/src/views/ops/cleaning/work-order/modules/assign-form.vue b/apps/web-antd/src/views/ops/cleaning/work-order/modules/assign-form.vue new file mode 100644 index 000000000..56008c481 --- /dev/null +++ b/apps/web-antd/src/views/ops/cleaning/work-order/modules/assign-form.vue @@ -0,0 +1,232 @@ + + + + + diff --git a/apps/web-antd/src/views/ops/cleaning/work-order/modules/cancel-form.vue b/apps/web-antd/src/views/ops/cleaning/work-order/modules/cancel-form.vue new file mode 100644 index 000000000..a62b95fe9 --- /dev/null +++ b/apps/web-antd/src/views/ops/cleaning/work-order/modules/cancel-form.vue @@ -0,0 +1,123 @@ + + + + + diff --git a/apps/web-antd/src/views/ops/cleaning/work-order/modules/card-view.vue b/apps/web-antd/src/views/ops/cleaning/work-order/modules/card-view.vue new file mode 100644 index 000000000..aed8495bc --- /dev/null +++ b/apps/web-antd/src/views/ops/cleaning/work-order/modules/card-view.vue @@ -0,0 +1,726 @@ + + + + + diff --git a/apps/web-antd/src/views/ops/cleaning/work-order/modules/stats-bar.vue b/apps/web-antd/src/views/ops/cleaning/work-order/modules/stats-bar.vue new file mode 100644 index 000000000..db6837714 --- /dev/null +++ b/apps/web-antd/src/views/ops/cleaning/work-order/modules/stats-bar.vue @@ -0,0 +1,474 @@ + + + + + diff --git a/apps/web-antd/src/views/ops/cleaning/work-order/modules/upgrade-priority-form.vue b/apps/web-antd/src/views/ops/cleaning/work-order/modules/upgrade-priority-form.vue new file mode 100644 index 000000000..5f2813780 --- /dev/null +++ b/apps/web-antd/src/views/ops/cleaning/work-order/modules/upgrade-priority-form.vue @@ -0,0 +1,136 @@ + + + + +