集成电商场景

本文介绍电商场景业务流程,及常见功能例如商品入口、商品卡片、商品列表等具体实现。

前置条件

  • 已了解互动课堂场景,详见简介

  • 已完成互动课堂服务端集成,详见服务端集成

  • 已完成互动课堂客户端集成,详见Web端接入

概述

互动课堂集成电商,是在互动课堂的基础之上,增加了电商功能。

互动行为

互动课堂在集成电商的情况下,增加了以下互动行为:

角色

互动行为

商品运营

  • 直播前,在后台设置商品信息

  • 直播时,在教师需要上链接时,商品运营可在后台请求下发商品卡片,AppServer 通过 IMServer 向学员下发信令,信令的数据部分包含商品信息

教师

  • 直播开始前或直播中,请求已配置的商品列表

  • 直播中,上链接给学员推荐商品,将商品信息广播给教室里的学员

助教

  • 参与教室的互动,且具备上链接的能力

  • 在教师需要上链接时,把商品信息广播给教室里的学员

学员

  • 进入教室时,如果当前教室已经上过链接,则直接展示商品卡片

  • 观看直播时,收到展示卡片的信令时,直接展示商品卡片

流程图

互动流程如下:

image

商品卡片

教室中的商品卡片一般用于展示教师推介商品的核心信息,一般包含标题、描述、封面、购买地址等。商品卡片的信息会经 IM 下发给学员端,所以我们需要定义一个消息类型,和自定义一个商品卡片的消息结构体。

下发商品卡片消息类型

export enum CustomMessageTypes {
  ..., // AUI互动课堂已定义的消息类型,这里不再列出
  ShoppingProduct = 30011,  // 电商卡片消息
}

定义商品卡片 Class

export interface ClassRoomProductConfig {
  productId: string; // 商品id
  title: string; // 商品标题
  info: string; // 商品描述
  coverUrl: string; // 商品封面URL
  sellUrl: string; // 商品购买URL
}

// 定义与实现商品卡片 Class
export class ClassRoomProduct {
  productId: string; // 商品id
  title: string; // 商品标题
  info: string; // 商品描述
  coverUrl: string; // 商品封面URL
  sellUrl: string; // 商品购买URL

  constructor(config: ClassRoomProductConfig) {
    const { productId, title, info, coverUrl, sellUrl } = config;
    this.productId = productId;
    this.title = title;
    this.info = info;
    this.coverUrl = coverUrl;
    this.sellUrl = sellUrl;
  }
}

定义商品管理模块

由教师端和助教端实例化该模块。

import { ClassRoomProductConfig } from 'path/to/ClassRoomProductConfig';
import { CustomMessageTypes } from 'path/to/CustomMessageTypes';
import AUIMessage from '@/BaseKits/AUIMessage';

export class ProductManager {
  private productList: ClassRoomProductConfig[] = [];
  private message: InstanceType<typeof AUIMessage>;

  constructor(message: InstanceType<typeof AUIMessage>) {
    this.message = message;
  }

  // 下发商品卡片
  public sendProduct(productId: string): Promise<void> {
    const product = this.productList.find((item) => item.productId === productId);
    if (product) {
      this.message.sendGroupSignal({
        type: CustomMessageTypes.ShoppingProduct,
        data: {
          product
        },
      });
    }
  }
  
  ...
}

此时可调用sendProduct方法进行商品卡片下发。如果需要从运营后台下发商品卡片到教室中,需要 AppServer 调用互动消息的 API 进行发送,具体参考:发送消息到群组

接收商品卡片消息

学员端需要处理来自教师端、助教端或者是运营侧触发的商品卡片消息。以下代码实现了对商品卡片消息的监听,CustomMessageTypes.ShoppingProduct来自于自定义的商品卡片消息类型。

接受商品卡片消息

import React, { 
  useContext, 
  useEffect, 
  useState, 
} from 'react';
import { Popover } from 'antd-mobile';
import { CloseOutline } from 'antd-mobile-icons'
import { ClassContext } from 'path/to/ClassContext';
import { AUIMessageEvents } from '@/BaseKits/AUIMessage/types';
import { CustomMessageTypes } from 'path/to/CustomMessageTypes';
import styles from './index.less';

const ProductCard: React.FC = () => {
  const { auiMessage } = useContext(ClassContext);
  const [productCardVisible, setProductCardVisible] = useState<boolean>(false);

  const handleShoppingProduct = (data: any) => {
    setProductCardVisible(true);
    // 更多业务逻辑自行实现
  };

  useEffect(() => {
    const handleReceivedMessage = (eventData: any) => {
      const { type, senderInfo, data } = eventData || {};

      switch (type) {
        case CustomMessageTypes.ShoppingProduct:
          // 商品卡片消息
          handleShoppingProduct(data);
          break;
        default:
          break;
      }
    };
    auiMessage.addListener(AUIMessageEvents.onMessageReceived, handleReceivedMessage);

    return () => {
      auiMessage.removeListener(AUIMessageEvents.onMessageReceived, handleReceivedMessage);
    };
  }, [auiMessage]);

  return (
    <Popover
      placement='top'
      mode='light'
      content={(
        <div className={styles['shopping-card']}>
          <div
            className={styles['shopping-close-icon']}
            onClick={() => setProductCardVisible(false)}
          >
            <CloseOutline />
          </div>
        </div> 
      )}
      visible={productCardVisible}
    >
      <div>
        {/* 由业务实现商品卡片内容 */}
      </div>
    </Popover>
  );
};

export default ProductCard;

展示商品卡片

const isShowProductCard = useMemo(() => {
  // 业务判断是否显示商品卡片组件
}, [...]);

{isShowProductCard ? <ProductCard /> : null}

商品列表

添加入口按钮

在教室学员端的底部新增一个按钮,用于打开商品列表。

添加商品列表入口按钮

const isShowProductList = useMemo(() => {
  // 业务判断是否显示商品列表
}, [...]);

{isShowProductList ? <ShoppingList /> : null}

打开商品列表

点击入口按钮后,动画往上展示一个半屏的浮层,浮层上加载商品列表信息,具体的商品信息的展示及购买流程需要根据自身的需求进行开发。

import React, { useState } from 'react';
import { Popup } from 'antd-mobile';
import styles from './index.less';

const ProductList: React.FC = () => {
  const [productListVisible, setProductListVisible] = useState<boolean>(false);

  const closeProductList = () => {
    setProductListVisible(false)
  };

  return (
    <>
      <Popup
        onMaskClick={() => closeProductList()}
        onClose={() => closeProductList()}
        visible={productListVisible}
      >
        <div className={styles['shopping-list']}>
          <div className={styles['shopping-title']}>
            {/* 由业务实现商品列表内容 */}
          </div>
        </div>
      </Popup>

      <span className="chat-btn-wrap" onClick={() => setProductListVisible(true)}>
        <span className="chat-btn">
          <img src="https://img.alicdn.com/imgextra/i3/O1CN012R9g7P1F7ZCYy96rK_!!6000000000440-2-tps-108-108.png" />
        </span>
      </span>
    </>
  );
};

export default ProductList;