## 问卷组件

### 版本历史

版本号 | 更新时间 | 更新描述
--- | --- | ---
1.0.1 | 2022.6.15 | 问卷组件上线
1.1.3 | 2023.4.6 | 图片选择组件更换
1.2.4 | 2023.8.7 | 修复已知问题
1.2.6 | 2023.12.1 | 升级依赖Glide4.x版本
1.2.7 | 2024.2.2 | 修复已知问题

### 组件引入

注意：所有使用互动组件必须要引入basemodule库，最新版本见 互动组件对接文档

项目根目录build.gradle引入：

     repositories {     maven { url 'http://nexus-app.bokecc.com/repository/sdk-group/' } }

module的build.gradle引入：

     dependencies {     api ('com.bokecc:basemodule:x.x.x')     api ('com.bokecc.module:questionnairemodule:x.x.x') }

Application的onCreate方法中，调用 `DWLiveEngine.init` 初始化dwlivesdk后，添加代码：

    QuestionnaireInteractSDK.getInstance().init(app);

### 1. 组件描述

问卷组件是基于基础组件库扩展的问卷组件服务，通过IM组件实现问卷活动事件的推送，包括获取问卷列表，获取问卷详情、发送问卷等功能，为业务方提供问卷能力。问卷组件包含管理器和基于管理器实现的UI界面，接入方可基于管理器对外API实现完全自定义UI的问卷，也可直接集成组件SDK提供的UI。

### 2. 组件架构

#### 2.1 组件架构图

#### 2.2 核心对外API

IQuestionnaireManager内部唯一实现类为QuestionnaireManagerImpl

