编辑 | blame | 历史 | 原始文档

通用任务管理功能说明

功能概述

根据需求文档,已完成通用任务和转运任务的后台管理功能开发,包括:

  1. 通用任务管理 - 支持维修保养、加油任务、其他任务类型
  2. 完整的CRUD操作 - 创建、查询、更新、删除、分配、状态管理
  3. 权限控制 - 基于角色的操作权限控制
  4. 数据隔离 - 基于机构的数据权限隔离

技术架构

后端架构 (ruoyi-task模块)

  • 采用DDD架构设计,分层明确
  • 领域层: 任务聚合根、值对象、领域服务
  • 应用层: CQRS命令查询分离、应用服务
  • 基础设施层: 持久化、消息推送
  • 接口层: REST API控制器

前端架构 (ruoyi-ui模块)

  • 页面组件: 任务列表、任务详情、任务创建
  • API服务: 统一的API接口调用
  • 路由配置: 动态路由和权限控制

核心功能

1. 任务类型管理

通用任务类型

  • 维修保养 (MAINTENANCE) - 车辆维修保养任务
  • 加油任务 (FUEL) - 车辆加油任务
  • 其他 (OTHER) - 其他类型任务

2. 任务状态管理

任务状态定义

  • 待开始 (PENDING) - 任务已创建,等待开始
  • 任务中 (IN_PROGRESS) - 任务已经开始
  • 已完成 (COMPLETED) - 任务已完成
  • 已取消 (CANCELLED) - 任务已取消

任务状态流转规则

