知识1

35 阅读1分钟
<script setup>

import { reactive, onMounted } from 'vue'

import { useRouter, useRoute } from 'vue-router'

import { useStore } from '@/stores/index.js'

import {

  get,

  post

} from '@/http/axios.js'

import {

  NoticeBar,

  Popover,

  Icon,

  Picker,

  Popup,

  Button,

  Toast,

} from 'vant'

import { queryParkByMenuItemID, getPreference, getExamSchemeRelationInfo, getRelationInfoToExam, startToExam, startAnswerSheet, userLogin, } from "@/http/api.js";

import {

  isMobilePhone,

  isIdentityNumber,

} from '@/utils/regex.js'

import { getQueryString } from '@/utils/com.js'

import { events } from '@/utils/mitt.js'

import parkLoc from '@/assets/icons/park_location.jpg';

import passIcon from '@/assets/icons/pass_valid.png';

import errorIcon from '@/assets/icons/error_invalid.png';

import personIcon from '@/assets/icons/person_change.png';

  


const router = useRouter()

const route = useRoute()

const store = useStore()

  


const state = reactive({

  parkName: '',

  parkID: '', // '73fbe1440af1401b90e1c65f7b276267', // 园区id

  menuItemID: '',

  mod: '',//访问者身份-排队者/园区人员,通过地址栏参数取值-PPS 园区人员考试 QUR 排队者考试

  showParkPopover: false,

  gps: { // 经纬度信息

    lat: '',

    lng: ''

  },

  parkPositons: [], // 园区列表

  showPreference: false, // 人员信息偏好显示状态

  showPreferenceIcon: true,//偏好图标显示状态

  preferInfoList: [], // 偏好信息列表

  //到访人员

  personalInfo: {

    examineeName: '',

    queuerMobileNo: '',

    queuerIdentificationCode: '',

    belongComponent: '',

    belongComponentCode: ''

  },

  readOnly: false,//用户信息是否只读-默认不只读

  belongComponentList: [],//所属公司列表

  opentityIdAndParkPersonnelIdMap: {},//公司id对应园区人员的映射对象

  parkPersonnelId: '',//选择所属公司映射的人员id

  validPhone: true, // 验证手机号

  validCrewID: true,//验证身份证号

  loading: false,

  belongCompany: false,//所属公司

  pkExamScheme: '',//考试方案id

  pkExamPaper: '',//考试试卷id

  examInfo: null,//考试信息

  onceMoreInfo: null,//再来一次

  paramsInfo: {},//地址栏信息parkID

  pkExaminee: '',//应试者id

  remainingExamTimes: 0,//剩余考试次数

  getInfoLink: {},//地址栏信息接口需要的参数

  videoUrl: '',//考试培训视频

  routerMode: '',//进入模式-用于判断是否为短驳/快递进入

  examRecognizeId: '',//应试者识别ID

  


})

