DeliveryMethod.vue 5.61 KB
<template>
  <div class="delivery-method-selector">
    <el-radio-group
      v-model="selectedMethod"
      class="method-group"
      @change="handleChange"
    >
      <el-radio
        v-for="method in deliveryMethods"
        :key="method.value"
        :label="method.value"
        :border="true"
        class="method-radio"
      >
        <div class="method-content">
          <div class="method-icon">
            <el-icon :size="28">
              <component :is="method.icon" />
            </el-icon>
          </div>
          <div class="method-text">
            <div class="method-name">{{ method.name }}</div>
            <div class="method-desc">{{ method.desc }}</div>
            <div class="method-hint">
              <el-tag
                :type="method.tagType"
                size="small"
                effect="plain"
              >
                {{ method.hint }}
              </el-tag>
            </div>
          </div>
        </div>
      </el-radio>
    </el-radio-group>
    
    <!--    &lt;!&ndash; 方式说明 &ndash;&gt;-->
    <!--    <div v-if="selectedMethod === 'email'" class="method-notice">-->
    <!--      <el-alert-->
    <!--        title="电子发票说明"-->
    <!--        type="success"-->
    <!--        :closable="false"-->
    <!--        show-icon-->
    <!--      >-->
    <!--        <ul class="notice-list">-->
    <!--          <li>环保便捷,无纸化办公</li>-->
    <!--          <li>开具后立即发送至邮箱</li>-->
    <!--          <li>支持下载、打印,具有同等法律效力</li>-->
    <!--          <li>可通过邮件中的链接验证真伪</li>-->
    <!--          <li>建议将邮件添加至白名单,避免被误判为垃圾邮件</li>-->
    <!--        </ul>-->
    <!--      </el-alert>-->
    <!--    </div>-->
    <!--    -->
    <!--    <div v-else class="method-notice">-->
    <!--      <el-alert-->
    <!--        title="纸质发票说明"-->
    <!--        type="warning"-->
    <!--        :closable="false"-->
    <!--        show-icon-->
    <!--      >-->
    <!--        <ul class="notice-list">-->
    <!--          <li>需提供准确完整的邮寄信息</li>-->
    <!--          <li>邮寄时间:7-15个工作日</li>-->
    <!--          <li>使用顺丰快递邮寄,免邮费</li>-->
    <!--          <li>发票为普通发票或专用发票(根据开票类型)</li>-->
    <!--          <li>如地址变更,请在开票前联系客服修改</li>-->
    <!--        </ul>-->
    <!--      </el-alert>-->
    <!--    </div>-->
  </div>
</template>

<script setup>
import { computed } from 'vue'

// Props
const props = defineProps({
  modelValue: {
    type: String,
    default: 'email'
  }
})

// Emits
const emit = defineEmits(['update:modelValue', 'delivery-change'])

// 计算属性
const selectedMethod = computed({
  get: () => props.modelValue,
  set: (value) => {
    emit('update:modelValue', value)
  }
})

// 接收方式配置
const deliveryMethods = [
  {
    value: 'email',
    name: '电子发票',
    desc: '发送至短信',
    hint: '推荐',
    tagType: 'success',
    icon: 'Message'
  }
  // {
  //   value: 'paper',
  //   name: '纸质发票',
  //   desc: '邮寄纸质发票',
  //   hint: '7-15个工作日',
  //   tagType: 'warning',
  //   icon: 'DocumentCopy'
  // }
]

// 方法
const handleChange = (value) => {
  emit('delivery-change', value)
}
</script>

<style scoped lang="scss">
.delivery-method-selector {
  width: 100%;
}

.method-group {
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
  width: 100%;
}

.method-radio {
  flex: 1;
  min-width: 200px;
  height: auto;
  margin: 0;
  padding: 0;
  border: none;
}

:deep(.method-radio .el-radio__input) {
  display: none;
}

:deep(.method-radio .el-radio__label) {
  padding: 0;
  width: 100%;
}

.method-content {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 20px;
  width: 100%;
  border: 2px solid #e4e7ed;
  border-radius: 8px;
  transition: all 0.3s ease;
  cursor: pointer;
  min-height: 100px;
}

.method-radio:not(.is-disabled) .method-content:hover {
  border-color: #409eff;
  background-color: #f5f7ff;
}

:deep(.method-radio.is-checked .method-content) {
  border-color: #409eff;
  background-color: #f0f6ff;
  box-shadow: 0 0 0 1px #409eff inset;
}

.method-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 60px;
  height: 60px;
  background-color: #f5f7ff;
  border-radius: 12px;
  color: #409eff;
  flex-shrink: 0;
}

:deep(.method-radio.is-checked .method-icon) {
  background-color: #409eff;
  color: white;
}

.method-text {
  flex: 1;
  min-width: 0;
}

.method-name {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 6px;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.method-desc {
  font-size: 13px;
  color: #909399;
  line-height: 1.4;
  margin-bottom: 8px;
}

.method-hint {
  margin-top: 4px;
}

.method-notice {
  margin-top: 20px;
  animation: fadeIn 0.3s ease;
}

.notice-list {
  list-style: none;
  padding: 0;
  margin: 8px 0 0 0;
  font-size: 13px;
  line-height: 1.6;
  color: #606266;
}

.notice-list li {
  padding: 4px 0;
  position: relative;
  padding-left: 16px;
}

.notice-list li:before {
  content: "✓";
  color: #409eff;
  position: absolute;
  left: 0;
  font-size: 12px;
  font-weight: bold;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .method-group {
    flex-direction: column;
  }
  
  .method-radio {
    min-width: 100%;
  }
  
  .method-content {
    padding: 15px;
  }
}
</style>