index.vue 8.25 KB
<!--
 * @Date: 2022-09-19 14:11:06
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2025-08-05 15:29:14
 * @FilePath: /jgdl/src/pages/collectionSettings/index.vue
 * @Description: 收款设置
-->
<template>
  <view class="collection-settings">

    <!-- 设置列表 -->
    <view class="settings-list">
      <!-- 收款账号 -->
      <view class="setting-item" @click="openAccountModal">
        <view class="setting-left">
          <text class="setting-label">收款账号</text>
        </view>
        <view class="setting-right">
          <text class="setting-status" :class="{ 'status-set': accountInfo.bankName }">
            {{ accountInfo.bankName ? '已设置' : '未设置' }}
          </text>
          <text class="arrow">></text>
        </view>
      </view>

      <!-- 身份信息 -->
      <view class="setting-item" @click="openIdentityModal">
        <view class="setting-left">
          <text class="setting-label">身份信息</text>
        </view>
        <view class="setting-right">
          <text class="setting-status" :class="{ 'status-set': identityInfo.userName }">
            {{ identityInfo.userName ? '已设置' : '未设置' }}
          </text>
          <text class="arrow">></text>
        </view>
      </view>
    </view>

    <!-- 收款账号弹窗 -->
    <nut-popup
      v-model:visible="showAccountModal"
      position="bottom"
      :style="{ width: '100%', height: '80%' }"
      closeable
      close-icon-position="top-right"
      @close="closeAccountModal"
    >
      <view class="modal-content">
        <view class="modal-header">
          <text class="modal-title">收款账号设置</text>
        </view>

        <view class="form-content">
          <view class="form-item">
            <text class="form-label">银行名称</text>
            <nut-input
              v-model="tempAccountInfo.bankName"
              placeholder="请输入银行名称"
              class="form-input"
            />
          </view>

          <view class="form-item">
            <text class="form-label">银行账号</text>
            <nut-input
              v-model="tempAccountInfo.bankAccount"
              placeholder="请输入银行账号"
              class="form-input"
              type="number"
            />
          </view>
        </view>

        <view class="modal-footer">
          <nut-button
            type="default"
            @click="closeAccountModal"
            class="footer-btn footer-btn-cancel"
          >
            关闭
          </nut-button>
          <nut-button
            type="primary"
            @click="saveAccountInfo"
            color="#ffa500"
            :disabled="!tempAccountInfo.bankName || !tempAccountInfo.bankAccount"
            class="footer-btn footer-btn-save"
          >
            保存
          </nut-button>
        </view>
      </view>
    </nut-popup>

    <!-- 身份信息弹窗 -->
    <nut-popup
      v-model:visible="showIdentityModal"
      position="bottom"
      :style="{ width: '100%', height: '80%' }"
      closeable
      close-icon-position="top-right"
      @close="closeIdentityModal"
    >
      <view class="modal-content">
        <view class="modal-header">
          <text class="modal-title">身份信息设置</text>
        </view>

        <view class="form-content">
          <view class="form-item">
            <text class="form-label">用户名称</text>
            <nut-input
              v-model="tempIdentityInfo.userName"
              placeholder="请输入真实姓名"
              class="form-input"
            />
          </view>

          <view class="form-item">
            <text class="form-label">身份证号码</text>
            <nut-input
              v-model="tempIdentityInfo.idCard"
              placeholder="请输入身份证号码"
              class="form-input"
              maxlength="18"
              @blur="handleIdCardBlur"
            />
            <text v-if="idCardError" class="error-text">{{ idCardError }}</text>
          </view>
        </view>

        <view class="modal-footer">
          <nut-button
            type="default"
            @click="closeIdentityModal"
            class="footer-btn footer-btn-cancel"
          >
            关闭
          </nut-button>
          <nut-button
            type="primary"
            @click="saveIdentityInfo"
            color="#ffa500"
            :disabled="!tempIdentityInfo.userName || !tempIdentityInfo.idCard || !!idCardError"
            class="footer-btn footer-btn-save"
          >
            保存
          </nut-button>
        </view>
      </view>
    </nut-popup>
  </view>