onMounted(() => {

  document.title = '在线考试'

  // console.log(getSearchParams('exam=111&test=222'))

  


  // getExamInfo();

  // initParkList(); // 通过菜单项id初始化园区

  


  /** 测试数据 S **/

  


  // state.menuItemID = '5188070f5ce145b4a64a5514bb6c75ba' //'5188070f5ce145b4a64a5514bb6c75ba'; // '18ada998ac9d46fb9e6faf93646a39c2'; //  菜单项id

  // testUserLogin() // 测试使用

  


  // 携带参数测试

  // store.setToken('7994a81f07374a4c8915a4d8465bc7aa');

  // state.parkID = 'ede44b826bcf40409e36495e7f3e324e';

  // initAppointData(); // 初始化数据

  


  // ymstest

  // http://localhost:3003/newBooking?token=5160ec04cf744bbeada1e00784aaa38e&menuInfo=%7B%22parkID%22:%2273fbe1440af1401b90e1c65f7b276267%22,%22toIdentificationIDList%22:%5B%22SHAI2209290002%22%5D%7D

  


  // training

  // http://localhost:3003/newBooking?token=95ef7c3741d44df48fe501d905118ea6&menuInfo=%7B%22parkID%22:%2266ee1453f82a4097813489980e3f8119%22,%22toIdentificationIDList%22:%5B%22SHAI2210180005%22%5D%7D

  /** 测试数据 E **/

  


  let url = window.location.href.split('/')

  state.baseURL = url[0] + '//' + url[2]

  


  // if (localStorage.getItem('debugger') == 'open') {

  //     alert(

  //       JSON.stringify({

  //         url:window.location.href,

  //       })

  //     )

  //   }

  
  
  


  if (getQueryString('token')) {

    sessionStorage.clear()

    store.setToken(getQueryString('token'))

    sessionStorage.setItem('token', getQueryString('token'))

    if (getQueryString('menuInfo')) {

      // 首页菜单访问模式

      state.readOnly = false// 初次进入-用户信息可编辑,不只读

      state.showPreferenceIcon = true//偏好信息-初次进入默认显示

      let info = JSON.parse(decodeURIComponent(decodeURIComponent(getQueryString('menuInfo'))))

      state.paramsInfo = info

      console.log(info)

      state.menuItemID = info.appletProjectMenuItemID // 菜单项id

  
  


      if (info.mod) { //短链接进入携带mod方式不同 取值方式不同-zmy

        state.mod = info.mod

      } else {

        state.mod = getSearchParams(info.param).mod//访问者mode

      }

      // if (info.unchangeable == true) {  //短链接进来-unchangeable判断是否只读

      //   state.readOnly = true// 短链接进来 用户信息不可编辑,只读

      // } else {

      //   state.readOnly = false

      // }

      // state.mod = getSearchParams(info.param).mod//访问者mode

      // console.log(state.mod)

      sessionStorage.setItem("applyParkMenuInfo", JSON.stringify(state.paramsInfo));

      // 缓存menuInfor内的queueBizType

      sessionStorage.setItem("menuInfor", JSON.stringify(info));

      state.getInfoLink = info//获取考试方案id时需要该数据作为入参,和 state.paramsInfo 值一致,但不知道存在两个一致data的原因,所以暂未删除

      // 原有模式-非短驳/快递进入

      if (info.queueBizType != 'STM_SBG' && info.queueBizType != 'STM_EXP') {

        if (info.parkID) {

          // 短链接/携带参数进入-按照壳程序传参逻辑,扫码访问携带parkid

          // state.resourceServQueuerID = info.resourceServQueuerID

          state.parkID = info.parkID

          initAppointData() // 初始化数据

          console.log(info.queueBizType)

          if (!info.examineeName) { //如果没有用户信息再去获取/且用户不是通过新首页短驳/快递菜单访问

            getPersonInfo() // 通过token获取人员信息

          } else {

            state.readOnly = false

  


            // 用户信息-用于反显

            state.personalInfo = {

              examineeName: state.getInfoLink.examineeName,

              queuerMobileNo: state.getInfoLink.mobileNo,

              queuerIdentificationCode: (state.getInfoLink.idNo == 'null' || state.getInfoLink.idNo == 'undefined' || !state.getInfoLink.idNo) ? '' : state.getInfoLink.idNo,

              belongComponent: state.getInfoLink.opEntityName,

              belongComponentCode: state.getInfoLink.opEntityId

            }

          }

          // alert(JSON.stringify(state.getInfoLink))

          sessionStorage.setItem("applyGetInfoLink", JSON.stringify(state.getInfoLink));//存缓存

          // 缓存排队者id-用于判断是引导页面跳转过来,最后的考试结果页面判断显示返回引导页面入口并且返传回去

          sessionStorage.setItem("resourceServQueuerID", state.getInfoLink.resourceServQueuerID);

          sessionStorage.setItem("applyParkMenuInfo", JSON.stringify(state.getInfoLink));

          // 查询成功后获取考试方案

          getExamInfo()

  


        } else if (state.menuItemID) {

          // 从主界面进入-按照壳程序传参逻辑,点击菜单访问不携带parkid

          initParkList() // 通过菜单项id初始化园区

  


          if (!info.examineeName) {  //短链接进来后通过地址栏携带参数信息确定是否通过token获取人员信息

            getPersonInfo() // 通过token获取人员信息

          }

        }

  


      } else {

        // 短驳/快递模式缓存menuInfo-存到了两个字短内,不理解但是保留-jly

        sessionStorage.setItem("applyGetInfoLink", JSON.stringify(state.getInfoLink));//存缓存

        sessionStorage.setItem("applyParkMenuInfo", JSON.stringify(state.getInfoLink));

  


        state.routerMode = 'express'//短驳/快递菜单进入,后续录完用户信息后,直接查询考试方案,不查询所属公司

        // 通过短驳/快递菜单进入-可能携带部分页面参数

        state.personalInfo = {

          examineeName: info.examineeName,

          queuerMobileNo: info.mobileNo,

          queuerIdentificationCode: (info.idNo == 'null' || info.idNo == 'undefined' || !info.idNo) ? '' : info.idNo,

  


        }

        // 携带完整用户信息,直接查询考试方案

        if (info.examBizType && info.softProdCode && info.objectType && info.objectId) {

          getExamInfo()

        }

  


      }

  
  


    } else if (getQueryString('info')) {

      // 流程引导进入模式

      state.readOnly = true// 用户信息只读

      let guiInfo = JSON.parse(decodeURIComponent(decodeURIComponent(getQueryString('info'))))//流程引导页面跳转过来-获取地址栏携带参数

      // 用户信息-用于反显

      state.personalInfo = {

        examineeName: guiInfo.examineeName,

        queuerMobileNo: guiInfo.mobileNo,

        queuerIdentificationCode: (guiInfo.idNo == 'null' || guiInfo.idNo == 'undefined' || !guiInfo.idNo) ? '' : guiInfo.idNo,

        belongComponent: guiInfo.opEntityName,

        belongComponentCode: guiInfo.opEntityId

      }

      // 其他隐藏参数-用于查询考试方案

      state.getInfoLink = guiInfo

      // alert(JSON.stringify(state.getInfoLink))

      sessionStorage.setItem("applyGetInfoLink", JSON.stringify(state.getInfoLink));//存缓存

      // 缓存排队者id-用于判断是引导页面跳转过来,最后的考试结果页面判断显示返回引导页面入口并且返传回去

      sessionStorage.setItem("resourceServQueuerID", getQueryString('resourceServQueuerID'));

      sessionStorage.setItem("applyParkMenuInfo", JSON.stringify(state.getInfoLink));

      // 查询成功后获取考试方案

      getExamInfo()

  


    }

  } else {

    // 再考一次模式

    if (JSON.parse(sessionStorage.getItem('onceMoreInfo'))) {

      console.log(sessionStorage.getItem('onceMoreInfo'))

      state.readOnly = false// 再次考试-用户信息不只读 --5/12 zmy

      state.showPreferenceIcon = false//偏好信息-再次考试隐藏

  


      // 缓存应试者识别ID,用于再次考试时使用-jly

      state.examRecognizeId = sessionStorage.getItem("examRecognizeId");

  


      if (sessionStorage.getItem('personalInfo')) state.personalInfo = JSON.parse(sessionStorage.getItem('personalInfo'))//缓存获取用户信息,'

  


      store.setToken(sessionStorage.getItem('token'))

      state.onceMoreInfo = JSON.parse(sessionStorage.getItem('onceMoreInfo')) //再考一次

      state.paramsInfo = JSON.parse(sessionStorage.getItem("applyParkMenuInfo"));

      state.getInfoLink = JSON.parse(sessionStorage.getItem("applyGetInfoLink"));

      // alert(sessionStorage.getItem("applyGetInfoLink"))

      // state.examInfo = JSON.parse(sessionStorage.getItem("examInfo"));

      console.log(store.token)

      // alert(store.token)

      // alert(JSON.stringify(state.paramsInfo))

      if (store.token) {

        if (state.paramsInfo) {

          state.menuItemID = state.paramsInfo.appletProjectMenuItemID; // 菜单项id

          state.mod = state.paramsInfo.mod//访问者mode

          initAppointData() // 初始化数据-双行线,不影响页面其他初始逻辑

          // 再考一次进入

          getRelationInfoToExamInfo()

        }

      }

    } else {

      state.onceMoreInfo = null

    }

  


  }

  


})

