wlzboy
1 天以前 08f95b2f159b56fa3bd4f4b348855989de8aa456
feat: vehicle
2个文件已添加
17个文件已修改
333 ■■■■ 已修改文件
app/pages/index.vue 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/task/index.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pagesTask/detail.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/DeptUtil.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/UserUtil.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTask.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTaskService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/NotifyDispatchServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java 115 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/VehicleGpsMapper.xml 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/VehicleGpsSegmentMileageMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/add_is_head_push_to_sys_task.sql 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/index.vue
@@ -95,9 +95,10 @@
          <view class="task-main" @click="viewTaskDetail(task)">
            <!-- 任务头部:标题和状态标签 -->
            <view class="task-header">
              <view class="task-title"
                >{{ getTaskTypeText(task.type) }} - {{ task.vehicle }}</view
              >
              <view class="task-title">
                {{ getTaskTypeText(task.type) }} - {{ task.vehicle }}
                <text v-if="task.isHeadPush === '1'" class="head-push-tag">总</text>
              </view>
              <view
                class="task-status"
                :class="
@@ -767,6 +768,17 @@
  }
}
// 总部推送标记样式
.head-push-tag {
  color: #ff0000;
  font-size: 24rpx;
  font-weight: bold;
  margin-left: 10rpx;
  padding: 2rpx 8rpx;
  border: 1rpx solid #ff0000;
  border-radius: 4rpx;
}
// 用户信息区域
.user-info-section {
  background-color: white;
app/pages/task/index.vue
@@ -112,7 +112,10 @@
            <view class="task-main" @click="viewTaskDetail(task)">
              <!-- 任务头部:标题和状态标签 -->
              <view class="task-header">
                <view class="task-title">{{ getTaskTypeText(task.taskType) }} - {{ task.vehicle }}</view>
                <view class="task-title">
                  {{ getTaskTypeText(task.taskType) }} - {{ task.vehicle }}
                  <text v-if="task.isHeadPush === '1'" class="head-push-tag">总</text>
                </view>
                <view class="task-status" :class="task.taskStatus === 'PENDING' ? 'status-pending' : task.taskStatus === 'DEPARTING' ? 'status-departing' : task.taskStatus === 'ARRIVED' ? 'status-arrived' : task.taskStatus === 'RETURNING' ? 'status-returning' : task.taskStatus === 'COMPLETED' ? 'status-completed' : task.taskStatus === 'CANCELLED' ? 'status-cancelled' : task.taskStatus === 'IN_PROGRESS' ? 'status-in-progress' : 'status-default'">
                  {{ getStatusText(task.taskStatus) }}
                </view>
@@ -713,6 +716,17 @@
    }
  }
  
  // 总部推送标记样式
  .head-push-tag {
    color: #ff0000;
    font-size: 24rpx;
    font-weight: bold;
    margin-left: 10rpx;
    padding: 2rpx 8rpx;
    border: 1rpx solid #ff0000;
    border-radius: 4rpx;
  }
  // 任务列表区域
  .task-list-section {
    flex: 1;
app/pagesTask/detail.vue
@@ -12,7 +12,10 @@
        <view class="section-title">基本信息</view>
        <view class="info-item">
          <view class="label">任务编号</view>
          <view class="value">{{ taskDetail.showTaskCode }}</view>
          <view class="value">
            {{ taskDetail.showTaskCode }}
            <text v-if="taskDetail.isHeadPush === '1'" class="head-push-tag">总</text>
          </view>
        </view>
        <view class="info-item">
          <view class="label">任务类型</view>
@@ -1461,6 +1464,17 @@
      }
    }
    
    // 总部推送标记样式
    .head-push-tag {
      color: #ff0000;
      font-size: 24rpx;
      font-weight: bold;
      margin-left: 10rpx;
      padding: 2rpx 8rpx;
      border: 1rpx solid #ff0000;
      border-radius: 4rpx;
    }
    .detail-content {
      padding: 20rpx;
      height: calc(100vh - 220rpx); // 减去header(100rpx)和按钮区域(120rpx)的高度
ruoyi-common/src/main/java/com/ruoyi/common/utils/DeptUtil.java
@@ -1,5 +1,7 @@
package com.ruoyi.common.utils;
import java.util.Map;
public class DeptUtil {
    /**
@@ -10,4 +12,14 @@
     * 广州总部部门ID
     */
    public static Long GUANGZHOU_DEPT_ID=101L;
    private static final Map<Long,Long> deptIdBranchIdMap=new java.util.HashMap<>();
    public static void setDeptIdBranchId(Long deptId,Long branchId){
        deptIdBranchIdMap.put(deptId, branchId);
    }
    public static Long getBranchId(Long deptId) {
        return deptIdBranchIdMap.get(deptId);
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/UserUtil.java
New file
@@ -0,0 +1,21 @@
package com.ruoyi.common.utils;
import java.util.HashMap;
import java.util.Map;
public class UserUtil {
    /**
     * 用户ID和分公司ID的映射关系
     */
    private static final Map<Long,Long> userIdBranchMap = new HashMap<>();
    public static void addUserIdBranch(Long userId,Long branchId){
        if(userId != null && branchId != null && !userIdBranchMap.containsKey(userId)) {
            userIdBranchMap.put(userId, branchId);
        }
    }
    public static Long getBranchIdByUserId(Long userId){
        return userIdBranchMap.get(userId);
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTask.java
@@ -32,6 +32,18 @@
    @Excel(name = "任务状态", readConverterExp = "PENDING=待开始,IN_PROGRESS=任务中,COMPLETED=已完成,CANCELLED=已取消")
    private String taskStatus;
    /** 是否总部推送 */
    @Excel(name = "是否总部推送", readConverterExp = "0=否,1=是")
    private String isHeadPush;
    public void setIsHeadPush(String isHeadPush) {
        this.isHeadPush = isHeadPush;
    }
    public String getIsHeadPush() {
        return isHeadPush;
    }
    /** 任务描述 */
    @Excel(name = "任务描述")
    private String taskDescription;
@@ -88,6 +100,8 @@
    @Excel(name = "创建人ID")
    private Long creatorId;
    /** 执行人ID */
    @Excel(name = "执行人ID")
    private Long assigneeId;
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java
@@ -134,6 +134,14 @@
     * @return 分公司列表
     */
    public List<SysDept> computeBranchCompaniesForUser(SysUser user);
    /**
     * 根据用户ID查询所属分公司 ID
     * @param deptId 用户ID
     * @return 分公司信息
     */
    public Long getBranchCompany(Long deptId);
    
    /**
     * 根据service_class查询部门信息
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTaskService.java
@@ -20,6 +20,14 @@
public interface ISysTaskService {
    public Boolean dispatchSyncEvent(Long taskId);
    /**
     * 判断任务是否总部推送
     * @param taskCreatorId
     * @param taskDeptId
     * @return
     */
    public Boolean isTaskHeaderPush(Long taskCreatorId,Long taskDeptId);
    /**
     * 查询任务管理
     * 
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
@@ -202,6 +202,12 @@
    public int resetPwd(SysUser user);
    /**
     * 通过用户ID查询用户所属公司ID
     * @param userId
     * @return
     */
    public Long getBranchCompanyIdByUserId(Long userId);
    /**
     * 重置用户密码
     * 
     * @param userName 用户名
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java
@@ -3,6 +3,7 @@
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.LongUtil;
import com.ruoyi.common.utils.MapValueUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysTaskEmergency;
@@ -257,8 +258,14 @@
            }
            SysDept dept=sysDeptService.selectDeptByServiceClass(serviceOrdClass);
            Long deptId=dept==null?null:dept.getDeptId();
            if(deptId==null){
                log.error("创建任务时,获取部门信息失败,serviceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID);
                return false;
            }
            createTaskVo.setDeptId(deptId);
            TaskUpdateVO updateTaskVo = new TaskUpdateVO();
            BeanUtils.copyProperties(createTaskVo, updateTaskVo);
//            log.info("开始保存转运任务,serviceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID);
            int result = sysTaskService.updateTask(updateTaskVo,serviceOrdID,dispatchOrdID, serviceOrdNo, taskCreatorId,createUserName, deptId, ServiceOrd_CC_Time, ServiceOrd_CC_Time);
@@ -334,6 +341,11 @@
            String createUserName= sysUser.getUserName();
            SysDept dept=sysDeptService.selectDeptByServiceClass(serviceOrdClass);
            Long deptId=dept==null?null:dept.getDeptId();
            if(deptId==null){
                log.error("创建任务时,获取部门信息失败,serviceOrdID={}, DispatchOrdID={} ServiceOrdClass:{}", serviceOrdID, dispatchOrdID, serviceOrdClass);
                return false;
            }
            createTaskVo.setDeptId(deptId);
            int result = sysTaskService.insertTask(createTaskVo,serviceOrdID,dispatchOrdID, serviceOrdNo, taskCreatorId,createUserName, deptId, ServiceOrd_CC_Time, ServiceOrd_CC_Time);
@@ -370,7 +382,7 @@
    public boolean isTransferOrderSynced(Long serviceOrdID, Long dispatchOrdID) {
        try {
            // 检查参数有效性
            if (serviceOrdID == null || serviceOrdID<=0) {
            if (LongUtil.isEmpty(serviceOrdID)) {
                log.warn("服务单ID不能为空");
                return false;
            }
@@ -387,7 +399,7 @@
                log.warn("服务单ID不是有效数字: {}", serviceOrdID);
            }
            
            if (dispatchOrdID>0) {
            if (LongUtil.isNotEmpty(dispatchOrdID)) {
                try {
                    SysTaskEmergency emergency = sysTaskEmergencyMapper.selectByLegacyDispatchOrdId(dispatchOrdID);
                    if (emergency != null) {
@@ -435,7 +447,7 @@
                return null;
            }
            
            if (serviceOrdID==null || serviceOrdID<=0) {
            if (LongUtil.isEmpty(serviceOrdID)) {
                log.error("服务单ID不能为空");
                return null;
            }
@@ -561,7 +573,7 @@
            createTaskVo.setPrice(MapValueUtils.getBigDecimalValue(order, "ServiceOrdTraTxnPrice"));
            // 距离信息需要从其他字段计算或获取
            if(dispatchOrdID!=null) {
            if(LongUtil.isNotEmpty(dispatchOrdID)) {
                // 设置执行人信息
                List<TaskCreateVO.AssigneeInfo> assignees = queryAssignees(dispatchOrdID);
                createTaskVo.setAssignees(assignees);
@@ -718,22 +730,16 @@
        long startTime = System.currentTimeMillis();
        try {
            // 检查参数有效性
            if (dispatchOrdID==null || dispatchOrdID <= 0) {
            if (LongUtil.isEmpty(dispatchOrdID)) {
                log.warn("调度单ID不能为空");
                return new ArrayList<>();
            }
            
            // 将String转换为Long,避免数据库类型不匹配导致的性能问题
            Long dispatchOrdIdLong;
            try {
                dispatchOrdIdLong = Long.valueOf(dispatchOrdID);
            } catch (NumberFormatException e) {
                log.error("调度单ID格式不正确: {}", dispatchOrdID, e);
                return new ArrayList<>();
            }
            
            // 从SQL Server查询执行人信息(使用Long类型,匹配BIGINT字段)
            List<Map<String, Object>> assigneeList = legacyTransferSyncMapper.selectAssigneesByDispatchOrdID(dispatchOrdIdLong);
            List<Map<String, Object>> assigneeList = legacyTransferSyncMapper.selectAssigneesByDispatchOrdID(dispatchOrdID);
            long queryTime = System.currentTimeMillis() - startTime;
            
            // 记录慢查询(超过500ms)
@@ -782,7 +788,7 @@
                }
            }
            
            log.debug("查询到{}个执行人,调度单ID: {}, 耗时: {}ms", assignees.size(), dispatchOrdID, System.currentTimeMillis() - startTime);
//            log.debug("查询到{}个执行人,调度单ID: {}, 耗时: {}ms", assignees.size(), dispatchOrdID, System.currentTimeMillis() - startTime);
            return assignees;
        } catch (Exception e) {
            long totalTime = System.currentTimeMillis() - startTime;
@@ -800,7 +806,7 @@
    private String queryDiseaseIds(Long serviceOrdID) {
        try {
            // 检查参数有效性
            if (serviceOrdID==null || serviceOrdID <= 0) {
            if (LongUtil.isEmpty(serviceOrdID) ) {
                log.warn("服务单ID不能为空");
                return null;
            }
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/NotifyDispatchServiceImpl.java
@@ -86,8 +86,8 @@
            return 0;
        }
        log.info("开始分发通知任务,id={}, taskId={}, userId={}, notifyType={}",
                notifyTask.getId(), notifyTask.getTaskId(), notifyTask.getUserId(), notifyTask.getNotifyType());
//        log.info("开始分发通知任务,id={}, taskId={}, userId={}, notifyType={}",
//                notifyTask.getId(), notifyTask.getTaskId(), notifyTask.getUserId(), notifyTask.getNotifyType());
        // 更新状态为处理中
        notifyTaskService.markProcessing(notifyTask.getId());
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
@@ -6,6 +6,8 @@
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import com.ruoyi.common.utils.DeptUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.annotation.DataScope;
@@ -429,6 +431,20 @@
        return result;
    }
    
    @Override
    public Long getBranchCompany(Long deptId) {
       Long branchId = DeptUtil.getBranchId(deptId);
       if(branchId!=null)return branchId;
        branchId = deptMapper.selectBranchCompanyIdByDeptId(deptId);
        if(branchId!=null){
            DeptUtil.setDeptIdBranchId(deptId,branchId);
            return branchId;
        }
        else {
            return null;
        }
    }
    /**
     * 根据service_class查询部门信息
     * 
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java
@@ -8,6 +8,7 @@
import java.net.URL;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.*;
import com.ruoyi.system.domain.vo.*;
@@ -77,8 +78,13 @@
    @Autowired
    private ISysTaskAttachmentService sysTaskAttachmentService;
    @Autowired
    private SysUserMapper sysUserMapper;
    private ISysDeptService deptService;
    @Autowired
    private ISysUserService userService;
    @Autowired(required = false)
    private IMapService mapService;
@@ -98,13 +104,16 @@
    @Override
    public Boolean dispatchSyncEvent(Long taskId) {
        SysTask task= sysTaskMapper.selectSysTaskByTaskId(taskId);
        SysUser user= sysUserMapper.selectUserById(task.getCreatorId());
        SysUser user= userService.selectUserById(task.getCreatorId());
        Integer oaUser=user.getOaUserId();
        SysTaskEmergency emergency = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(taskId);
        eventPublisher.publishEvent(new TaskDispatchSyncEvent(this, taskId, task.getTaskCode(),emergency.getLegacyServiceOrdId(), emergency.getLegacyDispatchOrdId(),oaUser));
        return true;
    }
    private Long getBranchCompanyId(Long userId) {
       return userService.getBranchCompanyIdByUserId(userId);
    }
    /**
     * 查询任务管理
     * 
@@ -115,6 +124,7 @@
    public SysTask selectSysTaskByTaskId(Long taskId) {
        SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId);
        if (task != null) {
            // 加载急救转运扩展信息
            if ("EMERGENCY_TRANSFER".equals(task.getTaskType())) {
                SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(taskId);
@@ -139,12 +149,32 @@
    public List<SysTask> selectSysTaskList(TaskQueryVO queryVO) {
        List<SysTask> tasks= sysTaskMapper.selectSysTaskList(queryVO);
        tasks.forEach(task -> {
            if ("EMERGENCY_TRANSFER".equals(task.getTaskType())) {
                SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(task.getTaskId());
                task.setEmergencyInfo(emergencyInfo);
            }
        });
        return tasks;
    }
    /**
     * 设置任务是总部推送的标记
     * @param taskCreatorId 任务创建人的用户ID
     * @param taskDeptId 任务中的归属机构ID
     */
    @Override
    public Boolean isTaskHeaderPush(Long taskCreatorId,Long taskDeptId){
        if(LongUtil.isEmpty(taskCreatorId))return false;
        if(LongUtil.isEmpty(taskDeptId))return false ;
        Long createrDeptId = getBranchCompanyId(taskCreatorId);
        if(createrDeptId !=null && !taskDeptId.equals(createrDeptId) && createrDeptId.equals(DeptUtil.GUANGZHOU_DEPT_ID)){
            //广州总部推送的任务
           return true;
        }else{
            return false;
        }
    }
    /**
@@ -180,6 +210,7 @@
        // Get all tasks matching the other criteria
        List<SysTask> allTasks = sysTaskMapper.selectSysTaskList(newQuery);
        allTasks.stream().forEach(task -> {
            if ("EMERGENCY_TRANSFER".equals(task.getTaskType())) {
                SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(task.getTaskId());
                task.setEmergencyInfo(emergencyInfo);
@@ -189,6 +220,7 @@
            if (task.getTaskCode() != null && task.getTaskCode().contains(taskCode)) {
                return true;
            }
            if ("EMERGENCY_TRANSFER".equals(task.getTaskType()) && task.getEmergencyInfo() != null) {
                String dispatchCode = task.getEmergencyInfo().getDispatchCode();
                String serviceCode = task.getEmergencyInfo().getServiceCode();
@@ -233,6 +265,8 @@
        task.setUpdateTime(DateUtils.getNowDate());
        task.setRemark(createVO.getRemark());
        task.setDelFlag("0");
        task.setIsHeadPush(isTaskHeaderPush(userId,task.getDeptId())?"1":"0");
        
        // 设置地址和坐标信息
        setAddressAndCoordinatesFromVO(task, createVO);
@@ -336,6 +370,13 @@
        task.setUpdateBy(userName);
        task.setRemark(createVO.getRemark());
        task.setDelFlag("0");
        Boolean isHeadPush=this.isTaskHeaderPush(userId, deptId);
        if(isHeadPush){
            task.setIsHeadPush("1");
        }else{
            task.setIsHeadPush("0");
        }
        
@@ -457,6 +498,8 @@
        task.setUpdateTime(updateVO.getUpdateTime() != null ? updateVO.getUpdateTime() : DateUtils.getNowDate());
        task.setRemark(updateVO.getRemark());
        
        // 设置通用地址和坐标信息
        task.setDepartureAddress(updateVO.getDepartureAddress());
        task.setDestinationAddress(updateVO.getDestinationAddress());
@@ -479,13 +522,16 @@
        // 如果更新了部门ID
        if (updateVO.getDeptId() != null) {
            task.setDeptId(updateVO.getDeptId());
        }else{
            task.setDeptId(oldTask.getDeptId());
        }
        
        // 如果更新了任务编号
        if (updateVO.getTaskCode() != null) {
            task.setTaskCode(updateVO.getTaskCode());
        }
        //设置总部推送
        task.setIsHeadPush(this.isTaskHeaderPush(oldTask.getCreatorId(), task.getDeptId())?"1":"0");
        // 自动获取出发地GPS坐标(如果更新了地址但缺失坐标)
        if (updateVO.getDepartureAddress() != null && 
            (updateVO.getDepartureLongitude() == null || updateVO.getDepartureLatitude() == null) && 
@@ -533,7 +579,7 @@
            task.setAssigneeName(assigneeInfo.getUserName());
        }
        // 用于跟踪是否需要重新同步(车辆、人员、地址、成交价变更)
        boolean needResync = false;
        boolean needResync = true;
        int result = sysTaskMapper.updateSysTask(task);
        
@@ -585,7 +631,10 @@
                userId, userName);
        }
        if(result > 0 && oldTask.getTaskStatus().equals(TaskStatus.PENDING.getCode()) && updateVO.getAssignees() != null && !updateVO.getAssignees().isEmpty() && dispatchOrderId>0L){
        if(result > 0 && oldTask.getTaskStatus().equals(TaskStatus.PENDING.getCode())
                && updateVO.getAssignees() != null
                && !updateVO.getAssignees().isEmpty()
                && LongUtil.isNotEmpty(dispatchOrderId)){
            this.sendTaskAssigneeEvent(updateVO,oldTask,userId,userName);
        }
@@ -612,11 +661,13 @@
                         Long userId, String userName, Long deptId, Date createTime, Date updateTime) {
//        log.info("开始更新任务 ServiceOrdID: {} , dispatchOrdId:{}", serviceOrderId,dispatchOrderId);
        // 通过旧系统服务单ID查找任务
        // 获取旧任务信息,用于判断地址是否变更
        SysTaskEmergency taskEmergency = sysTaskEmergencyMapper.selectByLegacyServiceOrdId(serviceOrderId);
        Long taskId = taskEmergency.getTaskId();
        SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId);
        updateVO.setTaskId(taskId);
        SysTask task = new SysTask();
        task.setTaskId(taskId);
        if(updateVO.getTaskStatus()!=null){
            task.setTaskStatus(updateVO.getTaskStatus());
        }
@@ -629,6 +680,11 @@
        if(updateVO.getActualEndTime() != null) {
            task.setActualEndTime(updateVO.getActualEndTime());
        }
        if(deptId!=null){
            task.setDeptId(deptId);
        }
//        task.setAssigneeId(updateVO.getAssigneeId());
        task.setUpdateBy(userName);
        task.setUpdateTime(DateUtils.getNowDate());
@@ -636,12 +692,7 @@
        
        // 设置地址和坐标信息
        task.setDepartureAddress(updateVO.getDepartureAddress());
        task.setDestinationAddress(updateVO.getDestinationAddress());
        task.setDepartureLongitude(updateVO.getDepartureLongitude());
        task.setDepartureLatitude(updateVO.getDepartureLatitude());
        task.setDestinationLongitude(updateVO.getDestinationLongitude());
        task.setDestinationLatitude(updateVO.getDestinationLatitude());
        if(updateVO.getAssignees()!=null && !updateVO.getAssignees().isEmpty()){
            TaskCreateVO.AssigneeInfo assigneeInfo= updateVO.getAssignees().get(0);
            task.setAssigneeId(assigneeInfo.getUserId());
@@ -657,12 +708,17 @@
            task.setTaskCode(updateVO.getTaskCode());
        }
        
        // 获取旧任务信息,用于判断地址是否变更
        SysTask oldTask = sysTaskMapper.selectSysTaskByTaskId(taskId);
        
//        task.setDepartureLongitude(updateVO.getDepartureLongitude());
//        task.setDepartureLatitude(updateVO.getDepartureLatitude());
//        task.setDestinationLongitude(updateVO.getDestinationLongitude());
//        task.setDestinationLatitude(updateVO.getDestinationLatitude());
        Boolean modifyOutLongLat = false;
        // 自动获取出发地GPS坐标(如果地址变更且缺失坐标)
        if (oldTask != null && updateVO.getDepartureAddress() != null
            && !updateVO.getDepartureAddress().equals(oldTask.getDepartureAddress())
        if (task != null && updateVO.getDepartureAddress() != null
            && !updateVO.getDepartureAddress().equals(task.getDepartureAddress())
            && (updateVO.getDepartureLongitude() == null || updateVO.getDepartureLatitude() == null)
            && mapService != null) {
            try {
@@ -673,16 +729,23 @@
                if (coords != null) {
                    task.setDepartureLongitude(BigDecimal.valueOf(coords.get("lng")));
                    task.setDepartureLatitude(BigDecimal.valueOf(coords.get("lat")));
                    modifyOutLongLat = true;
//                    log.info("出发地GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                }
            } catch (Exception e) {
                log.error("自动获取出发地GPS坐标失败", e);
            }
        }
        task.setDepartureAddress(updateVO.getDepartureAddress());
        if(!modifyOutLongLat){
            task.setDepartureLongitude(updateVO.getDepartureLongitude());
            task.setDepartureLatitude(updateVO.getDepartureLatitude());
        }
        
        Boolean modifyInLongLat = false;
        // 自动获取目的地GPS坐标(如果地址变更且缺失坐标)
        if (oldTask != null && updateVO.getDestinationAddress() != null
            && !updateVO.getDestinationAddress().equals(oldTask.getDestinationAddress())
        if (task != null && updateVO.getDestinationAddress() != null
            && !updateVO.getDestinationAddress().equals(task.getDestinationAddress())
            && (updateVO.getDestinationLongitude() == null || updateVO.getDestinationLatitude() == null)
            && mapService != null) {
            try {
@@ -693,11 +756,17 @@
                if (coords != null) {
                    task.setDestinationLongitude(BigDecimal.valueOf(coords.get("lng")));
                    task.setDestinationLatitude(BigDecimal.valueOf(coords.get("lat")));
                    modifyInLongLat = true;
//                    log.info("目的地GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                }
            } catch (Exception e) {
                log.error("自动获取目的地GPS坐标失败", e);
            }
        }
        task.setDestinationAddress(updateVO.getDestinationAddress());
        if(!modifyInLongLat){
            task.setDestinationLongitude(updateVO.getDestinationLongitude());
            task.setDestinationLatitude(updateVO.getDestinationLatitude());
        }
        
        int result = sysTaskMapper.updateSysTask(task);
@@ -745,7 +814,10 @@
            dispatchOrderId = emergency.getLegacyDispatchOrdId();
        }
        if(updateVO.getTaskStatus()!=null && updateVO.getTaskStatus().equals(TaskStatus.PENDING.getCode()) && updateVO.getAssignees()!=null && !updateVO.getAssignees().isEmpty() && dispatchOrderId>0L){
        if(updateVO.getTaskStatus()!=null
                && updateVO.getTaskStatus().equals(TaskStatus.PENDING.getCode())
                && updateVO.getAssignees()!=null && !updateVO.getAssignees().isEmpty()
                && LongUtil.isNotEmpty(dispatchOrderId)){
            this.sendTaskAssigneeEvent(updateVO,task,userId,userName);
        }
@@ -758,7 +830,7 @@
        if(task.getTaskStatus()!=null && task.getTaskStatus().equals(TaskStatus.PENDING.getCode())){
            //如果没有分配人员,且没有调度单,不是广州总公司的就需要发送通知跟进
            if(LongUtil.isEmpty(dispatchOrderId)){
                if(!task.getDeptId().equals(DeptUtil.GUANGZHOU_DEPT_ID) && task.getAssignees().isEmpty()){
                if(!task.getDeptId().equals(DeptUtil.GUANGZHOU_DEPT_ID) && (task.getAssignees()==null  || task.getAssignees().isEmpty())){
                    //发送通知
                    eventPublisher.publishEvent(new TaskOnlyServerOrderSyncEvent(this, taskId, taskCode));
@@ -1112,6 +1184,7 @@
    public List<SysTask> selectMyTasks(Long userId) {
        List<SysTask> list = sysTaskMapper.selectMyTasks(userId);
        list.stream().forEach(task -> {
            if(task.getTaskType().equals("EMERGENCY_TRANSFER")){
                task.setEmergencyInfo(sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(task.getTaskId()));
            }
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
@@ -4,6 +4,9 @@
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.Validator;
import com.ruoyi.common.utils.UserUtil;
import com.ruoyi.system.service.ISysDeptService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -60,6 +63,8 @@
    @Autowired
    protected Validator validator;
    @Autowired
    private ISysDeptService sysDeptService;
    /**
     * 根据条件分页查询用户列表
@@ -410,6 +415,24 @@
        return userMapper.updateUser(user);
    }
    @Override
    public Long getBranchCompanyIdByUserId(Long userId) {
        Long branchId=UserUtil.getBranchIdByUserId(userId);
        if(branchId!=null)return branchId;
        SysUser u=userMapper.selectUserById(userId);
        if(u!=null){
            Long deptId= u.getDeptId();
            branchId= sysDeptService.getBranchCompany(deptId);
            if(branchId!=null){
                UserUtil.addUserIdBranch(userId,branchId);
                return branchId;
            }
        }
        return null;
    }
    /**
     * 重置用户密码
     * 
ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml
@@ -35,6 +35,7 @@
        <result property="assigneeName"     column="assignee_name"     />
        <result property="deptName"         column="dept_name"         />
        <result property="vehicleNo"        column="vehicle_no"        />
        <result property="isHeadPush"       column="is_head_push"      />
        <collection property="assignedVehicles" ofType="SysTaskVehicle">
            <result property="id"            column="tv_id"             />
            <result property="taskId"        column="tv_task_id"        />
@@ -57,6 +58,7 @@
               t.planned_start_time, t.planned_end_time,
               t.actual_start_time, t.actual_end_time, t.creator_id, t.assignee_id, t.dept_id,
               t.create_time, t.update_time, t.create_by, t.update_by, t.remark, t.del_flag, t.legacy_synced,
               t.is_head_push,
               u1.nick_name as creator_name, u2.nick_name as assignee_name, d.dept_name,
               (
                   select v2.vehicle_no 
@@ -234,6 +236,7 @@
            <if test="creatorId != null">creator_id,</if>
            <if test="assigneeId != null">assignee_id,</if>
            <if test="deptId != null">dept_id,</if>
            <if test="isHeadPush != null">is_head_push,</if>
            <if test="createTime != null">create_time,</if>
            update_time,
            <if test="createBy != null">create_by,</if>
@@ -260,6 +263,7 @@
            <if test="creatorId != null">#{creatorId},</if>
            <if test="assigneeId != null">#{assigneeId},</if>
            <if test="deptId != null">#{deptId},</if>
            <if test="isHeadPush != null">#{isHeadPush},</if>
            <if test="createTime != null">#{createTime},</if>
            now(),
            <if test="createBy != null">#{createBy},</if>
@@ -289,8 +293,8 @@
            <if test="actualEndTime != null">actual_end_time = #{actualEndTime},</if>
            <if test="creatorId != null">creator_id = #{creatorId},</if>
            <if test="assigneeId != null">assignee_id = #{assigneeId},</if>
            <if test="deptId != null">dept_id = #{deptId},</if>
            <if test="isHeadPush != null">is_head_push = #{isHeadPush},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
            <if test="updateBy != null">update_by = #{updateBy},</if>
            <if test="remark != null">remark = #{remark},</if>
ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -172,6 +172,7 @@
             <if test="status != null and status != ''">status,</if>
             <if test="oaUserId != null">oa_user_id,</if>
             <if test="oaOrderClass != null and oaOrderClass != ''">oa_order_class,</if>
            <if test="canViewAllConsult != null and canViewAllConsult != ''">can_view_all_consult,</if>
             <if test="qyWechatUserId != null and qyWechatUserId != ''">qy_wechat_user_id,</if>
             <if test="qyWechatUpdateTime != null">qy_wechat_update_time,</if>
             <if test="createBy != null and createBy != ''">create_by,</if>
ruoyi-system/src/main/resources/mapper/system/VehicleGpsMapper.xml
@@ -127,7 +127,6 @@
        where vehicle_id = #{vehicleId}
          and collect_time &gt;= #{startTime}
          and collect_time &lt;= #{endTime}
        order by collect_time
    </select>
    <!-- 查询活跃车辆ID(优化:使用GROUP BY替代DISTINCT,提升性能) -->
@@ -135,8 +134,6 @@
        select vehicle_id
        from tb_vehicle_gps
        where collect_time &gt;= #{startTime}
        group by vehicle_id
        order by vehicle_id
    </select>
    
    <!-- 查询未被计算的GPS坐标(优化:使用NOT EXISTS替代LEFT JOIN ... IS NULL) -->
ruoyi-system/src/main/resources/mapper/system/VehicleGpsSegmentMileageMapper.xml
@@ -67,7 +67,6 @@
          AND segment_start_time &lt;= #{endDate}
          AND segment_end_time &gt;= #{startDate}
          AND segment_distance &gt;0
        ORDER BY segment_start_time
    </select>
    
    <!-- 按任务ID查询分段里程列表 -->
sql/add_is_head_push_to_sys_task.sql
New file
@@ -0,0 +1,9 @@
-- 为 sys_task 表添加 is_head_push 字段
-- 用于标记任务是否由总部推送
ALTER TABLE sys_task
ADD COLUMN is_head_push CHAR(1) DEFAULT '0' COMMENT '是否总部推送(0否 1是)';
-- 添加索引以提高查询性能
ALTER TABLE sys_task
ADD INDEX idx_is_head_push (is_head_push);