浏览代码

增加学生端小组课课程组详情页面

Pq 8 月之前
父节点
当前提交
803d934946

+ 6 - 0
student/src/main/AndroidManifest.xml

@@ -268,6 +268,12 @@
             android:configChanges="orientation|screenSize|keyboardHidden|fontScale|smallestScreenSize|screenLayout|uiMode"
             android:screenOrientation="portrait"
             android:windowSoftInputMode="adjustPan" />
+
+        <activity
+            android:name=".ui.course.GroupCourseGroupDetailActivity"
+            android:configChanges="orientation|screenSize|keyboardHidden|fontScale|smallestScreenSize|screenLayout|uiMode"
+            android:screenOrientation="portrait"
+            android:windowSoftInputMode="adjustPan" />
         <!--        分享开始-->
         <activity
             android:name=".wxapi.WXEntryActivity"

+ 94 - 0
student/src/main/java/com/cooleshow/student/adapter/GroupCourseGroupCourseListAdapter.java

@@ -0,0 +1,94 @@
+package com.cooleshow.student.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.UiUtils;
+import com.cooleshow.student.R;
+import com.cooleshow.student.bean.VIPCourseGroupDetailListBean;
+import com.cooleshow.student.constants.CourseConstants;
+
+import java.util.ArrayList;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Author by pq, Date on 2024/11/25.
+ */
+public class GroupCourseGroupCourseListAdapter extends BaseQuickAdapter<VIPCourseGroupDetailListBean, BaseViewHolder> {
+    public GroupCourseGroupCourseListAdapter() {
+        super(R.layout.item_group_course_group_course_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);
+
+        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, getStudentNames(data.getCourseStudentVos()));
+
+        holder.setText(R.id.tv_course_name, data.getSubjectName());
+
+        TextView tv_des = holder.getView(R.id.tv_des);
+        tv_des.setText(data.getCoursePlan());
+        tv_des.setVisibility(!TextUtils.isEmpty(data.getCoursePlan()) ? View.VISIBLE : View.GONE);
+
+        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));
+        }
+    }
+
+    private String getStudentNames(ArrayList<VIPCourseGroupDetailListBean.CourseStudentVosBean> list) {
+        if (list == null || list.size() == 0) {
+            return "";
+        }
+        StringBuilder stringBuilder = new StringBuilder();
+        if (list.size() > 1) {
+            stringBuilder.append(list.get(0).getUserName())
+                    .append("、")
+                    .append(list.get(1).getUserName())
+                    .append("等")
+                    .append(list.size())
+                    .append("人");
+        } else {
+            stringBuilder.append(list.get(0).getUserName());
+        }
+        return stringBuilder.toString();
+    }
+}

+ 10 - 0
student/src/main/java/com/cooleshow/student/api/APIService.java

@@ -18,6 +18,7 @@ import com.cooleshow.student.bean.AwardStatusBean;
 import com.cooleshow.student.bean.CountOfUnreadBean;
 import com.cooleshow.student.bean.CourseTableDataBean;
 import com.cooleshow.student.bean.FriendInfoBean;
+import com.cooleshow.student.bean.GroupCourseGroupDetailBean;
 import com.cooleshow.student.bean.HelpCenterContentBean;
 import com.cooleshow.student.bean.HomeHotMusicSheetBean;
 import com.cooleshow.student.bean.HomeHotNewsBean;
@@ -616,4 +617,13 @@ public interface APIService {
      */
     @GET(STUDENT_GROUP + "sysConfig/queryByParamName")
     Observable<BaseResponse<QueryParamsConfigBean>> querySysConfigByParamName(@Query("paramName") String name);
+
+    /**
+     *
+     *
+     * @param
+     * @return
+     */
+    @GET(STUDENT_GROUP + "courseGroup/queryCourseInfo")
+    Observable<BaseResponse<GroupCourseGroupDetailBean>> getGroupCourseGroupDetail(@Query("groupId") String groupId);
 }

+ 291 - 0
student/src/main/java/com/cooleshow/student/bean/GroupCourseGroupDetailBean.java

