sen
2 天以前 7ed2a032d0724e68aec8af940f2ce0023a9f0eb7
ui/car_wx_app/pages/transportation/index.vue
@@ -1,854 +1,503 @@
<template>
    <view class="container">
        <!-- 标题栏 -->
        <Nav :title="formData.name" :customBack="formData.router"></Nav>
  <view class="container">
    <!-- 导航栏 -->
    <Nav :title="pageTitle" custom-back="/pages/beReferred/index" />
        <!-- 基础信息区域 -->
        <view class="info-section">
            <view class="info-item" v-for="(item, index) in infoList" :key="index">
                <view class="item-label">{{ item.label }}</view>
                <view class="item-value" :class="{ status: item.status }">{{ item.value }}</view>
            </view>
        </view>
    <!-- 基础信息 - 使用统一的 InfoSection 组件 -->
    <InfoSection :list="infoList" />
    <!-- 表单区域 -->
    <view class="form-content">
      <view class="form-section">
        <!-- 甩挂表单 -->
        <template v-if="statusStr === '待甩挂'">
          <u--form ref="dropForm" :rules="rules" :model="form" labelPosition="left">
            <!-- 甩挂地址 -->
            <u-form-item borderBottom label=" " labelWidth="0" prop="address">
              <view class="form-row" @click="getLocation">
                <view class="form-label required">
                  <view class="label-icon">
                    <u--image :showLoading="true" src="/static/bt.png" width="18" height="18" />
                  </view>
                  <text class="label-text">甩挂地址</text>
                </view>
                <view class="address-box">
                  <u--text
                    :lines="3"
                    :text="form.address"
                    :placeholder="locationLoading ? '正在获取位置...' : '点击获取当前地址'"
                  />
                  <view class="location-icon">
                    <u-loading-icon v-if="locationLoading" size="20" color="#409eff" />
                    <u-icon v-else name="map-fill" color="#409eff" size="22" />
                  </view>
                </view>
              </view>
            </u-form-item>
            <!-- 甩挂时间 -->
            <u-form-item borderBottom label=" " labelWidth="0" prop="tripTime">
              <view class="form-row">
                <view class="form-label">
                  <u--image :showLoading="true" src="/static/bt.png" width="20" height="20" />
                  <text>甩挂时间</text>
                </view>
                <uni-datetime-picker type="datetime" v-model="form.tripTime" class="flex-1" />
              </view>
            </u-form-item>
        <!-- 上传行程表单 -->
        <view class="form-section" v-if="newForm.statusStr == '待甩挂'">
            <!-- 单选操作按钮组(遍历优化) -->
            <!-- <view class="action-buttons-container">
        <view class="action-buttons-row" v-for="(row, rowIndex) in actionButtonRows" :key="rowIndex">
          <button class="action-btn" v-for="(btn, btnIndex) in row" :key="btnIndex"
            :class="{ selected: selectedAction === btn.dictValue }" @tap="selectAction(btn.dictValue)">
            {{ btn.dictLabel }}
          </button>
        </view>
      </view> -->
            <!-- 凭证上传 -->
            <u-form-item label="凭证" labelWidth="80" :borderBottom="false">
              <u-upload
                :fileList="fileList"
                name="file"
                multiple
                :maxCount="6"
                :maxSize="50 * 1024 * 1024"
                @afterRead="afterRead"
                @delete="deletePic"
                @oversize="overSize"
              />
            </u-form-item>
          </u--form>
          <BottomBar :loading="loading" @submit="submitForm" @advance="goToAdvanceList" />
        </template>
        <!-- 接挂表单 -->
        <template v-if="statusStr === '待接挂'">
          <u--form ref="pickForm" :rules="rules" :model="form" labelPosition="left">
            <!-- 接挂地址 -->
            <u-form-item borderBottom label=" " labelWidth="0" prop="address">
              <view class="form-row" @click="getLocation">
                <view class="form-label required">
                  <view class="label-icon">
                    <u--image :showLoading="true" src="/static/bt.png" width="18" height="18" />
                  </view>
                  <text class="label-text">接挂地址</text>
                </view>
                <view class="address-box">
                  <u--text
                    :lines="3"
                    :text="form.address"
                    :placeholder="locationLoading ? '正在获取位置...' : '点击获取当前地址'"
                  />
                  <view class="location-icon">
                    <u-loading-icon v-if="locationLoading" size="20" color="#409eff" />
                    <u-icon v-else name="map-fill" color="#409eff" size="22" />
                  </view>
                </view>
              </view>
            </u-form-item>
            <u--form ref="uForm" :rules="rules" :model="form" labelPosition="left">
                <u-form-item ref="item1" borderBottom label=" " labelWidth="0" prop="address">
                   <!-- <view style="display: flex; align-items: center; width: 100%;">
                        <view style="display: flex; align-items: center; flex-shrink: 0; margin-right: 10px;">
                            <u--image :showLoading="true" src="/static/bt.png" width="20px" height="20px"></u--image>
                            <text>甩挂地址:</text>
                        </view>
                       <u--input placeholder="请获取甩挂地址" v-model="form.address" suffixIcon="map-fill"
                            @click="getLocation" suffixIconStyle="color: #909399"></u--input>
            <!-- 接挂时间 -->
            <u-form-item borderBottom label=" " labelWidth="0" prop="tripTime">
              <view class="form-row">
                <view class="form-label">
                  <u--image :showLoading="true" src="/static/bt.png" width="20" height="20" />
                  <text>接挂时间</text>
                </view>
                <uni-datetime-picker type="datetime" v-model="form.tripTime" class="flex-1" />
              </view>
            </u-form-item>
                    </view>  -->
                       <view style="display: flex; align-items: flex-start; width: 100%;">
                        <!-- 左侧标签(带必填星号) -->
                        <view
                            style="display: flex; align-items: center; flex-shrink: 0; margin-right: 10px; padding-top: 12rpx;">
                            <u--image :showLoading="true" src="/static/bt.png" width="20px" height="20px"></u--image>
                            <text style="display: flex; align-items: center;">
                                <span style="color: #ff4d4f; margin-right: 4rpx;">*</span> <!-- 红色必填星号 -->
                                甩挂地址:
                            </text>
                        </view>
            <!-- 凭证上传 -->
            <u-form-item label="凭证" labelWidth="80" :borderBottom="false">
              <u-upload
                :fileList="fileList"
                name="file"
                multiple
                :maxCount="6"
                :maxSize="50 * 1024 * 1024"
                @afterRead="afterRead"
                @delete="deletePic"
                @oversize="overSize"
              />
            </u-form-item>
          </u--form>
                        <!-- 右侧文本框+图标(带边框,图标在框内) -->
                        <view style="position: relative; width: 100%; margin-top: 6rpx;" @click="getLocation">
                            <view class="custom-textarea" style="border: 1px solid #e5e5e5;">
                                <u--text :lines="2" :text="form.address"></u--text>
                                <view style="position: absolute; top: 50%; right: 10rpx; transform: translateY(-50%);">
                                    <u-icon name="map-fill" color="#909399" size="24" @click="getLocation"></u-icon>
                                </view>
                            </view>
                        </view>
                    </view>
                </u-form-item>
                <u-form-item ref="item1" borderBottom label=" " labelWidth="0" prop="tripTime">
                    <view style="display: flex; align-items: center; width: 100%;">
                        <view style="display: flex; align-items: center; flex-shrink: 0; margin-right: 10px;">
                            <u--image :showLoading="true" src="/static/bt.png" width="20px" height="20px"></u--image>
                            <text>甩挂时间</text>
                        </view>
                        <uni-datetime-picker type="datetime" v-model="form.tripTime" style="flex: 1;"
                            @change="onDateTimeChange">
                        </uni-datetime-picker>
                    </view>
                </u-form-item>
                <!-- <u-form-item ref="item1" borderBottom label=" " labelWidth="0" prop="odometer">
          <view style="display: flex; align-items: center; width: 100%;">
            <view style="display: flex; align-items: center; flex-shrink: 0; margin-right: 10px;">
              <u--image :showLoading="true" src="/static/bt.png" width="20px" height="20px"></u--image>
              <text>仪表里程(km):</text>
            </view>
            <uni-number-box v-model="form.odometer" @change="changeValue" />
          </view>
        </u-form-item> -->
                <u-form-item ref="item1" borderBottom label=" " labelWidth="0" prop="" :borderBottom="false">
                    <view style="display: flex;align-items: center;"><u--image :showLoading="true" src="/static/bt.png"
                            width="20px" height="20px"></u--image>凭证<span
                            style="color: #c6c0ba;margin-left: 10px;display: inline-block;"></span></view>
                </u-form-item>
                <u-form-item ref="item1" borderBottom label=" " labelWidth="0" prop="fileList" :borderBottom="false">
                    <view style="margin-right: 10px;"></view>
                    <u-upload :fileList="fileList" name="file" multiple :maxCount="6" :maxSize="2 * 1024 * 1024"
                        @afterRead="afterRead" :previewFullImage="true" @delete="deletePic" @oversize="overSize">
                    </u-upload>
                </u-form-item>
            </u--form>
            <view class="bottom-btn-group">
                <u-button class="btn-list" @click="goToAdvanceList" text="垫付列表"></u-button>
                <!-- <u-button class="btn-budget" @click="goToAdvanceBudget" type="success" text="垫付预算"></u-button> -->
                <u-button class="btn-submit" @click="submitForm" type="primary" text="提交"></u-button>
            </view>
        </view>
        <!-- 上报垫付表单 -->
        <view class="form-section" v-if="newForm.statusStr == '待接挂'">
            <u--form ref="uForm" :rules="rules" :model="form" labelPosition="left">
                <u-form-item ref="item1" borderBottom label=" " labelWidth="0" prop="address">
                    <!-- <view style="display: flex; align-items: center; width: 100%;">
                        <view style="display: flex; align-items: center; flex-shrink: 0; margin-right: 10px;">
                            <u--image :showLoading="true" src="/static/bt.png" width="20px" height="20px"></u--image>
                            <text>接挂地址:</text>
                        </view>
                        <view @click="getLocation" style="width: 100%;">
                            <u--input placeholder="请获取甩挂地址" readonly v-model="form.address" suffixIcon="map-fill"
                                suffixIconStyle="color: #909399"></u--input>
                        </view>
                    </view> -->
                    <view style="display: flex; align-items: flex-start; width: 100%;">
                        <!-- 左侧标签(带必填星号) -->
                        <view
                            style="display: flex; align-items: center; flex-shrink: 0; margin-right: 10px; padding-top: 12rpx;">
                            <u--image :showLoading="true" src="/static/bt.png" width="20px" height="20px"></u--image>
                            <text style="display: flex; align-items: center;">
                                <span style="color: #ff4d4f; margin-right: 4rpx;">*</span> <!-- 红色必填星号 -->
                                接挂地址:
                            </text>
                        </view>
                        <!-- 右侧文本框+图标(带边框,图标在框内) -->
                        <view style="position: relative; width: 100%; margin-top: 6rpx;" @click="getLocation">
                            <view class="custom-textarea" style="border: 1px solid #e5e5e5;">
                                <u--text :lines="2" :text="form.address"></u--text>
                                <view style="position: absolute; top: 50%; right: 10rpx; transform: translateY(-50%);">
                                    <u-icon name="map-fill" color="#909399" size="24" @click="getLocation"></u-icon>
                                </view>
                            </view>
                        </view>
                    </view>
                </u-form-item>
                <u-form-item ref="item1" borderBottom label=" " labelWidth="0" prop="tripTime">
                    <view style="display: flex; align-items: center; width: 100%;">
                        <view style="display: flex; align-items: center; flex-shrink: 0; margin-right: 10px;">
                            <u--image :showLoading="true" src="/static/bt.png" width="20px" height="20px"></u--image>
                            <text>接挂时间</text>
                        </view>
                        <uni-datetime-picker type="datetime" v-model="form.tripTime" style="flex: 1;"
                            @change="onDateTimeChange">
                        </uni-datetime-picker>
                    </view>
                </u-form-item>
                <!-- <u-form-item ref="item1" borderBottom label=" " labelWidth="0" prop="odometer">
          <view style="display: flex; align-items: center; width: 100%;">
            <view style="display: flex; align-items: center; flex-shrink: 0; margin-right: 10px;">
              <u--image :showLoading="true" src="/static/bt.png" width="20px" height="20px"></u--image>
              <text>仪表里程(km):</text>
            </view>
            <uni-number-box v-model="form.odometer" @change="changeValue" />
          </view>
        </u-form-item> -->
                <u-form-item ref="item1" borderBottom label=" " labelWidth="0" prop="" :borderBottom="false">
                    <view style="display: flex;align-items: center;"><u--image :showLoading="true" src="/static/bt.png"
                            width="20px" height="20px"></u--image>凭证<span
                            style="color: #c6c0ba;margin-left: 10px;display: inline-block;"></span></view>
                </u-form-item>
                <u-form-item ref="item1" borderBottom label=" " labelWidth="0" prop="fileList" :borderBottom="false">
                    <view style="margin-right: 10px;"></view>
                    <u-upload :fileList="fileList" name="file" multiple :maxCount="6" :maxSize="2 * 1024 * 1024"
                        @afterRead="afterRead" :previewFullImage="true" @delete="deletePic" @oversize="overSize">
                    </u-upload>
                </u-form-item>
            </u--form>
            <view class="bottom-btn-group">
                <u-button class="btn-list" @click="goTravelItinerary" text="行程历史"></u-button>
                <!-- <u-button class="btn-budget" @click="goToAdvanceBudget" type="success" text="垫付预算"></u-button> -->
                <u-button :loading="loading" class="btn-submit"  @click="submitForm" type="primary" text="提交"></u-button>
            </view>
        </view>
          <BottomBar :loading="loading" @submit="submitForm" @history="goTravelItinerary" />
        </template>
      </view>
    </view>
  </view>
