| | |
| | | <template> |
| | | <view class="container"> |
| | | <!-- 标题栏 --> |
| | | <Nav :title="formData.name" :customBack="formData.router"></Nav> |
| | | <!-- 导航栏 --> |
| | | <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> |
| | | <!-- 基础信息 - 使用统一的 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="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 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> --> |
| | | |
| | | |
| | | |
| | | <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> |
| | | |
| | | |
| | | |
| | | </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> |
| | | <!-- 甩挂时间 --> |
| | | <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" style="flex: 1;" |
| | | @change="onDateTimeChange"> |
| | | </uni-datetime-picker> |
| | | <uni-datetime-picker type="datetime" v-model="form.tripTime" class="flex-1" /> |
| | | </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 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-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> |
| | | |
| | | <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="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 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 @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> |
| | | <!-- 接挂时间 --> |
| | | <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" style="flex: 1;" |
| | | @change="onDateTimeChange"> |
| | | </uni-datetime-picker> |
| | | <uni-datetime-picker type="datetime" v-model="form.tripTime" class="flex-1" /> |
| | | </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 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-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> |
| | | <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 { |
| | | components: { InfoSection, BottomBar }, |
| | | |
| | | data() { |
| | | return { |
| | | mapApiKey: 'fdb2d2e64ffc9254045935d3227d5cd9', // <-- 替换成你的 API Key |
| | | // 高德地图配置 |
| | | mapApiKey: 'fdb2d2e64ffc9254045935d3227d5cd9', |
| | | amapPlugin: null, |
| | | formData: { |
| | | name: '', |
| | | router: '', |
| | | id: '' |
| | | }, |
| | | fileList: [], |
| | | range: [ |
| | | isHk: false, |
| | | |
| | | ], |
| | | feeTypeList: [], |
| | | cleanedForm: {}, |
| | | // 页面参数 |
| | | dispatchId: '', |
| | | statusStr: '', |
| | | pageTitle: '', |
| | | |
| | | // 调度信息 |
| | | newForm: {}, |
| | | selectedAction: '', |
| | | activeTab: 'upload', |
| | | infoList: [ |
| | | { label: '调度单号', value: '' }, |
| | | { label: '运输工具号码', value: '' }, |
| | | { label: '路线', value: '' }, |
| | | { label: '客户', value: '' }, |
| | | { label: '当前状态', value: '待发车', status: true }, |
| | | { label: '要求最晚发车时间', value: '' } |
| | | ], |
| | | actionButtonRows: [ |
| | | infoList: INFO_FIELDS.map(f => ({ ...f, value: f.default || '' })), |
| | | |
| | | ], |
| | | // 表单数据 |
| | | form: { |
| | | address: '', |
| | | tripTime: '', |
| | | odometer: 0, |
| | | 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' }] |
| | | } |
| | | } |
| | | }, |
| | | |
| | | 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(); |
| | | // 使用新的参数方式 |
| | | 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.getList(); |
| | | this.form.tripTime = this.getCurrentDateTime(); |
| | | |
| | | 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; |
| | | 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())}` |
| | | }, |
| | | goTravelItinerary() { |
| | | setTimeout(() => { |
| | | uni.$u.route('/pages/travelItinerary/index?id=' + this.formData.id + '&name=' + '上传行程' + '&router=' + '/pages/travelItinerary/index' + '&statusStr=' + this.formData.statusStr); |
| | | }, 1000); |
| | | |
| | | }, |
| | | feeTypeChange(e) { |
| | | }, |
| | | getList() { |
| | | getcarDispatch(this.formData.id).then((res) => { |
| | | res.statusStr = '待接挂' |
| | | this.newForm = res; |
| | | // 定义字段映射关系 |
| | | const fieldMap = { |
| | | dispatchNo: '调度单号', |
| | | licensePlate: '运输工具号码', |
| | | transportLine: '路线', |
| | | customerName: '客户', |
| | | statusStr: '当前状态', |
| | | latestDeparture: '要求最晚发车时间' |
| | | }; |
| | | // 加载调度信息 |
| | | 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 })) |
| | | |
| | | // 遍历 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] }; |
| | | // 加载行程类型 |
| | | const tripTypes = await getcarType('trip_type') |
| | | // 可根据需要存储 tripTypes |
| | | } catch (err) { |
| | | console.error('加载调度信息失败:', err) |
| | | uni.$u.toast('加载数据失败') |
| | | } |
| | | 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' |
| | | }) |
| | | // 文件验证 |
| | | validateFiles(rule, value, callback) { |
| | | if (this.fileList.length === 0) { |
| | | callback(new Error('请上传凭证')) |
| | | } else { |
| | | resolve({ |
| | | url: dataObject.fileName, |
| | | status: 'failed' |
| | | }) |
| | | callback() |
| | | } |
| | | }, |
| | | fail: (err) => { |
| | | reject({ status: 'failed' }); |
| | | |
| | | // 图片上传 |
| | | 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('上传失败') |
| | | } |
| | | }); |
| | | }) |
| | | }, |
| | | // 图片大小超出最大允许大小 |
| | | overSize(e) { |
| | | uni.$u.toast('上传图片大小不能超过2MB!') |
| | | }, |
| | | |
| | | // 删除图片 |
| | | deletePic(event) { |
| | | this.fileList.splice(event.index, 1) |
| | | }, |
| | | onDateTimeChange(event) { |
| | | // this.form.workTime = event.detail.value; |
| | | |
| | | // 图片超出大小 |
| | | overSize() { |
| | | uni.$u.toast('图片大小不能超过2MB') |
| | | }, |
| | | |
| | | 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({ |
| | | this.locationLoading = true |
| | | |
| | | // 设置 10 秒超时 |
| | | const timeout = setTimeout(() => { |
| | | this.locationLoading = false |
| | | uni.$u.toast('定位超时,请手动输入地址') |
| | | }, 10000) |
| | | |
| | | uni.getLocation({ |
| | | type: 'gcj02', |
| | | success: (res) => { |
| | | const latitude = res.latitude; |
| | | const longitude = res.longitude; |
| | | this.getAddress(latitude, longitude); |
| | | clearTimeout(timeout) |
| | | this.getAddress(res.latitude, res.longitude) |
| | | }, |
| | | fail: (err) => { |
| | | console.error('获取位置失败:', err); |
| | | wx.showToast({ title: '获取位置失败', icon: 'none' }); |
| | | clearTimeout(timeout) |
| | | this.locationLoading = false |
| | | console.error('获取位置失败:', err) |
| | | uni.$u.toast('获取位置失败,请手动输入地址') |
| | | } |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | // 解析地址 |
| | | 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.locationLoading = false |
| | | const datum = data[0] |
| | | if (datum.regeocodeData?.addressComponent?.province) { |
| | | this.isHk = datum.regeocodeData.addressComponent.province.includes('香港') |
| | | } |
| | | } |
| | | |
| | | |
| | | this.form.address = datum.name; |
| | | this.form.address = datum.name || datum.desc |
| | | }, |
| | | fail: (err) => { |
| | | console.error("SDK调用失败:", err); |
| | | wx.showToast({ title: '地址解析失败'+JSON.stringify(err) + latitude+ longitude, icon: 'none' }); |
| | | 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; |
| | | min-height: 100vh; |
| | | background-color: #f7f7f7; |
| | | align-items: stretch; |
| | | } |
| | | |
| | | .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 { |
| | | .form-content { |
| | | 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; |
| | | 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; */ |
| | | 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 布局确保一致性 */ |
| | | .form-row { |
| | | 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; |
| | | align-items: flex-start; |
| | | width: 100%; |
| | | padding: 10rpx 0; |
| | | } |
| | | |
| | | .form-label { |
| | | font-size: 28rpx; |
| | | color: #333; |
| | | margin-bottom: 16rpx; |
| | | 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; |
| | | } |
| | | |
| | | .form-control { |
| | | .label-icon { |
| | | display: flex; |
| | | align-items: center; |
| | | border: 1rpx solid #eee; |
| | | border-radius: 8rpx; |
| | | padding: 16rpx; |
| | | background-color: #f9f9f9; |
| | | justify-content: center; |
| | | width: 36rpx; |
| | | height: 36rpx; |
| | | margin-right: 8rpx; |
| | | } |
| | | |
| | | .form-control input { |
| | | flex: 1; |
| | | .label-text { |
| | | font-size: 28rpx; |
| | | color: #303133; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .icon { |
| | | width: 32rpx; |
| | | height: 32rpx; |
| | | margin-left: 16rpx; |
| | | .form-label.required .label-text::after { |
| | | content: '*'; |
| | | color: #ff4d4f; |
| | | margin-left: 4rpx; |
| | | } |
| | | |
| | | .form-control input[disabled] { |
| | | background-color: #f9f9f9; |
| | | color: #999; |
| | | } |
| | | |
| | | .picker-value { |
| | | .flex-1 { |
| | | flex: 1; |
| | | font-size: 28rpx; |
| | | color: #333; |
| | | } |
| | | |
| | | .bottom-buttons { |
| | | .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; |
| | | } |
| | | |
| | | .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%); |
| | | } |
| | | |
| | | // 时间选择 |
| | | .datetime-wrapper { |
| | | display: flex; |
| | | align-items: center; |
| | | width: 100%; |
| | | } |
| | | |
| | | .datetime-picker { |
| | | flex: 1; |
| | | } |
| | | |
| | | // 按钮组 |
| | | .btn-group { |
| | | display: flex; |
| | | gap: 20rpx; |
| | | margin-top: 40rpx; |
| | | padding-top: 20rpx; |
| | | border-top: 1rpx solid #ebeef5; |
| | | } |
| | | |
| | | .bottom-btn { |
| | | .btn-default { |
| | | 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; |
| | | } |
| | | |
| | | .bottom-btn.primary { |
| | | background-color: #4285f4; |
| | | color: #fff; |
| | | border: none; |
| | | } |
| | | |
| | | .bottom-btn::after { |
| | | border: none; |
| | | } |
| | | |
| | | /* 按钮 */ |
| | | .bottom-btn-group { |
| | | display: flex; |
| | | gap: 20rpx; |
| | | padding: 30rpx; |
| | | } |
| | | |
| | | /* 文本框样式优化:内边距+占位符 */ |
| | | ::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; |
| | | /* 去掉组件自带边框,用外层自定义边框 */ |
| | | .btn-primary { |
| | | flex: 2; |
| | | } |
| | | </style> |