Files
gjt_mini/pages/returnCar/detail.vue
2025-12-30 09:44:46 +08:00

3870 lines
121 KiB
Vue
Raw Permalink 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>
<scroll-view scroll-y="true" style="height: 95vh">
<view v-if="isPageShow">
<page-container
:show="isPageShow"
:duration="0"
:overlay="false"
@beforeleave="onBeforeleave"
></page-container>
</view>
<view class="container">
<u-collapse
:value="['basic', 'truck', 'pic', 'cost', 'explain', 'sign']"
:border="false"
>
<u-collapse-item title="基本信息" name="basic">
<view class="item">
<view class="title">合同编号</view>
<u--input
border="surround"
v-model="datas.take.contractSimple.contractNo"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">项目名称</view>
<u--input
border="surround"
v-model="datas.take.contractSimple.projectName"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">客户名称</view>
<u--input
border="surround"
v-model="datas.take.contractSimple.customerName"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">客户联系人</view>
<u--input
border="surround"
v-model="datas.take.contractSimple.customerContactName"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">客户联系人手机</view>
<u--input
border="surround"
v-model="datas.take.contractSimple.customerContactPhone"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">销售经理</view>
<u--input
border="surround"
:value="
getSalesManagerName(
datas.take &&
datas.take.contractSimple &&
datas.take.contractSimple.businessManager
)
"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">车牌号</view>
<u--input
border="surround"
v-model="datas.take.truckSimple.plateNumber"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">品牌</view>
<u--input
border="surround"
v-model="datas.take.truckSimple.brandName"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">车型</view>
<u--input
border="surround"
v-model="datas.take.truckSimple.modelName"
disabled
fontSize="26"
></u--input>
</view>
</u-collapse-item>
<u-collapse-item title="还车信息" ref="trunkCollapse" name="truck">
<view class="item">
<view class="title required">还车人</view>
<view class="tip">授权人:{{ datas.take.takeName || "" }} </view>
<u--input
border="surround"
@change="trimSpace('returnDriver')"
v-model="datas.returnDriver"
:disabled="disabled"
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title required">还车人电话</view>
<view class="tip"
>授权人联系电话:{{ datas.take.takePhone || "" }}
</view>
<u--input
border="surround"
v-model="datas.returneePhone"
@change="trimPhone"
:disabled="disabled"
fontSize="26"
type="number"
></u--input>
</view>
<view class="item">
<view class="title required">还车人身份证</view>
<view class="tip"
>授权人身份证:{{ datas.take.takeIdNo || "" }}
</view>
<u--input
border="surround"
@change="trimSpace('identityCard')"
v-model="datas.identityCard"
:disabled="disabled"
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title required">还车里程</view>
<view class="tip"
>交车里程:{{ datas.take.takeMileage || "" }}
<text class="unit">km</text>
</view>
<u-input
border="surround"
v-model="datas.returnMileage"
:disabled="disabled"
type="digit"
fontSize="26"
>
<template slot="suffix">
<text class="unit">km</text>
</template>
</u-input>
</view>
<view class="item">
<view class="title required">还车电量</view>
<view class="tip"
>交车电量:{{ datas.take.electricity || "" }}
<text class="unit">%</text>
</view>
<u-input
border="surround"
v-model="datas.electricity"
:disabled="disabled"
type="digit"
fontSize="26"
>
<template slot="suffix">
<text class="unit">%</text>
</template>
</u-input>
</view>
<view class="item">
<view class="title required">还车氢量</view>
<view class="tip"
>交车氢量:{{ datas.take.hydrogenMeasure || ""
}}{{ datas.take.hydrogenUnitName || "" }}
</view>
<u-input
border="surround"
v-model="datas.hydrogenMeasure"
type="digit"
:disabled="disabled"
fontSize="26"
>
<template slot="suffix">
<text class="unit"
>{{ datas.take.hydrogenUnitName || "" }}
</text>
</template>
</u-input>
</view>
<view class="item">
<view class="title required">还车时间</view>
<view class="tip"
>交车时间:{{
formatDateTime(
datas.take && datas.take.handoverDate,
"hour"
) || ""
}}
</view>
<u-datetime-picker
:show="showHandoverDatePicker"
mode="datetime"
@confirm="confirmHandoverDate"
@cancel="showHandoverDatePicker = false"
></u-datetime-picker>
<u--input
border="surround"
:disabledColor="disabled ? '#f5f7fa' : '#ffffff'"
disabled
fontSize="26"
:value="formatDateTime(datas.returnDate, 'hour')"
@tap="!disabled && (showHandoverDatePicker = true)"
>
</u--input>
</view>
<view class="item">
<view class="title required">还车地点</view>
<!-- <view class="tip"
>交车地点:{{ datas.take.handoverAddress || "" }}
</view> -->
<!-- <u--input
border="surround"
v-model="datas.returnLocation"
disabled
fontSize="26"
></u--input> -->
<u-picker
:show="showParkOrFixPicker"
:columns="[returnLocationTypeList]"
keyName="dicName"
:immediateChange="true"
:disabled="disabled"
@confirm="confirmIsParkOrFix"
@cancel="showParkOrFixPicker = false"
>
</u-picker>
<u--input
border="surround"
:disabledColor="disabled ? '#f5f7fa' : '#ffffff'"
disabled
fontSize="26"
:value="
returnLocationTypeList[datas.returnLocationType - 1].dicName
"
@tap="!disabled && (showParkOrFixPicker = true)"
>
</u--input>
<!-- returnLocationType是dicCode123 -->
<view
style="margin-top: 10rpx"
v-if="datas.returnLocationType == 1"
>
<u-picker
:show="showParkPicker"
:columns="[parkingList]"
:disabled="disabled"
keyName="dicName"
:immediateChange="true"
@confirm="confirmPark"
@cancel="showParkPicker = false"
>
</u-picker>
<u--input
border="surround"
:disabledColor="disabled ? '#f5f7fa' : '#ffffff'"
disabled
fontSize="26"
:value="parkingList[parkingSel].dicName"
@tap="!disabled && (showParkPicker = true)"
>
</u--input>
</view>
<view
style="margin-top: 10rpx"
v-if="datas.returnLocationType == 2"
>
<u-picker
:show="showFixPicker"
:columns="[maintainSite]"
keyName="name"
:immediateChange="true"
@confirm="confirmFix"
@cancel="showFixPicker = false"
>
</u-picker>
<u--input
border="surround"
:disabledColor="disabled ? '#f5f7fa' : '#ffffff'"
disabled
fontSize="26"
:value="maintainSite[maintainSel].name"
@tap="!disabled && (showFixPicker = true)"
>
</u--input>
</view>
<view class="item">
<view class="title">接车服务费</view>
<u-input
border="surround"
v-model="datas.pickupServiceFee"
@blur="formatToFixed"
:disabled="disabled"
type="digit"
fontSize="26"
>
<template slot="suffix">
<text class="unit"></text>
</template>
</u-input>
</view>
<!-- <view
style="margin-top: 10rpx"
v-if="datas.returnLocationType === 3"
>
<u--input
border="surround"
v-model="otherInpt"
fontSize="26"
></u--input>
</view> -->
</view>
<view class="item">
<button class="btn checkList required" @tap="openCheckListPopup">
还车检查单
</button>
</view>
</u-collapse-item>
<u-collapse-item ref="uploadCollapse" title="照片上传" name="pic">
<view class="item">
<view class="title required">仪表盘照片</view>
<u-upload
:fileList="getFileList(1)"
@afterRead="afterRead"
@delete="deletePic"
:maxCount="2"
multiple
:width="200"
:height="200"
:disabled="disabled"
:deletable="!disabled"
name="1"
></u-upload>
</view>
<view class="item">
<view class="title required">正面照片</view>
<u-upload
:fileList="getFileList(2)"
@afterRead="afterRead"
@delete="deletePic"
:maxCount="1"
:width="200"
:height="200"
:disabled="disabled"
:deletable="!disabled"
name="2"
></u-upload>
</view>
<view class="item">
<view class="title required">左前方照片</view>
<u-upload
:fileList="getFileList(3)"
@afterRead="afterRead"
@delete="deletePic"
:maxCount="1"
:width="200"
:height="200"
:disabled="disabled"
:deletable="!disabled"
name="3"
></u-upload>
</view>
<view class="item">
<view class="title required">右前方照片</view>
<u-upload
:fileList="getFileList(4)"
@afterRead="afterRead"
@delete="deletePic"
:maxCount="1"
:width="200"
:height="200"
:disabled="disabled"
:deletable="!disabled"
name="4"
></u-upload>
</view>
<view class="item">
<view class="title required">左后方照片</view>
<u-upload
:fileList="getFileList(5)"
@afterRead="afterRead"
@delete="deletePic"
:maxCount="1"
:width="200"
:height="200"
:disabled="disabled"
:deletable="!disabled"
name="5"
></u-upload>
</view>
<view class="item">
<view class="title required">右后方照片</view>
<u-upload
:fileList="getFileList(6)"
@afterRead="afterRead"
@delete="deletePic"
:maxCount="1"
:width="200"
:height="200"
:disabled="disabled"
:deletable="!disabled"
name="6"
></u-upload>
</view>
<view class="item">
<view class="title">瑕疵照片</view>
<u-upload
:fileList="getFileList(7)"
@afterRead="afterRead"
@delete="deletePic"
:maxCount="10"
:width="155"
:height="155"
multiple
:disabled="disabled"
:deletable="!disabled"
name="7"
></u-upload>
</view>
<view class="item">
<view class="title">轮胎照片</view>
<u-upload
:fileList="getFileList(8)"
@afterRead="afterRead"
@delete="deletePic"
:maxCount="20"
multiple
:width="155"
:height="155"
:disabled="true"
:deletable="!disabled"
name="8"
></u-upload>
</view>
<view class="item">
<view class="title required">轮胎照片</view>
<view
class="flexBox"
v-if="datas.take.truckSimple.tireNumber == 6"
>
<view class="flexItem">
<u-upload
:fileList="getFileList(15)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="15"
></u-upload>
<view class="title">左前轮</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(16)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="16"
></u-upload>
<view class="title">左后轮()</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(17)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="17"
></u-upload>
<view class="title">左后轮()</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(18)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="18"
></u-upload>
<view class="title">右前轮</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(19)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="19"
></u-upload>
<view class="title">右后轮()</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(20)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="20"
></u-upload>
<view class="title">右后轮()</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(21)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="21"
></u-upload>
<view class="title">备胎</view>
</view>
</view>
<view
class="flexBox"
v-else-if="
datas.take.truckSimple.tireNumber == 10 ||
datas.take.truckSimple.tireNumber == 12
"
>
<template v-if="datas.take.truckSimple.tireNumber == 10">
<view class="flexItem">
<u-upload
:fileList="getFileList(15)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="15"
></u-upload>
<view class="title">左前轮</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(18)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="18"
></u-upload>
<view class="title">右前轮</view>
</view>
</template>
<template v-else>
<view class="flexItem">
<u-upload
:fileList="getFileList(36)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="36"
></u-upload>
<view class="title">左前外</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(37)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="37"
></u-upload>
<view class="title">左前内</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(38)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="38"
></u-upload>
<view class="title">右前外</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(39)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="39"
></u-upload>
<view class="title">右前内</view>
</view>
</template>
<view class="flexItem">
<u-upload
:fileList="getFileList(22)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="22"
></u-upload>
<view class="title">左中内</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(23)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="23"
></u-upload>
<view class="title">左中外</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(24)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="24"
></u-upload>
<view class="title">左后内</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(25)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="25"
></u-upload>
<view class="title">左后外</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(26)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="26"
></u-upload>
<view class="title">右中内</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(27)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="27"
></u-upload>
<view class="title">右中外</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(28)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="28"
></u-upload>
<view class="title">右后内</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(29)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="29"
></u-upload>
<view class="title">右后外</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(21)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="21"
></u-upload>
<view class="title">备胎</view>
</view>
</view>
</view>
<view class="item">
<view class="title required">底盘照片</view>
<view class="flexBox">
<view class="flexItem">
<u-upload
:fileList="getFileList(30)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="30"
></u-upload>
<view class="title">正前方底部</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(31)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="31"
></u-upload>
<view class="title">左侧前部底部</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(32)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="32"
></u-upload>
<view class="title">左侧后方底部</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(33)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="33"
></u-upload>
<view class="title">右侧前方底部</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(34)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="34"
></u-upload>
<view class="title">右侧后方底部</view>
</view>
<view class="flexItem">
<u-upload
:fileList="getFileList(35)"
@afterRead="afterRead"
@delete="deletePic"
:width="155"
:height="155"
:maxCount="1"
:disabled="disabled"
:deletable="!disabled"
name="35"
></u-upload>
<view class="title">正后方底部</view>
</view>
</view>
</view>
<view class="item">
<view class="title">其它</view>
<u-upload
:fileList="getFileList(9)"
@afterRead="afterRead"
@delete="deletePic"
:maxCount="10"
:width="155"
multiple
:height="155"
:disabled="disabled"
:deletable="!disabled"
name="9"
></u-upload>
</view>
</u-collapse-item>
<!-- <u-collapse-item title="费用信息" ref="costCollapse" name="cost">
<view class="item" style="width: 20px">
<u-button
class="btn"
style=""
type="primary"
size="mini"
plain
@tap="addForm"
text="添加"
></u-button>
</view>
<view class="item department">
<view
class="truckItem"
v-for="(item, index) in departmentList"
:key="index"
>
<view class="item">
<view class="title">项目</view>
<picker
@change="confirmSubject($event, index)"
:range="subjectList"
:disabled="disabled"
range-key="name"
>
<u--input
border="surround"
:disabledColor="disabled ? '#f5f7fa' : '#ffffff'"
:value="item.subjectName"
:disabled="true"
fontSize="26"
>
</u--input>
</picker>
</view>
<view class="item">
<view class="title required">金额</view>
<u-input
border="surround"
:value="item.amount"
@change="(value) => (departmentList[index].amount = value)"
fontSize="26"
type="digit"
:disabled="disabled"
>
</u-input>
</view>
<view class="item">
<view class="title">备注</view>
<u--textarea
border="surround"
v-model="item.remark"
fontSize="26"
:disabled="disabled"
></u--textarea>
</view>
<view class="item">
<view class="title">照片</view>
<u-upload
:fileList="item.pictureList"
@afterRead="afterReadCost"
:width="155"
multiple
:height="155"
:name="index"
:disabled="disabled"
:deletable="!disabled"
@delete="deletePicCost"
></u-upload>
</view>
<view class="item">
<view class="title">附件</view>
<view class="block">
<view class="item">
<u-upload
:fileList="item.attachmentList"
:disabled="disabled"
@afterRead="afterReadPdf"
uploadIcon="plus"
accept="all"
multiple
@delete="deletePdfCost"
:deletable="!disabled"
:width="155"
:height="155"
:name="index"
></u-upload>
</view>
<view
class="item"
v-for="t in item.attachmentList"
:key="t.url"
>
<view class="line" style="justify-content: space-between">
<view class="text-small left">{{ t.fileName }}</view>
<view class="text-small" @tap="previewYyPdf(t)"
>预览</view
>
</view>
</view>
</view>
</view>
<view class="item">
<view class="depDetailCostVoListBtns">
<button
:class="{ disabled: isRead }"
class="del"
@tap="delForm(index)"
>
删除
</button>
</view>
</view>
</view>
</view>
</u-collapse-item> -->
<u-collapse-item title="还车说明" name="explain">
<view class="item">
<view class="title">备注</view>
<u--textarea
border="surround"
v-model="datas.remark"
fontSize="26"
:disabled="disabled"
></u--textarea>
</view>
<view class="item">
<view class="title">相关材料</view>
<u-upload
:fileList="getFileList(12)"
@afterRead="afterRead"
@delete="deletePic"
:maxCount="10"
multiple
:width="155"
:height="155"
:disabled="disabled"
:deletable="!disabled"
name="12"
></u-upload>
</view>
<view class="item">
<view class="title">司机证件</view>
<u-upload
:fileList="getFileList(10)"
@afterRead="afterRead"
@delete="deletePic"
:maxCount="10"
multiple
:width="155"
:height="155"
:disabled="disabled"
:deletable="!disabled"
name="10"
></u-upload>
</view>
</u-collapse-item>
<u-collapse-item title="签收栏" name="sign">
<view class="item">
<button
class="btn sign"
:class="{ disabled: disabled }"
:disabled="disabled"
@tap="generateWord"
>
点击签名
</button>
<button
v-if="clearButton"
class="btn sign"
style="
background-color: #fff;
color: #7ba746;
border: 1px solid #7ba746;
"
:class="{ disabled: disabled }"
:disabled="disabled"
@tap="clearSign"
>
清除签名信息
</button>
</view>
<view class="item">
<button
class="btn genDocument"
:class="{ disabled: disabled }"
:disabled="disabled"
@tap="fileDownloadUrl"
>
生成签署文件
</button>
</view>
<view class="item">
<u-upload
:fileList="getFileList(11)"
@afterRead="afterRead"
@delete="deletePic"
uploadIcon="plus"
:disabled="true"
:deletable="false"
:previewFullImage="false"
@tap="previewPdf"
:maxCount="1"
:width="155"
:height="155"
name="11"
></u-upload>
</view>
</u-collapse-item>
</u-collapse>
<u-loading-page
bg-color="#ffffff"
color="#7ba746"
font-size="24"
:loading="loading"
:loading-text="loadingText"
></u-loading-page>
<view>
<!-- <page-container :show="checkListShow" :duration="0" :overlay="false"> -->
<u-popup :show="checkListShow" mode="right">
<scroll-view scroll-y="true" style="height: 95vh">
<!-- 编辑模式 -->
<no-bad-table
:columns="columns"
:list="formDataList"
:spanArr="spanArr"
:isRead="disabled"
:slot-cols="[
'dataCategory',
'dataName',
'returnTruck',
'remark',
]"
:span-method="objectSpanMethod"
>
<template v-slot="{ row, col, index, isRead }">
<view
v-if="col.key == 'dataCategory'"
style="white-space: pre-wrap"
>
{{ row.dataCategory }}
</view>
<view
v-else-if="col.key == 'dataName'"
style="white-space: pre-wrap"
>
{{ row.dataName }}
</view>
<view
v-else-if="col.key == 'returnTruck'"
style="display: flex; justify-content: center"
>
<u-switch
size="50"
v-if="row.dataType != 3"
v-model="row.returnTruck"
@change="switchTakeTruck(index)"
:disabled="isRead"
inactiveColor="#f5f7fa"
activeColor="#7ba746"
>
</u-switch>
<u--input
border="surround"
fontSize="26"
v-else
:value="row.returnTruck"
:disabled="isRead"
@change="inputTakeTruck($event, index)"
>
</u--input>
</view>
<view
v-else-if="col.key == 'remark' && !row.notUpdate"
style="display: flex; justify-content: center"
>
<u--input
border="surround"
fontSize="26"
v-if="row.dataType != 3"
:value="row.remark"
:disabled="isRead"
@change="inputQuality($event, index)"
>
</u--input>
</view>
</template>
</no-bad-table>
<view class="btns">
<button
class="save"
:class="{ disabled: disabled }"
:disabled="disabled"
@tap="saveFormDataList"
>
保存
</button>
<button class="cancel" @tap="cancelFormDataChange">取消</button>
</view>
</scroll-view>
</u-popup>
<!-- </page-container> -->
</view>
<view class="btns">
<button
class="done"
:class="{ disabled: isRead }"
:disabled="isRead"
@tap="submitConfirm"
>
提交
</button>
<button
class="done"
:class="{ disabled: isRead }"
:disabled="isRead"
@tap="save(false)"
>
保存
</button>
<button class="cancel" @tap="navigateBack">取消</button>
</view>
<view style="width: 0px; height: 0px; overflow: hidden">
<canvas
:style="
'width: ' +
canvasWidth +
'px; height:' +
canvasHeight +
'px;left:8888px'
"
canvas-id="myCanvas"
></canvas>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
import { getUser } from "@/utils/auth.js";
import { checkButtonPermission } from "@/utils/permission.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
value: null,
checkListShow: false, // 检查单弹窗
spanArr: [],
showParkOrFixPicker: false,
showParkPicker: false,
showFixPicker: false,
showParkingPicker: false,
parkingSel: "",
maintainSel: "",
parkingList: [],
maintainSite: [], // 维修站
otherInpt: "", //其他输入框
returnLocationTypeList: [
// {
// dicCode: 1,
// dicName: "停车场",
// },
// {
// dicCode: 2,
// dicName: "维修站",
// },
// {
// dicCode: 3,
// dicName: "其他",
// },
],
columns: [
{
title: "检查类别",
key: "dataCategory",
},
{
title: "检查项目",
key: "dataName",
},
{
title: "是否拥有/检查",
key: "returnTruck",
},
{
title: "数量/备注",
key: "remark",
},
],
range: [
{ value: 1, text: "%" },
{ value: 2, text: "MPa" },
{ value: 3, text: "kg" },
],
datas: {
contractNo: "合同编号",
projectName: "项目名称",
isDrivingTraining: 0,
dataList: [], // 交车单数据
hydrogenUnit: null,
returnLocationType: "",
pickupServiceFee: "", //接车服务费
take: {
truckSimple: {
tireNumber: 6,
},
},
},
DrivingTrainingRange: [
{ value: 0, text: "否" },
{ value: 1, text: "是" },
],
id: "1062294605097091072",
brands: [], // 车辆品牌字典列表
truckType: [], // 车辆型号字典列表,
salesManagerDic: [], // 销售经理字典列表
userInfo: {}, // 用户信息
contractAuthorizerInformationList: [], // 授权人列表
inStoreList: [], // 在库状态车辆列表
showAuthorizerPicker: false,
showIsDrivingTrainingPicker: false,
showHandoverDatePicker: false,
platNumberDisabled: true,
showPlateNumberPicker: false,
// 文件列表配置
fileConfig: {
// 基础照片
1: { key: "dashboardPic", maxCount: 2, isArray: false }, // 仪表盘照片
2: { key: "frontPic", maxCount: 1, isArray: false }, // 正面照片
3: { key: "leftFrontPic", maxCount: 1, isArray: false }, // 左前方照片
4: { key: "rightFrontPic", maxCount: 1, isArray: false }, // 右前方照片
5: { key: "leftRearPic", maxCount: 1, isArray: false }, // 左后方照片
6: { key: "rightRearPic", maxCount: 1, isArray: false }, // 右后方照片
7: { key: "blemish", maxCount: 10, isArray: true }, // 瑕疵照片
8: { key: "tirePic", maxCount: 20, isArray: true }, // 轮胎照片
9: { key: "otherPics", maxCount: 10, isArray: true }, // 其它
10: { key: "documents", maxCount: 10, isArray: true }, // 司机证件
11: { key: "esignatureAttachment", maxCount: 1, isArray: true }, // 电子文档
12: { key: "signAttachment", maxCount: 10, isArray: true }, // 相关材料
// 底盘照片
30: { key: "frontBottomPic", maxCount: 1, isArray: false }, // 正前方底部照片
31: { key: "leftFrontBottomPic", maxCount: 1, isArray: false }, // 左侧前部底部照片
32: { key: "leftRearBottomPic", maxCount: 1, isArray: false }, // 左侧后方底部照片
33: { key: "rightFrontBottomPic", maxCount: 1, isArray: false }, // 右侧前方底部照片
34: { key: "rightRearBottomPic", maxCount: 1, isArray: false }, // 右侧后方底部照片
35: { key: "rearBottomPic", maxCount: 1, isArray: false }, // 正后方底部照片
// 6轮轮胎照片
15: {
key: "leftFrontTirePic",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 左前轮照片
16: {
key: "leftRearTirePicIn",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 左后轮(内)
17: {
key: "leftRearTirePicOut",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 左后轮(外)
18: {
key: "rightFrontTirePic",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 右前轮
19: {
key: "rightRearTirePicIn",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 右后轮(内)
20: {
key: "rightRearTirePicOut",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 右后轮(外)
21: { key: "spareTirePic", maxCount: 1, isArray: false }, // 备胎
// 12轮车新增的轮胎字段
36: {
key: "leftFrontTirePicOut",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 左前外
37: {
key: "leftFrontTirePicIn",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 左前内
38: {
key: "rightFrontTirePicOut",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 右前外
39: {
key: "rightFrontTirePicIn",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 右前内
// 10轮轮胎照片
22: {
key: "leftMiddleTirePicIn",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 左中内
23: {
key: "leftMiddleTirePicOut",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 左中外
24: {
key: "leftRearMiddleTirePicIn",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 左后内
25: {
key: "leftRearMiddleTirePicOut",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 左后外
26: {
key: "rightMiddleTirePicIn",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 右中内
27: {
key: "rightMiddleTirePicOut",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 右中外
28: {
key: "rightRearMiddleTirePicIn",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 右后内
29: {
key: "rightRearMiddleTirePicOut",
maxCount: 1,
isArray: false,
showTireModal: true,
}, // 右后外
},
// 动态生成的文件列表
fileLists: {},
// 轮胎厚度映射
canvasWidth: 0,
canvasHeight: 0,
isRead: false, // 页面是否处于阅读模式
formDataList: [], // 交车检查单数据副本
loading: false,
loadingText: "加载中...",
hasSign: false, // 已完成签名,签署文件已生成
hasSaveCheckList: false, // 是否保存过还车检查单
compressPicMap: new Map(), // 缩略图映射key为原图value为缩略图
isPageShow: false,
departmentList: [],
subjectList: [], // 项目列表
gpsLocation: "", // GPS定位用在水印上 以前的datas.returnLocation已经改做他用了
showClearTip: false, // 是否显示提示清除签章
};
},
methods: {
formatToFixed() {
if (
this.datas.pickupServiceFee === "" ||
this.datas.pickupServiceFee == null
)
return;
// 转为数字,保留两位小数,再转回字符串(避免科学计数法)
const num = parseFloat(this.datas.pickupServiceFee);
if (!isNaN(num)) {
this.$set(this.datas, "pickupServiceFee", num.toFixed(2));
} else {
this.$set(this.datas, "pickupServiceFee", "");
}
},
trimSpace(val) {
if (val === "returnDriver" && this.datas.signFlowId) {
this.showClearTip = true;
//在修改签章人信息后记录一个信息被修改的标签,点击点击签名的时候验证标签如果是则提示先点击清除签名信息.
}
this.datas[val] = this.datas[val]
? this.datas[val].replace(/\s+/g, "")
: "";
},
trimPhone(value) {
if (this.datas.signFlowId) {
this.showClearTip = true;
//在修改签章人信息后记录一个信息被修改的标签,点击点击签名的时候验证标签如果是则提示先点击清除签名信息.
}
this.datas.returneePhone = value ? value.replace(/[^0-9]/g, "") : "";
},
//还车地点逻辑相关调整
maintainSiteSelect() {
this.$api.returnCar.getFixPageList().then((res) => {
console.log(res);
this.maintainSite = res;
});
},
async getLocationTypeList() {
this.$api.returnCar.getLocationTypeList().then((res) => {
console.log(`res:`, res);
this.returnLocationTypeList = res;
});
},
async getParkList() {
await this.$api.returnCar
.getParkingPageList({
pageNo: 1,
pageSize: 999,
})
.then((res) => {
if (res) {
let datas = res?.data;
this.parkingList = datas.records.map((item) => {
return {
dicCode: item.id,
dicName: item.parkingName,
};
});
}
});
},
confirmIsParkOrFix(e) {
this.datas.returnLocationType = e.value[0].dicCode;
this.showParkOrFixPicker = false;
console.log(
`this.datas.returnLocationType:`,
this.datas.returnLocationType
);
this.$nextTick(() => {
// 解决折叠collapse高度无法动态更新的问题
this.$refs.trunkCollapse.init();
});
},
confirmPark(e) {
this.parkingSel = e.indexs[0];
this.showParkPicker = false;
},
confirmFix(e) {
this.maintainSel = e.indexs[0];
this.showFixPicker = false;
},
onBeforeleave() {
this.isPageShow = false;
if (this.checkListShow) {
this.checkListShow = false;
this.$nextTick(() => {
this.isPageShow = true;
});
} else {
uni.showModal({
title: "离开提示",
content: "请确认是否退出当前界面?",
success: (res) => {
if (res.confirm) {
this.navigateBack();
} else {
this.isPageShow = true;
console.log("用户点击取消");
}
},
});
}
// this.$nextTick(() => {
// this.isPageShow = true;
// });
// this.isPageShow = false;
//
// setTimeout(() => {
// this.isPageShow = true;
// }, 10);
},
getData() {
this.$api.returnCar.getTakeId({ id: this.id }).then((res) => {
res.truckRentTaskId = this.id;
// 避免出现额外的小数,"100.00" => 100
res.takeMileage = res.takeMileage ? Number(res.takeMileage) : null;
res.electricity = res.electricity ? Number(res.electricity) : null;
res.hydrogenMeasure = res.hydrogenMeasure
? Number(res.hydrogenMeasure)
: null;
this.datas = res;
console.log("res", res);
this.$set(this.datas, "returnLocationType", res.returnLocationType); //set大法好
if (this.datas.returnLocationType == 1) {
const parkingIndex =
this.parkingList.findIndex(
(item) => item.dicCode == res?.returnLocation
) ?? "";
this.$set(this, "parkingSel", parkingIndex); //set大法好
} else if (this.datas.returnLocationType == 2) {
const fixIndex =
this.maintainSite.findIndex(
(item) => item.id == res?.returnLocation
) ?? "";
console.log(this.maintainSite);
console.log(res?.returnLocation);
console.log("fixIndex", fixIndex);
this.$set(this, "maintainSel", fixIndex); //set大法好
}
console.log("res", res.depDetailCostEoList);
this.departmentList =
res.depDetailCostEoList.map((t) => {
t.subjectName = this.subjectList.filter(
(s) => s.id == t.costSubjectId
)[0]?.name;
t.pictureList = t.pictureList.map((p) => {
p.url = p.path;
p.thumb = p.compressedImagePath || p.path;
return p;
});
t.attachmentList = t.attachmentList.map((p) => {
p.url = p.path;
return p;
});
return t;
}) || [];
// if (!res.depDetailCostEoList || res.depDetailCostEoList.length === 0) {
// this.addForm();
// } else {
// this.departmentList = res.depDetailCostEoList; // 部门费用
// }
this.datas.hydrogenUnit = this.datas.take.hydrogenUnit; // 沿用交车单单位
const authorizerList = res.contractAuthorizerInformationList;
this.contractAuthorizerInformationList = authorizerList;
// 如果授权人列表只有一个授权人,默认填入
if (authorizerList && authorizerList.length == 1) {
this.datas.takeName = authorizerList[0].authorizer;
this.datas.takeIdNo = authorizerList[0].authorizerIdentityCard;
this.datas.takePhone = authorizerList[0].authorizerTelephone;
}
// 将底盘照片从对象格式转换为字符串格式,统一处理
this.convertChassisPicsToString();
// 根据后端相应的相关图片字段重新得到fileList用于前端图片预览
this.parseFileListBack();
// 自动获取用户当前位置,填入 "交车地点" 字段中
//2025.1.23注释 还停车地点由用户选择车场/维修站
//2025.3.4恢复 水印需要
if (!this.isRead) {
this.getLocation();
}
// formDataList为深度拷贝的一个对象并不会直接影响到该车辆的交车检查单单信息
this.formDataList = this.processFormDataList(
this.deepClone(this.datas.dataList)
);
this.getSpanArr(this.formDataList);
this.$nextTick(() => {
// this.$refs.costCollapse.init();
this.$refs.trunkCollapse.init();
});
});
},
// 将底盘照片从对象格式转换为字符串格式
convertChassisPicsToString() {
const chassisPicKeys = [
"frontBottomPic",
"leftFrontBottomPic",
"leftRearBottomPic",
"rightFrontBottomPic",
"rightRearBottomPic",
"rearBottomPic",
];
chassisPicKeys.forEach((key) => {
const picData = this.datas[key];
// 如果是对象格式提取path作为字符串
if (picData && typeof picData === "object" && picData.path) {
this.datas[key] = picData.path;
}
});
},
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
navigateBack() {
this.isPageShow = false;
setTimeout(() => {
uni.navigateBack();
}, 100);
},
formatDateTime(obj, type = "date") {
if (obj == null) {
return "";
}
// 精确到日
if (type == "date") {
let date = new Date(obj);
let y = 1900 + date.getYear();
let m = "0" + (date.getMonth() + 1);
let d = "0" + date.getDate();
return (
y +
"-" +
m.substring(m.length - 2, m.length) +
"-" +
d.substring(d.length - 2, d.length)
);
}
// 精确到小时
else if (type == "hour") {
const date = new Date(obj); // 将时间戳转换为毫秒
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从0开始
const day = String(date.getDate()).padStart(2, "0");
const hour = String(date.getHours()).padStart(2, "0");
const minute = String(date.getMinutes()).padStart(2, "0");
return `${year}-${month}-${day} ${hour}:${minute}`;
}
},
getNowDateTime() {
let currentTime = new Date();
let year = currentTime.getFullYear();
let month = currentTime.getMonth() + 1;
let day = currentTime.getDate();
let hours = currentTime.getHours();
let minutes = currentTime.getMinutes();
month = month < 10 ? "0" + month : month;
day = day < 10 ? "0" + day : day;
hours = hours < 10 ? "0" + hours : hours;
minutes = minutes < 10 ? "0" + minutes : minutes;
return `${year}-${month}-${day} ${hours}:${minutes}`;
},
getDic() {
this.$api.standbyVehicle.getVehicleBrand().then((res) => {
this.brands = res;
});
this.$api.standbyVehicle.getTruckType().then((res) => {
this.truckType = res;
});
this.$api.returnCar.getSalesManagerDic().then((res) => {
this.salesManagerDic = res;
});
},
getBrandName(dicCode) {
return this.getDicValue(this.brands, dicCode);
},
getModelName(dicCode) {
return this.getDicValue(this.truckType, dicCode);
},
getSalesManagerName(dicCode) {
return this.getDicValue(this.salesManagerDic, dicCode);
},
getDicValue(dic, dicCode) {
if (dic.length == 0) {
return "";
}
return dic.find((x) => x.dicCode == dicCode)?.dicName ?? "";
},
getInStoreList() {
this.$api.truck.queryInStoreList({}).then((res) => {
this.inStoreList = res;
});
},
confirmAuthorizer(e) {
this.showAuthorizerPicker = false;
this.datas.takeName = e.value[0].authorizer;
this.datas.takeIdNo = e.value[0].authorizerIdentityCard;
this.datas.takePhone = e.value[0].authorizerTelephone;
},
confirmIsDrivingTraining(e) {
this.datas.isDrivingTraining = e.indexs[0];
this.showIsDrivingTrainingPicker = false;
},
confirmHandoverDate(e) {
if (e.value) {
const selectedTime = new Date(e.value);
const now = new Date();
// 如果选择的日期是今天,检查时间是否超过当前时间
if (selectedTime > now) {
this.alert("还车时间不能大于当前时间");
this.datas.returnDate = now.getTime();
} else {
this.datas.returnDate = e.value;
}
}
this.showHandoverDatePicker = false;
},
enbalbeChangeTruck() {
this.platNumberDisabled = false;
this.showPlateNumberPicker = true;
},
getLocation() {
uni.getLocation({
type: "wgs84",
success: (res) => {
const longitude = res.longitude;
const latitude = res.latitude;
this.$api.returnCar
.getAddress({ longitude, latitude })
.then((res) => {
console.log("getLocation", res);
this.gpsLocation = res?.data ?? "浙江省嘉兴市";
});
},
fail: (err) => {
console.log(err);
if (
err.errMsg.includes("auth deny") ||
err.errMsg.includes("auth denied")
) {
// 判断是临时拒绝还是永久拒绝
// 方法:调用 wx.getSetting 检查用户授权状态
uni.getSetting({
success: (res) => {
console.log("getSetting", res);
if (res.authSetting["scope.userLocation"] === false) {
let that = this;
// 返回 false 表示用户**永久拒绝**了授权
uni.showModal({
title: "定位权限被关闭",
content:
"您已关闭定位权限,无法获取位置。请前往设置页手动开启。",
confirmText: "去设置",
showCancel: true,
success: function (modalRes) {
if (modalRes.confirm) {
// 跳转到小程序设置页
uni.openSetting({
success: (settingRes) => {
// 用户在设置页修改了权限
if (settingRes.authSetting["scope.userLocation"]) {
// 权限已开启,重新获取位置
uni.getLocation({
type: "wgs84",
success: (locRes) => {
console.log("重新获取位置成功:", locRes);
const longitude = locRes.longitude;
const latitude = locRes.latitude;
that.$api.returnCar
.getAddress({ longitude, latitude })
.then((res) => {
console.log("getLocation", res);
that.gpsLocation =
res?.data ?? "浙江省嘉兴市";
});
},
fail: (locErr) => {
console.log("重新获取位置失败:", locErr);
uni.showToast({
title: "仍未获取到位置",
icon: "none",
});
},
});
} else {
uni.showToast({
title: "请开启定位权限",
icon: "none",
});
}
},
});
}
},
});
} else {
// 返回 undefined 表示未授权(可能是临时拒绝)
uni.showModal({
title: "需要定位权限",
content: "请允许定位授权以使用此功能。",
confirmText: "去授权",
success: function (modalRes) {
if (modalRes.confirm) {
// 再次尝试,可能会弹出授权窗口
getLocation();
}
},
});
}
},
fail: (err) => {
console.error("获取设置失败:", err);
uni.showToast({ title: "检查权限失败", icon: "none" });
},
});
} else {
uni.showToast({
title: "获取位置失败: " + err.errMsg,
icon: "none",
});
}
},
});
},
objectSpanMethod(row, column, rowIndex, columnIndex) {
if (columnIndex === 0) {
const _row = this.spanArr[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col,
};
}
},
switchTakeTruck(index) {
this.formDataList[index].returnTruck =
!this.formDataList[index].returnTruck;
},
inputQuality(value, index) {
if (
["证件信息", "工具信息"].includes(this.formDataList[index].dataCategory)
) {
if (value) {
this.formDataList[index].returnTruck = true;
} else {
this.formDataList[index].returnTruck = false;
}
}
this.formDataList[index].remark = value;
},
inputTakeTruck(value, index) {
this.formDataList[index].returnTruck = value;
},
cancelFormDataChange() {
this.formDataList = this.processFormDataList(
this.deepClone(this.datas.dataList)
);
this.getSpanArr(this.formDataList);
this.checkListShow = false;
uni.setNavigationBarTitle({
title: "还车信息",
});
},
getSpanArr(data) {
this.spanArr = [];
for (let i = 0; i < data.length; i++) {
if (i === 0) {
this.spanArr.push(1);
this.pos = 0;
} else {
// 判断当前元素与上一个元素是否相同 dataCategory (类别字段)
if (data[i].dataCategory === data[i - 1].dataCategory) {
this.spanArr[this.pos] += 1;
this.spanArr.push(0);
} else {
this.spanArr.push(1);
this.pos = i;
}
}
}
console.log(data);
console.log(this.spanArr);
},
deepClone(obj) {
if (obj === null) return null;
if (typeof obj !== "object") return obj;
if (obj instanceof Date) {
let date = new Date();
date.setTime(obj.getTime());
return date;
}
if (obj instanceof RegExp) {
let re = new RegExp(obj.source);
re.lastIndex = obj.lastIndex;
return re;
}
let newObj = new obj.constructor();
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = this.deepClone(obj[key]);
}
}
return newObj;
},
processFormDataList(dataList) {
dataList = dataList.filter((x) => x.dataName != "检查项目");
for (let item of dataList) {
if (item.dataType === 3) {
// 当 dataType == 3 时,只显示非 "true"、非 "false" 和非空字符串的值
if (
item.returnTruck !== "true" &&
item.returnTruck !== "false" &&
item.returnTruck !== ""
) {
// 保留并显示该值
item.returnTruck = item.returnTruck;
} else {
// 显示空字符串
item.returnTruck = ""; // 或者 item.returnTruck = null;
}
} else if (item.dataType === 1) {
// 当 dataType == 1 时,处理 returnTruck 的值
if (item.returnTruck === "true" || item.returnTruck === true) {
item.returnTruck = true;
} else {
item.returnTruck = false;
}
}
}
return dataList;
},
openCheckListPopup() {
this.checkListShow = true;
uni.setNavigationBarTitle({
title: "还车检查单",
});
},
change(e) {
this.datas.hydrogenUnit = e;
},
checkCameraPermission() {
console.log("checkCameraPermission");
uni.getSetting({
success(res) {
if (!res.authSetting["scope.camera"]) {
console.log(`有相机权限`);
return;
} else {
console.log(`没有相机权限! 开始申请获取`);
this.requestCameraPermission();
}
},
fail(e) {
console.log(`获取setting失败:\n`, e);
},
});
},
requestCameraPermission() {
uni.authorize({
scope: "scope.camera",
success() {
console.log(`相机权限授权成功`);
},
fail() {
console.log(`相机权限授权失败`);
},
});
},
// 保存备车检查单
saveFormDataList() {
if (!this.checkFormData()) {
return false;
}
this.hasSaveCheckList = true;
this.checkListShow = false;
this.datas.dataList = this.deepClone(this.formDataList);
uni.setNavigationBarTitle({
title: "还车信息",
});
},
// 检查备车检查单是否正确填写
checkFormData(alert = true) {
const targets = this.formDataList.filter(
(x) => x.dataCategory == "外观检查" && x.dataName != "其他"
);
const target = targets?.find(
(x) => (!x.returnTruck || x.returnTruck === "false") && !x.remark
);
if (target) {
alert && this.alert(`${target.dataName} 未勾选,需填写备注!`);
return false;
}
return true;
},
// 初始化文件列表
initFileLists() {
Object.keys(this.fileConfig).forEach((key) => {
this.$set(this.fileLists, key, []);
});
},
// 获取文件列表
getFileList(name) {
return this.fileLists[name] || [];
},
// 删除图片
deletePic(event) {
const name = event.name;
const fileList = this.getFileList(name);
if (fileList.some((x) => x.status == "uploading")) {
this.alert(`请等待现有图片上传完成后再操作`);
return;
}
fileList.splice(event.index, 1);
this.updateDataFromFileList(name);
this.save(true); //自动保存
},
// 根据文件列表更新数据
updateDataFromFileList(name) {
const config = this.fileConfig[name];
if (!config) return;
const fileList = this.getFileList(name);
const urls = fileList.map((item) => item.url).filter((url) => url);
if (config.isArray) {
// 数组类型
if (name === "7") {
// 瑕疵照片
this.datas.blemish = urls.map((url) => url);
} else if (name === "8") {
// 轮胎照片
this.datas.tirePic = urls.map((url) => url);
} else if (name === "9") {
// 其他
this.datas.otherPics = urls.map((url) => ({ path: url }));
} else if (name === "10") {
// 司机证件
this.datas.documents = urls;
} else if (name === "11") {
// 电子文档
this.datas.esignatureAttachment = urls.map((url) => ({ path: url }));
} else if (name === "12") {
// 相关材料
this.datas.signAttachment = urls.map((url) => ({ path: url }));
}
} else {
// 单个或多个但非数组类型
if (name === "1") {
// 仪表盘照片特殊处理最多2张
if (fileList.length === 0) {
this.datas.dashboardPic = "";
this.datas.dashboard2Pic = "";
} else if (fileList.length === 1) {
this.datas.dashboardPic = urls[0] || "";
this.datas.dashboard2Pic = "";
} else {
this.datas.dashboardPic = urls[0] || "";
this.datas.dashboard2Pic = urls[1] || "";
}
} else if (name >= 30 && name <= 35) {
// 底盘照片,需要转换为字符串格式
this.datas[config.key] = urls[0] || "";
} else {
// 其他单个图片
this.datas[config.key] = urls[0] || "";
}
}
},
// 新增图片
async afterRead(event) {
const name = event.name;
const config = this.fileConfig[name];
if (!config) return;
// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file);
let fileList = this.getFileList(name);
let fileListLen = fileList.length;
// 添加上传中状态
lists.map((item) => {
fileList.push({
...item,
status: "uploading",
message: "上传中",
});
});
for (let i = 0; i < lists.length; i++) {
this.loading = true;
this.loadingText = "添加水印中...";
const fileSize = lists[i].size / 1024 ** 2; // 图片多少MB
let waterUrl = "";
try {
waterUrl = await this.addWatermark(lists[i].url, fileSize);
} catch (e) {
console.log(
`e:
`,
e
);
this.alert(e.toString());
fileList.splice(fileListLen, 1);
return;
}
const result = await this.uploadFilePromise(waterUrl);
const imgUrl = result.data?.url ?? "";
if (imgUrl) {
this.compressPicMap.set(
imgUrl,
result.data?.compressedImageUrl ?? ""
);
}
// 更新文件项状态
let item = fileList[fileListLen];
fileList.splice(
fileListLen,
1,
Object.assign(item, {
status: "success",
message: "",
url: imgUrl,
thumb: waterUrl,
})
);
fileListLen++;
// 特殊处理:轮胎照片上传后显示厚度输入框
if (config.showTireModal && imgUrl) {
this.showTireModal(config.key);
}
this.$nextTick(() => {
// 解决折叠collapse高度无法动态更新的问题
this.$refs.uploadCollapse.init();
});
}
// 更新数据
this.updateDataFromFileList(name);
this.save(true); //自动保存
},
showTireModal(tire) {
let tireTitle = "";
let inputName = "";
//4.5 18t
if (this.datas.take.truckSimple.tireNumber === 6) {
switch (tire) {
case "leftFrontTirePic":
tireTitle = "左前轮";
inputName = "左前1轴";
break;
case "leftRearTirePicIn":
tireTitle = "左后轮(内)";
inputName = "左后内2轴";
break;
case "leftRearTirePicOut":
tireTitle = "左后轮(外)";
inputName = "左后外2轴";
break;
case "rightFrontTirePic":
tireTitle = "右前轮";
inputName = "右前1轴";
break;
case "rightRearTirePicIn":
tireTitle = "右后轮(内)";
inputName = "右后内2轴";
break;
case "rightRearTirePicOut":
tireTitle = "右后轮(外)";
inputName = "右后外2轴";
break;
}
} else if (this.datas.take.truckSimple.tireNumber === 10) {
switch (tire) {
case "leftFrontTirePic":
tireTitle = "左前轮";
inputName = "左前1轴";
break;
case "rightFrontTirePic":
tireTitle = "右前轮";
inputName = "右前1轴";
break;
case "leftMiddleTirePicIn":
tireTitle = "左中内";
inputName = "左中内2轴";
break;
case "leftMiddleTirePicOut":
tireTitle = "左中外";
inputName = "中外2轴";
break;
case "leftRearMiddleTirePicIn":
tireTitle = "左后内";
inputName = "左后内3轴";
break;
case "leftRearMiddleTirePicOut":
tireTitle = "左后外";
inputName = "左后外3轴";
break;
case "rightMiddleTirePicIn":
tireTitle = "右中内";
inputName = "右中内2轴";
break;
case "rightMiddleTirePicOut":
tireTitle = "右中外";
inputName = "右中外2轴";
break;
case "rightRearMiddleTirePicIn":
tireTitle = "右后内";
inputName = "右后内3轴";
break;
case "rightRearMiddleTirePicOut":
tireTitle = "右后外";
inputName = "右后外3轴";
break;
}
} else if (this.datas.take.truckSimple.tireNumber === 12) {
switch (tire) {
case "leftFrontTirePicOut":
tireTitle = "左前外";
inputName = "左前外";
break;
case "leftFrontTirePicIn":
tireTitle = "左前内";
inputName = "左前内";
break;
case "rightFrontTirePicOut":
tireTitle = "右前外";
inputName = "右前外";
break;
case "rightFrontTirePicIn":
tireTitle = "右前内";
inputName = "右前内";
break;
case "leftMiddleTirePicIn":
tireTitle = "左中内";
inputName = "左中内";
break;
case "leftMiddleTirePicOut":
tireTitle = "左中外";
inputName = "左中外"; //中外2轴
break;
case "leftRearMiddleTirePicIn":
tireTitle = "左后内";
inputName = "左后内";
break;
case "leftRearMiddleTirePicOut":
tireTitle = "左后外";
inputName = "左后外";
break;
case "rightMiddleTirePicIn":
tireTitle = "右中内";
inputName = "右中内";
break;
case "rightMiddleTirePicOut":
tireTitle = "右中外";
inputName = "右中外";
break;
case "rightRearMiddleTirePicIn":
tireTitle = "右后内";
inputName = "右后内";
break;
case "rightRearMiddleTirePicOut":
tireTitle = "右后外";
inputName = "右后外";
break;
}
}
uni.showModal({
title: `请输入${tireTitle}厚度`,
confirmText: "确认",
editable: true,
placeholderText: "请输入轮胎厚度用于还车检查单",
success: (res) => {
if (res.confirm) {
console.log(res);
console.log(this.datas.dataList);
const obj = this.datas.dataList.find(
(item) => item.dataName === inputName
);
if (obj) {
this.$set(obj, "returnTruck", res.content);
this.$set(obj, "takeTruck", res.content);
}
this.formDataList = this.processFormDataList(
this.deepClone(this.datas.dataList)
);
this.getSpanArr(this.formDataList);
}
},
});
},
uploadFilePromise(url) {
console.log(url);
return new Promise((resolve, reject) => {
let a = uni.uploadFile({
url: "/attachment/upload",
filePath: url,
name: "file",
success: (res) => {
resolve(JSON.parse(res.data || {}));
},
fail: (e) => {
reject(e);
},
});
});
},
// 图片添加水印
async addWatermark(img, fileSize) {
const image = img;
let res1 = await new Promise((resolve, reject) => {
uni.getImageInfo({
src: img,
success: (res) => {
// 设置canvas宽高等于原图片宽高
this.canvasWidth = res.width;
this.canvasHeight = res.height;
// 创建 canvas 的绘图上下文
const ctx = uni.createCanvasContext("myCanvas", this);
// 绘制图片
ctx.drawImage(image, 0, 0, res.width, res.height);
//先加logo
// const watermarkImg = this.$refs.logo;
ctx.drawImage("/static/logo3.png", 10, res.height - 150, 200, 40.8);
//再加时间
ctx.font = "25px 黑体";
ctx.fillStyle = "#fff";
ctx.textAlign = "left";
ctx.fillText(this.getNowDateTime(), 10, res.height - 70);
//最后加地址
ctx.font = "25px 黑体";
ctx.fillStyle = "#fff";
ctx.textAlign = "left";
ctx.fillText(this.gpsLocation, 10, res.height - 30);
// 画到 canvas 中
ctx.draw(false, () => {
// 将画布转化为图片
// 设置延时,延时的秒数和图片体积正相关,越大的图片,延时越长
// 如果不延时,导出的图片可能存在有黑边、只显示部分 等问题
let timeout = 0;
if (fileSize <= 3) {
timeout = 1000;
} else {
timeout = 1000 * (fileSize / 3);
}
setTimeout(() => {
uni.canvasToTempFilePath(
{
canvasId: "myCanvas",
fileType: "jpg",
quality: fileSize <= 3 ? 1 : 0.75, // 如果不到3MB则不压缩否则压缩
success: (res) => {
console.log(res);
this.loading = false;
resolve(res.tempFilePath);
},
fail: (err) => {
this.loading = false;
reject(err);
},
},
this
);
}, timeout);
});
},
});
});
return res1;
},
// 解析后端返回的文件数据
parseFileListBack() {
// 初始化文件列表
this.initFileLists();
// 处理仪表盘照片特殊处理最多2张
this.parseDashboardPic();
// 处理基础照片
this.parseBasicPics();
// 处理数组类型照片
this.parseArrayPics();
// 处理电子签名文档
this.parseSignatureDoc();
// 处理轮胎照片
this.parseTirePics();
// 处理底盘照片
this.parseChassisPics();
this.$nextTick(() => {
this.$refs.uploadCollapse.init();
});
},
// 处理仪表盘照片
parseDashboardPic() {
// 仪表盘1
let picData = this.datas.dashboardPicData;
if (picData?.path) {
this.fileLists[1].push({
url: picData.path,
thumb: picData.compressedImagePath || picData.path,
});
this.compressPicMap.set(
picData.path,
picData.compressedImagePath || picData.path
);
}
this.datas.dashboardPic = picData?.path ?? "";
// 仪表盘2
picData = this.datas.dashboard2PicData;
if (picData?.path) {
this.fileLists[1].push({
url: picData.path,
thumb: picData.compressedImagePath || picData.path,
});
this.compressPicMap.set(
picData.path,
picData.compressedImagePath || picData.path
);
}
this.datas.dashboard2Pic = picData?.path ?? "";
},
// 处理基础照片
parseBasicPics() {
const basicPicKeys = [
{ dataKey: "frontPicData", fileKey: 2, targetKey: "frontPic" },
{ dataKey: "leftFrontPicData", fileKey: 3, targetKey: "leftFrontPic" },
{
dataKey: "rightFrontPicData",
fileKey: 4,
targetKey: "rightFrontPic",
},
{ dataKey: "leftRearPicData", fileKey: 5, targetKey: "leftRearPic" },
{ dataKey: "rightRearPicData", fileKey: 6, targetKey: "rightRearPic" },
];
basicPicKeys.forEach(({ dataKey, fileKey, targetKey }) => {
const picData = this.datas[dataKey];
if (picData?.path) {
this.fileLists[fileKey] = [
{
url: picData.path,
thumb: picData.compressedImagePath || picData.path,
},
];
this.compressPicMap.set(
picData.path,
picData.compressedImagePath || picData.path
);
}
this.datas[targetKey] = picData?.path ?? "";
});
},
// 处理数组类型照片
parseArrayPics() {
// 瑕疵照片
// 处理接口返回的对象格式数据
if (
this.datas.blemish &&
this.datas.blemish.length > 0 &&
typeof this.datas.blemish[0] === "object"
) {
this.fileLists[7] = this.datas.blemish.map((x) => ({
url: x.path,
thumb: x.compressedImagePath || x.path,
}));
this.datas.blemish.forEach((x) => {
this.compressPicMap.set(x.path, x.compressedImagePath || x.path);
});
// 转换为字符串数组格式用于保存
this.datas.blemish = this.datas.blemish.map((x) => x.path);
}
// 轮胎照片
this.fileLists[8] = this.datas.tirePic.map((x) => ({
url: x.path,
thumb: x.compressedImagePath || x.path,
}));
this.datas.tirePic.forEach((x) => {
this.compressPicMap.set(x.path, x.compressedImagePath || x.path);
});
this.datas.tirePic = this.datas.tirePic.map((x) => x.path);
// 其他
this.fileLists[9] = this.datas.otherPics.map((x) => ({
url: x.path,
thumb: x.compressedImagePath || x.path,
}));
this.datas.otherPics.forEach((x) => {
this.compressPicMap.set(x.path, x.compressedImagePath || x.path);
});
// 司机证件
this.fileLists[10] = this.datas.documents.map((x) => ({
url: x.path,
thumb: x.compressedImagePath || x.path,
}));
this.datas.documents.forEach((x) => {
this.compressPicMap.set(x.path, x.compressedImagePath || x.path);
});
this.datas.documents = this.datas.documents.map((x) => x.path);
// 相关材料
this.fileLists[12] = this.datas.signAttachment.map((x) => ({
url: x.path,
thumb: x.compressedImagePath || x.path,
}));
this.datas.signAttachment.forEach((x) => {
this.compressPicMap.set(x.path, x.compressedImagePath || x.path);
});
},
// 处理电子签名文档
parseSignatureDoc() {
if (
this.datas.esignatureAttachment &&
this.datas.esignatureAttachment.length >= 1
) {
this.fileLists[11] = [
{
url: this.datas.esignatureAttachment[0].path,
thumb: "/static/pdf.png",
},
];
this.hasSign = true;
}
},
// 处理轮胎照片
parseTirePics() {
// 6轮车轮胎照片
const keysTire = [
{ key: "leftFrontTirePic", fileKey: 15 },
{ key: "leftRearTirePicIn", fileKey: 16 },
{ key: "leftRearTirePicOut", fileKey: 17 },
{ key: "rightFrontTirePic", fileKey: 18 },
{ key: "rightRearTirePicIn", fileKey: 19 },
{ key: "rightRearTirePicOut", fileKey: 20 },
{ key: "spareTirePic", fileKey: 21 }, // 备胎
];
// 10轮车轮胎照片
const keysTire2 = [
{ key: "leftMiddleTirePicIn", fileKey: 22 },
{ key: "leftMiddleTirePicOut", fileKey: 23 },
{ key: "leftRearMiddleTirePicIn", fileKey: 24 },
{ key: "leftRearMiddleTirePicOut", fileKey: 25 },
{ key: "rightMiddleTirePicIn", fileKey: 26 },
{ key: "rightMiddleTirePicOut", fileKey: 27 },
{ key: "rightRearMiddleTirePicIn", fileKey: 28 },
{ key: "rightRearMiddleTirePicOut", fileKey: 29 },
];
// 12轮车轮胎照片
const keysTire3 = [
{ key: "leftFrontTirePicOut", fileKey: 36 },
{ key: "leftFrontTirePicIn", fileKey: 37 },
{ key: "rightFrontTirePicOut", fileKey: 38 },
{ key: "rightFrontTirePicIn", fileKey: 39 },
];
// 处理所有轮胎照片
[...keysTire, ...keysTire2, ...keysTire3].forEach(({ key, fileKey }) => {
if (this.datas[key]) {
const picData = this.datas[key];
if (picData?.path) {
this.fileLists[fileKey] = [
{
url: picData.path,
thumb: picData.compressedImagePath || picData.path,
},
];
this.compressPicMap.set(
picData.path,
picData.compressedImagePath || picData.path
);
}
this.datas[key] = picData?.path ?? "";
}
});
},
// 处理底盘照片
parseChassisPics() {
const chassisPicKeys = [
{ dataKey: "frontBottomPic", fileKey: 30 },
{ dataKey: "leftFrontBottomPic", fileKey: 31 },
{ dataKey: "leftRearBottomPic", fileKey: 32 },
{ dataKey: "rightFrontBottomPic", fileKey: 33 },
{ dataKey: "rightRearBottomPic", fileKey: 34 },
{ dataKey: "rearBottomPic", fileKey: 35 },
];
chassisPicKeys.forEach(({ dataKey, fileKey }) => {
const picData = this.datas[dataKey];
// 现在底盘照片已经是字符串格式
if (picData && typeof picData === "string") {
this.fileLists[fileKey] = [
{
url: picData,
thumb: picData,
},
];
this.compressPicMap.set(picData, picData);
}
});
},
// 保存
save(isAuto = false) {
let parmas = { ...this.datas };
parmas.submit = false; // 不提交,仅保存
parmas.depDetailCostEoList = [...this.departmentList];
if (parmas.returnLocationType == 1) {
parmas.returnLocation =
this.parkingList[this.parkingSel]?.dicCode || "";
} else if (parmas.returnLocationType == 2) {
parmas.returnLocation = this.maintainSite[this.maintainSel]?.id || "";
}
if (parmas.returnLocationType && !parmas.returnLocation) {
this.alert(`请选择还车地点`);
return;
}
this.$api.returnCar.addTake(parmas).then((res) => {
if (res && !isAuto) {
uni.showToast({
title: "保存成功",
icon: "success",
duration: 1500,
success() {},
});
this.isPageShow = false;
setTimeout(() => {
uni.navigateBack();
}, 1500);
}
});
},
clearSign() {
uni.showModal({
title: "提示",
content: "确认清除签名信息吗?",
success: (res) => {
if (res.confirm) {
this.$api.returnCar.clearSignInfo({ id: this.id }).then((res) => {
if (res) {
this.datas.signFlowId = null;
uni.showToast({
title: "清除成功",
icon: "success",
duration: 1500,
success() {},
});
}
});
}
},
});
},
submitConfirm() {
uni.showModal({
title: "提示",
content: "确认还车?",
success: (res) => {
if (res.confirm) {
this.submit();
}
},
});
},
submit() {
if (
!this.datas.esignatureAttachment ||
this.datas.esignatureAttachment.length == 0
) {
this.alert(`请完成电子签名`);
return;
}
let parmas = { ...this.datas };
parmas.submit = true; //提交
parmas.depDetailCostEoList = [...this.departmentList];
if (parmas.returnLocationType == 1) {
parmas.returnLocation =
this.parkingList[this.parkingSel]?.dicCode || "";
} else if (parmas.returnLocationType == 2) {
parmas.returnLocation = this.maintainSite[this.maintainSel]?.id || "";
}
this.$api.returnCar.addTake(parmas).then((res) => {
if (res) {
uni.showToast({
title: "提交成功",
icon: "success",
duration: 1500,
success() {},
});
this.isPageShow = false;
setTimeout(() => {
uni.navigateBack();
}, 1500);
}
});
},
// 在提交前检查,是否有必填字段未填写
check() {
if (!this.datas.returnDriver) {
this.alert("请填写还车人");
return false;
}
if (!this.datas.returneePhone) {
this.alert("请填写还车人电话");
return false;
}
if (!this.datas.identityCard) {
this.alert("请填写还车人身份证");
return false;
}
if (!this.datas.returnMileage) {
this.alert("请填写还车里程");
return false;
}
if (!this.datas.electricity) {
this.alert("请填写还车电量");
return false;
}
if (!this.datas.hydrogenMeasure) {
this.alert("请填写还车氢量");
return false;
}
if (!this.datas.hydrogenUnit) {
this.alert("请选择还车氢量单位");
return false;
}
if (!this.datas.returnDate) {
this.alert("请填写还车时间");
return false;
}
if (!this.datas.returnLocationType) {
this.alert(`请选择还车地点类型`);
return;
}
if (this.datas.returnLocationType == 1) {
if (this.parkingSel === "" || this.parkingSel === -1) {
this.alert(`请选择停车场`);
return;
}
} else if (this.datas.returnLocationType == 2) {
if (this.maintainSel === "" || this.maintainSel === -1) {
this.alert(`请选择维修站`);
return;
}
}
if (!this.datas.dashboardPic) {
this.alert("请上传仪表盘照片");
return false;
}
if (!this.datas.frontPic) {
this.alert("请上传正面照片");
return false;
}
if (!this.datas.leftFrontPic) {
this.alert("请上传左前方照片");
return false;
}
if (!this.datas.rightFrontPic) {
this.alert("请上传右前方照片");
return false;
}
if (!this.datas.leftRearPic) {
this.alert("请上传左后方照片");
return false;
}
if (!this.datas.rightRearPic) {
this.alert("请上传右后方照片");
return false;
}
// if (!this.datas.tirePic || this.datas.tirePic.length == 0) {
// this.alert("请上传轮胎照片");
// return false;
// }
// if (this.datas.tirePic.length < this.datas.take.truckSimple.tireNumber) {
// this.alert("轮胎照片上传数量不小于车辆轮胎数量");
// return false;
// }
if (this.datas.take.truckSimple.tireNumber == 6) {
if (!this.datas.leftFrontTirePic) {
this.alert("请上传左前轮照片");
return false;
}
if (!this.datas.leftRearTirePicIn) {
this.alert("请上传左后轮(内)照片");
return false;
}
if (!this.datas.leftRearTirePicOut) {
this.alert("请上传左后轮(外)照片");
return false;
}
if (!this.datas.rightFrontTirePic) {
this.alert("请上传右前轮照片");
return false;
}
if (!this.datas.rightRearTirePicIn) {
this.alert("请上传右后轮(内)照片");
return false;
}
if (!this.datas.rightRearTirePicOut) {
this.alert("请上传右后轮(外)照片");
return false;
}
} else if (
this.datas.take.truckSimple.tireNumber == 10 ||
this.datas.take.truckSimple.tireNumber == 12
) {
if (this.datas.take.truckSimple.tireNumber == 10) {
if (!this.datas.leftFrontTirePic) {
this.alert("请上传左前轮照片");
return false;
}
if (!this.datas.rightFrontTirePic) {
this.alert("请上传右前轮照片");
return false;
}
} else {
if (!this.datas.leftFrontTirePicOut) {
this.alert("请上传左前外照片");
return false;
}
if (!this.datas.leftFrontTirePicIn) {
this.alert("请上传左前内照片");
return false;
}
if (!this.datas.rightFrontTirePicOut) {
this.alert("请上传右前外照片");
return false;
}
if (!this.datas.rightFrontTirePicIn) {
this.alert("请上传右前内照片");
return false;
}
}
if (!this.datas.leftMiddleTirePicIn) {
this.alert("请上传左中内照片");
return false;
}
if (!this.datas.leftMiddleTirePicOut) {
this.alert("请上传左中外照片");
return false;
}
if (!this.datas.leftRearMiddleTirePicIn) {
this.alert("请上传左后内照片");
return false;
}
if (!this.datas.leftRearMiddleTirePicOut) {
this.alert("请上传左后外照片");
return false;
}
if (!this.datas.rightMiddleTirePicIn) {
this.alert("请上传右中内照片");
return false;
}
if (!this.datas.rightMiddleTirePicOut) {
this.alert("请上传右中外照片");
return false;
}
if (!this.datas.rightRearMiddleTirePicIn) {
this.alert("请上传右后内照片");
return false;
}
if (!this.datas.rightRearMiddleTirePicOut) {
this.alert("请上传右后外照片");
return false;
}
}
// 底盘照片验证
if (!this.datas.frontBottomPic) {
this.alert("请上传正前方底部照片");
return false;
}
if (!this.datas.leftFrontBottomPic) {
this.alert("请上传左侧前部底部照片");
return false;
}
if (!this.datas.leftRearBottomPic) {
this.alert("请上传左侧后方底部照片");
return false;
}
if (!this.datas.rightFrontBottomPic) {
this.alert("请上传右侧前方底部照片");
return false;
}
if (!this.datas.rightRearBottomPic) {
this.alert("请上传右侧后方底部照片");
return false;
}
if (!this.datas.rearBottomPic) {
this.alert("请上传正后方底部照片");
return false;
}
return true;
},
alert(msg, time = 1500) {
uni.showToast({
title: msg,
icon: "none",
duration: time,
});
},
// 生成交车确认单文档
generateWord() {
// 若存在字段未填写,则不请求接口
if (!this.check()) {
return;
}
if (!this.hasSaveCheckList) {
this.alert(`请填写还车检查单`);
return;
}
if (!this.datas.returneePhone || !this.datas.returnDriver) {
this.alert(`签名需要指定授权人`);
return;
}
if (this.showClearTip) {
this.alert(`当前交车单已存在签名流程,建议先清除签名信息`, 2500);
this.showClearTip = false;
return;
}
this.loading = true;
this.loadingText = "生成签署文档中...";
let datas = this.deepClone(this.datas);
datas.returnDriver = datas.returnDriver.replace(/\s+/g, "");
datas.identityCard = datas.identityCard.replace(/\s+/g, "");
datas.returneePhone = datas.returneePhone.replace(/[^0-9]/g, "");
this.handleDatasCompressImg(datas); // 替换为缩略图
this.$api.returnCar.generateWordforReturn(datas).then((res) => {
if (!res) {
//this.alert("生成签署文档失败");
this.loading = false;
return;
}
if (res.msg === "signatureAgain") {
this.loading = false;
uni.navigateTo({
url: `/pages/webview/index?url=${encodeURIComponent(res.data)}`,
});
return;
}
if (res.msg != "OK") {
this.alert(res.msg);
this.loading = false;
return;
}
let filePath = res.data[0]?.path;
if (!filePath) {
this.alert("生成签署文档失败");
this.loading = false;
return;
}
this.initiateSignature(filePath);
});
},
// 发起电子签章
initiateSignature(filePath) {
this.loading = true;
this.loadingText = "发起电子签章中...";
this.$api.truckRent
.initiateSignature({
businessType: "2",
fileName: `${this.datas.take.truckSimple.plateNumber}还车确认单.docx`,
filePath: filePath,
psnAccount1: this.userInfo.phone,
psnAccount2: this.datas.returneePhone,
psnName1: this.userInfo.userName,
psnName2: this.datas.returnDriver,
signFlowTitle: `${this.datas.take.truckSimple.plateNumber}还车确认单`,
tireNumber: this.datas.take.truckSimple.tireNumber,
})
.then((res) => {
if (!res) {
this.alert(`发起电子签章失败`);
this.loading = false;
return;
}
const signFlowId = res.data;
if (!signFlowId) {
this.alert(res?.msg || `发起电子签章失败`);
this.loading = false;
return;
}
this.datas.signFlowId = signFlowId;
this.getSignatureUrl(signFlowId);
});
},
// 生成签署链接
getSignatureUrl(signFlowId) {
this.loading = true;
this.loadingText = "获取电子签章签署链接中...";
this.$api.truckRent
.getSignatureUrl({
signFlowId: signFlowId,
psnAccount: this.userInfo.phone,
})
.then((res) => {
if (!res) {
this.alert(`获取电子签章签署链接失败`);
this.loading = false;
return;
}
console.log(res);
const signUrl = res.data;
if (!signUrl) {
this.alert(`获取电子签章签署链接失败`);
this.loading = false;
return;
}
this.loading = false;
this.save(true); //自动保存
uni.navigateTo({
url: `/pages/webview/index?url=${encodeURIComponent(signUrl)}`,
});
});
},
fileDownloadUrl() {
if (!this.datas.signFlowId) {
uni.showToast({
icon: "none",
title: "请先点击签名",
duration: 2000,
});
return;
}
this.loading = true;
this.loadingText = "下载中...";
this.$api.truckRent
.fileDownloadUrl({
signFlowId: this.datas.signFlowId,
})
.then((res) => {
this.loading = false;
if (!res) {
this.alert(`下载失败`);
return;
}
if (res.msg != "OK") {
this.alert(res.msg);
return;
}
this.datas.esignatureAttachment = res.data;
this.fileLists[11] = res.data.map((x) => ({
url: x.path,
thumb: "/static/pdf.png",
}));
this.hasSign = true;
this.save(true); //自动保存
});
},
previewPdf() {
if (
!this.datas.esignatureAttachment ||
this.datas.esignatureAttachment.length == 0
) {
this.alert(`请先点击生成签署文件`);
return;
}
const path = this.datas.esignatureAttachment[0].path;
this.loading = true;
this.loadingText = "加载中...";
uni.downloadFile({
url: path,
success: function (res) {
var filePath = res.tempFilePath;
this.loading = false;
uni.openDocument({
filePath: filePath,
success: function (res) {
this.loading = false;
},
fail() {
this.loading = false;
},
});
},
fail() {
this.alert("预览文件失败");
this.loading = false;
},
});
},
// 提交给生成签署文档接口的参数,其中的图片全部替换为缩略图
handleDatasCompressImg(datas) {
const keys1 = [
"dashboardPic",
"dashboard2Pic",
"frontPic",
"leftFrontPic",
"rightFrontPic",
"leftRearPic",
"rightRearPic",
//4.5 18T
"leftFrontTirePic",
"leftRearTirePicIn",
"leftRearTirePicOut",
"rightFrontTirePic",
"rightRearTirePicIn",
"rightRearTirePicOut",
"spareTirePic",
//49T
"leftMiddleTirePicIn",
"leftMiddleTirePicOut",
"leftRearMiddleTirePicIn",
"leftRearMiddleTirePicOut",
"rightMiddleTirePicIn", //右中内
"rightMiddleTirePicOut",
"rightRearMiddleTirePicIn",
"rightRearMiddleTirePicOut",
];
for (let key of keys1) {
if (datas[key]) {
datas[key] = this.compressPicMap.get(datas[key]);
}
}
const keys2 = ["blemish", "tirePic", "documents"];
for (let key of keys2) {
// 确保瑕疵照片是字符串数组格式
if (key === "blemish") {
datas[key] = datas[key].map((x) => this.compressPicMap.get(x) || x);
} else {
datas[key] = datas[key].map((x) => this.compressPicMap.get(x));
}
}
//字符串数组
const keys3 = ["signAttachment"];
for (let key of keys3) {
console.log(datas[key]);
datas[key] = datas[key].map((x) => {
return { path: this.compressPicMap.get(x.path) || x.path };
});
}
},
confirmSubject(e, index) {
console.log(e);
const selecItem = this.subjectList[Number(e.detail.value)];
console.log(index);
this.departmentList[index].subjectName = selecItem.name;
this.departmentList[index].costSubjectId = selecItem.id;
},
// 删除 图片
deletePicCost(event) {
const index = event.name;
const fileList = this.departmentList[index].pictureList;
if (fileList.some((x) => x.status == "uploading")) {
this.alert(`请等待现有图片上传完成后再操作`);
return;
}
this.departmentList[index].pictureList.splice(event.index, 1);
},
// 删除 附件
deletePdfCost(event) {
const index = event.name;
const fileList = this.departmentList[index].attachmentList;
if (fileList.some((x) => x.status == "uploading")) {
this.alert(`请等待现有图片上传完成后再操作`);
return;
}
this.departmentList[index].attachmentList.splice(event.index, 1);
},
// 新增图片
// async afterReadCost(event) {
// console.log(event);
// const index = event.name;
// // 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
// let lists = [].concat(event.file);
// let fileListLen = this.departmentList[index].pictureList.length;
// lists.map((item) => {
// this.departmentList[index].pictureList.push({
// ...item,
// status: "uploading",
// message: "上传中",
// });
// });
// console.log(`event.file:\n`, event.file);
// for (let i = 0; i < lists.length; i++) {
// this.loading = true;
// this.loadingText = "添加水印中...";
// const fileSize = event.file.size / 1024 ** 2; // 图片多少MB
// let waterUrl = "";
// try {
// waterUrl = await this.addWatermark(lists[i].url, fileSize);
// } catch (e) {
// this.alert(e.toString());
// this.departmentList[index].pictureList.splice(fileListLen, 1);
// return;
// }
// const result = await this.uploadFilePromise(waterUrl);
// // let result = { data: { url: waterUrl }}
// let item = this.departmentList[index].pictureList[fileListLen];
// this.departmentList[index].pictureList.splice(
// fileListLen,
// 1,
// Object.assign(item, {
// status: "success",
// message: "",
// path: result.data?.url ?? item.url ?? "",
// thumb: waterUrl,
// url: result.data?.url ?? "",
// compressedImagePath: result.data?.compressedImageUrl ?? "",
// })
// );
// fileListLen++;
// //const imgUrl = result.data?.url ?? "";
// // // 司机证件
// // if (event.name == "13") {
// // this.datas.documents.push(imgUrl);
// // }
// this.$nextTick(() => {
// // 解决折叠collapse高度无法动态更新的问题
// this.$refs.costCollapse.init();
// });
// }
// },
// delForm(index) {
// // if (this.departmentList[depIndex].depDetailCostVoList.length <= 1) {
// // this.alert(`至少保留一条数据`);
// // return;
// // }
// this.departmentList.splice(index, 1);
// this.$nextTick(() => {
// this.$refs.costCollapse.init();
// });
// },
// addForm() {
// this.departmentList.push({
// subjectName: "",
// costSubjectId: null,
// remark: "",
// amount: "",
// pictureList: [],
// attachmentList: [],
// });
// this.$nextTick(() => {
// this.$refs.costCollapse.init();
// });
// },
// 新增附件
// async afterReadPdf(event) {
// const index = event.name;
// console.log(event);
// console.log(index);
// // 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
// let lists = [].concat(event.file);
// let fileListLen = this.departmentList[index].attachmentList.length;
// lists.map((item) => {
// this.departmentList[index].attachmentList.push({
// ...item,
// status: "uploading",
// message: "上传中",
// });
// });
// //const fileSize = event.file.size / 1024 ** 2; // 图片多少MB
// console.log(`event.file:\n`, event.file);
// for (let i = 0; i < lists.length; i++) {
// const result = await this.uploadFilePromise(lists[i].url);
// // let result = { data: { url: waterUrl }}
// let item = this.departmentList[index].attachmentList[fileListLen];
// const imgUrl = result.data?.url ?? item.url ?? "";
// const fileName = event.file[0]?.name ?? "";
// this.departmentList[index].attachmentList.splice(
// fileListLen,
// 1,
// Object.assign(item, {
// status: "success",
// message: "",
// fileName: fileName,
// path: imgUrl,
// url: imgUrl,
// thumb: item.type === "file" ? "/static/pdf.png" : "",
// })
// );
// fileListLen++;
// console.log("fileList");
// console.log(result.data);
// // const imgUrl = result.data?.url ?? "";
// // const fileName = event.file[0]?.name ?? "";
// // this.datas.safetyTrainingAttachment.push({
// // path: imgUrl,
// // fileName: fileName,
// // thumb: "/static/pdf.png",
// // });
// this.$nextTick(() => {
// // 解决折叠collapse高度无法动态更新的问题
// this.$refs.costCollapse.init();
// });
// }
// this.save(true); // 自动保存.
// },
// 预览附件
previewYyPdf(data) {
if (!data || !data.path) {
this.alert(`文件上传异常`);
return;
}
console.log(data);
const path = data.path;
this.loading = true;
this.loadingText = "加载中...";
const that = this;
uni.downloadFile({
url: path,
success: function (res) {
var filePath = res.tempFilePath;
that.loading = false;
uni.openDocument({
filePath: filePath,
success: function (res) {
that.loading = false;
},
fail() {
that.loading = false;
},
});
},
fail() {
that.alert("预览文件失败");
that.loading = false;
},
});
},
async getsubjectTowId() {
await this.$api.returnCar
.getQuerySubjectTowNames()
.then((res) => {
console.log("getsubject");
console.log(res);
this.subjectList = res;
})
.catch((err) => {
console.log("error");
this.subjectList = [];
});
},
},
computed: {
// 大部分组件的禁用直接用 disabled查看模式或者已完成签署
disabled() {
return this.isRead || this.hasSign;
},
//清除签名信息按钮
clearButton: function () {
return checkButtonPermission(
"clearSignInfo",
"carapplicationForDelivery"
);
},
},
async onLoad(options) {
if (options.id) {
this.id = options.id;
}
// uni.enableAlertBeforeUnload({
// message: "签署文件已",
// success: function (res) {
// console.log("成功:", res);
// },
// fail: function (err) {
// console.log("失败:", err);
// },
// });
if (options.isRead) {
this.isRead = Number(options.isRead);
}
if (!this.isRead) {
this.isPageShow = true; // 如果不是查看模式,则开启拦截
}
this.userInfo = getUser() || {};
console.log(this.userInfo);
this.checkCameraPermission(); // 检测拍照权限
this.getDic();
await this.getLocationTypeList(); // 获取还车地点类型列表
await this.getParkList(); // 获取停车场列表
await this.maintainSiteSelect(); // 获取维修站点列表
await this.getsubjectTowId(); // 获取费用科目列表
// 初始化文件列表
this.initFileLists();
this.getData();
this.getInStoreList();
},
onPullDownRefresh() {
// this.getData()
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
onShow() {
if (this.loadingText != "添加水印中...") {
this.loading = false;
}
},
onHide() {},
destroyed() {},
};
</script>
<!-- <style>
page {
position: relative !important;
top: 0px !important;
}
</style> -->
<style lang="less" scoped>
.flexBox {
display: flex;
flex-wrap: wrap;
.flexItem {
flex: 0 0 33.3%;
box-sizing: border-box;
.title {
font-size: 24rpx;
}
}
}
.container {
// background-color: #d7d7d7;
padding: 30rpx;
.depDetailCostVoListBtns {
display: flex;
justify-content: flex-end;
align-items: center;
button {
background-color: transparent;
font-size: 26rpx;
width: 100rpx;
height: 50rpx;
line-height: 50rpx;
margin-left: 30rpx;
margin-right: 0;
padding: 0;
&.add {
background-color: #7ba746;
color: white;
}
&.del {
background-color: white;
color: #7ba746;
border: 1rpx #7ba746 solid;
}
&.disabled {
opacity: 0.6;
}
}
}
.line {
display: flex;
align-items: center;
margin-bottom: 15rpx;
font-size: 14px;
.left {
margin-right: 50rpx;
width: 300rpx;
}
.text-small {
font-size: x-small;
}
.text-normal {
font-size: small;
}
}
.truckItem {
margin-top: 30rpx;
padding: 30rpx;
border: #7ba746 solid 4rpx;
}
.item {
margin-top: 30rpx;
.title {
font-size: 26rpx;
margin-bottom: 15rpx;
&.required::before {
content: "*";
color: red;
margin-right: 3rpx;
}
}
.tip {
font-size: 26rpx;
margin-bottom: 15rpx;
color: #aaaaaa;
position: relative;
}
.btn.checkList {
width: 200rpx;
height: 60rpx;
font-size: 26rpx;
line-height: 26rpx;
padding: 17rpx 0;
text-align: center;
background-color: #7ba746;
color: white;
margin-left: 0;
&.required::before {
content: "*";
color: red;
margin-right: 3rpx;
}
}
.unit {
font-size: 26rpx;
}
.btn {
width: 200rpx;
height: 80rpx;
margin-left: 0;
font-size: 26rpx;
line-height: 26rpx;
padding: 27rpx 0;
text-align: center;
color: white;
&.sign {
background-color: #7ba746;
display: inline-block;
margin-right: 30rpx;
}
&.genDocument {
background-color: #1e98d7;
}
&.disabled {
opacity: 0.6;
}
}
}
.btns {
display: flex;
align-items: center;
justify-content: space-around;
margin-top: 20rpx;
button {
width: 200rpx;
height: 60rpx;
font-size: 26rpx;
line-height: 26rpx;
padding: 17rpx 0;
text-align: center;
}
.cancel {
background-color: white;
color: #7ba746;
border: 1rpx #7ba746 solid;
}
.save {
background-color: #7ba746;
color: white;
}
.done {
background-color: #7ba746;
color: white;
}
.disabled {
opacity: 0.6;
}
}
}
/deep/ .u-textarea textarea {
min-height: 100rpx !important;
font-size: 26rpx !important;
}
/deep/ .u-border {
border-width: 1rpx !important;
border-color: gray !important;
border-style: solid;
}
/deep/ .u-collapse-item__content__text {
padding: unset !important;
color: unset !important;
font-size: unset !important;
}
/deep/ .u-cell__title-text {
font-size: unset !important;
line-height: unset !important;
color: unset !important;
}
/deep/ .u-cell__body {
padding: unset !important;
font-size: unset !important;
color: unset !important;
}
/deep/ .u-cell__right-icon-wrap text {
font-size: 32rpx !important;
}
/deep/ .u-cell--clickable {
background-color: unset !important;
}
/deep/ .u-collapse-item {
margin-bottom: 30rpx;
}
/deep/ .uni-select {
width: 100rpx !important;
}
/deep/ .u-upload__button text {
font-size: 48rpx !important;
}
/deep/ .u-upload__deletable {
height: 42rpx !important;
width: 42rpx !important;
}
/deep/ .u-upload__deletable text {
font-size: 32rpx !important;
line-height: 32rpx !important;
}
/deep/ picker-view {
height: 450rpx !important;
}
/deep/ .uni-select__input-text {
font-size: 26rpx !important;
text-align: right !important;
}
/deep/ .uni-select__selector-item text {
font-size: 26rpx !important;
}
/deep/ .uni-select {
padding-right: 18rpx !important;
border-width: 1rpx !important;
border-color: gray !important;
border-style: solid !important;
border-top-width: 0 !important;
border-right-width: 0 !important;
border-bottom-width: 0 !important;
}
// /deep/ picker-view picker-view-column:nth-of-type(5) {
// display: none;
// }
.changeCarBtn {
height: 76rpx;
font-size: 26rpx;
line-height: 76rpx;
border-width: 1rpx !important;
border-color: gray !important;
border-style: solid !important;
border-top-width: 0 !important;
border-right-width: 0 !important;
border-bottom-width: 0 !important;
}
/* 检查单样式开始 */
/deep/ .td_wrap {
height: auto !important;
}
/deep/ checkbox-group view.td {
width: 186rpx !important;
}
/deep/ checkbox-group view.td_wrap {
width: 186rpx !important;
}
/deep/ .no-bad-table-wrap .td.rowspan {
display: flex;
align-items: center;
justify-content: center;
}
/deep/ .div-table-head .thead .tr view {
width: 186rpx !important;
}
/deep/ no-bad-table {
overflow-x: hidden;
}
/deep/ .no-bad-table-wrap .thead .tr .td {
background-color: #7ba746;
color: white;
}
/deep/ .no-bad-table-wrap .thead .tr .td .td_wrap {
background-color: #7ba746;
color: white;
}
/* 检查单样式结束 */
/* loading 置于顶层 */
/deep/ .u-fade-enter-to.u-fade-enter-active {
z-index: 10074 !important;
}
</style>