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

任务状态变更GPS定位功能说明

功能概述

在手机端操作任务状态变更时(如出发、到达、返程、完成等),系统会自动获取当前用户的GPS位置信息和地理位置信息,并记录到任务操作日志中。

数据库变更

1. 任务操作日志表新增字段

sys_task_log 表中新增了以下字段用于存储GPS和位置信息:

字段名 类型 说明
latitude DECIMAL(10,6) 纬度
longitude DECIMAL(10,6) 经度
location_address VARCHAR(500) 位置地址(街道或POI名称)
location_province VARCHAR(50) 省份
location_city VARCHAR(50) 城市
location_district VARCHAR(50) 区县
gps_accuracy DECIMAL(10,2) GPS精度(米)
altitude DECIMAL(10,2) 海拔高度(米)
speed DECIMAL(10,2) 速度(米/秒)
heading DECIMAL(10,2) 方向角度(0-360度)

2. 执行数据库脚本

-- 执行此脚本添加GPS位置字段
source sql/add_location_fields.sql

后端实现

1. 实体类修改

SysTaskLog.java - 添加GPS位置信息字段及getter/setter方法

2. Mapper修改

SysTaskLogMapper.xml - 更新SQL语句,支持GPS字段的查询和插入

3. Service层修改

ISysTaskService.java - 新增带GPS位置信息的状态变更方法
java public int changeTaskStatusWithLocation(Long taskId, TaskStatus newStatus, String remark, SysTaskLog locationLog);

SysTaskServiceImpl.java - 实现GPS位置记录逻辑
- 保留原有的 changeTaskStatus 方法(不带GPS信息)
- 新增 changeTaskStatusWithLocation 方法(带GPS信息)
- 修改 recordTaskLog 方法支持GPS信息传递

4. Controller层修改

SysTaskController.java
- ChangeStatusRequest 请求对象新增GPS位置信息字段
- changeTaskStatus 方法自动判断是否包含GPS信息,调用对应的Service方法

前端实现

1. 修改的页面

以下三个页面的任务状态变更功能均已集成GPS定位:

  1. app/pages/task/detail.vue - 任务详情页
  2. app/pages/task/index.vue - 任务列表页
  3. app/pages/index.vue - 首页(运行中任务)

2. 实现逻辑

获取GPS位置信息

使用UniApp的 uni.getLocation API获取GPS信息:

uni.getLocation({
  type: 'gcj02',        // 使用国测局坐标系
  geocode: true,        // 解析地址信息
  altitude: true,       // 获取高度信息
  success: function(res) {
    // GPS定位成功,携带位置信息更新状态
  },
  fail: function(err) {
    // GPS定位失败,提示用户是否继续
  }
})

获取的GPS信息包括

  • 经纬度latitude, longitude
  • 地址信息address.province, address.city, address.district, address.street
  • 定位精度accuracy(米)
  • 海拔高度altitude(米)
  • 移动速度speed(米/秒)
  • 移动方向heading/direction(度)

状态更新流程

  1. 用户点击状态变更按钮(如"出发"、"已到达"等)
  2. 系统弹出二次确认对话框
  3. 用户确认后,自动获取GPS位置信息
  4. 将状态数据和GPS信息一起发送到后端
  5. GPS定位失败时,提示用户是否继续(可选择不带GPS信息更新)

3. 修改的方法

所有页面的 updateTaskStatus 方法统一改为调用 getLocationAndUpdateStatus 方法:

// 更新任务状态
updateTaskStatus(taskId, status, remark) {
  this.getLocationAndUpdateStatus(taskId, status, remark)
},

