wlzboy
2025-12-21 f08739f46afe856f60ebb1d21ab23d72947629ed
feat:优化任务搜索查询 app
15个文件已修改
3个文件已添加
1346 ■■■■ 已修改文件
app/pages/index.vue 99 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/task/index.vue 808 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pagesTask/components/DepartmentSelector.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pagesTask/detail.vue 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pagesTask/edit-emergency.vue 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/IntegerUtil.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTask.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTaskEmergency.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TaskCreateVO.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TaskQueryVO.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysEmergencyTaskServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/LegacyTransferSyncMapper.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysTaskEmergencyMapper.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/add_vip_and_hq_fields_to_sys_task_emergency.sql 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/remove_is_head_push_from_sys_task.sql 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/index.vue
@@ -101,7 +101,8 @@
            <view class="task-header">
              <view class="task-title">
                {{ getTaskTypeText(task.type) }} - {{ task.vehicle }}
                <text v-if="task.isHeadPush === '1'" class="head-push-tag">总</text>
                <text v-if="task.emergencyInfo && task.emergencyInfo.serviceOrdVip === '1'" class="vip-tag">VIP</text>
                <text v-if="task.emergencyInfo && task.emergencyInfo.fromHq2Is === '1'" class="hq-tag">广总</text>
              </view>
              <view
                class="task-status"
@@ -127,9 +128,10 @@
              </view>
            </view>
            <!-- 任务编号单独一行 -->
            <!-- 任务编号和开始时间在同一行显示,但分开一些 -->
            <view class="task-code-row">
              <text class="task-code">{{ task.showTaskCode }}</text>
              <text class="task-time">{{ task.startTime }}</text>
            </view>
            <!-- 任务详细信息 -->
@@ -137,18 +139,18 @@
              <view class="info-row">
                <view class="info-item">
                  <view class="label">出发地:</view>
                  <view class="value">{{ task.startLocation }}</view>
                  <view class="value">{{ getStartLocationDisplay(task) }}</view>
                </view>
                <view class="info-item">
                  <view class="label">目的地:</view>
                  <view class="value">{{ task.endLocation }}</view>
                </view>
              </view>
              <view class="info-row">
                <view class="info-item">
                  <view class="label">出发时间:</view>
                  <view class="value">{{ task.startTime }}</view>
                  <view class="label">目的地:</view>
                  <view class="value">{{ getEndLocationDisplay(task) }}</view>
                </view>
              </view>
              <view class="info-row">
                <view class="info-item">
                  <view class="label">执行人员:</view>
                  <view class="value">{{ task.assignee }}</view>
@@ -505,12 +507,8 @@
                type: task.taskType,
                vehicle: vehicleInfo,
                vehicleList: task.assignedVehicles || [],
                startLocation: this.formatAddress(
                  task.departureAddress || task.startLocation || "未设置"
                ),
                endLocation: this.formatAddress(
                  task.destinationAddress || task.endLocation || "未设置"
                ),
                startLocation: task.departureAddress || task.startLocation || "未设置",
                endLocation: task.destinationAddress || task.endLocation || "未设置",
                startTime: task.plannedStartTime
                  ? formatDateTime(task.plannedStartTime, "YYYY-MM-DD HH:mm")
                  : "未设置",
@@ -553,6 +551,33 @@
        return address.substring(0, dashIndex);
      }
      return address;
    },
    // 获取出发地显示内容(转运任务显示转出医院名称)
    getStartLocationDisplay(task) {
      // 如果是转运任务且有emergencyInfo信息
      if (task.taskType === 'EMERGENCY_TRANSFER' && task.emergencyInfo && task.emergencyInfo.hospitalOutName) {
        return task.emergencyInfo.hospitalOutName;
      }
      // 其他情况使用原来的startLocation
      return this.formatAddress(task.startLocation || "未设置");
    },
    // 获取目的地显示内容(转运任务显示转入医院名称或详细地址)
    getEndLocationDisplay(task) {
      // 如果是转运任务且有emergencyInfo信息
      if (task.taskType === 'EMERGENCY_TRANSFER' && task.emergencyInfo) {
        // 优先显示转入医院名称
        if (task.emergencyInfo.hospitalInName) {
          if(task.emergencyInfo.hospitalInName.includes("家中")){
            return task.emergencyInfo.destinationAddress;
          }
          return task.emergencyInfo.hospitalInName;
        }
      }
      // 其他情况使用原来的endLocation
      return this.formatAddress(task.endLocation || "未设置");
    },
    // 转换状态格式(将数据库状态转换为UI使用的状态)
@@ -824,17 +849,6 @@
  * {
    -ms-overflow-style: none; /* IE 10+ */
  }
}
// 总部推送标记样式
.head-push-tag {
  color: #ff0000;
  font-size: 24rpx;
  font-weight: bold;
  margin-left: 10rpx;
  padding: 2rpx 8rpx;
  border: 1rpx solid #ff0000;
  border-radius: 4rpx;
}
// 用户信息区域
@@ -1115,13 +1129,22 @@
          }
        }
        // 任务编号单独一行
        // 任务编号和时间在同一行显示
        .task-code-row {
          margin-bottom: 15rpx;
          padding: 10rpx 0;
          border-bottom: 1rpx dashed #e0e0e0;
          display: flex;
          justify-content: space-between;
          .task-code {
            font-size: 28rpx;
            color: #333;
            font-weight: 500;
            font-family: monospace;
          }
          .task-time {
            font-size: 28rpx;
            color: #333;
            font-weight: 500;
@@ -1220,6 +1243,28 @@
        color: #666;
      }
    }
    .vip-tag {
      display: inline-block;
      padding: 2rpx 8rpx;
      font-size: 20rpx;
      color: #fff;
      background-color: #ff0000;
      border-radius: 4rpx;
      margin-left: 10rpx;
      vertical-align: middle;
    }
    .hq-tag {
      display: inline-block;
      padding: 2rpx 8rpx;
      font-size: 20rpx;
      color: #fff;
      background-color: #5856d6;
      border-radius: 4rpx;
      margin-left: 10rpx;
      vertical-align: middle;
    }
  }
}
</style>
app/pages/task/index.vue
@@ -6,7 +6,10 @@
        <view class="header-title">任务列表</view>
        <view class="header-actions">
          <button class="search-toggle-btn" @click="toggleSearch">
            <uni-icons :type="showSearch ? 'close' : 'search'" size="20"></uni-icons>
            <uni-icons
              :type="showSearch ? 'close' : 'search'"
              size="20"
            ></uni-icons>
          </button>
          <button class="refresh-btn" @click="refreshList">
            <uni-icons type="refresh" size="20"></uni-icons>
@@ -19,9 +22,13 @@
        <view class="search-form">
          <view class="form-item">
            <view class="form-label">任务状态</view>
            <picker mode="selector" :range="statusOptions" @change="onStatusChange">
            <picker
              mode="selector"
              :range="statusOptions"
              @change="onStatusChange"
            >
              <view class="form-input picker-input">
                {{ selectedStatusText || '全部状态' }}
                {{ selectedStatusText || "全部状态" }}
                <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
              </view>
            </picker>
@@ -108,22 +115,60 @@
      
      <scroll-view class="task-list-scroll" scroll-y="true">
        <view class="task-list">
          <view class="task-item" v-for="task in filteredTaskList" :key="task.taskId">
          <view
            class="task-item"
            v-for="task in filteredTaskList"
            :key="task.taskId"
          >
            <view class="task-main" @click="viewTaskDetail(task)">
              <!-- 任务头部:标题和状态标签 -->
              <view class="task-header">
                <view class="task-title">
                  {{ getTaskTypeText(task.taskType) }} - {{ task.vehicle }}
                  <text v-if="task.isHeadPush === '1'" class="head-push-tag">总</text>
                  <text
                    v-if="
                      task.emergencyInfo &&
                      task.emergencyInfo.serviceOrdVip === '1'
                    "
                    class="vip-tag"
                    >VIP</text
                  >
                  <text
                    v-if="
                      task.emergencyInfo && task.emergencyInfo.fromHq2Is === '1'
                    "
                    class="hq-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'">
                <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>
              </view>
              
              <!-- 任务编号单独一行 -->
              <!-- 任务编号和开始时间在同一行显示,但分开一些 -->
              <view class="task-code-row">
                <text class="task-code">{{ task.showTaskCode }}</text>
                <text class="task-time">出发时间:{{ task.startTime }}</text>
              </view>
              
              <!-- 任务详细信息 -->
@@ -131,18 +176,16 @@
                <view class="info-row">
                  <view class="info-item">
                    <view class="label">出发地:</view>
                    <view class="value">{{ task.startLocation }}</view>
                  </view>
                  <view class="info-item">
                    <view class="label">目的地:</view>
                    <view class="value">{{ task.endLocation }}</view>
                    <view class="value">{{ getStartLocationDisplay(task) }}</view>
                  </view>
                </view>
                <view class="info-row">
                  <view class="info-item">
                    <view class="label">出发时间:</view>
                    <view class="value">{{ task.startTime }}</view>
                    <view class="label">目的地:</view>
                    <view class="value">{{ getEndLocationDisplay(task) }}</view>
                  </view>
                </view>
                <view class="info-row">
                  <view class="info-item">
                    <view class="label">执行人员:</view>
                    <view class="value">{{ task.assignee }}</view>
