cycle-selection.vue 8.35 KB
<template>
  <van-config-provider :theme-vars="themeVars">
    <van-popup
      v-model:show="showPopup"
      position="center"
      :style="{ width: '85vw', maxWidth: '500px', borderRadius: '12px' }"
      :close-on-click-overlay="false"
    >
      <div class="cycle-popup-content">
        <div class="popup-header">
          <h3>选择周期</h3>
        </div>
        <div class="popup-content">
          <p class="cycle-note">{{ cycle_note }}</p>
          <van-radio-group v-model="selectedCycle">
            <div v-for="cycle in cycleList" :key="cycle.id" class="cycle-item">
              <van-radio :name="cycle.id">
                <template #icon="{ checked }">
                  <div class="custom-icon" :class="{ checked }">
                    <van-icon name="success" v-if="checked" />
                  </div>
                </template>
                <div class="cycle-info">
                  <div class="cycle-title">{{ cycle.title }}</div>
                  <div class="cycle-time">
                    <div v-if="cycle.start_date">活动开始时间: {{ cycle.start_date }}</div>
                    <div v-if="cycle.end_date">活动结束时间: {{ cycle.end_date }}</div>
                    <div v-if="cycle.reg_begin_time">报名开始时间: {{ cycle.reg_begin_time }}</div>
                    <div v-if="cycle.reg_end_time">报名结束时间: {{ cycle.reg_end_time }}</div>
                    <div v-if="cycle.description">说明: {{ cycle.description }}</div>
                  </div>
                </div>
              </van-radio>
            </div>
          </van-radio-group>
        </div>
        <div class="popup-footer">
          <van-button
            type="primary"
            block
            round
            @click="confirmCycleSelection"
            :disabled="!selectedCycle"
          >
            确认选择
          </van-button>
        </div>
      </div>
    </van-popup>
  </van-config-provider>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { getCycleListAPI } from '@/api/cycle';
import { styleColor } from '@/constant.js';
import { showUnfinishedFormDialog } from '@/utils/dialogControl.js';
import Cookies from 'js-cookie';

const $router = useRouter();
const $route = useRoute();

// 主题配置
const themeVars = {
  // 主色调配置
  radioCheckedIconColor: styleColor.baseColor,
  buttonPrimaryBackground: styleColor.baseColor,
  buttonPrimaryBorderColor: styleColor.baseColor,
};

// 周期选择相关变量
const cycleList = ref([]);
const selectedCycle = ref('');
const cycle_note = ref('');
const showPopup = ref(false);



/**
 * 获取周期列表
 * @param {string} form_code 表单唯一标识
 */
const getCycleList = async (form_code) => {
  try {
    const { data } = await getCycleListAPI({ form_code });
    if (data.is_cycle) {
      if (!data.cycle_list || data.cycle_list.length === 0) {
        // 如果is_cycle是true但cycle_list为空,跳转到停用页面
        $router.push("/stop?status=disable");
        return;
      }
      // 设置周期列表
      cycleList.value = data.cycle_list;
      cycle_note.value = data.cycle_note;
      // 显示弹框
      showPopup.value = true;
    } else {
      // 如果不需要周期选择,检查未完成表单后跳转到目标页面
      const targetRoute = sessionStorage.getItem('cycle_target_route');
      if (targetRoute) {
        sessionStorage.removeItem('cycle_target_route');
        const route = JSON.parse(targetRoute);

        // 调试信息:检查不需要周期选择时的路由对象
        console.log('不需要周期选择时的路由对象:', route);
        console.log('不需要周期选择时的查询参数:', route.query);
        console.log('不需要周期选择时的code参数:', route.query.code);

        // 检查是否需要显示未完成表单弹框
        checkUnfinishedForm(route);
      } else {
        $router.replace({
          path: '/',
          query: {
            ...$route.query
          }
        });
      }
    }
  } catch (error) {
    console.error('获取周期列表失败:', error);
  }
};

/**
 * 确认选择周期
 */