const getSearchParams = (params) => {

  const searchParams = new URLSearchParams(params);

  const paramsObj = {};

  for (const [key, value] of searchParams.entries()) {

    paramsObj[key] = value;

  }

  return paramsObj;

}

  


// 测试使用

const testUserLogin = async () => {

  let result = await userLogin({

    loginName: 'yms-test',

    pswd: '1qaz@WSX', // 'Qwer1234'

  })

  if (result.data.code == 'S') {

    store.setToken(result.data.data.token) // 设置token

    initParkList() // 通过菜单项id初始化园区

  }

}

// 初始化园区

const initParkList = async () => {

  const toast = Toast.loading({

    duration: 0,

    forbidClick: true,

    loadingType: 'spinner',

  })

  let res = await queryParkByMenuItemID({

    token: store.token,

    gps: state.gps,

    mod: state.mod,

    menuItemID: state.menuItemID,

    parkID: state.parkID,//初次进入该值为空

  })

  toast.clear()

  if (res.data.code == 'S') {

    state.parkPositons = res.data.data

    if (state.parkPositons.length) {

      state.parkPositons.forEach((ele) => {

        ele.text = ele.resourceName

      })

      handleSelectPark(state.parkPositons[0]) // 初始化信息

    }

  } else {

    Toast.fail({

      duration: 0,

      closeOnClick: true,

      message: res.data.msg,

      icon: 'close',

    })

  }

}

// 初始化数据-该方法在onMounted内有parkid则直接执行,如无则先通过其他方法【initParkList>handleSelectPark】获取parkid后再执行

const initAppointData = () => {

  // getCompanyDataList(2);//所属公司

  handlePreferenceInfo(3); // 偏好信息

  
  


}

// 选择园区

const handleSelectPark = (action) => {

  // console.log(action);

  state.parkName = action.text;

  state.parkID = action.parkID;//选中园区parkid

  // state.bookableResourceID = action.bookableResourceID;

  // 重置页面数据

  


  if (state.menuItemID) {//从小程序菜单进

    state.getInfoLink = getSearchParams(state.paramsInfo.param) //从菜单进取的是param的值

    sessionStorage.setItem("applyGetInfoLink", JSON.stringify(state.getInfoLink));//存缓存

    state.personalInfo = { //给考试人员信息赋值

      examineeName: state.getInfoLink.examineeName,

      queuerMobileNo: state.getInfoLink.mobileNo,

      queuerIdentificationCode: (state.getInfoLink.idNo == 'null' || state.getInfoLink.idNo == 'undefined' || !state.getInfoLink.idNo) ? '' : state.getInfoLink.idNo,

      belongComponent: state.getInfoLink.opEntityName,

      belongComponentCode: state.getInfoLink.opEntityId

    }

    // 查询成功后获取考试方案

    // getExamInfo()  一进页面没有填写用户信息时不能直接获取考试方案

  } else {

    state.personalInfo = {

      examineeName: '',

      queuerMobileNo: '',

      queuerIdentificationCode: '',

      belongComponent: '',

      // belongComponentCode: ''

    }

  }

  
  
  
  


  // 初始化页面

  initAppointData();

};

  


// 初始进入查询用户信息

const getPersonInfo = async () => {

  let params = {

    "ServiceType": "getParkPersonnelByToken",

    "ServiceData": {

      token: store.token,

      appletProjectMenuItemID: state.menuItemID,

      mod: state.mod,

      appletCode: ''//小程序code-因为壳程序跳转链接未携带该参数,经沟通可为空

    }

  };

  await post(

    "/hlcloud-yms-app/webServiceReport/adapter", params

  ).then((res) => {

    console.log(res)

    // res = res.data

    if (res.data.code == "S") {

  


      // 查询到人员信息-赋值反显

      let returnInfor = res.data.data

      state.personalInfo.examineeName = returnInfor.examineeName

      state.personalInfo.queuerMobileNo = returnInfor.mobileNo

      state.personalInfo.queuerIdentificationCode = (returnInfor.idNo == 'null' || returnInfor.idNo == 'undefined' || !returnInfor.idNo) ? '' : returnInfor.idNo,

      state.belongComponentList = returnInfor.operateEntityList ? returnInfor.operateEntityList : []

      state.validPhone = true

      state.validCrewID = true

      state.opentityIdAndParkPersonnelIdMap = returnInfor.opentityIdAndParkPersonnelIdMap

      console.log(state.belongComponentList)

      // 园区人员/排队者两种模式下所属公司和人员id赋值方式不同

      if (state.mod == 'QUR') {

        qurMod(state.belongComponentList[0], returnInfor.resourceServQueuerID)//排队者-所属公司/人员id赋值

      } else if (state.mod == 'PPS') {

        confirmVisitCompany(state.belongComponentList[0])//园区人员-所属公司/人员id赋值

      }

  


    }

  });

  


}

// 排队者模式赋值人员id/所属公司

const qurMod = (action, resourceServQueuerID) => {

  


  state.belongCompany = false

  console.log(action)

  state.personalInfo.belongComponent = action?.opentityname;

  state.personalInfo.belongComponentCode = action?.opentityid;

  state.showVisitType = false;

  state.parkPersonnelId = resourceServQueuerID

  // 查询考试方案

  // 初次进入

  getElseParam()

}

// 获取偏好信息