@@ -218,7 +261,10 @@
            <uni-icons type="spinner-cycle" size="20" color="#999"></uni-icons>
            <text>正在加载更多数据...</text>
          </view>
          <view class="load-more no-more" v-else-if="filteredTaskList.length > 0 && !hasMore">
          <view
            class="load-more no-more"
            v-else-if="filteredTaskList.length > 0 && !hasMore"
          >
            <text>没有更多数据了</text>
          </view>
        </view>
@@ -228,15 +274,15 @@
</template>
<script>
  import uniDatetimePicker from '@/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue'
  import { listTask, changeTaskStatus } from '@/api/task'
  import { mapState } from 'vuex'
  import { formatDateTime } from '@/utils/common'
  import { checkTaskCanDepart } from '@/utils/taskValidator'
import uniDatetimePicker from "@/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue";
import { listTask, changeTaskStatus } from "@/api/task";
import { mapState } from "vuex";
import { formatDateTime } from "@/utils/common";
import { checkTaskCanDepart } from "@/utils/taskValidator";
  
  export default {
    components: {
      uniDatetimePicker
    uniDatetimePicker,
    },
    data() {
      return {
@@ -245,16 +291,16 @@
        
        // 查询条件
        searchForm: {
          vehicle: '',
          taskNo: ''
        vehicle: "",
        taskNo: "",
        },
        statusOptions: ['全部状态', '待处理', '处理中', '已完成'],
        statusValues: ['', 'pending', 'processing', 'completed'],
        selectedStatus: '',
        selectedStatusText: '',
        startDate: '',
        endDate: '',
        currentFilter: 'all',
      statusOptions: ["全部状态", "待处理", "处理中", "已完成"],
      statusValues: ["", "pending", "processing", "completed"],
      selectedStatus: "",
      selectedStatusText: "",
      startDate: "",
      endDate: "",
      currentFilter: "all",
        
        // 任务列表
        taskList: [],
@@ -265,143 +311,137 @@
        currentPage: 1,
        pageSize: 10,
        total: 0,
        hasMore: true
      }
      hasMore: true,
    };
    },
    computed: {
      ...mapState({
        currentUser: state => state.user
      currentUser: (state) => state.user,
      }),
      filteredTaskList() {
        let filtered = this.taskList;
        // 应用筛选器
        if (this.currentFilter !== 'all') {
          filtered = filtered.filter(task => {
            if (this.currentFilter === 'pending') return task.taskStatus === 'PENDING';
            if (this.currentFilter === 'processing') return ['DEPARTING', 'ARRIVED', 'RETURNING', 'IN_PROGRESS'].includes(task.taskStatus);
            if (this.currentFilter === 'completed') return task.taskStatus === 'COMPLETED';
            return true;
          });
        }
        // 应用状态筛选
        if (this.selectedStatus) {
          const statusMap = {
            'pending': ['PENDING'],
            'processing': ['DEPARTING', 'ARRIVED', 'RETURNING', 'IN_PROGRESS'],
            'completed': ['COMPLETED']
          }
          const validStatuses = statusMap[this.selectedStatus];
          if (validStatuses) {
            filtered = filtered.filter(task => validStatuses.includes(task.taskStatus));
          }
        }
        // 应用车牌号筛选 - 搜索assignedVehicles数组中的车辆
        if (this.searchForm.vehicle) {
          filtered = filtered.filter(task => {
            // 在车辆列表中查找匹配的车牌号
            if (task.vehicleList && task.vehicleList.length > 0) {
              return task.vehicleList.some(vehicle =>
                vehicle.vehicleNo && vehicle.vehicleNo.includes(this.searchForm.vehicle)
              )
            }
            return false
          });
        }
        // 应用任务编号筛选 - 使用taskCode而不是taskNo
        if (this.searchForm.taskNo) {
          filtered = filtered.filter(task =>
            task.showTaskCode && task.showTaskCode.includes(this.searchForm.taskNo)
          );
        }
        // 应用时间范围筛选
        if (this.startDate) {
          filtered = filtered.filter(task =>
            task.plannedStartTime && task.plannedStartTime >= this.startDate
          );
        }
        if (this.endDate) {
          // 结束日期加一天,以便包含当天的数据
          const end = new Date(this.endDate);
          end.setDate(end.getDate() + 1);
          const endDateStr = end.toISOString().split('T')[0];
          filtered = filtered.filter(task =>
            task.plannedStartTime && task.plannedStartTime < endDateStr
          );
        }
        return filtered;
      }
      // 注意:这里不再进行前端过滤,而是直接返回从服务器加载的数据
      // 实际的筛选将在请求服务器时完成
      return this.taskList;
    },
    },
    onLoad() {
      this.loadTaskList()
    this.loadTaskList();
      
      // 监听任务列表刷新事件
      uni.$on('refreshTaskList', this.handleRefreshEvent)
    uni.$on("refreshTaskList", this.handleRefreshEvent);
    },
    onShow() {
      // 页面显示时刷新列表(从其他页面返回时)
      this.loadTaskList()
    this.loadTaskList();
    },
    onUnload() {
      // 页面销毁时移除事件监听
      uni.$off('refreshTaskList', this.handleRefreshEvent)
    uni.$off("refreshTaskList", this.handleRefreshEvent);
    },
    onPullDownRefresh() {
      this.refreshList()
    this.refreshList();
    },
    // 监听滚动到底部事件
    onReachBottom() {
      if (this.hasMore && !this.loading) {
        this.loadMore()
      this.loadMore();
      }
    },
    methods: {
      // 处理刷新事件
      handleRefreshEvent() {
        console.log('收到刷新任务列表事件')
        this.refreshList()
      console.log("收到刷新任务列表事件");
      this.refreshList();
      },
      
      // 加载任务列表
      loadTaskList() {
        this.loading = true
      this.loading = true;
        // 重置分页参数
        this.currentPage = 1
        this.hasMore = true
        this.taskList = []
      this.currentPage = 1;
      this.hasMore = true;
      this.taskList = [];
        
        // 后端会自动获取当前用户信息,实现综合查询
        // 综合查询:当前用户所在机构任务 + 当前用户创建的任务 + 分配给当前用户的任务
        const queryParams = {
          pageNum: this.currentPage,
          pageSize: this.pageSize,
          orderByColumn: 'create_time',
          isAsc: 'desc'
        orderByColumn: "create_time",
        isAsc: "desc",
      };
      // 根据筛选条件添加状态参数(优先使用顶部tab筛选条件)
      if (this.currentFilter === "pending") {
        queryParams.taskStatus = "PENDING";
      } else if (this.currentFilter === "processing") {
        queryParams.taskStatusList = [
          "DEPARTING",
          "ARRIVED",
          "RETURNING",
          "IN_PROGRESS",
        ].join(",");
      } else if (this.currentFilter === "completed") {
        queryParams.taskStatus = "COMPLETED";
      } else {
        // 如果没有使用顶部tab筛选,则使用查询条件中的状态筛选
        if (this.selectedStatus) {
          const statusMap = {
            pending: "PENDING",
            processing: [
              "DEPARTING",
              "ARRIVED",
              "RETURNING",
              "IN_PROGRESS",
            ].join(","),
            completed: "COMPLETED",
          };
          if (statusMap[this.selectedStatus]) {
            if (
              this.selectedStatus === "pending" ||
              this.selectedStatus === "completed"
            ) {
              queryParams.taskStatus = statusMap[this.selectedStatus];
            } else {
              queryParams.taskStatusList = statusMap[this.selectedStatus];
            }
          }
        }
        }
        
        listTask(queryParams).then(response => {
          this.loading = false
          const data = response.data || response.rows || []
          // 设置总数和是否有更多数据
          this.total = response.total || data.length || 0
          this.hasMore = data.length === this.pageSize
      if (this.searchForm.vehicle) {
        queryParams.vehicleNo = this.searchForm.vehicle;
      }
          
          this.taskList = data.map(task => {
      if (this.searchForm.taskNo) {
        queryParams.showTaskCode = this.searchForm.taskNo;
      }
      if (this.startDate) {
        queryParams.startDate = this.startDate;
      }
      if (this.endDate) {
        queryParams.endDate = this.endDate;
      }
      listTask(queryParams)
        .then((response) => {
          this.loading = false;
          const data = response.data || response.rows || [];
          // 设置总数和是否有更多数据
          this.total = response.total || data.length || 0;
          this.hasMore = data.length === this.pageSize;
          this.taskList = data.map((task) => {
            // 从assignedVehicles数组中获取车辆信息
            let vehicleInfo = '未分配车辆'
            let vehicleInfo = "未分配车辆";
            if (task.assignedVehicles && task.assignedVehicles.length > 0) {
              // 如果有多个车辆,显示第一个,并标注数量
              const firstVehicle = task.assignedVehicles[0]
              vehicleInfo = firstVehicle.vehicleNo || '未知车牌'
              const firstVehicle = task.assignedVehicles[0];
              vehicleInfo = firstVehicle.vehicleNo || "未知车牌";
              if (task.assignedVehicles.length > 1) {
                vehicleInfo += ` 等${task.assignedVehicles.length}辆`
                vehicleInfo += ` 等${task.assignedVehicles.length}辆`;
              }
            }
            
@@ -410,48 +450,110 @@
              // 格式化显示字段 - 使用后端返回的assignedVehicles数据
              vehicle: vehicleInfo,
              vehicleList: task.assignedVehicles || [],
              startLocation: this.formatAddress(task.departureAddress || task.startLocation || '未设置'),
              endLocation: this.formatAddress(task.destinationAddress || task.endLocation || '未设置'),
              startTime: task.plannedStartTime ? formatDateTime(task.plannedStartTime, 'YYYY-MM-DD HH:mm') : '未设置',
              assignee: task.assigneeName || '未分配'
            }
              startLocation: this.formatAddress(
                task.departureAddress || task.startLocation || "未设置"
              ),
              endLocation: this.formatAddress(
                task.destinationAddress || task.endLocation || "未设置"
              ),
              startTime: task.plannedStartTime
                ? formatDateTime(task.plannedStartTime, "YYYY-MM-DD HH:mm")
                : "未设置",
              assignee: task.assigneeName || "未分配",
            };
          });
          })
        }).catch(error => {
          this.loading = false
          console.error('加载任务列表失败:', error)
          this.$modal.showToast('加载任务列表失败')
        })
        .catch((error) => {
          this.loading = false;
          console.error("加载任务列表失败:", error);
          this.$modal.showToast("加载任务列表失败");
        });
      },
      
      // 加载更多数据
      loadMore() {
        if (!this.hasMore || this.loading) return
      if (!this.hasMore || this.loading) return;
        
        this.loading = true
        this.currentPage++
      this.loading = true;
      this.currentPage++;
        
        const queryParams = {
          pageNum: this.currentPage,
          pageSize: this.pageSize,
          orderByColumn: 'create_time',
          isAsc: 'desc'
        orderByColumn: "create_time",
        isAsc: "desc",
      };
      // 根据筛选条件添加状态参数(优先使用顶部tab筛选条件)
      if (this.currentFilter === "pending") {
        queryParams.taskStatus = "PENDING";
      } else if (this.currentFilter === "processing") {
        queryParams.taskStatusList = [
          "DEPARTING",
          "ARRIVED",
          "RETURNING",
          "IN_PROGRESS",
        ].join(",");
      } else if (this.currentFilter === "completed") {
        queryParams.taskStatus = "COMPLETED";
      } else {
        // 如果没有使用顶部tab筛选,则使用查询条件中的状态筛选
        if (this.selectedStatus) {
          const statusMap = {
            pending: "PENDING",
            processing: [
              "DEPARTING",
              "ARRIVED",
              "RETURNING",
              "IN_PROGRESS",
            ].join(","),
            completed: "COMPLETED",
          };
          if (statusMap[this.selectedStatus]) {
            if (
              this.selectedStatus === "pending" ||
              this.selectedStatus === "completed"
            ) {
              queryParams.taskStatus = statusMap[this.selectedStatus];
            } else {
              queryParams.taskStatusList = statusMap[this.selectedStatus];
            }
          }
        }
        }
        
        listTask(queryParams).then(response => {
          this.loading = false
          const data = response.data || response.rows || []
          // 更新是否有更多数据
          this.hasMore = data.length === this.pageSize
      if (this.searchForm.vehicle) {
        queryParams.vehicleNo = this.searchForm.vehicle;
      }
          
          const newTasks = data.map(task => {
      if (this.searchForm.taskNo) {
        queryParams.showTaskCode = this.searchForm.taskNo;
      }
      if (this.startDate) {
        queryParams.startDate = this.startDate;
      }
      if (this.endDate) {
        queryParams.endDate = this.endDate;
      }
      listTask(queryParams)
        .then((response) => {
          this.loading = false;
          const data = response.data || response.rows || [];
          // 更新是否有更多数据
          this.hasMore = data.length === this.pageSize;
          const newTasks = data.map((task) => {
            // 从assignedVehicles数组中获取车辆信息
            let vehicleInfo = '未分配车辆'
            let vehicleInfo = "未分配车辆";
            if (task.assignedVehicles && task.assignedVehicles.length > 0) {
              // 如果有多个车辆,显示第一个,并标注数量
              const firstVehicle = task.assignedVehicles[0]
              vehicleInfo = firstVehicle.vehicleNo || '未知车牌'
              const firstVehicle = task.assignedVehicles[0];
              vehicleInfo = firstVehicle.vehicleNo || "未知车牌";
              if (task.assignedVehicles.length > 1) {
                vehicleInfo += ` 等${task.assignedVehicles.length}辆`
                vehicleInfo += ` 等${task.assignedVehicles.length}辆`;
              }
            }
            
@@ -460,32 +562,65 @@
              // 格式化显示字段 - 使用后端返回的assignedVehicles数据
              vehicle: vehicleInfo,
              vehicleList: task.assignedVehicles || [],
              startLocation: this.formatAddress(task.departureAddress || task.startLocation || '未设置'),
              endLocation: this.formatAddress(task.destinationAddress || task.endLocation || '未设置'),
              startTime: task.plannedStartTime ? formatDateTime(task.plannedStartTime, 'YYYY-MM-DD HH:mm') : '未设置',
              assignee: task.assigneeName || '未分配'
            }
          })
              startLocation: this.formatAddress(
                task.departureAddress || task.startLocation || "未设置"
              ),
              endLocation: this.formatAddress(
                task.destinationAddress || task.endLocation || "未设置"
              ),
              startTime: task.plannedStartTime
                ? formatDateTime(task.plannedStartTime, "YYYY-MM-DD HH:mm")
                : "未设置",
              assignee: task.assigneeName || "未分配",
            };
          });
          
          // 将新数据追加到现有列表中
          this.taskList = [...this.taskList, ...newTasks]
        }).catch(error => {
          this.loading = false
          this.currentPage-- // 出错时回退页码
          console.error('加载更多任务失败:', error)
          this.$modal.showToast('加载更多任务失败')
          this.taskList = [...this.taskList, ...newTasks];
        })
        .catch((error) => {
          this.loading = false;
          this.currentPage--; // 出错时回退页码
          console.error("加载更多任务失败:", error);
          this.$modal.showToast("加载更多任务失败");
        });
      },
      
      // 格式化地址 - 只显示-前面的部分
      formatAddress(address) {
        if (!address) return '未设置'
      if (!address) return "未设置";
        // 如果地址包含-,只返回-前面的部分
        const dashIndex = address.indexOf('-')
      const dashIndex = address.indexOf("-");
        if (dashIndex > 0) {
          return address.substring(0, dashIndex)
        return address.substring(0, dashIndex);
        }
        return address
      return address;
    },
    // 获取出发地显示内容(转运任务显示转出医院名称)
    getStartLocationDisplay(task) {
      // 如果是转运任务且有emergencyInfo信息
      if (task.taskType === 'EMERGENCY_TRANSFER' && task.emergencyInfo && task.emergencyInfo.hospitalOutName) {
        return task.emergencyInfo.hospitalOutName;
      }
      // 其他情况使用原来的startLocation
      return this.formatAddress(task.startLocation || "未设置");
    },
    // 获取目的地显示内容(转运任务显示转入医院名称或详细地址)
    getEndLocationDisplay(task) {
      // 如果是转运任务且有emergencyInfo信息
      if (task.taskType === 'EMERGENCY_TRANSFER' && task.emergencyInfo) {
        // 优先显示转入医院名称
        if (task.emergencyInfo.hospitalInName) {
          if(task.emergencyInfo.hospitalInName.includes("家中")){
            return task.emergencyInfo.destinationAddress;
          }
          return task.emergencyInfo.hospitalInName;
        }
      }
      // 其他情况使用原来的endLocation
      return this.formatAddress(task.endLocation || "未设置");
      },
      
      // 切换查询界面显示/隐藏
@@ -501,171 +636,197 @@
      
      // 查询
      handleSearch() {
        this.loadTaskList()
        this.$modal.showToast('查询成功');
      this.loadTaskList();
      this.$modal.showToast("查询成功");
        // 查询完成后隐藏查询界面
        this.showSearch = false;
      },
      
      // 重置查询条件
      resetSearch() {
        this.selectedStatus = '';
        this.selectedStatusText = '';
        this.startDate = '';
        this.endDate = '';
        this.searchForm.vehicle = '';
        this.searchForm.taskNo = '';
      this.selectedStatus = "";
      this.selectedStatusText = "";
      this.startDate = "";
      this.endDate = "";
      this.searchForm.vehicle = "";
      this.searchForm.taskNo = "";
      },
      
      // 刷新列表
      refreshList() {
        this.refreshing = true
        this.loadTaskList()
      this.refreshing = true;
      this.loadTaskList();
        setTimeout(() => {
          this.refreshing = false
        this.refreshing = false;
          // this.$modal.showToast('列表已刷新');
          // 停止下拉刷新
          uni.stopPullDownRefresh()
        }, 1000)
        uni.stopPullDownRefresh();
      }, 1000);
      },
      
      // 筛选
      changeFilter(filter) {
        this.currentFilter = filter;
      // 重新加载数据
      this.loadTaskList();
      },
      
      // 查看任务详情
      viewTaskDetail(task) {
        // 防御性检查
        if (!task || !task.taskId) {
          console.error('任务数据无效:', task)
          this.$modal.showToast('任务数据异常')
          return
        console.error("任务数据无效:", task);
        this.$modal.showToast("任务数据异常");
        return;
        }
        
        // 跳转到任务详情页面 - 使用uni.navigateTo
        uni.navigateTo({
          url: `/pagesTask/detail?id=${task.taskId}`
        url: `/pagesTask/detail?id=${task.taskId}`,
        });
      },
      
      // 处理任务操作
      async handleTaskAction(task, action) {
        switch (action) {
          case 'depart':
        case "depart":
            // 出发 -> 状态变为出发中
            // 显示加载提示
            uni.showLoading({
              title: '检查任务状态...'
            title: "检查任务状态...",
            });
            
            try {
              // 调用工具类检查任务是否可以出发(包含基本校验和冲突检查)
              const checkResult = await checkTaskCanDepart(task)
            const checkResult = await checkTaskCanDepart(task);
              
              uni.hideLoading();
              
              console.log('出发检查结果:', checkResult);
              console.log('valid:', checkResult.valid);
              console.log('conflicts:', checkResult.conflicts);
            console.log("出发检查结果:", checkResult);
            console.log("valid:", checkResult.valid);
            console.log("conflicts:", checkResult.conflicts);
              
              if (!checkResult.valid) {
                // 校验失败,显示提示信息并提供跳转选项
                const conflicts = checkResult.conflicts || [];
                const conflictInfo = conflicts.length > 0 ? conflicts[0] : null;
                
                console.log('冲突信息:', conflictInfo);
              console.log("冲突信息:", conflictInfo);
                
                // 如果有冲突任务信息,提供跳转按钮
                if (conflictInfo && conflictInfo.taskId) {
                  console.log('显示带跳转按钮的弹窗,任务ID:', conflictInfo.taskId);
                console.log(
                  "显示带跳转按钮的弹窗,任务ID:",
                  conflictInfo.taskId
                );
                  
                  const conflictTaskId = conflictInfo.taskId;
                  const message = checkResult.message || conflictInfo.message || '存在冲突任务';
                const message =
                  checkResult.message || conflictInfo.message || "存在冲突任务";
                  
                  uni.showModal({
                    title: '提示',
                  title: "提示",
                    content: message,
                    confirmText: '去处理',
                    cancelText: '知道了',
                  confirmText: "去处理",
                  cancelText: "知道了",
                    success: function(res) {
                      console.log('弹窗点击结果:', res);
                    console.log("弹窗点击结果:", res);
                      if (res.confirm) {
                        // 用户点击"现在去处理",跳转到冲突任务详情页
                        console.log('准备跳转到任务详情页:', conflictTaskId);
                      console.log("准备跳转到任务详情页:", conflictTaskId);
                        uni.navigateTo({
                          url: `/pagesTask/detail?id=${conflictTaskId}`
                        url: `/pagesTask/detail?id=${conflictTaskId}`,
                        });
                      }
                    },
                    fail: function(err) {
                      console.error('显示弹窗失败:', err);
                    }
                    console.error("显示弹窗失败:", err);
                  },
                  });
                } else {
                  // 没有冲突任务ID,只显示提示
                  console.log('显示普通提示弹窗');
                console.log("显示普通提示弹窗");
                  uni.showModal({
                    title: '提示',
                    content: checkResult.message || '任务校验失败',
                  title: "提示",
                  content: checkResult.message || "任务校验失败",
                    showCancel: false,
                    confirmText: '知道了',
                  confirmText: "知道了",
                    fail: function(err) {
                      console.error('显示弹窗失败:', err);
                    }
                    console.error("显示弹窗失败:", err);
                  },
                  });
                }
                return;
              }
              
              // 所有检查通过,可以出发
              this.$modal.confirm('确定要出发吗?').then(() => {
                this.updateTaskStatus(task.taskId, 'DEPARTING', '任务已出发')
              }).catch(() => {});
            this.$modal
              .confirm("确定要出发吗?")
              .then(() => {
                this.updateTaskStatus(task.taskId, "DEPARTING", "任务已出发");
              })
              .catch(() => {});
            } catch (error) {
              uni.hideLoading();
              console.error('检查任务状态失败:', error);
            console.error("检查任务状态失败:", error);
              // 检查失败时,仍然允许出发
              this.$modal.confirm('检查任务状态失败,是否继续出发?').then(() => {
                this.updateTaskStatus(task.taskId, 'DEPARTING', '任务已出发')
              }).catch(() => {});
            this.$modal
              .confirm("检查任务状态失败,是否继续出发?")
              .then(() => {
                this.updateTaskStatus(task.taskId, "DEPARTING", "任务已出发");
              })
              .catch(() => {});
            }
            break;
            
          case 'cancel':
        case "cancel":
            // 取消 -> 二次确认后状态变为已取消
            this.$modal.confirm('确定要取消此任务吗?').then(() => {
              this.updateTaskStatus(task.taskId, 'CANCELLED', '任务已取消')
            }).catch(() => {});
          this.$modal
            .confirm("确定要取消此任务吗?")
            .then(() => {
              this.updateTaskStatus(task.taskId, "CANCELLED", "任务已取消");
            })
            .catch(() => {});
            break;
            
          case 'arrive':
        case "arrive":
            // 已到达 -> 状态变为已到达
            this.$modal.confirm('确认已到达目的地?').then(() => {
              this.updateTaskStatus(task.taskId, 'ARRIVED', '已到达目的地')
            }).catch(() => {});
          this.$modal
            .confirm("确认已到达目的地?")
            .then(() => {
              this.updateTaskStatus(task.taskId, "ARRIVED", "已到达目的地");
            })
            .catch(() => {});
            break;
            
          case 'forceCancel':
        case "forceCancel":
            // 强制结束 -> 状态变为已取消
            this.$modal.confirm('确定要强制结束此任务吗?').then(() => {
              this.updateTaskStatus(task.taskId, 'CANCELLED', '任务已强制结束')
            }).catch(() => {});
          this.$modal
            .confirm("确定要强制结束此任务吗?")
            .then(() => {
              this.updateTaskStatus(task.taskId, "CANCELLED", "任务已强制结束");
            })
            .catch(() => {});
            break;
            
          case 'return':
        case "return":
            // 已返程 -> 状态变为返程中
            this.$modal.confirm('确认开始返程?').then(() => {
              this.updateTaskStatus(task.taskId, 'RETURNING', '已开始返程')
            }).catch(() => {});
          this.$modal
            .confirm("确认开始返程?")
            .then(() => {
              this.updateTaskStatus(task.taskId, "RETURNING", "已开始返程");
            })
            .catch(() => {});
            break;
            
          case 'complete':
        case "complete":
            // 已完成 -> 状态变为已完成
            this.$modal.confirm('确认任务已完成?').then(() => {
              this.updateTaskStatus(task.taskId, 'COMPLETED', '任务已完成')
            }).catch(() => {});
          this.$modal
            .confirm("确认任务已完成?")
            .then(() => {
              this.updateTaskStatus(task.taskId, "COMPLETED", "任务已完成");
            })
            .catch(() => {});
            break;
        }
      },
