根据需求文档,已完成通用任务和转运任务的后台管理功能开发,包括:
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='任务管理表';
-- 基于现有车辆表结构,添加机构关联字段
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='车辆信息表';
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='任务车辆关联表';
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='任务附件表';
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='任务操作日志表';
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, '其他类型任务');
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, '任务已取消');
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, '维修车');
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, '车辆停用');
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, '车辆任务已取消');
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"
}
}
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
}
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": "分配救护车执行任务"
}
]
}
}
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": "操作成功"
}
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": "操作成功"
}
PUT /api/task/{taskId}/assign
Content-Type: application/json
Request Body:
{
"assigneeId": 102,
"remark": "重新分配给王五"
}
Response:
{
"code": 200,
"msg": "操作成功"
}
DELETE /api/task/{taskIds}
Response:
{
"code": 200,
"msg": "操作成功"
}
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"
}
}
DELETE /api/task/attachment/{attachmentId}
Response:
{
"code": 200,
"msg": "操作成功"
}
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
}
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": "车辆状态良好"
}
}
POST /api/task/{taskId}/assign-vehicle
Content-Type: application/json
Request Body:
{
"vehicleId": 1,
"remark": "分配救护车执行任务"
}
Response:
{
"code": 200,
"msg": "操作成功"
}
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": "分配成功"
}
]
}
}
DELETE /api/task/{taskId}/vehicle/{vehicleId}
Response:
{
"code": 200,
"msg": "操作成功"
}
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": "分配救护车执行任务"
}
]
}
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": "北京市海淀区"
}
]
}
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
}
}
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
/**
* 任务实体类
* 包含任务的所有属性和业务方法
*/
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);
}
/**
* 任务服务接口
* 定义任务相关的业务操作
*/
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);
}
/**
* 任务状态流转验证器
*/
@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);
}
}
/**
* 任务编号生成器
* 格式: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) {
// 查询当日最大序号并递增
// 实现逻辑...
}
}
src/views/task/
├── index.vue # 任务列表页面
├── detail.vue # 任务详情页面
├── create.vue # 创建任务页面
├── edit.vue # 编辑任务页面
└── components/
├── TaskList.vue # 任务列表组件
├── TaskForm.vue # 任务表单组件
├── TaskStatus.vue # 任务状态组件
├── TaskAttachment.vue # 任务附件组件
└── TaskLog.vue # 任务日志组件
// 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'
})
}
-- 任务管理菜单
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, '');
/**
* 任务数据权限控制
* 基于部门进行数据隔离
*/
@Aspect
@Component
public class TaskDataScopeAspect {
@Before("@annotation(dataScope)")
public void doBefore(JoinPoint point, DataScope dataScope) {
// 获取当前用户部门权限
// 添加数据权限过滤条件
// 实现逻辑...
}
}
/**
* 任务相关业务异常
*/
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";
}
/**
* 全局异常处理器
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(TaskException.class)
public AjaxResult handleTaskException(TaskException e) {
return AjaxResult.error(e.getCode(), e.getMessage());
}
}
# 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
-- 执行数据库表创建脚本
source sql/task_tables.sql;
-- 执行数据字典初始化脚本
source sql/task_dict_data.sql;
-- 执行菜单权限初始化脚本
source sql/task_menu.sql;