瀏覽代碼

增加老师端VIP定制课程和趣纠课课程组详情

Pq 7 月之前
父節點
當前提交
d2f8833651
共有 36 個文件被更改,包括 2290 次插入3 次删除
  1. 18 0
      BaseLibrary/src/main/java/com/cooleshow/base/bean/CommonCourseConfigBean.java
  2. 45 0
      BaseLibrary/src/main/java/com/cooleshow/base/constanst/CourseAttendanceStatusType.java
  3. 1 1
      BaseLibrary/src/main/java/com/cooleshow/base/constanst/CourseGroupStatusType.java
  4. 1 0
      BaseLibrary/src/main/java/com/cooleshow/base/router/RouterPath.kt
  5. 138 0
      BaseLibrary/src/main/java/com/cooleshow/base/widgets/dialog/CommonFilterDialog.java
  6. 5 0
      BaseLibrary/src/main/res/drawable/shape_2dc7aa_11dp.xml
  7. 34 0
      BaseLibrary/src/main/res/layout/dialog_common_filter_layout.xml
  8. 26 0
      BaseLibrary/src/main/res/layout/item_common_filter_dialog_list_layout.xml
  9. 7 0
      teacher/src/main/AndroidManifest.xml
  10. 74 0
      teacher/src/main/java/com/cooleshow/teacher/adapter/VIPCourseGroupDetailAdapter.java
  11. 32 0
      teacher/src/main/java/com/cooleshow/teacher/api/APIService.java
  12. 123 0
      teacher/src/main/java/com/cooleshow/teacher/bean/VIPCourseGroupDetailBean.java
  13. 271 0
      teacher/src/main/java/com/cooleshow/teacher/bean/VIPCourseGroupDetailListBean.java
  14. 30 0
      teacher/src/main/java/com/cooleshow/teacher/contract/VIPCourseGroupDetailContract.java
  15. 108 0
      teacher/src/main/java/com/cooleshow/teacher/presenter/course/VIPOrInterestCourseGroupDetailPresenter.java
  16. 12 0
      teacher/src/main/java/com/cooleshow/teacher/ui/course/InterestCourseGroupFragment.java
  17. 2 1
      teacher/src/main/java/com/cooleshow/teacher/ui/course/MineCourseActivity.java
  18. 1 0
      teacher/src/main/java/com/cooleshow/teacher/ui/course/PianoRoomCourseFragment.java
  19. 11 1
      teacher/src/main/java/com/cooleshow/teacher/ui/course/VIPCourseGroupFragment.java
  20. 510 0
      teacher/src/main/java/com/cooleshow/teacher/ui/course/VIPOrInterestCourseGroupDetailActivity.java
  21. 167 0
      teacher/src/main/java/com/cooleshow/teacher/widgets/dialog/AddCourseGroupPlanDialog.java
  22. 二進制
      teacher/src/main/res/drawable-xhdpi/icon_add_course_group_plan_tag.png
  23. 二進制
      teacher/src/main/res/drawable-xhdpi/icon_course_attendance_arrive.png
  24. 二進制
      teacher/src/main/res/drawable-xhdpi/icon_course_attendance_truancy.png
  25. 二進制
      teacher/src/main/res/drawable-xhdpi/icon_course_group_edit_plan.png
  26. 二進制
      teacher/src/main/res/drawable-xhdpi/icon_course_group_plan_tag.png
  27. 二進制
      teacher/src/main/res/drawable-xxhdpi/bg_course_group_detail_top.png
  28. 二進制
      teacher/src/main/res/drawable-xxhdpi/icon_add_course_group_plan_tag.png
  29. 二進制
      teacher/src/main/res/drawable-xxhdpi/icon_course_attendance_arrive.png
  30. 二進制
      teacher/src/main/res/drawable-xxhdpi/icon_course_attendance_truancy.png
  31. 二進制
      teacher/src/main/res/drawable-xxhdpi/icon_course_group_edit_plan.png
  32. 二進制
      teacher/src/main/res/drawable-xxhdpi/icon_course_group_plan_tag.png
  33. 12 0
      teacher/src/main/res/drawable/shape_add_course_plan_bg.xml
  34. 402 0
      teacher/src/main/res/layout/ac_vip_or_interest_course_group_detail_layout.xml
  35. 90 0
      teacher/src/main/res/layout/dialog_add_course_group_plan_layout.xml
  36. 170 0
      teacher/src/main/res/layout/item_vip_course_group_layout.xml

+ 18 - 0
BaseLibrary/src/main/java/com/cooleshow/base/bean/CommonCourseConfigBean.java