@@ -673,106 +834,115 @@
      // 更新任务状态
      updateTaskStatus(taskId, status, remark) {
        // 获取GPS位置信息
        this.getLocationAndUpdateStatus(taskId, status, remark)
      this.getLocationAndUpdateStatus(taskId, status, remark);
      },
      
      // 获取位置信息并更新状态
      getLocationAndUpdateStatus(taskId, status, remark) {
        const that = this
      const that = this;
        
        // 使用uni.getLocation获取GPS位置
        uni.getLocation({
          type: 'gcj02',
        type: "gcj02",
          geocode: true,
          altitude: true,
          success: function(res) {
            console.log('GPS定位成功:', res)
          console.log("GPS定位成功:", res);
            
            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 || '' : '',
            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
            }
            heading: res.direction || res.heading,
          };
            
            changeTaskStatus(taskId, statusData).then(response => {
              that.$modal.showToast('状态更新成功')
          changeTaskStatus(taskId, statusData)
            .then((response) => {
              that.$modal.showToast("状态更新成功");
              // 刷新任务列表
              that.loadTaskList()
            }).catch(error => {
              console.error('更新任务状态失败:', error)
              that.$modal.showToast('状态更新失败,请重试')
              that.loadTaskList();
            })
            .catch((error) => {
              console.error("更新任务状态失败:", error);
              that.$modal.showToast("状态更新失败,请重试");
            });
          },
          fail: function(err) {
            console.error('GPS定位失败:', err)
          console.error("GPS定位失败:", err);
            
            that.$modal.confirm('GPS定位失败,是否继续更新状态?').then(() => {
          that.$modal
            .confirm("GPS定位失败,是否继续更新状态?")
            .then(() => {
              const statusData = {
                taskStatus: status,
                remark: remark
              }
                remark: remark,
              };
              
              changeTaskStatus(taskId, statusData).then(response => {
                that.$modal.showToast('状态更新成功')
              changeTaskStatus(taskId, statusData)
                .then((response) => {
                  that.$modal.showToast("状态更新成功");
                // 刷新任务列表
                that.loadTaskList()
              }).catch(error => {
                console.error('更新任务状态失败:', error)
                that.$modal.showToast('状态更新失败,请重试')
                  that.loadTaskList();
              })
            }).catch(() => {})
          }
                .catch((error) => {
                  console.error("更新任务状态失败:", error);
                  that.$modal.showToast("状态更新失败,请重试");
                });
        })
            .catch(() => {});
        },
      });
      },
      
      getStatusText(status) {
        const statusMap = {
          'PENDING': '待处理',
          'DEPARTING': '出发中',
          'ARRIVED': '已到达',
          'RETURNING': '返程中',
          'COMPLETED': '已完成',
          'CANCELLED': '已取消',
          'IN_PROGRESS': '处理中' // 兼容旧数据
        }
        return statusMap[status] || '未知'
        PENDING: "待处理",
        DEPARTING: "出发中",
        ARRIVED: "已到达",
        RETURNING: "返程中",
        COMPLETED: "已完成",
        CANCELLED: "已取消",
        IN_PROGRESS: "处理中", // 兼容旧数据
      };
      return statusMap[status] || "未知";
      },
      
      // 获取状态样式类
      getStatusClass(status) {
        const statusClassMap = {
          'PENDING': 'status-pending',
          'DEPARTING': 'status-departing',
          'ARRIVED': 'status-arrived',
          'RETURNING': 'status-returning',
          'COMPLETED': 'status-completed',
          'CANCELLED': 'status-cancelled',
          'IN_PROGRESS': 'status-in-progress'
        }
        return statusClassMap[status] || 'status-default'
        PENDING: "status-pending",
        DEPARTING: "status-departing",
        ARRIVED: "status-arrived",
        RETURNING: "status-returning",
        COMPLETED: "status-completed",
        CANCELLED: "status-cancelled",
        IN_PROGRESS: "status-in-progress",
      };
      return statusClassMap[status] || "status-default";
      },
      
      getTaskTypeText(type) {
        const typeMap = {
          'MAINTENANCE': '维修保养',
          'FUEL': '加油',
          'OTHER': '其他',
          'EMERGENCY_TRANSFER': '转运任务',
          'WELFARE': '福祉车'
        }
        return typeMap[type] || '未知类型'
      }
    }
  }
        MAINTENANCE: "维修保养",
        FUEL: "加油",
        OTHER: "其他",
        EMERGENCY_TRANSFER: "转运任务",
        WELFARE: "福祉车",
      };
      return typeMap[type] || "未知类型";
    },
  },
};
</script>
<style lang="scss">
@@ -801,17 +971,6 @@
    }
  }
  
  // 总部推送标记样式
  .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;
