lanan-app/pages/process/dispatchProcess.vue
2025-09-25 15:45:12 +08:00

4202 lines
116 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="content">
<view class="mubu">
<view class="c-top">
<view class="top-heder"></view>
<view class="topjianjian">
<view style="width: 20rpx; height: 100%;" @click="goback()">
<uni-icons type="left" color="#ffffff" size="22"></uni-icons>
</view>
<view class="bai-title">调度流程</view>
<view style="width: 20rpx; height: 100%;"></view>
</view>
<view class="dis-b" style="margin-top: 32rpx; box-sizing: border-box; padding: 0rpx 30rpx; ">
<view class="t-left">
<view class="left-t">
<view class="sj">
<image src="../../static/detection/sja.png" mode=""></image>
</view>
<view class="t-zi1">
<text>{{detailsData.rescueStatusStr}}</text>
</view>
</view>
</view>
<view class="t-right">
<view class="" @click="gotel(detailsData.connectionPhone)">
<view class="ximg">
<image src="../../static/detection/shouji.png" mode=""></image>
</view>
<view class="ai">拨打电话</view>
</view>
<view style="margin-left: 20rpx;" @click="gogogo()">
<view class="ximg">
<image src="../../static/detection/xiaofeij.png" mode=""></image>
</view>
<view class="ai">到这去</view>
</view>
</view>
</view>
<view class="ding-top">
<view class="dis-bb">
<view style="display: flex;justify-content: space-between;width: 100%; align-items: center;">
<view class="xhui">
救援地点
</view>
</view>
<view class="ja-you">{{detailsData.rescuePosition || '暂未设置'}}</view>
<view class="xhui">
终点位置
</view>
<view class="ja-you">
{{detailsData.destinationInfo || '暂未设置'}}
</view>
<view class="xhui-kc" v-if="detailsData.rescueType == '5' ">
扣车地点:{{ detailsData.kcPosition }}
</view>
<view style="margin-top: 40rpx;">
<view style="font-size: 28rpx; color:#999999; margin-bottom: 20rpx;">
救援地址备注:<view style="color:black; font-weight: bold;; font-size: 30rpx;">
{{ detailsData.remarkRescuePosition || '暂无备注' }}
</view>
</view>
<view style="font-size: 28rpx; color:#999999; margin-bottom: 20rpx;">
目的地备注:<view style="color:black; font-weight: bold; font-size: 30rpx;">
{{ detailsData.remarkDestinationInfo || '暂无备注' }}
</view>
</view>
</view>
</view>
<view class="dix" style="font-weight: bold;">客户信息: </view>
<view class="dix">
<text class="huiy">客户车牌:</text>
<text
:class="{ 'no-data': !detailsData.licenseNum }">{{detailsData.licenseNum || '暂无数据'}}</text>
</view>
<view class="dix">
<text class="huiy">客户姓名:</text>
<text
:class="{ 'no-data': !detailsData.connectionName }">{{detailsData.connectionName || '暂无数据'}}</text>
</view>
<view class="dix">
<text class="huiy">客户手机号:</text>
<text
:class="{ 'no-data': !detailsData.connectionPhone }">{{detailsData.connectionPhone || '暂无数据'}}</text>
</view>
<view class="dix">
<text class="huiy">车主姓名:</text>
<text :class="{ 'no-data': !detailsData.carOwner }">{{detailsData.carOwner || '暂无数据'}}</text>
</view>
<view class="dix">
<text class="huiy">车主手机号:</text>
<text
:class="{ 'no-data': !detailsData.carOwnerPhone }">{{detailsData.carOwnerPhone || '暂无数据'}}</text>
</view>
<view class="dix">
<text class="huiy">车型(品牌):</text>
<text :class="{ 'no-data': !detailsData.carBrand }">{{detailsData.carBrand || '暂无数据'}}</text>
</view>
<view class="dix">
<text class="huiy">车辆类型:</text>
<text
:class="{ 'no-data': !detailsData.carTypeStr }">{{detailsData.carTypeStr || '暂无数据'}}</text>
</view>
<view class="dix">
<text class="huiy">是否为新能源:</text>
<text :class="{ 'no-data': !detailsData.ifNewEnergy }">
{{ detailsData.ifNewEnergy == '0' ? '否' : detailsData.ifNewEnergy == '1' ? '是' : '暂无数据' }}</text>
</view>
<!-- <view class="dix">
<text class="huiy">收款类型:</text>
<text
:class="{ 'no-data': !detailsData.feeTypeStr }">{{detailsData.feeTypeStr || '暂无数据'}}</text>
</view> -->
<view class="dix">
<text class="huiy">救援类型:</text>
<text
:class="{ 'no-data': !detailsData.rescueTypeStr }">{{detailsData.rescueTypeStr || '暂无数据'}}</text>
</view>
<view class="dix">
<text class="huiy">故障类型:</text>
<text :class="{ 'no-data': !detailsData.faultType }">{{detailsData.faultType || '暂无数据'}}</text>
</view>
<view class="dix">
<text class="huiy">故障现象:</text>
<text
:class="{ 'no-data': !detailsData.phenomenon }">{{detailsData.phenomenon || '暂无数据'}}</text>
</view>
<view class="dix">
<text class="huiy">故障现象备注:</text>
<text
:class="{ 'no-data': !detailsData.faultPhenomenon }">{{detailsData.faultPhenomenon || '暂无数据'}}</text>
</view>
<view class="dix">
<text class="huiy">救援需求:</text>
<text
:class="{ 'no-data': !detailsData.rescueNeeds }">{{detailsData.rescueNeeds || '暂无数据'}}</text>
</view>
<view class="dix">
<text class="huiy">预估下车地:</text>
<text
:class="{ 'no-data': !detailsData.estimateDownCar }">{{detailsData.estimateDownCar || '暂无数据'}}</text>
</view>
<!-- <view class="dix">
<text class="huiy">预估费用:</text>
<text
:class="{ 'no-data': !detailsData.estimateMoney }">{{detailsData.estimateMoney || '暂无数据'}}</text>
</view> -->
<view style="border-bottom: 1px solid #EEEEEE;"></view>
<view class="dix" style="font-weight: bold;">救援司机信息: </view>
<view class="dix">
<text class="huiy">司机姓名:</text>
<text
:class="{ 'no-data': !detailsData.driverName }">{{detailsData.driverName || '暂无数据'}}</text>
</view>
<view class="dix">
<text class="huiy">手机号:</text>
<text
:class="{ 'no-data': !detailsData.driverPhoneNum }">{{detailsData.driverPhoneNum || '暂无数据'}}</text>
</view>
<view class="dix">
<text class="huiy">车牌号:</text>
<text
:class="{ 'no-data': !detailsData.driverCarNum }">{{detailsData.driverCarNum || '暂无数据'}}</text>
</view>
<view class="dix">
<text class="huiy">车辆种类:</text>
<text
:class="{ 'no-data': !detailsData.driverCarCategory }">{{detailsData.driverCarCategory || '暂无数据'}}</text>
</view>
<view class="floating-end-btn"
v-if="detailsData.dispatchRecordStep <= 4 && detailsData.rescueType == 8"
@click="endShow = true">
<uni-icons type="closeempty" color="red" size="25"></uni-icons>
<view class="terminate-text">结束订单</view>
</view>
<view class="floating-go-btn"
v-if="detailsData.isDispatchedToScene == '0' && detailsData.dispatchRecordStep == 5 "
@click="againYesToSceneShow = true">
<uni-icons type="paperplane" color="#42b983" size="25"></uni-icons>
<view class="go-text">重新出发</view>
</view>
<view class="floating-terminate-btn"
v-if="detailsData.dispatchRecordStep >= 2 && detailsData.dispatchRecordStep <= 4"
@click="terminateShow = true">
<uni-icons type="smallcircle-filled" color="red" size="25"></uni-icons>
<view class="terminate-text">终止流程</view>
</view>
<view class="floating-refresh-btn" @click="getrescueDetail(id)">
<uni-icons type="refresh-filled" color="#1b5dfd" size="25"></uni-icons>
<view class="refresh-text">刷新订单</view>
</view>
</view>
<view class="hui-content">
<view class="content-box">
<view class="dis-bb">
<view class="ja-you">事情描述:</view>
</view>
<view class="xx-hui">
{{detailsData.rescueDetail || '暂无描述'}}
</view>
</view>
<view class="content-box" v-if="detailsData.rescueSceneImageList != null ">
<view class="dis-bb">
<view class="ja-you">现场照片</view>
</view>
<view class="img-boxs">
<view class="g-img" v-for="(item,index) in detailsData.rescueSceneImageList" :key="index">
<image :src="baseImageUrl + item " mode=""></image>
</view>
</view>
</view>
<view class="content-box">
<view class="dis-bb">
<view class="ja-you">调度进程</view>
</view>
<view v-if="detailList && detailList.length > 0" class="c-box">
<view class="lan-ga" v-for="(item,index) in detailList" :key="index">
<view class="ga-top-box">
<view class="gain">
<image class="gainIcon" src="@/static/icons/currentDetails.png"
mode="aspectFit"></image>
</view>
<view class="ga-content">
<view class="ga-content-top">
<view class="ga-content-title">{{item.title}}</view>
<view class="xhui">
{{item.createTime}}
</view>
</view>
<view class="beizh-auto">
{{item.autoRemark && item.autoRemark.replace(/, /g, '\n')}}
</view>
<view class="beizh" style="margin-top: 10rpx;"
v-if="item.remark && item.remark !== ''">
备注: {{item.remark}}
</view>
<view class="wrap-box_bc" v-if="item.images" style="margin-top: 10rpx;">
<view class="edit_images">
<text
style="font-size: 28rpx; font-weight: bold; margin-right: 20rpx;">照片:</text>
<view class="edit-photo-btn" @click="showEditPhotoPopup(item, 'images')"
v-if="isEditableStatus">
<uni-icons type="compose" size="16" color="#0D2E8D"></uni-icons>
<text>编辑</text>
</view>
</view>
<view style="display: flex; flex-direction: row;">
<view class="img-box" v-for="(items,index) in item.images.split(',') "
:key="index" @click="lookimg(index,item.images.split(','))">
<image :src="baseImageUrl + items " mode=""></image>
</view>
</view>
</view>
<view class="wrap-box_bc" v-if="item.supplementImages"
style="margin-top: 20rpx;">
<text style="font-size: 28rpx; font-weight: bold;">补充照片:</text>
<view style="display: flex; flex-direction: row;">
<view class="img-box"
v-for="(items,index) in item.supplementImages.split(',') "
:key="index"
@click="lookimg(index,item.supplementImages.split(','))">
<image :src="baseImageUrl + items " mode=""></image>
</view>
</view>
</view>
<!-- 补充照片按钮 -->
<view class="supplement-photo-btn" @click="showSupplementPopup(item)">
<uni-icons type="plus" size="16" color="#0D2E8D"></uni-icons>
<text>补充照片</text>
</view>
</view>
</view>
<view v-if="index < detailList.length - 1" class="lan-ga-line"></view>
</view>
</view>
<view v-if="detailList && detailList.length == 0">
<view class="ques">
<image src="../../static/quesheng2.png" mode="aspectFit"></image>
</view>
</view>
</view>
</view>
</view>
</view>
<u-picker :show="carNumShow" @cancel="carNumShow = false" @close="carNumShow = false" @confirm="chooseCar"
:columns="[carNumList]" keyName="rescueCarNum"></u-picker>
<u-modal :show="show" title="修改" content='您确认修改吗' :showCancelButton="true" @confirm="confirmadd()"
@cancel="cancelopen()"></u-modal>
<u-modal :show="terminateShow" title="终止" content='您确认终止吗' :showCancelButton="true"
@confirm="cancelTerminateConfirm()" @cancel="cancelTerminateOpen()"></u-modal>
<u-modal :show="endShow" title="结束订单" content='您确认结束订单吗' :showCancelButton="true" @confirm="cancelEndConfirm()"
@cancel="cancelEndOpen()"></u-modal>
<u-popup :show="toSceneShow" mode="center" round="10">
<view class="custom-modal">
<view class="modal-header">
<view class="modal-title">是否出发现场</view>
<uni-icons type="close" size="20" color="#999" class="close-icon" @click="cancelToSceneOpen">
</uni-icons>
</view>
<view class="modal-content">请选择是否出发现场</view>
<view class="modal-buttons">
<button class="modal-btn no-btn" @click="cancelToSceneConfirm('noTo')">否</button>
<button class="modal-btn yes-btn" @click="cancelToSceneConfirm('yesTo')">是</button>
</view>
<view class="modal-footer">
<button class="modal-btn cancel-btn" @click="cancelToSceneOpen">关闭</button>
</view>
</view>
</u-popup>
<u-popup :show="againYesToSceneShow" mode="center" round="10">
<view class="custom-modal">
<view class="modal-header">
<view class="modal-title">重新出发现场</view>
<uni-icons type="close" size="20" color="#999" class="close-icon" @click="cancelToSceneOpen">
</uni-icons>
</view>
<view class="modal-buttons">
<button class="modal-btn no-btn" @click="cancelToSceneOpen">关闭</button>
<button class="modal-btn yes-btn" @click="cancelToSceneConfirm('againYesTo')">是</button>
</view>
</view>
</u-popup>
<u-picker :show="roadShow" @cancel="roadShow = false" @close="roadShow = false" @confirm="chooseRoad"
:columns="[roadList]" keyName="label"></u-picker>
<u-picker :show="sourceShow" @cancel="sourceShow = false" @close="sourceShow = false" @confirm="chooseSource"
:columns="[sourceList]" keyName="label"></u-picker>
<!-- 故障类型和故障现象选择 -->
<u-picker :show="faultPhenomenonShow" @cancel="faultPhenomenonShow = false" @close="faultPhenomenonShow = false"
@confirm="chooseFaultPhenomenon" :columns="[faultPhenomenonList]" keyName="name"></u-picker>
<u-picker :show="faultTypeShow" @cancel="faultTypeShow = false" @close="faultTypeShow = false"
@confirm="chooseFaultType" :columns="[faultTypeList]" keyName="name"></u-picker>
<u-popup :show="recordShow" mode="center" :round="10">
<view class="popup-box">
<view class="p-title">描述</view>
<!-- <view class="huinput" @click="gettype"> -->
<view class="huinput">
<text>节点:</text>
<text class="tshe">{{ dictLabel }}</text>
</view>
<view class="huinput" v-if="dispatchStepIndex !== 5">
<text>备注信息:</text>
<u--textarea v-model="remark" placeholder="请输入备注" border="bottom" autoHeight></u--textarea>
</view>
<!-- 上传状态提示 -->
<view class="upload-tips" v-if="uploadingRecord">
<u-loading-icon size="20" color="#0D2E8D"></u-loading-icon>
<text>照片上传中,请稍候...</text>
</view>
<!-- 当 dispatchStepIndex 为 4 时额外显示三个选项按钮 -->
<view v-if="dispatchStepIndex === 5" class="option-buttons">
<view class="huinput">
<text>请选择人移交类型:</text>
</view>
<view class="option-button" :class="{'active': selectedOption === 'repair'}"
@click="selectedOption = 'repair'">
转维修
</view>
<view class="option-button" :class="{'active': selectedOption === 'detain'}"
@click="selectedOption = 'detain'">
扣车
</view>
<view class="option-button" :class="{'active': selectedOption === 'handover'}"
@click="selectedOption = 'handover'">
移交客户
</view>
<view class="option-button" :class="{'active': selectedOption === 'specifyRepairShop'}"
@click="selectedOption = 'specifyRepairShop'">
移交客户指定修理厂
</view>
<view class="option-button" :class="{'active': selectedOption === 'specifyPickUpPeople'}"
@click="selectedOption = 'specifyPickUpPeople'">
移交客户指定接车人
</view>
</view>
<view class="p-title" v-if="dispatchStepIndex !== 5">照片</view>
<view class="huinput" v-if="dispatchStepIndex !== 5">
<u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple
:maxCount="5" :disabled="uploadingRecord"></u-upload>
</view>
<view class="button-group">
<view class="cancel-button" @click="cancelRecord" :disabled="uploadingRecord">
<text>取消</text>
</view>
<view class="confirm-button" @click="getdaoda()" :disabled="isSubmitting || uploadingRecord">
<!-- <text>确认</text> -->
<text>{{ isSubmitting ? '处理中...' : '确认' }}</text>
</view>
</view>
</view>
</u-popup>
<u-popup :show="acceptOrderShow" mode="center" :round="10" @close="closeAcceptOrderPopup"
:closeOnClickOverlay="false">
<view class="popup-box">
<view class="p-title" v-if="this.dispatchStepIndex == 2">调度出发现场</view>
<view class="p-title" v-if="this.dispatchStepIndex == 3">调度到达现场</view>
<view class="huinput" v-if="dispatchStepIndex == 2">
<text>出发里程数: </text>
<u--input v-model="dispatchStartScale" type="number" placeholder="请输入出发里程数" />
</view>
<view class="huinput" v-if="dispatchStepIndex == 3">
<text>到达里程数: </text>
<u--input v-model="dispatchArriveScale" type="number" placeholder="请输入到达里程数" />
</view>
<view class="huinput">
<text>备注信息: </text>
<u--textarea v-model="remark" placeholder="请输入备注信息" border="bottom" autoHeight></u--textarea>
</view>
<view class="p-title">车辆里程表照片</view>
<view class="huinput">
<u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple
:maxCount="5"></u-upload>
</view>
<view class="button-group">
<view class="cancel-button" @click="closeAcceptOrderPopup">
<text>取消</text>
</view>
<view class="confirm-button" @click="confirmAcceptOrder" :disabled="isSubmitting">
<text>{{ isSubmitting ? '处理中...' : '确认' }}</text>
</view>
</view>
</view>
</u-popup>
<u-popup :show="toRepairShow" mode="center" :round="10" @close="closeRepairPopup">
<view class="popup-box repair-popup">
<view class="p-title title-content-s">转维修信息</view>
<scroll-view class="popup-scroll" scroll-y="true">
<u-form labelPosition="top" :model="repairFormData" class="repair-form">
<u-form-item label="客户姓名" borderBottom label-width="100%" style="font-weight: bold;">
<u--input placeholder="请输入客户姓名" v-model="repairFormData.name" border="none"
style="font-weight: normal;"></u--input>
</u-form-item>
<u-form-item label="客户联系电话" borderBottom label-width="100%" style="font-weight: bold;">
<u--input placeholder="请输入客户联系电话" v-model="repairFormData.phone" border="none"
style="font-weight: normal;"></u--input>
</u-form-item>
<u-form-item label="车牌号" borderBottom label-width="100%" style="font-weight: bold;">
<u--input placeholder="请输入车牌号" v-model="repairFormData.carNo" border="none"
style="font-weight: normal;"></u--input>
</u-form-item>
<u-form-item label="车辆品牌" borderBottom label-width="100%" style="font-weight: bold;">
<u--input placeholder="请输入车辆品牌" v-model="repairFormData.brandName" border="none"
style="font-weight: normal;"></u--input>
</u-form-item>
<u-form-item label="车辆型号" borderBottom label-width="100%" style="font-weight: bold;">
<u--input placeholder="请输入车辆型号" v-model="repairFormData.brandModel" border="none"
style="font-weight: normal;"></u--input>
</u-form-item>
<u-form-item label="移交接车人" borderBottom label-width="100%" style="font-weight: bold;">
<view class="select-box" @click="showLzcPicker">
<text v-if="repairFormData.adviserName">{{ repairFormData.adviserName }}</text>
<text v-else class="placeholder">请选择移交接车人</text>
<view class="select-actions">
<u-icon name="arrow-right"></u-icon>
</view>
</view>
</u-form-item>
<u-form-item label="移交接车人(如果列表中没有,请手动输入)" borderBottom label-width="100%"
style="font-weight: bold;">
<u--input placeholder="请输入移交接车人" v-model="repairFormData.adviserNameManual" border="none"
style="font-weight: normal;" :disabled="!!repairFormData.adviserName"></u--input>
</u-form-item>
<u-form-item label="移交接车人电话" borderBottom label-width="100%" style="font-weight: bold;">
<u--input placeholder="请输入移交接车人电话" v-model="repairFormData.adviserPhone" border="none"
style="font-weight: normal;"></u--input>
</u-form-item>
<u-form-item label="备注信息" borderBottom label-width="100%" style="font-weight: bold;">
<u--textarea v-model="repairFormData.remark" placeholder="请输入备注信息" border="none" autoHeight
style="font-weight: normal;"></u--textarea>
</u-form-item>
<!-- 修理厂选择 -->
<u-form-item label="修理厂" borderBottom label-width="100%" style="font-weight: bold;">
<view class="select-box-with-add">
<view class="select-box" @click="repairFactoryShow = true">
<text
v-if="repairFormData.repairFactoryName">{{ repairFormData.repairFactoryName }}</text>
<text v-else class="placeholder">请选择修理厂</text>
<u-icon name="arrow-right"></u-icon>
</view>
<view class="add-button" @click="showAddRepairFactoryModal">
<uni-icons type="plus" size="20" color="#0D2E8D"></uni-icons>
</view>
</view>
</u-form-item>
</u-form>
<!-- 上传状态提示 -->
<view class="upload-tips" v-if="uploadingRecord">
<u-loading-icon size="20" color="#0D2E8D"></u-loading-icon>
<text>照片上传中,请稍候...</text>
</view>
<view class="p-title">现场照片</view>
<view class="huinput">
<u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple
:maxCount="5" :disabled="uploadingRecord"></u-upload>
</view>
</scroll-view>
<view class="button-group">
<view class="cancel-button" @click="closeRepairPopup">
<text>取消</text>
</view>
<view class="confirm-button" @click="confirmRepair">
<text>确认</text>
</view>
</view>
</view>
</u-popup>
<!-- 扣车弹框 -->
<u-popup :show="toDetainShow" mode="center" :round="10" @close="closeDetainPopup">
<view class="popup-box">
<view class="p-title title-content-s">扣车信息</view>
<view @click="showKcPositionPicker" style="margin-top: 40rpx;">
<text style="margin-bottom: 60rpx; font-size: 32rpx; font-weight: bold;">扣车地点:</text>
<text class="tshe">{{ selectedKcPosition || '请选择扣车地点' }}</text>
</view>
<u-form labelPosition="top" :model="kcFormData" class="detain-form">
<u-form-item label="移交接车人" borderBottom label-width="100%" style="font-weight: bold;">
<view class="select-box" @click="showLzcPickerKc">
<text v-if="kcFormData.adviserName">{{ kcFormData.adviserName }}</text>
<text v-else class="placeholder">请选择移交接车人</text>
<view class="select-actions">
<u-icon name="arrow-right"></u-icon>
</view>
</view>
</u-form-item>
<u-form-item label="移交接车人(如果列表中没有,请手动输入)" borderBottom label-width="100%"
style="font-weight: bold;">
<u--input placeholder="请输入移交接车人姓名" v-model="kcFormData.name" border="none"
style="font-weight: normal;" :disabled="!!kcFormData.adviserName"></u--input>
</u-form-item>
<u-form-item label="移交接车人电话" borderBottom label-width="100%" style="font-weight: bold;">
<u--input placeholder="请输入移交接车人电话" v-model="kcFormData.phone" border="none"
style="font-weight: normal;"></u--input>
</u-form-item>
<u-form-item label="备注信息" borderBottom label-width="100%" style="font-weight: bold;">
<u--textarea v-model="kcFormData.remark" placeholder="请输入备注信息" border="none" autoHeight
style="font-weight: normal;"></u--textarea>
</u-form-item>
</u-form>
<!-- 上传状态提示 -->
<view class="upload-tips" v-if="uploadingRecord">
<u-loading-icon size="20" color="#0D2E8D"></u-loading-icon>
<text>照片上传中,请稍候...</text>
</view>
<view class="p-title">现场照片</view>
<view class="huinput">
<u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple
:maxCount="5" :disabled="uploadingRecord"></u-upload>
</view>
<view class="button-group">
<view class="cancel-button" @click="closeDetainPopup">
<text>取消</text>
</view>
<view class="confirm-button" @click="confirmDetain">
<text>确认扣车</text>
</view>
</view>
</view>
</u-popup>
<!-- 移交客户弹框 -->
<u-popup :show="toHandoverShow" mode="center" :round="10" @close="closeHandoverPopup">
<view class="popup-box">
<view class="p-title title-content-s">{{ handoverTitle }}</view>
<u-form labelPosition="top" :model="handoverFormData" class="repair-form">
<u-form-item label="移交接车人姓名" borderBottom label-width="100%" style="font-weight: bold;">
<u--input placeholder="请输入移交接车人姓名" v-model="handoverFormData.name" border="none"
style="font-weight: normal;"></u--input>
</u-form-item>
<u-form-item label="移交接车人电话" borderBottom label-width="100%" style="font-weight: bold;">
<u--input placeholder="请输入移交接车人电话" v-model="handoverFormData.phone" border="none"
style="font-weight: normal;"></u--input>
</u-form-item>
<u-form-item label="备注信息" borderBottom label-width="100%" style="font-weight: bold;">
<u--textarea v-model="handoverFormData.remark" placeholder="请输入备注信息" border="none" autoHeight
style="font-weight: normal;"></u--textarea>
</u-form-item>
</u-form>
<!-- 上传状态提示 -->
<view class="upload-tips" v-if="uploadingRecord">
<u-loading-icon size="20" color="#0D2E8D"></u-loading-icon>
<text>照片上传中,请稍候...</text>
</view>
<view class="p-title">现场照片</view>
<view class="huinput">
<u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple
:maxCount="5" :disabled="uploadingRecord"></u-upload>
</view>
<view class="button-group">
<view class="cancel-button" @click="closeHandoverPopup" :disabled="uploadingRecord">
<text>取消</text>
</view>
<view class="confirm-button" @click="confirmHandover" :disabled="uploadingRecord">
<text>确认移交</text>
</view>
</view>
</view>
</u-popup>
<!-- 补充照片弹窗 -->
<u-popup :show="supplementShow" mode="center" :round="10" @close="closeSupplementPopup"
:closeOnClickOverlay="false">
<view class="popup-box_bc">
<view class="p-title">补充照片</view>
<view class="upload-tips" v-if="uploading">
<u-loading-icon size="20" color="#0D2E8D"></u-loading-icon>
<text>照片上传中,请稍候...</text>
</view>
<view class="huinput">
<u-upload :fileList="supplementFileList" @afterRead="supplementAfterRead"
@delete="deleteSupplementPic" name="supplement" multiple :maxCount="10"
:disabled="uploading"></u-upload>
</view>
<view class="button-group">
<view class="cancel-button" @click="closeSupplementPopup" :disabled="uploading">
<text>取消</text>
</view>
<view class="confirm-button" @click="confirmSupplement" :disabled="uploading">
<text>确认</text>
</view>
</view>
</view>
</u-popup>
<!-- 费用主弹框 -->
<u-popup :show="showFeePopup" mode="center" :round="10" @close="closeFeePopup" :closeOnClickOverlay="false">
<view class="popup-box_sf">
<view class="p-title">费用信息</view>
<view class="payment-options">
<view style="display: flex; flex-direction: row; justify-content: center; align-items: center;">
<view class="payment-option" :class="{'active': selectedPayment === 'shouldCharge'}"
@click="selectPayment('shouldCharge')">
<text style="font-size: 36rpx;">应收费用信息</text>
</view>
<view v-if="orderData && orderData.dispatchIsConfirmCharge == '1'">
<uni-icons type="checkbox" color="#67c23a" size="30"></uni-icons>
</view>
</view>
<view style="display: flex; flex-direction: row; justify-content: center; align-items: center;">
<view class="payment-option" :class="{'active': selectedPayment === 'shouldPay'}"
@click="selectPayment('shouldPay')">
<text style="font-size: 36rpx;">应付费用信息</text>
</view>
<view v-if="orderData && orderData.dispatchIsConfirmShouldPay == '1'">
<uni-icons type="checkbox" color="#67c23a" size="30"></uni-icons>
</view>
</view>
</view>
<view style="color: red; font-size: 28rpx;"
v-if="orderData && orderData.dispatchIsConfirmCharge == '1' && orderData.dispatchIsConfirmShouldPay == '1' ">
*全部确认无误之后,请点击 <text style="font-weight: bold;"> 核算完成 </text> 按钮
</view>
<view class="button-group">
<view class="cancel-button" @click="closeFeePopup">
<text>取消</text>
</view>
<view class="open-button" @click="confirmPayment">
<text>打开</text>
</view>
<view class="confirm-button-new" style="margin-left: 20rpx;" @click="confirmAllFeeMsg"
v-if="orderData && orderData.dispatchIsConfirmCharge == '1' && orderData.dispatchIsConfirmShouldPay == '1' ">
<text>核算完成</text>
</view>
</view>
</view>
</u-popup>
<!-- 应收费用弹框 -->
<u-popup :show="showShouldChargePopup" mode="center" :round="10" @close="closeShowShouldChargePopup"
:closeOnClickOverlay="false">
<view class="popup-box_ys">
<view class="p-title">应收费用信息</view>
<scroll-view class="popup-scroll" scroll-y="true">
<view class="ysfy-top">司机收取费用信息</view>
<view class="huinput_sf_top">
<text class="pay_font" style="margin-bottom: 2rpx; margin-right: 20rpx;">拖车费用:</text>
<text v-if="orderData && orderData.towingFee">{{orderData.towingFee}} 元</text>
<text v-else>暂未设置</text>
</view>
<view class="huinput_sf_top">
<text class="pay_font" style="margin-bottom: 2rpx; margin-right: 20rpx;">吊车费用:</text>
<text v-if="orderData && orderData.craneFee">{{orderData.craneFee}} 元</text>
<text v-else>暂未设置</text>
</view>
<view class="huinput_sf_top">
<text class="pay_font" style="margin-bottom: 2rpx; margin-right: 20rpx;">其他费用:</text>
<text v-if="orderData && orderData.otherFee">{{orderData.otherFee}} 元</text>
<text v-else>暂未设置</text>
</view>
<view class="huinput_sf_two">
<text class="pay_font" style="margin-bottom: 2rpx; margin-right: 20rpx;">其他费用备注:</text>
<text-area v-if="orderData && orderData.otherFeeRemark"
style="padding: 10rpx;">{{orderData.otherFeeRemark}}</text-area>
<text-area v-else style="padding: 10rpx;">暂未设置</text-area>
</view>
<view class="huinput_sf_top">
<text class="pay_font"
style="color: red; margin-bottom: 2rpx; margin-right: 20rpx;">总计金额:</text>
<text v-if="orderData && orderData.setMoney">{{orderData.setMoney}} 元</text>
<text v-else>暂未设置</text>
</view>
<view class="huinput_sf_top">
<text class="pay_font" style="margin-bottom: 2rpx; margin-right: 20rpx;">收款方式:</text>
<text v-if="orderData && orderData.payType">{{orderData.payType}}</text>
<text v-else>暂未设置</text>
</view>
<view style="border-top: 3px solid #d0d0d0; margin-top: 10rpx; width: 100%;"></view>
<view class="ysfy-top">调度确认应收费信息</view>
<view class="huinput_sf">
<text class="pay_font" style="margin-bottom: 2rpx; margin-right: 20rpx;">拖车费用:</text>
<u--input type="number" v-model="orderData.dispatchTowingFee" placeholder="请输入拖车费用"
border="surround" clearable @input="calculateShouldChargeTotalAmount"
customStyle="padding: 2rpx; margin-right: 20rpx;"></u--input>
</view>
<view class="huinput_sf">
<text class="pay_font" style="margin-bottom: 2rpx; margin-right: 20rpx;">吊车费用:</text>
<u--input type="number" v-model="orderData.dispatchCraneFee" placeholder="请输入吊车费用"
border="surround" clearable @input="calculateShouldChargeTotalAmount"
customStyle="padding: 2rpx; margin-right: 20rpx;"></u--input>
</view>
<view class="huinput_sf">
<text class="pay_font" style="margin-bottom: 2rpx; margin-right: 20rpx;">其他费用:</text>
<u--input type="number" v-model="orderData.dispatchOtherFee" placeholder="请输入其他费用"
border="surround" clearable @input="calculateShouldChargeTotalAmount"
customStyle="padding: 2rpx; margin-right: 20rpx;"></u--input>
</view>
<view class="huinput_sf_two">
<text class="pay_font" style="margin-bottom: 10rpx;">其他费用备注:</text>
<textarea v-model="orderData.dispatchOtherFeeRemark" placeholder="请输入其他费用备注" auto-height
adjust-position
style="border: 2rpx solid rgba(151, 151, 152, 0.20); padding: 14rpx; width: 93%;"></textarea>
</view>
<view class="huinput_sf">
<text class="pay_font"
style="color: red;margin-bottom: 2rpx;margin-right: 20rpx;">应收总计金额:</text>
<u--input type="number" v-model="orderData.dispatchSumFee" placeholder="请输入应收总计金额"
border="surround" clearable color='red'
customStyle="font-weight: bold; padding: 2rpx; margin-right: 20rpx;"></u--input>
</view>
<view class="huinput_sf_two">
<text class="pay_font" style="margin-bottom: 10rpx;">备注信息:</text>
<textarea v-model="orderData.dispatchConfirmChargeRemark" placeholder="请输入备注信息" border="bottom"
auto-height adjust-position
style="border: 2rpx solid rgba(151, 151, 152, 0.20); padding: 14rpx; width: 93%;"></textarea>
</view>
<!-- 上传状态提示 -->
<view class="upload-tips" v-if="uploadingPayment">
<u-loading-icon size="20" color="#0D2E8D"></u-loading-icon>
<text>照片上传中,请稍候...</text>
</view>
<view class="pay_font">凭证照片</view>
<view class="huinput_sf">
<u-upload :fileList="paymentFileListCharge" @afterRead="paymentAfterReadCharge"
@delete="deletePaymentPicCharge" name="paymentCharge" multiple :maxCount="3"
:disabled="uploadingPayment"></u-upload>
</view>
</scroll-view>
<view>
<view v-if="!orderData.id" style="color: red;">* 当前工单暂未指派或暂无司机接单</view>
<view class="button-group">
<view class="cancel-button" @click="closeShowShouldChargePopup">
<text>取消</text>
</view>
<view class="confirm-button" @click="shouldChargeConfirm" :class="{ 'disabled': !orderData.id }"
:style="!orderData.id ? 'background-color: #ccc;' : ''" :disabled="!orderData.id">
<text>确认</text>
</view>
</view>
</view>
</view>
</u-popup>
<!-- 应付费用弹框 -->
<u-popup :show="showShouldPayPopup" mode="center" :round="10" @close="closeShowShouldPayPopup"
:closeOnClickOverlay="false">
<view class="popup-box_yf">
<view class="p-title">应付费用信息</view>
<scroll-view class="popup-scroll" scroll-y="true">
<view class="huinput_sf_two">
<text class="pay_font" style="margin-bottom: 2rpx; ">应付拖车费用(元):</text>
<u--input type="number" v-model="orderData.dispatchShouldPayTowingFee" placeholder="请输入拖车费用"
border="surround" clearable @input="calculateShouldPayTotalAmount"></u--input>
</view>
<view class="huinput_sf_two">
<text class="pay_font" style="margin-bottom: 2rpx; ">应付吊车费用(元):</text>
<u--input type="number" v-model="orderData.dispatchShouldPayCraneFee" placeholder="请输入吊车费用"
border="surround" clearable @input="calculateShouldPayTotalAmount"></u--input>
</view>
<view class="huinput_sf_two">
<text class="pay_font" style="margin-bottom: 2rpx;">应付其他费用(元):</text>
<u--input type="number" v-model="orderData.dispatchShouldPayOtherFee" placeholder="请输入其他费用"
border="surround" clearable @input="calculateShouldPayTotalAmount"></u--input>
</view>
<view class="huinput_sf_two">
<text class="pay_font" style="margin-bottom: 2rpx;">应付其他费用备注:</text>
<textarea v-model="orderData.dispatchShouldPayOtherFeeRemark" placeholder="请输入其他费用备注"
auto-height adjust-position
style="border: 2rpx solid rgba(151, 151, 152, 0.20); padding: 14rpx; width: 93%;"></textarea>
</view>
<view class="huinput_sf_two">
<text class="pay_font" style="color: red;">应付总计金额(元):</text>
<u--input type="number" v-model="orderData.dispatchShouldPaySumFee" placeholder="请输入应付金额"
border="surround" clearable style="font-weight: bold;" color='red'></u--input>
</view>
<view class="huinput_sf_two">
<text class="pay_font">应付费用备注信息:</text>
<u--textarea v-model="orderData.dispatchShouldPayRemark" placeholder="请输入备注信息" border="bottom"
autoHeight></u--textarea>
</view>
<!-- 上传状态提示 -->
<view class="upload-tips" v-if="uploadingPayment">
<u-loading-icon size="20" color="#0D2E8D"></u-loading-icon>
<text>照片上传中,请稍候...</text>
</view>
<view class="pay_font">凭证照片</view>
<view class="huinput_sf_two">
<u-upload :fileList="paymentFileListPay" @afterRead="paymentAfterReadPay"
@delete="deletePaymentPicPay" name="paymentPay" multiple :maxCount="3"
:disabled="uploadingPayment"></u-upload>
</view>
</scroll-view>
<view>
<view v-if="!orderData.id" style="color: red;">* 当前工单暂未指派或暂无司机接单</view>
<view class="button-group">
<view class="cancel-button" @click="closeShowShouldPayPopup">
<text>取消</text>
</view>
<view class="confirm-button" @click="shouldPayConfirm" :class="{ 'disabled': !orderData.id }"
:style="!orderData.id ? 'background-color: #ccc;' : ''" :disabled="!orderData.id">
<text>确认</text>
</view>
</view>
</view>
</view>
</u-popup>
<u-popup :show="showAddRepairFactoryModalView" mode="center" :round="10" @close="closeAddRepairFactoryModal">
<view class="popup-box">
<view class="p-title">新增修理厂</view>
<view class="huinput">
<u--input v-model="newRepairFactoryName" placeholder="请输入修理厂名称" border="bottom"></u--input>
</view>
<view class="button-group">
<view class="cancel-button" @click="closeAddRepairFactoryModal">
<text>取消</text>
</view>
<view class="confirm-button" @click="addNewRepairFactory">
<text>确认</text>
</view>
</view>
</view>
</u-popup>
<!-- 现场照片编辑弹窗 -->
<u-popup :show="editPhotoShow" mode="center" :round="10" @close="closeEditPhotoPopup"
:closeOnClickOverlay="false">
<view class="popup-box_bc">
<view class="p-title">编辑照片</view>
<view class="upload-tips" v-if="uploading">
<u-loading-icon size="20" color="#0D2E8D"></u-loading-icon>
<text>照片上传中,请稍候...</text>
</view>
<view class="huinput">
<u-upload :fileList="editFileList" @afterRead="editAfterRead" @delete="deleteEditPic" name="edit"
multiple :maxCount="10" :disabled="uploading"></u-upload>
</view>
<view class="button-group">
<view class="cancel-button" @click="closeEditPhotoPopup" :disabled="uploading">
<text>取消</text>
</view>
<view class="confirm-button" @click="confirmEditPhoto" :disabled="uploading">
<text>确认</text>
</view>
</view>
</view>
</u-popup>
<!-- 服务顾问选择器 -->
<lzc-picker ref="lzcPicker" :pickerList="staffList" pickerTittle="选择移交接车人"
@change="onLzcPickerConfirm"></lzc-picker>
<!-- 扣车人员选择 -->
<lzc-picker ref="lzcPickerKc" :pickerList="staffList" pickerTittle="选择移交接车人"
@change="onKcLzcPickerConfirm"></lzc-picker>
<!-- 扣车地点选择 -->
<u-picker :show="kcPositionShow" :columns="[kcPositionList]" keyName="label" @confirm="onKcPositionConfirm"
@cancel="kcPositionShow = false"></u-picker>
<!-- 调度人员选择器 -->
<u-picker :show="dispatcherPickerShow" :columns="dispatcherColumns" keyName="nickname"
@confirm="onDispatcherConfirm" @cancel="dispatcherPickerShow = false">
</u-picker>
<!-- 修理厂选择器 -->
<u-picker :show="repairFactoryShow" :columns="[repairFactoryList]" keyName="label"
@confirm="onRepairFactoryConfirm" @cancel="repairFactoryShow = false"></u-picker>
<!-- // 底部按钮 -->
<view class="fixed-bottom-button_1" v-if="this.dispatchStepIndex <= (this.recordSteps.length + 1)">
<button @click="diyshow(detailsData.id)" :style="{backgroundColor: isProcessFinished ? '#999' : '#1b5dfd'}"
:disabled="isProcessFinished">
{{ nextStepName }}
</button>
</view>
</view>
</template>
<script>
import request from '../../utils/request';
import dayjs from '../../uni_modules/uview-ui/libs/util/dayjs';
import upload from '@/utils/upload.js';
import lzcPicker from '@/components/lzc-picker/lzc-picker.vue';
import {
getTenantId,
hasRole
} from "@/utils/auth";
export default {
components: {
lzcPicker
},
data() {
return {
rescueId: null,
show: false,
terminateShow: false,
endShow: false,
toSceneShow: false,
againYesToSceneShow: false,
qdList: [],
skindex: 0,
carNumList: [],
carindex: 0,
ifNewEnergyIndex: 0,
codeShow: false,
carNumShow: false,
roadShow: false,
roadList: [],
sourceShow: false,
sourceList: [],
carList: [],
rescueDetail: '',
id: 0,
baseUrl: this.$baseUrl,
baseImageUrl: this.$baseImageUrlNew,
type: 'center',
msgType: 'success',
imageList: [],
isLoop: true,
messageText: '这是一条成功提示',
msg: '1',
detailsData: {},
orderData: {},
singleList: [],
detailList: [],
tabindex: 0,
title: 'user',
checkedindex: false,
destinationLongitude: '',
destinationLatitude: '',
destinationInfo: '请选择',
province1: '',
city1: '',
area1: '',
four1: '',
recordShow: false,
recordSteps: [], // 记录流程步骤
dispatchStepIndex: null, // 当前步骤索引
nextStepName: '记录', // 下一步按钮文字
fileList1: [],
ulImages: [],
dictLabel: '',
dictValue: '',
remark: '',
isProcessFinished: false,
selectedOption: '', // 用于存储选中的选项
show1: false,
setMoney: '',
setMoneyWx: '',
confirmedSetMoney: '',
// 新增转维修相关数据
toRepairShow: false, // 转维修弹框显示
adviserShow: false, // 服务顾问选择器显示
kcAdviserShow: false, // 服务顾问选择器显示
repairFormData: { // 转维修表单数据
name: '',
phone: '',
brandName: '',
brandModel: '',
adviserName: '',
adviserId: '',
adviserPhone: '',
remark: '',
adviserNameManual: '',
repairFactoryName: '',
carNo: '',
},
staffList: [], // 服务顾问列表
toDetainShow: false, // 扣车弹框显示
kcPositionShow: false, // 扣车地点选择器显示
selectedKcPosition: '', // 选中的扣车地点
kcPositionList: [], // 扣车地点列表
kcFormData: {
isKouChe: 0,
kcPosition: '',
name: '',
phone: '',
remark: '',
adviserName: '',
adviserId: '',
adviserPhone: '',
},
// 移交客户相关
toHandoverShow: false,
handoverTitle: '移交客户',
handoverType: '', // 记录移交类型
handoverFormData: { // 转维修表单数据
name: '',
phone: '',
remark: '',
},
// 补充相片相关
// 控制弹窗显示
supplementShow: false,
// 上传文件列表
supplementFileList: [],
// 已上传的图片URL数组
supplementImages: [],
// 上传状态
uploading: false,
// 当前操作的流程项
currentSupplementItem: null,
// 救援开始弹框显示状态
acceptOrderShow: false,
startScale: '',
uploadingRecord: false,
// 收费弹框相关数据
showFeePopup: false,
showShouldPayPopup: false,
showShouldChargePopup: false,
selectedPayment: '',
paymentAmount: '',
changeAmount: '',
creditTarget: '',
// 收款相关备注
creditRemark: '',
// 挂账收款负责人
amountDirector: '',
// 子支付弹框显示状态
showCashPopup: false,
showCreditPopup: false,
// 支付相关数据
paymentFileList: [], // 支付凭证文件列表
paymentImages: [], // 已上传的支付凭证图片URL
uploadingPayment: false, // 支付凭证上传状态
isSubmitting: false,
// 调度人员信息
dispatcherColumns: [],
// 调度人员选择器显示状态
dispatcherPickerShow: false,
// 选中的调度人员姓名
selectedDispatcherName: '',
// 选中的调度人员ID
selectedDispatcherId: '',
repairFactoryShow: false, // 修理厂选择器显示状态
repairFactoryList: [], // 修理厂列表
showAddRepairFactoryModalView: false, // 新增修理厂弹框显示状态
newRepairFactoryName: '', // 新修理厂名称
faultPhenomenonShow: false,
faultPhenomenonList: [],
faultTypeShow: false,
faultTypeList: [],
// 现有变量保持不变...
editPhotoShow: false, // 编辑照片弹窗显示状态
editFileList: [], // 编辑文件列表
editImages: [], // 已编辑的图片URL数组
currentEditItem: null, // 当前编辑的流程项
editField: '', // 编辑的字段名images或supplementImages
// 拖车费用
towingFee: 0,
// 吊车费用
craneFee: 0,
//其他费用
otherFee: 0,
//其他费用备注
otherFeeRemark: '',
ifNewEnergyList: [{
label: '是',
value: 1
},
{
label: '否',
value: 0
},
],
dispatchArriveScale: null,
dispatchStartScale: null,
userinfo: {},
paymentImagesCharge: [], // 应收费用凭证图片
paymentImagesPay: [], // 应付费用凭证图片
paymentFileListCharge: [], // 应收费用文件列表
paymentFileListPay: [], // 应付费用文件列表
}
},
onLoad(option) {
this.id = option.id
this.rescueId = option.id
this.getrescueDetail(option.id)
this.newtwo()
this.getRoadList(false);
this.getSourceList(false)
this.getSecondDispatcher()
},
mounted() {
this.getStaffList()
this.getKcPositionList()
},
onShow() {
this.userinfo = uni.getStorageSync('userInfo')
},
computed: {
isEditableStatus() {
const editableStatuses = ['1', '2', '3', '4'];
return editableStatuses.includes(this.detailsData.rescueStatus);
}
},
methods: {
// 自动计算调度确认应收总计金额
calculateShouldChargeTotalAmount() {
const towing = parseFloat(this.orderData.dispatchTowingFee) || 0;
const crane = parseFloat(this.orderData.dispatchCraneFee) || 0;
const other = parseFloat(this.orderData.dispatchOtherFee) || 0;
const total = towing + crane + other;
this.orderData.dispatchSumFee = total;
},
// 自动计算调度确认应付总计金额
calculateShouldPayTotalAmount() {
const towing = parseFloat(this.orderData.dispatchShouldPayTowingFee) || 0;
const crane = parseFloat(this.orderData.dispatchShouldPayCraneFee) || 0;
const other = parseFloat(this.orderData.dispatchShouldPayOtherFee) || 0;
const total = towing + crane + other;
this.orderData.dispatchShouldPaySumFee = total;
},
chooseRoad(data) {
console.log(data);
this.detailsData.channel = data.value[0].label
this.roadShow = false
},
chooseFaultType(data) {
console.log(data);
this.detailsData.faultType = data.value[0].name;
this.faultTypeShow = false;
},
chooseFaultPhenomenon(data) {
console.log(data);
this.detailsData.phenomenon = data.value[0].name;
this.faultPhenomenonShow = false;
},
chooseCar(data) {
this.carNumShow = false
this.detailsData.driverCarNum = data.value[0].rescueCarNum
},
getRoadList(flag = true) {
request({
url: '/system/rescueInfo/getRescueChannel',
method: 'get'
}).then((res) => {
this.roadShow = flag
this.roadList = res.data
})
},
chooseSource(data) {
console.log(data);
this.detailsData.source = data.value[0].label
this.sourceShow = false
},
getSourceList(flag = true) {
request({
url: '/system/rescueInfo/getRescueSource',
method: 'get'
}).then((res) => {
this.sourceShow = flag
this.sourceList = res.data
})
},
lookimg(idx, tmpList) {
let resList = [];
tmpList.forEach(it => {
resList.push(this.baseImageUrl + it)
})
uni.previewImage({
urls: resList,
current: idx,
indicator: 'none',
loop: this.isLoop
})
},
// 修改工单信息
confirmadd() {
let data = this.detailsData
request({
// url: '/app/rescueInfo/edit',
url: '/app/driver/updateRescueInfo',
method: 'put',
data: data
}).then((res) => {
console.log(res);
if (res.code == 200) {
uni.showToast({
title: '修改成功',
icon: 'success'
})
this.terminateShow = false
this.getrescueDetail(this.detailsData.id)
}
})
},
// 上传调度流程信息
uploadDispatchDetail(data) {
request({
url: '/app/driver/uploadDispatchDetailByDriver',
method: 'post',
data: data
});
},
cancelopen() {
this.show = false
},
// 终止操作相关
cancelTerminateOpen() {
this.terminateShow = false
},
cancelTerminateConfirm() {
let data = this.detailsData
data.dispatchRecordStep = 5
request({
url: '/app/driver/updateRescueInfo',
method: 'put',
data: data
}).then((res) => {
console.log(res);
if (res.code == 200) {
uni.showToast({
title: '已终止',
icon: 'success'
})
this.terminateShow = false
let dispatchDetailsData = {
rescueInfoId: this.rescueId,
title: '调度终止流程',
type: '0',
};
if (this.detailsData && this.detailsData.secondDispatchName && this.detailsData
.secondDispatchName != '' && this.detailsData.secondDispatchPhone && this
.detailsData.secondDispatchPhone != '') {
dispatchDetailsData.autoRemark = '调度: ' + this.detailsData.secondDispatchName +
', ' + '调度电话: ' + this.detailsData.secondDispatchPhone
}
this.uploadDispatchDetail(dispatchDetailsData)
this.getrescueDetail(this.detailsData.id)
}
})
},
// 结束订单操作相关
cancelEndOpen() {
this.endShow = false
},
cancelEndConfirm() {
let data = this.detailsData
data.dispatchRecordStep = 8
data.rescueStatus = 5
request({
url: '/app/driver/updateRescueInfo',
method: 'put',
data: data
}).then((res) => {
console.log(res);
if (res.code == 200) {
uni.showToast({
title: '已结束',
icon: 'success'
})
this.endShow = false
let dispatchDetailsData = {
rescueInfoId: this.rescueId,
title: '调度结束订单',
type: '0',
};
if (this.detailsData && this.detailsData.secondDispatchName && this.detailsData
.secondDispatchName != '' && this.detailsData.secondDispatchPhone && this
.detailsData.secondDispatchPhone != '') {
dispatchDetailsData.autoRemark = '调度: ' + this.detailsData.secondDispatchName +
', ' + '调度电话: ' + this.detailsData.secondDispatchPhone
}
this.uploadDispatchDetail(dispatchDetailsData)
this.getrescueDetail(this.detailsData.id)
}
})
},
// 出发现场相关
cancelToSceneOpen() {
this.toSceneShow = false
this.againYesToSceneShow = false
},
cancelToSceneConfirm(to) {
let data = this.detailsData
if (to == 'noTo') {
data.dispatchRecordStep = 5
data.isDispatchedToScene = '0'
}
if (to == 'yesTo') {
data.dispatchRecordStep = data.dispatchRecordStep + 1
data.isDispatchedToScene = '1'
}
if (to == 'againYesTo') {
data.dispatchRecordStep = 2
data.isDispatchedToScene = '1'
}
request({
url: '/app/driver/updateRescueInfo',
method: 'put',
data: data
}).then((res) => {
console.log(res);
if (res.code == 200) {
this.toSceneShow = false
this.againYesToSceneShow = false
let dispatchDetailsData = {
rescueInfoId: this.rescueId,
type: '0',
};
if (to == 'noTo') {
dispatchDetailsData.title = '调度确认不出发现场'
if (this.detailsData && this.detailsData.secondDispatchName && this.detailsData
.secondDispatchName != '' && this.detailsData.secondDispatchPhone && this
.detailsData.secondDispatchPhone != '') {
dispatchDetailsData.autoRemark = '调度: ' + this.detailsData.secondDispatchName +
', ' + '调度电话: ' + this.detailsData.secondDispatchPhone
}
}
if (to == 'yesTo' || to == 'againYesTo') {
dispatchDetailsData.title = '调度确认出发现场'
if (this.detailsData && this.detailsData.secondDispatchName && this.detailsData
.secondDispatchName != '' && this.detailsData.secondDispatchPhone && this
.detailsData.secondDispatchPhone != '') {
dispatchDetailsData.autoRemark = '调度: ' + this.detailsData.secondDispatchName +
', ' + '调度电话: ' + this.detailsData.secondDispatchPhone
}
}
this.uploadDispatchDetail(dispatchDetailsData)
this.getrescueDetail(this.detailsData.id)
}
})
},
newtwo() {
request({
url: '/rescue/dict/data/type/fee_type',
method: 'get',
}).then((res) => {
console.log('fee_type', res);
this.qdList = res.data
})
request({
url: '/rescue/dict/data/type/rescue_car_type',
method: 'get',
}).then((res) => {
this.carList = res.data
console.log('rescue_car_type', res);
})
},
gogogo() {
uni.openLocation({
latitude: parseFloat(this.detailsData.rescueLatitude),
longitude: parseFloat(this.detailsData.rescueLongitude),
success: function() {
console.log('success');
},
complete: function(res) {
console.log(res);
}
});
},
goback() {
uni.navigateBack()
},
gotel(num) {
uni.makePhoneCall({
phoneNumber: num
});
},
getrescueDetail(id) {
uni.showLoading({
title: '刷新中'
});
request({
url: '/app/driver/rescueDetailByDispatch?rescueId=' + id,
method: 'get',
}).then((res) => {
console.log('详情', res);
this.detailsData = res.data.rescueInfo
if (res.data.orderInfo) {
this.orderData = res.data.orderInfo
if (res.data.orderInfo.setMoney) {
this.orderData.setMoney = res.data.orderInfo.setMoney / 100
}
if (res.data.orderInfo.payType) {
if (res.data.orderInfo.payType == 'wx') {
this.orderData.payType = '微信'
} else if (res.data.orderInfo.payType == 'qd') {
this.orderData.payType = '挂账'
} else if (res.data.orderInfo.payType == 'xj') {
this.orderData.payType = '现金'
}
}
}
this.carindex = res.data.rescueInfo.carType // 回显车型
this.ifNewEnergyIndex = res.data.rescueInfo.ifNewEnergy
this.skindex = res.data.rescueInfo.feeType
this.detailList = res.data.detailList
if (res.data.rescueInfo.dispatchRecordStep != null) {
this.dispatchStepIndex = res.data.rescueInfo.dispatchRecordStep
}
if (this.detailList && this.detailList.length > 0) {
this.detailList.forEach(item => {
if (item.createTime) {
item.createTime = dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss')
}
})
}
if (res.data.rescueInfo.setMoney != null) {
this.setMoneyWx = res.data.rescueInfo.setMoney / 100
this.confirmedSetMoney = res.data.rescueInfo.setMoney / 100
}
this.getRecordSteps();
uni.hideLoading();
})
},
dialogToggle() {
this.$refs.alertDialog.open()
},
inputDialogToggle() {
this.$refs.inputDialog.open()
},
dialogClose() {
console.log('点击关闭')
},
dialogInputConfirm(val) {
this.$refs.inputDialog.close()
},
gettab(index) {
this.tabindex = index
},
/* diyshow(id) {
if (this.isProcessFinished) {
uni.showToast({
title: '流程已结束',
icon: 'none'
});
return;
}
this.rescueId = id;
if (this.recordSteps.length > 0) {
this.dictValue = this.recordSteps[this.dispatchStepIndex - 1].value;
this.dictLabel = this.recordSteps[this.dispatchStepIndex - 1].label;
}
if (this.dispatchStepIndex === 2) {
// 只显示出发里程输入
this.dispatchStartScale = '';
this.acceptOrderShow = true;
} else if (this.dispatchStepIndex === 1) {
this.toSceneShow = true
} else if (this.dispatchStepIndex === 3) {
// 只显示到达里程输入
this.dispatchArriveScale = '';
this.acceptOrderShow = true;
} else if (this.dispatchStepIndex === 6) {
this.showFeePopup = true
} else {
this.recordShow = true;
}
// 调度确认订单完成之前需要司机先确认完成订单
}, */
diyshow(id) {
if (this.isProcessFinished) {
uni.showToast({
title: '流程已结束',
icon: 'none'
});
return;
}
// 添加检查当dispatchStepIndex为7且rescueStatus不等于4时弹出确认框
if (this.dispatchStepIndex === 7 && this.detailsData.rescueStatus !== '4') {
uni.showModal({
title: '提示',
content: '司机尚未确认订单完成,是否继续?',
confirmText: '是',
cancelText: '否',
success: (res) => {
if (res.confirm) {
// 用户选择继续,执行原有逻辑
this.continueDiyshow(id);
} else {
// 用户选择取消,不执行任何操作
console.log('用户取消操作');
}
}
});
} else {
// 正常执行原有逻辑
this.continueDiyshow(id);
}
},
// 将原有diyshow的逻辑提取到这个方法中
continueDiyshow(id) {
this.rescueId = id;
if (this.recordSteps.length > 0) {
this.dictValue = this.recordSteps[this.dispatchStepIndex - 1].value;
this.dictLabel = this.recordSteps[this.dispatchStepIndex - 1].label;
}
if (this.dispatchStepIndex === 2) {
// 只显示出发里程输入
this.dispatchStartScale = '';
this.acceptOrderShow = true;
} else if (this.dispatchStepIndex === 1) {
this.toSceneShow = true
} else if (this.dispatchStepIndex === 3) {
// 只显示到达里程输入
this.dispatchArriveScale = '';
this.acceptOrderShow = true;
} else if (this.dispatchStepIndex === 6) {
this.showFeePopup = true
} else {
this.recordShow = true;
}
},
cancelRecord() {
this.recordShow = false;
this.remark = ''; // 清空备注
this.fileList1 = []; // 清空图片列表
this.selectedOption = '';
this.ulImages = [];
},
deletePic(event) {
// 从 fileList 中删除
this[`fileList${event.name}`].splice(event.index, 1);
// 重新构建 ulImages
this.ulImages = this.fileList1
.filter(item => item.status === 'success')
.map(item => item.url);
console.log('this.fileList1', this.fileList1)
},
// 新增图片
async afterRead(event) {
// 设置上传状态
this.uploadingRecord = true;
// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file)
let fileListLen = this[`fileList${event.name}`].length
lists.map((item) => {
this[`fileList${event.name}`].push({
...item,
status: 'uploading' // 设置初始状态为上传中
})
})
for (let i = 0; i < lists.length; i++) {
try {
const result = await this.uploadFilePromise(lists[i].url)
let item = this[`fileList${event.name}`][fileListLen]
this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
status: 'success',
message: '',
url: result
}))
fileListLen++
} catch (error) {
console.error('上传失败:', error);
let item = this[`fileList${event.name}`][fileListLen]
this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
status: 'failed',
message: '上传失败'
}))
fileListLen++
}
}
// 上传完成,取消上传状态
this.uploadingRecord = false;
},
uploadFilePromise(url) {
return new Promise((resolve, reject) => {
upload({
url: '/infra/file/upload',
filePath: url,
}).then((res) => {
console.log('ulImages', res.data);
this.ulImages.push(res.data)
resolve(res.data);
}).catch(reject);
});
},
uploadFilePromiseSupplement(url) {
return new Promise((resolve, reject) => {
upload({
url: '/infra/file/upload',
filePath: url,
}).then((res) => {
console.log('supplementImages', res.data);
// this.supplementImages.push(res.data);
resolve(res.data);
}).catch(reject);
});
},
getRecordSteps() {
request({
url: '/rescue/dict/data/type/rescue_dispatch_process',
method: 'get'
}).then(res => {
this.recordSteps = res.data.sort((a, b) => a.value - b.value);
console.log('this.recordSteps', this.recordSteps)
console.log('this.recordSteps111111111111111111111111', this.recordSteps.length)
// 修正:使用 value 来查找对应的步骤
const currentStep = this.recordSteps.find(step => step.value == this.dispatchStepIndex);
if (!currentStep) {
this.isProcessFinished = true;
this.nextStepName = '流程结束';
} else {
this.isProcessFinished = false;
this.nextStepName = `下一步:${currentStep.label}`;
}
});
},
// 获取位置
getLocation() {
return new Promise((resolve, reject) => {
uni.getLocation({
isHighAccuracy: true,
success: (res) => resolve(res),
fail: (error) => reject(error)
});
});
},
/** 获取服务顾问列表 */
getStaffList() {
if (this.staffList.length > 0) return;
request({
url: '/system/role/selectListByRoleIdJYNew',
method: 'get',
params: {
pageSize: 1000,
pageNum: 1
}
}).then((res) => {
if (res.code == 200) {
this.staffList = res.data.records;
}
console.log('服务顾问res', res)
}).catch(error => {
console.error('获取服务顾问列表失败:', error);
});
},
getKcPositionList() {
request({
url: '/rescue/dict/data/type/kcPosition-' + getTenantId(),
method: 'get'
}).then(res => {
this.kcPositionList = res.data
})
},
// 显示自定义选择器
showLzcPicker() {
if (this.staffList.length === 0) {
this.getStaffList().then(() => {
this.$refs.lzcPicker.handleShow();
});
} else {
this.$refs.lzcPicker.handleShow();
}
},
showLzcPickerKc() {
if (this.staffList.length === 0) {
this.getStaffList().then(() => {
this.$refs.lzcPickerKc.handleShow();
});
} else {
this.$refs.lzcPickerKc.handleShow();
}
},
// 自定义选择器确认
onLzcPickerConfirm(selectedItem) {
this.repairFormData.adviserName = selectedItem.nickname;
this.repairFormData.adviserId = selectedItem.id;
this.repairFormData.userId = selectedItem.id;
this.repairFormData.adviserPhone = selectedItem.mobile || '';
},
onKcLzcPickerConfirm(selectedItem) {
this.kcFormData.adviserName = selectedItem.nickname;
this.kcFormData.adviserId = selectedItem.id;
this.kcFormData.userId = selectedItem.id;
this.kcFormData.phone = selectedItem.mobile || '';
},
onKcPositionConfirm(e) {
this.selectedKcPosition = e.value[0].label
this.kcFormData.isKouChe = 1
this.kcFormData.kcPosition = e.value[0].label
this.kcPositionShow = false;
},
/** 准备转维修表单数据 */
prepareRepairForm() {
this.getRepairFactoryList();
this.repairFormData = {
name: this.detailsData.connectionName || '',
phone: this.detailsData.connectionPhone || '',
brandName: this.detailsData.carBrand || '',
brandModel: '',
adviserName: '',
adviserId: '',
adviserPhone: '',
remark: '',
adviserNameManual: '',
carNo: this.detailsData.licenseNum || '',
};
},
/** 确认转维修 */
confirmRepair() {
// 检查是否正在上传
if (this.uploadingRecord) {
uni.showToast({
title: '照片上传中,请稍候',
icon: 'none'
});
return;
}
// 检查是否有图片正在上传fileList1中有status为uploading的项
const isUploading = this.fileList1.some(item => item.status === 'uploading');
if (isUploading) {
uni.showToast({
title: '有照片正在上传,请等待完成',
icon: 'none'
});
return;
}
// 验证必填字段
if (!this.repairFormData.name || !this.repairFormData.phone) {
uni.showToast({
title: '请填写姓名和联系电话',
icon: 'none'
});
return;
}
if (this.ulImages.length === 0) {
uni.showToast({
title: '请上传照片',
icon: 'none'
})
return
}
// 关闭转维修弹框
this.toRepairShow = false;
this.recordShow = false;
// 继续执行主流程提交,携带转维修数据
this.submitProcessData({
toRepair: true,
...this.repairFormData
});
},
/** 关闭转维修弹框 */
closeRepairPopup() {
this.toRepairShow = false;
// 用户取消转维修,清空选择
this.selectedOption = '';
},
/** 提交流程数据 */
async submitProcessData(additionalData = null) {
try {
if (this.ulImages.length === 0 && this.dispatchStepIndex != 5) {
uni.showToast({
title: '请上传照片',
icon: 'none'
});
return;
}
if (this.dispatchStepIndex === 5 && !this.selectedOption && !additionalData?.toRepair) {
uni.showToast({
title: '请选择一个车辆去向',
icon: 'none'
});
return;
}
// 基础数据
let tempImage = JSON.parse(JSON.stringify(this.ulImages))
let data = {
rescueInfoId: this.rescueId,
title: this.dictLabel,
images: tempImage.join(","),
remark: this.remark,
type: this.dictValue,
};
// 合并附加数据
if (additionalData) {
Object.assign(data, additionalData);
}
// 处理步骤5
if (this.dispatchStepIndex === 5) {
this.processStep5Data(data);
}
// 处理交接类型
if (additionalData?.handoverType) {
this.processHandoverData(data, additionalData);
}
if (this.detailsData.dispatchRecordStep == 7) {
data.autoRemark = '确认人: ' + this.userinfo.nickname + ', 电话: ' + this.userinfo.mobile
}
const res = await request({
url: '/app/driver/uploadDispatchDetailByDriver',
method: 'post',
data: data
});
if (res.code == 200) {
// 重置表单数据
this.ulImages = [];
this.remark = '';
this.fileList1 = [];
this.selectedOption = '';
uni.showToast({
title: '提交成功',
icon: 'success',
duration: 2000
});
// 如果是转维修,额外调用转维修接口
if (additionalData?.toRepair && this.repairFormData.adviserId && this.repairFormData
.adviserName) {
await this.submitToRepair(additionalData);
}
// 更新流程状态
let updateData = {
id: this.detailsData.id,
dispatchRecordStep: this.dispatchStepIndex + 1
};
// 更新下一步显示
this.dispatchStepIndex++;
if (this.dispatchStepIndex < this.recordSteps.length) {
this.nextStepName = `下一步:${this.recordSteps[this.dispatchStepIndex].label}`;
this.isProcessFinished = false;
} else {
this.nextStepName = '流程结束';
this.isProcessFinished = true;
updateData.rescueStatus = '5'
}
await request({
url: '/app/driver/updateRescueInfo',
method: 'put',
data: updateData
});
// 刷新订单详情
this.recordShow = false;
this.getrescueDetail(this.rescueId);
} else {
throw new Error(`API返回错误代码: ${res.code}`);
}
} catch (error) {
console.error('提交失败:', error);
}
},
/** 处理车辆移交 */
processStep5Data(data) {
if (!this.selectedOption) return;
switch (this.selectedOption) {
case 'repair':
let autoRemarkTemp = '转维修';
if (!this.repairFormData.adviserId || !this.repairFormData.adviserName) {
if (this.repairFormData.adviserNameManual) {
autoRemarkTemp = '转维修, ' + '移交接车人: ' + this.repairFormData.adviserNameManual + ', ' +
'移交接车人电话: ' + this.repairFormData.adviserPhone;
}
} else {
autoRemarkTemp = '转维修, ' + '移交接车人: ' + this.repairFormData.adviserName + ', ' +
'移交接车人电话: ' + this.repairFormData.adviserPhone;
}
if (this.repairFormData.repairFactoryName) {
autoRemarkTemp = autoRemarkTemp + ', ' + '修理厂: ' + this.repairFormData.repairFactoryName
}
data.remark = this.repairFormData.remark;
data.autoRemark = autoRemarkTemp;
break;
case 'detain':
let autoRemarkTempKc = '扣车' + ', ' + '扣车地点: ' + this.kcFormData.kcPosition;
if (!this.kcFormData.adviserId || !this.kcFormData.adviserName) {
autoRemarkTempKc = '扣车, ' + '扣车地点: ' + this.kcFormData.kcPosition + ', ' + '移交接车人: ' +
this.kcFormData.name + ', ' + '移交接车人电话: ' + this.kcFormData.phone;
} else {
autoRemarkTempKc = '扣车, ' + '扣车地点: ' + this.kcFormData.kcPosition + ', ' + '移交接车人: ' +
this.kcFormData.adviserName + ', ' + '移交接车人电话: ' + this.kcFormData.phone;
}
data.remark = this.kcFormData.remark;
data.autoRemark = autoRemarkTempKc;
break;
}
},
/** 处理交接类型数据逻辑 */
processHandoverData(data, additionalData) {
let remarkText = '';
let handoverTitle = '';
switch (additionalData.handoverType) {
case 'handover':
remarkText = '移交接车人: ' + additionalData.name + ', ' + '移交接车人电话: ' + additionalData.phone;
handoverTitle = '移交客户';
break;
case 'specifyRepairShop':
remarkText = '移交接车人: ' + additionalData.name + ', ' + '移交接车人电话: ' + additionalData.phone;
handoverTitle = '客户指定修理厂';
break;
case 'specifyPickUpPeople':
remarkText = '移交接车人: ' + additionalData.name + ', ' + ' 移交接车人电话: ' + additionalData.phone;
handoverTitle = '客户指定接车人';
break;
}
data.autoRemark = remarkText;
data.handoverTitle = handoverTitle;
},
/* =============================================================================================== */
/** 提交转维修请求 */
async submitToRepair(repairData) {
try {
const toRepairData = {
rescueId: this.detailsData.id,
userName: this.repairFormData.name,
userMobile: this.repairFormData.phone,
brandName: this.repairFormData.brandName,
brandModel: this.repairFormData.brandModel,
adviserName: this.repairFormData.adviserName,
adviserId: this.repairFormData.adviserId,
adviserPhone: this.repairFormData.adviserPhone,
remark: this.repairFormData.remark,
carNo: this.repairFormData.carNo,
};
const res = await request({
url: '/app/rescueInfo/toRepair',
method: 'post',
data: toRepairData
});
if (res.code == 200) {
uni.showToast({
title: '转维修成功'
});
}
} catch (error) {
console.error('转维修提交失败:', error);
}
},
// 显示移交客户弹框
showHandoverPopup(type) {
this.handoverType = type;
// 根据类型设置不同的标题
switch (type) {
case 'handover':
this.handoverTitle = '移交客户';
break;
case 'specifyRepairShop':
this.handoverTitle = '移交客户指定修理厂';
break;
case 'specifyPickUpPeople':
this.handoverTitle = '移交客户指定接车人';
break;
default:
this.handoverTitle = '移交客户';
}
// 重置表单数据
this.handoverFormData = {
name: '',
phone: '',
remark: ''
};
this.toHandoverShow = true;
},
// 关闭移交客户弹框
closeHandoverPopup() {
this.toHandoverShow = false;
this.handoverType = '';
},
// 确认移交
async confirmHandover() {
// 检查是否正在上传
if (this.uploadingRecord) {
uni.showToast({
title: '照片上传中,请稍候',
icon: 'none'
});
return;
}
// 检查是否有图片正在上传fileList1中有status为uploading的项
const isUploading = this.fileList1.some(item => item.status === 'uploading');
if (isUploading) {
uni.showToast({
title: '有照片正在上传,请等待完成',
icon: 'none'
});
return;
}
// 验证必填字段
if (!this.handoverFormData.name) {
uni.showToast({
title: '请填写移交接车人姓名',
icon: 'none'
});
return;
}
if (!this.handoverFormData.phone) {
uni.showToast({
title: '请填写移交接车人电话',
icon: 'none'
});
return;
}
if (this.ulImages.length === 0) {
uni.showToast({
title: '请上传照片',
icon: 'none'
})
return
}
// 关闭弹框
this.toHandoverShow = false;
// 关闭父弹框
this.recordShow = false;
// 准备移交数据
let additionalData = {
handoverType: this.handoverType,
name: this.handoverFormData.name,
phone: this.handoverFormData.phone,
remark: this.handoverFormData.remark || ''
};
// 执行主流程提交
await this.submitProcessData(additionalData);
},
// 显示扣车弹框
showDetainPopup() {
this.selectedKcPosition = '';
this.toDetainShow = true;
},
// 关闭扣车弹框
closeDetainPopup() {
this.toDetainShow = false;
this.selectedKcPosition = '';
this.kcFormData = [];
},
// 显示扣车地点选择器
showKcPositionPicker() {
if (this.kcPositionList.length === 0) {
this.getKcPositionList();
}
this.kcPositionShow = true;
},
// 确认扣车
confirmDetain() {
// 检查是否正在上传
if (this.uploadingRecord) {
uni.showToast({
title: '照片上传中,请稍候',
icon: 'none'
});
return;
}
// 检查是否有图片正在上传fileList1中有status为uploading的项
const isUploading = this.fileList1.some(item => item.status === 'uploading');
if (isUploading) {
uni.showToast({
title: '有照片正在上传,请等待完成',
icon: 'none'
});
return;
}
if (!this.selectedKcPosition) {
uni.showToast({
title: '请选择扣车地点',
icon: 'none'
});
return;
}
if (this.ulImages.length === 0) {
uni.showToast({
title: '请上传照片',
icon: 'none'
})
return
}
// 关闭扣车弹框
this.toDetainShow = false;
this.recordShow = false;
// 执行扣车操作
this.submitDetainData();
// 主流程
this.submitProcessData()
},
// 提交扣车数据
async submitDetainData() {
this.detailsData.isKouChe = this.kcFormData.isKouChe
this.detailsData.kcPosition = this.kcFormData.kcPosition
this.detailsData.kcUserId = this.kcFormData.adviserId
// this.detailsData.rescueType = 5
this.confirmadd()
},
// 保存开始里程
async updateStartScaleData() {
if (this.dispatchStepIndex === 2) {
this.detailsData.dispatchStartScale = this.dispatchStartScale;
this.detailsData.dispatchRecordStep = this.detailsData.dispatchRecordStep + 1
} else if (this.dispatchStepIndex === 3) {
this.detailsData.dispatchArriveScale = this.dispatchArriveScale;
this.detailsData.dispatchRecordStep = this.detailsData.dispatchRecordStep + 1
}
this.confirmadd();
},
/**流程记录提交*/
async getdaoda() {
if (this.isSubmitting) {
uni.showToast({
title: '请求处理中,请稍候',
icon: 'none'
});
return;
}
if (this.uploadingRecord) {
uni.showToast({
title: '照片上传中,请稍候',
icon: 'none'
});
return;
}
// 检查是否有图片正在上传fileList1中有status为uploading的项
const isUploading = this.fileList1.some(item => item.status === 'uploading');
if (isUploading) {
uni.showToast({
title: '有照片正在上传,请等待完成',
icon: 'none'
});
return;
}
if (this.ulImages.length === 0 && this.dispatchStepIndex != 5) {
uni.showToast({
title: '请上传照片',
icon: 'none'
})
return
}
try {
this.isSubmitting = true;
// 如果选择了转维修,先显示转维修弹框
if (this.selectedOption === 'repair') {
this.prepareRepairForm();
this.toRepairShow = true;
return; // 中断执行,等待转维修表单确认
}
// 扣车
if (this.selectedOption === 'detain') {
this.showDetainPopup();
return;
}
// 处理移交客户相关选项
if (this.selectedOption === 'handover' ||
this.selectedOption === 'specifyRepairShop' ||
this.selectedOption === 'specifyPickUpPeople') {
this.showHandoverPopup(this.selectedOption);
return;
}
// 非转维修情况,直接执行提交
await this.submitProcessData();
} catch (error) {
console.error('提交失败:', error);
} finally {
// 确保在任何情况下都会重置提交状态
this.isSubmitting = false;
}
},
// 关闭救援开始弹框
closeAcceptOrderPopup() {
this.acceptOrderShow = false;
this.startScale = '';
this.fileList1 = [];
this.ulImages = [];
},
// 确认救援开始
async confirmAcceptOrder() {
if (this.isSubmitting) {
uni.showToast({
title: '请求处理中,请稍候',
icon: 'none'
});
return;
}
// 检查是否有图片正在上传fileList1中有status为uploading的项
const isUploading = this.fileList1.some(item => item.status === 'uploading');
if (isUploading) {
uni.showToast({
title: '有照片正在上传,请等待完成',
icon: 'none'
});
return;
}
if (this.dispatchStepIndex === 2 && !this.dispatchStartScale) {
uni.showToast({
title: '请输入出发里程数',
icon: 'none'
});
return;
}
if (this.dispatchStepIndex === 3 && !this.dispatchArriveScale) {
uni.showToast({
title: '请输入到达里程数',
icon: 'none'
});
return;
}
if (this.ulImages.length === 0) {
uni.showToast({
title: '请上传里程表照片',
icon: 'none'
});
return;
}
try {
// 更新里程信息
this.updateStartScaleData()
this.getdaoda()
// 清空数据
this.closeAcceptOrderPopup()
} catch (error) {
console.error('提交失败:', error);
uni.showToast({
title: '提交失败',
icon: 'none'
});
} finally {
// 确保重置提交状态
this.isSubmitting = false;
}
},
// 显示补充照片弹窗
showSupplementPopup(item) {
this.currentSupplementItem = item;
this.supplementShow = true;
// 保留之前上传的照片,不重置数组
// 将已有的补充照片转换为文件列表格式
if (item.supplementImages) {
const existingImages = item.supplementImages.split(',');
this.supplementImages = [...existingImages];
this.supplementFileList = existingImages.map(url => ({
url: this.baseImageUrl + url,
status: 'success',
message: ''
}));
} else {
this.supplementImages = [];
this.supplementFileList = [];
}
},
// 关闭补充照片弹窗
closeSupplementPopup() {
if (!this.uploading) {
this.supplementShow = false;
// 不清空数据
}
},
// 补充照片上传
async supplementAfterRead(event) {
if (this.uploading) return;
let lists = [].concat(event.file);
let fileListLen = this.supplementFileList.length;
lists.map((item) => {
this.supplementFileList.push({
...item,
status: 'uploading'
});
});
// 开始上传
this.uploading = true;
for (let i = 0; i < lists.length; i++) {
try {
const result = await this.uploadFilePromiseSupplement(lists[i].url);
console.log('result', result)
let item = this.supplementFileList[fileListLen];
this.supplementFileList.splice(fileListLen, 1, Object.assign(item, {
status: 'success',
message: '',
url: result
}));
// 保存到补充图片数组
this.supplementImages.push(result);
fileListLen++;
} catch (error) {
console.error('上传失败:', error);
let item = this.supplementFileList[fileListLen];
this.supplementFileList.splice(fileListLen, 1, Object.assign(item, {
status: 'failed',
message: '上传失败'
}));
fileListLen++;
}
}
this.uploading = false;
},
// 删除补充照片
deleteSupplementPic(event) {
if (this.uploading) return;
this.supplementFileList.splice(event.index, 1);
this.supplementImages.splice(event.index, 1);
},
// 补充照片
async confirmSupplement() {
if (this.uploading) {
uni.showToast({
title: '照片上传中,请稍候',
icon: 'none'
});
return;
}
if (this.supplementImages.length === 0) {
uni.showToast({
title: '请上传照片',
icon: 'none'
});
return;
}
try {
// 获取原有的补充照片
const originalImages = this.currentSupplementItem.supplementImages ?
this.currentSupplementItem.supplementImages.split(',') : [];
// 合并新旧照片
const allImages = [...new Set([...originalImages, ...this.supplementImages])];
// 调用API保存补充照片
const res = await request({
url: '/app/driver/updateRescueInfoDispatchDetail',
method: 'put',
data: {
id: this.currentSupplementItem.id,
supplementImages: allImages.join(',')
}
});
if (res.code === 200) {
uni.showToast({
title: '补充成功',
icon: 'success'
});
// 关闭弹窗并重置数据
this.supplementShow = false;
this.supplementFileList = [];
this.supplementImages = [];
// 刷新页面数据
this.getrescueDetail(this.id);
}
} catch (error) {
console.error('补充照片失败:', error);
uni.showToast({
title: '补充失败',
icon: 'none'
});
}
},
// 关闭收费弹框
closeFeePopup() {
this.showFeePopup = false;
},
closeShowShouldPayPopup() {
this.showShouldPayPopup = false;
this.showFeePopup = true;
},
closeShowShouldChargePopup() {
this.showShouldChargePopup = false;
this.showFeePopup = true;
},
// 选择支付方式
selectPayment(type) {
this.selectedPayment = type;
},
// 确认支付方式
confirmPayment() {
if (!this.selectedPayment) {
uni.showToast({
title: '请选择一个选项',
icon: 'none'
});
return;
}
// 关闭主弹框,打开对应的子弹框
this.showFeePopup = false;
switch (this.selectedPayment) {
case 'shouldCharge':
this.showShouldChargePopup = true;
break;
case 'shouldPay':
this.showShouldPayPopup = true;
break;
}
},
// 支付凭证上传
uploadFilePromisePayment(url) {
return new Promise((resolve, reject) => {
upload({
url: '/infra/file/upload',
filePath: url,
}).then((res) => {
resolve(res.data);
}).catch(reject);
});
},
// 应收费用确认
async shouldChargeConfirm() {
if (this.orderData.dispatchTowingFee === undefined || this.orderData.dispatchTowingFee === null ||
this.orderData.dispatchCraneFee === undefined || this.orderData.dispatchCraneFee === null ||
this.orderData.dispatchOtherFee === undefined || this.orderData.dispatchOtherFee === null) {
uni.showToast({
title: '请输入金额',
icon: 'none'
});
return;
}
let autoRemarkTemp = '应收总金额: ' + this.orderData.dispatchSumFee + ' 元, 拖车费用: ' + this.orderData
.dispatchTowingFee + ', 吊车费用: ' + this.orderData.dispatchCraneFee + ', 其他费用: ' + this.orderData
.dispatchOtherFee
if (this.orderData.dispatchOtherFeeRemark) {
autoRemarkTemp = autoRemarkTemp + ', 其他费用备注: ' + this.orderData.dispatchOtherFeeRemark
}
let data = {
rescueInfoId: this.id,
title: '调度确认应收费用',
images: this.paymentImages.join(','),
remark: this.orderData.dispatchConfirmChargeRemark,
autoRemark: autoRemarkTemp,
};
try {
const res = await request({
url: '/app/driver/uploadDispatchDetailByDriver',
method: 'post',
data: data
});
if (res.code == 200) {
uni.showToast({
title: '提交成功',
icon: 'success',
duration: 2000
});
this.orderData.dispatchIsConfirmCharge = '1'
this.orderData.setMoney = this.orderData.setMoney * 100
this.updateOrderInfo(this.orderData);
// 确保在成功后再关闭弹框
this.showShouldChargePopup = false;
this.showFeePopup = true;
// 刷新数据
this.getrescueDetail(this.id);
} else {
uni.showToast({
title: '提交失败: ' + (res.msg || '未知错误'),
icon: 'none'
});
}
} catch (error) {
console.error('提交失败:', error);
uni.showToast({
title: '提交失败',
icon: 'none'
});
}
},
// 应付费用确认
async shouldPayConfirm() {
if (this.orderData.dispatchShouldPayTowingFee === undefined || this.orderData
.dispatchShouldPayTowingFee === null ||
this.orderData.dispatchShouldPayCraneFee === undefined || this.orderData
.dispatchShouldPayCraneFee === null ||
this.orderData.dispatchShouldPayOtherFee === undefined || this.orderData
.dispatchShouldPayOtherFee === null) {
uni.showToast({
title: '请输入金额',
icon: 'none'
});
return;
}
let autoRemarkTemp = '应付总金额: ' + this.orderData.dispatchShouldPaySumFee + ', 拖车费用: ' + this.orderData
.dispatchShouldPayTowingFee + ', 吊车费用: ' + this.orderData.dispatchShouldPayCraneFee + ', 其他费用: ' +
this.orderData
.dispatchShouldPayOtherFee
if (this.orderData.dispatchShouldPayOtherFeeRemark) {
autoRemarkTemp = autoRemarkTemp + ', 其他费用备注: ' + this.orderData.dispatchShouldPayOtherFeeRemark
}
let data = {
rescueInfoId: this.id,
title: '调度确认应付费用',
images: this.paymentImages.join(','),
remark: this.orderData.dispatchShouldPayRemark,
autoRemark: autoRemarkTemp,
};
try {
const res = await request({
url: '/app/driver/uploadDispatchDetailByDriver',
method: 'post',
data: data
});
if (res.code == 200) {
uni.showToast({
title: '提交成功',
icon: 'success',
duration: 2000
});
this.orderData.dispatchIsConfirmShouldPay = '1'
console.log('this.orderData.setMoney1', this.orderData.setMoney)
this.orderData.setMoney = this.orderData.setMoney * 100
console.log('this.orderData.setMoney2', this.orderData.setMoney)
this.updateOrderInfo(this.orderData);
// 确保在成功后再关闭弹框
this.showShouldPayPopup = false;
this.showFeePopup = true;
// 刷新数据
this.getrescueDetail(this.id);
} else {
uni.showToast({
title: '提交失败: ' + (res.msg || '未知错误'),
icon: 'none'
});
}
} catch (error) {
console.error('提交失败:', error);
uni.showToast({
title: '提交失败',
icon: 'none'
});
}
},
async confirmAllFeeMsg() {
let autoRemarkTemp = '确认人: ' + this.userinfo.nickname + ', 电话 ' + this.userinfo.mobile
let data = {
rescueInfoId: this.id,
title: '调度已确认财务信息',
autoRemark: autoRemarkTemp,
};
try {
const res = await request({
url: '/app/driver/uploadDispatchDetailByDriver',
method: 'post',
data: data
});
if (res.code == 200) {
uni.showToast({
title: '提交成功',
icon: 'success',
duration: 2000
});
this.detailsData.dispatchRecordStep = this.detailsData.dispatchRecordStep + 1
this.confirmadd()
// 在主弹框确认后清空所有支付凭证
this.paymentImagesCharge = [];
this.paymentImagesPay = [];
this.paymentFileListCharge = [];
this.paymentFileListPay = [];
// 在成功后关闭弹框
this.showFeePopup = false;
// 刷新数据
this.getrescueDetail(this.id);
} else {
uni.showToast({
title: '提交失败: ' + (res.msg || '未知错误'),
icon: 'none'
});
}
} catch (error) {
console.error('提交失败:', error);
uni.showToast({
title: '提交失败',
icon: 'none'
});
}
},
// 更新订单信息
updateOrderInfo(orderData) {
request({
url: '/rescue/orderInfo/edit',
method: 'post',
data: orderData
}).then((res) => {
console.log(res);
})
},
// 获取调度人员信息合并second_dispatcher和ddzx角色
getSecondDispatcher() {
console.log('12-12')
this.dispatcherColumns = [];
const tenantId = getTenantId();
// 创建两个请求的Promise
const request1 = request({
url: `/company/staff/staffListByRoleCode?tenantId=${tenantId}&code=second_dispatcher`,
method: 'get',
});
const request2 = request({
url: `/company/staff/staffListByRoleCode?tenantId=${tenantId}&code=ddzx`,
method: 'get',
});
// 使用Promise.all并行请求
Promise.all([request1, request2])
.then(([res1, res2]) => {
// 合并两个数据数组
const combinedData = [...(res1.data || []), ...(res2.data || [])];
// 使用Map根据id去重
const uniqueMap = new Map();
combinedData.forEach(item => {
if (item && item.id) {
uniqueMap.set(item.id, item);
}
});
// 将去重后的数据转换为数组
const uniqueData = Array.from(uniqueMap.values());
// 存储到secondColumns
this.dispatcherColumns.push(uniqueData);
console.log('合并后的调度人员数据:', uniqueData);
})
.catch(error => {
console.error('获取调度人员数据失败:', error);
uni.showToast({
title: '获取调度人员失败',
icon: 'none'
});
});
},
// 调度人员选择确认
onDispatcherConfirm(e) {
const selectedDispatcher = e.value[0];
this.selectedDispatcherName = selectedDispatcher.nickname;
this.selectedDispatcherId = selectedDispatcher.id;
this.dispatcherPickerShow = false;
},
// 获取修理厂列表
getRepairFactoryList() {
request({
url: '/rescue/dict/data/type/rescue_to_repair',
method: 'get'
}).then((res) => {
if (res.code === 200) {
this.repairFactoryList = res.data;
console.log('this.repairFactoryList', this.repairFactoryList)
}
}).catch(error => {
console.error('获取修理厂列表失败:', error);
});
},
// 修理厂选择确认
onRepairFactoryConfirm(e) {
const selectedFactory = e.value[0];
this.repairFormData.repairFactoryName = selectedFactory.label || '';
this.repairFormData.repairFactoryId = selectedFactory.id || '';
this.repairFactoryShow = false;
},
// 显示新增修理厂弹框
showAddRepairFactoryModal() {
this.newRepairFactoryName = '';
this.showAddRepairFactoryModalView = true;
},
// 关闭新增修理厂弹框
closeAddRepairFactoryModal() {
this.showAddRepairFactoryModalView = false;
},
// 新增修理厂
async addNewRepairFactory() {
if (!this.newRepairFactoryName.trim()) {
uni.showToast({
title: '请输入修理厂名称',
icon: 'none'
});
return;
}
// 检查是否已存在相同名称的修理厂
const exists = this.repairFactoryList.some(item =>
item.label === this.newRepairFactoryName.trim()
);
if (exists) {
uni.showToast({
title: '该修理厂已存在',
icon: 'none'
});
return;
}
try {
// 新增修理厂接口
const response = await request({
url: '/system/dict-data/create',
method: 'post',
data: {
dictType: 'rescue_to_repair',
label: this.newRepairFactoryName.trim(),
value: this.newRepairFactoryName.trim().toLowerCase().replace(/\s+/g, '_'),
sort: this.repairFactoryList.length + 1,
status: 0
}
});
if (response.code === 200) {
uni.showToast({
title: '添加成功'
});
// 重新加载修理厂列表
this.getRepairFactoryList();
this.showAddRepairFactoryModalView = false;
// 自动选中新添加的修理厂
this.repairFormData.repairFactoryName = this.newRepairFactoryName.trim();
} else {
uni.showToast({
title: response.msg || '添加失败',
icon: 'none'
});
}
} catch (error) {
console.error('添加修理厂失败:', error);
uni.showToast({
title: '添加失败',
icon: 'none'
});
}
},
// 显示编辑照片弹窗
showEditPhotoPopup(item, field) {
this.currentEditItem = item;
this.editField = field;
this.editPhotoShow = true;
// 将已有的照片转换为文件列表格式
if (item[field]) {
const existingImages = item[field].split(',');
this.editImages = [...existingImages];
this.editFileList = existingImages.map(url => ({
url: this.baseImageUrl + url,
status: 'success',
message: ''
}));
} else {
this.editImages = [];
this.editFileList = [];
}
},
// 关闭编辑照片弹窗
closeEditPhotoPopup() {
if (!this.uploading) {
this.editPhotoShow = false;
// 不清空数据,以便用户再次打开时能看到之前上传的照片
}
},
// 编辑照片上传
async editAfterRead(event) {
if (this.uploading) return;
let lists = [].concat(event.file);
let fileListLen = this.editFileList.length;
lists.map((item) => {
this.editFileList.push({
...item,
status: 'uploading'
});
});
// 开始上传
this.uploading = true;
for (let i = 0; i < lists.length; i++) {
try {
const result = await this.uploadFilePromiseEdit(lists[i].url);
let item = this.editFileList[fileListLen];
this.editFileList.splice(fileListLen, 1, Object.assign(item, {
status: 'success',
message: '',
url: result
}));
// 保存到编辑图片数组
this.editImages.push(result);
fileListLen++;
} catch (error) {
console.error('上传失败:', error);
let item = this.editFileList[fileListLen];
this.editFileList.splice(fileListLen, 1, Object.assign(item, {
status: 'failed',
message: '上传失败'
}));
fileListLen++;
}
}
this.uploading = false;
},
// 编辑照片上传Promise
uploadFilePromiseEdit(url) {
return new Promise((resolve, reject) => {
upload({
url: '/infra/file/upload',
filePath: url,
}).then((res) => {
resolve(res.data);
}).catch(reject);
});
},
// 删除编辑照片
deleteEditPic(event) {
if (this.uploading) return;
this.editFileList.splice(event.index, 1);
this.editImages.splice(event.index, 1);
},
// 确认编辑照片
async confirmEditPhoto() {
if (this.uploading) {
uni.showToast({
title: '照片上传中,请稍候',
icon: 'none'
});
return;
}
try {
// 调用API保存编辑后的照片
const res = await request({
url: '/app/driver/updateRescueInfoDispatchDetail',
method: 'put',
data: {
id: this.currentEditItem.id,
[this.editField]: this.editImages.join(',')
}
});
if (res.code === 200) {
uni.showToast({
title: '编辑成功',
icon: 'success'
});
// 关闭弹窗
this.editPhotoShow = false;
this.editFileList = [];
this.editImages = [];
// 刷新页面数据
this.getrescueDetail(this.id);
}
} catch (error) {
console.error('编辑照片失败:', error);
uni.showToast({
title: '编辑失败',
icon: 'none'
});
}
},
// 应收费用凭证上传
async paymentAfterReadCharge(event) {
if (this.uploadingPayment) return;
let lists = [].concat(event.file);
let fileListLen = this.paymentFileListCharge.length;
lists.map((item) => {
this.paymentFileListCharge.push({
...item,
status: 'uploading'
});
});
this.uploadingPayment = true;
for (let i = 0; i < lists.length; i++) {
try {
const result = await this.uploadFilePromisePayment(lists[i].url);
let item = this.paymentFileListCharge[fileListLen];
this.paymentFileListCharge.splice(fileListLen, 1, Object.assign(item, {
status: 'success',
message: '',
url: result
}));
this.paymentImagesCharge.push(result);
fileListLen++;
} catch (error) {
console.error('支付凭证上传失败:', error);
let item = this.paymentFileListCharge[fileListLen];
this.paymentFileListCharge.splice(fileListLen, 1, Object.assign(item, {
status: 'failed',
message: '上传失败'
}));
fileListLen++;
}
}
this.uploadingPayment = false;
},
// 应付费用凭证上传
async paymentAfterReadPay(event) {
if (this.uploadingPayment) return;
let lists = [].concat(event.file);
let fileListLen = this.paymentFileListPay.length;
lists.map((item) => {
this.paymentFileListPay.push({
...item,
status: 'uploading'
});
});
this.uploadingPayment = true;
for (let i = 0; i < lists.length; i++) {
try {
const result = await this.uploadFilePromisePayment(lists[i].url);
let item = this.paymentFileListPay[fileListLen];
this.paymentFileListPay.splice(fileListLen, 1, Object.assign(item, {
status: 'success',
message: '',
url: result
}));
this.paymentImagesPay.push(result);
fileListLen++;
} catch (error) {
console.error('支付凭证上传失败:', error);
let item = this.paymentFileListPay[fileListLen];
this.paymentFileListPay.splice(fileListLen, 1, Object.assign(item, {
status: 'failed',
message: '上传失败'
}));
fileListLen++;
}
}
this.uploadingPayment = false;
},
// 删除应收费用凭证图片
deletePaymentPicCharge(event) {
if (this.uploadingPayment) return;
this.paymentFileListCharge.splice(event.index, 1);
this.paymentImagesCharge.splice(event.index, 1);
},
// 删除应付费用凭证图片
deletePaymentPicPay(event) {
if (this.uploadingPayment) return;
this.paymentFileListPay.splice(event.index, 1);
this.paymentImagesPay.splice(event.index, 1);
},
}
}
</script>
<style scoped lang="scss">
.content {
box-sizing: border-box;
width: 100%;
}
.left-t {
display: flex;
height: 50rpx;
}
.xx-hui {
font-size: 30rpx;
font-weight: 400;
color: #666666;
line-height: 50rpx;
margin-top: 20rpx;
}
.img-boxs {
width: 100%;
display: flex;
flex-wrap: wrap;
}
.img-box {
width: 140rpx;
height: 140rpx;
border-radius: 12rpx;
overflow: hidden;
margin-top: 20rpx;
margin-right: 20rpx;
image {
width: 100%;
height: 100%;
}
}
.wrap-box {
width: 100%;
display: flex;
flex-wrap: wrap;
}
.wrap-box_bc {
width: 100%;
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
.edit_images {
display: flex;
width: 100%;
}
.beizh {}
.gain {
font-style: 36rpx;
font-weight: bold;
margin-right: 20rpx;
color: #0D2E8D;
}
.g-img {
width: 30%;
height: 222rpx;
margin-right: 20rpx;
margin-top: 10rpx;
image {
width: 100%;
height: 100%;
}
}
.ximg {
width: 40rpx;
height: 40rpx;
margin: 0 auto;
margin-bottom: 20rpx;
image {
width: 100%;
height: 100%;
}
}
.sj {
width: 50rpx;
height: 50rpx;
margin-right: 20rpx;
image {
width: 100%;
height: 100%;
}
}
.bai-title {
font-weight: bold;
color: #ffffff;
}
.ai {
font-size: 28rpx;
}
.top-heder {
width: 100%;
height: 80rpx;
background: #1b5dfd;
}
.topjianjian {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
padding: 30rpx 30rpx;
}
.dix {
display: flex;
align-items: center;
margin: 40rpx auto;
}
.huiy {
font-size: 30rpx;
font-weight: 400;
color: #999999;
margin-right: 16rpx;
}
.htzit {
display: flex;
align-items: center;
font-size: 30rpx;
color: #999999;
}
.xshui {
font-size: 30rpx;
font-weight: 400;
color: #333333;
}
.dis-bb {
box-sizing: border-box;
padding-bottom: 30rpx;
border-bottom: 1px solid #EEEEEE;
}
.c-top {
width: 100%;
height: 360rpx;
background: #1b5dfd;
box-sizing: border-box;
}
.ding-top {
width: 100%;
background-color: white;
box-sizing: border-box;
padding: 30rpx;
border-radius: 16rpx 16rpx 0 0;
position: relative;
}
.dis-b {
display: flex;
justify-content: space-between;
margin-bottom: 20rpx;
}
.t-left {}
.t-zi1 {
font-size: 30rpx;
font-weight: bold;
color: white;
}
.t-zi2 {
font-size: 28rpx;
font-weight: bold;
color: white;
margin-bottom: 20rpx;
margin-top: 20rpx;
}
.t-right {
color: white;
display: flex;
}
.t-zi2 {
font-size: 28rpx;
font-weight: bold;
color: white;
text-align: center;
}
.hui-content {
width: 100%;
background-color: #f4f4f4;
box-sizing: border-box;
padding: 20rpx 0 160rpx 0;
}
.content-box {
width: 100%;
box-sizing: border-box;
padding: 30rpx;
background: #FFFFFF;
margin-bottom: 20rpx;
}
.mubu {
width: 100%;
background-color: #f4f4f4;
}
.ja-you {
width: 100%;
font-weight: bold;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
margin: 20rpx auto;
}
.xhui {
font-size: 24rpx;
font-weight: 400;
color: #999999;
}
.xhui-kc {
font-size: 32rpx;
font-weight: 400;
color: #000000;
}
.lan-ga {
width: 100%;
margin: 20rpx auto;
box-sizing: border-box;
padding-bottom: 40rpx;
position: relative;
.lan-ga-line {
position: absolute;
width: 2rpx;
height: calc(100% - 56rpx);
background-color: #979797;
left: calc(56rpx / 2 - 2rpx);
transform: translate(-50%, 0);
top: calc(56rpx + 10rpx);
}
}
.ga-top-box {
display: flex;
justify-content: space-between;
}
.ga-content {
flex: 1;
width: 0;
.ga-content-top {
display: flex;
align-items: center;
justify-content: space-between;
column-gap: 8rpx;
padding-bottom: 14rpx;
}
.ga-content-title {
font-weight: bold;
flex: 1;
width: 0;
word-break: break-all
}
.xhui {
font-size: 22rpx;
color: #929292;
flex-shrink: 0;
}
.beizh {
font-size: 28rpx;
color: #000000;
white-space: pre-wrap;
word-break: break-word;
line-height: 1.6;
}
.beizh-auto {
font-size: 28rpx;
color: #000000;
white-space: pre-line;
line-height: 1.5;
/* 增加行高提高可读性 */
margin-bottom: 10rpx;
}
}
.img-box {
width: 140rpx;
height: 140rpx;
border-radius: 12rpx;
overflow: hidden;
margin-top: 20rpx;
margin-right: 20rpx;
image {
width: 100%;
height: 100%;
}
}
.wrap-box {
width: 100%;
display: flex;
flex-wrap: wrap;
}
.gain {
box-sizing: border-box;
width: 52rpx;
height: 52rpx;
font-size: 34rpx;
color: #327DFB;
margin-right: 20rpx;
border: 2rpx solid #327DFB;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
font-weight: bold;
.gainIcon {
width: 100%;
height: 100%;
}
}
.fixed-bottom-button_1 {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 15px;
background-color: #fff;
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.1);
z-index: 999;
button {
width: 100%;
background-color: #1b5dfd;
color: white;
border-radius: 10rpx;
height: 90rpx;
line-height: 90rpx;
}
}
.fixed-bottom-button {
display: flex;
justify-content: space-between;
gap: 20rpx;
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 12px;
background-color: #fff;
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.1);
z-index: 999;
button {
height: 90rpx;
line-height: 90rpx;
border-radius: 10rpx;
color: white;
font-size: 32rpx;
border: none;
}
.fee-button {
width: 30%;
}
.next-button {
width: 70%;
}
}
.popup-box {
width: 640rpx;
box-sizing: border-box;
padding: 30rpx;
background-color: white;
border-radius: 20rpx;
min-height: 1000rpx;
/* 设置最小高度 */
padding: 50rpx 30rpx;
/* 增加上下内边距 */
display: flex;
flex-direction: column;
justify-content: space-between;
/* 内容均匀分布 */
}
// 补充照片
.popup-box_bc {
width: 640rpx;
box-sizing: border-box;
padding: 30rpx;
background-color: white;
border-radius: 20rpx;
min-height: 600rpx;
/* 设置最小高度 */
padding: 50rpx 30rpx;
/* 增加上下内边距 */
display: flex;
flex-direction: column;
justify-content: space-between;
/* 内容均匀分布 */
}
// 收费弹框
.popup-box_sf {
width: 640rpx;
box-sizing: border-box;
padding: 30rpx;
background-color: white;
border-radius: 20rpx;
min-height: 600rpx;
/* 设置最小高度 */
padding: 50rpx 30rpx;
/* 增加上下内边距 */
display: flex;
flex-direction: column;
justify-content: space-between;
/* 内容均匀分布 */
}
// 应收费用确认弹框
.popup-box_ys {
width: 640rpx;
box-sizing: border-box;
padding: 30rpx;
background-color: white;
border-radius: 20rpx;
min-height: 600rpx;
/* 设置最小高度 */
max-height: 1200rpx;
padding: 50rpx 30rpx;
/* 增加上下内边距 */
display: flex;
flex-direction: column;
justify-content: space-between;
/* 内容均匀分布 */
}
// 应付费用确认弹框
.popup-box_yf {
width: 640rpx;
box-sizing: border-box;
padding: 30rpx;
background-color: white;
border-radius: 20rpx;
min-height: 600rpx;
/* 设置最小高度 */
max-height: 1200rpx;
padding: 50rpx 30rpx;
/* 增加上下内边距 */
display: flex;
flex-direction: column;
justify-content: space-between;
/* 内容均匀分布 */
}
.p-title {
font-size: 40rpx;
color: rgb(26, 26, 26);
font-weight: bold;
}
.huinput {
width: 100%;
box-sizing: border-box;
display: flex;
align-items: center;
border-radius: 16rpx;
margin: 30rpx auto;
}
.huinput_sf {
width: 100%;
box-sizing: border-box;
display: flex;
flex-direction: row;
border-radius: 16rpx;
margin: 24rpx 0;
justify-content: center;
align-items: center;
}
.huinput_sf_two {
width: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
border-radius: 16rpx;
margin: 24rpx 0;
}
.huinput_sf_top {
width: 100%;
box-sizing: border-box;
display: flex;
flex-direction: row;
border-radius: 16rpx;
margin: 24rpx 0;
}
.tshe {
color: #0D2E8D;
font-size: 32rpx;
}
.button-group {
display: flex;
width: 100%;
margin-top: 30rpx;
}
.cancel-button {
width: 40%;
height: 80rpx;
border-radius: 12rpx;
background: #f4f4f4;
display: flex;
align-items: center;
justify-content: center;
color: #333;
font-size: 32rpx;
font-weight: 700;
margin-right: 20rpx;
}
.confirm-button {
width: 60%;
height: 80rpx;
border-radius: 12rpx;
background: #0D2E8D;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 32rpx;
font-weight: 700;
}
.confirm-button-new {
width: 60%;
height: 80rpx;
border-radius: 12rpx;
background: #67c23a;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 32rpx;
font-weight: 700;
}
.open-button {
width: 60%;
height: 80rpx;
border-radius: 12rpx;
background: #0D2E8D;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 32rpx;
font-weight: 700;
}
.option-buttons {
display: flex;
flex-wrap: wrap;
/* 添加这一行实现自动换行 */
justify-content: flex-start;
margin: 30rpx 0;
gap: 16rpx;
/* 添加间距,使按钮看起来更清晰 */
}
.option-button {
flex: 0 1 auto;
/* 改为自动宽度 */
min-width: 80rpx;
/* 设置最小宽度 */
margin: 8rpx;
/* 调整边距 */
padding: 20rpx;
text-align: center;
border: 1px solid #0D2E8D;
color: #0D2E8D;
border-radius: 10rpx;
white-space: nowrap;
/* 防止文字换行 */
}
.option-button.active {
background-color: #0D2E8D;
color: white;
}
/* 转维修表单样式 */
.repair-form {
width: 100%;
margin-bottom: 40rpx;
}
.repair-form-item {
margin-bottom: 30rpx;
}
.detain-form {
width: 100%;
margin-bottom: 40rpx;
}
.detain-form-item {
display: flex;
flex-direction: column;
margin-bottom: 30rpx;
}
.floating-refresh-btn {
position: fixed;
right: 40rpx;
bottom: 240rpx;
/* 调整位置,避免与底部按钮重叠 */
width: 140rpx;
height: 140rpx;
background-color: #fff;
border-radius: 50%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.2);
z-index: 998;
/* 确保在底部按钮之上,但低于弹窗 */
}
.refresh-text {
font-size: 24rpx;
color: #1b5dfd;
margin-top: 8rpx;
text-align: center;
}
.supplement-photo-btn {
display: flex;
align-items: center;
justify-content: center;
margin-top: 20rpx;
padding: 16rpx 24rpx;
background-color: #f0f5ff;
border: 1px dashed #0D2E8D;
border-radius: 8rpx;
color: #0D2E8D;
font-size: 28rpx;
width: 30%;
text {
margin-left: 8rpx;
}
}
.upload-tips {
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx;
color: #0D2E8D;
font-size: 28rpx;
text {
margin-left: 16rpx;
}
}
.floating-go-btn {
position: fixed;
right: 40rpx;
bottom: 660rpx;
width: 140rpx;
height: 140rpx;
background-color: #fff;
border-radius: 50%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.2);
z-index: 998;
}
.go-text {
font-size: 24rpx;
color: #42b983;
margin-top: 8rpx;
text-align: center;
}
.floating-terminate-btn {
position: fixed;
right: 40rpx;
bottom: 460rpx;
/* 放在刷新按钮上方 */
width: 140rpx;
height: 140rpx;
background-color: #fff;
border-radius: 50%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.2);
z-index: 998;
}
.floating-end-btn {
position: fixed;
right: 40rpx;
bottom: 860rpx;
/* 放在刷新按钮上方 */
width: 140rpx;
height: 140rpx;
background-color: #fff;
border-radius: 50%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.2);
z-index: 998;
}
.terminate-text {
font-size: 24rpx;
color: red;
margin-top: 8rpx;
text-align: center;
}
/* 上传提示样式 */
.upload-tips {
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx;
color: #1b5dfd;
font-size: 28rpx;
margin: 20rpx 0;
text {
margin-left: 16rpx;
}
}
/* 禁用状态样式 */
.cancel-button:disabled,
.confirm-button:disabled {
opacity: 0.6;
pointer-events: none;
}
.payment-options {
display: flex;
flex-direction: column;
justify-content: center;
margin: 40rpx 0;
}
.payment-option {
flex: 1;
/* 改为自动宽度 */
min-width: 100rpx;
/* 设置最小宽度 */
margin: 16rpx;
/* 调整边距 */
padding: 20rpx;
text-align: center;
border: 1px solid #0D2E8D;
color: #0D2E8D;
border-radius: 10rpx;
white-space: nowrap;
}
.payment-option.active {
border-color: #0D2E8D;
background-color: #dde8ff;
}
.payment-option text {
margin-top: 16rpx;
font-size: 24rpx;
}
.pay_font {
margin-bottom: 16rpx;
font-size: 30rpx;
font-weight: bold;
}
.select-box {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 0;
width: 100%;
}
.placeholder {
color: #999;
}
.repair-popup {
max-height: 70vh;
/* 限制最大高度 */
display: flex;
flex-direction: column;
}
.popup-scroll {
flex: 1;
max-height: calc(80vh - 120rpx);
/* 减去按钮区域的高度 */
overflow-y: auto;
padding: 20rpx 0;
}
.title-content-s {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 20rpx;
}
/* 编辑照片按钮样式 */
.edit-photo-btn {
display: flex;
align-items: center;
justify-content: center;
padding: 4rpx 8rpx;
background-color: #f0f5ff;
border: 1px solid #0D2E8D;
border-radius: 8rpx;
color: #0D2E8D;
font-size: 24rpx;
text {
margin-left: 8rpx;
}
}
.ques {
width: 80%;
margin: 0 auto;
image {
width: 100%;
}
}
.custom-modal {
padding: 48rpx;
background: white;
border-radius: 32rpx;
width: 640rpx;
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.15);
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 32rpx;
}
.modal-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.close-icon {
padding: 8rpx;
border-radius: 50%;
background: #f5f5f5;
}
.modal-content {
margin-bottom: 48rpx;
color: #666;
font-size: 30rpx;
text-align: center;
}
.modal-buttons {
display: flex;
justify-content: space-between;
margin-bottom: 32rpx;
gap: 24rpx;
}
.modal-footer {
border-top: 1px solid #eee;
padding-top: 32rpx;
}
.modal-btn {
flex: 1;
height: 88rpx;
border-radius: 16rpx;
font-size: 32rpx;
font-weight: 500;
border: none;
transition: all 0.2s;
}
.modal-btn:active {
opacity: 0.8;
transform: scale(0.98);
}
.yes-btn {
background-color: #327DFB;
color: white;
}
.yes-btn:active {
background-color: #327DFB;
}
.no-btn {
background-color: #f0f0f0;
color: #333;
}
.no-btn:active {
background-color: #e5e5e5;
}
.cancel-btn {
background-color: transparent;
color: #999;
border: 1px solid #eee;
}
.cancel-btn:active {
background-color: #f9f9f9;
}
.ysfy-top {
display: flex;
justify-content: center;
align-items: center;
color: black;
font-size: 32rpx;
margin-top: 20rpx;
font-weight: bold;
}
.confirm-button.disabled {
background-color: #ccc !important;
pointer-events: none;
cursor: not-allowed;
}
.no-data {
color: #999;
}
</style>