@@ -20,6 +20,24 @@ public class CommonCourseConfigBean {
     private String practiceEndTime;
     private String liveStartTime;
     private String pianoStartTime;
+    private String vipStartTime;
+    private String vipEndTime;
+
+    public String getVipStartTime() {
+        return vipStartTime;
+    }
+
+    public void setVipStartTime(String vipStartTime) {
+        this.vipStartTime = vipStartTime;
+    }
+
+    public String getVipEndTime() {
+        return vipEndTime;
+    }
+
+    public void setVipEndTime(String vipEndTime) {
+        this.vipEndTime = vipEndTime;
+    }
 
     public String getPianoEndTime() {
         return pianoEndTime;

+ 45 - 0
BaseLibrary/src/main/java/com/cooleshow/base/constanst/CourseAttendanceStatusType.java

@@ -0,0 +1,45 @@
+package com.cooleshow.base.constanst;
+
+import com.contrarywind.interfaces.IPickerViewData;
+import com.cooleshow.base.interfaces.IFilterViewData;
+
+/**
+ * Author by pq, Date on 2022/12/23.
+ */
+public enum CourseAttendanceStatusType implements IPickerViewData, IFilterViewData {
+    ALL("", "全部考勤"),
+    ARRIVE_FOR_CLASS("1", "到课"),
+    TRUANCY("0", "旷课");
+
+
+    private final String value;
+    private final String id;
+
+    public String getValue() {
+        return value;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    CourseAttendanceStatusType(String id, String s) {
+        this.id = id;
+        this.value = s;
+    }
+
+    @Override
+    public String getPickerViewText() {
+        return getValue();
+    }
+
+    @Override
+    public String getDataId() {
+        return getId();
+    }
+
+    @Override
+    public String getShowName() {
+        return getValue();
+    }
+}

+ 1 - 1
BaseLibrary/src/main/java/com/cooleshow/base/constanst/CourseGroupStatusType.java

@@ -9,7 +9,7 @@ import com.cooleshow.base.interfaces.IFilterViewData;
 public enum CourseGroupStatusType implements IPickerViewData, IFilterViewData {
     ALL("", "全部"),
     NOT_START("NOT_START", "未开始"),
-    ING("ING", "进行"),
+    ING("ING", "进行"),
     COMPLETE("COMPLETE", "已结课"),
     CANCEL("CANCEL", "已取消");
 

+ 1 - 0
BaseLibrary/src/main/java/com/cooleshow/base/router/RouterPath.kt

@@ -97,6 +97,7 @@ object RouterPath {
             const val TEACHER_MINE_VIDEO_COURSE = "/teacher/ui/course/MineVideoCourseActivity"
             const val SPARRING_EVALUATE_TEACHER = "/teacher/ui/course/EvaluateTeacherActivity"
             const val VIP_COURSE_SETTING = "/teacher/ui/course/VIPCourseSettingActivity"
+            const val VIP_COURSE_GROUP_DETAIL = "/teacher/ui/course/VIPOrInterestCourseGroupDetailActivity"
 
         }
     }

+ 138 - 0
BaseLibrary/src/main/java/com/cooleshow/base/widgets/dialog/CommonFilterDialog.java

@@ -0,0 +1,138 @@
+package com.cooleshow.base.widgets.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.listener.OnItemClickListener;
+import com.chad.library.adapter.base.viewholder.BaseViewHolder;
+import com.contrarywind.interfaces.IPickerViewData;
+import com.cooleshow.base.R;
+import com.cooleshow.base.interfaces.IFilterData;
+import com.cooleshow.base.interfaces.IFilterViewData;
+
+import java.util.List;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+/**
+ * Author by pq, Date on 2023/2/20.
+ */
+public class CommonFilterDialog<T> extends Dialog implements View.OnClickListener {
+
+    private RecyclerView mRecyclerView;
+    private BaseQuickAdapter<T, BaseViewHolder> mAdapter;
+    private OnEventListener mEventListener;
+    private int selectPos = -1;
+
+    public CommonFilterDialog(@NonNull Context context) {
+        super(context, R.style.BottomDialogStyle);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.dialog_common_filter_layout);
+        Window window = getWindow();
+        //设置dialog在屏幕底部
+        window.setGravity(Gravity.BOTTOM);
+        //设置dialog弹出时的动画效果,从屏幕底部向上弹出
+        window.setWindowAnimations(R.style.BottomAnimation);
+        window.getDecorView().setPadding(0, 0, 0, 0);
+        //获得window窗口的属性
+        WindowManager.LayoutParams lp = window.getAttributes();
+        //设置窗口宽度为充满全屏
+        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
+        //设置窗口高度为包裹内容
+        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
+        lp.horizontalMargin = 0;
+        lp.verticalMargin = 0;
+        //将设置好的属性set回去
+        window.setAttributes(lp);
+
+        mRecyclerView = findViewById(R.id.recyclerView);
+        mAdapter = new BaseQuickAdapter<T, BaseViewHolder>(R.layout.item_common_filter_dialog_list_layout) {
+            @Override
+            protected void convert(@NonNull BaseViewHolder holder, T t) {
+                String text = "";
+                if (t instanceof IFilterData) {
+                    IFilterData iFilterData = (IFilterData) t;
+                    text = iFilterData.getFilterViewText();
+                }
+
+                if (t instanceof IFilterViewData) {
+                    IFilterViewData iFilterViewData = (IFilterViewData) t;
+                    text = iFilterViewData.getShowName();
+                }
+
+                if (t instanceof IPickerViewData) {
+                    IPickerViewData iPickerViewData = (IPickerViewData) t;
+                    text = iPickerViewData.getPickerViewText();
+                }
+                if (t instanceof String) {
+                    text = (String) t;
+                }
+                TextView tv_text = holder.getView(R.id.tv_text);
+                tv_text.setText(text);
+                if (holder.getLayoutPosition() == selectPos) {
+                    tv_text.setBackgroundResource(R.drawable.shape_f2f2f2_6dp);
+                    tv_text.setTextColor(getContext().getResources().getColor(R.color.color_2dc7aa));
+                } else {
+                    tv_text.setBackgroundColor(Color.TRANSPARENT);
+                    tv_text.setTextColor(getContext().getResources().getColor(R.color.color_333333));
+                }
+            }
+        };
+        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
+        mRecyclerView.setAdapter(mAdapter);
+        TextView tv_cancel = findViewById(R.id.tv_cancel);
+        tv_cancel.setOnClickListener(this);
+        mAdapter.setOnItemClickListener(new OnItemClickListener() {
+            @Override
+            public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
+                if (mEventListener != null) {
+                    dismiss();
+                    mEventListener.onItemClickListener(adapter, position);
+                    selectPos = position;
+                    mAdapter.notifyDataSetChanged();
+                }
+            }
+        });
+    }
+
+    public void setData(List<T> data) {
+        if (mAdapter != null) {
+            mAdapter.setNewInstance(data);
+        }
+    }
+
+    public void setSelectPos(int pos) {
+        this.selectPos = pos;
+    }
+
+    @Override
+    public void onClick(View v) {
+        int id = v.getId();
+        if (id == R.id.tv_cancel) {
+            dismiss();
+            return;
+        }
+    }
+
+    public void setOnEventListener(OnEventListener listener) {
+        this.mEventListener = listener;
+    }
+
+    public interface OnEventListener {
+        void onItemClickListener(BaseQuickAdapter baseQuickAdapter, int pos);
+    }
+}

+ 5 - 0
BaseLibrary/src/main/res/drawable/shape_2dc7aa_11dp.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/color_2dc7aa" />
+    <corners android:radius="11dp" />
+</shape>

+ 34 - 0
BaseLibrary/src/main/res/layout/dialog_common_filter_layout.xml

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/bg_white_top_10dp"
+    android:orientation="vertical"
+    android:paddingTop="15dp"
+    android:paddingBottom="15dp">
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/recyclerView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:overScrollMode="never"
+        android:scrollbars="none" />
+
+    <View
+        android:layout_marginTop="10dp"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="@color/color_f2f2f2" />
+
+    <TextView
+        android:id="@+id/tv_cancel"
+        android:layout_width="match_parent"
+        android:layout_height="50dp"
+        android:gravity="center"
+        android:text="取消"
+        android:textColor="@color/color_aaaaaa"
+        android:textSize="@dimen/sp_16"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+</LinearLayout>

+ 26 - 0
BaseLibrary/src/main/res/layout/item_common_filter_dialog_list_layout.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="44dp"
+    android:paddingStart="13dp"
+    android:paddingEnd="13dp"
+    xmlns:tools="http://schemas.android.com/tools">
+
+
+    <TextView
+        android:id="@+id/tv_text"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        tools:text="已完成"
+        android:textColor="@color/color_333333"
+        android:textSize="@dimen/sp_16"
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 7 - 0
teacher/src/main/AndroidManifest.xml

@@ -111,6 +111,7 @@
             android:screenOrientation="portrait" />
         <activity
             android:name=".ui.course.MineCourseActivity"
+            android:windowSoftInputMode="adjustPan"
             android:configChanges="orientation|screenSize|keyboardHidden|fontScale|smallestScreenSize|screenLayout|uiMode"
             android:screenOrientation="portrait" />
         <activity
@@ -376,6 +377,12 @@
             android:windowSoftInputMode="adjustPan" />
 
         <activity
+            android:name=".ui.course.VIPOrInterestCourseGroupDetailActivity"
+            android:configChanges="orientation|screenSize|keyboardHidden|fontScale|smallestScreenSize|screenLayout|uiMode"
+            android:screenOrientation="portrait"
+            android:windowSoftInputMode="adjustPan" />
+
+        <activity
             android:name="com.tencent.tauth.AuthActivity"
             android:launchMode="singleTask"
             android:noHistory="true">

+ 74 - 0
teacher/src/main/java/com/cooleshow/teacher/adapter/VIPCourseGroupDetailAdapter.java

@@ -0,0 +1,74 @@
+package com.cooleshow.teacher.adapter;
+
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.viewholder.BaseViewHolder;
+import com.cooleshow.base.utils.GlideUtils;
+import com.cooleshow.base.utils.UiUtils;
+import com.cooleshow.teacher.R;
+import com.cooleshow.teacher.bean.VIPCourseGroupDetailListBean;
+import com.cooleshow.teacher.constants.CourseConstants;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Author by pq, Date on 2024/11/22.
+ */
+public class VIPCourseGroupDetailAdapter extends BaseQuickAdapter<VIPCourseGroupDetailListBean, BaseViewHolder> {
+    public VIPCourseGroupDetailAdapter() {
+        super(R.layout.item_vip_course_group_layout);
+        addChildClickViewIds(R.id.tv_go_start);
+    }
+
+    @Override
+    protected void convert(@NonNull BaseViewHolder holder, VIPCourseGroupDetailListBean data) {
+        //时间
+        holder.setText(R.id.tv_time, UiUtils.getCourseTimeString(data.getStartTime(), data.getEndTime()));
+
+        TextView tv_course_status = holder.getView(R.id.tv_course_status);
+
+        ImageView iv_avatar = holder.getView(R.id.iv_avatar);
+        GlideUtils.INSTANCE.loadImage(getContext(), data.getAvatar(), iv_avatar, R.drawable.icon_teacher_default_head);
+
+        holder.setText(R.id.tv_title, data.getCourseGroupName());
+
+        ImageView iv_attendance_status = holder.getView(R.id.iv_attendance_status);
+
+        holder.setText(R.id.tv_name, data.getUserName());
+
+        holder.setText(R.id.tv_course_name, data.getSubjectName());
+
+        TextView tv_go_start = holder.getView(R.id.tv_go_start);
+        if (TextUtils.equals(CourseConstants.COURSE_STATUS_NOT_START, data.getStatus())) {
+            //未开始
+            iv_attendance_status.setVisibility(View.GONE);
+            tv_go_start.setVisibility(View.GONE);
+            tv_course_status.setVisibility(View.VISIBLE);
+            tv_course_status.setText("未开始");
+            tv_course_status.setTextColor(getContext().getResources().getColor(com.cooleshow.base.R.color.color_ff802c));
+        }
+
+        if (TextUtils.equals(CourseConstants.COURSE_STATUS_ING, data.getStatus())) {
+            //进行中
+            iv_attendance_status.setVisibility(View.GONE);
+            tv_go_start.setVisibility(View.VISIBLE);
+            tv_course_status.setVisibility(View.GONE);
+            tv_course_status.setText("进行中");
+            tv_course_status.setTextColor(getContext().getResources().getColor(com.cooleshow.base.R.color.color_2dc7aa));
+        }
+
+        if (TextUtils.equals(CourseConstants.COURSE_STATUS_COMPLETE, data.getStatus())) {
+            //已结束
+            iv_attendance_status.setVisibility(View.VISIBLE);
+            tv_go_start.setVisibility(View.GONE);
+            tv_course_status.setVisibility(View.VISIBLE);
+            iv_attendance_status.setImageResource(data.isAttendanceStatus() ? R.drawable.icon_course_attendance_arrive : R.drawable.icon_course_attendance_truancy);
+            tv_course_status.setText("已结束");
+            tv_course_status.setTextColor(getContext().getResources().getColor(com.cooleshow.base.R.color.color_999999));
+        }
+    }
+}

+ 32 - 0
teacher/src/main/java/com/cooleshow/teacher/api/APIService.java

@@ -18,6 +18,8 @@ import com.cooleshow.base.bean.StudentPageListBean;
 import com.cooleshow.teacher.bean.SysParamConfigBean;
 import com.cooleshow.teacher.bean.TeacherPromoteIncomeBean;
 import com.cooleshow.teacher.bean.UnBindTenantDetailBean;
+import com.cooleshow.teacher.bean.VIPCourseGroupDetailBean;
+import com.cooleshow.teacher.bean.VIPCourseGroupDetailListBean;
 import com.cooleshow.teacher.bean.VIPCourseGroupListBean;
 import com.cooleshow.teacher.bean.request.AssignHomeWorkEntry;
 import com.cooleshow.teacher.bean.request.CommentHomeWorkEntry;
@@ -900,4 +902,34 @@ public interface APIService {
     @FormUrlEncoded
     @POST(TEACHER_GROUP + "teacherSubjectPrice/delete")
     Observable<BaseResponse<Object>> delVIPCourseOpetions(@FieldMap Map<String, String> map);
+
+
+    /**
+     *
+     *
+     * @param
+     * @return
+     */
+    @FormUrlEncoded
+    @POST(TEACHER_GROUP + "courseGroup/getCourseGroup")
+    Observable<BaseResponse<VIPCourseGroupDetailBean>> getCourseGroupDetail(@FieldMap Map<String, String> map);
+
+    /**
+     *
+     *
+     * @param
+     * @return
+     */
+    @POST(TEACHER_GROUP + "courseSchedule/list")
+    Observable<BaseResponse<ArrayList<VIPCourseGroupDetailListBean>>> getCourseGroupCourseList(@Body RequestBody body);
+
+    /**
+     *
+     *
+     * @param
+     * @return
+     */
+    @FormUrlEncoded
+    @POST(TEACHER_GROUP + "courseGroup/updateCoursePlan")
+    Observable<BaseResponse<Object>> updateCoursePlan(@FieldMap Map<String, String> map);
 }

+ 123 - 0
teacher/src/main/java/com/cooleshow/teacher/bean/VIPCourseGroupDetailBean.java

@@ -0,0 +1,123 @@
+package com.cooleshow.teacher.bean;
+
+import java.io.Serializable;
+
+/**
+ * Author by pq, Date on 2024/11/22.
+ */
+public class VIPCourseGroupDetailBean {
+
+    /**
+     * completeCourseNum : 0
+     * courseGroupId : 0
+     * courseGroupName :
+     * courseNum : 0
+     * coursePlan :
+     * status :
+     * studentAvatar :
+     * studentName :
+     * studentNum : 0
+     * subjectId : 0
+     * subjectName :
+     */
+
+    private String completeCourseNum;
+    private String courseGroupId;
+    private String courseGroupName;
+    private String courseNum;
+    private String coursePlan;
+    private String status;
+    private String studentAvatar;
+    private String studentName;
+    private String studentNum;
+    private String subjectId;
+    private String subjectName;
+
+    public String getCompleteCourseNum() {
+        return completeCourseNum;
+    }
+
+    public void setCompleteCourseNum(String completeCourseNum) {
+        this.completeCourseNum = completeCourseNum;
+    }
+
+    public String getCourseGroupId() {
+        return courseGroupId;
+    }
+
+    public void setCourseGroupId(String courseGroupId) {
+        this.courseGroupId = courseGroupId;
+    }
+
+    public String getCourseGroupName() {
+        return courseGroupName;
+    }
+
+    public void setCourseGroupName(String courseGroupName) {
+        this.courseGroupName = courseGroupName;
+    }
+
+    public String getCourseNum() {
+        return courseNum;
+    }
+
+    public void setCourseNum(String courseNum) {
+        this.courseNum = courseNum;
+    }
+
+    public String getCoursePlan() {
+        return coursePlan;
+    }
+
+    public void setCoursePlan(String coursePlan) {
+        this.coursePlan = coursePlan;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getStudentAvatar() {
+        return studentAvatar;
+    }
+
+    public void setStudentAvatar(String studentAvatar) {
+        this.studentAvatar = studentAvatar;
+    }
+
+    public String getStudentName() {
+        return studentName;
+    }
+
+    public void setStudentName(String studentName) {
+        this.studentName = studentName;
+    }
+
+    public String getStudentNum() {
+        return studentNum;
+    }
+
+    public void setStudentNum(String studentNum) {
+        this.studentNum = studentNum;
+    }
+
+    public String getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(String subjectId) {
+        this.subjectId = subjectId;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public void setSubjectName(String subjectName) {
+        this.subjectName = subjectName;
+    }
+}

+ 271 - 0
teacher/src/main/java/com/cooleshow/teacher/bean/VIPCourseGroupDetailListBean.java

@@ -0,0 +1,271 @@
+package com.cooleshow.teacher.bean;
+
+import java.util.ArrayList;
+
+/**
+ * Author by pq, Date on 2024/11/22.
+ */
+public class VIPCourseGroupDetailListBean {
+
+
+    /**
+     * attendanceStatus : true
+     * avatar :
+     * classDate :
+     * courseGoupId : 0
+     * courseGroupName :
+     * courseId : 0
+     * delFlag : true
+     * endTime :
+     * id : 0
+     * imUserId :
+     * realName :
+     * signInTime :
+     * startTime :
+     * status :
+     * studentReplied : 0
+     * subjectId : 0
+     * subjectName :
+     * teacherReplied : 0
+     * userId : 0
+     * userName :
+     */
+
+    private boolean attendanceStatus;
+    private String avatar;
+    private String classDate;
+    private String courseGoupId;
+    private String courseGroupName;
+    private String courseId;
+    private boolean delFlag;
+    private String endTime;
+    private String id;
+    private String imUserId;
+    private String realName;
+    private String signInTime;
+    private String startTime;
+    private String status;
+    private String studentReplied;
+    private String subjectId;
+    private String subjectName;
+    private String teacherReplied;
+    private String userId;
+    private String userName;
+    private ArrayList<CourseStudentVosBean> courseStudentVos;
+
+    public ArrayList<CourseStudentVosBean> getCourseStudentVos() {
+        return courseStudentVos;
+    }
+
+    public void setCourseStudentVos(ArrayList<CourseStudentVosBean> courseStudentVos) {
+        this.courseStudentVos = courseStudentVos;
+    }
+
+    public boolean isAttendanceStatus() {
+        return attendanceStatus;
+    }
+
+    public void setAttendanceStatus(boolean attendanceStatus) {
+        this.attendanceStatus = attendanceStatus;
+    }
+
+    public String getAvatar() {
+        return avatar;
+    }
+
+    public void setAvatar(String avatar) {
+        this.avatar = avatar;
+    }
+
+    public String getClassDate() {
+        return classDate;
+    }
+
+    public void setClassDate(String classDate) {
+        this.classDate = classDate;
+    }
+
+    public String getCourseGoupId() {
+        return courseGoupId;
+    }
+
+    public void setCourseGoupId(String courseGoupId) {
+        this.courseGoupId = courseGoupId;
+    }
+
+    public String getCourseGroupName() {
+        return courseGroupName;
+    }
+
+    public void setCourseGroupName(String courseGroupName) {
+        this.courseGroupName = courseGroupName;
+    }
+
+    public String getCourseId() {
+        return courseId;
+    }
+
+    public void setCourseId(String courseId) {
+        this.courseId = courseId;
+    }
+
+    public boolean isDelFlag() {
+        return delFlag;
+    }
+
+    public void setDelFlag(boolean delFlag) {
+        this.delFlag = delFlag;
+    }
+
+    public String getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(String endTime) {
+        this.endTime = endTime;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getImUserId() {
+        return imUserId;
+    }
+
+    public void setImUserId(String imUserId) {
+        this.imUserId = imUserId;
+    }
+
+    public String getRealName() {
+        return realName;
+    }
+
+    public void setRealName(String realName) {
+        this.realName = realName;
+    }
+
+    public String getSignInTime() {
+        return signInTime;
+    }
+
+    public void setSignInTime(String signInTime) {
+        this.signInTime = signInTime;
+    }
+
+    public String getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(String startTime) {
+        this.startTime = startTime;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getStudentReplied() {
+        return studentReplied;
+    }
+
+    public void setStudentReplied(String studentReplied) {
+        this.studentReplied = studentReplied;
+    }
+
+    public String getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(String subjectId) {
+        this.subjectId = subjectId;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public void setSubjectName(String subjectName) {
+        this.subjectName = subjectName;
+    }
+
+    public String getTeacherReplied() {
+        return teacherReplied;
+    }
+
+    public void setTeacherReplied(String teacherReplied) {
+        this.teacherReplied = teacherReplied;
+    }
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+
+    public static class CourseStudentVosBean{
+
+        /**
+         * avatar : https://oss.dayaedu.com/klx/user/android/2024-11/2250318_1732179712792.jpeg
+         * imUserId : CLX_2250318_STUDENT
+         * userId : 2250318
+         * userName : 游客哈哈哈哈哈哈哈哈哈哈
+         */
+
+        private String avatar;
+        private String imUserId;
+        private String userId;
+        private String userName;
+
+        public String getAvatar() {
+            return avatar;
+        }
+
+        public void setAvatar(String avatar) {
+            this.avatar = avatar;
+        }
+
+        public String getImUserId() {
+            return imUserId;
+        }
+
+        public void setImUserId(String imUserId) {
+            this.imUserId = imUserId;
+        }
+
+        public String getUserId() {
+            return userId;
+        }
+
+        public void setUserId(String userId) {
+            this.userId = userId;
+        }
+
+        public String getUserName() {
+            return userName;
+        }
+
+        public void setUserName(String userName) {
+            this.userName = userName;
+        }
+    }
+}

+ 30 - 0
teacher/src/main/java/com/cooleshow/teacher/contract/VIPCourseGroupDetailContract.java

@@ -0,0 +1,30 @@
+package com.cooleshow.teacher.contract;
+
+import com.cooleshow.base.bean.CommonCourseConfigBean;
+import com.cooleshow.base.presenter.view.BaseView;
+import com.cooleshow.teacher.bean.VIPCourseGroupDetailBean;
+import com.cooleshow.teacher.bean.VIPCourseGroupDetailListBean;
+import com.cooleshow.teacher.bean.VideoCourseListBean;
+
+import java.util.ArrayList;
+
+/**
+ * Author by pq, Date on 2022/4/20.
+ */
+public interface VIPCourseGroupDetailContract {
+
+    interface View extends BaseView {
+        void getDetailSuccess(VIPCourseGroupDetailBean data);
+
+        void getCourseListSuccess(ArrayList<VIPCourseGroupDetailListBean> data);
+
+
+        void getCourseConfigSuccess(CommonCourseConfigBean data);
+
+        void updateCoursePlanSuccess();
+
+    }
+
+    interface Presenter {
+    }
+}

+ 108 - 0
teacher/src/main/java/com/cooleshow/teacher/presenter/course/VIPOrInterestCourseGroupDetailPresenter.java

@@ -0,0 +1,108 @@
+package com.cooleshow.teacher.presenter.course;
+
+import android.text.TextUtils;
+
+import com.cooleshow.base.bean.CommonCourseConfigBean;
+import com.cooleshow.base.constanst.Constants;
+import com.cooleshow.base.constanst.CourseAttendanceStatusType;
+import com.cooleshow.base.presenter.BasePresenter;
+import com.cooleshow.base.rx.BaseObserver;
+import com.cooleshow.base.utils.RequestBodyUtil;
+import com.cooleshow.teacher.api.APIService;
+import com.cooleshow.teacher.bean.VIPCourseGroupDetailBean;
+import com.cooleshow.teacher.bean.VIPCourseGroupDetailListBean;
+import com.cooleshow.teacher.bean.VideoCourseListBean;
+import com.cooleshow.teacher.contract.VIPCourseGroupDetailContract;
+import com.cooleshow.teacher.contract.VideoCourseContract;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * 陪练课presenter
+ * Author by pq, Date on 2022/4/20.
+ */
+public class VIPOrInterestCourseGroupDetailPresenter extends BasePresenter<VIPCourseGroupDetailContract.View> implements VIPCourseGroupDetailContract.Presenter {
+
+    public void queryDetail(boolean isShowLoading, String courseGroupId) {
+        if (isShowLoading && getView() != null) {
+            getView().showLoading();
+        }
+        HashMap<String,String> hashMap =new HashMap();
+        hashMap.put("courseGroupId", courseGroupId);
+        addSubscribe(create(APIService.class).getCourseGroupDetail(hashMap), new BaseObserver<VIPCourseGroupDetailBean>(getView()) {
+            @Override
+            protected void onSuccess(VIPCourseGroupDetailBean data) {
+                if (getView() != null) {
+                    getView().getDetailSuccess(data);
+                }
+            }
+
+        });
+    }
+
+    public void queryCourseList(boolean isShowLoading, String courseGroupId, String classMonth, String status, String attendanceStatus) {
+        if (isShowLoading && getView() != null) {
+            getView().showLoading();
+        }
+        JSONObject jsonObject = new JSONObject();
+        try {
+            jsonObject.putOpt("courseGroupId", courseGroupId);
+            if (!TextUtils.isEmpty(classMonth)) {
+                jsonObject.putOpt("classMonth", classMonth);
+            }
+            if (!TextUtils.isEmpty(status)) {
+                jsonObject.putOpt("status", status);
+            }
+            if (!TextUtils.isEmpty(attendanceStatus)) {
+                boolean attendanceStatusFlag = false;
+                if(TextUtils.equals(attendanceStatus, CourseAttendanceStatusType.ARRIVE_FOR_CLASS.getId())){
+                    attendanceStatusFlag = true;
+                }
+                jsonObject.putOpt("attendanceStatus", attendanceStatusFlag);
+            }
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+        addSubscribe(create(APIService.class).getCourseGroupCourseList(RequestBodyUtil.convertToRequestBodyJson(jsonObject.toString())), new BaseObserver<ArrayList<VIPCourseGroupDetailListBean>>(getView()) {
+            @Override
+            protected void onSuccess(ArrayList<VIPCourseGroupDetailListBean> data) {
+                if (getView() != null) {
+                    getView().getCourseListSuccess(data);
+                }
+            }
+
+        });
+    }
+
+    public void getCourseConfig() {
+        addSubscribe(create(APIService.class).getCourseConfig(), new BaseObserver<CommonCourseConfigBean>(getView()) {
+            @Override
+            protected void onSuccess(CommonCourseConfigBean data) {
+                if (getView() != null) {
+                    getView().getCourseConfigSuccess(data);
+                }
+            }
+        });
+    }
+
+    public void updateCoursePlan(String groupId, String coursePlan) {
+        if (getView() != null) {
+            getView().showLoading();
+        }
+        HashMap<String, String> map = new HashMap<>();
+        map.put("groupId", groupId);
+        map.put("coursePlan", coursePlan);
+        addSubscribe(create(APIService.class).updateCoursePlan(map), new BaseObserver<Object>(getView()) {
+            @Override
+            protected void onSuccess(Object data) {
+                if (getView() != null) {
+                    getView().updateCoursePlanSuccess();
+                }
+            }
+        });
+    }
+}

+ 12 - 0
teacher/src/main/java/com/cooleshow/teacher/ui/course/InterestCourseGroupFragment.java

@@ -4,11 +4,13 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.widget.PopupWindow;
 
+import com.alibaba.android.arouter.launcher.ARouter;
 import com.chad.library.adapter.base.BaseQuickAdapter;
 import com.chad.library.adapter.base.listener.OnItemClickListener;
 import com.cooleshow.base.constanst.Constants;
 import com.cooleshow.base.constanst.CourseGroupStatusType;
 import com.cooleshow.base.interfaces.IFilterViewData;
+import com.cooleshow.base.router.RouterPath;
 import com.cooleshow.base.ui.fragment.BaseMVPFragment;
 import com.cooleshow.base.utils.LOG;
 import com.cooleshow.base.utils.PopupUtil;
@@ -19,6 +21,7 @@ import com.cooleshow.teacher.R;
 import com.cooleshow.teacher.adapter.VIPCourseAdapter;
 import com.cooleshow.teacher.bean.QuerySubjectBean;
 import com.cooleshow.teacher.bean.VIPCourseGroupListBean;
+import com.cooleshow.teacher.constants.CourseConstants;
 import com.cooleshow.teacher.contract.InterestCourseGroupContract;
 import com.cooleshow.teacher.contract.VipCourseGroupContract;
 import com.cooleshow.teacher.databinding.FgInterestCourseLayoutBinding;
@@ -102,8 +105,17 @@ public class InterestCourseGroupFragment extends BaseMVPFragment<FgInterestCours
             @Override
             public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
                 //课程详情页
+                if(position<mAdapter.getData().size()){
+                    VIPCourseGroupListBean.RowsBean rowsBean = mAdapter.getData().get(position);
+                    ARouter.getInstance().build(RouterPath.CourseCenter.VIP_COURSE_GROUP_DETAIL)
+                            .withString(CourseConstants.COURSE_GROUP_ID,rowsBean.getCourseGroupId())
+                            .withString(Constants.COMMON_EXTRA_KEY,Constants.INTEREST_COURSE_TAG)
+                            .navigation();
+                }
             }
         });
+
+
     }
 
     private void getData(boolean isLoading) {

+ 2 - 1
teacher/src/main/java/com/cooleshow/teacher/ui/course/MineCourseActivity.java

@@ -8,6 +8,7 @@ import android.view.View;
 import android.widget.TextView;
 
 import com.alibaba.android.arouter.facade.annotation.Route;
+import com.alibaba.android.arouter.launcher.ARouter;
 import com.cooleshow.base.bean.CourseTipBean;
 import com.cooleshow.base.router.RouterPath;
 import com.cooleshow.base.ui.activity.BaseMVPActivity;
@@ -82,11 +83,11 @@ public class MineCourseActivity extends BaseMVPActivity<ActivityMineCourseLayout
             createTab(tab, titles.get(position));
         });
 
+        mVipCourseFragment = new VIPCourseGroupFragment();
         mInterestCourseGroupFragment = new InterestCourseGroupFragment();
         mLiveCourseFragment = new LiveCourseGroupFragment();
         mVideoCourseFragment = new VideoCourseGroupFragment();
         mPianoRoomCourseGroupFragment = new PianoCourseGroupFragment();
-        mVipCourseFragment = new VIPCourseGroupFragment();
         mFragments.add(mVipCourseFragment);
         mFragments.add(mInterestCourseGroupFragment);
         mFragments.add(mLiveCourseFragment);

+ 1 - 0
teacher/src/main/java/com/cooleshow/teacher/ui/course/PianoRoomCourseFragment.java

@@ -60,6 +60,7 @@ import androidx.recyclerview.widget.RecyclerView;
  * Author by pq, Date on 2022/4/25.
  * 我的课程->琴房课
  */
+@Deprecated
 public class PianoRoomCourseFragment extends BaseMVPFragment<FragmentPianoRoomCourseLayoutBinding, PianoRoomCoursePresenter> implements PianoRoomCourseContract.PianoRoomCourseView, View.OnClickListener {
     private String currentCourseFilterStatus = CourseConstants.COURSE_FILTER_ALL;
     private String currentFilterDate;

+ 11 - 1
teacher/src/main/java/com/cooleshow/teacher/ui/course/VIPCourseGroupFragment.java

@@ -4,11 +4,13 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.widget.PopupWindow;
 
+import com.alibaba.android.arouter.launcher.ARouter;
 import com.chad.library.adapter.base.BaseQuickAdapter;
 import com.chad.library.adapter.base.listener.OnItemClickListener;
 import com.cooleshow.base.constanst.Constants;
 import com.cooleshow.base.constanst.CourseGroupStatusType;
 import com.cooleshow.base.interfaces.IFilterViewData;
+import com.cooleshow.base.router.RouterPath;
 import com.cooleshow.base.ui.fragment.BaseMVPFragment;
 import com.cooleshow.base.utils.LOG;
 import com.cooleshow.base.utils.PopupUtil;
@@ -19,6 +21,7 @@ import com.cooleshow.teacher.R;
 import com.cooleshow.teacher.adapter.VIPCourseAdapter;
 import com.cooleshow.teacher.bean.QuerySubjectBean;
 import com.cooleshow.teacher.bean.VIPCourseGroupListBean;
+import com.cooleshow.teacher.constants.CourseConstants;
 import com.cooleshow.teacher.contract.VipCourseGroupContract;
 import com.cooleshow.teacher.databinding.FgVipCourseLayoutBinding;
 import com.cooleshow.teacher.presenter.course.VipCourseGroupPresenter;
@@ -100,7 +103,14 @@ public class VIPCourseGroupFragment extends BaseMVPFragment<FgVipCourseLayoutBin
         mAdapter.setOnItemClickListener(new OnItemClickListener() {
             @Override
             public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
-                //课程详情页
+                //课程组详情页
+
+                if(position<mAdapter.getData().size()){
+                    VIPCourseGroupListBean.RowsBean rowsBean = mAdapter.getData().get(position);
+                    ARouter.getInstance().build(RouterPath.CourseCenter.VIP_COURSE_GROUP_DETAIL)
+                            .withString(CourseConstants.COURSE_GROUP_ID,rowsBean.getCourseGroupId())
+                            .navigation();
+                }
             }
         });
     }

+ 510 - 0
teacher/src/main/java/com/cooleshow/teacher/ui/course/VIPOrInterestCourseGroupDetailActivity.java

@@ -0,0 +1,510 @@
+package com.cooleshow.teacher.ui.course;
+
+import android.content.DialogInterface;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.TextView;
+
+import com.alibaba.android.arouter.facade.annotation.Route;
+import com.alibaba.android.arouter.launcher.ARouter;
+import com.bigkoo.pickerview.builder.OptionsPickerBuilder;
+import com.bigkoo.pickerview.builder.TimePickerBuilder;
+import com.bigkoo.pickerview.listener.CustomListener;
+import com.bigkoo.pickerview.listener.OnDismissListener;
+import com.bigkoo.pickerview.view.OptionsPickerView;
+import com.bigkoo.pickerview.view.TimePickerView;
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.listener.OnItemChildClickListener;
+import com.chad.library.adapter.base.listener.OnItemClickListener;
+import com.cooleshow.base.bean.CommonCourseConfigBean;
+import com.cooleshow.base.constanst.Constants;
+import com.cooleshow.base.constanst.CourseAttendanceStatusType;
+import com.cooleshow.base.constanst.CourseGroupStatusType;
+import com.cooleshow.base.constanst.StyleConfig;
+import com.cooleshow.base.interfaces.IFilterViewData;
+import com.cooleshow.base.router.RouterPath;
+import com.cooleshow.base.ui.activity.BaseMVPActivity;
+import com.cooleshow.base.utils.GlideUtils;
+import com.cooleshow.base.utils.TimeUtils;
+import com.cooleshow.base.utils.ToastUtil;
+import com.cooleshow.base.utils.UiUtils;
+import com.cooleshow.base.utils.helper.QMUIStatusBarHelper;
+import com.cooleshow.base.widgets.EmptyViewLayout;
+import com.cooleshow.base.widgets.dialog.CommonFilterDialog;
+import com.cooleshow.teacher.R;
+import com.cooleshow.teacher.adapter.VIPCourseGroupDetailAdapter;
+import com.cooleshow.teacher.bean.QuerySubjectBean;
+import com.cooleshow.teacher.bean.VIPCourseGroupDetailBean;
+import com.cooleshow.teacher.bean.VIPCourseGroupDetailListBean;
+import com.cooleshow.teacher.constants.CourseConstants;
+import com.cooleshow.teacher.contract.VIPCourseGroupDetailContract;
+import com.cooleshow.teacher.databinding.AcVipOrInterestCourseGroupDetailLayoutBinding;
+import com.cooleshow.teacher.presenter.course.VIPOrInterestCourseGroupDetailPresenter;
+import com.cooleshow.teacher.widgets.AppBarLayoutStateChangeListener;
+import com.cooleshow.teacher.widgets.dialog.AddCourseGroupPlanDialog;
+import com.dayayuemeng.classroom.helper.OpenClassRoomHelper;
+import com.google.android.material.appbar.AppBarLayout;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.LinearLayoutManager;
+
+/**
+ * Author by pq, Date on 2024/11/22.
+ */
+@Route(path = RouterPath.CourseCenter.VIP_COURSE_GROUP_DETAIL)
+public class VIPOrInterestCourseGroupDetailActivity extends BaseMVPActivity<AcVipOrInterestCourseGroupDetailLayoutBinding, VIPOrInterestCourseGroupDetailPresenter> implements VIPCourseGroupDetailContract.View, View.OnClickListener {
+    private int titleStyleMode = 1;//根据折叠展开状态控制title样式
+    public static final int EXPAND_MODE = 1;
+    public static final int COLLAP_MODE = 2;
+    private AppBarLayoutStateChangeListener.State lastState = AppBarLayoutStateChangeListener.State.EXPANDED;
+    private String title = "VIP定制课详情";
+    private String courseGroupId;
+    private String courseType = Constants.VIP_COURSE_TAG;
+    private String classMonth;
+    private Date currentSelectDate;
+    private String courseStatus = CourseGroupStatusType.ALL.getId();
+    private String currentAttendanceStatus;
+    private VIPCourseGroupDetailAdapter mAdapter;
+    private CommonCourseConfigBean mConfigBean;
+    private VIPCourseGroupDetailBean mDetailBean;
+    private TimePickerView pvTime;
+    private List<IFilterViewData> statusList;//状态筛选
+    private List<IFilterViewData> attendanceStatusList;//考勤状态筛选
+    private int currentSelectStatusPosition = 0;
+    private int currentSelectAttendancePosition = 0;
+    private CommonFilterDialog mAttendanceStatusFilterDialog;
+    private CommonFilterDialog mStatusFilterDialog;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        QMUIStatusBarHelper.setStatusBarLightMode(VIPOrInterestCourseGroupDetailActivity.this);
+    }
+
+    @Override
+    protected void initView() {
+        String courseTypeValue = getIntent().getStringExtra(Constants.COMMON_EXTRA_KEY);
+        if (!TextUtils.isEmpty(courseTypeValue)) {
+            courseType = courseTypeValue;
+        }
+        title = TextUtils.equals(courseType, Constants.VIP_COURSE_TAG) ? "VIP定制课详情" : "趣纠课详情";
+        initMidTitleToolBar(viewBinding.toolbarInclude.toolbar, title);
+        viewBinding.toolbarInclude.toolbar.setBackgroundColor(Color.TRANSPARENT);
+        viewBinding.appBarLayout.addOnOffsetChangedListener(new AppBarLayoutStateChangeListener() {
+
+            @Override
+            public void onStateChanged(AppBarLayout appBarLayout, State state) {
+                switch (state) {
+                    case EXPANDED:    //展开
+                        switchTitleStyle(EXPAND_MODE);
+                        break;
+                    case COLLAPSED:    //折叠
+                        switchTitleStyle(COLLAP_MODE);
+                        break;
+                    case INTERMEDIATE: //中间状态
+                        if (lastState == State.COLLAPSED) {
+                            switchTitleStyle(EXPAND_MODE);
+                        }
+                        break;
+                }
+                lastState = state;
+            }
+        });
+    }
+
+    @Override
+    public void initData() {
+        super.initData();
+        courseGroupId = getIntent().getStringExtra(CourseConstants.COURSE_GROUP_ID);
+        if (TextUtils.isEmpty(courseGroupId)) {
+            finish();
+            return;
+        }
+
+        initFilterData();
+
+        EmptyViewLayout emptyViewLayout = new EmptyViewLayout(this);
+        emptyViewLayout.setContent(com.cooleshow.base.R.drawable.icon_empty_course, "暂无课程");
+        mAdapter = new VIPCourseGroupDetailAdapter();
+        mAdapter.setEmptyView(emptyViewLayout);
+        viewBinding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
+        viewBinding.recyclerView.setAdapter(mAdapter);
+        initListener();
+    }
+
+    private void initFilterData() {
+        CourseGroupStatusType[] values = CourseGroupStatusType.values();
+        List<CourseGroupStatusType> courseGroupStatusTypes = Arrays.asList(values);
+        statusList = new ArrayList<IFilterViewData>(courseGroupStatusTypes);
+
+        CourseAttendanceStatusType[] attendanceStatuValues = CourseAttendanceStatusType.values();
+        List<CourseAttendanceStatusType> attendanceStatus = Arrays.asList(attendanceStatuValues);
+        attendanceStatusList = new ArrayList<>(attendanceStatus);
+    }
+
+    private void initListener() {
+        viewBinding.viewAddPlan.setOnClickListener(this);
+        viewBinding.tvEditPlan.setOnClickListener(this);
+        viewBinding.tvTime.setOnClickListener(this);
+        viewBinding.tvCourseStatus.setOnClickListener(this);
+        viewBinding.tvAgency.setOnClickListener(this);
+        mAdapter.setOnItemClickListener(new OnItemClickListener() {
+            @Override
+            public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
+                if(position<mAdapter.getData().size()){
+                    VIPCourseGroupDetailListBean bean = mAdapter.getData().get(position);
+                    ArrayList<VIPCourseGroupDetailListBean.CourseStudentVosBean> courseStudentVos = bean.getCourseStudentVos();
+                    if(courseStudentVos!=null &&courseStudentVos.size()>0){
+                        VIPCourseGroupDetailListBean.CourseStudentVosBean courseStudentVosBean = courseStudentVos.get(0);
+                        ARouter.getInstance()
+                                .build(RouterPath.CourseCenter.SPARRING_COURSE_DETAIL)
+                                .withString(CourseConstants.COURSE_ID, bean.getCourseId())
+                                .withString(CourseConstants.COURSE_GROUP_ID, bean.getCourseGoupId())
+                                .withString(CourseConstants.STUDENT_ID, courseStudentVosBean.getUserId())
+                                .navigation();
+                    }
+                }
+            }
+        });
+
+        mAdapter.setOnItemChildClickListener(new OnItemChildClickListener() {
+            @Override
+            public void onItemChildClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
+                //去上课
+                if (UiUtils.isFastClick()) {
+                    return;
+                }
+                if(view.getId() == R.id.tv_go_start){
+                    if (position < mAdapter.getData().size()) {
+                        VIPCourseGroupDetailListBean bean = mAdapter.getData().get(position);
+                        goCourse(bean.getId(), bean.getStartTime(), bean.getSubjectName());
+                    }
+                }
+            }
+        });
+    }
+
+    private void reBuildFilter(Date date, String status, String attendanceStatus) {
+        currentSelectDate = date != null ? date : TimeUtils.getNowDate();
+        String targetDateTimeStr = TimeUtils.date2String(currentSelectDate, TimeUtils.getSafeDateFormat("yyyy-MM"));
+        classMonth = targetDateTimeStr;
+        courseStatus = !TextUtils.isEmpty(status) ? status : CourseGroupStatusType.ALL.getId();
+        currentAttendanceStatus = !TextUtils.isEmpty(attendanceStatus) ? attendanceStatus : CourseAttendanceStatusType.ALL.getId();
+        if (viewBinding != null) {
+            viewBinding.tvTime.setText(classMonth);
+        }
+        refreshCourseList(true);
+    }
+
+    private void goCourse(String courseScheduleId, String courseStartTime, String subjectName) {
+        if (!TextUtils.isEmpty(courseScheduleId) && !TextUtils.isEmpty(courseStartTime)) {
+            if (mConfigBean != null) {
+                boolean lessThanTargetTime = TimeUtils.isLessThanTargetTime(getTargetTime(), courseStartTime);
+                if (!lessThanTargetTime) {
+                    ToastUtil.getInstance().showShort("课程还未开始,请在上课前" + mConfigBean.getPracticeStartTime() + "分钟进入");
+                    return;
+                }
+                OpenClassRoomHelper.start(this, courseScheduleId, subjectName);
+            }
+        }
+    }
+
+    private String getTargetTime() {
+        if (TextUtils.equals(courseType, Constants.VIP_COURSE_TAG)) {
+            return mConfigBean.getVipStartTime();
+        }
+        return mConfigBean.getPracticeStartTime();
+    }
+
+    private void switchTitleStyle(int mode) {
+        if (titleStyleMode == mode) {
+            return;
+        }
+        titleStyleMode = mode;
+        if (mode == 1) {
+            viewBinding.collapsingToolbarLayout.setContentScrimColor(Color.TRANSPARENT);
+            viewBinding.collapsingToolbarLayout.setStatusBarScrimColor(Color.TRANSPARENT);
+            viewBinding.toolbarInclude.toolbar.setBackgroundColor(Color.TRANSPARENT);
+            viewBinding.csFilter.setBackgroundColor(Color.TRANSPARENT);
+        } else {
+            viewBinding.collapsingToolbarLayout.setContentScrimColor(Color.WHITE);
+            viewBinding.collapsingToolbarLayout.setStatusBarScrimColor(Color.WHITE);
+            viewBinding.toolbarInclude.toolbar.setBackgroundColor(Color.WHITE);
+            viewBinding.csFilter.setBackgroundColor(Color.WHITE);
+        }
+    }
+
+    @Override
+    protected AcVipOrInterestCourseGroupDetailLayoutBinding getLayoutView() {
+        return AcVipOrInterestCourseGroupDetailLayoutBinding.inflate(getLayoutInflater());
+    }
+
+    @Override
+    protected VIPOrInterestCourseGroupDetailPresenter createPresenter() {
+        return new VIPOrInterestCourseGroupDetailPresenter();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        refresh();
+    }
+
+    private void refresh() {
+        presenter.getCourseConfig();
+        presenter.queryDetail(true, courseGroupId);
+        reBuildFilter(currentSelectDate, courseStatus, currentAttendanceStatus);
+    }
+
+    private void refreshCourseList(boolean isShowLoading) {
+        presenter.queryCourseList(isShowLoading, courseGroupId, classMonth, courseStatus, currentAttendanceStatus);
+    }
+
+
+    @Override
+    public void getDetailSuccess(VIPCourseGroupDetailBean bean) {
+        if (!checkActivityExist()) {
+            return;
+        }
+        this.mDetailBean = bean;
+        GlideUtils.INSTANCE.loadImage(this, bean.getStudentAvatar(), viewBinding.ivAvatar, R.drawable.icon_teacher_default_head);
+
+        viewBinding.tvCourseGroupTitle.setText(bean.getCourseGroupName());
+        viewBinding.tvName.setText(bean.getStudentName());
+        viewBinding.tvCourseCompletedValue.setText(bean.getCompleteCourseNum());
+        viewBinding.tvCourseTotalValue.setText(bean.getCourseNum());
+        viewBinding.tvCourseName.setText(bean.getSubjectName());
+
+        TextView tv_status = viewBinding.tvStatus;
+        String status = bean.getStatus();
+        if (TextUtils.equals(status, CourseGroupStatusType.ING.getId())) {
+            //进行中
+            tv_status.setText(CourseGroupStatusType.ING.getValue());
+            tv_status.setTextColor(getResources().getColor(com.cooleshow.base.R.color.color_2dc7aa));
+        } else if (TextUtils.equals(status, CourseGroupStatusType.NOT_START.getId())) {
+            //未开始
+            tv_status.setText(CourseGroupStatusType.NOT_START.getValue());
+            tv_status.setTextColor(getResources().getColor(com.cooleshow.base.R.color.color_ff802c));
+        } else if (TextUtils.equals(status, CourseGroupStatusType.COMPLETE.getId())) {
+            //已结课
+            tv_status.setText(CourseGroupStatusType.COMPLETE.getValue());
+            tv_status.setTextColor(getResources().getColor(com.cooleshow.base.R.color.color_999999));
+        } else if (TextUtils.equals(status, CourseGroupStatusType.CANCEL.getId())) {
+            //已取消
+            tv_status.setText(CourseGroupStatusType.CANCEL.getValue());
+            tv_status.setTextColor(getResources().getColor(com.cooleshow.base.R.color.color_999999));
+        }
+
+        String coursePlan = bean.getCoursePlan();
+        boolean hasPlan = !TextUtils.isEmpty(coursePlan);
+        viewBinding.tvPlanContent.setText(coursePlan);
+        viewBinding.groupAddCoursePlan.setVisibility(hasPlan ? View.GONE : View.VISIBLE);
+        viewBinding.csCoursePlan.setVisibility(hasPlan ? View.VISIBLE : View.GONE);
+    }
+
+    @Override
+    public void getCourseListSuccess(ArrayList<VIPCourseGroupDetailListBean> data) {
+        if (!checkActivityExist()) {
+            return;
+        }
+        if (mAdapter != null) {
+            mAdapter.setList(data);
+        }
+    }
+
+    @Override
+    public void getCourseConfigSuccess(CommonCourseConfigBean data) {
+        if (!checkActivityExist()) {
+            return;
+        }
+        this.mConfigBean = data;
+    }
+
+    @Override
+    public void updateCoursePlanSuccess() {
+        if (!checkActivityExist()) {
+            return;
+        }
+        refresh();
+    }
+
+    private void showAddPlanDialog(String content) {
+        if (UiUtils.isFastClick()) {
+            return;
+        }
+        AddCourseGroupPlanDialog courseGroupPlanDialog = new AddCourseGroupPlanDialog(this);
+        courseGroupPlanDialog.show();
+        courseGroupPlanDialog.setOnEventListener(new AddCourseGroupPlanDialog.OnEventListener() {
+            @Override
+            public void onResult(String content) {
+                courseGroupPlanDialog.dismiss();
+                presenter.updateCoursePlan(courseGroupId, content);
+            }
+        });
+        if (!TextUtils.isEmpty(content)) {
+            courseGroupPlanDialog.setContentText(content);
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        int id = v.getId();
+        if (id == R.id.view_add_plan) {
+            showAddPlanDialog("");
+            return;
+        }
+        if (id == R.id.tv_edit_plan) {
+            if (mDetailBean != null) {
+                showAddPlanDialog(mDetailBean.getCoursePlan());
+            }
+            return;
+        }
+
+        if (id == R.id.tv_time) {
+            showTimeSelectPicker();
+            return;
+        }
+        if (id == R.id.tv_course_status) {
+            selectCourseStatus();
+            return;
+        }
+
+        if (id == R.id.tv_agency) {
+            selectAttendanceStatus();
+            return;
+        }
+    }
+
+
+    private void showTimeSelectPicker() {
+        if (pvTime == null) {
+            pvTime = new TimePickerBuilder(this, (date, v) -> {//选中事件回调
+                reBuildFilter(date, courseStatus, currentAttendanceStatus);
+            }).setLayoutRes(com.cooleshow.base.R.layout.pickerview_default_layout, new CustomListener() {
+                        @Override
+                        public void customLayout(View v) {
+                            //自定义布局中的控件初始化及事件处理
+                            final TextView tvSubmit = (TextView) v.findViewById(com.cooleshow.base.R.id.tv_finish);
+                            TextView ivCancel = (TextView) v.findViewById(com.cooleshow.base.R.id.tv_cancel);
+                            tvSubmit.setOnClickListener(new View.OnClickListener() {
+                                @Override
+                                public void onClick(View v) {
+                                    pvTime.returnData();
+                                    pvTime.dismiss();
+                                }
+                            });
+                            ivCancel.setOnClickListener(new View.OnClickListener() {
+                                @Override
+                                public void onClick(View v) {
+                                    pvTime.dismiss();
+                                }
+                            });
+
+                        }
+                    })
+                    .setTextColorOut(getResources().getColor(com.cooleshow.base.R.color.color_aaaaaa))
+                    .setDividerColor(Color.TRANSPARENT)
+                    .setBgColor(Color.TRANSPARENT)
+                    .setLineSpacingMultiplier(2.5f)
+                    .setType(new boolean[]{true, true, false, false, false, false})// 默认全部显示
+                    .setTextColorCenter(getResources().getColor(com.cooleshow.base.R.color.color_1a1a1a))//设置选中项的颜色
+                    .isDialog(false)//是否显示为对话框样式
+                    .setLabel("年", "月", "", "", "", "")
+                    .build();
+
+            pvTime.setOnDismissListener(new OnDismissListener() {
+                @Override
+                public void onDismiss(Object o) {
+                    UiUtils.refreshFilterTextStyle2(false, viewBinding.tvTime);
+                }
+
+                @Override
+                public void onShow() {
+                    UiUtils.refreshFilterTextStyle2(true, viewBinding.tvTime);
+                }
+            });
+        }
+        Calendar calendar = Calendar.getInstance();
+        if (currentSelectDate == null) {
+            currentSelectDate = TimeUtils.getNowDate();
+        }
+        calendar.setTime(currentSelectDate);
+        pvTime.setDate(calendar);
+        if (!pvTime.isShowing()) {
+            pvTime.show();
+        }
+    }
+
+    private void selectCourseStatus() {
+        if (mStatusFilterDialog == null) {
+            mStatusFilterDialog = new CommonFilterDialog<IFilterViewData>(this);
+            mStatusFilterDialog.setOnEventListener(new CommonFilterDialog.OnEventListener() {
+                @Override
+                public void onItemClickListener(BaseQuickAdapter baseQuickAdapter, int pos) {
+                    if (statusList != null && pos < statusList.size()) {
+                        VIPOrInterestCourseGroupDetailActivity.this.currentSelectStatusPosition = pos;
+                        IFilterViewData iFilterViewData = statusList.get(pos);
+                        courseStatus = iFilterViewData.getDataId();
+                        viewBinding.tvCourseStatus.setText(!TextUtils.isEmpty(courseStatus) ? iFilterViewData.getShowName() : "全部状态");
+                        reBuildFilter(currentSelectDate, courseStatus, currentAttendanceStatus);
+                    }
+                }
+            });
+
+            mStatusFilterDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+                @Override
+                public void onDismiss(DialogInterface dialog) {
+                    UiUtils.refreshFilterTextStyle(false, viewBinding.tvCourseStatus);
+                }
+            });
+        }
+        if (!mStatusFilterDialog.isShowing()) {
+            mStatusFilterDialog.show();
+            UiUtils.refreshFilterTextStyle(true, viewBinding.tvCourseStatus);
+        }
+        mStatusFilterDialog.setSelectPos(currentSelectStatusPosition);
+        mStatusFilterDialog.setData(statusList);
+
+    }
+
+
+    private void selectAttendanceStatus() {
+        if (mAttendanceStatusFilterDialog == null) {
+            mAttendanceStatusFilterDialog = new CommonFilterDialog<IFilterViewData>(this);
+            mAttendanceStatusFilterDialog.setOnEventListener(new CommonFilterDialog.OnEventListener() {
+                @Override
+                public void onItemClickListener(BaseQuickAdapter baseQuickAdapter, int pos) {
+                    if (attendanceStatusList != null && pos < attendanceStatusList.size()) {
+                        VIPOrInterestCourseGroupDetailActivity.this.currentSelectAttendancePosition = pos;
+                        IFilterViewData iFilterViewData = attendanceStatusList.get(pos);
+                        currentAttendanceStatus = iFilterViewData.getDataId();
+                        viewBinding.tvAgency.setText(iFilterViewData.getShowName());
+                        reBuildFilter(currentSelectDate, courseStatus, currentAttendanceStatus);
+                    }
+                }
+            });
+
+            mAttendanceStatusFilterDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+                @Override
+                public void onDismiss(DialogInterface dialog) {
+                    UiUtils.refreshFilterTextStyle(false, viewBinding.tvAgency);
+                }
+            });
+        }
+        if (!mAttendanceStatusFilterDialog.isShowing()) {
+            mAttendanceStatusFilterDialog.show();
+            UiUtils.refreshFilterTextStyle(true, viewBinding.tvAgency);
+        }
+        mAttendanceStatusFilterDialog.setSelectPos(currentSelectAttendancePosition);
+        mAttendanceStatusFilterDialog.setData(attendanceStatusList);
+    }
+}

