<template>
<div class="wrap vehicleAdd">
  <div class="navBar">
    <van-nav-bar
        :title="id ? '修改车辆信息' : '添加车辆'"
        left-arrow
        left-arrow-color="#FFFFFF"
        :border="false"
        :fixed="true"
        :safe-area-inset-top="true"
        @click-left="back"
    />
  </div>
  <div class="addContentWrap">
  <div class="itemContent">
    <div class="titleType">
      <img class="startImg" src="@/assets/start.png" />
      <span>行驶证首页</span>
    </div>
    <div class="uploadSlotWrap">
      <van-uploader
        ref="licenseFrontUploader"
        v-model="vehicleLicenseFrontList"
        :after-read="vehicleLicenseFrontHandler"
        @delete="vehicleLicenseFrontDelete"
        max-count="1"
        :preview-size="54"
        accept="image/*"
      />
      <div class="slotClickMask" @click="onLicenseSlotClick('front')"></div>
    </div>
  </div>
  <div class="itemContent">
    <div class="titleType">
      <img class="startImg" src="@/assets/start.png" />
      <span>行驶证副页</span>
    </div>
    <div class="uploadSlotWrap">
      <van-uploader
        ref="licenseBackUploader"
        v-model="vehicleLicenseBackList"
        :after-read="vehicleLicenseBackHandler"
        @delete="vehicleLicenseBackDelete"
        max-count="1"
        :preview-size="54"
        accept="image/*"
      />
      <div class="slotClickMask" @click="onLicenseSlotClick('back')"></div>
    </div>
  </div>
  <div class="itemContent">
    <div class="titleType">
      <img class="startImg" src="@/assets/start.png" />
      <span>行驶证车辆照片页</span>
    </div>
    <div class="uploadSlotWrap">
      <van-uploader
        ref="licenseCarUploader"
        v-model="vehicleLicenseCarPhotoList"
        :after-read="vehicleLicenseCarHandler"
        @delete="vehicleLicenseCarPhotoDelete"
        max-count="1"
        :preview-size="54"
        accept="image/*"
      />
      <div class="slotClickMask" @click="onLicenseSlotClick('car')"></div>
    </div>
  </div>
  <div class="itemContent">
    <div class="titleType">
      <img class="startImg" src="@/assets/start.png" />
      <span>车头照</span>
    </div>
    <van-uploader
      v-model="vehicleFrontPhotoList"
      :after-read="vehicleFrontPhotoHandler"
      @delete="vehicleFrontPhotoDelete"
      max-count="1"
      :preview-size="54"
      accept="image/*"
    />
  </div>

  <cell-group label="车牌号" placeholder="车牌号" disabled v-model="carNum" />
  <div class="itemContent">
    <div class="titleType">
      <img class="startImg" src="@/assets/start.png" />
      <span>车辆类别</span>
    </div>
<!--
    <select
        id="mySelect"
        class="mySelect"
        v-model="selectedOption"
        multiple
    >
      <option
          v-for="item in typeList"
          :key="item"
          :value="item"
          :disabled="isOptionDisabled(item)"
      >
        {{ item }}
      </option>
    </select>
-->
    <el-select
        multiple
        :multiple-limit="isMultiple ? 2 : 1"
        v-model="selectedOption"
        :disabled="vehicleInfoDisabled"
        value-key="name"
        class="elSelect"
        collapse-tags="collapse-tags"
        :popper-append-to-body="false"
        placeholder="请选择"  style="width: 55%"
    >
      <el-option
          v-for="item in vehicleTypes"
          :key="item.name"
          :label="item.name"
          :value="item.value"
          :disabled="!item.disabled ? false : true"
      >
      </el-option>
    </el-select>

  </div>
  <div class="itemContent">
    <div class="titleType">
      <img class="startImg" src="@/assets/start.png" />
      <span>车辆属性</span>
    </div>
    <div class="virtualVehicleField">
      <el-select
        v-model="virtualVehicle"
        value-key="name"
        class="elSelect"
        collapse-tags="collapse-tags"
        :disabled="vehicleInfoDisabled || virtualVehicleLocked"
        placeholder="请选择"  style="width: 55%"
      >
        <el-option
          v-for="item in virtualVehicleOptions"
          :key="item.name"
          :label="item.name"
          :value="item.value"
        >
        </el-option>
      </el-select>
      <span class="matchRoleArrow" :class="{expanded: matchRoleExpand}"
            @click="matchRoleExpand = !matchRoleExpand">▾</span>
    </div>
  </div>
  <div v-if="matchRoleExpand" class="matchRolePanel">
    匹配角色：{{ virtualVehicleMatchRole || '—' }}
  </div>
  <div class="lineBot"></div>
  <div class="itemContent">
    <div class="titleType">
      <span>牌照</span>
    </div>
    <el-select
      v-model="vehicleLicense"
      disabled
      value-key="name"
      class="elSelect"
      collapse-tags="collapse-tags"
      placeholder="请选择"  style="width: 55%"
    >
      <el-option
        v-for="item in vehicleLicenseOptions"
        :key="item.name"
        :label="item.name"
        :value="item.value"
      >
      </el-option>
    </el-select>

  </div>
  <div class="lineBot"></div>
  <!--<div class="itemContent">
    <div class="titleType">
      <img class="startImg" src="@/assets/start.png" />
      <span>是否参与聚合</span>
    </div>
    <div class="isJoin">
      <van-radio-group v-model="isJoin" @change="isChange"  class="joinWrap">
        <van-radio :name="1" style="margin-right: 26px">
          参与
          <img
              slot="icon"
              slot-scope="props"
              :src="props.checked ? activeIcon : inactiveIcon"
          >
        </van-radio>
        <van-radio :name="0">
          不参与
          <img
              slot="icon"
              slot-scope="props"
              :src="props.checked ? activeIcon : inactiveIcon"
          >
        </van-radio>
      </van-radio-group>
    </div>
  </div>
  <div class="lineBot"></div>-->
  <div class="itemContent">
    <div class="titleType">
      <img class="startImg" src="@/assets/start.png" />
      <span>车辆状态</span>
    </div>
    <div class="isJoin">
      <van-radio-group v-model="vehicleStatus"  :class="{ 'disabled-tree': vehicleInfoDisabled || vehicleStatusDisabled }" :disabled="vehicleInfoDisabled || vehicleStatusDisabled" @change="isVehicleChange"  class="joinWrap">
        <van-radio :name="1" style="margin-right: 14px">
          启用
          <img
            slot="icon"
            slot-scope="props"
            :src="props.checked ? activeIcon : inactiveIcon"
          >
        </van-radio>
        <van-radio :name="2" style="margin-right: 14px">
          停用
          <img
            slot="icon"
            slot-scope="props"
            :src="props.checked ? activeIcon : inactiveIcon"
          >
        </van-radio>
        <van-radio :name="12" disabled>
          否-服务商停用
          <img
              slot="icon"
              slot-scope="props"
              :src="props.checked ? activeIcon : inactiveIcon"
          >
        </van-radio>
      </van-radio-group>
    </div>
  </div>
  <div class="itemContent">
    <div class="titleType">
      <img class="startImg" src="@/assets/start.png" />
      <span>有无投保救援职业责任险或货运险</span>
    </div>
    <div class="isJoin">
      <van-radio-group v-model="hasLiabilityInsurance" @change="isChange" :disabled="disabledShow" class="joinWrap">
        <van-radio :name="1" style="margin-right: 26px">
          有
          <img
            slot="icon"
            slot-scope="props"
            :src="props.checked ? activeIcon : inactiveIcon"
          >
        </van-radio>
        <van-radio :name="0">
          无
          <img
            slot="icon"
            slot-scope="props"
            :src="props.checked ? activeIcon : inactiveIcon"
          >
        </van-radio>
      </van-radio-group>
    </div>
  </div>
  <div class="item_content_btn" v-if="[2,3].includes(this.liabilityInsuranceAudit)">
    <span @click="goContinueInsurance">续保更新</span>
  </div>
  <span style="color: red">如有投保，选“有”，未投保选“无”，不必上传交强险或者商业险等其他保单</span>
  <div class="lineBot"></div>
  <template v-if="hasLiabilityInsurance == 1">
    <div class="itemContent">
      <div class="titleType">
        <img class="startImg" src="@/assets/start.png" />
        <span style="line-height: 20px">请上传救援职业责任险或货运险保单PDF或者关键信息页截图</span>
      </div>
      <van-uploader
        v-model="insurancePictureFiles"
        :after-read="insurancePictureFilesHandler"
        :disabled="disabledShow"
        :deletable="!disabledShow"
        max-count="1"
        :preview-size="54"
        @click-preview="clickPreview"
      />
    </div>
    <div class="lineBot"></div>
    <div class="itemContent">
      <div class="titleType">
        <img class="startImg" src="@/assets/start.png" />
        <span>承保保司</span>
      </div>
      <el-select
        v-model="insuranceCorp"
        value-key="name"
        class="elSelect"
        collapse-tags="collapse-tags"
        :disabled="disabledShow"
        placeholder="请选择"  style="width: 55%"
      >
        <el-option
          v-for="item in insuranceOptions"
          :key="item.name"
          :label="item.name"
          :value="item.value"
        >
        </el-option>
      </el-select>
    </div>
    <div class="lineBot"></div>
    <div class="itemContent">
      <div class="titleType">
        <img class="startImg" src="@/assets/start.png" />
        <span>保险有效期</span>
      </div>
      <el-input style="width: 55%" readonly @focus="showDateHandler"  v-model="dateVal"  placeholder="请选择发布日期" :class="{'customSel':true,'customInput':true , 'has-value': dateVal }" >
        <template #suffix>
          <i
            v-if="dateVal && !disabledShow"
            class="el-icon-circle-close el-input__icon"
            @click="dateVal = ''"
          ></i>
        </template>
      </el-input>
    </div>
    <div class="lineBot" v-if="permissonList?.includes('hasInsuranceAudit')"></div>
    <div class="itemContent" v-if="permissonList?.includes('hasInsuranceAudit')">
      <div class="titleType">
        <img class="startImg" src="@/assets/start.png" />
        <span>保费</span>
      </div>
      <van-field
          type="number"
          class="vanIpt"
          v-model="liabilityInsuranceAmount"
          input-align="right"
      >
        <template slot="right-icon" >
          <span style="white-space: nowrap;">元</span>
        </template>
      </van-field>
    </div>
    <div class="lineBot" v-if="permissonList?.includes('hasInsuranceAudit')"></div>
    <div class="itemContent" v-if="permissonList?.includes('hasInsuranceAudit')">
      <div class="titleType">
        <img class="startImg" src="@/assets/start.png" />
        <span>保额</span>
      </div>
      <div style="display:flex;align-items: center;justify-content: flex-end">
        <el-select
            v-model="liabilityInsuranceQuota"
            value-key="name"
            class="elSelect"
            collapse-tags="collapse-tags"
            placeholder="请选择"  style="width: 55%"
        >
          <el-option
              v-for="item in liabilityQuotaOptions"
              :key="item.value"
              :label="item.value"
              :value="item.value"
          >
          </el-option>
        </el-select><span style="margin-right: 16px;opacity: .5;">万元</span>
      </div>