@@ -0,0 +1,291 @@
+package com.cooleshow.student.bean;
+
+/**
+ * Author by pq, Date on 2024/11/22.
+ */
+public class GroupCourseGroupDetailBean {
+
+
+    /**
+     * auditVersion : 0
+     * avatar : https://oss.dayaedu.com/klx/user/android/2024-11/2248321_1732503189777.jpeg
+     * backgroundPic :
+     * courseGroupId : 377
+     * courseGroupName : 长笛VIP定制课
+     * courseIntroduce : 长笛VIP定制课
+     * courseNum : 4
+     * coursePlan :
+     * coursePrice : 40.0
+     * courseStartTime : null
+     * degreeFlag : 1
+     * existBuy : 0
+     * imGroupId :
+     * maxStudentNum : 5
+     * mixStudentNum : 1
+     * myself : true
+     * reason :
+     * salesEndDate : null
+     * salesStartDate : null
+     * singleCourseMinutes : 45
+     * status : ING
+     * studentCount : 1
+     * subjectName : 长笛
+     * teacherFlag : 1
+     * teacherId : 2248321
+     * teacherName : 李霞
+     * userName : 郭娜妍
+     */
+
+    private int auditVersion;
+    private String avatar;
+    private String backgroundPic;
+    private int courseGroupId;
+    private String courseGroupName;
+    private String courseIntroduce;
+    private int courseNum;
+    private String coursePlan;
+    private String coursePrice;
+    private String courseStartTime;
+    private int degreeFlag;
+    private int existBuy;
+    private String imGroupId;
+    private int maxStudentNum;
+    private int mixStudentNum;
+    private boolean myself;
+    private String reason;
+    private Object salesEndDate;
+    private Object salesStartDate;
+    private int singleCourseMinutes;
+    private String status;
+    private int studentCount;
+    private String subjectName;
+    private int teacherFlag;
+    private int teacherId;
+    private String teacherName;
+    private String userName;
+    private String completeCourseNum;
+
+    public String getCompleteCourseNum() {
+        return completeCourseNum;
+    }
+
+    public void setCompleteCourseNum(String completeCourseNum) {
+        this.completeCourseNum = completeCourseNum;
+    }
+
+    public int getAuditVersion() {
+        return auditVersion;
+    }
+
+    public void setAuditVersion(int auditVersion) {
+        this.auditVersion = auditVersion;
+    }
+
+    public String getAvatar() {
+        return avatar;
+    }
+
+    public void setAvatar(String avatar) {
+        this.avatar = avatar;
+    }
+
+    public String getBackgroundPic() {
+        return backgroundPic;
+    }
+
+    public void setBackgroundPic(String backgroundPic) {
+        this.backgroundPic = backgroundPic;
+    }
+
+    public int getCourseGroupId() {
+        return courseGroupId;
+    }
+
+    public void setCourseGroupId(int courseGroupId) {
+        this.courseGroupId = courseGroupId;
+    }
+
+    public String getCourseGroupName() {
+        return courseGroupName;
+    }
+
+    public void setCourseGroupName(String courseGroupName) {
+        this.courseGroupName = courseGroupName;
+    }
+
+    public String getCourseIntroduce() {
+        return courseIntroduce;
+    }
+
+    public void setCourseIntroduce(String courseIntroduce) {
+        this.courseIntroduce = courseIntroduce;
+    }
+
+    public int getCourseNum() {
+        return courseNum;
+    }
+
+    public void setCourseNum(int courseNum) {
+        this.courseNum = courseNum;
+    }
+
+    public String getCoursePlan() {
+        return coursePlan;
+    }
+
+    public void setCoursePlan(String coursePlan) {
+        this.coursePlan = coursePlan;
+    }
+
+    public String getCoursePrice() {
+        return coursePrice;
+    }
+
+    public void setCoursePrice(String coursePrice) {
+        this.coursePrice = coursePrice;
+    }
+
+    public String getCourseStartTime() {
+        return courseStartTime;
+    }
+
+    public void setCourseStartTime(String courseStartTime) {
+        this.courseStartTime = courseStartTime;
+    }
+
+    public int getDegreeFlag() {
+        return degreeFlag;
+    }
+
+    public void setDegreeFlag(int degreeFlag) {
+        this.degreeFlag = degreeFlag;
+    }
+
+    public int getExistBuy() {
+        return existBuy;
+    }
+
+    public void setExistBuy(int existBuy) {
+        this.existBuy = existBuy;
+    }
+
+    public String getImGroupId() {
+        return imGroupId;
+    }
+
+    public void setImGroupId(String imGroupId) {
+        this.imGroupId = imGroupId;
+    }
+
+    public int getMaxStudentNum() {
+        return maxStudentNum;
+    }
+
+    public void setMaxStudentNum(int maxStudentNum) {
+        this.maxStudentNum = maxStudentNum;
+    }
+
+    public int getMixStudentNum() {
+        return mixStudentNum;
+    }
+
+    public void setMixStudentNum(int mixStudentNum) {
+        this.mixStudentNum = mixStudentNum;
+    }
+
+    public boolean isMyself() {
+        return myself;
+    }
+
+    public void setMyself(boolean myself) {
+        this.myself = myself;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    public void setReason(String reason) {
+        this.reason = reason;
+    }
+
+    public Object getSalesEndDate() {
+        return salesEndDate;
+    }
+
+    public void setSalesEndDate(Object salesEndDate) {
+        this.salesEndDate = salesEndDate;
+    }
+
+    public Object getSalesStartDate() {
+        return salesStartDate;
+    }
+
+    public void setSalesStartDate(Object salesStartDate) {
+        this.salesStartDate = salesStartDate;
+    }
+
+    public int getSingleCourseMinutes() {
+        return singleCourseMinutes;
+    }
+
+    public void setSingleCourseMinutes(int singleCourseMinutes) {
+        this.singleCourseMinutes = singleCourseMinutes;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public int getStudentCount() {
+        return studentCount;
+    }
+
+    public void setStudentCount(int studentCount) {
+        this.studentCount = studentCount;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public void setSubjectName(String subjectName) {
+        this.subjectName = subjectName;
+    }
+
+    public int getTeacherFlag() {
+        return teacherFlag;
+    }
+
+    public void setTeacherFlag(int teacherFlag) {
+        this.teacherFlag = teacherFlag;
+    }
+
+    public int getTeacherId() {
+        return teacherId;
+    }
+
+    public void setTeacherId(int teacherId) {
+        this.teacherId = teacherId;
+    }
+
+    public String getTeacherName() {
+        return teacherName;
+    }
+
+    public void setTeacherName(String teacherName) {
+        this.teacherName = teacherName;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+}

+ 3 - 3
student/src/main/java/com/cooleshow/student/bean/LiveCourseListBean.java

@@ -89,15 +89,15 @@ public class LiveCourseListBean {
         public String startTime;
         public String courseType;
         public String subjectName;
-        public int courseId;
+        public String courseId;
         public String imGroupId;
-        public int subjectId;
+        public String subjectId;
         public String avatar;
         public int studentReplied;
         public String userId;
         public String classDate;
         public int teacherReplied;
-        public int courseGoupId;
+        public String courseGoupId;
         public String cover;
         public String payCount;
         public String name;

+ 9 - 0
student/src/main/java/com/cooleshow/student/bean/VIPCourseGroupDetailListBean.java

@@ -52,6 +52,15 @@ public class VIPCourseGroupDetailListBean {
     private String userId;
     private String userName;
     private ArrayList<CourseStudentVosBean> courseStudentVos;
+    private String coursePlan;
+
+    public String getCoursePlan() {
+        return coursePlan;
+    }
+
+    public void setCoursePlan(String coursePlan) {
+        this.coursePlan = coursePlan;
+    }
 
     public ArrayList<CourseStudentVosBean> getCourseStudentVos() {
         return courseStudentVos;

+ 1 - 0
student/src/main/java/com/cooleshow/student/constants/CourseConstants.java

@@ -31,6 +31,7 @@ public class CourseConstants {
     public static final String COURSE_ID = "course_id";
     public static final String COURSE_GROUP_ID = "course_group_id";
     public static final String STUDENT_ID = "student_id";
+    public static final String COURSE_GROUP_STATUS_APPLY = "APPLY";//学生课程组状态报名中
 
     public static final int COURSE_HOMEWORK_MAX_VIDEO_COUNT=3;//课后作业最多视频数量
 

+ 26 - 0
student/src/main/java/com/cooleshow/student/contract/GroupCourseGroupDetailContract.java

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

+ 86 - 0
student/src/main/java/com/cooleshow/student/presenter/course/GroupCourseGroupDetailPresenter.java

@@ -0,0 +1,86 @@
+package com.cooleshow.student.presenter.course;
+
+import android.text.TextUtils;
+
+import com.cooleshow.base.bean.CommonCourseConfigBean;
+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.student.api.APIService;
+import com.cooleshow.student.bean.GroupCourseGroupDetailBean;
+import com.cooleshow.student.bean.VIPCourseGroupDetailListBean;
+import com.cooleshow.student.contract.GroupCourseGroupDetailContract;
+
+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 GroupCourseGroupDetailPresenter extends BasePresenter<GroupCourseGroupDetailContract.View> implements GroupCourseGroupDetailContract.Presenter {
+
+    public void queryDetail(boolean isShowLoading, String courseGroupId) {
+        if (isShowLoading && getView() != null) {
+            getView().showLoading();
+        }
+        addSubscribe(create(APIService.class).getGroupCourseGroupDetail(courseGroupId), new BaseObserver<GroupCourseGroupDetailBean>(getView()) {
+            @Override
+            protected void onSuccess(GroupCourseGroupDetailBean 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);
+                }
+            }
+        });
+    }
+}

+ 383 - 0
student/src/main/java/com/cooleshow/student/ui/course/GroupCourseGroupDetailActivity.java

@@ -0,0 +1,383 @@
+package com.cooleshow.student.ui.course;
+
+import android.content.DialogInterface;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+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.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.CourseAttendanceStatusType;
+import com.cooleshow.base.constanst.CourseStatusType;
+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.StringUtils;
+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.SolveEditTextScrollClash;
+import com.cooleshow.base.widgets.dialog.CommonFilterDialog;
+import com.cooleshow.student.R;
+import com.cooleshow.student.adapter.GroupCourseGroupCourseListAdapter;
+import com.cooleshow.student.adapter.PianoCourseGroupCourseListAdapter;
+import com.cooleshow.student.bean.GroupCourseGroupDetailBean;
+import com.cooleshow.student.bean.VIPCourseGroupDetailListBean;
+import com.cooleshow.student.constants.CourseConstants;
+import com.cooleshow.student.contract.GroupCourseGroupDetailContract;
+import com.cooleshow.student.databinding.AcGroupCourseGroupDetailLayoutBinding;
+import com.cooleshow.student.presenter.course.GroupCourseGroupDetailPresenter;
+import com.cooleshow.student.widgets.AppBarLayoutStateChangeListener;
+import com.dayayuemeng.classroom.helper.OpenClassRoomHelper;
+import com.google.android.material.appbar.AppBarLayout;
+import com.google.android.material.tabs.TabLayout;
+import com.google.android.material.tabs.TabLayoutMediator;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.LinearLayoutManager;
+
+/**
+ * Author by pq, Date on 2024/11/22.
+ */
+@Route(path = RouterPath.CourseCenter.GROUP_COURSE_GROUP_DETAIL)
+public class GroupCourseGroupDetailActivity extends BaseMVPActivity<AcGroupCourseGroupDetailLayoutBinding, GroupCourseGroupDetailPresenter> implements GroupCourseGroupDetailContract.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 courseGroupId;
+    private CommonCourseConfigBean mConfigBean;
+    private GroupCourseGroupDetailBean mDetailBean;
+    private GroupCourseGroupCourseListAdapter mAdapter;
+    private List<IFilterViewData> statusList;//状态筛选
+    private List<IFilterViewData> attendanceStatusList;//考勤状态筛选
+    private int currentSelectStatusPosition = 0;
+    private int currentSelectAttendancePosition = 0;
+    private CommonFilterDialog mAttendanceStatusFilterDialog;
+    private CommonFilterDialog mStatusFilterDialog;
+    private String courseStatus = CourseStatusType.ALL.getId();
+    private String currentAttendanceStatus;
+    private String classMonth;
+    private Date currentSelectDate;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        QMUIStatusBarHelper.setStatusBarLightMode(GroupCourseGroupDetailActivity.this);
+    }
+
+    @Override
+    protected void initView() {
+        initMidTitleToolBar(viewBinding.toolbarInclude.toolbar, "小组课详情");
+        viewBinding.scCoursePlan.setOnTouchListener(new SolveEditTextScrollClash(viewBinding.scCoursePlan));
+        viewBinding.scCoursePlan.setVerticalScrollBarEnabled(true);
+    }
+
+    @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 GroupCourseGroupCourseListAdapter();
+        mAdapter.setEmptyView(emptyViewLayout);
+        viewBinding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
+        viewBinding.recyclerView.setAdapter(mAdapter);
+
+        initListener();
+    }
+
+    private void initFilterData() {
+        CourseStatusType[] values = CourseStatusType.values();
+        List<CourseStatusType> 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.flStatus.setOnClickListener(this);
+        viewBinding.flAttendance.setOnClickListener(this);
+        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;
+            }
+        });
+
+        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);
+//                    ARouter.getInstance().build(RouterPath.CourseCenter.PIANO_ROOM_COURSE_DETAIL)
+//                            .withString(CourseConstants.COURSE_ID, bean.getCourseId())
+//                            .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 switchTitleStyle(int mode) {
+        if (titleStyleMode == mode) {
+            return;
+        }
+        titleStyleMode = mode;
+        if (mode == 1) {
+            viewBinding.collapsingToolbarLayout.setContentScrimColor(Color.TRANSPARENT);
+            viewBinding.collapsingToolbarLayout.setStatusBarScrimColor(Color.TRANSPARENT);
+        } else {
+            viewBinding.collapsingToolbarLayout.setContentScrimColor(Color.WHITE);
+            viewBinding.collapsingToolbarLayout.setStatusBarScrimColor(Color.WHITE);
+        }
+    }
+
+    @Override
+    protected AcGroupCourseGroupDetailLayoutBinding getLayoutView() {
+        return AcGroupCourseGroupDetailLayoutBinding.inflate(getLayoutInflater());
+    }
+
+    @Override
+    protected GroupCourseGroupDetailPresenter createPresenter() {
+        return new GroupCourseGroupDetailPresenter();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        refresh();
+    }
+
+    private void goCourse(String id, String startTime, String subjectName) {
+        if (mConfigBean != null) {
+            boolean lessThanTargetTime = TimeUtils.isLessThanTargetTime(mConfigBean.getGroupStartTime(), startTime);
+            if (!lessThanTargetTime) {
+                ToastUtil.getInstance().showShort("课程还未开始,请在上课前" + mConfigBean.getGroupStartTime() + "分钟进入");
+                return;
+            }
+            OpenClassRoomHelper.start(this, id, subjectName);
+        }
+    }
+
+    private void refresh() {
+        presenter.getCourseConfig();
+        presenter.queryDetail(true, courseGroupId);
+        reBuildFilter(currentSelectDate, courseStatus, currentAttendanceStatus);
+    }
+
+
+    @Override
+    public void getDetailSuccess(GroupCourseGroupDetailBean bean) {
+        if (!checkActivityExist()) {
+            return;
+        }
+        this.mDetailBean = bean;
+
+        GlideUtils.INSTANCE.loadImage(this, bean.getBackgroundPic(), viewBinding.ivBg, com.cooleshow.base.R.drawable.bg_video_placeholder);
+        GlideUtils.INSTANCE.loadImage(this, bean.getAvatar(), viewBinding.ivAvatar, R.drawable.icon_teacher_default_head);
+        viewBinding.tvCourseName.setText(bean.getSubjectName());
+
+        viewBinding.tvTitle.setText(bean.getCourseGroupName());
+        String timeStr = TextUtils.isEmpty(bean.getCourseStartTime()) ? "" : TimeUtils.date2String(TimeUtils.string2Date(bean.getCourseStartTime()), "yyyy-MM-dd HH:mm");
+        //时间
+        viewBinding.tvTime.setText(String.format("开课时间:%s", timeStr));
+        String tip = "";
+        if (TextUtils.equals(bean.getStatus(), CourseConstants.COURSE_GROUP_STATUS_APPLY)) {
+            tip = String.format("剩余%d个名额", bean.getMaxStudentNum() - bean.getStudentCount());
+        } else {
+            tip = UiUtils.getBuyNumTip2("", String.valueOf(bean.getStudentCount()));
+        }
+        viewBinding.tvBuyNum.setText(tip);
+
+        viewBinding.tvTeacherName.setText(bean.getTeacherName());
+        viewBinding.tvCourseCompletedValue.setText(bean.getCompleteCourseNum());
+        viewBinding.tvCourseTotalValue.setText(String.valueOf(bean.getCourseNum()));
+
+        //价格
+        viewBinding.tvPrice.setText(UiUtils.getLiveCoursePriceTextForStu(bean.getCoursePrice()));
+
+        viewBinding.tvPriceUnit.setText(String.format("/%d课时", bean.getCourseNum()));
+
+        String courseIntroduce = StringUtils.replaceSpace(bean.getCourseIntroduce());
+        boolean hasPlan = !TextUtils.isEmpty(courseIntroduce);
+        viewBinding.tvPlanContent.setText(courseIntroduce);
+        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 onClick(View v) {
+        int id = v.getId();
+
+        if (id == R.id.fl_status) {
+            selectCourseStatus();
+            return;
+        }
+
+        if (id == R.id.fl_attendance) {
+            selectAttendanceStatus();
+            return;
+        }
+    }
+
+    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()) {
+                        GroupCourseGroupDetailActivity.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()) {
+                        GroupCourseGroupDetailActivity.this.currentSelectAttendancePosition = pos;
+                        IFilterViewData iFilterViewData = attendanceStatusList.get(pos);
+                        currentAttendanceStatus = iFilterViewData.getDataId();
+                        viewBinding.tvAttendanceStatus.setText(iFilterViewData.getShowName());
+                        reBuildFilter(currentSelectDate, courseStatus, currentAttendanceStatus);
+                    }
+                }
+            });
+
+            mAttendanceStatusFilterDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+                @Override
+                public void onDismiss(DialogInterface dialog) {
+                    UiUtils.refreshFilterTextStyle(false, viewBinding.tvAttendanceStatus);
+                }
+            });
+        }
+        if (!mAttendanceStatusFilterDialog.isShowing()) {
+            mAttendanceStatusFilterDialog.show();
+            UiUtils.refreshFilterTextStyle(true, viewBinding.tvAttendanceStatus);
+        }
+        mAttendanceStatusFilterDialog.setSelectPos(currentSelectAttendancePosition);
+        mAttendanceStatusFilterDialog.setData(attendanceStatusList);
+    }
+
+
+    private void reBuildFilter(Date date, String status, String attendanceStatus) {
+        currentSelectDate = date != null ? date : TimeUtils.getNowDate();
+        String targetDateTimeStr = TimeUtils.date2String(currentSelectDate, TimeUtils.getSafeDateFormat("yyyy-MM"));
+        String targetDateTimeText = TimeUtils.date2String(currentSelectDate, TimeUtils.getSafeDateFormat("yyyy年MM月"));
+        classMonth = targetDateTimeStr;
+        courseStatus = !TextUtils.isEmpty(status) ? status : CourseStatusType.ALL.getId();
+        currentAttendanceStatus = !TextUtils.isEmpty(attendanceStatus) ? attendanceStatus : CourseAttendanceStatusType.ALL.getId();
+        if (viewBinding != null) {
+            viewBinding.tvTime.setText(targetDateTimeText);
+        }
+        refreshCourseList(false);
+    }
+
+    private void refreshCourseList(boolean isShowLoading) {
+        if (TextUtils.isEmpty(courseGroupId)) {
+            return;
+        }
+        presenter.queryCourseList(isShowLoading, courseGroupId, "", courseStatus, currentAttendanceStatus);
+    }
+}