+ 167 - 0
teacher/src/main/java/com/cooleshow/teacher/widgets/dialog/AddCourseGroupPlanDialog.java

@@ -0,0 +1,167 @@
+package com.cooleshow.teacher.widgets.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.listener.OnItemClickListener;
+import com.cooleshow.base.bean.SubjectListBean;
+import com.cooleshow.base.bean.TenantGroupListBean;
+import com.cooleshow.base.iml.ICommonFilterData;
+import com.cooleshow.base.utils.ToastUtil;
+import com.cooleshow.teacher.R;
+import com.cooleshow.teacher.adapter.SelectTenantMemberFilterAdapter;
+import com.google.android.flexbox.FlexDirection;
+import com.google.android.flexbox.FlexWrap;
+import com.google.android.flexbox.FlexboxLayoutManager;
+
+import java.util.ArrayList;
+import java.util.Locale;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+/**
+ * Author by pq, Date on 2023/10/17.
+ */
+public class AddCourseGroupPlanDialog extends Dialog implements View.OnClickListener {
+
+
+    private OnEventListener mEventListener;
+    private TextWatcher mTextWatcher = new TextWatcher() {
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+        }
+
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+
+        }
+
+        @Override
+        public void afterTextChanged(Editable s) {
+            updateTextNum();
+        }
+    };
+    private EditText mEtContent;
+    private TextView mTvTextNum;
+    private TextView mTvConfirm;
+    private ImageView mIvClose;
+
+    public AddCourseGroupPlanDialog(@NonNull Context context) {
+        super(context, R.style.MyBottomDialogStyle);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.dialog_add_course_group_plan_layout);
+        initParams();
+        initViews();
+        initData();
+        initListener();
+    }
+
+
+    private void initViews() {
+        mEtContent = findViewById(R.id.et_content);
+        mTvTextNum = findViewById(R.id.tv_text_num);
+        mTvConfirm = findViewById(R.id.tv_confirm);
+        mIvClose = findViewById(R.id.iv_close);
+    }
+
+    private void initData() {
+
+    }
+
+    private void initListener() {
+        mEtContent.addTextChangedListener(mTextWatcher);
+        mIvClose.setOnClickListener(this);
+        mTvConfirm.setOnClickListener(this);
+    }
+
+    private void updateTextNum() {
+        String text = mEtContent.getText().toString().trim();
+        int cLength = text.length();
+        mTvTextNum.setText(String.format(Locale.getDefault(), "%d/500", cLength));
+    }
+
+    private void initParams() {
+        Window window = getWindow();
+        //设置dialog在屏幕底部
+        window.setGravity(Gravity.BOTTOM);
+        //设置dialog弹出时的动画效果,从屏幕底部向上弹出
+        window.setWindowAnimations(com.cooleshow.base.R.style.BottomAnimation);
+        window.getDecorView().setPadding(0, 0, 0, 0);
+        //获得window窗口的属性
+        WindowManager.LayoutParams lp = window.getAttributes();
+        //设置窗口宽度为充满全屏
+        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
+        //设置窗口高度为包裹内容
+        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
+        lp.horizontalMargin = 0;
+        lp.verticalMargin = 0;
+        //将设置好的属性set回去
+        window.setAttributes(lp);
+    }
+
+    @Override
+    public void onClick(View v) {
+        int id = v.getId();
+        if (id == R.id.iv_close) {
+            dismiss();
+            return;
+        }
+        if (id == R.id.tv_confirm) {
+            if (mEventListener != null) {
+                Editable text = mEtContent.getText();
+                if (text != null) {
+                    String content = text.toString().trim();
+                    if (TextUtils.isEmpty(content)) {
+                        ToastUtil.getInstance().showShort("请填写您的课程规划");
+                        return;
+                    }
+                    mEventListener.onResult(content);
+                }
+            }
+            return;
+        }
+
+    }
+
+
+    public void setOnEventListener(OnEventListener listener) {
+        this.mEventListener = listener;
+    }
+
+    public void setContentText(String content) {
+        if (mEtContent != null) {
+            mEtContent.setText(content);
+            updateTextNum();
+        }
+    }
+
+    public interface OnEventListener {
+        void onResult(String content);
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        if (mEtContent != null && mTextWatcher != null) {
+            mEtContent.removeTextChangedListener(mTextWatcher);
+        }
+    }
+}