@@ -838,7 +997,8 @@
    .header-actions {
      display: flex;
      
      .search-toggle-btn, .refresh-btn {
    .search-toggle-btn,
    .refresh-btn {
        width: 60rpx;
        height: 60rpx;
        border-radius: 50%;
@@ -913,7 +1073,8 @@
      display: flex;
      margin-top: 20rpx;
      
      .search-btn, .reset-btn {
    .search-btn,
    .reset-btn {
        flex: 1;
        height: 70rpx;
        border-radius: 10rpx;
@@ -922,7 +1083,7 @@
      }
      
      .search-btn {
        background-color: #007AFF;
      background-color: #007aff;
        color: white;
      }
    }
@@ -962,7 +1123,7 @@
        font-size: 28rpx;
        
        &.active {
          background-color: #007AFF;
        background-color: #007aff;
          color: white;
        }
      }
@@ -1032,7 +1193,7 @@
            // 出发中 - 蓝色
            &.status-departing {
              background-color: #e3f2fd;
              color: #007AFF;
            color: #007aff;
            }
            
            // 已到达 - 紫色
@@ -1050,7 +1211,7 @@
            // 已完成 - 绿色
            &.status-completed {
              background-color: #e8f5e9;
              color: #34C759;
            color: #34c759;
            }
            
            // 已取消 - 灰色
@@ -1062,7 +1223,7 @@
            // 处理中 (兼容旧数据) - 蓝色
            &.status-in-progress {
              background-color: #e3f2fd;
              color: #007AFF;
            color: #007aff;
            }
            
            // 默认样式
@@ -1073,13 +1234,22 @@
          }
        }
        
        // 任务编号单独一行
      // 任务编号和时间在同一行显示
        .task-code-row {
          margin-bottom: 15rpx;
          padding: 10rpx 0;
          border-bottom: 1rpx dashed #e0e0e0;
        display: flex;
        justify-content: space-between;
          
          .task-code {
          font-size: 28rpx;
          color: #333;
          font-weight: 500;
          font-family: monospace;
        }
        .task-time {
            font-size: 28rpx;
            color: #333;
            font-weight: 500;
@@ -1131,7 +1301,7 @@
          color: #333;
          
          &.primary {
            background-color: #007AFF;
          background-color: #007aff;
            color: white;
          }
          
@@ -1178,5 +1348,27 @@
        color: #666;
      }
    }
  .vip-tag {
    display: inline-block;
    padding: 2rpx 8rpx;
    font-size: 20rpx;
    color: #fff;
    background-color: #ff0000;
    border-radius: 4rpx;
    margin-left: 10rpx;
    vertical-align: middle;
  }
  .hq-tag {
    display: inline-block;
    padding: 2rpx 8rpx;
    font-size: 20rpx;
    color: #fff;
    background-color: #5856d6;
    border-radius: 4rpx;
    margin-left: 10rpx;
    vertical-align: middle;
  }
  }