<!--      <van-field
          type="number"
          class="vanIpt"
          v-model="liabilityInsuranceQuota"
          input-align="right"
      >
        <template slot="right-icon" >
          <span style="white-space: nowrap;">万元 </span>
        </template>
      </van-field>-->
    </div>

    <!--    <div class="lineBot"></div>
    <div class="itemContent">
      <div class="titleType">
        <img class="startImg" src="@/assets/start.png" />
        <span>保单号(救援)</span>
      </div>
      <van-field
          class="vanIpt"
          style="width: 72%"
          v-model="insuranceCode"
          input-align="right"
      >  </van-field>
    </div>
    <div class="lineBot"></div>
    <div class="itemContent">
      <div class="titleType"> <span>保单号(中道物流)</span> </div>
      <van-field
          class="vanIpt"
          style="width: 65%"
          v-model="insuranceCodeZd"
          input-align="right"
      >  </van-field>
    </div>
    <div class="lineBot"></div>-->
  </template>
  <div class="itemContent">
    <div class="titleType">
      <img class="startImg" src="@/assets/start.png" />
      <span>选择服务种类</span>
    </div>
  </div>
  <div class="serviceType">
    <el-tree
      show-checkbox
      node-key="id"
      ref="tree"
      :highlight-current="true"
      :expand-on-click-node="false"
      :class="{ 'disabled-tree': vehicleInfoDisabled }"
      :data="supplierServiceList"
      :props="defaultProps">
    </el-tree>
      <!--<div class="trailerService" v-for="(item,index) in supplierServiceList" :key="index">
        <div class="serviceline"  @click="loadAll(index)">
          <img  :ref="'serviceline' + index" :src="imageUrl" style="width: 20px;height: 15px" >
          <span  class="service">{{ item.name }}:</span>
          <span class="line"></span>
        </div>
        <div :ref="'checkboxGroup' + index"  class="checkbox-group">
          <van-checkbox-group  v-model="serviceIds" v-for="(item2,index2) in item.children" :key="index2" class="radioWrap">
            <van-checkbox class="item" :name="item2.id">{{item2.name }}</van-checkbox>
          </van-checkbox-group>
        </div>
      </div>-->
  </div>
  <two-common-btn class="btn" @cancelClick="back" @submitClick="submitBtn" />
  <van-calendar v-model="showDatePicker"  :min-date="minDate"
                :max-date="maxDate" type="range" @confirm="onConfirm" />

</div>
  <van-popup ref="success"  v-model="approvalDialogShow">
    <div class="pop_wrap">
      <div class="pop_title">车辆提交审批</div>
      <div class="pop_content">
        <div class="iptWrap" v-if="vehicleInfoChange">
          <div>车辆和服务备注</div>
          <el-input placeholder="请输入车辆和服务备注" type="textarea" show-word-limit maxlength="200"
                    v-model="approvalForm.serviceRemark"></el-input>
        </div>
        <div  class="iptWrap" v-if="insuranceChange">
          <div>保单备注</div>
          <el-input placeholder="请输入保单备注" type="textarea" show-word-limit maxlength="200"
                    v-model="approvalForm.insuranceRemark"></el-input>
        </div>
      </div>
      <div class="tip_button_wrap">
        <div class="continue close" @click="closeApproval">取消</div>
        <div class="continue" :class="{'loading': loading}" @click="submitApprovalHandle">提交审批</div>
      </div>
    </div>
  </van-popup>

</div>
</template>

<script>
  // uploadImage
  import {Dialog, ImagePreview} from "vant";
  import {formatDate1} from "@/utils/common"
import {myMixins} from "@/utils/myMixins"
import {vehicleTypeList,saveVehicle,getInfoById,supplierServiceTree, uploadImage, ocrHandler,
  userOperationPermissions,saveSupplierApproval,preJudgeVirtualVehicle as preJudgeVirtualVehicleApi} from "@/api/mine"