二進制
teacher/src/main/res/drawable-xhdpi/icon_add_course_group_plan_tag.png


二進制
teacher/src/main/res/drawable-xhdpi/icon_course_attendance_arrive.png


二進制
teacher/src/main/res/drawable-xhdpi/icon_course_attendance_truancy.png


二進制
teacher/src/main/res/drawable-xhdpi/icon_course_group_edit_plan.png


二進制
teacher/src/main/res/drawable-xhdpi/icon_course_group_plan_tag.png


二進制
teacher/src/main/res/drawable-xxhdpi/bg_course_group_detail_top.png


二進制
teacher/src/main/res/drawable-xxhdpi/icon_add_course_group_plan_tag.png


二進制
teacher/src/main/res/drawable-xxhdpi/icon_course_attendance_arrive.png


二進制
teacher/src/main/res/drawable-xxhdpi/icon_course_attendance_truancy.png


二進制
teacher/src/main/res/drawable-xxhdpi/icon_course_group_edit_plan.png


二進制
teacher/src/main/res/drawable-xxhdpi/icon_course_group_plan_tag.png


+ 12 - 0
teacher/src/main/res/drawable/shape_add_course_plan_bg.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+        android:angle="270"
+        android:endColor="@color/transparent"
+        android:startColor="#1a2DC7AA" />
+    <stroke
+        android:width="1dp"
+        android:color="#662DC7AA" />
+
+    <corners android:radius="6dp"/>
+</shape>