</style>
app/pagesTask/components/DepartmentSelector.vue
@@ -227,3 +227,4 @@
    }
  }
}
</style>
app/pagesTask/detail.vue
@@ -14,7 +14,8 @@
          <view class="label">任务编号</view>
          <view class="value">
            {{ taskDetail.showTaskCode }}
            <text v-if="taskDetail.isHeadPush === '1'" class="head-push-tag">总</text>
            <text v-if="taskDetail.emergencyInfo && taskDetail.emergencyInfo.serviceOrdVip === '1'" class="vip-tag">VIP</text>
            <text v-if="taskDetail.emergencyInfo && taskDetail.emergencyInfo.fromHq2Is === '1'" class="hq-tag">广总</text>
          </view>
        </view>
        <view class="info-item">
@@ -54,21 +55,12 @@
              <view class="assignee-role">
                <view 
                  class="role-tag"
                  :class="{
                    'role-driver': assignee.userType === 'driver',
                    'role-doctor': assignee.userType === 'doctor',
                    'role-nurse': assignee.userType === 'nurse'
                  }"
                >
                  :class="{'role-driver': assignee.userType === 'driver','role-doctor': assignee.userType === 'doctor','role-nurse': assignee.userType === 'nurse'}">
                  {{ getUserTypeLabel(assignee.userType) }}
                </view>
                <view 
                  class="ready-badge"
                  :class="{
                    'ready': isAssigneeReady(assignee),
                    'unready': !isAssigneeReady(assignee)
                  }"
                >
                  :class="{'ready': isAssigneeReady(assignee),'unready': !isAssigneeReady(assignee)}">
                  {{ isAssigneeReady(assignee) ? '已就绪' : '未就绪' }}
                </view>
              </view>
@@ -105,13 +97,13 @@
        <view class="section-title">位置信息</view>
        <!-- 转运任务:显示转出/转入医院地址 -->
        <template v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo">
          <view class="info-item" v-if="taskDetail.emergencyInfo.hospitalOutAddress">
          <view class="info-item" v-if="taskDetail.emergencyInfo.hospitalOutName">
            <view class="label">转出医院</view>
            <view class="value">{{ taskDetail.emergencyInfo.hospitalOutAddress }}</view>
            <view class="value">{{ taskDetail.emergencyInfo.hospitalOutName }}</view>
          </view>
          <view class="info-item" v-if="taskDetail.emergencyInfo.hospitalInAddress">
          <view class="info-item" v-if="taskDetail.emergencyInfo.hospitalInName">
            <view class="label">转入医院</view>
            <view class="value">{{ taskDetail.emergencyInfo.hospitalInAddress }}</view>
            <view class="value">{{ taskDetail.emergencyInfo.hospitalInName }}</view>
          </view>
        </template>
        <!-- 福祉车任务:显示接送/目的地址 -->