import TwoCommonBtn from "@/components/twoBtnCommon.vue"
import CellGroup from "@/components/cellGroup.vue";
export default {
  name: "vehicleAdd",
  mixins:[myMixins],
  data(){
    return{
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      minDate: new Date(1970, 0, 1),  // 设置最小可选日期（1970年1月1日）
      maxDate: new Date(2099, 11, 31), // 设置最大可选日期（2099年12月31日）
      checkList: [],
      virtualVehicle: '',
      potentialFlag: new URLSearchParams(window.location.search).get('potentialFlag') || '',
      vehicleStatus: new URLSearchParams(window.location.search).get('potentialFlag') === '1' ? 2 : '',
      showDatePicker: false,
      dateVal: '',
      trailerService: '',//拖车服务
      isJoin:'',//是否参与
      hasLiabilityInsurance: '',   // 有无责任险
      liabilityInsuranceAudit: '',
      activeIcon: require('@/assets/check.png'),
      inactiveIcon: require('@/assets/uncheck.png'),
      // result: [],
      checked: true,
      carNum:"",//车牌号
      typeList:[],//车辆类型列表
      selectedOption:[],//车辆类型
      id:'',//车辆Id
      supplierId:'',//服务商Id
      serviceIds:[],//车辆服务种类,
      supplierServiceList:[],
      oldSupplierServiceList:[],
      show:false,
      imageUrl: require('@/assets/arr_right.png'),
      cameraGuideType: 'front',  // 当前拍摄槽位 front/back/car
      vehicleLicenseFrontList: [],
      vehicleLicenseBackList: [],
      vehicleLicenseCarPhotoList: [],
      vehicleFrontPhotoList: [],
      insurancePictureFiles: [],
      vehicleLicenseFront: '',  // 行驶证首页
      vehicleLicenseBack: '',   // 行驶证副页
      vehicleLicenseCarPhoto: '',  // 行驶证车辆照片
      vehicleFrontPhoto: '',    // 车头照
      insurancePicturePhoto: '',    // 保单照片
      vehicleLicenseInfo: {},
      vehicleLicenseBackOcrFlag: false,   // 行驶证副页 修改时默认不需要 ocr识别
      isMultiple: false,     // 是否支持多选
      virtualVehicleLocked: false, // 车辆属性锁定（OCR所有人命中服务商信息时锁定为自有车辆）
      virtualVehicleMatchRole: '', // 车辆属性自动判定命中的匹配角色
      matchRoleExpand: false,      // 匹配角色面板展开状态
      vehicleLicense:'',//牌照
      vehicleFrontLicensePlate:'',//车头照车牌号码
      insuranceCorp: '',
      auditStatus: '',
      permissonList:[],
      vehicleTypes:[{
        name: '小修车',
        value: 1
      },{
        name: '一般平板车',
        value: 2
      },{
        name: '全落地平板车',
        value: 3
      },{
        name: '地库车',
        value: 4
      },
        {
          name:'牵引车',
          value: 5 },
        {
          name:'随车吊平板车',
          value:6},
        {
          name:'充电车',
          value: 7 },
        {
          name:'吊车',
          value: 8 },
        {
          name:'公车',
          value: 9 },
        {
          name:'箱式拖车',
          value: 10 },
        {
          name:'斜落一体平板车',
          value: 11 },

      ],
      vehicleLicenseOptions: [{
        name: '蓝牌',
        value: 1
      }, {
        name: '黄牌',
        value: 2
      }, {
        name: '绿牌',
        value: 3
      }, {
        name: '临牌',
        value: 4
      }, {
        name: '其他',
        value: 5
      }, {
        name: '黄绿牌',
        value: 6
      }],
      virtualVehicleOptions: [{
        name: '自有车辆',
        value: 1
      }, {
        name: '挂靠车辆',
        value: 2
      }, {
        name: '虚拟车辆',
        value: 3
      }, {
        name: '借入车辆',
        value: 4
      }],
      insuranceOptions: [{
        name: '太平洋',
        value: 1
      }, {
        name: '人保',
        value: 2
      }, {
        name: '平安',
        value: 3
      }, {
        name: '中华联合',
        value: 4
      }, {
        name: '大地',
        value: 5
      }, {
        name: '阳光',
        value: 6
      }, {
        name: '太平',
        value: 7
      }, {
        name: '人寿',
        value: 8
      }, {
        name: '永安',
        value: 9
      }, {
        name: '华安',
        value: 10
      }, {
        name: '申能',
        value: 11
      }, {
        name: '大家',
        value: 12
      }, {
        name: '富德',
        value: 13
      }, {
        name: '其他',
        value: 14
      }],
      liabilityQuotaOptions:[{value:10},{value:20},{value:30},{value:50},{value:70},{value:80},{value:100},{value:200}],
      approvalForm:{
        type:2,
        supplierId:'',
        vehicleId:'',
        serviceChange:null,
        serviceRemark:'',
        insuranceChange:null,
        insuranceRemark:'',
        vehicleOtherChange:null,
        vehicleOtherRemark:'',
      },
      originData:{},//记录更改之前的数据
      changedFields: [], // 用于存储变更过的字段
      approvalDialogShow:false,
      vehicleInfoChange:false,
      insuranceChange:false,
      loading: false,
      liabilityInsuranceAmount:'',
      liabilityInsuranceQuota:'',
      insuranceCode:'',
      insuranceCodeZd:'',
    }
  },
  computed: {
    vehicleInfoDisabled() {
      return [1,2].includes(this.auditStatus)
    },
    disabledShow() {
      if (this.id) {
        return !this.permissonList.includes('hasInsuranceAudit') && [2,3].includes(this.liabilityInsuranceAudit)
      } else {
        return false
      }
    },
    vehicleStatusDisabled() {
      return !this.id && this.potentialFlag === '1';
    }
  },
  watch:{
    selectedOption(newVal){
      if(newVal == 4){
        this.isMultiple = true
        this.vehicleTypes[2].disabled=true
        this.vehicleTypes[5].disabled=true
        this.vehicleTypes[6].disabled=true
        this.vehicleTypes[7].disabled=true
        this.vehicleTypes[8].disabled=true
        this.vehicleTypes[9].disabled=true
        this.vehicleTypes[10].disabled=true
      }else{
        this.isMultiple = false
        this.vehicleTypes[2].disabled=false
        this.vehicleTypes[5].disabled=false
        this.vehicleTypes[6].disabled=false
        this.vehicleTypes[7].disabled=false
        this.vehicleTypes[8].disabled=false
        this.vehicleTypes[9].disabled=false
        this.vehicleTypes[10].disabled=false
      }
      if (newVal == 1 || newVal == 7 || newVal == 9){
        let arr = []
        this.supplierServiceList.forEach((item)=>{
          if(!(item.name == '拖车服务' || item.name == '大型车救援')){
            arr.push(item)
          }
        })
        this.supplierServiceList = arr
      }else{
        this.supplierServiceList = this.oldSupplierServiceList
      }
      this.setDefault();
    },
  },
  async mounted() {
    await this.initPage()
    this.hasInited = true // 标记首次初始化完成（keep-alive 下 activated 据此判断再次进入需重新初始化）
  },
  activated() {
    // 从拍摄页返回：取回拍照结果/降级信息，保留表单不重新初始化
    const cam = this.$store.state.camera
    if (cam.result || cam.fallback) {
      const { result, fallback } = cam
      this.$store.commit('camera/clear')
      if (result) {
        this.cameraGuideType = result.type
        this.onCameraConfirm(result)
      } else {
        this.cameraGuideType = fallback.type
        this.handleCameraFail(fallback.error)
      }
      return
    }
    // 从车辆管理等其他页面再次进入（keep-alive 缓存复用）：按当前路由重新初始化
    if (this.hasInited) {
      this.initPage()
    }
  },
  methods:{
    async initPage() {
      // 整体重置为初始 data（keep-alive 缓存复用时清空上一次的新增/修改数据，含 watcher 改过的 vehicleTypes.disabled），再按当前模式初始化
      Object.assign(this.$data, this.$options.data.call(this, this))
      this.id=this.$route.params?.id
      this.approvalForm.supplierId=this.$route.params?.supplierId
      const urlParams = new URLSearchParams(window.location.search);
      const rawId = this.$route.query.supplierId || urlParams.get('supplierId');
      this.supplierId = rawId ? Number(rawId) : '';
      await this.getSupplierServiceTree();
      await this.getTypeList();
      if( this.id){
        await this.vehicleInfo()
      }else{
        // 新增：清空 el-tree 勾选状态（缓存复用时可能残留上一辆车的服务种类勾选）
        this.$nextTick(() => {
          this.$refs.tree && this.$refs.tree.setCheckedKeys([])
        })
        this.originData={
          vehicleType:'',
          vehicleStatus:'',
          virtualVehicle:'',
          serviceIds:[],
          hasLiabilityInsurance:'',
          insuranceCorp:'',
          liabilityInsuranceStartTime:'',
          liabilityInsuranceEndTime:'',
          insurancePicturePhoto:''
        }
        // 复制新增：从 query 预填类别/属性/服务种类（id 为空，提交仍走新增分支）
        this.prefillFromQuery()
      }
    },
    // 复制新增：从 query 解析并回填车辆类别/属性/服务种类 3 项，不调任何接口；
    // 字段缺失或为空时等价普通新增兜底；其余字段（照片/OCR/责任险/保单/车辆状态）保持重置后的空值
    // 注意：SPA 内 $router.push 跳转时 $route.query 保留原始类型（copyFlag 为数字 1），
    // 整页加载/刷新时则为字符串 "1"，此处统一 String() 兼容两种来源
    prefillFromQuery() {
      const urlParams = new URLSearchParams(window.location.search);
      const copyFlag = this.$route.query.copyFlag || urlParams.get('copyFlag');
      if (String(copyFlag) !== '1') {
        return
      }
      const vehicleType = this.$route.query.vehicleType || urlParams.get('vehicleType');
      const virtualVehicle = this.$route.query.virtualVehicle || urlParams.get('virtualVehicle');
      const serviceIds = this.$route.query.serviceIds || urlParams.get('serviceIds');
      if (vehicleType) {
        this.selectedOption = String(vehicleType).split(',').map(Number)
      }
      if (virtualVehicle) {
        this.virtualVehicle = Number(virtualVehicle)
      }
      // selectedOption 赋值触发 watch（类别 disabled 重置、小修车过滤拖车服务节点、setDefault），
      // 服务树勾选必须在 watch 过滤之后执行，$nextTick 回调注册顺序保证清空勾选 → watch 过滤 → 预填勾选
      this.$nextTick(() => {
        if (serviceIds) {
          this.$refs.tree && this.$refs.tree.setCheckedKeys(String(serviceIds).split(',').map(Number))
        }
      })
    },
    showDateHandler() {
      if( this.id ) {   // 修改
        if( this.permissonList.includes('hasInsuranceAudit') ) {
          this.showDatePicker = true
        }
      } else {
        this.showDatePicker = true
      }

    },
    async getPermissions(){
      let res = await userOperationPermissions();
      this.permissonList = res.data
    },
    goContinueInsurance() {
      this.$router.push({
        name:'continueInsurance',
        params:{
          id: this.id
        }
      })
    },
    formatDate(date) {
      return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
    },
    onConfirm(date) {
      const [start, end] = date;
      this.showDatePicker = false;
      this.dateVal = `${this.formatDate(start)} - ${this.formatDate(end)}`;
      console.log('this.dateVal',this.dateVal)
      let timeObj = this.formatDateTimeRange(this.dateVal)
      console.log('timeObj',timeObj)

    },
    formatDateTimeRange(str) {
      const [startStr, endStr] = str.split(' - ').map(s => s.trim());
      const startDate = new Date(startStr);
      const startTime = `${startDate.getFullYear()}-${(startDate.getMonth() + 1).toString().padStart(2, '0')}-${startDate.getDate().toString().padStart(2, '0')} 00:00:00`;
      const endDate = new Date(endStr);
      const endTime = `${endDate.getFullYear()}-${(endDate.getMonth() + 1).toString().padStart(2, '0')}-${endDate.getDate().toString().padStart(2, '0')} 23:59:59`;
      return {
        startTime,
        endTime
      };
    },
    setDefault() {
      if( this.vehicleLicenseInfo?.vehicleType?.includes('小型') || this.vehicleLicenseInfo?.vehicleType?.includes('微型') || this.vehicleLicenseInfo?.vehicleType?.includes('普通') || this.vehicleLicenseInfo?.vehicleType?.includes('摩托') ) {
        this.vehicleTypes.map(item => {
          if( item.value == 1 || item.value == 9 ) {
            item.disabled = false;
          } else {
            item.disabled = true;
          }
        })
        this.$forceUpdate();
      } else if( this.vehicleLicenseInfo?.vehicleType?.includes('载货') || this.vehicleLicenseInfo?.vehicleType?.includes('中型') || this.vehicleLicenseInfo?.vehicleType?.includes('重型')) {
        this.vehicleTypes.map(item => {
          if( item.value == 1 || item.value == 9 ) {
            item.disabled = true;
          } else {
            item.disabled = false;
          }
        })
      } else {
        this.vehicleTypes.map(item => {
          item.disabled = false;
        })
        this.$forceUpdate();
      }
    },
    getVehicleLicense(color) {
      color = color || ''
      if( color == '蓝' ) {
        this.vehicleLicense = 1
      } else if(color == '黄') {
        this.vehicleLicense = 2
      } else if(color == '临牌') {
        this.vehicleLicense = 4
      } else if(color.includes('黄绿')) {
        this.vehicleLicense = 6
      } else if(color.includes('绿')) {
        this.vehicleLicense = 3
      } else {
        this.vehicleLicense = 5
      }
    },
    onOversize() {
      this.$toast(`文件大小不能超过5M`)
    },
    // 将 base64 dataURL 转为 Blob，用于 APP WebView 只返回 content 的场景
    dataURLToBlob(dataURL) {
      const arr = dataURL.split(',');
      const mime = arr[0].match(/:(.*?);/)[1];
      const bstr = atob(arr[1]);
      let n = bstr.length;
      const u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new Blob([u8arr], { type: mime });
    },
    blobToDataURL(blob) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = (e) => resolve(e.target.result);
        reader.onerror = () => reject(new Error('读取压缩图片失败'));
        reader.readAsDataURL(blob);
      });
    },
    compressImage(file, maxSize = 5 * 1024 * 1024) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = (e) => {
          const img = new Image();
          img.onload = () => {
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            const originWidth = img.width;
            const originHeight = img.height;

            const tryQuality = (quality = 0.9) => {
              canvas.width = originWidth;
              canvas.height = originHeight;
              ctx.clearRect(0, 0, originWidth, originHeight);
              ctx.drawImage(img, 0, 0, originWidth, originHeight);
              canvas.toBlob((blob) => {
                if (!blob) return reject(new Error('压缩失败'));
                if (blob.size <= maxSize || quality <= 0.1) {
                  if (blob.size <= maxSize) {
                    resolve(blob);
                  } else {
                    tryResolution();
                  }
                  return;
                }
                tryQuality(quality - 0.1);
              }, 'image/jpeg', quality);
            };

            const tryResolution = (scale = 0.9, quality = 0.8) => {
              const width = Math.floor(originWidth * scale);
              const height = Math.floor(originHeight * scale);
              canvas.width = width;
              canvas.height = height;
              ctx.clearRect(0, 0, width, height);
              ctx.drawImage(img, 0, 0, width, height);
              canvas.toBlob((blob) => {
                if (!blob) return reject(new Error('压缩失败'));
                if (blob.size <= maxSize || scale <= 0.1) {
                  if (blob.size <= maxSize) {
                    resolve(blob);
                  } else {
                    reject(new Error('超过5M'));
                  }
                  return;
                }
                tryResolution(scale - 0.1, quality);
              }, 'image/jpeg', quality);
            };

            tryQuality();
          };
          img.onerror = () => reject(new Error('图片加载失败'));
          img.src = e.target.result;
        };
        reader.onerror = () => reject(new Error('文件读取失败'));
        reader.readAsDataURL(file);
      });
    },
    async compressFileItem(fileItem, maxSize = 5 * 1024 * 1024) {
      let rawFile = fileItem?.file;
      const rawContent = fileItem?.content;

      // 打印可序列化的基础信息，VConsole 中对象会显示为空，但 name/size/type 能看到
      console.log('rawFile info:', {
        name: rawFile?.name,
        size: rawFile?.size,
        type: rawFile?.type,
        constructor: rawFile?.constructor?.name
      });
      console.log('rawContent prefix:', typeof rawContent === 'string' ? rawContent.slice(0, 60) : rawContent);

      // 部分 APP WebView 返回的文件对象异常或为空，但 content 是 base64，此时用 content 兜底
      if ((!rawFile || !(rawFile instanceof File) || rawFile.size === 0) &&
          typeof rawContent === 'string' && rawContent.startsWith('data:')) {
        try {
          const blob = this.dataURLToBlob(rawContent);
          const ext = blob.type === 'image/png' ? 'png' : 'jpg';
          rawFile = new File([blob], `upload_${Date.now()}.${ext}`, { type: blob.type || 'image/jpeg' });
          console.log('fallback file from content, size:', rawFile.size);
        } catch (e) {
          console.error('content to file error:', e);
          throw new Error('文件解析失败，请重新上传');
        }
      }

      if (!rawFile) {
        throw new Error('未获取到文件，请重新上传');
      }

      if (rawFile.size <= maxSize) return rawFile;
      const blob = await this.compressImage(rawFile, maxSize);
      if (blob.size > maxSize) {
        throw new Error('超过5M');
      }
      const fileName = (rawFile.name || 'image').replace(/\.[^.]+$/, '') + '.jpg';
      const compressedFile = new File([blob], fileName, { type: 'image/jpeg' });
      fileItem.file = compressedFile;
      fileItem.size = compressedFile.size;
      fileItem.content = await this.blobToDataURL(blob);
      const mb1 = (compressedFile.size / 1024 / 1024).toFixed(2);
      console.log(`压缩后为：${mb1}M`)
      return compressedFile;
    },
    isCameraSupported() {   // 是否支持 getUserMedia（不支持则降级系统选择器）
      return !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) && window.isSecureContext !== false
    },
    onLicenseSlotClick(type) {   // 行驶证三槽位点击：已有图片→预览，无图片→跳拍摄页（不支持相机则降级系统选择器）
      this.cameraGuideType = type
      const listMap = {
        front: 'vehicleLicenseFrontList',
        back: 'vehicleLicenseBackList',
        car: 'vehicleLicenseCarPhotoList'
      }
      const item = (this[listMap[type]] || [])[0]
      const src = item && (item.url || item.content)
      if (src) {
        // 已有图片：预览（删除按钮在拦截层之上，可删除后重拍）
        ImagePreview({ images: [src], closeable: true })
        return
      }
      // 无图片：拍照
      if (!this.isCameraSupported()) {
        // 不支持 getUserMedia（如 iOS 微信、非 HTTPS、老 WebView）：直接调系统选择器
        this.triggerNativeUpload(type)
        return
      }
      this.$router.push({ name: 'cameraGuide', query: { type } })
    },
    isCameraPermissionError(e) {   // 是否为相机权限类错误
      return !!(e && (e.name === 'NotAllowedError' || e.name === 'SecurityError' || e.name === 'PermissionDeniedError'))
    },
    handleCameraFail(e) {   // 相机不可用统一处理：权限类弹确认框，其他异常提示后由用户点击触发相册（保证点击手势有效）
      if (this.isCameraPermissionError(e)) {
        Dialog.confirm({
          title: '提示',
          message: '相机权限未开启，无法使用拍摄引导。是否重新尝试开启相机？',
          confirmButtonText: '重新尝试',
          cancelButtonText: '从相册选择',
          confirmButtonColor: '#354D93',
        }).then(() => {
          // 重新走前置探测，探测通过才打开拍摄引导
          this.onLicenseSlotClick(this.cameraGuideType)
        }).catch(() => {
          this.triggerNativeUpload(this.cameraGuideType)
        })
      } else {
        Dialog.alert({
          title: '提示',
          message: '当前设备无法调用相机拍摄，请从相册选择照片上传。',
          confirmButtonText: '从相册选择',
          confirmButtonColor: '#354D93',
        }).then(() => {
          this.triggerNativeUpload(this.cameraGuideType)
        })
      }
    },
    triggerNativeUpload(type) {  // 主动触发对应 uploader 的原生文件选择
      const refMap = { front: 'licenseFrontUploader', back: 'licenseBackUploader', car: 'licenseCarUploader' }
      this.$nextTick(() => {
        const uploader = this.$refs[refMap[type]]
        const input = uploader && uploader.$el && uploader.$el.querySelector('.van-uploader__input')
        if (input) input.click()
      })
    },
    onCameraConfirm({ blob, dataURL }) {   // 拍摄确认：构造 {file, content} 走现有压缩→上传→OCR 链路
      const type = this.cameraGuideType
      const file = new File([blob], `vehicle_license_${type}_${Date.now()}.jpg`, { type: 'image/jpeg' })
      const fileItem = { file, content: dataURL }
      const handlerMap = {
        front: 'vehicleLicenseFrontHandler',
        back: 'vehicleLicenseBackHandler',
        car: 'vehicleLicenseCarHandler'
      }
      const listMap = {
        front: 'vehicleLicenseFrontList',
        back: 'vehicleLicenseBackList',
        car: 'vehicleLicenseCarPhotoList'
      }
      // 写回 uploader 的 v-model 列表，使槽位缩略图回显
      this[listMap[type]] = [fileItem]
      this[handlerMap[type]](fileItem)
    },
    async vehicleLicenseFrontHandler(file) {    // 上传 行驶证首页
      console.log('file',file)
      try {
        const uploadFile = await this.compressFileItem(file);
        console.log('uploadFile',uploadFile)
        if (uploadFile.size > 5 * 1024 * 1024) {
          this.onOversize();
          return;
        }
        const formData = new FormData();
        formData.append("file" , uploadFile);
        let res = await uploadImage(formData)
        this.vehicleLicenseFront = res.data;
        await this.vehicleOcrHandler();
      } catch (e) {
        console.error('upload compress error:', e);
        if (e && e.message === '超过5M') {
          this.onOversize();
        } else {
          this.$toast(e && e.message ? e.message : '上传失败，请重试');
        }
      }
    },
    async vehicleLicenseBackHandler(file) {     // 上传 行驶证副页
      try {
        this.vehicleLicenseBackOcrFlag = true;
        const uploadFile = await this.compressFileItem(file);
        if (uploadFile.size > 5 * 1024 * 1024) {
          this.onOversize();
          return;
        }
        const formData = new FormData();
        formData.append("file" , uploadFile);
        let res = await uploadImage(formData);
        this.vehicleLicenseBack = res.data;
        await this.vehicleBackOcrHandler();
      } catch (e) {
        console.error('upload compress error:', e);
        if (e && e.message === '超过5M') {
          this.onOversize();
        } else {
          this.$toast(e && e.message ? e.message : '上传失败，请重试');
        }
      }
    },
    async vehicleLicenseCarHandler(file) {     // 上传 行驶证车辆照片
      try {
        const uploadFile = await this.compressFileItem(file);
        if (uploadFile.size > 5 * 1024 * 1024) {
          this.onOversize();
          return;
        }
        const formData = new FormData();
        formData.append("file" , uploadFile);
        let res = await uploadImage(formData);
        this.vehicleLicenseCarPhoto = res.data;
      } catch (e) {
        console.error('upload compress error:', e);
        if (e && e.message === '超过5M') {
          this.onOversize();
        } else {
          this.$toast(e && e.message ? e.message : '上传失败，请重试');
        }
      }
    },
    async vehicleFrontPhotoHandler(file) {     // 上传 车头照
      try {
        const uploadFile = await this.compressFileItem(file);
        if (uploadFile.size > 5 * 1024 * 1024) {
          this.onOversize();
          return;
        }
        const formData = new FormData();
        formData.append("file" , uploadFile);
        let res = await uploadImage(formData);
        this.vehicleFrontPhoto = res.data;
        await this.ocrCarFrontHandler()
      } catch (e) {
        console.error('upload compress error:', e);
        if (e && e.message === '超过5M') {
          this.onOversize();
        } else {
          this.$toast(e && e.message ? e.message : '上传失败，请重试');
        }
      }
    },
    vehicleLicenseFrontDelete() {              // 删除 行驶证首页
      this.vehicleLicenseFront = '';
    },
    vehicleLicenseBackDelete() {               // 删除 行驶证副页
      this.vehicleLicenseBack = '';
      this.vehicleLicenseBackOcrFlag = false;
    },
    vehicleLicenseCarPhotoDelete() {           // 删除 行驶证车辆照片
      this.vehicleLicenseCarPhoto = '';
    },
    vehicleFrontPhotoDelete() {                // 删除 车头照
      this.vehicleFrontPhoto = '';
    },
    clickPreview(){
      console.log(' this.insurancePicturePhoto', this.insurancePicturePhoto)
      if(this.insurancePicturePhoto && this.insurancePicturePhoto.indexOf('.pdf') !== -1){
        let url=this.insurancePicturePhoto?.split(',')[0]
        window.open(url.replace("http://", "https://"))
      }
    },
    async insurancePictureFilesHandler(file) {
      const formData = new FormData();
      formData.append("file" , file.file);
      let res = await uploadImage(formData);
      this.insurancePicturePhoto = res.data;
      console.log('insurancePictureFilesHandler',this.insurancePictureFiles)
    },
    async ocrCarFrontHandler() {     // 车辆正面 orc 识别
      let res = await ocrHandler({
        ocrType: 10,
        imageUrl: this.vehicleFrontPhoto,
        cardSide: 'FRONT'
      });
      this.vehicleFrontLicensePlate=res.data?.number
      this.getVehicleLicense(res.data?.color)
    },
    async vehicleOcrHandler() {     // 行驶证首页 ocr 识别
      this.vehicleLicenseInfo.licensePlateNumber = '';
      this.vehicleLicenseInfo.vehicleType = '';
      this.vehicleLicenseInfo.owner = '';
      this.vehicleLicenseInfo.address = '';
      this.vehicleLicenseInfo.useNature = '';
      this.vehicleLicenseInfo.model = '';
      this.vehicleLicenseInfo.vinCode = '';
      this.vehicleLicenseInfo.engineNumber = '';
      this.vehicleLicenseInfo.registrationDate = '';
      this.vehicleLicenseInfo.issueDate = '';
      this.vehicleLicenseInfo.issueAuthority = '';
      let res = await ocrHandler({
        ocrType: 3,
        imageUrl: this.vehicleLicenseFront,
        cardSide: 'FRONT'
      })
      if ( res?.data?.frontInfo ) {
        let frontInfo = res?.data?.frontInfo;
        this.carNum = frontInfo?.plateNo;
        this.vehicleLicenseInfo.licensePlateNumber = frontInfo?.plateNo;
        this.vehicleLicenseInfo.vehicleType = frontInfo?.vehicleType;
        this.vehicleLicenseInfo.owner = frontInfo?.owner;
        // 行驶证所有人识别成功后，预判车辆属性（命中服务商信息则锁定为自有车辆）
        this.preJudgeVirtualVehicle();
        this.vehicleLicenseInfo.address = frontInfo?.address;
        this.vehicleLicenseInfo.useNature = frontInfo?.useCharacter;
        this.vehicleLicenseInfo.model = frontInfo?.model;
        this.vehicleLicenseInfo.vinCode = String(frontInfo?.vin || '').toUpperCase().replace(/O/g, '0');
        this.vehicleLicenseInfo.engineNumber = frontInfo?.engineNo;
        this.vehicleLicenseInfo.registrationDate = frontInfo?.registerDate;
        this.vehicleLicenseInfo.issueDate = frontInfo?.issueDate;
        this.vehicleLicenseInfo.issueAuthority = frontInfo?.seal;
        this.setDefault();
        this.checkDisabledItems();
      }
    },
    checkDisabledItems() {
      let _arr = [];
      this.selectedOption.map(item => {
        let _tempArr = this.vehicleTypes.filter(_item => _item.disabled && _item.value == item);
        _arr = [..._arr, ..._tempArr]
      })
      if (_arr.length > 0) {
        this.$toast(`车辆类别数据不合法：${_arr.map(item => item.name).join('、')}`)
        return false
      }
      return  true
    },
    // 车辆属性预判：行驶证所有人与车辆归属服务商的名称/法人/关联人员比对，命中自有则锁定选择器
    async preJudgeVirtualVehicle() {
      this.virtualVehicleLocked = false;
      this.virtualVehicleMatchRole = '';
      const owner = (this.vehicleLicenseInfo.owner || '').trim();
      if (!owner) {
        return;
      }
      try {
        const res = await preJudgeVirtualVehicleApi({
          owner,
          supplierId: this.supplierId || undefined  // 车辆归属服务商ID，自录场景为空由后端取当前用户服务商
        });
        if (res?.data?.locked) {
          this.virtualVehicleLocked = true;
          this.virtualVehicleMatchRole = res.data.matchRole || '';
          this.virtualVehicle = 1;
        }
      } catch (e) {
        // 预判失败不影响保存，选择器保持可编辑
      }
    },
    async vehicleBackOcrHandler() {     // 行驶证副页 ocr 识别
      this.vehicleLicenseInfo.recordNumber = '';
      this.vehicleLicenseInfo.passengerCapacity = '';
      this.vehicleLicenseInfo.totalWeight = '';
      this.vehicleLicenseInfo.curbWeight = '';
      this.vehicleLicenseInfo.permittedWeight = '';
      this.vehicleLicenseInfo.overallDimension = '';
      this.vehicleLicenseInfo.tractionWeight = '';
      this.vehicleLicenseInfo.backPlateNo = '';     // 行驶证副页 车牌号，仅用来判断 ocr 识别是否成功
      this.vehicleLicenseInfo.energySign = '';
      this.vehicleLicenseInfo.marks = ''
      let res = await ocrHandler({
        ocrType: 3,
        imageUrl: this.vehicleLicenseBack,
        cardSide: 'BACK'
      })
      if(res?.data?.backInfo) {
        let backInfo = res?.data?.backInfo;
        this.vehicleLicenseInfo.recordNumber = backInfo?.fileNo;
        this.vehicleLicenseInfo.passengerCapacity = backInfo?.allowNum;
        this.vehicleLicenseInfo.totalWeight = backInfo?.totalMass;
        this.vehicleLicenseInfo.curbWeight = backInfo?.curbWeight;
        this.vehicleLicenseInfo.permittedWeight = backInfo?.loadQuality;
        this.vehicleLicenseInfo.overallDimension = backInfo?.externalSize;
        this.vehicleLicenseInfo.tractionWeight = backInfo?.TotalQuasiMass;
        this.vehicleLicenseInfo.backPlateNo = backInfo?.plateNo;
        this.vehicleLicenseInfo.energySign = backInfo?.fuelType;
        this.vehicleLicenseInfo.marks = backInfo?.marks
      }
      console.log('this.vehicle', this.vehicleLicenseInfo)
    },
    loadAll(i){
      // console.log(i)
      this.show = !this.show
      const refName='checkboxGroup' + i;
      const element1 = this.$refs[refName]; // 通过动态属性名访问引用this.$refs.checkboxGroup.style.display = 'block';
      const refName1='serviceline' + i;
      const element = this.$refs[refName1];
      if(this.show){
        element1[0].style.display = 'block'
        element[0].src= require('@/assets/arr_bot.png')
      }else {
        element1[0].style.display = 'none'
        element[0].src= require('@/assets/arr_right.png')
      }
    },
    async getTypeList() {
        let result=await vehicleTypeList();
        this.typeList=[]
        if(result.code === 200){
          for (const key in result.data){
            // console.log("keys",result.data[key])
            this.typeList.push({name:result.data[key],disabled:false,value:(key+1)})
            // this.typeList.push(result.data[key])

          }
        }
    },
    async getSupplierServiceTree(){
      let res = await supplierServiceTree({ supplierId: this.supplierId });
      this.supplierServiceList=res.data
      this.oldSupplierServiceList=this.supplierServiceList
    },
    async vehicleInfo(){
      let res= await  getInfoById({
        vehicleId:this.id
      })
      let result=res.data;
      console.log("result",result)
      this.id=result.vehicleId
      this.approvalForm.vehicleId=this.id
      this.carNum=result.plateNumber
      this.isJoin=result.hasPolymerization.code
      this.selectedOption=result.vehicleType?.split(',').map((item)=>{
        return Number(item);
      });
      this.auditStatus = result.auditStatus;
      this.virtualVehicle = result.virtualVehicle;
      // 车辆属性溯源：编辑场景初始化匹配角色，已是自有车辆且命中角色时锁定选择器
      this.virtualVehicleMatchRole = result.virtualVehicleMatchRole || '';
      this.virtualVehicleLocked = !!(result.virtualVehicleMatchRole && result.virtualVehicle === 1);
      this.$refs.tree.setCheckedKeys(result.serviceIds)
      this.vehicleStatus = result.vehicleStatus
      this.vehicleLicenseFront = result.vehicleLicenseFront;
      this.vehicleLicenseBack = result.vehicleLicenseBack;
      this.vehicleFrontPhoto = result.vehicleFrontPhoto;
      this.insurancePicturePhoto = result.insurancePicturePhoto;
      this.vehicleLicenseInfo = result.vehicleLicenseInfo;
      this.vehicleLicenseCarPhoto = result.vehicleLicenseCarPhoto;
      this.vehicleLicense = result.vehicleLicense;
      this.vehicleFrontLicensePlate = result.vehicleFrontLicensePlate;
      this.hasLiabilityInsurance = result.hasLiabilityInsurance
      this.insuranceCorp = result.insuranceCorp;
      this.liabilityInsuranceAudit = result.liabilityInsuranceAudit
      if(this.insurancePicturePhoto) {
        this.insurancePictureFiles = [{url: this.insurancePicturePhoto?.split(',')[0]}]
      }
      console.log('this.insurancePictureFiles',this.insurancePictureFiles)
      if( this.vehicleLicenseFront ) {
        this.vehicleLicenseFrontList = [{ url : this.vehicleLicenseFront }];
      }
      if(this.vehicleLicenseBack) {
        this.vehicleLicenseBackList = [{ url : this.vehicleLicenseBack }];
      }
      if(this.vehicleFrontPhoto) {
        this.vehicleFrontPhotoList = [{ url : this.vehicleFrontPhoto }];
      }
      if(this.vehicleLicenseCarPhoto) {
        this.vehicleLicenseCarPhotoList = [{ url : this.vehicleLicenseCarPhoto }];
      }
      if(this.vehicleLicenseCarPhoto) {
        this.vehicleLicenseCarPhotoList = [{ url : this.vehicleLicenseCarPhoto }];
      }
      if( result.liabilityInsuranceEndTime && result.liabilityInsuranceStartTime ) {
        this.dateVal =  formatDate1(result.liabilityInsuranceStartTime) + ' - ' + formatDate1(result.liabilityInsuranceEndTime)
      }
      this.originData={
        vehicleType:result.vehicleType,
        vehicleStatus:result.vehicleStatus,
        virtualVehicle:result.virtualVehicle,
        serviceIds:result.serviceIds,
        hasLiabilityInsurance:result.hasLiabilityInsurance,
        insuranceCorp:result.insuranceCorp,
        liabilityInsuranceStartTime:result.liabilityInsuranceStartTime,
        liabilityInsuranceEndTime:result.liabilityInsuranceEndTime,
        insurancePicturePhoto:result.insurancePicturePhoto
      }
    },
    isChange(e){
      this.hasLiabilityInsurance=e
      if (e === 0) {
        Dialog.confirm({
          title: '提醒',
          message: '有救援职业责任险车辆会提升案件聚合能力和接单能力。',
          confirmButtonText: '我已知晓', // 确认按钮文字，默认为“确认”
          showCancelButton: false // 是否显示取消按钮，默认为 true。如果不需要取消按钮，可以设置为 false。
        })
        .then(() => { /* 确认后的操作 */ })
        .catch(() => { /* 取消后的操作 */ });
      }
    },
    isVehicleChange(e) {
      this.vehicleStatus=e
    },