+ 402 - 0
teacher/src/main/res/layout/ac_vip_or_interest_course_group_detail_layout.xml

@@ -0,0 +1,402 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ImageView
+        android:id="@+id/iv_top_bg"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:adjustViewBounds="true"
+        android:src="@drawable/bg_course_group_detail_top"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <include
+        android:id="@+id/toolbar_include"
+        layout="@layout/common_toolbar_layout" />
+
+    <androidx.coordinatorlayout.widget.CoordinatorLayout
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:fitsSystemWindows="true"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/toolbar_include">
+
+        <com.google.android.material.appbar.AppBarLayout
+            android:id="@+id/app_bar_layout"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:background="@color/transparent"
+            android:fitsSystemWindows="true"
+            android:theme="@style/AppTheme.AppBarOverlay">
+
+            <com.google.android.material.appbar.CollapsingToolbarLayout
+                android:id="@+id/collapsing_toolbar_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:fitsSystemWindows="true"
+                android:paddingBottom="0dp"
+                app:contentScrim="@color/transparent"
+                app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
+                app:scrimAnimationDuration="10"
+                app:statusBarScrim="@color/transparent"
+                app:titleEnabled="false">
+
+                <androidx.constraintlayout.widget.ConstraintLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:layout_marginTop="12dp"
+                    android:paddingStart="14dp"
+                    android:paddingEnd="14dp"
+                    app:layout_collapseMode="none">
+
+                    <androidx.constraintlayout.widget.ConstraintLayout
+                        android:id="@+id/cs_header"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:background="@drawable/bg_white_10dp"
+                        android:padding="12dp"
+                        app:layout_constraintLeft_toLeftOf="parent"
+                        app:layout_constraintTop_toTopOf="parent">
+
+                        <TextView
+                            android:id="@+id/tv_course_group_title"
+                            android:layout_width="0dp"
+                            android:layout_height="wrap_content"
+                            android:ellipsize="end"
+                            android:maxLines="1"
+                            android:textColor="@color/color_131415"
+                            android:textSize="@dimen/sp_16"
+                            android:textStyle="bold"
+                            app:layout_constraintLeft_toLeftOf="parent"
+                            app:layout_constraintRight_toLeftOf="@+id/tv_status"
+                            app:layout_constraintTop_toTopOf="parent"
+                            tools:text="VIP定制课-张涵宇" />
+
+                        <TextView
+                            android:id="@+id/tv_status"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:includeFontPadding="false"
+                            android:textColor="@color/color_999999"
+                            android:textSize="@dimen/sp_14"
+                            app:layout_constraintBottom_toBottomOf="@+id/tv_course_group_title"
+                            app:layout_constraintRight_toRightOf="parent"
+                            app:layout_constraintTop_toTopOf="@+id/tv_course_group_title"
+                            tools:text="已结课" />
+
+                        <de.hdodenhof.circleimageview.CircleImageView
+                            android:id="@+id/iv_avatar"
+                            android:layout_width="40dp"
+                            android:layout_height="40dp"
+                            android:layout_marginTop="8dp"
+                            android:src="@drawable/icon_teacher_default_head"
+                            app:layout_constraintLeft_toLeftOf="parent"
+                            app:layout_constraintTop_toBottomOf="@+id/tv_course_group_title" />
+
+                        <TextView
+                            android:id="@+id/tv_name"
+                            android:layout_width="0dp"
+                            android:layout_height="wrap_content"
+                            android:layout_marginStart="10dp"
+                            android:layout_marginEnd="5dp"
+                            android:ellipsize="end"
+                            android:includeFontPadding="false"
+                            android:maxLines="1"
+                            android:textColor="@color/color_333333"
+                            android:textSize="@dimen/sp_13"
+                            app:layout_constraintBottom_toTopOf="@+id/tv_course_completed_title"
+                            app:layout_constraintHorizontal_bias="0"
+                            app:layout_constraintHorizontal_chainStyle="packed"
+                            app:layout_constraintLeft_toRightOf="@+id/iv_avatar"
+                            app:layout_constraintRight_toLeftOf="@+id/tv_course_name"
+                            app:layout_constraintTop_toTopOf="@+id/iv_avatar"
+                            app:layout_constraintVertical_chainStyle="packed"
+                            app:layout_constraintWidth_default="wrap"
+                            tools:text="张涵宇" />
+
+
+                        <TextView
+                            android:id="@+id/tv_course_name"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_marginStart="5dp"
+                            android:background="@drawable/shape_couse_type_text_bg"
+                            android:gravity="center"
+                            android:includeFontPadding="false"
+                            android:paddingStart="4dp"
+                            android:paddingTop="2dp"
+                            android:paddingEnd="4dp"
+                            android:paddingBottom="2dp"
+                            android:textColor="@color/color_ff8c00"
+                            android:textSize="@dimen/sp_10"
+                            app:layout_constraintBottom_toBottomOf="@+id/tv_name"
+                            app:layout_constraintLeft_toRightOf="@+id/tv_name"
+                            app:layout_constraintRight_toRightOf="parent"
+                            app:layout_constraintTop_toTopOf="@+id/tv_name"
+                            tools:text="单簧管" />
+
+                        <ImageView
+                            android:id="@+id/iv_course_tag"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:src="@drawable/icon_course_completed_tag"
+                            app:layout_constraintBottom_toBottomOf="@+id/tv_course_completed_title"
+                            app:layout_constraintLeft_toLeftOf="@+id/tv_name"
+                            app:layout_constraintTop_toTopOf="@+id/tv_course_completed_title" />
+
+                        <TextView
+                            android:id="@+id/tv_course_completed_title"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_marginStart="4dp"
+                            android:layout_marginTop="6dp"
+                            android:includeFontPadding="false"
+                            android:text="已上课时"
+                            android:textColor="@color/color_999999"
+                            android:textSize="@dimen/sp_12"
+                            app:layout_constraintBottom_toBottomOf="@+id/iv_avatar"
+                            app:layout_constraintLeft_toRightOf="@+id/iv_course_tag"
+                            app:layout_constraintTop_toBottomOf="@+id/tv_name" />
+
+
+                        <TextView
+                            android:id="@+id/tv_course_completed_value"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:includeFontPadding="false"
+                            android:paddingStart="3dp"
+                            android:paddingEnd="3dp"
+                            android:text="0"
+                            android:textColor="@color/color_2dc7aa"
+                            android:textSize="@dimen/sp_12"
+                            android:textStyle="bold"
+                            app:layout_constraintBaseline_toBaselineOf="@+id/tv_course_completed_title"
+                            app:layout_constraintLeft_toRightOf="@+id/tv_course_completed_title" />
+
+                        <TextView
+                            android:id="@+id/tv_course_total_title"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:includeFontPadding="false"
+                            android:text="/总课时"
+                            android:textColor="@color/color_999999"
+                            android:textSize="@dimen/sp_12"
+                            app:layout_constraintBaseline_toBaselineOf="@+id/tv_course_completed_value"
+                            app:layout_constraintLeft_toRightOf="@+id/tv_course_completed_value" />
+
+
+                        <TextView
+                            android:id="@+id/tv_course_total_value"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:includeFontPadding="false"
+                            android:paddingStart="3dp"
+                            android:paddingEnd="3dp"
+                            android:text="0"
+                            android:textColor="@color/color_333333"
+                            android:textSize="@dimen/sp_12"
+                            android:textStyle="bold"
+                            app:layout_constraintBaseline_toBaselineOf="@+id/tv_course_total_title"
+                            app:layout_constraintLeft_toRightOf="@+id/tv_course_total_title" />
+
+                        <View
+                            android:id="@+id/view_add_plan"
+                            android:layout_width="match_parent"
+                            android:layout_height="36dp"
+                            android:layout_marginTop="24dp"
+                            android:background="@drawable/shape_add_course_plan_bg"
+                            app:layout_constraintLeft_toLeftOf="parent"
+                            app:layout_constraintRight_toRightOf="parent"
+                            app:layout_constraintTop_toBottomOf="@+id/iv_avatar" />
+
+                        <TextView
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:drawableStart="@drawable/icon_add_course_group_plan_tag"
+                            android:drawablePadding="2dp"
+                            android:gravity="center"
+                            android:includeFontPadding="false"
+                            android:text="添加课程规划"
+                            android:textColor="@color/color_333333"
+                            android:textSize="@dimen/sp_15"
+                            android:id="@+id/tv_add_course_plan"
+                            app:layout_constraintBottom_toBottomOf="@+id/view_add_plan"
+                            app:layout_constraintLeft_toLeftOf="@+id/view_add_plan"
+                            app:layout_constraintRight_toRightOf="@+id/view_add_plan"
+                            app:layout_constraintTop_toTopOf="@+id/view_add_plan" />
+
+                        <androidx.constraintlayout.widget.Group
+                            android:visibility="gone"
+                            android:id="@+id/group_add_course_plan"
+                            app:constraint_referenced_ids="view_add_plan,tv_add_course_plan"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"/>
+                    </androidx.constraintlayout.widget.ConstraintLayout>
+
+                    <androidx.constraintlayout.widget.ConstraintLayout
+                        android:visibility="gone"
+                        android:layout_width="match_parent"
+                        android:id="@+id/cs_course_plan"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="12dp"
+                        android:background="@drawable/bg_white_10dp"
+                        android:padding="12dp"
+                        app:layout_constraintLeft_toLeftOf="parent"
+                        app:layout_constraintTop_toBottomOf="@+id/cs_header">
+
+                        <TextView
+                            android:id="@+id/tv_plan_title"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:drawableStart="@drawable/icon_course_group_plan_tag"
+                            android:drawablePadding="6dp"
+                            android:gravity="center"
+                            android:includeFontPadding="false"
+                            android:text="课程规划"
+                            android:textColor="@color/color_333333"
+                            android:textSize="@dimen/sp_15"
+                            app:layout_constraintLeft_toLeftOf="parent"
+                            app:layout_constraintTop_toTopOf="parent" />
+
+                        <TextView
+                            android:id="@+id/tv_edit_plan"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:drawableStart="@drawable/icon_course_group_edit_plan"
+                            android:drawablePadding="2dp"
+                            android:gravity="center"
+                            android:includeFontPadding="false"
+                            android:text="修改"
+                            android:textColor="@color/color_777777"
+                            android:textSize="@dimen/sp_13"
+                            app:layout_constraintRight_toRightOf="parent"
+                            app:layout_constraintTop_toTopOf="@+id/tv_plan_title" />
+
+                        <TextView
+                            android:id="@+id/tv_plan_content"
+                            android:layout_width="0dp"
+                            android:layout_height="wrap_content"
+                            android:layout_marginTop="12dp"
+                            android:ellipsize="end"
+                            android:includeFontPadding="false"
+                            android:maxLines="4"
+                            android:textColor="@color/color_777777"
+                            android:textSize="@dimen/sp_13"
+                            app:layout_constraintLeft_toLeftOf="parent"
+                            app:layout_constraintRight_toRightOf="parent"
+                            app:layout_constraintTop_toBottomOf="@+id/tv_plan_title"
+                            tools:text="中国院长笛四级考级曲目教学中国院长笛四级考级曲目" />
+
+                    </androidx.constraintlayout.widget.ConstraintLayout>
+                </androidx.constraintlayout.widget.ConstraintLayout>
+            </com.google.android.material.appbar.CollapsingToolbarLayout>
+
+            <androidx.constraintlayout.widget.ConstraintLayout
+                android:id="@+id/cs_filter"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingStart="14dp"
+                android:paddingEnd="14dp">
+
+                <androidx.constraintlayout.widget.Guideline
+                    android:id="@+id/guide_line1"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:orientation="vertical"
+                    app:layout_constraintGuide_percent="0.33" />
+
+                <androidx.constraintlayout.widget.Guideline
+                    android:id="@+id/guide_line2"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:orientation="vertical"
+                    app:layout_constraintGuide_percent="0.66" />
+
+                <TextView
+                    android:id="@+id/tv_time"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:drawableRight="@drawable/icon_arrow_down"
+                    android:drawablePadding="6dp"
+                    android:ellipsize="end"
+                    android:gravity="center"
+                    android:includeFontPadding="false"
+                    android:maxLines="1"
+                    android:paddingStart="10dp"
+                    android:paddingTop="12dp"
+                    android:paddingEnd="10dp"
+                    android:paddingBottom="12dp"
+                    android:textColor="@color/color_131415"
+                    android:textSize="@dimen/sp_14"
+                    app:layout_constraintHorizontal_chainStyle="spread_inside"
+                    app:layout_constraintLeft_toLeftOf="parent"
+                    app:layout_constraintRight_toLeftOf="@+id/guide_line1"
+                    app:layout_constraintTop_toTopOf="parent"
+                    app:layout_constraintWidth_default="wrap"
+                    tools:text="2021年9月" />
+
+                <TextView
+                    android:id="@+id/tv_course_status"
+                    android:layout_width="0dp"
+                    android:layout_height="0dp"
+                    android:drawableRight="@drawable/icon_arrow_down"
+                    android:drawablePadding="6dp"
+                    android:ellipsize="end"
+                    android:gravity="center"
+                    android:includeFontPadding="false"
+                    android:maxLines="1"
+                    android:paddingStart="10dp"
+                    android:paddingTop="12dp"
+                    android:paddingEnd="10dp"
+                    android:paddingBottom="12dp"
+                    android:text="全部状态"
+                    android:textColor="@color/color_131415"
+                    android:textSize="@dimen/sp_14"
+                    app:layout_constraintBottom_toBottomOf="@+id/tv_time"
+                    app:layout_constraintLeft_toRightOf="@+id/guide_line1"
+                    app:layout_constraintRight_toLeftOf="@+id/guide_line2"
+                    app:layout_constraintTop_toTopOf="@+id/tv_time"
+                    app:layout_constraintWidth_default="wrap"
+                    tools:text="课程状态" />
+
+                <TextView
+                    android:id="@+id/tv_agency"
+                    android:layout_width="0dp"
+                    android:layout_height="0dp"
+                    android:drawableRight="@drawable/icon_arrow_down"
+                    android:drawablePadding="6dp"
+                    android:ellipsize="end"
+                    android:gravity="center"
+                    android:includeFontPadding="false"
+                    android:maxLines="1"
+                    android:paddingStart="10dp"
+                    android:paddingTop="12dp"
+                    android:paddingEnd="10dp"
+                    android:paddingBottom="12dp"
+                    android:text="全部考勤"
+                    android:textColor="@color/color_131415"
+                    android:textSize="@dimen/sp_14"
+                    app:layout_constraintBottom_toBottomOf="@+id/tv_time"
+                    app:layout_constraintLeft_toRightOf="@+id/guide_line2"
+                    app:layout_constraintRight_toRightOf="parent"
+                    app:layout_constraintTop_toTopOf="@+id/tv_time"
+                    app:layout_constraintWidth_default="wrap"
+                    tools:text="全部考勤" />
+            </androidx.constraintlayout.widget.ConstraintLayout>
+        </com.google.android.material.appbar.AppBarLayout>
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/recyclerView"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:overScrollMode="never"
+            android:scrollbars="none"
+            app:layout_behavior="@string/appbar_scrolling_view_behavior"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/tab_layout" />
+    </androidx.coordinatorlayout.widget.CoordinatorLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 90 - 0
teacher/src/main/res/layout/dialog_add_course_group_plan_layout.xml