const handlePreferenceInfo = async (times) => {

  let params = {

    token: store.token,

    parkID: state.parkID,

    preferenceType: 'QII',

    parkPassRole: '',

    otherTimes: new Date().getTime() + '-' + times

  };

  let res = await getPreference(params);

  if (res.data.code == 'S') {

    state.preferInfoList = res.data.data;

    /* 开发者调试数据 S */

    if (localStorage.getItem('debugger') == 'open') {

      alert(JSON.stringify(res));

    }

    /* 开发者调试数据 E */

  }

}

// 选择偏好

const handleSelectPreference = (item) => {

  // console.log(item);

  let result = item;

  


  if (result.driverName) state.personalInfo.examineeName = result.driverName; // 姓名

  if (result.queuerMobileNo) {

    state.personalInfo.queuerMobileNo = result.queuerMobileNo; // 手机号

    changeInput('phone'); // 校验

  }

  state.showPreference = false;

  


}

// 车牌号/手机号/身份证校验

const changeInput = (type) => {

  if (type == 'phone') { // 手机号

    state.validPhone = state.personalInfo.queuerMobileNo ? isMobilePhone(state.personalInfo.queuerMobileNo) : true;

  } else if (type == 'queuerIdentificationCode') { // 身份证号

    state.validCrewID = state.personalInfo.queuerIdentificationCode ? isIdentityNumber(state.personalInfo.queuerIdentificationCode) : true;

  }

  console.log(state.validCrewID)

}

//获取所属公司

const getCompanyDataList = async (times) => {

  let params = {

    "ServiceType": "getParkPersonnelByUserInfo",

    "ServiceData": {

      examineeName: state.personalInfo.examineeName,

      idNo: state.personalInfo.queuerIdentificationCode,

      mobileNo: state.personalInfo.queuerMobileNo,

      appletProjectMenuItemID: state.menuItemID,

      mod: state.mod,

      token: store.token

    }

  };

  await post(

    "/hlcloud-yms-app/webServiceReport/adapter", params

  ).then((res) => {

    if (res.data.code == 'S') {

      state.belongComponentList = res.data.data.operateEntityList

      state.opentityIdAndParkPersonnelIdMap = res.data.data.opentityIdAndParkPersonnelIdMap

      // 园区人员/排队者两种模式下所属公司和人员id赋值方式不同

      if (state.mod == 'QUR') {

        console.log(res)

        qurMod(state.belongComponentList[0], res.data.data.resourceServQueuerID)//排队者-所属公司/人员id赋值

      } else if (state.mod == 'PPS') {

        confirmVisitCompany(state.belongComponentList[0])//园区人员-所属公司/人员id赋值

      }

  


    } else {

  


      Toast.fail({

        duration: 0,

        closeOnClick: true,

        message: res.data.msg,

        icon: 'close',

      });

    }

  


  })

  
  


}

//所属公司-change

const confirmVisitCompany = (action) => {

  state.belongCompany = false

  console.log(action)

  state.personalInfo.belongComponent = action?.opentityname;

  state.personalInfo.belongComponentCode = action?.opentityid;

  state.showVisitType = false;

  // 匹配选择公司影射的人员id并赋值

  Object.keys(state.opentityIdAndParkPersonnelIdMap).forEach((key) => {

    if (key == action.opentityid) {

      state.parkPersonnelId = state.opentityIdAndParkPersonnelIdMap[key]

    }

  })

  console.log("映射:" + state.parkPersonnelId)

  // 所属公司改变时,清空考试方案信息

  state.pkExamScheme = '' //考试方案id

  state.pkExamPaper = '' //试卷id

  state.examInfo = null

  // 查询考试方案

  // 初次进入

  getElseParam()

  


}

//可填写人员信息-change时触发

const changeInfo = () => {

  if (state.personalInfo.examineeName) {

    // 姓名去空格

    state.personalInfo.examineeName = state.personalInfo.examineeName.split(/[\t\r\f\n\s]*/g).join('')

  }

  console.log(state.personalInfo.examineeName)

  


  // change时-清空考试方案信息/所属公司信息

  // 查询所属公司失败-清掉公司数据/考试方案数据

  state.personalInfo.belongComponent = ''

  state.personalInfo.belongComponentCode = ''

  state.belongComponentList = []

  state.opentityIdAndParkPersonnelIdMap = {}

  state.parkPersonnelId = ''

  state.pkExamScheme = '' //考试方案id

  state.pkExamPaper = '' //试卷id

  state.examInfo = null

  // && state.personalInfo.queuerIdentificationCode   && state.validCrewID 身份证号不必填

  if (state.personalInfo.examineeName && state.personalInfo.queuerMobileNo

    && state.validPhone) {

    // 判断短驳/快递菜单进入时,不查询所属公司,直接获取考试方案

    if (state.routerMode != 'express') {

      // 查询所属公司list

      getCompanyDataList()

  


    } else {

      getExamInfo()

    }

  
  


  }

}

// 获取其他未携带参数-在查询考试方案之前执行-jly

const getElseParam = async () => {

  // 园区人员/排队者两种模式请求接口使用的人员id参数名不同

  let personnelId = {}

  if (state.mod == 'PPS') {

    // 园区人员

    personnelId = {

      parkPersonnelId: state.parkPersonnelId

    }

  } else if (state.mod == 'QUR') {

    // 排队者

    personnelId = {

      resourceServQueuerID: state.parkPersonnelId

    }

  }

  let params = {

    "ServiceType": "getExamUrlByParkPersonnel",

    "ServiceData": {

      ...personnelId,

      mod: state.mod,

      appletCode: '',//经沟通可为空

      token: store.token,

      appletProjectMenuItemID: state.menuItemID//菜单项id-初始地址栏参数获取

    }

  };

  await post(

    "/hlcloud-yms-app/webServiceReport/adapter", params

  ).then((res) => {

    if (res.data.code == "S") {

      let info = res.data.data.split('?')[1]

      let returnParams = getSearchParams(info)//将返回的拼接参数转为对象

      console.log(returnParams)

      state.getInfoLink = returnParams

      sessionStorage.setItem("applyGetInfoLink", JSON.stringify(state.getInfoLink));//存缓存

      // 查询成功后获取考试方案

      getExamInfo()

  


    } else {

      Toast.fail({

        duration: 0,

        closeOnClick: true,

        message: '查询失败,请稍后重试',

        icon: 'close',

      });

    }

  


  })

  


}