@@ -499,7 +491,19 @@
        }
        return ['COMPLETED', 'CANCELLED'].includes(this.taskDetail.taskStatus)
      },
      // 显示任务类型
      // 生成执行人员角色标签的类名
      getRoleTagClass() {
        return (userType) => {
          const baseClass = 'role-tag'
          const roleClasses = {
            'driver': 'role-driver',
            'doctor': 'role-doctor',
            'nurse': 'role-nurse'
          }
          return [baseClass, roleClasses[userType] || '']
        }
      },      // 显示任务类型
      displayTaskType() {
        if (!this.taskDetail || !this.taskDetail.taskType) {
          return '未设置'
@@ -594,13 +598,7 @@
        
        getTask(this.taskId).then(response => {
          this.taskDetail = response.data || response
          // 调试:打印返回的数据
          // console.log('任务详情完整数据:', JSON.stringify(this.taskDetail, null, 2))
          // console.log('任务类型字段值:', this.taskDetail.taskType)
          // console.log('任务状态字段值:', this.taskDetail.taskStatus)
          // console.log('出发地址:', this.taskDetail.departureAddress)
          // console.log('目的地址:', this.taskDetail.destinationAddress)
          // console.log('转运任务信息 (emergencyInfo):', this.taskDetail.emergencyInfo)
          
          // 如果是转运任务,加载支付信息
          if (this.taskDetail.taskType === 'EMERGENCY_TRANSFER') {
@@ -1464,17 +1462,6 @@
      }
    }
    
    // 总部推送标记样式
    .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)的高度
@@ -1816,5 +1803,27 @@
        }
      }
    }
    .vip-tag {
      display: inline-block;
      padding: 2rpx 8rpx;
      font-size: 20rpx;
      color: #fff;
      background-color: #ff0000;
      border-radius: 4rpx;
      margin-left: 10rpx;
      vertical-align: middle;
    }
    .hq-tag {
      display: inline-block;
      padding: 2rpx 8rpx;
      font-size: 20rpx;
      color: #fff;
      background-color: #5856d6;
      border-radius: 4rpx;
      margin-left: 10rpx;
      vertical-align: middle;
    }
  }
</style>
app/pagesTask/edit-emergency.vue
@@ -39,6 +39,26 @@
      />
      
      <view class="form-item">
        <view class="form-label required">任务类型</view>
        <picker mode="selector" :range="emergencyTaskTypeOptions" range-key="text" @change="onEmergencyTaskTypeChange">
          <view class="form-input picker-input">
            {{ selectedEmergencyTaskType || '请选择任务类型' }}
            <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
          </view>
        </picker>
      </view>
      <view class="form-item">
        <view class="form-label required">单据类型</view>
        <picker mode="selector" :range="documentTypeOptions" range-key="text" @change="onDocumentTypeChange">
          <view class="form-input picker-input">
            {{ selectedDocumentType || '请选择单据类型' }}
            <uni-icons type="arrowright" size="16" color="#999"></uni-icons>
          </view>
        </picker>
      </view>
      <view class="form-item">
        <view class="form-label required">转运时间</view>
        <uni-datetime-picker 
          v-model="taskForm.transferTime" 
