next.vue 7.16 KB
<!--
 * @Date: 2023-08-22 14:13:07
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2023-08-25 17:07:08
 * @FilePath: /bieyuan/src/views/next.vue
 * @Description: 文件描述
-->
<template>
  <div class="next-page">
    <van-form @submit="onSubmit">
      <div v-for="(item, index) in userInfo" :key="index" class="input-box">
        <p class="title">{{ index + 1 }}.{{ index === 0 ? '我的信息' : '同行人' }}</p>
        <van-field :id="'name' + index" v-model="item.name" label="姓名:" type="text" placeholder="请输入姓名" :border="false"
          :rules="[{ required: true, message: '请填写姓名' }]" label-width="4em" class="input-text" @focus="onFocus"  @keydown="handleKeyDown" />
        <van-field :id="'phone' + index" v-model="item.phone" label="手机号:" type="digit" placeholder="请输入手机号" :border="false"
          :rules="[{ validator: validatorPhone, message: '请输入正确手机号' }]" label-width="4em" class="input-text"  @focus="onFocus"  @keydown="handleKeyDown" />
        <van-field label="证件类型:" :border="false" label-width="4.5em">
          <template #input>
            <van-radio-group v-model="item.id_type" direction="horizontal" checked-color="#93663D" style="height: 2.5rem;">
              <van-radio name="id_card">身份证</van-radio>
              <van-radio name="passport">护照</van-radio>
            </van-radio-group>
          </template>
        </van-field>
        <van-field :id="'id_type' + index" v-if="item.id_type === 'id_card'" v-model="item.id_number" label="身份证:" type="text" placeholder="请输入身份证号" :border="false"
          :rules="[{ validator: validatorId, message: '请填写正确身份证号' }]" label-width="4em" class="input-text"  @focus="onFocus"  @keydown="handleKeyDown" />
        <van-field :id="'id_type' + index" v-else v-model="item.id_number" label="护照:" type="text" placeholder="请输入护照号" :border="false"
            :rules="[{ required: true, message: '请填写正确护照号' }]" label-width="4em" class="input-text"  @focus="onFocus"  @keydown="handleKeyDown" />
      </div>
      <div style="padding: 2rem;">
        <van-button block type="primary" color="#93663D" native-type="submit">
          提交
        </van-button>
      </div>
    </van-form>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { useRoute, useRouter, onBeforeRouteLeave } from 'vue-router'
import { isIdCard, isPhone } from 'xijs';
import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js'
//import { } from '@/utils/generateModules.js'
//import { } from '@/utils/generateIcons.js'
//import { } from '@/composables'
import { orderDetailMyLastAPI } from '@/api/index'
import { showSuccessToast, showFailToast } from 'vant';
const $route = useRoute();
const $router = useRouter();
useTitle($route.meta.title);

const store = mainStore();
const { appUserInfo } = storeToRefs(store);

// // 监听路由离开
// onBeforeRouteLeave((to, from, next) => {
//   console.warn('leave');
//   next()
// })

const userInfo = ref([]); // 用户预约信息
const num = ref(1);
const keyDownList = ref([])

onMounted(async () => {
  num.value = $route.query.count ? +$route.query.count : 1;
  if (appUserInfo.value.length) { // 如果有填写缓存需要把数据还原
    userInfo.value = appUserInfo.value;
    if (num.value > appUserInfo.value.length) { // 新增预约数大于原来的预约数
      let new_count = num.value - appUserInfo.value.length;
      for (let index = 0; index < new_count; index++) {
        userInfo.value.push({
          name: '',
          phone: '',
          id_type: 'id_card',
          id_number: '',
        })
      }
    } else { // 新增预约数小于原来的预约数
      let new_count = appUserInfo.value.length - num.value;
      userInfo.value.splice(-new_count, new_count); // 从后往前删除指定数量
    }
  } else {
    // 根据预约数构造空结构
    for (let index = 0; index < num.value; index++) {
      userInfo.value.push({
        name: '',
        phone: '',
        id_type: 'id_card',
        id_number: '',
      })
    }
    // 查询用户是否填写过申请,如果有把个人信息直接填进去
    const { data } = await orderDetailMyLastAPI();
    if (data) {
      userInfo.value[0] = data;
    }
  }
  //
  for (let index = 0; index < userInfo.value.length; index++) {
    // const element = keyDownList[index];
    const arr = ['name', 'phone', 'id_type']
    for (let idx = 0; idx < arr.length; idx++) {
      const element = arr[idx] + index;
      keyDownList.value.push(element)
    }
  }
});

// 点击换行功能
const currentIndex = ref('');
const onFocus = (evt) => {
  const currentId = $(evt.target).attr('id');
  currentIndex.value = keyDownList.value.indexOf(currentId);
}
const handleKeyDown = (evt) => {
  //
  if (evt.keyCode === 13) {
    const id = `input#${keyDownList.value[currentIndex.value + 1]}`;
    if (id) {
      $(id).focus()
    }
  }
}

/**
 * 手机号码校验
 * 函数返回 true 表示校验通过,false 表示不通过
 * @param {*} val
 */
const validatorPhone = (val) => {
  let flag = false;
  // 简单判断手机号位数
  if (isPhone(val)) {
    flag = true;
  } else {
    flag = false;
  }
  return flag
};

const validatorId = (val) => {
  let flag = false;
  // 简单判断手机号位数
  if (isIdCard(val)) {
    flag = true;
  } else {
    flag = false;
  }
  return flag
};

const onSubmit = async () => {
  // 提交预约信息
  axios.post('/srv/?a=order_add', {
    dates: JSON.parse($route.query.dates),
    details: userInfo.value
  })
    .then(res => {
      if (res.data.code === 1) {
        // 跳转结果页
        $router.push({
          path: '/result',
          query: {
            id: res.data.data.id
          }
        })
      } else { // 预约不足返回上页面缓存信息
        console.warn(res);
        showFailToast({
          message: res.data.msg,
          onClose: () => {
            // TAG: 缓存用户填写信息
            store.changeUserInfo(userInfo.value);
            if ($route.query.page === 'single') { // 返回首页
              $router.push({
                path: '/',
                query: {
                  dates: $route.query.dates,
                  count: $route.query.count,
                  page: 'single'
                }
              });
            } else { // 返回日历选择页
              $router.push({
                path: '/preview',
                query: {
                  dates: $route.query.dates,
                  count: $route.query.count
                }
              });
            }
          }
        });
      }
    })
    .catch(err => {
      console.error(err);
    });
};

</script>

<style lang="less" scoped>
.next-page {
  padding: 1rem 1rem 0;
}

:deep(.van-field__label) {
  color: #976C46;
  font-weight: bold;
  line-height: 2.5rem;
}

:deep(.input-text .van-field__body) {
  border: 1px solid #D7D7D7;
  padding: 0.25rem;
}

.input-box {
  &:after {
    content: '';
    display: block;
    border-bottom: 1px solid #D7D7D7;
    margin: 1rem 0;
  }

  .title {
    text-align: center;
    font-size: 1.25rem;
    margin-bottom: 1rem;
  }
}
</style>