//获取考试方案(获取考试方案详情-根据考试场景获取) getExamSchemeRelationInfo

const getExamInfo = async () => {

  let toast = null;

  toast = Toast.loading({

    duration: 0,

    forbidClick: true,

    loadingType: "spinner",

  });

  


  // alert(JSON.stringify(state.getInfoLink))

  
  


  let params = {

    token: store.token,

    mod: state.mod,

    examBizType: state.getInfoLink ? state.getInfoLink.examBizType : '',//考试业务类型

    // softProdCode: state.getInfoLink ? state.getInfoLink.softProdCode : 'YMS',

    softProdCode: 'YMS',

    objectType: state.getInfoLink ? state.getInfoLink.objectType : '',

    objectId: state.getInfoLink ? state.getInfoLink.objectId : '',

    examRecognizeId: state.getInfoLink ? state.getInfoLink.examRecognizeId : '',//应试者识别id

    ddParkBizType: state.getInfoLink ? state.getInfoLink.ddParkBizType : '',

    personnelType: state.getInfoLink ? state.getInfoLink.personnelType : '',

    opEntityId: state.personalInfo.belongComponentCode,//所属公司id

    opEntityName: state.personalInfo.belongComponent//所属公司name

  }

  


  // alert(JSON.stringify(params))

  
  


  await getExamSchemeRelationInfo(

    "/hlcloud-oes-app/examScene/getExamSchemeRelationInfoByExamScene", params

  ).then((res) => {

    console.log(res)

    toast.clear()

    res = res.data

    if (res.code == "S") {

      state.pkExamScheme = res.data.pkExamScheme //考试方案id

      state.pkExamPaper = res.data.examPaperVoUse.pkExamPaper //试卷id

      // state.remainingExamTimes = res.data.remainingExamTimes //剩余考试次数

      state.examInfo = res.data

      state.examRecognizeId = res.data.examRecognizeId

      // 缓存应试者识别ID,用于再次考试时使用-jly

      sessionStorage.setItem("examRecognizeId", state.examRecognizeId);

      res.data.examSchemeLinkOpVoList.forEach(item => {

        if (item.ddOperationType == 'VDO') {

          state.videoUrl = item.operationUrl//考试培训视频

        }

      })

  
  


    } else {

      Toast.fail({

        duration: 0,

        closeOnClick: true,

        message: res.msg,

        icon: 'close',

      });

    }

  });

  


}

//获取考试方案(获取考试方案详情-根据考试方案id)

const getRelationInfoToExamInfo = async (pkExamSchemeId, pkExamineeId) => {

  let toast = null;

  toast = Toast.loading({

    duration: 0,

    forbidClick: true,

    loadingType: "spinner",

  });

  


  // alert(JSON.stringify(state.getInfoLink))

  


  let params = {

    token: store.token,

    mod: state.mod,

    pkExamScheme: state.onceMoreInfo?.pkExamScheme,

    pkExaminee: state.onceMoreInfo?.pkExaminee,

    examBizType: state.getInfoLink ? state.getInfoLink.examBizType : '',//考试业务类型

    softProdCode: state.getInfoLink ? state.getInfoLink.softProdCode : '',

    objectType: state.getInfoLink ? state.getInfoLink.objectType : '',

    objectId: state.getInfoLink ? state.getInfoLink.objectId : '',

    opEntityId: state.personalInfo.belongComponentCode,//所属公司id

    opEntityName: state.personalInfo.belongComponent//所属公司name

  }

  


  // alert(JSON.stringify(params))

  


  await getRelationInfoToExam(

    "/hlcloud-oes-app/examScheme/getExamSchemeRelationInfoToExam", params

  ).then((res) => {

    console.log(res)

    toast.clear()

    res = res.data

    if (res.code == "S") {

      state.pkExamScheme = res.data.pkExamScheme //考试方案id

      state.pkExamPaper = res.data.examPaperVoUse.pkExamPaper //试卷id

      // state.remainingExamTimes = res.data.remainingExamTimes //剩余考试次数

      state.examInfo = res.data

    } else {

  


      Toast.fail({

        duration: 0,

        closeOnClick: true,

        message: res.msg,

        icon: 'close',

      })

    }

  });

}

//开始考试

const startExam = async () => {

  sessionStorage.removeItem('onceMoreInfo')

  let params = {

    token: store.token,

    mod: state.mod,

    fkExamScheme: state.pkExamScheme, //考试方案id",

    ddExamineeType: state.getInfoLink ? state.getInfoLink.ddExamineeType : '',//"PPS" 应试者类型,必填 - 从地址栏取",

    examRecognizeId: state.examRecognizeId, //"20230221002-变化的" 应试识别ID,必填 - 从地址栏取",

    fkBizUnit: state.getInfoLink ? state.getInfoLink.fkBizUnit : '',

    objectType: state.getInfoLink ? state.getInfoLink.objectType : '',

    objectId: state.getInfoLink ? state.getInfoLink.objectId : '',

    examineeName: state.personalInfo.examineeName,//应试者姓名,必填",

    idNo: state.personalInfo.queuerIdentificationCode,//应试者身份证件号,必填",

    mobileNo: state.personalInfo.queuerMobileNo,//应试者手机号,必填",

    opEntityId: state.personalInfo.belongComponentCode, //所属公司id,非必填",

    opEntityName: state.personalInfo.belongComponent, //所属公司名称,非必填"

  


  }

  if (state.pkExamScheme) {

    await startToExam(

      "/hlcloud-oes-app/examinee/addExaminee", params

    ).then((res) => {

      console.log(res)

      res = res.data

      if (res.code == "S") {

        state.pkExaminee = res.data.pkExaminee, //应试者id

          state.remainingExamTimes = res.data.remainingExamTimes //剩余考试次数

        //添加应试者信息成功后调用开始答卷接口

        startAnswerSheetInfo()

        // 缓存用户信息-用于短驳、快递菜单返回后返显-jly

        sessionStorage.setItem("personalInfo", JSON.stringify(state.personalInfo));

  


      } else {

        Toast.fail({

          duration: 0,

          closeOnClick: true,

          message: res.msg,

          icon: 'close',

        })

      }

    });

  } else {

    Toast.fail({

      duration: 0,

      closeOnClick: true,

      message: '暂无可用考试方案',

      icon: 'close',

    })

  }

  
  


}

