2061 lines
64 KiB
Vue
2061 lines
64 KiB
Vue
<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', 'current', 'cost']" :border="false">
|
||
<u-collapse-item title="基本信息" ref="uploadCollapse" name="basic">
|
||
<!-- <view class="header">基本信息</view> -->
|
||
<view class="item">
|
||
<view class="title">车牌号</view>
|
||
<u--input
|
||
border="surround"
|
||
:value="info.plateNumber"
|
||
disabled
|
||
fontSize="26"
|
||
></u--input>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title">资产状态</view>
|
||
<u--input
|
||
border="surround"
|
||
:value="info.truckRentStatusName"
|
||
disabled
|
||
fontSize="26"
|
||
></u--input>
|
||
</view>
|
||
|
||
<view class="item">
|
||
<view class="title">车辆型号</view>
|
||
<u-input
|
||
border="surround"
|
||
disabled
|
||
v-model="info.modelName"
|
||
fontSize="26"
|
||
>
|
||
</u-input>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title">公告车型</view>
|
||
<u-input
|
||
border="surround"
|
||
disabled
|
||
v-model="info.noticeModelName"
|
||
fontSize="26"
|
||
>
|
||
</u-input>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title">所属公司</view>
|
||
<u-input
|
||
border="surround"
|
||
disabled
|
||
v-model="info.orgName"
|
||
fontSize="26"
|
||
>
|
||
</u-input>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title">项目名称</view>
|
||
<u-input
|
||
border="surround"
|
||
disabled
|
||
v-model="info.projectName"
|
||
fontSize="26"
|
||
>
|
||
</u-input>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title">仪表盘里程</view>
|
||
<u-input
|
||
border="surround"
|
||
disabled
|
||
v-model="info.totalMileage"
|
||
fontSize="26"
|
||
>
|
||
</u-input>
|
||
</view>
|
||
</u-collapse-item>
|
||
|
||
<u-collapse-item
|
||
title="保养记录"
|
||
ref="maintainCollapse"
|
||
name="maintain"
|
||
>
|
||
<view
|
||
v-if="!mainTableList || mainTableList.length == 0"
|
||
class="no-data"
|
||
>
|
||
暂无数据
|
||
</view>
|
||
<scroll-view v-else scroll-y="true" style="max-height: 590rpx">
|
||
<no-bad-table
|
||
:columns="columns"
|
||
:list="mainTableList"
|
||
:spanArr="spanArr"
|
||
:slot-cols="[
|
||
'index',
|
||
'maintainItem',
|
||
'maintenanceDueTime',
|
||
'maintenanceDueMileage',
|
||
'operation',
|
||
]"
|
||
:span-method="objectSpanMethod"
|
||
>
|
||
<template v-slot="{ row, col, index }">
|
||
<view v-if="col.key == 'index'" style="white-space: pre-wrap">
|
||
{{ index + 1 }}
|
||
</view>
|
||
<view
|
||
v-else-if="col.key == 'maintainItem'"
|
||
style="white-space: pre-wrap"
|
||
>
|
||
{{ row.maintainItem }}
|
||
</view>
|
||
<view
|
||
v-else-if="col.key == 'maintenanceDueTime'"
|
||
style="white-space: pre-wrap"
|
||
>
|
||
{{ row.maintenanceDueTime || "" }}
|
||
</view>
|
||
<view
|
||
v-else-if="col.key == 'maintenanceDueMileage'"
|
||
style="white-space: pre-wrap"
|
||
>
|
||
{{ row.maintenanceDueMileage || 0 }}
|
||
</view>
|
||
<view
|
||
v-else-if="col.key == 'operation'"
|
||
style="display: flex; justify-content: center"
|
||
>
|
||
<view class="viewBtn" @tap="viewRecord(row)">查看</view>
|
||
</view>
|
||
<!-- <view
|
||
v-else-if="col.key == 'maintenanceDueTime'"
|
||
style="white-space: pre-wrap"
|
||
>
|
||
{{ formatDateTime(row.maintenanceDueTime) }}
|
||
</view>
|
||
<view v-else-if="col.key == 'maintenanceDueMileage'" style="">
|
||
{{ row.maintenanceDueMileage }}
|
||
</view>
|
||
<view v-else-if="col.key == 'remark'" style="">
|
||
<view class="viewBtn" @tap="viewRecord(row)">查看历史记录</view>
|
||
</view> -->
|
||
</template>
|
||
</no-bad-table>
|
||
</scroll-view>
|
||
<!-- <view class="header">日常维护</view> -->
|
||
|
||
<!-- <u-checkbox-group v-model="checkoutIds" size="36" placement="column">
|
||
<view v-for="(item, index) in mainTableList" :key="index">
|
||
<u-cell-group>
|
||
<u-cell :border="false">
|
||
<view slot="title" class="u-slot-title">
|
||
{{ `序号${index + 1}` }}
|
||
<view class="viewBtn" @tap="viewRecord(item)"
|
||
>查看历史记录</view
|
||
>
|
||
</view>
|
||
</u-cell>
|
||
<u-cell
|
||
:border="false"
|
||
title="养护项目"
|
||
:titleStyle="`font-weight: normal;`"
|
||
:value="item.maintainItem"
|
||
></u-cell>
|
||
<u-cell
|
||
:border="false"
|
||
:titleStyle="`font-weight: normal;font-size: 13px;color:${
|
||
item.maintenanceDueTime &&
|
||
item.maintenanceDueTime <= new Date().getTime()
|
||
? 'red'
|
||
: ''
|
||
}`"
|
||
title="保养到期时间"
|
||
:value="formatDateTime(item.maintenanceDueTime)"
|
||
></u-cell>
|
||
<u-cell
|
||
:border="false"
|
||
:titleStyle="`font-weight: normal;font-size: 13px;color:${
|
||
info.totalMileage &&
|
||
item.maintenanceDueMileage &&
|
||
info.totalMileage > item.maintenanceDueMileage
|
||
? 'red'
|
||
: ''
|
||
}`"
|
||
title="保养到期公里数"
|
||
:value="item.maintenanceDueMileage || ''"
|
||
></u-cell>
|
||
</u-cell-group>
|
||
</view>
|
||
</u-checkbox-group> -->
|
||
</u-collapse-item>
|
||
<u-collapse-item
|
||
title="本次保养项目"
|
||
ref="currentCollapse"
|
||
name="current"
|
||
>
|
||
<view class="item">
|
||
<view class="title required">维修站</view>
|
||
<u-picker
|
||
:show="showFixPicker"
|
||
:columns="[maintainSiteList]"
|
||
keyName="name"
|
||
:immediateChange="true"
|
||
@confirm="confirmFix"
|
||
@cancel="showFixPicker = false"
|
||
>
|
||
</u-picker>
|
||
<u--input
|
||
border="surround"
|
||
:disabledColor="_disabled || isSubmited ? '#f5f7fa' : '#ffffff'"
|
||
disabled
|
||
fontSize="26"
|
||
:value="info.maintainSiteName"
|
||
@tap="!_disabled && !isSubmited && (showFixPicker = true)"
|
||
>
|
||
</u--input>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title required">实际保养日期</view>
|
||
<u-datetime-picker
|
||
placeholder="请选择实际保养日期"
|
||
:disabled="_disabled"
|
||
:show="showRealDatePicker"
|
||
mode="date"
|
||
@confirm="(e) => confirmRealDate(e)"
|
||
@cancel="showRealDatePicker = false"
|
||
></u-datetime-picker>
|
||
<u--input
|
||
border="surround"
|
||
:disabledColor="_disabled || isSubmited ? '#f5f7fa' : '#ffffff'"
|
||
fontSize="26"
|
||
disabled
|
||
:value="formatDateTime(info.actualMaintenanceDate, 'date')"
|
||
@tap="!_disabled && !isSubmited && (showRealDatePicker = true)"
|
||
>
|
||
</u--input>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title required">实际保养里程</view>
|
||
<u-input
|
||
border="surround"
|
||
:disabled="_disabled || isSubmited"
|
||
@change="changeSearch"
|
||
v-model="info.actualMaintenanceMileage"
|
||
fontSize="26"
|
||
type="digit"
|
||
>
|
||
</u-input>
|
||
</view>
|
||
<view
|
||
v-for="(item, index) in info.itemList"
|
||
:key="item.id"
|
||
class="currentItem"
|
||
>
|
||
<u-cell-group :border="false">
|
||
<view class="item">
|
||
<view class="title required">保养项目{{ index + 1 }}</view>
|
||
<u-picker
|
||
:show="mainItemPicker[index]"
|
||
:columns="[maintainItems]"
|
||
keyName="maintainItem"
|
||
:immediateChange="true"
|
||
@confirm="confirmMainItem($event, index)"
|
||
@cancel="cancelMainItem(index)"
|
||
>
|
||
</u-picker>
|
||
<u--input
|
||
border="surround"
|
||
disabled
|
||
:disabledColor="tableDisabled ? '#f5f7fa' : '#ffffff'"
|
||
fontSize="26"
|
||
:value="item.maintainItem"
|
||
@tap="!tableDisabled && showMainItemPicker(index)"
|
||
>
|
||
</u--input>
|
||
</view>
|
||
<u-cell
|
||
:border="false"
|
||
titleStyle="font-weight: normal;font-size: 13px"
|
||
title="保养到期时间"
|
||
:value="formatDateTime(item.maintenanceDueTime)"
|
||
></u-cell>
|
||
<u-cell
|
||
:border="false"
|
||
titleStyle="font-weight: normal;font-size: 13px"
|
||
title="保养到期公里数"
|
||
:value="item.maintenanceDueMileage || ''"
|
||
></u-cell>
|
||
|
||
<view class="item">
|
||
<view class="title required">工时费</view>
|
||
<u-input
|
||
border="surround"
|
||
:disabled="tableDisabled"
|
||
v-model="item.hourFee"
|
||
@change="changeFee1($event, index)"
|
||
fontSize="26"
|
||
type="digit"
|
||
>
|
||
</u-input>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title">材料费</view>
|
||
<u-input
|
||
border="surround"
|
||
:disabled="tableDisabled"
|
||
v-model="item.materialsExpenses"
|
||
@change="changeFee2($event, item, index)"
|
||
fontSize="26"
|
||
type="digit"
|
||
>
|
||
</u-input>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title">材料费(公司自采)</view>
|
||
<u-input
|
||
border="surround"
|
||
:disabled="tableDisabled"
|
||
v-model="item.companyMaterialsExpenses"
|
||
@change="changeCompanyEx($event, item, index)"
|
||
fontSize="26"
|
||
type="digit"
|
||
>
|
||
</u-input>
|
||
</view>
|
||
<u-cell
|
||
:border="false"
|
||
titleStyle="font-weight: normal;font-size: 13px"
|
||
title="合计"
|
||
:value="item.totalFee || 0"
|
||
></u-cell>
|
||
<u-cell
|
||
:border="false"
|
||
titleStyle="font-weight: normal;font-size: 13px"
|
||
title="公司承担费用"
|
||
:value="item.companyUndertake || 0"
|
||
></u-cell>
|
||
<u-cell
|
||
:border="false"
|
||
titleStyle="font-weight: normal;font-size: 13px"
|
||
title="客户承担费用"
|
||
:value="item.customerUndertake || 0"
|
||
></u-cell>
|
||
<view class="item">
|
||
<view class="title">超出费用</view>
|
||
<u-input
|
||
border="surround"
|
||
:disabled="tableDisabled"
|
||
v-model="item.overcharge"
|
||
@change="getComputedTotalFee(null)"
|
||
fontSize="26"
|
||
type="digit"
|
||
>
|
||
</u-input>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title">备注</view>
|
||
<u-input
|
||
border="surround"
|
||
:disabled="tableDisabled"
|
||
v-model="item.remark"
|
||
fontSize="26"
|
||
>
|
||
</u-input>
|
||
</view>
|
||
<view class="item" v-if="!_disabled">
|
||
<view class="truckListBtns">
|
||
<button
|
||
:class="{ disabled: _disabled }"
|
||
:disabled="_disabled"
|
||
v-if="info.itemList.length - 1 == index && !isSubmited"
|
||
class="add"
|
||
@tap="addForm"
|
||
>
|
||
添加
|
||
</button>
|
||
<button
|
||
v-if="info.itemList.length !== 1 && !isSubmited"
|
||
:class="{ disabled: _disabled }"
|
||
:disabled="_disabled"
|
||
class="del"
|
||
@tap="delForm(index)"
|
||
>
|
||
删除
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</u-cell-group>
|
||
</view>
|
||
<view
|
||
class="item"
|
||
v-if="!_disabled && info.truckRentStatus == 0"
|
||
style="margin-bottom: 30rpx"
|
||
>
|
||
<button class="btn checkList" @tap="makeTodo">
|
||
生成异动申请
|
||
</button>
|
||
</view>
|
||
</u-collapse-item>
|
||
<u-collapse-item title="费用明细" ref="costCollapse" name="cost">
|
||
<u-cell-group>
|
||
<u-cell
|
||
:border="false"
|
||
titleStyle="font-weight: normal;font-size: 13px"
|
||
title="费用总计(元)"
|
||
:value="info.amount || 0"
|
||
></u-cell>
|
||
<u-cell
|
||
:border="false"
|
||
titleStyle="font-weight: normal;font-size: 13px"
|
||
title="公司承担费用(总计)"
|
||
:value="info.companyUndertake || 0"
|
||
></u-cell>
|
||
<u-cell
|
||
:border="false"
|
||
titleStyle="font-weight: normal;font-size: 13px"
|
||
title="客户承担费用(总计)"
|
||
:value="info.customerUndertake || 0"
|
||
></u-cell>
|
||
<view class="item">
|
||
<view class="title">公司应支付</view>
|
||
<u-input
|
||
border="surround"
|
||
:disabled="_disabled"
|
||
v-model="info.companyPayable"
|
||
fontSize="26"
|
||
type="digit"
|
||
>
|
||
</u-input>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title">公司已支付</view>
|
||
<u-input
|
||
border="surround"
|
||
:disabled="_disabled"
|
||
v-model="info.companyPayed"
|
||
fontSize="26"
|
||
type="digit"
|
||
>
|
||
</u-input>
|
||
<view class="title">收款方:维修站</view>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title">公司支付凭证</view>
|
||
<u-upload
|
||
:fileList="fileList1"
|
||
@afterRead="afterReadPdf"
|
||
@delete="deletePic"
|
||
uploadIcon="plus"
|
||
:deletable="!_disabled"
|
||
:disabled="_disabled"
|
||
accept="all"
|
||
multiple
|
||
:width="155"
|
||
:height="155"
|
||
name="1"
|
||
></u-upload>
|
||
</view>
|
||
<view class="item" v-for="item in yyPdfList1" :key="item.path">
|
||
<view class="line yyBlock">
|
||
<view class="text-small left">{{ item.fileName }}</view>
|
||
<view class="text-small" @tap="previewYyPdf(item)">预览</view>
|
||
</view>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title">客户应支付</view>
|
||
<u-input
|
||
border="surround"
|
||
:disabled="_disabled"
|
||
v-model="info.customerPayable"
|
||
fontSize="26"
|
||
type="digit"
|
||
>
|
||
</u-input>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title">客户已支付</view>
|
||
<u-input
|
||
border="surround"
|
||
:disabled="_disabled"
|
||
v-model="info.customerPayed"
|
||
fontSize="26"
|
||
type="digit"
|
||
>
|
||
</u-input>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title">收款方</view>
|
||
<u-picker
|
||
:show="showPayeePicker"
|
||
:columns="[payeeList]"
|
||
keyName="dicName"
|
||
:immediateChange="true"
|
||
@confirm="confirmPayee"
|
||
@cancel="showPayeePicker = false"
|
||
>
|
||
</u-picker>
|
||
<u--input
|
||
border="surround"
|
||
:disabledColor="_disabled ? '#f5f7fa' : '#ffffff'"
|
||
disabled
|
||
fontSize="26"
|
||
:value="info.customerPayDirectionName"
|
||
@tap="!_disabled && (showPayeePicker = true)"
|
||
>
|
||
</u--input>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title">客户支付凭证</view>
|
||
<u-upload
|
||
:fileList="fileList2"
|
||
@afterRead="afterReadPdf"
|
||
@delete="deletePic"
|
||
uploadIcon="plus"
|
||
:deletable="!_disabled"
|
||
:disabled="_disabled"
|
||
accept="all"
|
||
multiple
|
||
:width="155"
|
||
:height="155"
|
||
name="2"
|
||
></u-upload>
|
||
</view>
|
||
<view class="item" v-for="t in yyPdfList2" :key="t.path">
|
||
<view
|
||
class="line yyBlock"
|
||
style="justify-content: space-between"
|
||
>
|
||
<view class="text-small left">{{ t.fileName }}</view>
|
||
<view class="text-small" @tap="previewYyPdf(t)">预览</view>
|
||
</view>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title">超出费用(总计)</view>
|
||
<u-input
|
||
border="surround"
|
||
:disabled="_disabled"
|
||
v-model="info.overcharge"
|
||
fontSize="26"
|
||
type="digit"
|
||
>
|
||
</u-input>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title required">保养单据</view>
|
||
<u-upload
|
||
:fileList="fileList3"
|
||
@afterRead="afterReadPdf"
|
||
@delete="deletePic"
|
||
uploadIcon="plus"
|
||
:deletable="!_disabled"
|
||
:disabled="_disabled"
|
||
accept="all"
|
||
multiple
|
||
:width="155"
|
||
:height="155"
|
||
name="3"
|
||
></u-upload>
|
||
</view>
|
||
<view class="item" v-for="t in yyPdfList3" :key="t.path">
|
||
<view
|
||
class="line yyBlock"
|
||
style="justify-content: space-between"
|
||
>
|
||
<view class="text-small left">{{ t.fileName }}</view>
|
||
<view class="text-small" @tap="previewYyPdf(t)">预览</view>
|
||
</view>
|
||
</view>
|
||
<view class="item">
|
||
<view class="title">保养照片</view>
|
||
<u-upload
|
||
:fileList="fileList4"
|
||
@afterRead="afterRead"
|
||
@delete="deletePic"
|
||
:maxCount="10"
|
||
multiple
|
||
:width="155"
|
||
:height="155"
|
||
:disabled="_disabled"
|
||
:deletable="!_disabled"
|
||
name="4"
|
||
></u-upload>
|
||
</view>
|
||
</u-cell-group>
|
||
</u-collapse-item>
|
||
</u-collapse>
|
||
<view class="item">
|
||
<view class="title">备注</view>
|
||
<u--textarea
|
||
border="surround"
|
||
v-model="info.remark"
|
||
fontSize="26"
|
||
autoHeight
|
||
></u--textarea>
|
||
</view>
|
||
<view class="btns">
|
||
<button
|
||
class="save"
|
||
:class="{ disabled: _disabled }"
|
||
:disabled="_disabled"
|
||
@tap="editMaintain(false)"
|
||
>
|
||
保存
|
||
</button>
|
||
<button
|
||
class="save"
|
||
:class="{ disabled: _disabled }"
|
||
v-if="!isSubmited"
|
||
:disabled="_disabled"
|
||
@tap="editMaintain(true)"
|
||
>
|
||
提交
|
||
</button>
|
||
<button class="cancel" @tap="navigateBack">取消</button>
|
||
</view>
|
||
<u-popup
|
||
:show="checkListShow"
|
||
mode="right"
|
||
@close="checkListShow = false"
|
||
>
|
||
<scroll-view scroll-y="true" style="height: 95vh">
|
||
<view>
|
||
<view
|
||
v-for="(item, index) in recordList"
|
||
class="truckItem"
|
||
:key="index"
|
||
>
|
||
<view style="text-align: center">{{
|
||
item.maintainItem + "保养"
|
||
}}</view>
|
||
<view class="border">
|
||
<view class="flexWrap">
|
||
<view class="item" style="margin-right: 56rpx">
|
||
<u-cell-group :border="false">
|
||
<u-cell
|
||
:border="false"
|
||
title="工时费"
|
||
titleStyle="font-size: 13px"
|
||
:value="item.hourFee"
|
||
></u-cell>
|
||
<u-cell
|
||
:border="false"
|
||
titleStyle="font-size: 13px"
|
||
title="材料费"
|
||
:value="item.materialsExpenses"
|
||
></u-cell>
|
||
</u-cell-group>
|
||
</view>
|
||
<view class="item">
|
||
<u-cell-group :border="false">
|
||
<u-cell
|
||
:border="false"
|
||
titleStyle="font-size: 13px"
|
||
title="材料费(公司自采)"
|
||
:value="item.companyMaterialsExpenses"
|
||
></u-cell>
|
||
<u-cell
|
||
:border="false"
|
||
title="合计"
|
||
titleStyle="font-size: 13px"
|
||
:value="item.totalFee"
|
||
></u-cell>
|
||
</u-cell-group>
|
||
</view>
|
||
</view>
|
||
<u-cell-group :border="false">
|
||
<u-cell
|
||
:border="false"
|
||
title="维修站"
|
||
titleStyle="font-size: 13px"
|
||
:value="item.maintainSiteName"
|
||
></u-cell>
|
||
<u-cell
|
||
:border="false"
|
||
titleStyle="font-size: 13px"
|
||
title="实际保养日期"
|
||
:value="formatDateTime(item.actualMaintenanceDate)"
|
||
></u-cell>
|
||
<u-cell
|
||
:border="false"
|
||
titleStyle="font-size: 13px"
|
||
title="实际保养公里数"
|
||
:value="item.actualMaintenanceMileage || ''"
|
||
></u-cell>
|
||
<u-cell
|
||
:border="false"
|
||
titleStyle="font-size: 13px"
|
||
title="负责人"
|
||
:value="item.handlerName"
|
||
></u-cell>
|
||
</u-cell-group>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="btns">
|
||
<button class="cancel" @tap="cancelFormDataChange">取消</button>
|
||
</view>
|
||
</scroll-view>
|
||
</u-popup>
|
||
|
||
<u-loading-page
|
||
bg-color="#ffffff"
|
||
color="#7ba746"
|
||
font-size="24"
|
||
:loading="loading"
|
||
:loading-text="loadingText"
|
||
></u-loading-page>
|
||
<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>
|
||
export default {
|
||
options: {
|
||
styleIsolation: "shared", // 解除样式隔离
|
||
},
|
||
data() {
|
||
return {
|
||
id: 0,
|
||
info: {
|
||
itemList: [], // 日常维护项
|
||
instrumentRange: null,
|
||
startupItemCheck: false, // 日常维护选中列表
|
||
oilWaterCheck: false, // 日常维护选中列表
|
||
tyreCheck: false, // 日常维护选中列表
|
||
maintainSiteName: "", // 维修站名称
|
||
customerPayDirectionName: "", //收款对象名称
|
||
}, // 该备车车辆记录的数据
|
||
preTypeList: [], // 整备类型列表
|
||
isRead: false,
|
||
isSubmited: false, //是否已提交 提交过后只有费用明细可编辑
|
||
showPreTypePicker: false, // 整备类型弹窗
|
||
showParkingPicker: false,
|
||
showProjectPicker: false, // 养护项目弹窗
|
||
showNextDatePicker: false, // 养护时间弹窗
|
||
showTestRunPicker: false, // 试车时间弹窗
|
||
prepareOk: false, // 备车完成 switch
|
||
spanArr: [],
|
||
columns: [
|
||
{
|
||
title: "序号",
|
||
key: "index",
|
||
width: 80,
|
||
},
|
||
{
|
||
title: "养护项目",
|
||
key: "maintainItem",
|
||
width: 160,
|
||
},
|
||
{
|
||
title: "保养到期时间",
|
||
key: "maintenanceDueTime",
|
||
width: 160,
|
||
},
|
||
{
|
||
title: "保养到期里程",
|
||
key: "maintenanceDueMileage",
|
||
width: 170,
|
||
},
|
||
{
|
||
title: "历史记录",
|
||
key: "operation",
|
||
width: 115,
|
||
},
|
||
],
|
||
range: [
|
||
{ value: 1, text: "%" },
|
||
{ value: 2, text: "MPa" },
|
||
{ value: 3, text: "kg" },
|
||
],
|
||
inStoreList: [], // 在库状态车辆列表
|
||
lastTestRunDatePicker: false, // 试车时间
|
||
checkoutIds: [], // 检查单选中项
|
||
testChecked: false, // 试车时间复选框
|
||
mainTableList: [], // 保养记录表格数据
|
||
maintainItems: [], // 养护项目 用在费用列表的下拉框
|
||
checkListShow: false, // 检查单弹窗
|
||
recordList: [], // 保养记录列表
|
||
mainItemPicker: [false], //本次养护项目-保养项目弹窗
|
||
showFixPicker: false, // 维修站
|
||
maintainSiteList: "", // 维修站列表
|
||
showRealDatePicker: false, // 实际保养时间
|
||
compressPicMap: new Map(), // 缩略图映射,key为原图,value为缩略图
|
||
fileList1: [], // 公司支付凭证
|
||
fileList2: [], // 客户支付凭证
|
||
fileList3: [], // 保养单据
|
||
fileList4: [], // 保养照片
|
||
showPayeePicker: false, // 收款方式
|
||
// payeeText: "", // 收款方式名称
|
||
payeeList: [], // 收款方式列表
|
||
gpsLocation: "", // GPS定位'
|
||
isPageShow: false,
|
||
loading: false,
|
||
loadingText: "加载中...",
|
||
canvasWidth: 0,
|
||
canvasHeight: 0,
|
||
};
|
||
},
|
||
computed: {
|
||
_disabled() {
|
||
return this.isRead;
|
||
},
|
||
tableDisabled() {
|
||
return (
|
||
!(
|
||
this.info.maintainSiteId &&
|
||
this.info.actualMaintenanceDate &&
|
||
this.info.actualMaintenanceMileage
|
||
) ||
|
||
this._disabled ||
|
||
this.isSubmited
|
||
);
|
||
},
|
||
yyPdfList1() {
|
||
console.log(this.info.companyVoucherAttachmentList);
|
||
return (
|
||
this.info.companyVoucherAttachmentList?.filter(
|
||
(item) => item.type == "file" || item.type == "pdf"
|
||
) || []
|
||
);
|
||
},
|
||
yyPdfList2() {
|
||
return (
|
||
this.info.customerVoucherAttachmentList?.filter(
|
||
(item) => item.type == "file" || item.type == "pdf"
|
||
) || []
|
||
);
|
||
},
|
||
yyPdfList3() {
|
||
return (
|
||
this.info.billsAttachmentList?.filter(
|
||
(item) => item.type == "file" || item.type == "pdf"
|
||
) || []
|
||
);
|
||
},
|
||
},
|
||
async onLoad(options) {
|
||
if (options.id) {
|
||
this.id = options.id;
|
||
}
|
||
if (options.isRead) {
|
||
this.isRead = Number(options.isRead);
|
||
}
|
||
if (!this.isRead) {
|
||
this.getLocation();
|
||
this.isPageShow = true; // 如果不是查看模式,则开启拦截
|
||
}
|
||
// await this.getPreTypeList(); // 获取整备类型列表
|
||
await this.maintainSiteSelect(); // 获取维修站列表
|
||
await this.getPayeeTypeList(); // 获取收款方式列表
|
||
await this.getData();
|
||
this.getMaintainTableList(); // 获取保养记录
|
||
this.parseFileListBack(); // 解析返回的文件列表
|
||
},
|
||
methods: {
|
||
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("用户点击取消");
|
||
}
|
||
},
|
||
});
|
||
}
|
||
},
|
||
objectSpanMethod(row, column, rowIndex, columnIndex) {
|
||
if (columnIndex === 0) {
|
||
const _row = this.spanArr[rowIndex];
|
||
const _col = _row > 0 ? 1 : 0;
|
||
return {
|
||
rowspan: _row,
|
||
colspan: _col,
|
||
};
|
||
}
|
||
},
|
||
async maintainSiteSelect() {
|
||
await this.$api.returnCar.getFixPageList().then((res) => {
|
||
console.log(res);
|
||
this.maintainSiteList = res;
|
||
});
|
||
},
|
||
async getPayeeTypeList() {
|
||
await this.$api.maintainTodo.getPayeeType().then((res) => {
|
||
console.log(res);
|
||
this.payeeList = res;
|
||
});
|
||
},
|
||
confirmPayee(e) {
|
||
this.info.customerPayDirection = e.value[0].dicCode;
|
||
this.info.customerPayDirectionName = e.value[0].dicName;
|
||
this.showPayeePicker = false;
|
||
},
|
||
confirmFix(e) {
|
||
this.info.maintainSiteId = e.value[0].id;
|
||
this.info.maintainSiteName = e.value[0].name;
|
||
this.showFixPicker = false;
|
||
this.getCostInfoByIds();
|
||
},
|
||
// *实际保养日期
|
||
confirmRealDate(e) {
|
||
this.info.actualMaintenanceDate = e.value;
|
||
this.showRealDatePicker = false;
|
||
this.getCostInfoByIds();
|
||
},
|
||
changeSearch() {
|
||
this.getCostInfoByIds();
|
||
},
|
||
changeFee1(val, index) {
|
||
console.log(val);
|
||
console.log(index);
|
||
this.info.itemList[index].totalFee =
|
||
Number(val || 0) +
|
||
(Number(this.info.itemList[index].materialsExpenses) || 0) +
|
||
(Number(this.info.itemList[index].companyMaterialsExpenses) || 0);
|
||
this.getComputedTotalFee(index);
|
||
},
|
||
changeFee2(val, row, index) {
|
||
console.log(val);
|
||
console.log(row);
|
||
this.info.itemList[index].totalFee =
|
||
Number(val || 0) +
|
||
(Number(row.hourFee) || 0) +
|
||
(Number(row.companyMaterialsExpenses) || 0);
|
||
this.getComputedTotalFee(index);
|
||
},
|
||
changeCompanyEx(val, row, index) {
|
||
console.log(val);
|
||
console.log(row);
|
||
this.info.itemList[index].totalFee =
|
||
Number(val || 0) +
|
||
(Number(row.hourFee) || 0) +
|
||
(Number(row.materialsExpenses) || 0);
|
||
|
||
this.getComputedTotalFee(index);
|
||
},
|
||
getComputedTotalFee(index = null) {
|
||
console.log("费用明细计算");
|
||
//通过公司承担百分比计算公司承担费用
|
||
if (index !== null) {
|
||
this.info.itemList[index].companyUndertake = this.info.itemList[index]
|
||
.companyUndertakePercent
|
||
? (
|
||
(Number(this.info.itemList[index].totalFee) *
|
||
this.info.itemList[index].companyUndertakePercent) /
|
||
100
|
||
).toFixed(2)
|
||
: 0;
|
||
//通过客户承担百分比计算客户承担费用
|
||
this.info.itemList[index].customerUndertake = this.info.itemList[index]
|
||
.customerUndertakePercent
|
||
? (
|
||
(Number(this.info.itemList[index].totalFee) *
|
||
this.info.itemList[index].customerUndertakePercent) /
|
||
100
|
||
).toFixed(2)
|
||
: 0;
|
||
}
|
||
//费用总计
|
||
this.info.amount = this.info.itemList.reduce(
|
||
(prev, cur) => prev + Number(cur.totalFee),
|
||
0
|
||
);
|
||
//公司承担总计
|
||
this.info.companyUndertake = this.info.itemList.reduce(
|
||
(prev, cur) => prev + Number(cur.companyUndertake),
|
||
0
|
||
);
|
||
//客户承担总计
|
||
this.info.customerUndertake = this.info.itemList.reduce(
|
||
(prev, cur) => prev + Number(cur.customerUndertake),
|
||
0
|
||
);
|
||
//公司应支付
|
||
this.info.companyPayable = this.info.itemList.reduce(
|
||
(prev, cur) =>
|
||
prev + cur.totalFee - Number(cur.companyMaterialsExpenses),
|
||
0
|
||
);
|
||
//客户应支付
|
||
this.info.customerPayable =
|
||
this.info.amount - Number(this.info.companyUndertake);
|
||
//超出费用总计
|
||
this.info.overcharge = this.info.itemList.reduce(
|
||
(prev, cur) => prev + Number(cur.overcharge),
|
||
0
|
||
);
|
||
},
|
||
async getCostInfoByIds(index = null) {
|
||
if (
|
||
!this.info.maintainSiteId ||
|
||
!this.info.actualMaintenanceDate ||
|
||
!this.info.actualMaintenanceMileage
|
||
) {
|
||
this.alert("请选择维修站、实际保养日期、实际保养里程");
|
||
return;
|
||
}
|
||
let ids = [];
|
||
if (index !== null) {
|
||
console.log(index);
|
||
ids = [this.info.itemList[index].maintainItemId];
|
||
} else {
|
||
ids = this.info.itemList
|
||
.filter((item) => !!item.maintainItemId)
|
||
.map((item) => item.maintainItemId);
|
||
}
|
||
|
||
if (!ids || ids.length == 0) {
|
||
this.alert("请选择保养项目");
|
||
return;
|
||
}
|
||
//this.listLoading = true;
|
||
this.$api.maintainTodo
|
||
.getCostInfoByIds({
|
||
truckId: this.info.truckId,
|
||
maintainSiteId: this.info.maintainSiteId,
|
||
maintainItemIds: ids,
|
||
actualMaintenanceDate: this.info.actualMaintenanceDate,
|
||
actualMaintenanceMileage: this.info.actualMaintenanceMileage,
|
||
noticeModel: this.info.noticeModel,
|
||
})
|
||
.then((res) => {
|
||
console.log(res);
|
||
if (index !== null) {
|
||
Object.assign(this.info.itemList[index], res?.data[0] || {});
|
||
} else {
|
||
this.info.itemList = this.info.itemList.map((item, idx) => {
|
||
Object.assign(item, res?.data[idx] || {});
|
||
return item;
|
||
});
|
||
}
|
||
this.getComputedTotalFee();
|
||
// this.listLoading = false;
|
||
});
|
||
},
|
||
confirmMainItem(e, index) {
|
||
console.log("showTrunkParkPicker:\n", e.value[0]);
|
||
const leng =
|
||
this.info?.itemList?.filter(
|
||
(item) => item.maintainItemId == e.value[0].maintainItemId
|
||
).length || 0;
|
||
if (leng > 0) {
|
||
this.alert("该保养项目已存在,请重新选择");
|
||
this.info.itemList[index].maintainItemId = "";
|
||
return;
|
||
}
|
||
this.info.itemList[index].maintainItemId = e.value[0].maintainItemId;
|
||
this.$set(
|
||
this.info.itemList[index],
|
||
"maintainItem",
|
||
e.value[0].maintainItem
|
||
);
|
||
this.getCostInfoByIds(index);
|
||
this.mainItemPicker[index] = false;
|
||
},
|
||
cancelMainItem(index) {
|
||
this.$set(this.mainItemPicker, index, false);
|
||
},
|
||
showMainItemPicker(index) {
|
||
if (this._disabled) {
|
||
return;
|
||
}
|
||
console.log("showMainItemPicker");
|
||
this.$set(this.mainItemPicker, index, true);
|
||
},
|
||
|
||
addForm() {
|
||
this.info.itemList.push({
|
||
maintainItemId: "", //养护项目ID
|
||
maintenanceDueTime: null, //养护到期时间
|
||
maintenanceDueMileage: "", //养护到期里程
|
||
hourFee: "", //工时费
|
||
materialsExpenses: "", //材料费用
|
||
companyMaterialsExpenses: "", //公司材料费用
|
||
totalFee: "", //总费用,
|
||
companyUndertake: "", //公司应付
|
||
companyUndertakePercent: 100, //公司应付百分比
|
||
customerUndertake: "", //客户应付
|
||
customerUndertakePercent: 100, //客户应付百分比
|
||
overcharge: "", //超出费用
|
||
remark: "", //备注
|
||
});
|
||
|
||
this.mainItemPicker.push(false);
|
||
this.$nextTick(() => {
|
||
this.$refs.currentCollapse.init();
|
||
});
|
||
},
|
||
delForm(index) {
|
||
if (this.info.itemList.length <= 1) {
|
||
this.alert(`至少保留一条数据`);
|
||
return;
|
||
}
|
||
this.info.itemList.splice(index, 1);
|
||
this.mainItemPicker.splice(index, 1);
|
||
this.getComputedTotalFee(); //重新计算总费用
|
||
this.$nextTick(() => {
|
||
this.$refs.currentCollapse.init();
|
||
});
|
||
},
|
||
cancelFormDataChange() {
|
||
this.checkListShow = false;
|
||
uni.setNavigationBarTitle({
|
||
title: "保养信息",
|
||
});
|
||
},
|
||
viewRecord(row) {
|
||
this.$api.maintainTodo
|
||
.getRecords({
|
||
truckId: this.info.truckId,
|
||
maintainItemId: row.id,
|
||
})
|
||
.then((res) => {
|
||
console.log(`res:`, res);
|
||
this.recordList =
|
||
res?.data.map((item) => {
|
||
item.totalFee =
|
||
Number(item.hourFee || 0) +
|
||
(Number(item.materialsExpenses) || 0) +
|
||
(Number(item.companyMaterialsExpenses) || 0);
|
||
return item;
|
||
}) || [];
|
||
this.checkListShow = true;
|
||
uni.setNavigationBarTitle({
|
||
title: "保养记录",
|
||
});
|
||
});
|
||
},
|
||
async makeTodo() {
|
||
console.log("makeTodo");
|
||
uni.showModal({
|
||
title: "提示",
|
||
content: "确认生成异动申请吗?",
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
let params = {
|
||
truckId: this.info.truckId,
|
||
transactionType: 2, //保养
|
||
};
|
||
if (this.info.maintainSiteId) {
|
||
params.transactionAddressType = 2;
|
||
params.transactionAddress = this.info.maintainSiteId;
|
||
}
|
||
if (this.info.actualMaintenanceDate) {
|
||
params.transactionStartTime = this.info.actualMaintenanceDate;
|
||
}
|
||
this.$api.unusualActionApply.addByTruckId(params).then((res) => {
|
||
if (res) {
|
||
uni.showToast({
|
||
title: "操作成功",
|
||
icon: "success",
|
||
duration: 1500,
|
||
});
|
||
}
|
||
});
|
||
}
|
||
},
|
||
});
|
||
|
||
//现在itemList的id或者maintainItemId是空的 checkoutIds也是空的做不了过滤
|
||
// let params = {
|
||
// truckId: this.info.truckId,
|
||
// itemList: this.info.agentItemListVoList.filter((item) =>
|
||
// this.checkoutIds.includes(item.id)
|
||
// ),
|
||
// };
|
||
// this.$api.maintainTodo.add(params).then((res) => {
|
||
// if (res) {
|
||
// uni.showToast({
|
||
// title: "操作成功",
|
||
// icon: "success",
|
||
// duration: 1500,
|
||
// });
|
||
// }
|
||
// });
|
||
},
|
||
async getMaintainTableList() {
|
||
await this.$api.maintainTodo
|
||
.getMaintainInfoByCarId({
|
||
id: this.info.truckId,
|
||
})
|
||
.then((res) => {
|
||
if (res) {
|
||
let datas = res?.data;
|
||
if (datas == null) {
|
||
this.tableList = [];
|
||
} else {
|
||
this.maintainItems = datas || [];
|
||
this.mainTableList = datas.map((item) => {
|
||
item.truckId = this.info.truckId;
|
||
item.maintainItemId = item.id;
|
||
item.maintenanceDueTime = this.formatDateTime(
|
||
item.maintenanceDueTime
|
||
);
|
||
return item;
|
||
});
|
||
|
||
this.getSpanArr(this.deepClone(this.mainTableList));
|
||
}
|
||
this.$nextTick(() => {
|
||
this.$refs.maintainCollapse.init();
|
||
});
|
||
}
|
||
});
|
||
},
|
||
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;
|
||
},
|
||
// https://www.cnblogs.com/janni/p/12992591.html
|
||
getSpanArr(data) {
|
||
this.spanArr = [];
|
||
for (let i = 0; i < data.length; i++) {
|
||
if (i === 0) {
|
||
this.spanArr.push(1);
|
||
this.pos = 0;
|
||
} else {
|
||
// 判断当前元素与上一个元素是否相同 dataCategory (类别字段)
|
||
this.spanArr.push(1);
|
||
this.pos = i;
|
||
}
|
||
}
|
||
},
|
||
async getData() {
|
||
await this.$api.maintainTodo.getById({ id: this.id }).then((res) => {
|
||
if (res.code != 200) {
|
||
return;
|
||
}
|
||
|
||
console.log(`res:`, res.data);
|
||
this.info = res.data;
|
||
this.isSubmited = !!this.info.maintenanceStatus; // 是否已提交
|
||
this.info.maintainSiteName =
|
||
this.maintainSiteList.find(
|
||
(item) => item.id == this.info.maintainSiteId
|
||
)?.name ?? ""; //回显维修站名称
|
||
|
||
this.info.customerPayDirectionName =
|
||
this.payeeList.find(
|
||
(item) => item.dicCode == this.info.customerPayDirection
|
||
)?.dicName ?? "";
|
||
this.$nextTick(() => {
|
||
this.$refs.uploadCollapse.init();
|
||
this.$refs.currentCollapse.init();
|
||
this.$refs.costCollapse.init();
|
||
});
|
||
// console.log(`this.info:\n`, this.info)
|
||
});
|
||
},
|
||
//试车时间
|
||
confirmTestRunDate(e) {
|
||
this.info.lastTestRunDate = e.value;
|
||
this.showTestRunPicker = false;
|
||
},
|
||
//养护时间
|
||
confirmNextDate(e) {
|
||
this.info.nextMaintenanceDate = e.value;
|
||
this.showNextDatePicker = false;
|
||
},
|
||
//整备类型确认
|
||
confirmPreType(e) {
|
||
this.info.preTypeSel = e.indexs[0];
|
||
this.showPreTypePicker = false;
|
||
},
|
||
//项目确认
|
||
confirmProject(e) {
|
||
this.info.projectSel = e.indexs[0];
|
||
this.showProjectPicker = false;
|
||
},
|
||
//停车场确认
|
||
confirmPark(e) {
|
||
this.info.parkingSel = e.indexs[0];
|
||
this.showParkingPicker = false;
|
||
},
|
||
getDicValue(dic, dicCode) {
|
||
if (dic.length == 0) {
|
||
return "";
|
||
}
|
||
|
||
return dic.find((x) => x.dicCode == dicCode)?.dicName ?? "";
|
||
},
|
||
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");
|
||
return `${year}-${month}-${day} ${hour}:00`;
|
||
}
|
||
},
|
||
timestampToDateAndBack(timestamp) {
|
||
const date = new Date(timestamp);
|
||
const year = date.getFullYear();
|
||
const month = (date.getMonth() + 1).toString().padStart(2, "0"); // 月份从0开始,所以要+1
|
||
const day = date.getDate().toString().padStart(2, "0");
|
||
const formattedDate = `${year}-${month}-${day}`;
|
||
const newTimestamp = new Date(`${formattedDate} 00:00:00`).getTime();
|
||
return newTimestamp;
|
||
},
|
||
getNowTimestamp() {
|
||
// 获取当前时间精确到小时的时间戳
|
||
const now = new Date();
|
||
now.setMinutes(0, 0, 0); // 设置分钟、秒、毫秒为0
|
||
return now.getTime(); // 返回时间戳
|
||
},
|
||
confirmBand(e) {
|
||
console.log(e);
|
||
const brand = e.value[0].dicCode;
|
||
// 没有更改
|
||
if (brand == this.info.brand) {
|
||
this.showParkingPicker = false;
|
||
return;
|
||
}
|
||
this.info.brand = brand;
|
||
this.showParkingPicker = false;
|
||
this.info.plateNumber = "";
|
||
this.info.vin = "";
|
||
this.info.hasTailboard = "";
|
||
this.info.hasAdvertisement = "";
|
||
this.info.isHang = "";
|
||
},
|
||
navigateBack() {
|
||
this.isPageShow = false;
|
||
setTimeout(() => {
|
||
uni.navigateBack();
|
||
}, 100);
|
||
},
|
||
// 在提交前检查,是否有必填字段未填写
|
||
check() {
|
||
if (!this.info.maintainSiteId) {
|
||
this.alert("请选择维修站");
|
||
return false;
|
||
}
|
||
if (!this.info.actualMaintenanceDate) {
|
||
this.alert("请选择实际保养日期");
|
||
return false;
|
||
}
|
||
if (!this.info.actualMaintenanceMileage) {
|
||
this.alert("请输入实际保养里程");
|
||
return false;
|
||
}
|
||
if (
|
||
this.info.itemList.filter((item) => ["", null].includes(item.hourFee))
|
||
.length > 0
|
||
) {
|
||
this.alert("请填写工时费");
|
||
return false;
|
||
}
|
||
if (
|
||
this.info.itemList.filter(
|
||
(item) =>
|
||
["", null].includes(item.materialsExpenses) &&
|
||
["", null].includes(item.companyMaterialsExpenses)
|
||
).length > 0
|
||
) {
|
||
this.alert("请填写材料费");
|
||
return false;
|
||
}
|
||
// if (!this.info.companyVoucherAttachmentList) {
|
||
// this.alert("请上传公司支付凭证");
|
||
// return false;
|
||
// }
|
||
// if (!this.info.customerVoucherAttachmentList) {
|
||
// this.alert("请上传客服支付凭证");
|
||
// return false;
|
||
// }
|
||
if (!this.info.billsAttachmentList) {
|
||
this.alert("请上传保养单据");
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
alert(msg) {
|
||
uni.showToast({
|
||
title: msg,
|
||
icon: "none",
|
||
duration: 1500,
|
||
});
|
||
},
|
||
// 保存备车信息表
|
||
editMaintain(submit = false) {
|
||
if (submit && !this.check()) {
|
||
return;
|
||
}
|
||
console.log(this.info);
|
||
let params = { ...this.info };
|
||
params.isSubmit = submit;
|
||
// params.projectId = this.projectList[params.projectSel].dicCode;
|
||
this.$api.maintainTodo.edit(params).then((res) => {
|
||
// todo: res是接口data数据,之后研究一下如何获取整个内容
|
||
if (res) {
|
||
uni.showToast({
|
||
title: submit ? "提交成功" : "保存成功",
|
||
icon: "success",
|
||
duration: 1500,
|
||
success() {},
|
||
});
|
||
this.isPageShow = false;
|
||
setTimeout(() => {
|
||
uni.navigateBack();
|
||
}, 1500);
|
||
}
|
||
});
|
||
},
|
||
// 删除图片
|
||
deletePic(event) {
|
||
const fileList = this[`fileList${event.name}`];
|
||
if (fileList.some((x) => x.status == "uploading")) {
|
||
this.alert(`请等待现有文件上传完成后再操作`);
|
||
return;
|
||
}
|
||
|
||
this[`fileList${event.name}`].splice(event.index, 1);
|
||
switch (event.name) {
|
||
case "1": //公司支付凭证
|
||
this.info.companyVoucherAttachmentList.splice(event.index, 1);
|
||
break;
|
||
case "2": //客户支付凭证
|
||
this.info.customerVoucherAttachmentList.splice(event.index, 1);
|
||
break;
|
||
case "3": //保养单据
|
||
this.info.billsAttachmentList.splice(event.index, 1);
|
||
break;
|
||
case "4": //保养照片
|
||
this.info.pictureList.splice(event.index, 1);
|
||
break;
|
||
}
|
||
},
|
||
// 新增附件
|
||
async afterReadPdf(event) {
|
||
// 当设置 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",
|
||
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[`fileList${event.name}`][fileListLen];
|
||
this[`fileList${event.name}`].splice(
|
||
fileListLen,
|
||
1,
|
||
Object.assign(item, {
|
||
status: "success",
|
||
message: "",
|
||
url: result.data?.url ?? "",
|
||
thumb: item.type === "file" ? "/static/pdf.png" : "",
|
||
})
|
||
);
|
||
fileListLen++;
|
||
console.log("fileList");
|
||
console.log(this[`fileList${event.name}`]);
|
||
console.log(item);
|
||
console.log(result.data);
|
||
const imgUrl = result.data?.url ?? "";
|
||
const fileName = event.file[0]?.name ?? "";
|
||
const type = item.type;
|
||
if (event.name == "1") {
|
||
this.info.companyVoucherAttachmentList.push({
|
||
path: imgUrl,
|
||
fileName: fileName,
|
||
thumb: "/static/pdf.png",
|
||
type: type,
|
||
});
|
||
console.log(this.info.companyVoucherAttachmentList);
|
||
} else if (event.name == "2") {
|
||
this.info.customerVoucherAttachmentList.push({
|
||
path: imgUrl,
|
||
fileName: fileName,
|
||
thumb: "/static/pdf.png",
|
||
type: type,
|
||
});
|
||
console.log(this.info.customerVoucherAttachmentList);
|
||
} else if (event.name == "3") {
|
||
this.info.billsAttachmentList.push({
|
||
path: imgUrl,
|
||
fileName: fileName,
|
||
thumb: "/static/pdf.png",
|
||
type: type,
|
||
});
|
||
console.log(this.info.billsAttachmentList);
|
||
}
|
||
this.$nextTick(() => {
|
||
this.$refs.costCollapse.init();
|
||
});
|
||
}
|
||
},
|
||
// 新增图片
|
||
async afterRead(event) {
|
||
// 当设置 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",
|
||
message: "上传中",
|
||
});
|
||
});
|
||
console.log(`event.file:\n`, event.file);
|
||
console.log(lists);
|
||
for (let i = 0; i < lists.length; i++) {
|
||
this.loading = true;
|
||
this.loadingText = "添加水印中...";
|
||
const fileSize = lists[i].size / 1024 ** 2; // 图片多少MB
|
||
let waterUrl = "";
|
||
console.log(lists[i].url);
|
||
try {
|
||
waterUrl = await this.addWatermark(lists[i].url, fileSize);
|
||
} catch (e) {
|
||
console.log(`e:\n`, e);
|
||
this.alert(e.toString());
|
||
this[`fileList${event.name}`].splice(fileListLen, 1);
|
||
return;
|
||
}
|
||
const result = await this.uploadFilePromise(waterUrl);
|
||
// let result = { data: { url: waterUrl }}
|
||
let item = this[`fileList${event.name}`][fileListLen];
|
||
this[`fileList${event.name}`].splice(
|
||
fileListLen,
|
||
1,
|
||
Object.assign(item, {
|
||
status: "success",
|
||
message: "",
|
||
url: result.data?.url ?? "",
|
||
thumb: waterUrl,
|
||
})
|
||
);
|
||
fileListLen++;
|
||
|
||
const imgUrl = result.data?.url ?? "";
|
||
|
||
if (imgUrl) {
|
||
this.compressPicMap.set(
|
||
imgUrl,
|
||
result.data?.compressedImageUrl ?? ""
|
||
);
|
||
}
|
||
|
||
if (event.name == "4") {
|
||
this.info.pictureList.push(imgUrl);
|
||
}
|
||
this.$nextTick(() => {
|
||
// 解决折叠collapse高度无法动态更新的问题
|
||
this.$refs.costCollapse.init();
|
||
});
|
||
}
|
||
},
|
||
uploadFilePromise(url) {
|
||
console.log("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);
|
||
},
|
||
});
|
||
});
|
||
},
|
||
previewYyPdf(data) {
|
||
console.log(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;
|
||
},
|
||
});
|
||
},
|
||
parseFileListBack() {
|
||
//this.fileList7 = this.datas.blemish.map((x) => ({ url: x }));
|
||
this.fileList1 = this.info.companyVoucherAttachmentList.map((x) => ({
|
||
url: x.path,
|
||
name: x.fileName,
|
||
type: x.fileName.substring(x.fileName.lastIndexOf(".") + 1) || "",
|
||
thumb: "",
|
||
}));
|
||
|
||
this.fileList2 = this.info.customerVoucherAttachmentList.map((x) => ({
|
||
url: x.path,
|
||
name: x.fileName,
|
||
type: x.fileName.substring(x.fileName.lastIndexOf(".") + 1) || "",
|
||
thumb: "",
|
||
}));
|
||
|
||
this.fileList3 = this.info.billsAttachmentList.map((x) => ({
|
||
url: x.path,
|
||
name: x.fileName,
|
||
type: x.fileName.substring(x.fileName.lastIndexOf(".") + 1) || "",
|
||
thumb: "",
|
||
}));
|
||
|
||
this.fileList4 = this.info.pictureList.map((x) => ({
|
||
url: x.path,
|
||
thumb: x.compressedImagePath || x.path,
|
||
}));
|
||
this.info.pictureList.forEach((x) => {
|
||
this.compressPicMap.set(x.path, x.compressedImagePath || x.path);
|
||
});
|
||
this.$nextTick(() => {
|
||
this.$refs.costCollapse.init();
|
||
});
|
||
},
|
||
getLocation() {
|
||
uni.getLocation({
|
||
type: "wgs84",
|
||
success: (res) => {
|
||
const longitude = res.longitude;
|
||
const latitude = res.latitude;
|
||
this.$api.returnCar
|
||
.getAddress({ longitude, latitude })
|
||
.then((res) => {
|
||
this.gpsLocation = res?.data ?? "浙江省嘉兴市";
|
||
});
|
||
},
|
||
fail: (res) => {
|
||
console.log(res);
|
||
},
|
||
});
|
||
},
|
||
// 图片添加水印
|
||
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);
|
||
}
|
||
console.log(111111111);
|
||
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;
|
||
},
|
||
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}`;
|
||
},
|
||
},
|
||
|
||
onPullDownRefresh() {
|
||
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style lang="less" scoped>
|
||
.yyBlock {
|
||
justify-content: space-between;
|
||
display: flex;
|
||
font-size: 26rpx;
|
||
}
|
||
.currentItem {
|
||
border: 1px solid #7ba746;
|
||
padding: 0 20rpx 20rpx;
|
||
border-radius: 20rpx;
|
||
margin: 20rpx 0;
|
||
}
|
||
.truckListBtns {
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
.truckItem {
|
||
margin-top: 30rpx;
|
||
padding: 30rpx;
|
||
.border {
|
||
margin-top: 10rpx;
|
||
border: 1px solid #7ba746;
|
||
border-radius: 20rpx;
|
||
padding: 0 20rpx;
|
||
}
|
||
.flexWrap {
|
||
display: flex;
|
||
.item {
|
||
margin-top: 0;
|
||
flex: 1;
|
||
}
|
||
}
|
||
}
|
||
.viewBtn {
|
||
display: inline-block;
|
||
font-size: 26rpx;
|
||
padding: 5rpx 10rpx;
|
||
border-radius: 10rpx;
|
||
margin-left: 10rpx;
|
||
background: #7ba746;
|
||
color: #fff;
|
||
}
|
||
/deep/ .u-collapse-item .u-cell__title-text {
|
||
font-weight: bold;
|
||
}
|
||
/deep/ .uni-select__input-text {
|
||
font-size: 26rpx !important;
|
||
text-align: right !important;
|
||
}
|
||
/deep/ .u-collapse-item__content__text {
|
||
padding: unset !important;
|
||
color: unset !important;
|
||
font-size: unset !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/ .uni-select {
|
||
width: 100rpx !important;
|
||
}
|
||
.container {
|
||
// background-color: #d7d7d7;
|
||
padding: 30rpx;
|
||
.header {
|
||
margin: 15rpx 0;
|
||
}
|
||
.item {
|
||
margin-top: 30rpx;
|
||
.content {
|
||
font-size: 26rpx;
|
||
color: #797979;
|
||
display: flex;
|
||
gap: 50rpx;
|
||
justify-content: space-between;
|
||
margin-bottom: 10rpx;
|
||
.text {
|
||
border: 2rpx solid #797979;
|
||
border-radius: 10rpx;
|
||
padding: 5rpx;
|
||
}
|
||
}
|
||
.title {
|
||
font-size: 26rpx;
|
||
margin-bottom: 15rpx;
|
||
|
||
&.required::before {
|
||
content: "*";
|
||
color: red;
|
||
margin-right: 3rpx;
|
||
}
|
||
}
|
||
.font30 {
|
||
font-size: 30rpx;
|
||
}
|
||
.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;
|
||
}
|
||
}
|
||
}
|
||
|
||
.btns {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-around;
|
||
margin-top: 40rpx;
|
||
|
||
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;
|
||
}
|
||
.disabled {
|
||
opacity: 0.6;
|
||
}
|
||
}
|
||
}
|
||
|
||
/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/ .u-border {
|
||
border-width: 1rpx !important;
|
||
border-color: #dadbde !important;
|
||
border-style: solid;
|
||
}
|
||
|
||
/deep/ .u-switch {
|
||
border-color: rgba(0, 0, 0, 0.12) !important;
|
||
}
|
||
|
||
/deep/ .u-slide-right-enter-to.u-slide-right-enter-active {
|
||
width: 750rpx;
|
||
}
|
||
|
||
/deep/ .td_wrap {
|
||
height: auto !important;
|
||
}
|
||
|
||
/deep/ .no-bad-table-wrap .td.rowspan {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
// /deep/ checkbox-group view.td {
|
||
// width: 136.5rpx !important;
|
||
// }
|
||
|
||
// /deep/ checkbox-group view.td_wrap {
|
||
// width: 136.5rpx !important;
|
||
// }
|
||
|
||
// /deep/ .div-table-head .thead .tr view {
|
||
// width: 136.5rpx !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;
|
||
}
|
||
</style>
|