+ 3 - 4
student/src/main/java/com/cooleshow/student/ui/course/GroupCourseGroupFragment.java

@@ -155,10 +155,9 @@ public class GroupCourseGroupFragment extends BaseMVPFragment<FragmentGroupCours
 
         mAdapter.setOnItemClickListener((adapter, view, position) -> {
             LiveCourseListBean.RowsBean item = (LiveCourseListBean.RowsBean) adapter.getItem(position);
-//            ARouter.getInstance()
-//                    .build(RouterPath.WebCenter.ACTIVITY_HTML)
-//                    .withString(WebConstants.WEB_URL, String.format(WebConstants.TEACHER_LIVE_DETAIL_NORMAL_COURSE, item.courseGoupId, item.courseId))
-//                    .navigation();
+            ARouter.getInstance().build(RouterPath.CourseCenter.GROUP_COURSE_GROUP_DETAIL)
+                    .withString(CourseConstants.COURSE_GROUP_ID, item.courseGoupId)
+                    .navigation();
         });
         mAdapter.setOnItemChildClickListener(new OnItemChildClickListener() {
             @Override

+ 461 - 0
student/src/main/res/layout/ac_group_course_group_detail_layout.xml

@@ -0,0 +1,461 @@
+<?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">
+
+    <include
+        android:id="@+id/toolbar_include"
+        layout="@layout/common_toolbar_layout" />
+
+    <androidx.coordinatorlayout.widget.CoordinatorLayout
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        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:paddingBottom="12dp"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:background="@color/transparent"
+            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: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"
+                    app:layout_collapseMode="none">
+
+                    <androidx.constraintlayout.widget.ConstraintLayout
+                        android:layout_width="match_parent"
+                        android:id="@+id/cs_header"
+                        app:layout_constraintTop_toTopOf="parent"
+                        app:layout_constraintLeft_toLeftOf="parent"
+                        android:layout_height="wrap_content"
+                        android:background="@drawable/bg_white_10dp"
+                        android:paddingBottom="12dp">
+
+                        <ImageView
+                            android:id="@+id/iv_bg"
+                            android:layout_width="0dp"
+                            app:layout_constraintDimensionRatio="h,16:9"
+                            app:layout_constraintRight_toRightOf="parent"
+                            android:layout_height="0dp"
+                            app:layout_constraintLeft_toLeftOf="parent"
+                            app:layout_constraintTop_toTopOf="parent"
+                            app:qmui_corner_radius="6dp" />
+
+                        <TextView
+                            android:id="@+id/tv_course_name"
+                            android:layout_width="wrap_content"
+                            android:layout_height="@dimen/dp_19"
+                            android:layout_marginTop="8dp"
+                            android:layout_marginStart="@dimen/dp_8"
+                            android:background="@drawable/shape_66000000_3dp"
+                            android:gravity="center"
+                            android:includeFontPadding="false"
+                            android:paddingStart="@dimen/dp_6"
+                            android:paddingEnd="@dimen/dp_6"
+                            android:textColor="@color/white"
+                            android:textSize="@dimen/sp_12"
+                            app:layout_constraintTop_toTopOf="@+id/iv_bg"
+                            app:layout_constraintLeft_toLeftOf="@+id/iv_bg"
+                            tools:text="单簧管" />
+
+                        <TextView
+                            android:visibility="gone"
+                            android:id="@+id/tv_course_status_tip"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:background="@drawable/shape_ffe7e7_15dp_left"
+                            android:gravity="center"
+                            android:paddingStart="12dp"
+                            android:paddingTop="3dp"
+                            android:paddingEnd="12dp"
+                            android:paddingBottom="3dp"
+                            android:text="销售中"
+                            android:textColor="@color/color_ff1919"
+                            android:textSize="@dimen/sp_10"
+                            app:layout_constraintBottom_toBottomOf="@+id/tv_course_name"
+                            app:layout_constraintRight_toRightOf="@+id/iv_bg"
+                            app:layout_constraintTop_toTopOf="@+id/tv_course_name" />
+
+
+                        <TextView
+                            android:layout_marginEnd="14dp"
+                            android:layout_marginStart="14dp"
+                            android:id="@+id/tv_title"
+                            android:layout_width="0dp"
+                            android:layout_height="wrap_content"
+                            android:ellipsize="end"
+                            android:includeFontPadding="false"
+                            android:maxLines="1"
+                            android:textColor="@color/color_1a1a1a"
+                            android:textSize="@dimen/sp_16"
+                            android:textStyle="bold"
+                            android:layout_marginTop="8dp"
+                            app:layout_constraintLeft_toLeftOf="@+id/iv_bg"
+                            app:layout_constraintRight_toRightOf="@+id/iv_bg"
+                            app:layout_constraintTop_toBottomOf="@+id/iv_bg"
+                            app:layout_constraintVertical_chainStyle="packed"
+                            tools:text="张豆张豆豆豆张豆张豆豆豆张豆张豆豆豆张豆张豆豆豆" />
+
+                        <TextView
+                            android:drawableStart="@drawable/icon_live_course_time_tag"
+                            android:id="@+id/tv_time"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_marginTop="12dp"
+                            android:includeFontPadding="false"
+                            android:textColor="@color/color_333333"
+                            android:textSize="@dimen/sp_14"
+                            android:textStyle="bold"
+                            android:drawablePadding="6dp"
+                            app:layout_constraintTop_toBottomOf="@+id/tv_title"
+                            app:layout_constraintLeft_toLeftOf="@+id/tv_title"
+                            tools:text="开课时间:2024-11-16 09:30" />
+
+                        <TextView
+                            android:visibility="gone"
+                            android:id="@+id/tv_des"
+                            android:layout_width="0dp"
+                            android:layout_height="wrap_content"
+                            android:ellipsize="end"
+                            android:includeFontPadding="false"
+                            android:maxLines="1"
+                            android:textColor="@color/color_777777"
+                            android:textSize="@dimen/sp_14"
+                            android:layout_marginTop="4dp"
+                            app:layout_constraintLeft_toLeftOf="@+id/iv_bg"
+                            app:layout_constraintRight_toRightOf="@+id/iv_bg"
+                            app:layout_constraintTop_toBottomOf="@+id/tv_title"
+                            tools:text="国际著名长笛演奏家、教育家子珊女士为您讲教育家子珊女士为您讲教育家子珊女士为您讲" />
+
+                        <TextView
+                            android:id="@+id/tv_buy_num"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:background="@drawable/shape_12ff802c_2dp"
+                            android:textColor="@color/color_ff6827"
+                            android:textSize="@dimen/sp_12"
+                            android:visibility="visible"
+                            android:paddingStart="4dp"
+                            android:paddingEnd="4dp"
+                            android:paddingTop="3dp"
+                            android:paddingBottom="3dp"
+                            android:includeFontPadding="false"
+                            app:layout_constraintBottom_toBottomOf="@+id/tv_time"
+                            app:layout_constraintTop_toTopOf="@+id/tv_time"
+                            app:layout_constraintRight_toRightOf="@+id/tv_title"
+                            tools:text="6人已购买" />
+
+
+                        <View
+                            android:id="@+id/view_line"
+                            android:layout_marginTop="12dp"
+                            app:layout_constraintRight_toRightOf="@+id/tv_title"
+                            app:layout_constraintLeft_toLeftOf="@+id/tv_title"
+                            app:layout_constraintTop_toBottomOf="@+id/tv_time"
+                            android:background="@color/color_f2f2f2"
+                            android:layout_width="match_parent"
+                            android:layout_height="1dp"/>
+
+                        <de.hdodenhof.circleimageview.CircleImageView
+                            android:layout_width="40dp"
+                            android:id="@+id/iv_avatar"
+                            android:layout_marginTop="12dp"
+                            app:layout_constraintLeft_toLeftOf="@+id/tv_title"
+                            app:layout_constraintTop_toBottomOf="@+id/view_line"
+                            android:layout_height="40dp"/>
+
+                        <TextView
+                            app:layout_constraintBottom_toTopOf="@+id/iv_course_tag"
+                            android:id="@+id/tv_teacher_name"
+                            tools:text="老师昵称"
+                            android:includeFontPadding="false"
+                            android:textSize="@dimen/sp_15"
+                            android:textColor="@color/color_333333"
+                            android:layout_marginStart="10dp"
+                            app:layout_constraintTop_toTopOf="@+id/iv_avatar"
+                            app:layout_constraintLeft_toRightOf="@+id/iv_avatar"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"/>
+
+                        <ImageView
+                            android:layout_marginTop="3dp"
+                            android:id="@+id/iv_course_tag"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            app:layout_constraintBottom_toBottomOf="@+id/iv_avatar"
+                            android:src="@drawable/icon_course_completed_tag"
+                            app:layout_constraintLeft_toLeftOf="@+id/tv_teacher_name"
+                            app:layout_constraintTop_toBottomOf="@+id/tv_teacher_name" />
+
+                        <TextView
+                            android:layout_marginStart="4dp"
+                            android:id="@+id/tv_course_completed_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_constraintBottom_toBottomOf="@+id/iv_course_tag"
+                            app:layout_constraintTop_toTopOf="@+id/iv_course_tag"
+                            app:layout_constraintLeft_toRightOf="@+id/iv_course_tag"
+                            />
+
+
+                        <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_title"
+                            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_completed_title"
+                            app:layout_constraintLeft_toRightOf="@+id/tv_course_total_title" />
+
+
+                        <TextView
+                            android:id="@+id/tv_price"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="¥120"
+                            android:textColor="@color/color_f44541"
+                            android:textSize="@dimen/sp_20"
+                            android:textStyle="bold"
+                            android:includeFontPadding="false"
+                            app:layout_constraintTop_toTopOf="@+id/iv_avatar"
+                            app:layout_constraintBottom_toBottomOf="@+id/iv_avatar"
+                            app:layout_constraintRight_toLeftOf="@+id/tv_price_unit" />
+
+                        <TextView
+                            android:includeFontPadding="false"
+                            android:id="@+id/tv_price_unit"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:paddingStart="2dp"
+                            android:text="/4课时"
+                            android:layout_marginEnd="14dp"
+                            android:textColor="@color/color_999999"
+                            android:textSize="@dimen/sp_12"
+                            app:layout_constraintRight_toRightOf="parent"
+                            app:layout_constraintBaseline_toBaselineOf="@+id/tv_price" />
+
+                        <ImageView
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:layout_marginStart="5dp"
+                            android:src="@drawable/icon_chat_small"
+                            android:visibility="gone"
+                            app:layout_constraintBottom_toBottomOf="@+id/tv_title"
+                            app:layout_constraintLeft_toRightOf="@+id/tv_title"
+                            app:layout_constraintTop_toTopOf="@+id/tv_title" />
+
+                    </androidx.constraintlayout.widget.ConstraintLayout>
+
+                    <androidx.constraintlayout.widget.ConstraintLayout
+                        android:id="@+id/cs_course_plan"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_marginTop="12dp"
+                        android:background="@drawable/shape_white_8dp"
+                        android:padding="12dp"
+                        android:layout_marginStart="14dp"
+                        android:layout_marginEnd="14dp"
+                        android:visibility="gone"
+                        tools:visibility="visible"
+                        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" />
+
+
+                        <androidx.core.widget.NestedScrollView
+                            android:layout_marginTop="12dp"
+                            android:id="@+id/sc_course_plan"
+                            android:scrollbars="vertical"
+                            android:fadeScrollbars="false"
+                            android:scrollbarThumbVertical="@drawable/shape_e2e2e2_2dp"
+                            android:scrollbarStyle="outsideInset"
+                            app:layout_constraintLeft_toLeftOf="parent"
+                            app:layout_constraintRight_toRightOf="parent"
+                            app:layout_constraintTop_toBottomOf="@+id/tv_plan_title"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content">
+                            <TextView
+                                android:id="@+id/tv_plan_content"
+                                android:layout_width="match_parent"
+                                android:layout_height="wrap_content"
+                                android:includeFontPadding="false"
+                                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.core.widget.NestedScrollView>
+
+                    </androidx.constraintlayout.widget.ConstraintLayout>
+                </androidx.constraintlayout.widget.ConstraintLayout>
+            </com.google.android.material.appbar.CollapsingToolbarLayout>
+
+            <LinearLayout
+                android:id="@+id/ll_filter"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="14dp"
+                android:layout_marginTop="12dp"
+                android:layout_marginEnd="14dp"
+                android:orientation="horizontal"
+                app:layout_constraintLeft_toLeftOf="parent"
+                app:layout_constraintTop_toTopOf="parent">
+
+                <FrameLayout
+                    android:visibility="gone"
+                    android:id="@+id/fl_time"
+                    android:layout_width="0dp"
+                    android:layout_height="22dp"
+                    android:layout_marginEnd="11dp"
+                    android:layout_weight="0.4"
+                    android:background="@drawable/bg_white_4dp">
+
+                    <TextView
+                        android:id="@+id/tv_time_filter"
+                        android:layout_width="wrap_content"
+                        android:layout_height="match_parent"
+                        android:layout_gravity="center"
+                        android:drawableRight="@drawable/icon_arrow_down"
+                        android:drawablePadding="4dp"
+                        android:ellipsize="end"
+                        android:gravity="center"
+                        android:includeFontPadding="false"
+                        android:maxLines="1"
+                        android:text="@string/all_attendance_str"
+                        android:textColor="@color/color_131415"
+                        android:textSize="@dimen/sp_14"
+                        tools:text="2024年10月" />
+                </FrameLayout>
+
+                <FrameLayout
+                    android:id="@+id/fl_status"
+                    android:layout_width="0dp"
+                    android:layout_height="26dp"
+                    android:layout_marginEnd="11dp"
+                    android:layout_weight="0.3"
+                    android:background="@drawable/bg_white_4dp">
+
+                    <TextView
+                        android:id="@+id/tv_course_status"
+                        android:layout_width="wrap_content"
+                        android:layout_height="match_parent"
+                        android:layout_gravity="center"
+                        android:background="@drawable/bg_white_10dp"
+                        android:drawableRight="@drawable/icon_arrow_down"
+                        android:drawablePadding="4dp"
+                        android:ellipsize="end"
+                        android:gravity="center"
+                        android:includeFontPadding="false"
+                        android:maxLines="1"
+                        android:text="@string/all_course_status_str"
+                        android:textColor="@color/color_131415"
+                        android:textSize="@dimen/sp_14"
+                        tools:text="全部状态" />
+
+                </FrameLayout>
+
+                <FrameLayout
+                    android:id="@+id/fl_attendance"
+                    android:layout_width="0dp"
+                    android:layout_height="26dp"
+                    android:layout_weight="0.3"
+                    android:background="@drawable/bg_white_4dp">
+
+                    <TextView
+                        android:id="@+id/tv_attendance_status"
+                        android:layout_width="wrap_content"
+                        android:layout_height="match_parent"
+                        android:layout_gravity="center"
+                        android:background="@drawable/bg_white_10dp"
+                        android:drawableRight="@drawable/icon_arrow_down"
+                        android:drawablePadding="4dp"
+                        android:ellipsize="end"
+                        android:gravity="center"
+                        android:includeFontPadding="false"
+                        android:maxLines="1"
+                        android:text="@string/all_attendance_str"
+                        android:textColor="@color/color_131415"
+                        android:textSize="@dimen/sp_14"
+                        tools:text="全部考勤" />
+                </FrameLayout>
+            </LinearLayout>
+        </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>

+ 197 - 0
student/src/main/res/layout/item_group_course_group_course_layout.xml

@@ -0,0 +1,197 @@
+<?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_marginEnd="14dp"
+    android:layout_marginBottom="12dp"
+    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" />
+
+    <ImageView
+        android:id="@+id/iv_avatar"
+        android:layout_width="40dp"
+        android:layout_height="40dp"
+        android:layout_marginTop="12dp"
+        android:src="@drawable/icon_group_course_avatar"
+        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:ellipsize="end"
+        android:includeFontPadding="false"
+        android:maxLines="1"
+        android:textColor="@color/color_1a1a1a"
+        android:textSize="@dimen/sp_15"
+        app:layout_constraintBottom_toTopOf="@+id/tv_name"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintLeft_toRightOf="@+id/iv_avatar"
+        app:layout_constraintRight_toLeftOf="@+id/iv_attendance_status"
+        app:layout_constraintTop_toTopOf="@+id/iv_avatar"
+        app:layout_constraintVertical_chainStyle="packed"
+        app:layout_constraintWidth_default="wrap"
+        tools:text="VIP定制课-张豆豆VIP定制课-张豆豆" />
+
+    <ImageView
+        android:id="@+id/iv_attendance_status"
+        android:layout_width="wrap_content"
+        android:adjustViewBounds="true"
+        android:layout_height="17.1dp"
+        android:layout_marginStart="5dp"
+        android:layout_marginEnd="5dp"
+        android:src="@drawable/icon_course_attendance_truancy"
+        android:visibility="gone"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_title"
+        app:layout_constraintLeft_toRightOf="@+id/tv_title"
+        app:layout_constraintRight_toLeftOf="@+id/iv_arrow"
+        app:layout_constraintTop_toTopOf="@+id/tv_title" />
+
+    <TextView
+        android:id="@+id/tv_name"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="4dp"
+        android:ellipsize="middle"
+        android:includeFontPadding="false"
+        android:singleLine="true"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_13"
+        app:layout_constraintBottom_toBottomOf="@+id/iv_avatar"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintLeft_toLeftOf="@+id/tv_title"
+        app:layout_constraintRight_toLeftOf="@+id/tv_course_name"
+        app:layout_constraintTop_toBottomOf="@+id/tv_title"
+        app:layout_constraintWidth_default="wrap"
+        tools:text="张豆豆张豆豆张豆豆张豆豆张豆豆张豆豆张豆豆张豆豆张豆豆张豆豆张豆豆张豆豆" />
+
+    <TextView
+        tools:visibility="visible"
+        android:visibility="gone"
+        android:layout_marginTop="12dp"
+        android:layout_marginEnd="12dp"
+        android:layout_marginStart="12dp"
+        app:layout_constraintTop_toBottomOf="@+id/iv_avatar"
+        android:id="@+id/tv_des"
+        android:padding="6dp"
+        tools:text="严琦老师带您零基础学习大号,通过4节课的学习掌握大号演奏的基本方式,培养良好的吐息习惯。"
+        android:textColor="@color/color_777777"
+        android:textSize="@dimen/sp_13"
+        android:background="@drawable/shape_f8f8f8_6dp"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"/>
+
+    <ImageView
+        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"
+        android:visibility="gone"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_title"
+        app:layout_constraintLeft_toRightOf="@+id/tv_title"
+        app:layout_constraintTop_toTopOf="@+id/tv_title" />
+
+    <TextView
+        android:id="@+id/tv_course_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="5dp"
+        android:layout_marginEnd="5dp"
+        android:background="@drawable/shape_couse_type_text_bg"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:paddingStart="4dp"
+        android:paddingTop="1.5dp"
+        android:paddingEnd="4dp"
+        android:paddingBottom="1.5dp"
+        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_toLeftOf="@+id/iv_arrow"
+        app:layout_constraintTop_toTopOf="@+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:id="@+id/tv_go_start"
+        android:layout_width="wrap_content"
+        android:layout_height="22dp"
+        android:background="@drawable/shape_2dc7aa_11dp"
+        android:gravity="center"
+        android:paddingStart="8dp"
+        android:paddingEnd="8dp"
+        android:text="开始上课"
+        android:textColor="@color/white"
+        android:textSize="@dimen/sp_12"
+        android:visibility="gone"
+        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"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/icon_arrow_right"
+        app:layout_constraintBottom_toBottomOf="@+id/iv_avatar"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/iv_avatar" />
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 2 - 0
student/src/main/res/values/strings.xml

@@ -45,4 +45,6 @@
     <string name="mine_course_search_tip">请输入课程组或老师名称</string>
     <string name="enter_room_tip_str">进入教室</string>
     <string name="will_start_tip_str">即将开始</string>
+    <string name="all_attendance_str">全部考勤</string>
+    <string name="all_course_status_str">全部状态</string>
 </resources>