package com.ruoyi.web.controller.task; import java.util.List; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import com.ruoyi.system.service.*; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.system.domain.SysTask; import com.ruoyi.system.domain.SysTaskLog; import com.ruoyi.system.domain.VehicleInfo; import com.ruoyi.system.domain.vo.TaskQueryVO; import com.ruoyi.system.domain.vo.TaskCreateVO; import com.ruoyi.system.domain.vo.TaskUpdateVO; import com.ruoyi.system.domain.vo.TaskStatisticsVO; import com.ruoyi.system.domain.enums.TaskStatus; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.utils.StringUtils; /** * 任务管理Controller * * @author ruoyi * @date 2024-01-15 */ @RestController @RequestMapping("/task") public class SysTaskController extends BaseController { @Autowired private ISysTaskService sysTaskService; @Autowired private IVehicleInfoService vehicleInfoService; @Autowired private ISysUserService userService; @Autowired private ISysDeptService deptService; @Autowired @Qualifier("tiandituMapService") private IMapService mapService; /** * 查询任务管理列表(后台管理端) * 管理员权限,可以查看所有任务 */ @PreAuthorize("@ss.hasPermi('task:general:query')") @GetMapping("/admin/list") public TableDataInfo adminList(TaskQueryVO queryVO) { startPage(); List list = sysTaskService.selectSysTaskList(queryVO); return getDataTable(list); } /** * 查询任务列表(APP端) * 根据用户权限返回不同范围的任务: * 1. 有查看所有咨询单权限(canViewAllConsult='1'):返回该用户管理所有分公司下的所有任务单 * 2. 无权限(canViewAllConsult='0'):只返回分配给该用户的单或该用户创建的单 */ @GetMapping("/list") public TableDataInfo appList(TaskQueryVO queryVO) { // 获取当前用户信息 Long currentUserId = getUserId(); SysUser currentUser = userService.selectUserById(currentUserId); if (currentUser == null) { return getDataTable(new java.util.ArrayList<>()); } // 判断用户是否有查看所有咨询单的权限 String canViewAllConsult = currentUser.getCanViewAllConsult(); if ("1".equals(canViewAllConsult)) { // 有权限:返回该用户管理所有分公司下的所有任务单 // 1. 获取用户管理的分公司列表 List branchCompanies = deptService.computeBranchCompaniesForUser(currentUser); if (branchCompanies != null && !branchCompanies.isEmpty()) { // 2. 提取所有分公司ID List deptIds = new java.util.ArrayList<>(); for (SysDept dept : branchCompanies) { deptIds.add(dept.getDeptId()); } // 3. 设置查询条件为分公司ID列表(SQL会自动包含所有子部门) queryVO.setDeptIds(deptIds); // 清空创建人和执行人过滤条件,返回这些分公司下的所有任务 queryVO.setCreatorId(null); queryVO.setAssigneeId(null); } else { // 如果没有找到分公司,返回空列表 return getDataTable(new java.util.ArrayList<>()); } } else { // 无权限:只返回分配给该用户的单或该用户创建的单 // 清空deptId和deptIds,使用creatorId和assigneeId进行OR查询 queryVO.setDeptId(null); queryVO.setDeptIds(null); queryVO.setCreatorId(currentUserId); queryVO.setAssigneeId(currentUserId); } startPage(); List list = sysTaskService.selectSysTaskList(queryVO); return getDataTable(list); } /** * 导出任务管理列表(后台管理端) */ @PreAuthorize("@ss.hasPermi('task:general:export')") @Log(title = "任务管理", businessType = BusinessType.EXPORT) @PostMapping("/admin/export") public void export(HttpServletResponse response, TaskQueryVO queryVO) { List list = sysTaskService.selectSysTaskList(queryVO); ExcelUtil util = new ExcelUtil(SysTask.class); util.exportExcel(response, list, "任务管理数据"); } /** * 获取任务详细信息(后台管理端) */ @PreAuthorize("@ss.hasPermi('task:general:query')") @GetMapping(value = "/admin/{taskId}") public AjaxResult adminGetInfo(@PathVariable("taskId") Long taskId) { return success(sysTaskService.getTaskDetail(taskId)); } /** * 获取任务详细信息(APP端) */ @GetMapping(value = "/{taskId}") public AjaxResult appGetInfo(@PathVariable("taskId") Long taskId) { return success(sysTaskService.getTaskDetail(taskId)); } /** * 新增任务(后台管理端) */ @PreAuthorize("@ss.hasPermi('task:general:add')") @Log(title = "任务管理", businessType = BusinessType.INSERT) @PostMapping("/admin") public AjaxResult adminAdd(@RequestBody TaskCreateVO createVO) { return toAjax(sysTaskService.insertSysTask(createVO)); } /** * 新增任务(APP端) */ @Log(title = "任务创建", businessType = BusinessType.INSERT) @PostMapping public AjaxResult appAdd(@RequestBody TaskCreateVO createVO) { return toAjax(sysTaskService.insertSysTask(createVO)); } /** * 修改任务(后台管理端) */ @PreAuthorize("@ss.hasPermi('task:general:edit')") @Log(title = "任务管理", businessType = BusinessType.UPDATE) @PutMapping("/admin") public AjaxResult adminEdit(@RequestBody TaskUpdateVO updateVO) { return toAjax(sysTaskService.updateSysTask(updateVO,false)); } /** * 修改任务(APP端) */ @Log(title = "任务修改", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult appEdit(@RequestBody TaskUpdateVO updateVO) { return toAjax(sysTaskService.updateSysTask(updateVO,false)); } /** * 删除任务(APP端) */ @Log(title = "任务删除", businessType = BusinessType.DELETE) @DeleteMapping("/{taskIds}") public AjaxResult appRemove(@PathVariable Long[] taskIds) { return toAjax(sysTaskService.deleteSysTaskByTaskIds(taskIds)); } /** * 删除任务(后台管理端) */ @PreAuthorize("@ss.hasPermi('task:general:remove')") @Log(title = "任务管理", businessType = BusinessType.DELETE) @DeleteMapping("/admin/{taskIds}") public AjaxResult adminRemove(@PathVariable Long[] taskIds) { return toAjax(sysTaskService.deleteSysTaskByTaskIds(taskIds)); } /** * 分配任务(后台管理端) */ @PreAuthorize("@ss.hasPermi('task:general:edit')") @Log(title = "任务分配", businessType = BusinessType.UPDATE) @PutMapping("/admin/{taskId}/assign") public AjaxResult adminAssignTask(@PathVariable Long taskId, @RequestBody AssignTaskRequest request) { return toAjax(sysTaskService.assignTask(taskId, request.getAssigneeId(), request.getRemark())); } /** * 分配任务(APP端) */ @Log(title = "任务分配", businessType = BusinessType.UPDATE) @PutMapping("/{taskId}/assign") public AjaxResult appAssignTask(@PathVariable Long taskId, @RequestBody AssignTaskRequest request) { return toAjax(sysTaskService.assignTask(taskId, request.getAssigneeId(), request.getRemark())); } /** * 更新任务状态(后台管理端) */ @PreAuthorize("@ss.hasPermi('task:general:edit')") @Log(title = "任务状态变更", businessType = BusinessType.UPDATE) @PutMapping("/admin/{taskId}/status") public AjaxResult adminChangeTaskStatus(@PathVariable Long taskId, @RequestBody ChangeStatusRequest request) { TaskStatus newStatus = TaskStatus.getByCode(request.getTaskStatus()); if (newStatus == null) { return error("无效的任务状态"); } return toAjax(sysTaskService.changeTaskStatus(taskId, newStatus, request.getRemark())); } /** * 更新任务状态(APP端) * 支持GPS位置信息上报 */ @Log(title = "任务状态变更", businessType = BusinessType.UPDATE) @PutMapping("/{taskId}/status") public AjaxResult appChangeTaskStatus(@PathVariable Long taskId, @RequestBody ChangeStatusRequest request) { TaskStatus newStatus = TaskStatus.getByCode(request.getTaskStatus()); if (newStatus == null) { return error("无效的任务状态"); } // 如果包含GPS位置信息,使用带位置的方法 if (request.getLatitude() != null && request.getLongitude() != null) { String address= mapService.reverseGeocoding(request.getLongitude(), request.getLatitude()); request.setLocationAddress(address); SysTaskLog locationLog = new SysTaskLog(); locationLog.setLatitude(request.getLatitude()); locationLog.setLongitude(request.getLongitude()); locationLog.setLocationAddress(request.getLocationAddress()); locationLog.setLocationProvince(request.getLocationProvince()); locationLog.setLocationCity(request.getLocationCity()); locationLog.setLocationDistrict(request.getLocationDistrict()); locationLog.setGpsAccuracy(request.getGpsAccuracy()); locationLog.setAltitude(request.getAltitude()); locationLog.setSpeed(request.getSpeed()); locationLog.setHeading(request.getHeading()); return toAjax(sysTaskService.changeTaskStatusWithLocation(taskId, newStatus, request.getRemark(), locationLog)); } return toAjax(sysTaskService.changeTaskStatus(taskId, newStatus, request.getRemark())); } /** * 查询任务统计信息(APP端) */ @GetMapping("/statistics") public AjaxResult getStatistics() { TaskStatisticsVO statistics = sysTaskService.getTaskStatistics(); return success(statistics); } /** * 查询任务统计信息(后台管理端) */ @PreAuthorize("@ss.hasPermi('task:general:query')") @GetMapping("/admin/statistics") public AjaxResult adminGetStatistics() { TaskStatisticsVO statistics = sysTaskService.getTaskStatistics(); return success(statistics); } /** * 查询超时任务列表(APP端) */ @GetMapping("/overdue") public AjaxResult getOverdueTasks() { List list = sysTaskService.selectOverdueTasks(); return success(list); } /** * 查询超时任务列表(后台管理端) */ @PreAuthorize("@ss.hasPermi('task:general:query')") @GetMapping("/admin/overdue") public AjaxResult adminGetOverdueTasks() { List list = sysTaskService.selectOverdueTasks(); return success(list); } /** * 查询我的任务列表(APP端) */ @GetMapping("/my") public AjaxResult getMyTasks() { List list = sysTaskService.selectMyTasks(getUserId()); return success(list); } /** * 检查车辆是否有正在进行中的任务(APP端) * 正在进行中的任务是指状态不为:PENDING(待处理)、COMPLETED(已完成)、CANCELLED(已取消)的任务 */ @GetMapping("/vehicle/{vehicleId}/active") public AjaxResult checkVehicleActiveTasks(@PathVariable Long vehicleId) { List activeTasks = sysTaskService.checkVehicleActiveTasks(vehicleId); return success(activeTasks); } /** * 检查任务是否可以出发(APP端) * 检查: * 1. 车辆是否有未完成的任务 * 2. 执行人员是否有未完成的任务 * * @param taskId 任务ID * @return 校验结果 */ @GetMapping("/{taskId}/check-depart") public AjaxResult checkTaskCanDepart(@PathVariable Long taskId) { return sysTaskService.checkTaskCanDepart(taskId); } /** * 执行人点击就绪(APP端) */ @PostMapping("/{taskId}/assignee/ready") public AjaxResult setAssigneeReady(@PathVariable Long taskId) { Long userId = getUserId(); return sysTaskService.setAssigneeReady(taskId, userId); } /** * 执行人取消就绪(APP端) */ @PostMapping("/{taskId}/assignee/cancel-ready") public AjaxResult cancelAssigneeReady(@PathVariable Long taskId) { Long userId = getUserId(); return sysTaskService.cancelAssigneeReady(taskId, userId); } /** * 分配任务请求对象 */ public static class AssignTaskRequest { private Long assigneeId; private String remark; public Long getAssigneeId() { return assigneeId; } public void setAssigneeId(Long assigneeId) { this.assigneeId = assigneeId; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } } /** * 变更状态请求对象 */ public static class ChangeStatusRequest { private String taskStatus; private String remark; // GPS位置信息字段 private Double latitude; private Double longitude; private String locationAddress; private String locationProvince; private String locationCity; private String locationDistrict; private Double gpsAccuracy; private Double altitude; private Double speed; private Double heading; public String getTaskStatus() { return taskStatus; } public void setTaskStatus(String taskStatus) { this.taskStatus = taskStatus; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } public Double getLatitude() { return latitude; } public void setLatitude(Double latitude) { this.latitude = latitude; } public Double getLongitude() { return longitude; } public void setLongitude(Double longitude) { this.longitude = longitude; } public String getLocationAddress() { return locationAddress; } public void setLocationAddress(String locationAddress) { this.locationAddress = locationAddress; } public String getLocationProvince() { return locationProvince; } public void setLocationProvince(String locationProvince) { this.locationProvince = locationProvince; } public String getLocationCity() { return locationCity; } public void setLocationCity(String locationCity) { this.locationCity = locationCity; } public String getLocationDistrict() { return locationDistrict; } public void setLocationDistrict(String locationDistrict) { this.locationDistrict = locationDistrict; } public Double getGpsAccuracy() { return gpsAccuracy; } public void setGpsAccuracy(Double gpsAccuracy) { this.gpsAccuracy = gpsAccuracy; } public Double getAltitude() { return altitude; } public void setAltitude(Double altitude) { this.altitude = altitude; } public Double getSpeed() { return speed; } public void setSpeed(Double speed) { this.speed = speed; } public Double getHeading() { return heading; } public void setHeading(Double heading) { this.heading = heading; } } }