作用 | API
--- | ---
初始化 | void init(BaseQuestionnaireListener listener, String userId, String roomId, String interactToken)
获取问卷列表 | getQuestionnaireList(IBaseCallBack callBack)
获取问卷详情 | getQuestionnaireDetail(String userCode,String formCode,IBaseCallBack<QuestionnaireListBean.DataDTO> callBack)
提交问卷 | submit(String formCode,String formContent,IBaseCallBack
获取问卷填写状况 | getQuestionnaireIsComplete(String formCode, IBaseCallBack callBack)
重连 | reConnect()
释放 | release()

API接口代码

    public interface IQuestionnaireManager {
        /**     * @param listener      监听     * @param userId        viewerId     * @param roomId        房间id     * @param interactToken token     */    void init(BaseQuestionnaireListener listener, String userId, String roomId, String interactToken);
        /**     * 获取问卷列表     */    void getQuestionnaireList(IBaseCallBack<QuestionnaireListBean> callBack);    /**     * 获取问卷详情     */    void getQuestionnaireDetail(String userCode,String formCode,IBaseCallBack<QuestionnaireListBean.DataDTO> callBack);        /**     * 获取问卷是否填写过     * @param formCode formCode     * @param callBack 回调     */    void getQuestionnaireIsComplete(String formCode, IBaseCallBack<Integer> callBack);
        /**     * 提交     */    void submit(String formCode,String formContent,IBaseCallBack<Object> callBack);

        /**     * 重连     */    void reConnect();
        /**     * 释放     */    void release();
    }

### 3. 组件接入

#### 3.1 使用组件提供UI

问卷ViewGroup为QuestionnaireMainLayout

1. 登录业务SDK（云直播等）

2. xml中添加QuestionnaireMainLayout

       <?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#eeeeee"    android:orientation="vertical">

           <com.bokecc.questionnaire.ui.QuestionnaireMainLayout        android:id="@+id/questionniare_layout"        android:layout_width="match_parent"        android:layout_height="match_parent"/>
       </LinearLayout>

3. 设置QuestionnaireMainLayout的Listener

       questionnaireMainLayout.setQuestionnaireMainListener(new IQuestionnaireMainListener() {            @Override            public void onQuestionnairePush() {                Toast.makeText(QuestionnaireTestActivity.this, "onQuestionnairePush", Toast.LENGTH_SHORT).show();            }
                   @Override            public void onCloseClick() {                Toast.makeText(QuestionnaireTestActivity.this, "onCloseClick", Toast.LENGTH_SHORT).show();            }        });

4. 初始化组件

   1. 获取token-初始组件需要传递参数token，可以通过业务SDK（云直播等）提供的对外API获取token

   2. 使用业务SDK提供的配置信息初始化组件SDK

      代码示例（以云直播为例）：

    private void initQuestionnaireModel() {        if (DWLiveCoreHandler.getInstance().getInteractionConfigure()!=null){            InteractionConfigure interactionConfigure = DWLiveCoreHandler.getInstance().getInteractionConfigure();            if (interactionConfigure.getQuestionnaire()!=null){                InteractionConfigure.Questionnaire questionnaire = interactionConfigure.getQuestionnaire();                if (questionnaire.getSwitch()>0){                    //推送方式：0:手动推送 1:进入直播时 2：结束直播时                    final int sendMode = questionnaire.getSendMode();                    if (questionnaireSendMode!=null){                        questionnaireSendMode.set(questionnaire.getSendMode());                    }                    //活动编码                    final String activityCode = questionnaire.getActivityCode();                    //表单编码                    final String formCode = questionnaire.getFormCode();
                        String viewerId = "";                    try {                        viewerId = DWLiveCoreHandler.getInstance().getViewer().getId();                    } catch (Exception e) {                        e.printStackTrace();                    }                    String roomId = "";                    try {                        roomId = DWLiveCoreHandler.getInstance().getRoomInfo().getId();                    } catch (Exception e) {                        e.printStackTrace();                    }                    final String finalViewerId = viewerId;                    final String finalRoomId = roomId;                    DWLive.getInstance().getInteractiveToken(new BaseCallback<String>() {                        @Override                        public void onError(String s) {                            Toast.makeText(mContext, "获取组件token失败:" + s, Toast.LENGTH_SHORT).show();                        }
                            @Override                        public void onSuccess(final String token) {                            questionniareLayout.setQuestionnaireMainListener(new IQuestionnaireMainListener() {                                @Override                                public void onQuestionnairePush() {                                    //收到问卷推送 显示问卷布局                                    showQuestionnaire(true);                                }
                                    @Override                                public void onCloseClick() {                                    questionniareLayout.setVisibility(View.GONE);                                }                            });
                                questionniareLayout.initialize(                                    new QuestionnaireBaseLayout.QuestionnaireConfig()                                            .setInteractToken(token)                                            .setUserId(finalViewerId)                                            .setRoomId(finalRoomId)                                            .setFormCode(formCode)                                            .setActivityId(activityCode)                                            .setSendMode(sendMode)                            );//                            if (sendMode==1){//                                showQuestionnaire();//                            }else if (sendMode==2){//                                //设置直播结束后展示问卷列表//                            }                        }                    });                }
                }        }    }

5. 销毁组件

       @Override    protected void onDestroy() {        super.onDestroy();         if (questionniareLayout!=null){            questionniareLayout.release();        }    }

#### 3.2 使用组件管理器+自定义UI

问卷管理器实现类为QuestionnaireManagerImpl，对外方法参照IQuestionnaireManager，UI可以参考QuestionnaireBaseLayout以及其子类QuestionnaireMainLayout实现

### 4. 混淆配置

混淆配置

    xxxxxxxxxx-keep class com.bokecc.**{*;}-keep interface com.bokecc.**{*;}

### 5. 组件库依赖

    implementation 'com.android.support:appcompat-v7:28.0.0'implementation 'com.android.support:recyclerview-v7:28.0.0'implementation 'com.github.bumptech.glide:glide:4.9.0'implementation 'com.bokecc.gson:gson:2.9.0'implementation 'com.bokecc.widget:pickerview:0.0.2'implementation 'it.sephiroth.android.library.imagezoom:library:1.0.4'implementation 'com.aliyun.dpa:oss-android-sdk:2.9.11'//图片选择框架implementation 'com.zhihu.android:matisse:0.5.3-beta3'