</template>

<script setup>
import { ref } from "vue";
import Taro from "@tarojs/taro";
import "./index.less";

/**
 * 收款账号信息
 */
const accountInfo = ref({
  bankName: '',
  bankAccount: ''
});

/**
 * 身份信息
 */
const identityInfo = ref({
  userName: '',
  idCard: ''
});

/**
 * 临时收款账号信息(用于弹窗编辑)
 */
const tempAccountInfo = ref({
  bankName: '',
  bankAccount: ''
});

/**
 * 临时身份信息(用于弹窗编辑)
 */
const tempIdentityInfo = ref({
  userName: '',
  idCard: ''
});

/**
 * 弹窗显示状态
 */
const showAccountModal = ref(false);
const showIdentityModal = ref(false);

/**
 * 身份证号码错误信息
 */
const idCardError = ref('');

/**
 * 身份证号码校验
 * @param {string} idCard - 身份证号码
 * @returns {boolean} - 是否有效
 */
const validateIdCard = (idCard) => {
  if (!idCard) {
    return { valid: false, error: '请输入身份证号码' };
  }

  // 身份证号码正则表达式
  const idCardRegex = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;

  if (!idCardRegex.test(idCard)) {
    return { valid: false, error: '身份证号码格式不正确' };
  }

  // 校验码验证
  const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
  const checkCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];

  let sum = 0;
  for (let i = 0; i < 17; i++) {
    sum += parseInt(idCard[i]) * weights[i];
  }

  const checkCode = checkCodes[sum % 11];
  const lastChar = idCard[17].toUpperCase();

  if (checkCode !== lastChar) {
    return { valid: false, error: '身份证号码校验失败' };
  }

  return { valid: true, error: '' };
};

/**
 * 处理身份证号码失焦事件
 */
const handleIdCardBlur = () => {
  const idCard = tempIdentityInfo.value.idCard;
  if (idCard) {
    const result = validateIdCard(idCard);
    idCardError.value = result.error;
  } else {
    idCardError.value = '';
  }
};

/**
 * 打开收款账号弹窗
 */
const openAccountModal = () => {
  tempAccountInfo.value = { ...accountInfo.value };
  showAccountModal.value = true;
};

/**
 * 关闭收款账号弹窗
 */
const closeAccountModal = () => {
  showAccountModal.value = false;
  tempAccountInfo.value = { bankName: '', bankAccount: '' };
};

/**
 * 保存收款账号信息
 */
const saveAccountInfo = () => {
  if (!tempAccountInfo.value.bankName || !tempAccountInfo.value.bankAccount) {
    Taro.showToast({
      title: '请填写完整信息',
      icon: 'none'
    });
    return;
  }

  accountInfo.value = { ...tempAccountInfo.value };
  closeAccountModal();

  Taro.showToast({
    title: '保存成功',
    icon: 'success'
  });
};

/**
 * 打开身份信息弹窗
 */
const openIdentityModal = () => {
  tempIdentityInfo.value = { ...identityInfo.value };
  idCardError.value = '';
  showIdentityModal.value = true;
};

/**
 * 关闭身份信息弹窗
 */
const closeIdentityModal = () => {
  showIdentityModal.value = false;
  tempIdentityInfo.value = { userName: '', idCard: '' };
  idCardError.value = '';
};

/**
 * 保存身份信息
 */
const saveIdentityInfo = () => {
  if (!tempIdentityInfo.value.userName || !tempIdentityInfo.value.idCard) {
    Taro.showToast({
      title: '请填写完整信息',
      icon: 'none'
    });
    return;
  }

  const validation = validateIdCard(tempIdentityInfo.value.idCard);
  if (!validation.valid) {
    Taro.showToast({
      title: validation.error,
      icon: 'none'
    });
    return;
  }

  identityInfo.value = { ...tempIdentityInfo.value };
  closeIdentityModal();

  Taro.showToast({
    title: '保存成功',
    icon: 'success'
  });
};
</script>

<script>
export default {
  name: "collectionSettings",
};
</script>