@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/shape_f8f9fc_top_12dp"
+    android:paddingBottom="30dp">
+
+    <TextView
+        android:id="@+id/tv_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="18dp"
+        android:includeFontPadding="false"
+        android:text="添加课程规划"
+        android:textColor="@color/color_333333"
+        android:textSize="@dimen/sp_18"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <ImageView
+        android:id="@+id/iv_close"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="12dp"
+        android:src="@drawable/icon_close_dialog_32_32"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_title"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tv_title" />
+
+    <FrameLayout
+        android:id="@+id/fl_input"
+        android:layout_width="match_parent"
+        android:layout_height="164dp"
+        android:layout_marginStart="14dp"
+        android:layout_marginTop="18dp"
+        android:layout_marginEnd="14dp"
+        android:background="@drawable/shape_white_8dp"
+        android:minHeight="164dp"
+        android:paddingStart="10dp"
+        android:paddingTop="12dp"
+        android:paddingEnd="10dp"
+        android:paddingBottom="18dp"
+        app:layout_constraintTop_toBottomOf="@+id/tv_title">
+
+        <EditText
+            android:id="@+id/et_content"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginBottom="20dp"
+            android:background="@color/transparent"
+            android:gravity="left"
+            android:hint="请填写您的课程规划"
+            android:maxLength="500"
+            android:textCursorDrawable="@drawable/shape_2dc7aa_1dp"
+            android:textColor="@color/black_333"
+            android:textColorHint="@color/color_aaaaaa"
+            android:textSize="@dimen/sp_15"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <TextView
+            android:id="@+id/tv_text_num"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom|right"
+            android:includeFontPadding="false"
+            android:text="0/500"
+            android:textColor="@color/color_aaaaaa"
+            android:textSize="@dimen/sp_14" />
+    </FrameLayout>
+
+
+    <TextView
+        android:id="@+id/tv_confirm"
+        android:layout_width="0dp"
+        android:layout_height="44dp"
+        android:layout_marginStart="28dp"
+        android:layout_marginTop="30dp"
+        android:layout_marginEnd="28dp"
+        android:background="@drawable/shape_2dc7aa_39dp"
+        android:gravity="center"
+        android:text="确认"
+        android:textColor="@color/white"
+        android:textSize="@dimen/sp_18"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/fl_input" />
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 170 - 0
teacher/src/main/res/layout/item_vip_course_group_layout.xml