/*    async submitAuditHandle(){//提交审核
      let urls=[]
      this.insurancePictureFiles?.forEach(item => urls.push(item.url))
      let time =this.dateVal ? this.formatDateTimeRange(this.dateVal) : ''
      // let time1=time.endTime?.split(' ')
      let newFormValue={
        vehicleStatus:this.vehicleStatus,
        virtualVehicle:this.virtualVehicle,
        serviceIds:this.$refs.tree.getCheckedKeys(true) || [],
        vehicleType:this.selectedOption?.join(',') || '',
        hasLiabilityInsurance:this.hasLiabilityInsurance,
        insuranceCorp:this.insuranceCorp,
        insurancePicturePhoto:urls?.join(','),
        // liabilityInsuranceStartTime:time.startTime ? time.startTime : '',
        liabilityInsuranceEndTime:time.endTime ? time.endTime  : '',
      }
      console.log('newFormValue',newFormValue)
      let oldFormValue={...this.originData,}
      console.log('oldFormValue',oldFormValue)

      this.compareObjects(newFormValue,oldFormValue);
      if( this.changedFields &&  this.changedFields.length>0){
        const arr1Set = new Set(this.changedFields);
        const change1=['vehicleStatus','virtualVehicle','vehicleType','serviceIds']
        const change2=['hasLiabilityInsurance','insurancePicturePhoto','insuranceCorp','liabilityInsuranceStartTime','liabilityInsuranceEndTime']
        const serviceChangeItems = change1.filter(item => arr1Set.has(item));
        console.log('serviceChangeItems',serviceChangeItems)
        if(serviceChangeItems?.length>0){
          this.vehicleInfoChange=true
          this.approvalForm.serviceChange={}
          change1.forEach(key => {
            this.approvalForm.serviceChange[key] = this[key];
            if(key=='serviceIds'){
              this.approvalForm.serviceChange[key]=this.$refs.tree.getCheckedKeys(true)
            }
            if(key=='vehicleType'){
              this.approvalForm.serviceChange[key]=this.selectedOption?.join(',') || ''
            }
          });
        }else {
          this.vehicleInfoChange=false
          this.approvalForm.serviceChange=null
        }
        const insuranceChangeItems = change2.filter(item => arr1Set.has(item));
        console.log('insuranceChangeItems',insuranceChangeItems)
        if(insuranceChangeItems?.length>0){
          this.insuranceChange=true
          this.approvalForm.insuranceChange={}
          change2.forEach(key => {
            this.approvalForm.insuranceChange[key] =this[key];
            let time =this.dateVal ? this.formatDateTimeRange(this.dateVal) : ''
            if(key=='liabilityInsuranceStartTime' && time && time.startTime){
              this.approvalForm.insuranceChange[key]=time.startTime
            }
            if(key=='liabilityInsuranceEndTime' && time && time.endTime){
              // let time1=time.endTime?.split(' ')
              this.approvalForm.insuranceChange[key]= time.endTime
            }
            if(key=='insurancePicturePhoto' && this.insurancePictureFiles?.length>0){
              let urls=[]
              this.insurancePictureFiles?.forEach(item => urls.push(item.url))
              this.approvalForm.insuranceChange[key]=urls?.join(',')
            }
          });
        }else {
          this.insuranceChange=false
          this.approvalForm.insuranceChange=null
        }
      }
      if((this.vehicleInfoChange || this.insuranceChange) && this.id){
        // this.approvalDialogShow=true
        this.submitApprovalHandle()
        console.log('11111',this.approvalForm.serviceChange)
        console.log('2222',this.approvalForm.insuranceChange)
      }else {
        this.approvalDialogShow=false
       await this.submitBtn();
      }
    },*/
    async submitApprovalHandle(){//提交审批-走接口
      if(this.vehicleInfoChange){
        if(!(this.selectedOption.length > 0)){
          this.$toast('车辆类别不能为空')
          return
        }
        let res = this.checkDisabledItems();
        if(!res) {
          return false
        }
        if( !this.virtualVehicle ) {
          this.$toast('车辆属性不能为空')
          return
        }
        if( !this.vehicleStatus ) {
          this.$toast('车辆状态不能为空')
          return
        }
       /* if(!this.approvalForm.serviceRemark){
          this.$toast('车辆和服务备注不能为空')
          return
        }*/
      }
      if(this.insuranceChange){
        if(this.hasLiabilityInsurance === null || this.hasLiabilityInsurance === undefined || this.hasLiabilityInsurance === '') {  // 有职业责任险，就需要有保单照片
          this.$toast('救援职业责任险不能为空')
          return
        }
        if(!this.insurancePicturePhoto && this.hasLiabilityInsurance == 1) {  // 有职业责任险，就需要有保单照片
          this.$toast('保单照片不能为空')
          return
        }
        if(this.selectedOption?.length==1 && this.selectedOption.includes(1)){//选择小修车时需清除原本的拖车服务类型
          let data=this.oldSupplierServiceList.filter(item => item.name ==='拖车服务')
          this.serviceIds = this.serviceIds.filter(item => !data[0].children.some(obj => obj.id === item));
        }
        if(!this.insuranceCorp && this.hasLiabilityInsurance == 1) {  // 有职业责任险，就需要有保单照片
          this.$toast('承保保司不能为空')
          return
        }
        if(!this.dateVal && this.hasLiabilityInsurance == 1) {  // 有职业责任险，就需要有保单照片
          this.$toast('保单有效期不能为空')
          return
        }
       /* if(!this.approvalForm.insuranceRemark){
          this.$toast('保单备注不能为空')
          return
        }*/
      }
      try {
        this.loading = true;
        await saveSupplierApproval({...this.approvalForm})
      } finally {
        this.loading = false;
      }
      this.$toast('提交审批成功')
      this.closeApproval()
      setTimeout(()=>{
        this.$router.back();
      },2000)
    },
    compareObjects(newObj, oldObj) {
      this.changedFields=[]
      for (let key in newObj) {
        if( Array.isArray(newObj[key])){
          if(newObj[key]?.length != oldObj[key]?.length){
            this.changedFields.push(key);
          }else {
            // console.log('newObj[key]',newObj[key])
            if(newObj[key][0]?.id){
              let flag=newObj[key].every((item, index) => item.id == oldObj[key][index]?.id);
              // console.log('flag',flag)
              if(!flag){
                this.changedFields.push(key);
              }
            }else{
              let flag=newObj[key].every((value, index) => value == oldObj[key][index]);
              if(!flag){
                this.changedFields.push(key);
              }
            }
          }
        }else{
          let isEqual = (
              (newObj[key] == null && oldObj[key] == 0) ||
              (newObj[key] == 0 && oldObj[key] == null) ||
              (newObj[key] == oldObj[key])
          );
          if (!isEqual) {
            this.changedFields.push(key);
          }
        }
      }
    },
    closeApproval(){
      this.approvalForm.serviceRemark=''
      this.approvalForm.insuranceRemark=''
      this.approvalForm.vehicleOtherRemark=''
      this.approvalDialogShow=false
      this.vehicleInfoChange=false
      this.insuranceChange=false
    },
    back() {
      this.$router.back();
      /*if( this.supplierId ) {
        this.$router.back();
      } else {
        this.$router.push({
          name:'vehicleManage',
          params:{
            id: this.id
          }
        })
      }*/

    },
    validatePlateNumber(value) {
      if (!value) {
        return { valid: false, message: '请输入车牌号' }
      }
      const provinceList = ['京','津','冀','晋','蒙','辽','吉','黑','沪','苏','浙','皖','闽','赣','鲁','豫','鄂','湘','粤','桂','琼','渝','川','贵','云','藏','陕','甘','青','宁','新']
      const firstChar = value.charAt(0)
      if (!provinceList.includes(firstChar)) {
        return { valid: false, message: '车牌号首位必须是省级简称（京/沪/津/渝/冀/晋/辽/吉/黑/苏/浙/皖/闽/赣/鲁/豫/鄂/湘/粤/琼/川/贵/云/陕/甘/青/蒙/桂/藏/宁/新）' }
      }
      if (!/^[\u4e00-\u9fa5][A-Z0-9]+$/.test(value)) {
        return { valid: false, message: '车牌号只能包含汉字、字母和数字' }
      }
      if (![7, 8].includes(value.length)) {
        return { valid: false, message: `车牌号必须为 7 位或 8 位（当前 ${value.length} 位）` }
      }
      return { valid: true, message: '' }
    },
    validateVinNo(value) {
      const normalizedValue = String(value || '').toUpperCase()
      if (!normalizedValue) {
        return { valid: false, message: '车架号识别错误，请重新拍照上传。' }
      }
      if (!/^[A-NP-Z0-9]{17}$/.test(normalizedValue)) {
        if (normalizedValue.includes('O')) {
          return { valid: false, message: '车架号识别错误，请重新拍照上传。' }
        }
        if (!/^[A-NP-Z0-9]+$/.test(normalizedValue)) {
          return { valid: false, message: '车架号识别错误，请重新拍照上传。' }
        }
        return { valid: false, message: `车架号识别错误，请重新拍照上传。` }
      }
      return { valid: true, message: '' }
    },
    async submitBtn(){
      const plateResult = this.validatePlateNumber(this.carNum)
      if (!plateResult.valid) {
        Dialog.alert({ message: plateResult.message })
        return
      }
      const vinCode = String(this.vehicleLicenseInfo.vinCode || '')
      const vinResult = this.validateVinNo(vinCode)
      if (!vinResult.valid) {
        Dialog.alert({ message: vinResult.message })
        return
      }
      this.vehicleLicenseInfo.vinCode = vinCode
      if( !this.vehicleLicenseFront ) {
        this.$toast('行驶证主页照片不能为空')
        return
      }
      if( !this.vehicleLicenseBack ) {
        this.$toast('行驶证副页照片不能为空')
        return
      }
      if( !this.vehicleLicenseCarPhoto ) {
        this.$toast('行驶证车辆照片页不能为空')
        return
      }
      if( !this.vehicleFrontPhoto ) {
        this.$toast('车头照片不能为空')
        return
      }
      if( !this.vehicleLicenseInfo.licensePlateNumber ) {
        this.$toast('行驶证主页识别失败')
        return
      }
      if(this.vehicleLicenseBackOcrFlag && !this.vehicleLicenseInfo.backPlateNo ) {
        this.$toast('行驶证副页识别失败')
        return
      }
      if(!(this.selectedOption.length > 0)){
        this.$toast('车辆类别不能为空')
        return
      }
      let res = this.checkDisabledItems();
      if(!res) {
        return false
      }
      if( !this.virtualVehicle ) {
        this.$toast('车辆属性不能为空')
        return
      }
      if( !this.vehicleStatus ) {
        this.$toast('车辆状态不能为空')
        return
      }
      if(this.hasLiabilityInsurance === null || this.hasLiabilityInsurance === undefined || this.hasLiabilityInsurance === '') {  // 有职业责任险，就需要有保单照片
        this.$toast('救援职业责任险不能为空')
        return
      }
      if(!this.insurancePicturePhoto && this.hasLiabilityInsurance == 1) {  // 有职业责任险，就需要有保单照片
        this.$toast('保单照片不能为空')
        return
      }
      if(this.selectedOption?.length==1 && this.selectedOption.includes(1)){//选择小修车时需清除原本的拖车服务类型
        let data=this.oldSupplierServiceList.filter(item => item.name ==='拖车服务')
        this.serviceIds = this.serviceIds.filter(item => !data[0].children.some(obj => obj.id === item));
      }
      if(!this.insuranceCorp && this.hasLiabilityInsurance == 1) {  // 有职业责任险，就需要有保单照片
        this.$toast('承保保司不能为空')
        return
      }
      if(!this.dateVal && this.hasLiabilityInsurance == 1) {  // 有职业责任险，就需要有保单照片
        this.$toast('保单有效期不能为空')
        return
      }
      if( this.hasLiabilityInsurance == 1){
        if(this.permissonList.includes('hasInsuranceAudit') && !this.liabilityInsuranceAmount && this.liabilityInsuranceAmount!=0){
          this.$toast('保费不能为空')
          return
        }
        if(this.permissonList.includes('hasInsuranceAudit') && !this.liabilityInsuranceQuota){
          this.$toast('保额不能为空')
          return
        }
       /* if(!this.insuranceCode){
          this.$toast('保单号(救援)不能为空')
          return
        }*/
      }
      let timeObj;
      if(this.dateVal) {
        timeObj = this.formatDateTimeRange(this.dateVal)
      }
      this.serviceIds = this.$refs.tree.getCheckedKeys(true)
      // console.log('1122',this.vehicleStatus)
      // return
      await saveVehicle({
          vehicleId:this.id ? this.id : '',
          supplierId: this.supplierId || undefined,
          plateNumber:this.carNum ? this.carNum :'',
          vehicleType:this.selectedOption?.length>0 ? this.selectedOption.join(',') : '',
          // hasPolymerization:this.isJoin,
          serviceIds:this.serviceIds ? this.serviceIds : [],
          vehicleLicenseFront: this.vehicleLicenseFront,
          vehicleLicenseBack: this.vehicleLicenseBack,
          vehicleFrontPhoto: this.vehicleFrontPhoto,
          vehicleLicenseInfo: this.vehicleLicenseInfo,
          vehicleLicenseCarPhoto: this.vehicleLicenseCarPhoto,
          vehicleLicense: this.vehicleLicense,
          vehicleFrontLicensePlate:this.vehicleFrontLicensePlate,
          hasLiabilityInsurance: this.hasLiabilityInsurance,
          insurancePicturePhoto: this.hasLiabilityInsurance == 1 ? this.insurancePicturePhoto : '',
          insuranceCorp: this.hasLiabilityInsurance == 1 ? this.insuranceCorp : '',
          liabilityInsuranceStartTime: this.hasLiabilityInsurance == 1 ? (timeObj?.startTime || '' ) : '',
          liabilityInsuranceEndTime: this.hasLiabilityInsurance == 1 ? (timeObj?.endTime || '') : '',
          virtualVehicle: this.virtualVehicle,
          canSubmitApproval:true,
          vehicleStatus:this.vehicleStatus,
          liabilityInsuranceAmount:this.liabilityInsuranceAmount,
          liabilityInsuranceQuota:this.liabilityInsuranceQuota,
          insuranceCode:this.insuranceCode,
          insuranceCodeZd:this.insuranceCodeZd,
        })
        if(this.id){
          this.$toast('修改成功')
        }else{
          this.$toast('添加成功')
        }
        setTimeout(()=>{
          this.$router.back();
        },2000)
      }
  },
  components:{
    CellGroup,
    TwoCommonBtn
  }
}
</script>

