# 通用任务管理功能说明 ## 功能概述 根据需求文档,已完成通用任务和转运任务的后台管理功能开发,包括: 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) - 任务已取消 #### 任务状态流转规则 ##### 任务状态流转规则 - **PENDING** → **IN_PROGRESS** → **COMPLETED** - 任何状态都可以流转到 **CANCELLED**(除了 **COMPLETED**) ##### 状态流转约束 1. 任务状态流转必须符合业务逻辑顺序 2. 支持状态回退(如从 IN_PROGRESS 回到 PENDING) 3. 任务取消后不能再次激活 ### 3. 任务字段设计 #### 通用字段 - 任务编号、任务创建人,任务归属机构 - 任务类型、任务状态 - 任务目的地址、任务出发地址 - 计划开始时间、计划结束时间 - 实际开始时间、实际结束时间 - 任务备注、附件列表 ## 数据库设计 ### 1. 核心表结构 #### 1.1 任务主表 (sys_task) ```sql 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) ```sql -- 基于现有车辆表结构,添加机构关联字段 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) ```sql 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) ```sql 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) ```sql 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 任务类型字典 ```sql 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 任务状态字典 ```sql 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 车辆类型字典 ```sql 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 车辆状态字典 ```sql 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 任务车辆关联状态字典 ```sql 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) ```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 assignedVehicles; // 业务方法 public boolean canChangeStatus(TaskStatus newStatus); public boolean isOverdue(); public long getDuration(); public void start(); public void complete(); public void cancel(); public List getAssignedVehicles(); public boolean hasVehicle(Long vehicleId); } ``` ##### 1.2.2 任务服务接口 (ITaskService.java) ```java /** * 任务服务接口 * 定义任务相关的业务操作 */ public interface ITaskService { // 基础CRUD操作 List 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 vehicleIds, String remark); List getTaskVehicles(Long taskId); List getAvailableVehicles(Long deptId, String taskType); // 统计查询 TaskStatisticsVO getTaskStatistics(); List selectOverdueTasks(); List selectMyTasks(Long userId); } ``` #### 1.3 业务规则设计 ##### 1.3.1 任务状态流转规则 ```java /** * 任务状态流转验证器 */ @Component public class TaskStatusValidator { private static final Map> 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 任务编号生成规则 ```java /** * 任务编号生成器 * 格式: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服务设计 ```javascript // 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 菜单权限配置 ```sql -- 任务管理菜单 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 数据权限控制 ```java /** * 任务数据权限控制 * 基于部门进行数据隔离 */ @Aspect @Component public class TaskDataScopeAspect { @Before("@annotation(dataScope)") public void doBefore(JoinPoint point, DataScope dataScope) { // 获取当前用户部门权限 // 添加数据权限过滤条件 // 实现逻辑... } } ``` ### 4. 异常处理设计 #### 4.1 业务异常定义 ```java /** * 任务相关业务异常 */ 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 全局异常处理 ```java /** * 全局异常处理器 */ @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. 配置文件 ```yaml # 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. 数据库初始化 ```sql -- 执行数据库表创建脚本 source sql/task_tables.sql; -- 执行数据字典初始化脚本 source sql/task_dict_data.sql; -- 执行菜单权限初始化脚本 source sql/task_menu.sql; ``` ## 测试策略 ### 1. 单元测试 - 服务层业务逻辑测试 - 数据访问层测试 - 工具类测试 ### 2. 集成测试 - API接口测试 - 数据库操作测试 - 权限控制测试 ### 3. 性能测试 - 并发创建任务测试 - 大数据量查询测试 - 文件上传性能测试 ## 监控和日志 ### 1. 业务监控 - 任务创建数量统计 - 任务完成率统计 - 任务超时率统计 ### 2. 系统监控 - API响应时间监控 - 数据库连接池监控 - 文件存储空间监控 ### 3. 日志记录 - 操作日志记录 - 异常日志记录 - 性能日志记录