@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_marginStart="14dp"
+    android:layout_marginBottom="12dp"
+    android:layout_marginEnd="14dp"
+    android:background="@drawable/bg_white_10dp"
+    android:paddingStart="12dp"
+    android:paddingEnd="12dp"
+    android:paddingBottom="12dp">
+
+    <ImageView
+        android:id="@+id/iv_clock_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="15dp"
+        android:src="@drawable/icon_clock"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <TextView
+        android:id="@+id/tv_time"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="6dp"
+        android:includeFontPadding="false"
+        android:textColor="@color/color_666666"
+        android:textSize="@dimen/sp_13"
+        app:layout_constraintBottom_toBottomOf="@+id/iv_clock_icon"
+        app:layout_constraintLeft_toRightOf="@+id/iv_clock_icon"
+        app:layout_constraintTop_toTopOf="@+id/iv_clock_icon"
+        tools:text="2021/09/17 14:00~14:25" />
+
+    <View
+        android:id="@+id/view_line"
+        android:layout_width="0dp"
+        android:layout_height="1dp"
+        android:layout_marginTop="15dp"
+        android:background="@color/color_f2f2f2"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/iv_clock_icon" />
+
+    <de.hdodenhof.circleimageview.CircleImageView
+        android:src="@drawable/icon_default_head"
+        android:id="@+id/iv_avatar"
+        android:layout_width="40dp"
+        android:layout_height="40dp"
+        android:layout_marginTop="12dp"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/view_line"
+        app:qmui_corner_radius="5dp" />
+
+    <TextView
+        android:id="@+id/tv_title"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="10dp"
+        android:includeFontPadding="false"
+        android:textColor="@color/color_1a1a1a"
+        android:textSize="@dimen/sp_15"
+        android:maxLines="1"
+        android:ellipsize="end"
+        app:layout_constraintWidth_default="wrap"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintRight_toLeftOf="@+id/iv_attendance_status"
+        app:layout_constraintBottom_toTopOf="@+id/tv_name"
+        app:layout_constraintLeft_toRightOf="@+id/iv_avatar"
+        app:layout_constraintTop_toTopOf="@+id/iv_avatar"
+        app:layout_constraintVertical_chainStyle="packed"
+        tools:text="VIP定制课-张豆豆VIP定制课-张豆豆" />
+
+    <ImageView
+        android:visibility="gone"
+        android:layout_marginStart="5dp"
+        android:id="@+id/iv_attendance_status"
+        app:layout_constraintRight_toLeftOf="@+id/iv_arrow"
+        app:layout_constraintLeft_toRightOf="@+id/tv_title"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_title"
+        app:layout_constraintTop_toTopOf="@+id/tv_title"
+        android:src="@drawable/icon_course_attendance_truancy"
+        android:layout_width="wrap_content"
+        android:layout_marginEnd="5dp"
+        android:layout_height="wrap_content"/>
+
+    <TextView
+        android:layout_marginTop="4dp"
+        app:layout_constraintBottom_toBottomOf="@+id/iv_avatar"
+        android:id="@+id/tv_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:includeFontPadding="false"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_13"
+        app:layout_constraintLeft_toLeftOf="@+id/tv_title"
+        app:layout_constraintTop_toBottomOf="@+id/tv_title"
+        tools:text="张豆豆" />
+
+    <ImageView
+        android:visibility="gone"
+        android:id="@+id/iv_go_chat"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="5dp"
+        android:src="@drawable/icon_chat_small"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_title"
+        app:layout_constraintLeft_toRightOf="@+id/tv_title"
+        app:layout_constraintTop_toTopOf="@+id/tv_title" />
+
+    <TextView
+        android:layout_marginStart="5dp"
+        android:id="@+id/tv_course_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="@drawable/shape_couse_type_text_bg"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:paddingStart="4dp"
+        android:paddingTop="2dp"
+        android:paddingEnd="4dp"
+        android:paddingBottom="2dp"
+        android:textColor="@color/color_ff8c00"
+        android:textSize="@dimen/sp_11"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_name"
+        app:layout_constraintLeft_toRightOf="@+id/tv_name"
+        app:layout_constraintTop_toBottomOf="@+id/tv_name"
+        tools:text="单簧管" />
+
+
+    <TextView
+        android:id="@+id/tv_course_status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintBottom_toTopOf="@+id/view_line"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="未开始" />
+
+    <TextView
+        android:visibility="gone"
+        android:id="@+id/tv_go_start"
+        android:layout_width="wrap_content"
+        android:layout_height="22dp"
+        android:textColor="@color/white"
+        android:textSize="@dimen/sp_12"
+        android:paddingStart="8dp"
+        android:gravity="center"
+        android:paddingEnd="8dp"
+        android:text="开始上课"
+        android:background="@drawable/shape_2dc7aa_11dp"
+        app:layout_constraintBottom_toTopOf="@+id/view_line"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="开始上课" />
+
+    <ImageView
+        android:id="@+id/iv_arrow"
+        app:layout_constraintBottom_toBottomOf="@+id/iv_avatar"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/iv_avatar"
+        android:src="@drawable/icon_arrow_right"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+</androidx.constraintlayout.widget.ConstraintLayout>