任务状态流转规则
  • PENDINGIN_PROGRESSCOMPLETED
  • 任何状态都可以流转到 CANCELLED(除了 COMPLETED
状态流转约束
  1. 任务状态流转必须符合业务逻辑顺序
  2. 支持状态回退(如从 IN_PROGRESS 回到 PENDING)
  3. 任务取消后不能再次激活

3. 任务字段设计

通用字段

  • 任务编号、任务创建人,任务归属机构
  • 任务类型、任务状态
  • 任务目的地址、任务出发地址
  • 计划开始时间、计划结束时间
  • 实际开始时间、实际结束时间
  • 任务备注、附件列表

数据库设计

1. 核心表结构

1.1 任务主表 (sys_task)

CREATE TABLE sys_task (
    task_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '任务ID',
    task_code VARCHAR(50) NOT NULL UNIQUE COMMENT '任务编号',
    task_type VARCHAR(20) NOT NULL COMMENT '任务类型:MAINTENANCE-维修保养,FUEL-加油任务,OTHER-其他',
    task_status VARCHAR(20) NOT NULL DEFAULT 'PENDING' COMMENT '任务状态:PENDING-待开始,IN_PROGRESS-任务中,COMPLETED-已完成,CANCELLED-已取消',    
    task_description varchar(1000) COMMENT '任务描述',
    
    -- 地址信息
    departure_address VARCHAR(500) COMMENT '出发地址',
    destination_address VARCHAR(500) COMMENT '目的地址',
    
    -- 时间信息
    planned_start_time DATETIME COMMENT '计划开始时间',
    planned_end_time DATETIME COMMENT '计划结束时间',
    actual_start_time DATETIME COMMENT '实际开始时间',
    actual_end_time DATETIME COMMENT '实际结束时间',
    
    -- 人员信息
    creator_id BIGINT NOT NULL COMMENT '创建人ID',
    assignee_id BIGINT COMMENT '执行人ID',
    dept_id BIGINT NOT NULL COMMENT '归属部门ID',
    
    -- 系统字段
    create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    create_by VARCHAR(64) NOT NULL COMMENT '创建者',
    update_by VARCHAR(64) COMMENT '更新者',
    remark VARCHAR(500) COMMENT '备注',
    del_flag CHAR(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
    
    INDEX idx_task_code (task_code),
    INDEX idx_task_type (task_type),
    INDEX idx_task_status (task_status),
    INDEX idx_creator_id (creator_id),
    INDEX idx_assignee_id (assignee_id),
    INDEX idx_dept_id (dept_id),
    INDEX idx_planned_start_time (planned_start_time),
    INDEX idx_create_time (create_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='任务管理表';

1.2 车辆信息表 (tb_vehicle_info)

-- 基于现有车辆表结构,添加机构关联字段
CREATE TABLE tb_vehicle_info (
    vehicle_id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '车辆ID',
    platform_code VARCHAR(50) NOT NULL COMMENT '平台标识(A/B)',
    vehicle_no VARCHAR(50) NOT NULL COMMENT '车牌号',
    vehicle_type VARCHAR(50) NOT NULL COMMENT '车辆类型:AMBULANCE-救护车,TRANSFER-转运车,MAINTENANCE-维修车',
    vehicle_brand VARCHAR(50) COMMENT '车辆品牌',
    vehicle_model VARCHAR(50) COMMENT '车辆型号',
    vehicle_color VARCHAR(20) COMMENT '车辆颜色',
    vehicle_status CHAR(1) DEFAULT '0' COMMENT '车辆状态(0正常 1停用)',
    device_id VARCHAR(50) DEFAULT NULL COMMENT '设备ID',
    
    -- 机构关联(新增字段)
    dept_id BIGINT(20) DEFAULT NULL COMMENT '归属机构ID',
    
    -- 系统字段
    create_by VARCHAR(64) DEFAULT '' COMMENT '创建者',
    create_time DATETIME COMMENT '创建时间',
    update_by VARCHAR(64) DEFAULT '' COMMENT '更新者',
    update_time DATETIME COMMENT '更新时间',
    remark VARCHAR(500) DEFAULT NULL COMMENT '备注',
    
    PRIMARY KEY (vehicle_id),
    INDEX idx_vehicle_no (vehicle_no),
    INDEX idx_vehicle_type (vehicle_type),
    INDEX idx_vehicle_status (vehicle_status),
    INDEX idx_dept_id (dept_id),
    INDEX idx_platform_code (platform_code),
    
    FOREIGN KEY (dept_id) REFERENCES sys_dept(dept_id) ON DELETE SET NULL
) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COMMENT='车辆信息表';

1.3 任务车辆关联表 (sys_task_vehicle)

CREATE TABLE sys_task_vehicle (
    id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '关联ID',
    task_id BIGINT NOT NULL COMMENT '任务ID',
    vehicle_id BIGINT NOT NULL COMMENT '车辆ID',
    assign_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '分配时间',
    assign_by VARCHAR(64) NOT NULL COMMENT '分配人',
    status VARCHAR(20) DEFAULT 'ASSIGNED' COMMENT '关联状态:ASSIGNED-已分配,ACTIVE-执行中,COMPLETED-已完成,CANCELLED-已取消',
    remark VARCHAR(500) COMMENT '备注',
    
    INDEX idx_task_id (task_id),
    INDEX idx_vehicle_id (vehicle_id),
    INDEX idx_status (status),
    INDEX idx_assign_time (assign_time),
    
    UNIQUE KEY uk_task_vehicle (task_id, vehicle_id),
    FOREIGN KEY (task_id) REFERENCES sys_task(task_id) ON DELETE CASCADE,
    FOREIGN KEY (vehicle_id) REFERENCES tb_vehicle_info(vehicle_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='任务车辆关联表';

1.4 任务附件表 (sys_task_attachment)

CREATE TABLE sys_task_attachment (
    attachment_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '附件ID',
    task_id BIGINT NOT NULL COMMENT '任务ID',
    file_name VARCHAR(255) NOT NULL COMMENT '文件名',
    file_path VARCHAR(500) NOT NULL COMMENT '文件路径',
    file_size BIGINT COMMENT '文件大小(字节)',
    file_type VARCHAR(50) COMMENT '文件类型',
    upload_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '上传时间',
    upload_by VARCHAR(64) NOT NULL COMMENT '上传者',
    
    INDEX idx_task_id (task_id),
    FOREIGN KEY (task_id) REFERENCES sys_task(task_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='任务附件表';

1.3 任务操作日志表 (sys_task_log)

CREATE TABLE sys_task_log (
    log_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '日志ID',
    task_id BIGINT NOT NULL COMMENT '任务ID',
    operation_type VARCHAR(20) NOT NULL COMMENT '操作类型:CREATE-创建,UPDATE-更新,ASSIGN-分配,STATUS_CHANGE-状态变更,DELETE-删除',
    operation_desc VARCHAR(500) COMMENT '操作描述',
    old_value TEXT COMMENT '操作前值',
    new_value TEXT COMMENT '操作后值',
    operator_id BIGINT NOT NULL COMMENT '操作人ID',
    operator_name VARCHAR(64) NOT NULL COMMENT '操作人姓名',
    operation_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '操作时间',
    ip_address VARCHAR(128) COMMENT 'IP地址',
    
    INDEX idx_task_id (task_id),
    INDEX idx_operation_type (operation_type),
    INDEX idx_operator_id (operator_id),
    INDEX idx_operation_time (operation_time),
    FOREIGN KEY (task_id) REFERENCES sys_task(task_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='任务操作日志表';

2. 数据字典设计

2.1 任务类型字典

INSERT INTO sys_dict_type VALUES ('sys_task_type', '任务类型', '0', 'admin', sysdate(), '', null, '任务类型列表');
INSERT INTO sys_dict_data VALUES (1, 1, '维修保养', 'MAINTENANCE', 'sys_task_type', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '维修保养任务');
INSERT INTO sys_dict_data VALUES (2, 2, '加油任务', 'FUEL', 'sys_task_type', '', 'success', 'N', '0', 'admin', sysdate(), '', null, '加油任务');
INSERT INTO sys_dict_data VALUES (3, 3, '其他', 'OTHER', 'sys_task_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '其他类型任务');

2.2 任务状态字典

INSERT INTO sys_dict_type VALUES ('sys_task_status', '任务状态', '0', 'admin', sysdate(), '', null, '任务状态列表');
INSERT INTO sys_dict_data VALUES (4, 1, '待开始', 'PENDING', 'sys_task_status', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '任务已创建,等待开始');
INSERT INTO sys_dict_data VALUES (5, 2, '任务中', 'IN_PROGRESS', 'sys_task_status', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '任务已经开始');
INSERT INTO sys_dict_data VALUES (6, 3, '已完成', 'COMPLETED', 'sys_task_status', '', 'success', 'N', '0', 'admin', sysdate(), '', null, '任务已完成');
INSERT INTO sys_dict_data VALUES (7, 4, '已取消', 'CANCELLED', 'sys_task_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '任务已取消');

2.3 车辆类型字典

INSERT INTO sys_dict_type VALUES ('sys_vehicle_type', '车辆类型', '0', 'admin', sysdate(), '', null, '车辆类型列表');
INSERT INTO sys_dict_data VALUES (8, 1, '救护车', 'AMBULANCE', 'sys_vehicle_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '救护车');
INSERT INTO sys_dict_data VALUES (9, 2, '转运车', 'TRANSFER', 'sys_vehicle_type', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '转运车');
INSERT INTO sys_dict_data VALUES (10, 3, '维修车', 'MAINTENANCE', 'sys_vehicle_type', '', 'warning', 'N', '0', 'admin', sysdate(), '', null, '维修车');

2.4 车辆状态字典

INSERT INTO sys_dict_type VALUES ('sys_vehicle_status', '车辆状态', '0', 'admin', sysdate(), '', null, '车辆状态列表');
INSERT INTO sys_dict_data VALUES (11, 1, '正常', '0', 'sys_vehicle_status', '', 'success', 'N', '0', 'admin', sysdate(), '', null, '车辆正常使用');
INSERT INTO sys_dict_data VALUES (12, 2, '停用', '1', 'sys_vehicle_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '车辆停用');

2.5 任务车辆关联状态字典

INSERT INTO sys_dict_type VALUES ('sys_task_vehicle_status', '任务车辆关联状态', '0', 'admin', sysdate(), '', null, '任务车辆关联状态列表');
INSERT INTO sys_dict_data VALUES (15, 1, '已分配', 'ASSIGNED', 'sys_task_vehicle_status', '', 'primary', 'N', '0', 'admin', sysdate(), '', null, '车辆已分配给任务');
INSERT INTO sys_dict_data VALUES (16, 2, '执行中', 'ACTIVE', 'sys_task_vehicle_status', '', 'success', 'N', '0', 'admin', sysdate(), '', null, '车辆正在执行任务');
INSERT INTO sys_dict_data VALUES (17, 3, '已完成', 'COMPLETED', 'sys_task_vehicle_status', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '车辆任务已完成');
INSERT INTO sys_dict_data VALUES (18, 4, '已取消', 'CANCELLED', 'sys_task_vehicle_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '车辆任务已取消');

接口设计

1. REST API 规范

1.1 任务管理接口

1.1.1 创建任务
POST /api/task
Content-Type: application/json

Request Body:
{
    "taskType": "MAINTENANCE",
    "taskTitle": "车辆维修保养",
    "taskDescription": "定期保养检查",
    "departureAddress": "北京市朝阳区",
    "destinationAddress": "北京市海淀区维修厂",
    "plannedStartTime": "2024-01-15 09:00:00",
    "plannedEndTime": "2024-01-15 17:00:00",
    "assigneeId": 100,
    "remark": "紧急维修"
}

Response:
{
    "code": 200,
    "msg": "操作成功",
    "data": {
        "taskId": 1,
        "taskCode": "TASK202401150001"
    }
}
1.1.2 查询任务列表
GET /api/task/list?pageNum=1&pageSize=10&taskType=MAINTENANCE&taskStatus=PENDING

Response:
{
    "code": 200,
    "msg": "查询成功",
    "rows": [
        {
            "taskId": 1,
            "taskCode": "TASK202401150001",
            "taskType": "MAINTENANCE",
            "taskStatus": "PENDING",
            "taskTitle": "车辆维修保养",
            "departureAddress": "北京市朝阳区",
            "destinationAddress": "北京市海淀区维修厂",
            "plannedStartTime": "2024-01-15 09:00:00",
            "plannedEndTime": "2024-01-15 17:00:00",
            "creatorName": "张三",
            "assigneeName": "李四",
            "createTime": "2024-01-15 08:30:00"
        }
    ],
    "total": 1
}
1.1.3 获取任务详情
GET /api/task/{taskId}

Response:
{
    "code": 200,
    "msg": "操作成功",
    "data": {
        "taskId": 1,
        "taskCode": "TASK202401150001",
        "taskType": "MAINTENANCE",
        "taskStatus": "PENDING",
        "taskTitle": "车辆维修保养",
        "taskDescription": "定期保养检查",
        "departureAddress": "北京市朝阳区",
        "destinationAddress": "北京市海淀区维修厂",
        "plannedStartTime": "2024-01-15 09:00:00",
        "plannedEndTime": "2024-01-15 17:00:00",
        "actualStartTime": null,
        "actualEndTime": null,
        "creatorName": "张三",
        "assigneeName": "李四",
        "remark": "紧急维修",
        "attachments": [],
        "operationLogs": [],
        "assignedVehicles": [
            {
                "id": 1,
                "vehicleId": 1,
                "vehicleNo": "京A12345",
                "vehicleType": "AMBULANCE",
                "assignTime": "2024-01-15 09:00:00",
                "assignBy": "张三",
                "status": "ASSIGNED",
                "remark": "分配救护车执行任务"
            }
        ]
    }
}
1.1.4 更新任务
PUT /api/task/{taskId}
Content-Type: application/json

Request Body:
{
    "taskTitle": "车辆维修保养(更新)",
    "taskDescription": "定期保养检查,增加安全检查",
    "plannedStartTime": "2024-01-15 10:00:00",
    "assigneeId": 101,
    "remark": "更新后的备注"
}

Response:
{
    "code": 200,
    "msg": "操作成功"
}
1.1.5 更新任务状态
PUT /api/task/{taskId}/status
Content-Type: application/json

Request Body:
{
    "taskStatus": "IN_PROGRESS",
    "actualStartTime": "2024-01-15 10:15:00",
    "remark": "任务开始执行"
}

Response:
{
    "code": 200,
    "msg": "操作成功"
}
1.1.6 分配任务
PUT /api/task/{taskId}/assign
Content-Type: application/json

Request Body:
{
    "assigneeId": 102,
    "remark": "重新分配给王五"
}

Response:
{
    "code": 200,
    "msg": "操作成功"
}
1.1.7 删除任务
DELETE /api/task/{taskIds}

Response:
{
    "code": 200,
    "msg": "操作成功"
}

1.2 任务附件接口

1.2.1 上传附件
POST /api/task/{taskId}/attachment
Content-Type: multipart/form-data

Request Body:
- file: 文件内容

Response:
{
    "code": 200,
    "msg": "上传成功",
    "data": {
        "attachmentId": 1,
        "fileName": "维修报告.pdf",
        "filePath": "/uploads/task/2024/01/15/xxx.pdf"
    }
}
1.2.2 删除附件
DELETE /api/task/attachment/{attachmentId}

Response:
{
    "code": 200,
    "msg": "操作成功"
}

1.3 车辆管理接口

1.3.1 查询车辆列表
GET /api/vehicle/list?pageNum=1&pageSize=10&vehicleType=AMBULANCE&vehicleStatus=ACTIVE&deptId=100

Response:
{
    "code": 200,
    "msg": "查询成功",
    "rows": [
        {
            "vehicleId": 1,
            "platformCode": "A",
            "vehicleNo": "京A12345",
            "vehicleType": "AMBULANCE",
            "vehicleBrand": "奔驰",
            "vehicleModel": "Sprinter",
            "vehicleStatus": "0",
            "deviceId": "DEV001",
            "deptId": 100,
            "deptName": "北京急救中心",
            "createTime": "2024-01-15 08:30:00"
        }
    ],
    "total": 1
}
1.3.2 获取车辆详情
GET /api/vehicle/{vehicleId}

Response:
{
    "code": 200,
    "msg": "操作成功",
    "data": {
        "vehicleId": 1,
        "platformCode": "A",
        "vehicleNo": "京A12345",
        "vehicleType": "AMBULANCE",
        "vehicleBrand": "奔驰",
        "vehicleModel": "Sprinter",
        "vehicleColor": "白色",
        "vehicleStatus": "0",
        "deviceId": "DEV001",
        "deptId": 100,
        "deptName": "北京急救中心",
        "createBy": "admin",
        "createTime": "2024-01-15 08:30:00",
        "updateBy": "admin",
        "updateTime": "2024-01-15 10:30:00",
        "remark": "车辆状态良好"
    }
}
1.3.3 分配车辆给任务
POST /api/task/{taskId}/assign-vehicle
Content-Type: application/json

Request Body:
{
    "vehicleId": 1,
    "remark": "分配救护车执行任务"
}

Response:
{
    "code": 200,
    "msg": "操作成功"
}
1.3.4 批量分配车辆给任务
POST /api/task/{taskId}/assign-vehicles
Content-Type: application/json

Request Body:
{
    "vehicleIds": [1, 2, 3],
    "remark": "分配多辆车执行任务"
}

Response:
{
    "code": 200,
    "msg": "操作成功",
    "data": {
        "successCount": 3,
        "failedCount": 0,
        "details": [
            {
                "vehicleId": 1,
                "vehicleNo": "京A12345",
                "status": "success",
                "message": "分配成功"
            },
            {
                "vehicleId": 2,
                "vehicleNo": "京A12346",
                "status": "success",
                "message": "分配成功"
            },
            {
                "vehicleId": 3,
                "vehicleNo": "京A12347",
                "status": "success",
                "message": "分配成功"
            }
        ]
    }
}
1.3.5 取消任务车辆分配
DELETE /api/task/{taskId}/vehicle/{vehicleId}

Response:
{
    "code": 200,
    "msg": "操作成功"
}
1.3.6 查询任务关联的车辆
GET /api/task/{taskId}/vehicles

Response:
{
    "code": 200,
    "msg": "查询成功",
    "data": [
        {
            "id": 1,
            "taskId": 1,
            "vehicleId": 1,
            "vehicleNo": "京A12345",
            "vehicleType": "AMBULANCE",
            "assignTime": "2024-01-15 09:00:00",
            "assignBy": "张三",
            "status": "ASSIGNED",
            "remark": "分配救护车执行任务"
        }
    ]
}
1.3.7 查询可用车辆
GET /api/vehicle/available?deptId=100&taskType=MAINTENANCE

Response:
{
    "code": 200,
    "msg": "查询成功",
    "data": [
        {
            "vehicleId": 1,
            "vehicleNo": "京A12345",
            "vehicleType": "AMBULANCE",
            "vehicleBrand": "奔驰",
            "vehicleModel": "Sprinter",
            "vehicleStatus": "0",
            "deptName": "北京急救中心",
            "currentLocation": "北京市朝阳区"
        },
        {
            "vehicleId": 2,
            "vehicleNo": "京A12346",
            "vehicleType": "AMBULANCE",
            "vehicleBrand": "奔驰",
            "vehicleModel": "Sprinter",
            "vehicleStatus": "0",
            "deptName": "北京急救中心",
            "currentLocation": "北京市海淀区"
        }
    ]
}

1.4 任务统计接口

1.4.1 任务统计概览
GET /api/task/statistics

Response:
{
    "code": 200,
    "msg": "查询成功",
    "data": {
        "totalTasks": 100,
        "pendingTasks": 20,
        "inProgressTasks": 30,
        "completedTasks": 45,
        "cancelledTasks": 5,
        "todayTasks": 8,
        "overdueTasks": 3,
        "vehicleUtilization": 85.5
    }
}

程序设计

1. 后端架构设计

1.1 模块结构

ruoyi-task/
├── src/main/java/com/ruoyi/task/
│   ├── controller/          # 控制器层
│   │   ├── TaskController.java
│   │   ├── TaskAttachmentController.java
│   │   ├── VehicleController.java
│   │   └── TaskVehicleController.java
│   ├── service/            # 服务层
│   │   ├── ITaskService.java
│   │   ├── impl/TaskServiceImpl.java
│   │   ├── ITaskAttachmentService.java
│   │   ├── impl/TaskAttachmentServiceImpl.java
│   │   ├── IVehicleService.java
│   │   ├── impl/VehicleServiceImpl.java
│   │   ├── ITaskVehicleService.java
│   │   └── impl/TaskVehicleServiceImpl.java
│   ├── domain/             # 领域层
│   │   ├── Task.java
│   │   ├── TaskAttachment.java
│   │   ├── TaskLog.java
│   │   ├── Vehicle.java
│   │   ├── TaskVehicle.java
│   │   ├── enums/
│   │   │   ├── TaskType.java
│   │   │   ├── TaskStatus.java
│   │   │   ├── VehicleType.java
│   │   │   ├── VehicleStatus.java
│   │   │   └── TaskVehicleStatus.java
│   │   └── vo/
│   │       ├── TaskQueryVO.java
│   │       ├── TaskCreateVO.java
│   │       ├── TaskUpdateVO.java
│   │       ├── VehicleQueryVO.java
│   │       ├── VehicleCreateVO.java
│   │       └── TaskVehicleAssignVO.java
│   ├── mapper/             # 数据访问层
│   │   ├── TaskMapper.java
│   │   ├── TaskAttachmentMapper.java
│   │   ├── TaskLogMapper.java
│   │   ├── VehicleMapper.java
│   │   └── TaskVehicleMapper.java
│   ├── config/             # 配置类
│   │   └── TaskConfig.java
│   └── utils/              # 工具类
│       ├── TaskCodeGenerator.java
│       ├── TaskStatusValidator.java
│       └── VehicleCodeGenerator.java
└── src/main/resources/
    └── mapper/
        ├── TaskMapper.xml
        ├── TaskAttachmentMapper.xml
        ├── TaskLogMapper.xml
        ├── VehicleMapper.xml
        └── TaskVehicleMapper.xml

1.2 核心类设计

1.2.1 任务实体类 (Task.java)
/**
 * 任务实体类
 * 包含任务的所有属性和业务方法
 */
public class Task extends BaseEntity {
    private Long taskId;
    private String taskCode;
    private TaskType taskType;
    private TaskStatus taskStatus;
    private String taskTitle;
    private String taskDescription;
    private String departureAddress;
    private String destinationAddress;
    private Date plannedStartTime;
    private Date plannedEndTime;
    private Date actualStartTime;
    private Date actualEndTime;
    private Long creatorId;
    private Long assigneeId;
    private Long deptId;
    
    // 关联车辆列表(通过中间表查询)
    private List<TaskVehicle> assignedVehicles;
    
    // 业务方法
    public boolean canChangeStatus(TaskStatus newStatus);
    public boolean isOverdue();
    public long getDuration();
    public void start();
    public void complete();
    public void cancel();
    public List<Vehicle> getAssignedVehicles();
    public boolean hasVehicle(Long vehicleId);
}
1.2.2 任务服务接口 (ITaskService.java)
/**
 * 任务服务接口
 * 定义任务相关的业务操作
 */
public interface ITaskService {
    // 基础CRUD操作
    List<Task> selectTaskList(TaskQueryVO queryVO);
    Task selectTaskById(Long taskId);
    int insertTask(TaskCreateVO createVO);
    int updateTask(TaskUpdateVO updateVO);
    int deleteTaskByIds(Long[] taskIds);
    
    // 业务操作
    int assignTask(Long taskId, Long assigneeId, String remark);
    int changeTaskStatus(Long taskId, TaskStatus newStatus, String remark);
    int uploadAttachment(Long taskId, MultipartFile file);
    int deleteAttachment(Long attachmentId);
    
    // 车辆管理操作
    int assignVehicleToTask(Long taskId, Long vehicleId, String remark);
    int unassignVehicleFromTask(Long taskId, Long vehicleId);
    int assignMultipleVehiclesToTask(Long taskId, List<Long> vehicleIds, String remark);
    List<TaskVehicle> getTaskVehicles(Long taskId);
    List<Vehicle> getAvailableVehicles(Long deptId, String taskType);
    
    // 统计查询
    TaskStatisticsVO getTaskStatistics();
    List<Task> selectOverdueTasks();
    List<Task> selectMyTasks(Long userId);
}

1.3 业务规则设计

1.3.1 任务状态流转规则
/**
 * 任务状态流转验证器
 */
@Component
public class TaskStatusValidator {
    
    private static final Map<TaskStatus, Set<TaskStatus>> ALLOWED_TRANSITIONS = new HashMap<>();
    
    static {
        // PENDING -> IN_PROGRESS, CANCELLED
        ALLOWED_TRANSITIONS.put(PENDING, Set.of(IN_PROGRESS, CANCELLED));
        // IN_PROGRESS -> COMPLETED, CANCELLED, PENDING
        ALLOWED_TRANSITIONS.put(IN_PROGRESS, Set.of(COMPLETED, CANCELLED, PENDING));
        // COMPLETED -> 不允许任何状态变更
        ALLOWED_TRANSITIONS.put(COMPLETED, Set.of());
        // CANCELLED -> 不允许任何状态变更
        ALLOWED_TRANSITIONS.put(CANCELLED, Set.of());
    }
    
    public boolean canTransition(TaskStatus from, TaskStatus to) {
        return ALLOWED_TRANSITIONS.get(from).contains(to);
    }
}
1.3.2 任务编号生成规则
/**
 * 任务编号生成器
 * 格式:TASK + YYYYMMDD + 4位序号
 */
@Component
public class TaskCodeGenerator {
    
    public String generateTaskCode() {
        String dateStr = DateUtils.formatDate(new Date(), "yyyyMMdd");
        String sequence = getNextSequence(dateStr);
        return "TASK" + dateStr + sequence;
    }
    
    private String getNextSequence(String dateStr) {
        // 查询当日最大序号并递增
        // 实现逻辑...
    }
}

2. 前端架构设计

2.1 页面组件结构

src/views/task/
├── index.vue              # 任务列表页面
├── detail.vue             # 任务详情页面
├── create.vue             # 创建任务页面
├── edit.vue               # 编辑任务页面
└── components/
    ├── TaskList.vue       # 任务列表组件
    ├── TaskForm.vue       # 任务表单组件
    ├── TaskStatus.vue     # 任务状态组件
    ├── TaskAttachment.vue # 任务附件组件
    └── TaskLog.vue        # 任务日志组件

2.2 API服务设计

// src/api/task.js
import request from '@/utils/request'

// 任务管理API
export function listTask(query) {
  return request({
    url: '/api/task/list',
    method: 'get',
    params: query
  })
}

export function getTask(taskId) {
  return request({
    url: '/api/task/' + taskId,
    method: 'get'
  })
}

export function addTask(data) {
  return request({
    url: '/api/task',
    method: 'post',
    data: data
  })
}

export function updateTask(data) {
  return request({
    url: '/api/task/' + data.taskId,
    method: 'put',
    data: data
  })
}

export function deleteTask(taskIds) {
  return request({
    url: '/api/task/' + taskIds,
    method: 'delete'
  })
}

export function assignTask(taskId, data) {
  return request({
    url: '/api/task/' + taskId + '/assign',
    method: 'put',
    data: data
  })
}

export function changeTaskStatus(taskId, data) {
  return request({
    url: '/api/task/' + taskId + '/status',
    method: 'put',
    data: data
  })
}

// 附件管理API
export function uploadAttachment(taskId, file) {
  const formData = new FormData()
  formData.append('file', file)
  return request({
    url: '/api/task/' + taskId + '/attachment',
    method: 'post',
    data: formData,
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  })
}

export function deleteAttachment(attachmentId) {
  return request({
    url: '/api/task/attachment/' + attachmentId,
    method: 'delete'
  })
}

// 统计API
export function getTaskStatistics() {
  return request({
    url: '/api/task/statistics',
    method: 'get'
  })
}

// 车辆管理API
export function listVehicleByDept(deptId, query) {
  return request({
    url: '/api/vehicle/list-by-dept/' + deptId,
    method: 'get',
    params: query
  })
}

export function listAvailableVehicles(deptId, taskType) {
  return request({
    url: '/api/vehicle/available',
    method: 'get',
    params: { deptId, taskType }
  })
}

export function assignVehiclesToTask(taskId, vehicleIds, remark) {
  return request({
    url: '/api/task/' + taskId + '/assign-vehicles',
    method: 'post',
    data: { vehicleIds, remark }
  })
}

export function getTaskVehicleUsage(taskId) {
  return request({
    url: '/api/task/' + taskId + '/vehicle-usage',
    method: 'get'
  })
}

3. 权限控制设计

3.1 菜单权限配置

-- 任务管理菜单
INSERT INTO sys_menu VALUES (2000, '任务管理', 0, 5, 'task', null, '', 1, 0, 'M', '0', '0', '', 'task', 'admin', sysdate(), '', null, '任务管理目录');

-- 通用任务菜单
INSERT INTO sys_menu VALUES (2001, '通用任务', 2000, 1, 'general', 'task/general/index', '', 1, 0, 'C', '0', '0', 'task:general:view', 'list', 'admin', sysdate(), '', null, '通用任务菜单');

-- 任务管理按钮权限
INSERT INTO sys_menu VALUES (2002, '任务查询', 2001, 1, '', '', '', 1, 0, 'F', '0', '0', 'task:general:query', '#', 'admin', sysdate(), '', null, '');
INSERT INTO sys_menu VALUES (2003, '任务新增', 2001, 2, '', '', '', 1, 0, 'F', '0', '0', 'task:general:add', '#', 'admin', sysdate(), '', null, '');
INSERT INTO sys_menu VALUES (2004, '任务修改', 2001, 3, '', '', '', 1, 0, 'F', '0', '0', 'task:general:edit', '#', 'admin', sysdate(), '', null, '');
INSERT INTO sys_menu VALUES (2005, '任务删除', 2001, 4, '', '', '', 1, 0, 'F', '0', '0', 'task:general:remove', '#', 'admin', sysdate(), '', null, '');
INSERT INTO sys_menu VALUES (2006, '任务分配', 2001, 5, '', '', '', 1, 0, 'F', '0', '0', 'task:general:assign', '#', 'admin', sysdate(), '', null, '');
INSERT INTO sys_menu VALUES (2007, '状态变更', 2001, 6, '', '', '', 1, 0, 'F', '0', '0', 'task:general:status', '#', 'admin', sysdate(), '', null, '');

3.2 数据权限控制

/**
 * 任务数据权限控制
 * 基于部门进行数据隔离
 */
@Aspect
@Component
public class TaskDataScopeAspect {
    
    @Before("@annotation(dataScope)")
    public void doBefore(JoinPoint point, DataScope dataScope) {
        // 获取当前用户部门权限
        // 添加数据权限过滤条件
        // 实现逻辑...
    }
}

4. 异常处理设计

4.1 业务异常定义

/**
 * 任务相关业务异常
 */
public class TaskException extends RuntimeException {
    private String code;
    private String message;
    
    public TaskException(String code, String message) {
        super(message);
        this.code = code;
        this.message = message;
    }
}

/**
 * 任务异常常量
 */
public class TaskErrorCode {
    public static final String TASK_NOT_FOUND = "TASK_001";
    public static final String TASK_STATUS_INVALID = "TASK_002";
    public static final String TASK_ASSIGNEE_INVALID = "TASK_003";
    public static final String TASK_PERMISSION_DENIED = "TASK_004";
}

4.2 全局异常处理

/**
 * 全局异常处理器
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(TaskException.class)
    public AjaxResult handleTaskException(TaskException e) {
        return AjaxResult.error(e.getCode(), e.getMessage());
    }
}

部署和配置

1. 环境要求

  • JDK 1.8+
  • MySQL 5.7+
  • Redis 3.0+
  • Maven 3.6+

2. 配置文件

# application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/ry-task?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password: password
    
  redis:
    host: localhost
    port: 6379
    password: 
    database: 0

# 任务相关配置
task:
  # 任务编号前缀
  code-prefix: TASK
  # 附件上传路径
  upload-path: /uploads/task/
  # 最大附件大小(MB)
  max-file-size: 10
  # 允许的文件类型
  allowed-file-types: pdf,doc,docx,jpg,jpeg,png

3. 数据库初始化

-- 执行数据库表创建脚本
source sql/task_tables.sql;

-- 执行数据字典初始化脚本
source sql/task_dict_data.sql;

-- 执行菜单权限初始化脚本
source sql/task_menu.sql;

测试策略

1. 单元测试

  • 服务层业务逻辑测试
  • 数据访问层测试
  • 工具类测试

2. 集成测试

  • API接口测试
  • 数据库操作测试
  • 权限控制测试

3. 性能测试

  • 并发创建任务测试
  • 大数据量查询测试
  • 文件上传性能测试

监控和日志

1. 业务监控

  • 任务创建数量统计
  • 任务完成率统计
  • 任务超时率统计

2. 系统监控

  • API响应时间监控
  • 数据库连接池监控
  • 文件存储空间监控

3. 日志记录

  • 操作日志记录
  • 异常日志记录
  • 性能日志记录