</template>
        <!-- 底部按钮 -->
        <view class="btn-group">
          <u-button class="btn-default" @click="goTravelItinerary" text="行程历史" />
          <u-button class="btn-primary" :loading="loading" @click="submitForm" type="primary" text="提交" />
        </view>
      </template>
    </view>
  </view>
</template>
<script>
import { getcarDispatch, getcarType, carUploadTrip, carUploadFinance, carSubmitDropHoo, carSubmitPickHook } from "@/common/examine";
import InfoSection from '@/components/InfoSection/index.vue'
import BottomBar from '@/components/BottomBar/index.vue'
import {
  getcarDispatch,
  getcarType,
  carSubmitDropHoo,
  carSubmitPickHook
} from '@/common/examine'
import { uploadImage } from '@/common/upload'
import config from '@/config'
import amap from '@/common/amap-wx.130.js'
import {navigateTo, PAGES, reLaunch} from '@/common/router'
import store from '@/store'
import {uploadImage} from "@/common/upload";
const INFO_FIELDS = Object.freeze([
  { key: 'dispatchNo', label: '调度单号' },
  { key: 'licensePlate', label: '车牌号' },
  { key: 'transportLine', label: '路线' },
  { key: 'customerName', label: '客户' },
  { key: 'statusStr', label: '当前状态', status: true, default: '待发车' },
  { key: 'latestDeparture', label: '最晚发车时间' }
])
export default {
    data() {
        return {
          mapApiKey: 'fdb2d2e64ffc9254045935d3227d5cd9', // <-- 替换成你的 API Key
          amapPlugin: null,
            formData: {
                name: '',
                router: '',
                id: ''
            },
            fileList: [],
            range: [
  components: { InfoSection, BottomBar },
            ],
            feeTypeList: [],
            cleanedForm: {},
            newForm: {},
            selectedAction: '',
            activeTab: 'upload',
            infoList: [
                { label: '调度单号', value: '' },
                { label: '运输工具号码', value: '' },
                { label: '路线', value: '' },
                { label: '客户', value: '' },
                { label: '当前状态', value: '待发车', status: true },
                { label: '要求最晚发车时间', value: '' }
            ],
            actionButtonRows: [
  data() {
    return {
      // 高德地图配置
      mapApiKey: 'fdb2d2e64ffc9254045935d3227d5cd9',
      amapPlugin: null,
      isHk: false,
            ],
            form: {
                address: '',
                tripTime: '',
                odometer: 0,
                tripType: ''
            },
            rules: {
      // 页面参数
      dispatchId: '',
      statusStr: '',
      pageTitle: '',
                address: [{ required: true, message: '请输入地址', trigger: 'blur' }],
                tripTime: [{ required: true, message: '请选择时间', trigger: 'change' }], // 修改这里
                // odometer: [{ required: true, message: '请输入仪表里程', trigger: 'change' }],
                voucher: [{ required: true, message: '请上传凭证', trigger: 'blur' }]
            },
            isHk: false,
         loading: false
        };
    },
    onLoad(options) {
        this.formData = options;
      this.amapPlugin = new amap.AMapWX({
        key: this.mapApiKey
      });
      this.getLocation();
        // 获取 URL 参数
        if (options.id) {
            this.getList();
        }
    },
    created() {
        // this.getList();
          this.form.tripTime = this.getCurrentDateTime();
    },
    methods: {
        getCurrentDateTime() {
            var now = new Date();
            var year = now.getFullYear();
            var month = (now.getMonth() + 1).toString().padStart(2, '0');
            var day = now.getDate().toString().padStart(2, '0');
            var hour = now.getHours().toString().padStart(2, '0');
            var minute = now.getMinutes().toString().padStart(2, '0');
            var second = now.getSeconds().toString().padStart(2, '0');
            return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second;
        },
        goTravelItinerary() {
            setTimeout(() => {
                uni.$u.route('/pages/travelItinerary/index?id=' + this.formData.id + '&name=' + '上传行程' + '&router=' + '/pages/travelItinerary/index' + '&statusStr=' + this.formData.statusStr);
            }, 1000);
      // 调度信息
      newForm: {},
      infoList: INFO_FIELDS.map(f => ({ ...f, value: f.default || '' })),
        },
        feeTypeChange(e) {
        },
        getList() {
            getcarDispatch(this.formData.id).then((res) => {
                res.statusStr = '待接挂'
                this.newForm = res;
                // 定义字段映射关系
                const fieldMap = {
                    dispatchNo: '调度单号',
                    licensePlate: '运输工具号码',
                    transportLine: '路线',
                    customerName: '客户',
                    statusStr: '当前状态',
                    latestDeparture: '要求最晚发车时间'
                };
                // 遍历 infoList,自动更新 value
                this.infoList = this.infoList.map(item => {
                    const key = Object.keys(fieldMap).find(k => fieldMap[k] === item.label);
                    if (key && res[key] !== undefined) {
                        return { ...item, value: res[key] };
                    }
                    return item;
                });
            }).catch(err => {
                console.error('获取调度信息失败:', err);
            });
            getcarType('trip_type').then((res) => {
                this.actionButtonRows = [res]
            }).catch(err => {
            });
            getcarType('fee_type').then((res) => {
                this.feeTypeList = res
                this.range = res.map(item => ({
                    value: item.dictValue,
                    text: item.dictLabel
                }));
            }).catch(err => {
            });
        },
        switchTab(tab) {
            this.activeTab = tab;
            this.form = {
                address: '',
                tripTime: '',
                odometer: 0,
                tripType: ''
            }
            this.fileList = []
            this.selectedAction = ''
        },
        selectAction(type) {
            // 设置选中的操作类型
            this.selectedAction = type;
            // 同时更新表单中的 tripType 字段
            this.form.tripType = type;
            // wx.showToast({
            //   title: `已选择${type}`,
            //   icon: 'none'
            // });
        },
        maskClick() {
        },
        // 新增图片
        async afterRead(event) {
          console.log(event)
          uploadImage(event.file[0].url,this.isHk).then(res=>{
            console.log(res)
                this.fileList.push(res);
          })
          // console.log(event)
          //   // 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
          //   let lists = [].concat(event.file)
          //   let fileListLen = this.fileList.length
          //   lists.map((item) => {
          //       this.fileList.push({
          //           ...item,
          //           status: 'success',
          //           message: '上传中'
          //       })
          //   })
          //   for (let i = 0; i < lists.length; i++) {
          //
          //       const result = await this.uploadFilePromise(lists[i].url)
          //       let item = this.fileList[fileListLen]
          //       this.fileList.splice(fileListLen, 1, Object.assign(item, {
          //           status: result.status,
          //           message: result.status == 'success' ? '上传成功' : '上传失败',
          //           urls: result.url
          //       }))
          //       fileListLen++
          //   }
        },
        uploadFilePromise(url) {
            const param = {
                filePath: url,
                type: 'images'
            }
            return new Promise((resolve, reject) => {
                // console.log(store.state);
                uni.uploadFile({
                    url: config.host + `app/car/uploadImg`, // 仅为示例,非真实的接口地址
                    filePath: url,
                    name: 'file',
                    header: {
                        "Authorization": store.state.sso_user_token
                    },
                    success: (res) => {
                        if (res.statusCode == 200) {
                            const dataObject = JSON.parse(res.data);
                            resolve({
                                url: config['wms'] + dataObject.fileName,
                                status: 'success'
                            })
                        } else {
                            resolve({
                                url: dataObject.fileName,
                                status: 'failed'
                            })
                        }
                    },
                    fail: (err) => {
                        reject({ status: 'failed' });
                    }
                });
            })
        },
        // 图片大小超出最大允许大小
        overSize(e) {
            uni.$u.toast('上传图片大小不能超过2MB!')
        },
        // 删除图片
        deletePic(event) {
            this.fileList.splice(event.index, 1)
        },
        onDateTimeChange(event) {
            // this.form.workTime = event.detail.value;
        },
        submitForm() {
         if(this.loading){
            return;
         }
            if (this.fileList.length == 0) {
                uni.$u.toast('图片上传不能为空')
                return
            }
         console.log(this.loading);
         this.loading = true;
            this.$refs.uForm.validate().then(res => {
                if (res) {
                    if (this.newForm.statusStr == '待甩挂') {
                        var urls = this.fileList.map(item => item.url).join(',');
                        this.form.voucherUrl = urls
                        this.form.dispatchOrderId = this.newForm.dispatchId
                        this.form.driverId = this.newForm.driverId
                        carSubmitDropHoo(this.form).then((res) => {
                            this.form = {
                                address: '',
                                tripTime: '',
                            }
                            this.fileList = []
                            this.selectedAction = ''
                            if (res == 1) {
                                uni.$u.toast('操作成功')
                            }
                        }).catch(()=>{
                  setTimeout(()=>{
                     this.loading = false
                  },2000)
                  })
                    } else if (this.newForm.statusStr == '待接挂') {
                        var urls = this.fileList.map(item => item.url).join(',');
                        this.form.voucherUrl = urls
                        this.form.dispatchOrderId = this.newForm.dispatchId
                        this.form.driverId = this.newForm.driverId
                        this.cleanedForm = this.cleanFormData({ ...this.form })
                        carSubmitPickHook(this.cleanedForm).then((res) => {
                  setTimeout(()=>{
                     this.loading = false
                  },2000)
                            this.form = {
                                address: '',
                                tripTime: '',
                            }
                            this.cleanedForm = {}
                            this.fileList = []
                            this.selectedAction = ''
                            if (res == 1) {
                                uni.$u.toast('操作成功')
                            }
                        }).catch(()=>{
                  setTimeout(()=>{
                     this.loading = false
                  },2000)
                  })
                    }
                }
            }).catch(errors => {
                uni.$u.toast('校验失败')
            setTimeout(()=>{
               this.loading = false
            },2000)
            })
            this.$forceUpdate();
        },
        changeValue(e) {
        },
        cleanFormData(formData) {
            const cleanedData = {};
            for (const key in formData) {
                if (formData[key] !== '' && formData[key] !== null && formData[key] !== undefined) {
                    cleanedData[key] = formData[key];
                }
            }
            return cleanedData;
        },
        goToAdvanceList() {
            // 使用箭头函数保持 this 上下文
            setTimeout(() => {
                uni.$u.route('/pages/paymentList/index?name=' + '垫付列表' + '&router=' + 'pages/examine/index' + '&id=' + this.formData.id);
            }, 1000);
        },
        // 获取经纬度
        getLocation() {
            wx.getLocation({
                type: 'gcj02',
                success: (res) => {
                    const latitude = res.latitude;
                    const longitude = res.longitude;
                    this.getAddress(latitude, longitude);
                },
                fail: (err) => {
                    console.error('获取位置失败:', err);
                    wx.showToast({ title: '获取位置失败', icon: 'none' });
                }
            });
        },
      getAddress(latitude, longitude) {
        this.amapPlugin.getRegeo({
          location:`${longitude},${latitude}`,
          success: (data) => {
            let datum = data[0];
            if (datum.regeocodeData){
              if (datum.regeocodeData.addressComponent){
                let province = datum.regeocodeData.addressComponent.province;
                this.isHk = province.indexOf("香港") != -1;
              }
            }
            this.form.address  = datum.name;
          },
          fail: (err) => {
            console.error("SDK调用失败:", err);
            wx.showToast({ title: '地址解析失败'+JSON.stringify(err) + latitude+ longitude, icon: 'none' });
          }
        });
      // 表单数据
      form: {
        address: '',
        tripTime: '',
        tripType: ''
      },
      // 文件列表
      fileList: [],
      // 加载状态
      loading: false,
      locationLoading: false,
      // 表单验证规则
      rules: {
        address: [{ required: true, message: '请获取地址', trigger: 'blur' }],
        tripTime: [{ required: true, message: '请选择时间', trigger: 'change' }],
        fileList: [{ validator: this.validateFiles, trigger: 'change' }]
      }
    }
};
  },
  onLoad(options) {
    // 使用新的参数方式
    this.dispatchId = options.id || ''
    this.statusStr = options.statusStr || ''
    // 根据状态设置标题
    this.pageTitle = this.statusStr || '上传行程'
    // 初始化高德地图
    this.amapPlugin = new amap.AMapWX({ key: this.mapApiKey })
    // 获取位置
    this.getLocation()
    // 加载数据
    if (this.dispatchId) {
      this.loadDispatchInfo()
    }
  },
  created() {
    this.form.tripTime = this.getCurrentDateTime()
  },
  methods: {
    // 获取当前时间
    getCurrentDateTime() {
      const now = new Date()
      const pad = (n) => n.toString().padStart(2, '0')
      return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`
    },
    // 加载调度信息
    async loadDispatchInfo() {
      try {
        const res = await getcarDispatch(this.dispatchId)
        this.newForm = { ...res, statusStr: this.statusStr }
        this.infoList = INFO_FIELDS.map(f => ({ ...f, value: res[f.key] ?? f.value }))
        // 加载行程类型
        const tripTypes = await getcarType('trip_type')
        // 可根据需要存储 tripTypes
      } catch (err) {
        console.error('加载调度信息失败:', err)
        uni.$u.toast('加载数据失败')
      }
    },
    // 文件验证
    validateFiles(rule, value, callback) {
      if (this.fileList.length === 0) {
        callback(new Error('请上传凭证'))
      } else {
        callback()
      }
    },
    // 图片上传
    async afterRead(event) {
      try {
        const res = await uploadImage(event.file[0].url, this.isHk)
        this.fileList.push(res)
      } catch (err) {
        console.error('上传失败:', err)
        uni.$u.toast('上传失败')
      }
    },
    // 删除图片
    deletePic(event) {
      this.fileList.splice(event.index, 1)
    },
    // 图片超出大小
    overSize() {
      uni.$u.toast('图片大小不能超过2MB')
    },
    // 获取位置(添加超时处理)
    getLocation() {
      this.locationLoading = true
      // 设置 10 秒超时
      const timeout = setTimeout(() => {
        this.locationLoading = false
        uni.$u.toast('定位超时,请手动输入地址')
      }, 10000)
      uni.getLocation({
        type: 'gcj02',
        success: (res) => {
          clearTimeout(timeout)
          this.getAddress(res.latitude, res.longitude)
        },
        fail: (err) => {
          clearTimeout(timeout)
          this.locationLoading = false
          console.error('获取位置失败:', err)
          uni.$u.toast('获取位置失败,请手动输入地址')
        }
      })
    },
    // 解析地址
    getAddress(latitude, longitude) {
      this.amapPlugin.getRegeo({
        location: `${longitude},${latitude}`,
        success: (data) => {
          this.locationLoading = false
          const datum = data[0]
          if (datum.regeocodeData?.addressComponent?.province) {
            this.isHk = datum.regeocodeData.addressComponent.province.includes('香港')
          }
          this.form.address = datum.name || datum.desc
        },
        fail: (err) => {
          this.locationLoading = false
          console.error('地址解析失败:', err)
          uni.$u.toast('地址解析失败,请手动输入地址')
        }
      })
    },
    // 提交表单
    submitForm() {
      if (this.loading) return
      const formRef = this.statusStr === '待甩挂' ? 'dropForm' : 'pickForm'
      this.$refs[formRef].validate().then(() => {
        this.doSubmit()
      }).catch(() => {
        uni.$u.toast('请完善表单信息')
      })
    },
    // 执行提交
    async doSubmit() {
      this.loading = true
      const submitData = {
        ...this.form,
        voucherUrl: this.fileList.map(item => item.url).join(','),
        dispatchOrderId: this.newForm.dispatchId,
        driverId: this.newForm.driverId
      }
      try {
        const api = this.statusStr === '待甩挂' ? carSubmitDropHoo : carSubmitPickHook
        const res = await api(submitData)
        uni.$u.toast('操作成功')
        reLaunch('/pages/beReferred/index')
      } catch (err) {
        uni.$u.toast(err.message || '提交失败')
      } finally {
        setTimeout(() => {
          this.loading = false
        }, 500)
      }
    },
    // 重置表单
    resetForm() {
      this.form = {
        address: '',
        tripTime: this.getCurrentDateTime(),
        tripType: ''
      }
      this.fileList = []
    },
    // 跳转到垫付列表
    goToAdvanceList() {
      navigateTo(PAGES.PAYMENT_LIST, { id: this.dispatchId })
    },
    // 跳转到行程历史
    goTravelItinerary() {
      navigateTo(PAGES.TRAVEL_ITINERARY, { id: this.dispatchId })
    }
  }
}
</script>
<style scoped>
.container {
    display: flex;
    flex-direction: column;
    height: 100vh;
    background-color: #f7f7f7;
    align-items: stretch;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  background-color: #f7f7f7;
}
.info-section {
    background-color: #fff;
    margin: 20rpx;
    border-radius: 12rpx;
    overflow: hidden;
    flex-shrink: 0;
}
.info-item {
    display: flex;
    padding: 20rpx;
    border-bottom: 1rpx solid #eee;
}
.info-item:last-child {
    border-bottom: none;
}
.item-label {
    width: 180rpx;
    color: #666;
    font-size: 28rpx;
}
.item-value {
    flex: 1;
    color: #333;
    font-size: 28rpx;
}
.item-value.status {
    color: #ff6b6b;
    font-weight: 500;
}
.tab-bar {
    display: flex;
    height: 80rpx;
    background-color: #fff;
    border-bottom: 1rpx solid #eee;
}
.tab-item {
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 28rpx;
    color: #666;
    position: relative;
    height: 80rpx;
    /* 确保高度 */
    z-index: 1;
    /* 确保层级 */
}
.tab-item.active {
    color: #4285f4;
    font-weight: 500;
}
.tab-item.active::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 60rpx;
    height: 6rpx;
    background-color: #4285f4;
    border-radius: 3rpx;
.form-content {
  flex: 1;
  padding-bottom: 40rpx;
}
.form-section {
    flex: 1;
    padding: 20rpx;
    background-color: #fff;
    margin: 0 20rpx 20rpx;
    border-radius: 12rpx;
    box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
    /* overflow-y: auto; */
  padding: 20rpx;
  background-color: #fff;
  border-radius: 12rpx;
  margin: 20rpx;
}
/* 上传行程-单选操作按钮组(自适应换行样式) */
.action-buttons-container {
    margin-bottom: 30rpx;
    overflow-y: auto;
}
.action-buttons-row {
    gap: 20rpx;
    /* margin-bottom: 20rpx; */
    display: grid;
    grid-template-columns: repeat(auto-fill, 150rpx);
    grid-gap: 20rpx;
    min-width: 100%;
}
.action-btn {
    width: 150rpx;
    height: 80rpx;
    line-height: 80rpx;
    text-align: center;
    font-size: 25rpx;
    border-radius: 8rpx;
    background-color: #fff;
    border: 1rpx solid #eee;
    color: #333;
    transition: all 0.2s ease;
    /* 使用 flex 布局确保一致性 */
    display: flex;
    justify-content: center;
    align-items: center;
    /* 关键:设置文本溢出处理 */
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
/* 选中状态样式 */
.action-btn.selected {
    background-color: #e8f4f8;
    border-color: #4285f4;
    color: #4285f4;
    font-weight: 500;
}
.action-btn::after {
    border: none;
}
/* 选中按钮按压反馈 */
.action-btn.selected:active {
    background-color: #d1e7fd;
}
/* 未选中按钮按压反馈 */
.action-btn:not(.selected):active {
    background-color: #f5f5f5;
}
.form-item {
    margin-bottom: 30rpx;
.form-row {
  display: flex;
  align-items: flex-start;
  width: 100%;
  padding: 10rpx 0;
}
.form-label {
    font-size: 28rpx;
    color: #333;
    margin-bottom: 16rpx;
    display: flex;
    align-items: center;
  display: flex;
  align-items: center;
  flex-shrink: 0;
  margin-right: 20rpx;
  min-width: 120rpx;
  padding-top: 16rpx;
}
.required-tag {
    display: inline-block;
    width: 24rpx;
    height: 24rpx;
    line-height: 24rpx;
    text-align: center;
    background-color: #e53e3e;
    color: #fff;
    font-size: 20rpx;
    border-radius: 50%;
    margin-left: 8rpx;
.label-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36rpx;
  height: 36rpx;
  margin-right: 8rpx;
}
.form-control {
    display: flex;
    align-items: center;
    border: 1rpx solid #eee;
    border-radius: 8rpx;
    padding: 16rpx;
    background-color: #f9f9f9;
.label-text {
  font-size: 28rpx;
  color: #303133;
  font-weight: 500;
}
.form-control input {
    flex: 1;
    font-size: 28rpx;
.form-label.required .label-text::after {
  content: '*';
  color: #ff4d4f;
  margin-left: 4rpx;
}
.icon {
    width: 32rpx;
    height: 32rpx;
    margin-left: 16rpx;
.flex-1 {
  flex: 1;
}
.form-control input[disabled] {
    background-color: #f9f9f9;
    color: #999;
.address-box {
  flex: 1;
  display: flex;
  align-items: center;
  background-color: #f5f7fa;
  border: 2rpx solid #e4e7ed;
  border-radius: 12rpx;
  padding: 20rpx 80rpx 20rpx 20rpx;
  position: relative;
}
.picker-value {
    flex: 1;
    font-size: 28rpx;
    color: #333;
.location-icon {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translateY(-50%);
  width: 72rpx;
  height: 72rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>
  top: 50%;
  right: 16rpx;
  transform: translateY(-50%);
}
.bottom-buttons {
    display: flex;
    gap: 20rpx;
    margin-top: 40rpx;
// 时间选择
.datetime-wrapper {
  display: flex;
  align-items: center;
  width: 100%;
}
.bottom-btn {
    flex: 1;
    height: 80rpx;
    line-height: 80rpx;
    text-align: center;
    font-size: 28rpx;
    border-radius: 8rpx;
    background-color: #fff;
    border: 1rpx solid #eee;
    color: #333;
.datetime-picker {
  flex: 1;
}
.bottom-btn.primary {
    background-color: #4285f4;
    color: #fff;
    border: none;
// 按钮组
.btn-group {
  display: flex;
  gap: 20rpx;
  margin-top: 40rpx;
  padding-top: 20rpx;
  border-top: 1rpx solid #ebeef5;
}
.bottom-btn::after {
    border: none;
.btn-default {
  flex: 1;
}
/* 按钮 */
.bottom-btn-group {
    display: flex;
    gap: 20rpx;
    padding: 30rpx;
.btn-primary {
  flex: 2;
}
/* 文本框样式优化:内边距+占位符 */
::v-deep .custom-textarea {
    padding: 16rpx 50rpx 16rpx 16rpx !important;
    /* 上下内边距稍大,右侧留图标位置 */
    min-height: 80rpx;
}
/* 占位符样式:灰色,和图片一致 */
::v-deep .custom-textarea textarea::placeholder {
    color: #c6c0ba !important;
    /* 浅灰色占位符 */
    font-size: 28rpx;
}
/* 确保文本框边框不被覆盖 */
::v-deep .custom-textarea .uni-textarea {
    border: none !important;
    /* 去掉组件自带边框,用外层自定义边框 */
}
</style>
</style>