<style>
  .vehicleAdd .van-field__control:disabled {
    color: #323643 !important;
    -webkit-text-fill-color: #323643 !important;
  }
</style>
<style scoped lang="scss">
@import "@/styles/mixin.scss";
@import "@/styles/common.scss";
/* 行驶证三槽位透明点击拦截层 */
.uploadSlotWrap{
  position: relative;
  display: inline-block;
  .slotClickMask{
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 10;
  }
  /* 已上传图片的删除按钮置于拦截层之上，保证可删除重传 */
  ::v-deep .van-uploader__preview-delete{
    z-index: 11;
  }
}
.mySelect{
  @include fontWeightSize(bold,13px);
  color: #323643;
  appearance: none;
  padding-right: 16px;
  background: url('@/assets/arrow_bot.png') no-repeat right center / 15px 14px;
}
.checkbox-group {
  display: none;
}
.navBar{
  margin-bottom: 46px;
  ::v-deep .van-nav-bar--fixed {
    z-index: 9999 !important;
  }
}
.wrap{
@include wh(100%,100%);
  overflow-y: auto;
}
.addContentWrap{
  margin-left: 16px;
  .item_content_btn {
    padding-right: 25px;
    text-align: right;
    span {
      display: inline-block;
      background: #354D93;
      padding: 5px 10px;
      font-size: 12px;
      font-weight: bold;
      color: #fff;
      border-radius: 4px;
      margin-bottom: 5px;
    }
  }
  .itemContent{
    @include flexColBet;
    line-height: 56px;
    box-sizing: border-box;
    padding-right: 25px;
    .titleType{
      @include fontWeightSize(bold,14px);
      color: #323643;
    }
    .isJoin{
      display: flex;
      .joinWrap{
        display: flex;
      }
      img{
        @include widHeiMar(16px,16px,6px)
      }
    }
    .startImg{
      @include widHeiMar(6px,6px,3px);
      vertical-align: super;
    }
    input{
      border: none;
      text-align: right;
      @include fontWeightSize(bold,13px);
      opacity: .5;
    }
  }
  .lineBot{
    @include wh(100%,1px);
    background: #E9E9EA;
    opacity: 0.6;
  }
  .serviceType{
    @include fontWeightSize(bold,13px);
    margin-left: 15px;
    .trailerService{
      margin-bottom: 10px;
    }
    .serviceline{
      @include flexCenter;
      margin-bottom: 10px;
    }
    .item{
     margin: 20px 0;
      @include flexCenter;
    }
    .radioWrap{
      margin-left: 10px;
    }
    .service{
      @include colorOpa(#323643,0.7);
      line-height: 18px;
      white-space: nowrap;
    }
    .line{
      display: inline-block;
      @include wh(240px,2px);
      opacity: 0.16;
      border-bottom: 1px solid;
      border-image: linear-gradient(270deg, rgba(217, 217, 217, 0.6), rgba(178, 178, 178, 1), rgba(178, 178, 178, 1), rgba(217, 217, 217, 0.6)) 1 1;
    }
    img{
      @include widHeiMar(16px,16px,12px)
    }
  }
  .btn{
    width: 90%;
    margin: 40px 0 30px 8px;
  }
}
.elSelect ::v-deep .el-input__inner{
  border: none !important;
  text-align: right !important;
}
.disabled-tree {
  pointer-events: none;
  opacity: 0.6;
}
/* 车辆属性-匹配角色溯源 */
.virtualVehicleField {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  .matchRoleArrow {
    margin-left: 6px;
    cursor: pointer;
    color: #909399;
    user-select: none;
    display: inline-block;
    transition: transform .2s;
    &.expanded {
      transform: rotate(180deg);
      color: #354D93;
    }
  }
}
.matchRolePanel {
  margin: 0 25px 6px 0;
  padding: 4px 10px;
  font-size: 12px;
  color: #606266;
  background: #f4f4f5;
  border-radius: 4px;
  line-height: 1.6;
  text-align: right;
}
.pop_wrap {
  width: 340px;
  box-sizing: border-box;
  padding: 10px 15px;
  position: relative;
  .pop_title {
    font-size: 14px;
    font-weight: 500;
  }
  .pop_content {
    width: 304px;
    font-size: 14px;
    color: #4C5361;
    margin-left: 6px;
    line-height: 25px;
    .iptWrap{
      margin: 10px 0;
    }
  }
  .tip_button_wrap {
    display: flex;
    justify-content: flex-end;
    .close {
      border: 1px solid #ccc;
      color: black;
      background-color: #FFFFFF;
    }
    .continue {
      padding: 6px 10px;
      border-radius: 4px;
    }
    div:last-child{
      background-color: #3266be;
      color: #FFFFFF;
      margin-left: 8px;
      margin-right: 4px;
    }
  }
}
.loading {
  position: relative;
}

.loading::after{
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 20px;
  height: 20px;
  border: 2px solid #000;
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% {
    transform: translate(-50%, -50%) rotate(0deg);
  }
  100% {
    transform: translate(-50%, -50%) rotate(360deg);
  }
}
.vanIpt{
  width: 80%;
  display: flex;
  align-items: center;
}
.vanIpt1{
  width: 72%;
}
</style>