//开始答卷

const startAnswerSheetInfo = async () => {

  


  let params = {

    token: store.token,

    fkExamPaper: state.pkExamPaper,//试卷主键,必填

    fkExaminee: state.pkExaminee,//应试者主键,通过考试方案进入的答卷记录考试方案应试者外键

    userIdExaminee: "",//答题人ID,匿名调查可能无答题人ID

    fkBizUnit: state.getInfoLink ? state.getInfoLink.fkBizUnit : '',

    mod: state.mod,

  }

  await startAnswerSheet(

    "/hlcloud-oes-app/answerSheet/startAnswerSheet", params

  ).then((res) => {

    console.log(res)

    res = res.data

    if (res.code == "S") {

      sessionStorage.setItem('personalInfo', JSON.stringify(state.personalInfo)) // 缓存用户信息,用于再次考试时反显

      let examInfo = {

        duration: state.examInfo.examPaperVoUse.duration,

        pkExamScheme: state.pkExamScheme,

        pkExamPaper: state.pkExamPaper,

        pkExaminee: state.pkExaminee, //应试者id

  


        remainingExamTimes: state.remainingExamTimes, //剩余考试次数

        pkAnswerSheet: res.data.pkAnswerSheet, //答卷主键

        mod: state.mod,

        fkBizUnit: state.getInfoLink ? state.getInfoLink.fkBizUnit : '',

  


      }

      // sessionStorage.setItem('duration', state.examInfo.examPaperVoUse.duration)

      // sessionStorage.setItem('pkExamScheme', state.pkExamScheme)

      // sessionStorage.setItem('pkExamPaper', state.pkExamPaper)

      // sessionStorage.setItem('pkExaminee', res.data.pkExaminee)

      // sessionStorage.setItem('remainingExamTimes', res.data.remainingExamTimes)

      sessionStorage.setItem('examInfo', JSON.stringify(examInfo))

      if (state.videoUrl) {

        sessionStorage.setItem('videoUrl', state.videoUrl)

        router.push(

          {

            name: 'trainVedio',

            // params: {

            //   examInfo: JSON.stringify(examInfo)

            // }

          }

        )

  


      } else {

        router.push(

          {

            name: 'onlineTest',

            // params: {

            //   examInfo: JSON.stringify(examInfo)

            // }

          }

        )

      }

  
  


    } else {

      Toast.fail({

        duration: 0,

        closeOnClick: true,

        message: res.msg,

        icon: 'close',

      })

    }

  });

  
  


}

</script>

  