@@ -233,6 +253,7 @@
import { getTask, updateTask } from "@/api/task"
import { tiandituDistanceByAddress } from "@/api/map"
import { calculateTransferPrice } from "@/api/price"
import { getServiceOrdAreaTypes, getServiceOrderTypes } from "@/api/dictionary"
import MapSelector from './components/map-selector.vue'
import VehicleSelector from './components/VehicleSelector.vue'
import OrganizationSelector from './components/OrganizationSelector.vue'
@@ -280,6 +301,17 @@
      departureLatitude: null,
      selectedDiseases: [], // 已选择的病情列表(确保初始化为空数组)
      selectedStaff: [], // 已选择的人员列表(确保初始化为空数组)
      // 任务类型和单据类型相关
      selectedEmergencyTaskType: '', // 选中的任务类型文本
      selectedEmergencyTaskTypeId: null, // 选中的任务类型ID
      selectedDocumentType: '', // 选中的单据类型文本
      selectedDocumentTypeId: null, // 选中的单据类型ID
      pendingTaskTypeId: null, // 等待设置的任务类型ID
      pendingDocumentTypeId: null, // 等待设置的单据类型ID
      emergencyTaskTypes: [], // 任务类型列表(从 SQL Server 动态加载)
      emergencyTaskTypeOptions: [], // 任务类型选项(用于picker显示)
      documentTypes: [], // 单据类型列表
      documentTypeOptions: [], // 单据类型选项(用于picker显示)
      taskForm: {
        transferTime: '',
        patient: {
@@ -326,6 +358,10 @@
    if (options.id) {
      this.taskId = options.id
      this.loadTaskDetail()
      // 加载任务类型数据
      this.loadEmergencyTaskTypes()
      // 加载单据类型数据
      this.loadDocumentTypes()
    } else {
      this.$modal.showToast('任务ID不能为空')
      setTimeout(() => {
@@ -420,6 +456,31 @@
          // 转运距离和价格
          this.taskForm.transferDistance = info.transferDistance ? String(info.transferDistance) : ''
          this.taskForm.price = info.transferPrice ? String(info.transferPrice) : ''
          // 任务类型和单据类型
          if (info.taskTypeId) {
            // 直接设置任务类型,如果选项还未加载完成,则在加载完成后再次设置
            const taskType = this.emergencyTaskTypeOptions.find(option => option.id == info.taskTypeId)
            if (taskType) {
              this.selectedEmergencyTaskType = taskType.text
              this.selectedEmergencyTaskTypeId = taskType.id
            } else {
              // 如果选项还未加载完成,标记需要设置的ID
              this.pendingTaskTypeId = info.taskTypeId
            }
          }
          if (info.documentTypeId) {
            // 直接设置单据类型,如果选项还未加载完成,则在加载完成后再次设置
            const docType = this.documentTypeOptions.find(option => option.id == info.documentTypeId)
            if (docType) {
              this.selectedDocumentType = docType.text
              this.selectedDocumentTypeId = docType.id
            } else {
              // 如果选项还未加载完成,标记需要设置的ID
              this.pendingDocumentTypeId = info.documentTypeId
            }
          }
        } else {
          console.warn('任务详情中没有emergencyInfo字段,尝试从主对象获取数据')
          // 兼容处理:如果emergencyInfo不存在,尝试从主对象获取
@@ -509,6 +570,92 @@
    // 车辆选择变化
    onVehicleChange(vehicle) {
      console.log('选中车辆:', vehicle)
    },
    // 加载任务类型数据(从 SQL Server)
    loadEmergencyTaskTypes() {
      getServiceOrderTypes().then(response => {
        const list = response.data || []
        this.emergencyTaskTypes = list
        this.emergencyTaskTypeOptions = list.map(item => ({
          id: item.vID,
          text: item.vtext
        }))
        // 如果任务详情已加载,设置当前选中的任务类型
        if (this.taskDetail && this.taskDetail.emergencyInfo && this.taskDetail.emergencyInfo.taskTypeId) {
          const currentType = this.emergencyTaskTypeOptions.find(option => option.id == this.taskDetail.emergencyInfo.taskTypeId)
          if (currentType) {
            this.selectedEmergencyTaskType = currentType.text
            this.selectedEmergencyTaskTypeId = currentType.id
          }
        }
        // 检查是否有待设置的任务类型ID
        if (this.pendingTaskTypeId) {
          const pendingType = this.emergencyTaskTypeOptions.find(option => option.id == this.pendingTaskTypeId)
          if (pendingType) {
            this.selectedEmergencyTaskType = pendingType.text
            this.selectedEmergencyTaskTypeId = pendingType.id
            this.pendingTaskTypeId = null
          }
        }
      }).catch(error => {
        console.error('加载任务类型失败:', error)
        this.emergencyTaskTypes = []
        this.emergencyTaskTypeOptions = []
      })
    },
    // 任务类型选择
    onEmergencyTaskTypeChange(e) {
      const index = e.detail.value
      const selected = this.emergencyTaskTypeOptions[index]
      this.selectedEmergencyTaskType = selected.text
      this.selectedEmergencyTaskTypeId = selected.id
    },
    // 加载单据类型数据
    loadDocumentTypes() {
      getServiceOrdAreaTypes().then(response => {
        const list = response.data || []
        this.documentTypes = list
        this.documentTypeOptions = list.map(item => ({
          id: item.vID,
          text: item.vtext
        }))
        // 如果任务详情已加载,设置当前选中的单据类型
        if (this.taskDetail && this.taskDetail.emergencyInfo && this.taskDetail.emergencyInfo.documentTypeId) {
          const currentType = this.documentTypeOptions.find(option => option.id == this.taskDetail.emergencyInfo.documentTypeId)
          if (currentType) {
            this.selectedDocumentType = currentType.text
            this.selectedDocumentTypeId = currentType.id
          }
        }
        // 检查是否有待设置的单据类型ID
        if (this.pendingDocumentTypeId) {
          const pendingType = this.documentTypeOptions.find(option => option.id == this.pendingDocumentTypeId)
          if (pendingType) {
            this.selectedDocumentType = pendingType.text
            this.selectedDocumentTypeId = pendingType.id
            this.pendingDocumentTypeId = null
          }
        }
      }).catch(error => {
        console.error('加载单据类型失败:', error)
        this.documentTypes = []
        this.documentTypeOptions = []
      })
    },
    // 单据类型选择
    onDocumentTypeChange(e) {
      const index = e.detail.value
      const selected = this.documentTypeOptions[index]
      this.selectedDocumentType = selected.text
      this.selectedDocumentTypeId = selected.id
    },
    
    // 加载所有机构ID
@@ -815,6 +962,16 @@
        return false
      }
      
      if (!this.selectedEmergencyTaskType) {
        this.$modal.showToast('请选择任务类型')
        return false
      }
      if (!this.selectedDocumentType) {
        this.$modal.showToast('请选择单据类型')
        return false
      }
      if (!this.taskForm.patient.contact) {
        this.$modal.showToast('请输入联系人')
        return false
@@ -940,6 +1097,9 @@
        deptId: this.selectedOrganizationId,
        vehicleIds: this.selectedVehicleId ? [this.selectedVehicleId] : [],
        plannedStartTime: this.taskForm.transferTime,
        // 任务类型和单据类型
        taskTypeId: this.selectedEmergencyTaskTypeId,
        documentTypeId: this.selectedDocumentTypeId,
        
        // 出发地地址和坐标(使用转出医院地址)
        departureAddress: this.departureAddress || this.taskForm.hospitalOut.address,
@@ -1178,6 +1338,7 @@
    }
  }
}
</script>
<style lang="scss" scoped>
@@ -1390,3 +1551,4 @@
    }
  }
}
</style>
ruoyi-common/src/main/java/com/ruoyi/common/utils/IntegerUtil.java
New file
@@ -0,0 +1,27 @@
package com.ruoyi.common.utils;
import com.sun.org.apache.xpath.internal.operations.Bool;
public class IntegerUtil {
    public static Boolean isInteger(String str) {
        try {
            Integer.parseInt(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    /**
     * 为空或小于0
     * @param integer
     * @return
     */
    public static Boolean isEmpty(Integer integer){
        return integer==null || integer<=0;
    }
    public static Boolean isNotEmpty(Integer integer){
        return !isEmpty(integer);
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTask.java
@@ -32,18 +32,7 @@
    @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;
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTaskEmergency.java
@@ -151,6 +151,12 @@
    /** 旧系统服务单分类 */
    private String legacyServiceOrdClass;
    /** 是否VIP客户(0否 1是) */
    private String serviceOrdVip;
    /** 是否广州总部推送(0否 1是) */
    private String fromHq2Is;
    public String getServiceCode(){
        if(this.legacyServiceOrdClass!=null && this.legacyServiceNsTime!=null && this.legacyServiceOrdNo!=null) {
            String nstime = DateUtils.parseDateToStr(DateUtils.YYYYMMDD, this.legacyServiceNsTime);
@@ -540,6 +546,22 @@
        this.legacyServiceOrdClass = legacyServiceOrdClass;
    }
    public String getServiceOrdVip() {
        return serviceOrdVip;
    }
    public void setServiceOrdVip(String serviceOrdVip) {
        this.serviceOrdVip = serviceOrdVip;
    }
    public String getFromHq2Is() {
        return fromHq2Is;
    }
    public void setFromHq2Is(String fromHq2Is) {
        this.fromHq2Is = fromHq2Is;
    }
    @Override
    public String toString() {
        return "SysTaskEmergency{" +
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TaskCreateVO.java
@@ -141,6 +141,34 @@
    private  String taskStatus;
    private String serviceOrdVIP;
    public String getServiceOrdVIP() {
        if(serviceOrdVIP != null)
        return serviceOrdVIP;
        else {
            return "0";
        }
    }
    public void setServiceOrdVIP(String serviceOrdVIP) {
        this.serviceOrdVIP = serviceOrdVIP;
    }
    /** 旧系统是否来自HQ2 */
    private String FromHQ2_is;
    public String  getFromHQ2_is() {
        if(FromHQ2_is != null)
        return FromHQ2_is;
        else {
            return "0";
        }
    }
    public void setFromHQ2_is(String fromHQ2_is) {
        FromHQ2_is = fromHQ2_is;
    }
    // 执行人员信息内部类
    public static class AssigneeInfo {
        /** 用户ID */
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TaskQueryVO.java
@@ -23,6 +23,9 @@
    /** 任务状态 */
    private String taskStatus;
    /** 任务状态列表 */
    private String taskStatusList;
    /** 车牌号 */
    private String vehicleNo;
@@ -160,4 +163,12 @@
    public void setOverdue(Boolean overdue) {
        this.overdue = overdue;
    }
    public String getTaskStatusList() {
        return taskStatusList;
    }
    public void setTaskStatusList(String taskStatusList) {
        this.taskStatusList = taskStatusList;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java
@@ -2,10 +2,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.common.utils.*;
import com.ruoyi.system.domain.SysTaskEmergency;
import com.ruoyi.system.domain.VehicleInfo;
import com.ruoyi.system.domain.enums.TaskStatus;
@@ -471,8 +468,21 @@
                createTaskVo.setTaskTypeId(serviceOrdType);
            }
            
            // 设置区域类型
            String serviceOrdAreaType = MapValueUtils.getStringValue(order, "ServiceOrdAreaType");
           String serviceOrdVIP = MapValueUtils.getStringValue(order, "ServiceOrdVIP");
           if(serviceOrdVIP!=null){
               createTaskVo.setServiceOrdVIP(serviceOrdVIP);
           }else{
               createTaskVo.setServiceOrdVIP("0");
           }
           Integer FromHQ2_is = MapValueUtils.getIntegerValue(order, "FromHQ2_is");
           if(IntegerUtil.isNotEmpty(FromHQ2_is)){
               createTaskVo.setFromHQ2_is("1");
           }else{
               createTaskVo.setFromHQ2_is("0");
           }
            // 设置用户ID
            Long serviceOrdUserID = MapValueUtils.getLongValue(order, "ServiceOrdUserID");
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysEmergencyTaskServiceImpl.java
@@ -44,6 +44,8 @@
                                  Long serviceOrderId, Long dispatchOrderId, String serviceOrdNo) {
        SysTaskEmergency emergencyInfo = new SysTaskEmergency();
        emergencyInfo.setTaskId(taskId);
        emergencyInfo.setServiceOrdVip(createVO.getServiceOrdVIP());
        emergencyInfo.setFromHq2Is(createVO.getFromHQ2_is());
        if (createVO.getPatient() != null) {
            emergencyInfo.setPatientContact(createVO.getPatient().getContact());
@@ -307,6 +309,9 @@
            oldEmergency.setLegacyServiceOrdClass(updateVO.getLegacyServiceOrdClass());
        }
        oldEmergency.setFromHq2Is(updateVO.getFromHQ2_is());
        oldEmergency.setServiceOrdVip(updateVO.getServiceOrdVIP());
        sysTaskEmergencyMapper.updateSysTaskEmergency(oldEmergency);
    }
@@ -473,6 +478,8 @@
            existingInfo.setLegacyServiceOrdClass(createVO.getLegacyServiceOrdClass());
        }
        
        existingInfo.setServiceOrdVip(createVO.getServiceOrdVIP());
        existingInfo.setFromHq2Is(createVO.getFromHQ2_is());
        // 执行更新
        sysTaskEmergencyMapper.updateSysTaskEmergency(existingInfo);
    }
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java
@@ -256,6 +256,7 @@
        task.setPlannedStartTime(createVO.getPlannedStartTime());
        task.setPlannedEndTime(createVO.getPlannedEndTime());
        task.setAssigneeId(createVO.getAssigneeId());
        task.setCreatorId(userId);
        // 优先使用前端传入的部门ID,如果没有则使用当前用户的部门ID
        task.setDeptId(createVO.getDeptId() != null ? createVO.getDeptId() : SecurityUtils.getDeptId());
@@ -266,7 +267,7 @@
        task.setRemark(createVO.getRemark());
        task.setDelFlag("0");
        task.setIsHeadPush(isTaskHeaderPush(userId,task.getDeptId())?"1":"0");
//        task.setIsHeadPush(isTaskHeaderPush(userId,task.getDeptId())?"1":"0");
        
        // 设置地址和坐标信息
        setAddressAndCoordinatesFromVO(task, createVO);
@@ -371,12 +372,12 @@
        task.setRemark(createVO.getRemark());
        task.setDelFlag("0");
        Boolean isHeadPush=this.isTaskHeaderPush(userId, deptId);
        if(isHeadPush){
            task.setIsHeadPush("1");
        }else{
            task.setIsHeadPush("0");
        }
//        Boolean isHeadPush=this.isTaskHeaderPush(userId, deptId);
//        if(isHeadPush){
//            task.setIsHeadPush("1");
//        }else{
//            task.setIsHeadPush("0");
//        }
        
@@ -519,7 +520,7 @@
        }
        Boolean hasSetDepartureFlag=false;
        //设置总部推送
        task.setIsHeadPush(this.isTaskHeaderPush(task.getCreatorId(), task.getDeptId())?"1":"0");
//        task.setIsHeadPush(this.isTaskHeaderPush(task.getCreatorId(), task.getDeptId())?"1":"0");
        // 自动获取出发地GPS坐标(如果更新了地址但缺失坐标)
        if (updateVO.getDepartureAddress() != null && 
            (updateVO.getDepartureLongitude() == null || updateVO.getDepartureLatitude() == null) && 
ruoyi-system/src/main/resources/mapper/system/LegacyTransferSyncMapper.xml
@@ -46,6 +46,8 @@
        <result property="DispatchOrdState" column="DispatchOrdState" />
        <result property="DispatchOrdNo" column="DispatchOrdNo" />
        <result property="DispatchOrdClass" column="DispatchOrdClass" />
        <result property="ServiceOrdVIP" column="ServiceOrdVIP" />
        <result property="FromHQ2_is" column="FromHQ2_is" />
        <result property="DispatchOrd_NS_Time" column="DispatchOrd_NS_Time" />
    </resultMap>
@@ -63,6 +65,8 @@
            a.ServiceOrdID,
            a.Old_ServiceOrdID_TXT,
            a.ServiceOrdNo,
            a.FromHQ2_is,
            a.ServiceOrdVIP,
            a.ServiceOrdTraVia,
            a.ServiceOrdApptDate,
            a.ServiceOrd_NS_ID,
@@ -115,6 +119,8 @@
            a.ServiceOrdID,
            a.Old_ServiceOrdID_TXT,
            a.ServiceOrdTraVia,
             a.FromHQ2_is,
            a.ServiceOrdVIP,
            a.ServiceOrdNo,
            a.ServiceOrdApptDate,
            a.ServiceOrdUserID,
@@ -165,6 +171,8 @@
        SELECT
        a.ServiceOrdID,
        a.Old_ServiceOrdID_TXT,
        a.FromHQ2_is,
        a.ServiceOrdVIP,
        a.ServiceOrdTraVia,
        a.ServiceOrdNo,
        a.ServiceOrdApptDate,
ruoyi-system/src/main/resources/mapper/system/SysTaskEmergencyMapper.xml
@@ -51,6 +51,8 @@
        <result property="legacyDispatchNsTime"    column="legacy_dispatch_ns_time" />
        <result property="legacyDispatchOrdClass"  column="legacy_dispatch_ord_class" />
        <result property="legacyServiceOrdClass"   column="legacy_service_ord_class" />
        <result property="serviceOrdVip"           column="service_ord_vip"         />
        <result property="fromHq2Is"               column="from_hq2_is"             />
        <result property="createTime"              column="create_time"             />
        <result property="updateTime"              column="update_time"             />
        <result property="createBy"                column="create_by"               />
@@ -65,7 +67,7 @@
               hospital_in_department_id, hospital_in_bed_number, hospital_in_address, hospital_in_longitude, 
               hospital_in_latitude, transfer_distance, transfer_price, passenger_contact, 
               passenger_phone, disease_ids, document_type_id, task_type_id, legacy_service_ord_id, legacy_dispatch_ord_id, 
               sync_status, sync_time, sync_error_msg, dispatch_sync_status, dispatch_sync_time, dispatch_sync_error_msg, need_resync, legacy_service_ord_no, legacy_dispatch_ord_no, legacy_service_ns_time, legacy_dispatch_ns_time, legacy_dispatch_ord_class, legacy_service_ord_class,
               sync_status, sync_time, sync_error_msg, dispatch_sync_status, dispatch_sync_time, dispatch_sync_error_msg, need_resync, legacy_service_ord_no, legacy_dispatch_ord_no, legacy_service_ns_time, legacy_dispatch_ns_time, legacy_dispatch_ord_class, legacy_service_ord_class, service_ord_vip, from_hq2_is,
               create_time, update_time, create_by, update_by
        from sys_task_emergency
    </sql>
@@ -128,6 +130,8 @@
            <if test="legacyDispatchNsTime != null">legacy_dispatch_ns_time,</if>
            <if test="legacyDispatchOrdClass != null">legacy_dispatch_ord_class,</if>
            <if test="legacyServiceOrdClass != null">legacy_service_ord_class,</if>
            <if test="serviceOrdVip != null">service_ord_vip,</if>
            <if test="fromHq2Is != null">from_hq2_is,</if>
            <if test="createTime != null">create_time,</if>
            <if test="updateTime != null">update_time,</if>
            <if test="createBy != null">create_by,</if>
@@ -179,6 +183,8 @@
            <if test="legacyDispatchNsTime != null">#{legacyDispatchNsTime},</if>
            <if test="legacyDispatchOrdClass != null">#{legacyDispatchOrdClass},</if>
            <if test="legacyServiceOrdClass != null">#{legacyServiceOrdClass},</if>
            <if test="serviceOrdVip != null">#{serviceOrdVip},</if>
            <if test="fromHq2Is != null">#{fromHq2Is},</if>
            <if test="createTime != null">#{createTime},</if>
            <if test="updateTime != null">#{updateTime},</if>
            <if test="createBy != null">#{createBy},</if>
@@ -233,6 +239,8 @@
            <if test="legacyDispatchNsTime != null">legacy_dispatch_ns_time = #{legacyDispatchNsTime},</if>
            <if test="legacyDispatchOrdClass != null">legacy_dispatch_ord_class = #{legacyDispatchOrdClass},</if>
            <if test="legacyServiceOrdClass != null">legacy_service_ord_class = #{legacyServiceOrdClass},</if>
            <if test="serviceOrdVip != null">service_ord_vip = #{serviceOrdVip},</if>
            <if test="fromHq2Is != null">from_hq2_is = #{fromHq2Is},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
            <if test="updateBy != null">update_by = #{updateBy},</if>
        </trim>
ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml
@@ -35,7 +35,6 @@
        <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"        />
@@ -58,7 +57,6 @@
               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 
@@ -88,6 +86,11 @@
            <if test="taskCode != null  and taskCode != ''"> and t.task_code like concat('%', #{taskCode}, '%')</if>
            <if test="taskType != null  and taskType != ''"> and t.task_type = #{taskType}</if>
            <if test="taskStatus != null  and taskStatus != ''"> and t.task_status = #{taskStatus}</if>
            <if test="taskStatusList != null and taskStatusList != ''"> and t.task_status in
                <foreach collection="taskStatusList.split(',')" item="status" open="(" separator="," close=")">
                    #{status}
                </foreach>
            </if>
            <if test="vehicleNo != null  and vehicleNo != ''"> and v.vehicle_no like concat('%', #{vehicleNo}, '%')</if>
            <!-- 综合查询:当前用户所在机构 OR 当前用户创建 OR 分配给当前用户 -->
            <if test="(creatorId != null and creatorId != 0) or (assigneeId != null and assigneeId != 0) or (deptId != null and deptId != 0) or (deptIds != null and deptIds.size() > 0)">
@@ -236,7 +239,6 @@
            <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>
@@ -294,7 +296,6 @@
            <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>
sql/add_vip_and_hq_fields_to_sys_task_emergency.sql
New file
@@ -0,0 +1,20 @@
-- ----------------------------
-- 在 sys_task_emergency 表中增加 ServiceOrdVIP 和 FromHQ2_is 字段
-- ServiceOrdVIP:是否VIP客户(0表示非VIP,1表示VIP)
-- FromHQ2_is:是否广州总部推送标记(空或0表示非广州总部推送,1表示广州总部推送)
-- ----------------------------
-- 添加 ServiceOrdVIP 字段
ALTER TABLE sys_task_emergency
ADD COLUMN service_ord_vip CHAR(1) DEFAULT '0' COMMENT '是否VIP客户(0否 1是)';
-- 添加 FromHQ2_is 字段
ALTER TABLE sys_task_emergency
ADD COLUMN from_hq2_is CHAR(1) DEFAULT '0' COMMENT '是否广州总部推送(0否 1是)';
-- 添加索引以提高查询性能
ALTER TABLE sys_task_emergency
ADD INDEX idx_service_ord_vip (service_ord_vip);
ALTER TABLE sys_task_emergency
ADD INDEX idx_from_hq2_is (from_hq2_is);
sql/remove_is_head_push_from_sys_task.sql
New file
@@ -0,0 +1,5 @@
-- 删除 sys_task 表中的 is_head_push 字段
-- 用于移除任务是否由总部推送的标记
ALTER TABLE sys_task
DROP COLUMN is_head_push;