// 获取位置信息并更新状态
getLocationAndUpdateStatus(taskId, status, remark) {
  const that = this
  
  uni.getLocation({
    type: 'gcj02',
    geocode: true,
    altitude: true,
    success: function(res) {
      // 携带GPS信息更新状态
      const statusData = {
        taskStatus: status,
        remark: remark,
        latitude: res.latitude,
        longitude: res.longitude,
        locationAddress: res.address ? res.address.street || res.address.poiName || '' : '',
        locationProvince: res.address ? res.address.province || '' : '',
        locationCity: res.address ? res.address.city || '' : '',
        locationDistrict: res.address ? res.address.district || '' : '',
        gpsAccuracy: res.accuracy,
        altitude: res.altitude,
        speed: res.speed,
        heading: res.direction || res.heading
      }
      
      changeTaskStatus(taskId, statusData).then(response => {
        that.$modal.showToast('状态更新成功')
        that.loadTaskList()
      })
    },
    fail: function(err) {
      // GPS定位失败,提示用户
      that.$modal.confirm('GPS定位失败,是否继续更新状态?').then(() => {
        // 不带GPS信息更新
      })
    }
  })
}

API接口

请求示例

PUT /task/{taskId}/status
Content-Type: application/json

{
  "taskStatus": "DEPARTING",
  "remark": "任务已出发",
  "latitude": 39.908722,
  "longitude": 116.397496,
  "locationAddress": "东长安街",
  "locationProvince": "北京市",
  "locationCity": "北京市",
  "locationDistrict": "东城区",
  "gpsAccuracy": 15.5,
  "altitude": 45.2,
  "speed": 0.0,
  "heading": 90.5
}

响应示例

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

权限配置

UniApp manifest.json配置

需要在 manifest.json 中添加定位权限:

{
  "mp-weixin": {
    "permission": {
      "scope.userLocation": {
        "desc": "您的位置信息将用于记录任务操作位置"
      }
    }
  },
  "app-plus": {
    "distribute": {
      "android": {
        "permissions": [
          "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
          "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
          "<uses-permission android:name=\"android.permission.ACCESS_LOCATION_EXTRA_COMMANDS\"/>"
        ]
      },
      "ios": {
        "idfa": false,
        "privacyDescription": {
          "NSLocationWhenInUseUsageDescription": "此应用需要获取您的位置信息用于记录任务操作位置"
        }
      }
    }
  }
}

使用场景

此功能适用于所有需要记录操作位置的任务状态变更操作:

  1. 出发(DEPARTING) - 记录出发时的GPS位置
  2. 已到达(ARRIVED) - 记录到达目的地的GPS位置
  3. 返程中(RETURNING) - 记录开始返程时的GPS位置
  4. 已完成(COMPLETED) - 记录任务完成时的GPS位置
  5. 已取消(CANCELLED) - 记录取消任务时的GPS位置

数据查询

查询任务操作日志(含GPS信息)

SELECT 
  log_id, task_id, operation_type, operation_desc,
  operator_name, operation_time,
  latitude, longitude, location_address,
  location_province, location_city, location_district,
  gps_accuracy, altitude, speed, heading
FROM sys_task_log
WHERE task_id = ?
ORDER BY operation_time DESC;

查询特定时间范围内的操作位置

SELECT 
  task_id, operation_type, operator_name, operation_time,
  latitude, longitude, location_address
FROM sys_task_log
WHERE operation_time BETWEEN ? AND ?
  AND latitude IS NOT NULL
  AND longitude IS NOT NULL
ORDER BY operation_time DESC;

注意事项

  1. 用户隐私:在首次使用定位功能时,会请求用户授权位置权限
  2. 定位失败处理:如果GPS定位失败,系统会提示用户是否继续操作(不带GPS信息)
  3. 网络要求:地理编码(逆地理解析)需要网络连接
  4. 坐标系统:使用GCJ-02坐标系(国测局坐标系),适用于国内地图
  5. 精度影响因素
  • 室内定位精度较低
  • 天气、建筑物遮挡会影响精度
  • 移动状态下精度较静止时略低

后续优化建议

  1. 离线定位:支持离线时先缓存GPS信息,联网后再上传
  2. 轨迹记录:可以记录任务执行过程中的完整GPS轨迹
  3. 地图展示:在任务详情页展示操作位置的地图标记
  4. 异常检测:通过GPS位置判断是否存在异常操作(如位置不匹配)
  5. 统计分析:基于GPS数据进行运营分析(如平均响应时间、服务范围等)