<template>

  <div class="new_booking">

    <!-- 园区信息 -->

    <div class="info_position">

      <NoticeBar style="opacity:0" left-icon="volume-o" text="1123123123123" background="#f5f5f5" />

      <Popover v-if="state.parkPositons.length > 1" v-model:show="state.showParkPopover" :actions="state.parkPositons"

        @select="handleSelectPark" placement="bottom-end">

        <template #reference>

          <p class="title_link">

            <Icon :name="parkLoc" size="14" />

          <p>

            <span>{{ state.parkName }}</span>

          </p>

          </p>

        </template>

      </Popover>

      <p v-else class="title_link">

        <Icon :name="parkLoc" size="14" />

        <span>{{ state.parkName }}</span>

      </p>

    </div>

    <div>

      <!-- 考生信息 -->

      <div class="vehicle_info personal_info">

        <p class="info_title ft-bold">考生信息</p>

        <div class="info_desc">

          <!-- 考生姓名 -->

          <div class="desc_item">

            <span class="label ft-bold">考生姓名</span>

            <span class="label">*</span>

            <div class="item_input item_personal ">

              <input type="text" class="input_name" v-model="state.personalInfo.examineeName" placeholder="请输入姓名"

                @change="changeInfo" :disabled="state.readOnly">

              <span v-show="state.showPreferenceIcon">

                <Popover v-model:show="state.showPreference" placement="bottom-end">

                  <div class="personal_prefer">

                    <div class="prefer_item" v-for="(ite, ind) in state.preferInfoList" :key="ind"

                      @click="handleSelectPreference(ite)">

                      <span>{{ ite.driverName }}</span>

                      <span>{{ ite.queuerMobileNo }}</span>

                    </div>

                    <div class="no_prefer" v-if="state.preferInfoList.length == 0">

                      <img src="@/assets/icons/no_data.png" alt="">

                      <p class="nodata_title ft-bold">暂无偏好信息</p>

                    </div>

                  </div>

                  <template #reference>

                    <img :src="personIcon" alt="">

                  </template>

                </Popover>

              </span>

            </div>

          </div>

          <!-- 手机号码 -->

          <div class="desc_item">

            <span class="label ft-bold">手机号码</span>

            <span class="label">*</span>

            <div class="item_input">

              <div class="select_item">

                <input pattern="[0-9]*" class="input_name" v-model="state.personalInfo.queuerMobileNo"

                  @input="changeInput('phone')" placeholder="请输入手机号" @change="changeInfo" :disabled="state.readOnly" />

                <Icon :style="state.personalInfo.queuerMobileNo ? '' : { opacity: 0 }" class="select_icon"

                  @click="!state.validPhone ? state.personalInfo.queuerMobileNo = '' : ''; changeInput('phone')"

                  :name="state.validPhone ? passIcon : errorIcon" color="#606266" />

              </div>

            </div>

          </div>

          <!-- 身份证号 -->

          <div class="desc_item">

            <span class="label ft-bold">身份证号</span>

            <!-- 5-8号 赵佳楠让把身份证号和所属公司设置为不必填 -->

            <span class="label"></span>

            <div class="item_input">

              <div class="select_item">

                <input class="input_name" v-model="state.personalInfo.queuerIdentificationCode"

                  @input="changeInput('queuerIdentificationCode')" placeholder="请输入证件号" @change="changeInfo"

                  :disabled="state.readOnly" />

                <Icon :style="state.personalInfo.queuerIdentificationCode ? '' : { opacity: 0 }" class="select_icon"

                  @click="!state.validCrewID ? state.personalInfo.queuerIdentificationCode = '' : ''; changeInput('queuerIdentificationCode')"

                  :name="state.validCrewID ? passIcon : errorIcon" color="#606266" />

              </div>

            </div>

          </div>

          <!-- <div class="desc_item">

                                  <span class="label ft-bold">所属公司</span>

                                  <span class="label"></span>

                                  <div class="item_input">

                                    <div class="select_item">

                                      <input type="text" class="input_name" v-model="state.personalInfo.belongComponent" placeholder="请输入所属公司"

                                        @change="changeInfo">

                                    </div>

                                  </div>

                                </div> -->

          <div class="desc_item">

            <span class="label ft-bold">所属公司</span>

            <span class="label" v-show="state.mod != 'QUR'"></span>

            <div class="item_input">

              <div class="select_item" @click="state.belongCompany = true">

                <span v-if="state.personalInfo.belongComponent">{{ state.personalInfo.belongComponent == 'null' ? '' :

                  state.personalInfo.belongComponent }}</span>

                <span v-else style="color:#888;fontWeight:normal">请选择所属公司</span>

              </div>

            </div>

            <Popup v-model:show="state.belongCompany" position="bottom">

              <Picker :columns="state.belongComponentList" :columns-field-names="{ text: 'opentityname' }"

                @cancel="state.belongCompany = false" @confirm="confirmVisitCompany">

              </Picker>

            </Popup>

          </div>

        </div>

      </div>

      <!-- 考试信息 -->

      <div class="vehicle_info personal_info info_last" v-if="state.examInfo">

        <p class="info_title ft-bold">考试信息</p>

        <div class="info_desc">

          <div class="desc_item">

            <span class="label ft-bold">试卷方案</span>

            <span class="label"></span>

            <div class="item_input">

              <div class="select_item">

                <!-- <span>入园安全考试</span> -->

                <span>{{ state.examInfo.examSchemeName }}</span>

              </div>

            </div>

          </div>

          <div class="desc_item">

            <span class="label ft-bold">考试时间</span>

            <span class="label"></span>

            <div class="item_input">

              <div class="select_item">

                <!-- <span>45分钟(不含视频学习时间)</span> -->

                <span>{{

                  state.examInfo.examPaperVoUse ? state.examInfo.examPaperVoUse.duration + '分钟(不含视频学习时间)' : ''

                }}</span>

              </div>

            </div>

          </div>

          <div class="desc_item">

            <span class="label ft-bold">通过分数</span>

            <span class="label"></span>

            <div class="item_input">

              <div class="select_item">

                <!-- <span>90分</span> -->

                <span>{{ state.examInfo.passScore + '分' }}</span>

              </div>

            </div>

          </div>

          <div class="desc_item">

            <span class="label ft-bold">可考次数</span>

            <div class="item_input">

              <div class="select_item">

                <!-- <span>2次</span> -->

                <span>{{ state.examInfo.remainingExamTimes }}</span>

              </div>

            </div>

          </div>

          <div class="note">

            <span class="label">*</span>开始考试即消耗考试次数,无法暂停,若因网络波动或其他原因造成中途退出或无法交卷系统不记录成绩,需要重新考试,考试时请确保网络及手机可靠。

          </div>

        </div>

      </div>

  


    </div>

    <div class="next_step">

      <Button @click="startExam" :color="state.pkExamScheme ? '#007EF5' : '#ccc'" type="primary" round

        size="small">开始考试</Button>

    </div>

  


  </div>

</template>

<style lang="scss" scoped>