const confirmCycleSelection = () => {
  if (selectedCycle.value) {
    // 获取目标路由
    const targetRoute = sessionStorage.getItem('cycle_target_route');
    if (targetRoute) {
      const route = JSON.parse(targetRoute);
      // 添加周期参数
      route.query = {
        ...route.query,
        x_cycle: selectedCycle.value,
        cycle_selected: '1'
      };

      // 调试信息:检查route对象内容
      console.log('周期选择后的路由对象:', route);
      console.log('查询参数:', route.query);
      console.log('code参数:', route.query.code);

      // 清除临时存储
      sessionStorage.removeItem('cycle_target_route');

      // 检查是否需要显示未完成表单弹框
      checkUnfinishedForm(route);
    } else {
      // 如果没有目标路由,跳转到首页
      $router.replace({
        path: '/',
        query: {
          ...$route.query,
          x_cycle: selectedCycle.value,
          cycle_selected: '1'
        }
      });
    }
  }
};

/**
 * 检查未完成的表单信息
 * @param {Object} route 目标路由对象
 */
const checkUnfinishedForm = (route) => {
    // TAG: 屏蔽未完成弹框功能
    // 新增:在显示未完成表单弹框之前,对 leader 来源进行特殊处理
    // 如果是新增页面或未指定类型,并且来源为 leader,则提前清理未完成表单的 Cookie,避免弹框
    if ((route.query.page_type === 'add' || route.query.page_type === undefined) && (route.query.volunteer_source === 'leader')) {
        if (route.query.code) {
            Cookies.remove(route.query.code);
        }
    }
  // 只在新增状态时检查
  if (route.query.page_type === 'add' || route.query.page_type === undefined) {
    const existingCookie = Cookies.get(route.query.code);
    if (existingCookie && route.query.force_back !== '1') {
      // 显示确认对话框
      showUnfinishedFormDialog(
        () => {
          // 用户选择继续,跳转到目标页面
          $router.replace(route);
        },
        () => {
          // 用户选择删除,删除cookie并跳转到首页
          Cookies.remove(route.query.code);
          $router.replace({
            path: '/',
            query: {
              ...route.query,
              x_cycle: selectedCycle.value,
              cycle_selected: '1'
            }
          });
        },
        route.query.code
      );
    } else {
      // 没有未完成的表单,直接跳转
      $router.replace(route);
    }
  } else {
    // 不是新增状态,直接跳转
    $router.replace(route);
  }
};

onMounted(() => {
  const form_code = $route.query.code;
  if (form_code) {
    getCycleList(form_code);
  } else {
    console.error('缺少表单代码参数');
    $router.replace('/');
  }
});
</script>

<style lang="less">
.cycle-popup-content {
  display: flex;
  flex-direction: column;
  max-height: 70vh;

  .popup-header {
    padding: 20px;
    text-align: center;
    border-bottom: 1px solid #eee;
    flex-shrink: 0;

    h3 {
      margin: 0;
      font-size: 18px;
      font-weight: 600;
      color: #333;
    }
  }

  .popup-content {
    flex: 1;
    overflow-y: auto;
    padding: 0 20px;
    min-height: 0;
  }

  .cycle-note {
    padding-top: 0.85rem;
    text-align: justify;
    margin-bottom: 1rem;
    color: #666;
    line-height: 1.5;
  }

  .cycle-item {
    padding: 15px 0;
    border-bottom: 1px solid #f5f5f5;

    &:last-child {
      border-bottom: none;
    }
  }

  .cycle-info {
    margin-left: 10px;
  }

  .cycle-title {
    font-size: 16px;
    font-weight: 500;
    color: #333;
    margin-bottom: 8px;
  }

  .cycle-time {
    font-size: 14px;
    color: #666;
    line-height: 1.5;

    div {
      margin-bottom: 4px;

      &:last-child {
        margin-bottom: 0;
      }
    }
  }

  .popup-footer {
    padding: 20px;
    border-top: 1px solid #eee;
    flex-shrink: 0;
  }

  .custom-icon {
    width: 20px;
    height: 20px;
    border: 2px solid #ddd;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s;

    &.checked {
      border-color: var(--van-radio-checked-icon-color);
      background-color: var(--van-radio-checked-icon-color);
      color: white;
    }
  }
}
</style>