# PressConvertExchangeTemplate 兑换模板组件

# 📦 组件简介

PressConvertExchangeTemplate 是一个封装了兑换列表和积分消耗的模板组件,整合了 press-convert-exchange-listpress-convert-point-cost 两个子组件,提供了完整的积分兑换功能。

✨ 架构优势:

  • Mixin 共享逻辑 - 避免重复代码
  • 独立模板文件 - 支持不同的 DOM 结构
  • Props 自动透传 - 使用 v-bind="{ ...$props, ...$attrs }" 和显式事件转发
  • 易于维护和扩展 - 修改逻辑只需改 mixin,修改结构只需改对应模板

# 🏗️ 架构设计

# 文件结构

press-convert-exchange-template/
├── press-convert-exchange-template.vue  # 主组件(负责路由分发)
├── template-mixin.js                    # 公共逻辑 Mixin
├── pwd/
│   └── index.vue                       # PWD 模板(独立DOM结构)
├── party/
│   └── index.vue                       # Party 模板(独立DOM结构)
├── demo.vue                             # 示例代码
└── README.md                            # 使用文档

# 架构原理

┌─────────────────────────────────────────────┐
│  press-convert-exchange-template.vue        │
│  (主组件 - 负责分发)                         │
│                                             │
│  <TemplatePwd v-if="type === 'pwd'" ... />  │
│  <TemplateParty v-else ... />               │
└──────────┬──────────────────────────────────┘
           │
           ├─── type="pwd" ──→ pwd/index.vue (PWD模板)
           │                    ├─ mixins: [templateMixin]
           │                    ├─ 独立的 DOM 结构
           │                    └─ 独有 prop: pwdWrapBg
           │
           └─── type="party" ──→ party/index.vue (Party模板)
                                  ├─ mixins: [templateMixin]
                                  └─ 独立的 DOM 结构

┌─────────────────────────────────────┐
│  template-mixin.js                  │
│  (公共逻辑 - 被所有模板共享)         │
│                                     │
│  - props 定义                       │
│  - emits 定义                       │
│  - methods (事件处理)               │
│  - components (子组件注册)          │
└─────────────────────────────────────┘

# 模板布局结构

两个模板的 DOM 布局均为:

┌─────────────────────┐
│   point-cost        │  ← 积分信息 + 刷新按钮
│     <slot />        │  ← 默认插槽(在积分区域内)
├─────────────────────┤
│   exchange-list     │  ← 兑换商品列表
└─────────────────────┘

# 🎯 功能特性

  • ✅ 支持 2 种预设模板(PWD/Party),每个模板有独立的 DOM 结构
  • ✅ 兑换列表展示
  • ✅ 积分信息显示
  • ✅ 插槽扩展支持
  • ✅ 事件回调处理
  • ✅ Mixin 共享逻辑,避免代码重复

# 📖 使用方法

# 基础用法 - 使用 PWD 模板

<template>
  <PressConvertExchangeTemplate
    type="pwd"
    :exchange-list="exchangeList"
    :point-icon="pointIcon"
    :point-info="pointInfo"
    @exchangeClick="handleExchangeClick"
    @showRewardExplain="handleShowRewardExplain"
    @refresh="handleRefresh"
  />
</template>

<script>
import PressConvertExchangeTemplate from 'press-plus/press-convert-exchange-template/press-convert-exchange-template';

export default {
  components: {
    PressConvertExchangeTemplate,
  },
  data() {
    return {
      pointIcon: 'https://example.com/point-icon.png',
      exchangeList: [
        {
          pic: 'https://example.com/reward.png',
          name: '100元优惠券',
          need_money: 1000,
          num: 50,
          showMoney: true,
          btnTxt: '立即兑换',
          disabled: false,
        },
      ],
      pointInfo: {
        pointIcon: 'https://example.com/point-icon.png',
        pointCount: 5000,
        expireTime: '30天',
      },
    };
  },
  methods: {
    handleExchangeClick(item) {
      console.log('兑换商品:', item);
    },
    handleShowRewardExplain(index) {
      console.log('显示奖励说明:', index);
    },
    handleRefresh() {
      console.log('刷新积分');
    },
  },
};
</script>

# 切换不同模板

<!-- PWD 模板 - PWD 专属布局 -->
<PressConvertExchangeTemplate type="pwd" ... />

<!-- Party 模板 - Party 狂欢布局 -->
<PressConvertExchangeTemplate type="party" ... />

# 使用插槽

默认插槽位于 point-cost 组件内部(积分信息区域中)。