.new_booking {

  overflow: auto;

  width: 100%;

  height: 100%;

  font-weight: normal;

  background-color: #fff;

  


  // 园区信息

  .info_position {

    position: relative;

    display: flex;

    justify-content: space-between;

    height: 30px;

    line-height: 30px;

    margin: 0 12px;

    text-align: right;

    font-size: 12px;

    color: #333;

    z-index: 0;

  


    :deep(.van-notice-bar__left-icon) {

      text-align: left;

    }

  


    :deep(.van-notice-bar__wrap) {

      margin: 0 5px 0 0;

    }

  


    :deep(.van-notice-bar) {

      width: 100%;

      height: 30px;

      padding: 0;

    }

  


    .title_link {

      display: flex;

      align-items: center;

      width: auto;

      height: 30px;

  


      &>p {

        white-space: nowrap;

  


        &>span {

          border-bottom: 1px solid #333;

          margin-left: 4px;

        }

      }

  


      &>span {

        white-space: nowrap;

        margin-left: 4px;

      }

    }

  }

  


  .vehicle_info {

    padding: 0 12px;

    margin-bottom: 16px;

  


    .info_title {

      font-size: 16px;

      color: #474747;

    }

  


    .info_desc {

      // height:130px;

      margin: 10px 0;

      border: 1px solid #f4f4f4;

      border-radius: 6px;

      position: relative;

  


      // 车牌号码

      .desc_item {

        padding: 8px 12px;

        display: flex;

        align-items: center;

        // height: 28px;

        // margin-bottom: 12px;

        border-bottom: 1px solid #f4f4f4;

  


        &:last-child {

          margin-bottom: 0;

        }

  


        .label:nth-child(1) {

          width: 22%;

          color: #888888;

          // font-weight: 500;

          font-weight: bold;

          -webkit-font-smoothing: antialiased;

          -moz-osx-font-smoothing: grayscale;

          -webkit-text-rendering: optimizeLegibility;

          -moz-text-rendering: optimizeLegibility;

          text-rendering: optimizeLegibility;

          font-size: 14px;

          font-family: 'Microsoft YaHei', 'PingFangSC-Light', 'PingFang SC', 'STHeitiSC-Light', 'Helvetica-Light', 'Arial', 'sans-serif';

        }

  


        .label:nth-child(2) {

          width: 5%;

          color: red;

        }

  


        // 输入框

        .item_input {

          position: relative;

          display: flex;

          align-items: center;

          width: 77%;

          height: 100%;

  


          .belong {

            width: 6%;

            color: #007ef5;

            font-weight: 600;

            -webkit-font-smoothing: antialiased;

            -moz-osx-font-smoothing: grayscale;

            -webkit-text-rendering: optimizeLegibility;

            -moz-text-rendering: optimizeLegibility;

            text-rendering: optimizeLegibility;

            font-size: 14px;

            margin-right: 4px;

          }

  


          .arrow_icon {

            width: 5%;

          }

  


          .input_detail {

            width: 75%;

            border: none;

            margin-left: 4px;

            font-weight: bold;

            font-size: 14px;

            -webkit-font-smoothing: antialiased;

            -moz-osx-font-smoothing: grayscale;

            -webkit-text-rendering: optimizeLegibility;

            -moz-text-rendering: optimizeLegibility;

            text-rendering: optimizeLegibility;

  


            // text-indent: 10px;

            // &:focus {

            //   border-bottom: 1px solid #f4f4f4;

            // }

  


            &::-webkit-input-placeholder {

              font-weight: normal;

              font-size: 14px;

            }

          }

  


          .input_trailer {

            position: absolute;

            right: 50%;

            top: 0;

            font-weight: bold;

            color: #6f6f6f;

            line-height: 28px;

            font-size: 14px;

            -webkit-font-smoothing: antialiased;

            -moz-osx-font-smoothing: grayscale;

            -webkit-text-rendering: optimizeLegibility;

            -moz-text-rendering: optimizeLegibility;

            text-rendering: optimizeLegibility;

          }

  


          .valid_icon {

            display: flex;

            flex-direction: row-reverse;

            width: 16%;

            font-size: 14px;

            padding-right: 11px;

            // margin-left: 1px;

          }

  


          // 下拉

          .select_item {

            display: flex;

            flex-direction: row;

            align-items: center;

            // flex-direction: row-reverse;

            justify-content: space-between;

            width: 100%;

            height: 100%;

            // padding: 0 10px;

            // border: 1px solid #f4f4f4;

            border-radius: 4px;

            font-size: 14px;

            font-weight: bold;

            -webkit-font-smoothing: antialiased;

            -moz-osx-font-smoothing: grayscale;

            -webkit-text-rendering: optimizeLegibility;

            -moz-text-rendering: optimizeLegibility;

            text-rendering: optimizeLegibility;

          }

        }

  


        // 展开样式

        &.y_unfold {

          color: #98999c;

          display: flex;

          // height: 100%;

          justify-content: space-between !important;

          padding-right: 10px !important;

          font-size: 13px;

  


          .label:nth-child(1) {

            padding: 0 !important;

            width: 40% !important;

            text-align: center;

          }

  


          .van-icon-home-o:before {

            transform: rotate(180deg);

            vertical-align: 1px;

          }

  


        }

      }

  


      .desc_item:last-child {

        border-bottom: none;

        padding: 12px;

      }

    }

  


  }

  


  .info_last {

    .info_desc {

      .desc_item {

        padding: 12px;

  


      }

    }

  


    .note {

      padding: 12px;

      font-size: 12px;

      color: #6f6f6f;

      line-height: 16px;

  


      .label {

        width: 5%;

        color: red;

      }

    }

  }

  


  // 人员信息

  .personal_info {

    .input_name {

      width: 86%;

      border: none;

      padding-left: 0;

  


      &::-webkit-input-placeholder {

        font-weight: normal;

        color: #888888;

        padding-left: -1px;

      }

    }

  


    // 司机姓名

    .item_personal {

      &>input {

        width: 80%;

        height: 100%;

        border: 1px solid transparent;

        // padding: 0 14px;

        font-size: 14px;

  


        &:disabled {

          background: none !important;

          ;

        }

      }

  


      &>span {

        width: 20%;

        height: 80%;

        text-align: right;

  


        img {

          position: relative;

          left: -5px;

          width: 80%;

        }

      }

    }

  }

  


  // 提交

  .next_step {

    position: fixed;

    bottom: 0;

    left: 0;

    width: 100%;

    height: 60px;

    padding: 0 10px;

    background-color: #fff;

    z-index: 998;

    font-size: 15px;

    font-weight: 600;

  


    :deep(.van-button--round) {

      width: 100%;

      height: 36px;

      border-radius: 14px;

    }

  


    :deep(.van-button__content) {

      padding: 10px 14px;

    }

  }

}

  


input {

  &:disabled {

    background: none !important;

    ;

  }

}

</style>

<style lang="scss">

.item_input {

  .van-uploader__preview {

    width: 30%;

    height: 55px;

    margin-right: 2px !important;

  }

  


  .van-uploader__upload {

    margin-right: 0 !important;

  }

  


  .van-field__control {

    &::-webkit-input-placeholder {

      font-weight: normal;

      color: #888888;

      padding-left: -1px;

    }

  }

}

  


.info_desc {

  .van-swipe-cell__right {

    right: -1px !important;

  }

}

</style>