<PressConvertExchangeTemplate
  type="pwd"
  :exchange-list="exchangeList"
  :point-icon="pointIcon"
  :point-info="pointInfo"
>
  <div class="custom-content">
    <button @click="handleCustomAction">
      查看更多奖励
    </button>
  </div>
</PressConvertExchangeTemplate>

# 📋 Props 属性

# 模板配置

属性名 类型 默认值 说明
type String 'pwd' 模板类型:'pwd' / 'party'

# 兑换列表相关

属性名 类型 默认值 说明
exchangeList Array [] 兑换列表数据
pointIcon String '' 积分图标 URL
exchangeListBg String '' 兑换列表背景图
tagBg String '' 兑换列表标签背景图
redeemRewardBg String '' 奖励框背景图
rewardTextColor String '' 奖励文字颜色
rewardBtnBg String '' 奖励按钮背景图
rewardBtnTextColor String '' 奖励按钮文字颜色

# 积分消耗相关

属性名 类型 默认值 说明
pointInfo Object {} 积分信息对象
pointTextColor String '' 积分文字颜色

# PWD 模板独有

属性名 类型 默认值 说明
pwdWrapBg String '' PWD 模板外层容器背景图

# exchangeList 数据结构

[
  {
    pic: 'https://example.com/reward.png',  // 奖励图片
    name: '100元优惠券',                     // 奖励名称
    need_money: 1000,                        // 所需积分
    num: 50,                                 // 剩余数量
    showMoney: true,                         // 是否显示积分
    btnTxt: '立即兑换',                      // 按钮文字
    disabled: false,                         // 是否禁用
  }
]

# pointInfo 数据结构

{
  pointIcon: 'https://example.com/point-icon.png',  // 积分图标
  pointCount: 5000,                                  // 积分数量
  expireTime: '30天',                                // 过期时间,显示为"X后失效",0表示不过期
}

# 🎪 Events 事件

事件名 参数 说明
exchangeClick item: Object 点击兑换按钮时触发,返回兑换项数据
showRewardExplain index: Number 点击奖励图片时触发,返回索引
refresh - 点击刷新按钮时触发

# 🎨 Slots 插槽

插槽名 说明
default 默认插槽,位于 point-cost 积分信息区域内部

# 💡 模板差异说明

# PWD 模板 (pwd/index.vue)

布局:

积分信息(point-cost)
  └─ <slot />
兑换列表(exchange-list)

特点:

  • 支持 pwdWrapBg 外层背景图
  • 适合 PWD 活动场景

# Party 模板 (party/index.vue)

布局:

积分信息(point-cost)
  └─ <slot />
兑换列表(exchange-list)

特点:

  • 适合派对活动场景

# 🔧 扩展新模板

# 步骤 1:创建新模板目录和文件 festival/index.vue

<template>
  <div class="press-exchange-festival">
    <point-cost
      :point-info="pointInfo"
      :text-color="pointTextColor"
      @refresh="handleRefresh"
    >
      <slot />
    </point-cost>
    <exchange-list
      :exchange-list="exchangeList"
      :point-icon="pointIcon"
      :exchange-list-bg="exchangeListBg"
      :tag-bg="tagBg"
      :redeem-reward-bg="redeemRewardBg"
      :reward-text-color="rewardTextColor"
      :reward-btn-bg="rewardBtnBg"
      :reward-btn-text-color="rewardBtnTextColor"
      @exchangeClick="handleExchangeClick"
      @showRewardExplain="handleShowRewardExplain"
    />
  </div>
</template>

<script>
import templateMixin from '../template-mixin';

export default {
  name: 'PressExchangeTemplateFestival',
  mixins: [templateMixin],
};
</script>

# 步骤 2:在主组件中注册

// press-convert-exchange-template.vue
import TemplateFestival from './festival/index.vue';

export default {
  components: {
    TemplatePwd,
    TemplateParty,
    TemplateFestival,
  },
  props: {
    type: {
      validator: value => ['pwd', 'party', 'festival'].includes(value),
    },
  },
};

# 📝 注意事项

  1. 修改公共逻辑 - 修改 template-mixin.js 会影响所有模板
  2. 修改模板结构 - 修改 pwd/index.vueparty/index.vue 只影响对应模板
  3. Props 自动透传 - 主组件的 props 会自动传递给子模板
  4. 事件自动透传 - 子模板的事件会自动冒泡到主组件
  5. 图片 URL 需要是有效的网络地址或本地路径
  6. 建议在兑换前进行积分余额校验和库存校验

# 📦 依赖组件

  • press-convert-exchange-list - 兑换列表组件
  • press-convert-point-cost - 积分消耗组件