Pārlūkot izejas kodu

解绑银行卡 学生端:课程增加琴房课

邓琴文 3 gadi atpakaļ
vecāks
revīzija
2a29b3d064

+ 90 - 0
BaseLibrary/src/main/java/com/cooleshow/base/widgets/CommonTipDialog.java

@@ -0,0 +1,90 @@
+package com.cooleshow.base.widgets;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.WindowManager;
+
+import androidx.annotation.NonNull;
+import androidx.viewbinding.ViewBinding;
+
+import com.cooleshow.base.R;
+import com.cooleshow.base.databinding.CommonDialogTipLayoutBinding;
+import com.cooleshow.base.utils.KeyboardUtils;
+import com.cooleshow.base.utils.ToastUtils;
+
+/**
+ * @author dengqw
+ * @time 2022/6/28 21:11
+ * @describe:
+ **/
+public class CommonTipDialog extends Dialog {
+    public static final int TYPE_SET_TEACHER_COMMENT = 0;//老师评价
+    public static final int TYPE_SET_HOMEWORK = 1;//布置作业
+    public static final int TYPE_SET_HOMEWORK_COMMENT = 2;//作业点评
+
+    private int showType = TYPE_SET_TEACHER_COMMENT;
+
+    private CommonDialogTipLayoutBinding mViewBinding;
+    private static CommonTipDialog dialog;
+
+    public CommonTipDialog(@NonNull Context context) {
+        super(context, R.style.DialogStyle);
+        mViewBinding = CommonDialogTipLayoutBinding.inflate(getLayoutInflater());
+        setContentView(mViewBinding.getRoot());
+        getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
+        mViewBinding.ivClose.setOnClickListener(v -> {
+            dismiss();
+        });
+        setOnDismissListener(dialog -> unbind());
+
+    }
+
+    public void unbind() {
+        if (mViewBinding != null) {
+            mViewBinding = null;
+        }
+    }
+
+    public static CommonTipDialog getInstance(Context context) {
+        dialog = new CommonTipDialog(context);
+        return dialog;
+    }
+
+    public CommonTipDialog setTitle(String titleText) {
+        mViewBinding.tvTitle.setText(titleText);
+        return this;
+    }
+
+    public CommonTipDialog setContent(String content) {
+        mViewBinding.contentText.setText(content);
+        return this;
+    }
+
+    public CommonTipDialog setCancel(String cancel, View.OnClickListener listener) {
+        if (!TextUtils.isEmpty(cancel)) {
+            mViewBinding.tvCancel.setVisibility(View.VISIBLE);
+        }
+        mViewBinding.tvCancel.setText(cancel);
+        mViewBinding.tvCancel.setOnClickListener(listener);
+        return this;
+    }
+
+    public CommonTipDialog setConfirm(String confirm, View.OnClickListener listener) {
+        if (!TextUtils.isEmpty(confirm)) {
+            mViewBinding.tvSure.setVisibility(View.VISIBLE);
+        }
+        mViewBinding.tvSure.setText(confirm);
+        mViewBinding.tvSure.setOnClickListener(listener);
+        return this;
+    }
+
+    public static void dismissDialog() {
+        if (dialog != null) {
+            dialog.dismiss();
+        }
+    }
+}

+ 6 - 0
BaseLibrary/src/main/res/drawable/cancel_btn_bg.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <corners android:radius="@dimen/dp_24"/>
+    <stroke android:color="#2DC7AA" android:width="@dimen/dp_1"/>
+</shape>

+ 0 - 0
BaseLibrary/src/main/res/drawable-v24/ic_launcher_foreground.xml → BaseLibrary/src/main/res/drawable/ic_launcher_foreground.xml


+ 8 - 0
BaseLibrary/src/main/res/drawable/shape_course_title_tag_bg.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient android:type="linear" android:useLevel="true"
+        android:startColor="#ff59e5d5"
+        android:endColor="#ff2dc7aa"
+        android:angle="180" />
+    <corners android:radius="3dp" />
+</shape>

+ 6 - 0
BaseLibrary/src/main/res/drawable/sure_btn_bg.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <corners android:radius="@dimen/dp_24"/>
+    <solid android:color="#2DC7AA"/>
+</shape>

+ 100 - 0
BaseLibrary/src/main/res/layout/common_dialog_tip_layout.xml

@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout 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">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="32dp"
+        android:layout_marginEnd="32dp"
+        android:background="@drawable/bg_white_10dp">
+
+        <ImageView
+            android:id="@+id/iv_close"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:padding="13dp"
+            android:visibility="gone"
+            android:src="@drawable/icon_close_dialog"
+            app:layout_constraintRight_toRightOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <View
+            android:id="@+id/view_title_tag"
+            android:layout_width="4dp"
+            android:layout_height="17dp"
+            android:layout_marginStart="19dp"
+            android:layout_marginTop="27dp"
+            android:background="@drawable/shape_course_title_tag_bg"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <TextView
+            android:id="@+id/tv_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="4dp"
+            android:includeFontPadding="false"
+            android:textColor="@color/color_333333"
+            android:textSize="@dimen/sp_18"
+            android:textStyle="bold"
+            app:layout_constraintBottom_toBottomOf="@+id/view_title_tag"
+            app:layout_constraintLeft_toRightOf="@+id/view_title_tag"
+            app:layout_constraintTop_toTopOf="@+id/view_title_tag"
+            tools:text="评价学员" />
+
+        <TextView
+            android:id="@+id/content_text"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="18dp"
+            android:layout_marginTop="20dp"
+            android:layout_marginEnd="18dp"
+            android:lineHeight="@dimen/dp_20"
+            android:textColor="@color/color_666666"
+            android:textSize="@dimen/sp_14"
+            app:layout_constraintTop_toBottomOf="@+id/view_title_tag"
+            tools:text="解绑后将无法" />
+
+        <TextView
+            android:id="@+id/tv_sure"
+            android:layout_width="0dp"
+            android:layout_height="44dp"
+            android:layout_marginTop="24dp"
+            android:layout_marginEnd="@dimen/dp_13"
+            android:layout_marginBottom="15dp"
+            android:background="@drawable/sure_btn_bg"
+            android:gravity="center"
+            android:includeFontPadding="false"
+            android:textColor="@color/white"
+            android:textSize="@dimen/sp_16"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintLeft_toRightOf="@+id/tv_cancel"
+            app:layout_constraintRight_toRightOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/content_text"
+            tools:text="确认" />
+
+        <TextView
+            android:id="@+id/tv_cancel"
+            android:layout_width="0dp"
+            android:layout_height="44dp"
+            android:layout_marginStart="@dimen/dp_13"
+            android:layout_marginTop="24dp"
+            android:layout_marginEnd="@dimen/dp_5"
+            android:layout_marginBottom="15dp"
+            android:background="@drawable/cancel_btn_bg"
+            android:gravity="center"
+            android:visibility="gone"
+            android:includeFontPadding="false"
+            android:textColor="@color/color_2dc7aa"
+            android:textSize="@dimen/sp_16"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintRight_toLeftOf="@+id/tv_sure"
+            app:layout_constraintTop_toBottomOf="@+id/content_text"
+            tools:text="取消" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</FrameLayout>

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

@@ -16,4 +16,6 @@
     <string name="nav_bar_msg">商城</string>
     <string name="nav_bar_user">我的</string>
     <string name="equipment_testing_hint">设备检测需要麦克风、储存权限,去设置?</string>
+    <string name="cancel">取消</string>
+    <string name="sure">确定</string>
 </resources>

+ 59 - 0
student/src/main/java/com/cooleshow/student/adapter/PianoRoomCourseListAdapter.java

@@ -0,0 +1,59 @@
+package com.cooleshow.student.adapter;
+
+import android.text.TextUtils;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.module.BaseLoadMoreModule;
+import com.chad.library.adapter.base.module.LoadMoreModule;
+import com.chad.library.adapter.base.viewholder.BaseViewHolder;
+import com.cooleshow.student.R;
+import com.cooleshow.student.bean.PianoRoomCourseListBean;
+import com.cooleshow.student.constants.CourseConstants;
+
+/**
+ * Author by pq, Date on 2022/4/25.
+ */
+public class PianoRoomCourseListAdapter extends BaseQuickAdapter<PianoRoomCourseListBean.RowsBean, BaseViewHolder> implements LoadMoreModule {
+
+    public PianoRoomCourseListAdapter(int layoutResId) {
+        super(layoutResId);
+    }
+
+    @Override
+    protected void convert(@NonNull BaseViewHolder holder, PianoRoomCourseListBean.RowsBean data) {
+        //时间
+        holder.setText(R.id.tv_time, data.startTime);
+        //title
+        holder.setText(R.id.tv_title, data.groupName);
+        //subjectName
+        holder.setText(R.id.tv_course_name, data.subjectName);
+        TextView tv_course_status = holder.getView(R.id.tv_course_status);
+
+        if (TextUtils.equals(CourseConstants.COURSE_STATUS_NOT_START, data.status)) {
+            //未开始
+            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.status)) {
+            //进行中
+            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.status)) {
+            //已结束
+            tv_course_status.setText("已结束");
+            tv_course_status.setTextColor(getContext().getResources().getColor(com.cooleshow.base.R.color.color_999999));
+        }
+    }
+
+    @NonNull
+    @Override
+    public BaseLoadMoreModule addLoadMoreModule(@NonNull BaseQuickAdapter<?, ?> baseQuickAdapter) {
+        return new BaseLoadMoreModule(baseQuickAdapter);
+    }
+}

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

@@ -20,6 +20,7 @@ import com.cooleshow.student.bean.LiveCourseListBean;
 import com.cooleshow.student.bean.LiveRoomInfoBean;
 import com.cooleshow.student.bean.PayTestBean;
 import com.cooleshow.student.bean.PianoRoomCourseHomeworkBean;
+import com.cooleshow.student.bean.PianoRoomCourseListBean;
 import com.cooleshow.student.bean.PracticeCourseListBean;
 import com.cooleshow.student.bean.QuerySubjectBean;
 import com.cooleshow.student.bean.SelectMyGroupBean;
@@ -442,4 +443,13 @@ public interface APIService {
     @GET
     @Headers("User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:0.9.4)")
     Observable<ResponseBody> downloadFileWithFixedUrl(@Url String url);
+
+    /**
+     * 查询琴房课列表
+     *
+     * @param
+     * @return
+     */
+    @POST(STUDENT_GROUP + "courseSchedule/selectCourseList")
+    Observable<BaseResponse<PianoRoomCourseListBean>> getPianoRoomCourseList(@Body RequestBody body);
 }

+ 98 - 0
student/src/main/java/com/cooleshow/student/bean/PianoRoomCourseListBean.java

@@ -0,0 +1,98 @@
+package com.cooleshow.student.bean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Author by pq, Date on 2022/4/25.
+ */
+public class PianoRoomCourseListBean {
+
+    /**
+     * footer : [{"avatar":"","classDate":"","courseGoupId":0,"courseId":0,"endTime":"","id":0,"signInTime":"","startTime":"","status":"","subjectId":0,"subjectName":"","userId":0,"userName":""}]
+     * limit : 0
+     * nextPage : 0
+     * offset : 0
+     * pageNo : 0
+     * prePage : 0
+     * rows : [{"avatar":"","classDate":"","courseGoupId":0,"courseId":0,"endTime":"","id":0,"signInTime":"","startTime":"","status":"","subjectId":0,"subjectName":"","userId":0,"userName":""}]
+     * statInfo : {}
+     * total : 0
+     * totalPage : 0
+     */
+
+    public int limit;
+    public int nextPage;
+    public int offset;
+    public int pageNo;
+    public int prePage;
+    public StatInfoBean statInfo;
+    public int total;
+    public int totalPage;
+    public List<FooterBean> footer;
+    public ArrayList<RowsBean> rows;
+
+    public static class StatInfoBean {
+    }
+
+    public static class FooterBean {
+        /**
+         * avatar :
+         * classDate :
+         * courseGoupId : 0
+         * courseId : 0
+         * endTime :
+         * id : 0
+         * signInTime :
+         * startTime :
+         * status :
+         * subjectId : 0
+         * subjectName :
+         * userId : 0
+         * userName :
+         */
+
+        public String avatar;
+        public String classDate;
+        public int courseGoupId;
+        public int courseId;
+        public String endTime;
+        public int id;
+        public String signInTime;
+        public String startTime;
+        public String status;
+        public int subjectId;
+        public String subjectName;
+        public int userId;
+        public String userName;
+    }
+
+    public static class RowsBean {
+
+        /**
+         * consumTime : 0
+         * courseId : 0
+         * endTime :
+         * groupName :
+         * imGroupId :
+         * singleCourseTime : 0
+         * startTime :
+         * status :
+         * studentCount : 0
+         * subjectId : 0
+         * subjectName :
+         */
+
+        public int consumTime;
+        public String courseId;
+        public String endTime;
+        public String groupName;
+        public String imGroupId;
+        public int singleCourseTime;
+        public String startTime;
+        public String status;
+        public int studentCount;
+        public int subjectId;
+        public String subjectName;
+    }
+}

+ 19 - 0
student/src/main/java/com/cooleshow/student/contract/PianoRoomCourseContract.java

@@ -0,0 +1,19 @@
+package com.cooleshow.student.contract;
+
+import com.cooleshow.base.presenter.view.BaseView;
+import com.cooleshow.student.bean.PianoRoomCourseListBean;
+
+/**
+ * Author by pq, Date on 2022/4/20.
+ */
+public interface PianoRoomCourseContract {
+
+    interface PianoRoomCourseView extends BaseView {
+        void onGetPianoRoomCourseListSuccess(int page, PianoRoomCourseListBean bean);
+        void onGetCourseError(int page);
+    }
+
+    interface Presenter {
+        void queryPianoRoomCourseList(boolean isShowLoading,String month, String status, int subjectId,int page);
+    }
+}

+ 55 - 0
student/src/main/java/com/cooleshow/student/presenter/course/PianoRoomCoursePresenter.java

@@ -0,0 +1,55 @@
+package com.cooleshow.student.presenter.course;
+
+import com.cooleshow.base.constanst.Constants;
+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.PianoRoomCourseListBean;
+import com.cooleshow.student.contract.PianoRoomCourseContract;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * 琴房课presenter
+ *
+ * Author by pq, Date on 2022/4/20.
+ */
+public class PianoRoomCoursePresenter extends BasePresenter<PianoRoomCourseContract.PianoRoomCourseView> implements PianoRoomCourseContract.Presenter {
+
+    @Override
+    public void queryPianoRoomCourseList(boolean isShowLoading, String month, String status, int subjectId, int page) {
+        if (isShowLoading && getView() != null) {
+            getView().showLoading();
+        }
+        JSONObject jsonObject = new JSONObject();
+        try {
+            jsonObject.putOpt("month", month);
+            jsonObject.putOpt("status", status);
+            if (subjectId != 0) {
+                jsonObject.putOpt("subjectId", subjectId);
+            }
+            jsonObject.putOpt("page", page);
+            jsonObject.putOpt("rows", Constants.DEFAULT_DATA_SIZE);
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+        addSubscribe(create(APIService.class).getPianoRoomCourseList(RequestBodyUtil.convertToRequestBodyJson(jsonObject.toString())), new BaseObserver<PianoRoomCourseListBean>(getView()) {
+            @Override
+            protected void onSuccess(PianoRoomCourseListBean data) {
+                if (getView() != null) {
+                    getView().onGetPianoRoomCourseListSuccess(page, data);
+                }
+            }
+
+            @Override
+            public void onError(Throwable e) {
+                super.onError(e);
+                if (getView() != null) {
+                    getView().onGetCourseError(page);
+                }
+            }
+        });
+    }
+}

+ 7 - 1
student/src/main/java/com/cooleshow/student/ui/course/MineCourseActivity.java

@@ -37,11 +37,12 @@ public class MineCourseActivity extends BaseMVPActivity<ActivityMineCourseBindin
 
     private TabLayout tabLayout;
     private ViewPager2 viewPager;
-    private List<String> titles = new ArrayList<String>(Arrays.asList("陪练课", "直播课", "视频课"));
+    private List<String> titles = new ArrayList<String>(Arrays.asList("陪练课", "直播课", "视频课", "琴房课"));
     private List<BaseMVPFragment> fragments = new ArrayList<>();
     private MinePracticeCourseFragment mMinePracticeCourseFragment;
     private LiveCourseFragment mLiveCourseFragment;
     private VideoCourseFragment mVideoCourseFragment;
+    private PianoRoomCourseFragment mPianoRoomCourseFragment;
 
     @Override
     protected void initView() {
@@ -78,9 +79,11 @@ public class MineCourseActivity extends BaseMVPActivity<ActivityMineCourseBindin
         mMinePracticeCourseFragment = MinePracticeCourseFragment.newInstance();
         mLiveCourseFragment = LiveCourseFragment.newInstance();
         mVideoCourseFragment = VideoCourseFragment.newInstance();
+        mPianoRoomCourseFragment = new PianoRoomCourseFragment();
         fragments.add(mMinePracticeCourseFragment);
         fragments.add(mLiveCourseFragment);
         fragments.add(mVideoCourseFragment);
+        fragments.add(mPianoRoomCourseFragment);
         MineCoursePagerAdapter mineCoursePageAdapter = new MineCoursePagerAdapter(this);
         mineCoursePageAdapter.setFragments(fragments);
         viewPager.setAdapter(mineCoursePageAdapter);
@@ -129,5 +132,8 @@ public class MineCourseActivity extends BaseMVPActivity<ActivityMineCourseBindin
         if (mVideoCourseFragment != null) {
             mVideoCourseFragment.querySubjectItemSuccess(data);
         }
+        if (mPianoRoomCourseFragment != null) {
+            mPianoRoomCourseFragment.querySubjectItemSuccess(data);
+        }
     }
 }

+ 297 - 0
student/src/main/java/com/cooleshow/student/ui/course/PianoRoomCourseFragment.java

@@ -0,0 +1,297 @@
+package com.cooleshow.student.ui.course;
+
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.TextView;
+
+import com.alibaba.android.arouter.launcher.ARouter;
+import com.bigkoo.pickerview.builder.TimePickerBuilder;
+import com.bigkoo.pickerview.listener.CustomListener;
+import com.bigkoo.pickerview.view.TimePickerView;
+import com.cooleshow.base.constanst.Constants;
+import com.cooleshow.base.router.RouterPath;
+import com.cooleshow.base.ui.fragment.BaseMVPFragment;
+import com.cooleshow.base.utils.LogUtils;
+import com.cooleshow.base.utils.TimeUtils;
+import com.cooleshow.base.widgets.EmptyViewLayout;
+import com.cooleshow.base.widgets.poplist.PopMenuBean;
+import com.cooleshow.base.widgets.poplist.PopupListWindow;
+import com.cooleshow.student.R;
+import com.cooleshow.student.adapter.PianoRoomCourseListAdapter;
+import com.cooleshow.student.bean.CourseFilterStatusBean;
+import com.cooleshow.student.bean.PianoRoomCourseListBean;
+import com.cooleshow.student.bean.QuerySubjectBean;
+import com.cooleshow.student.constants.CourseConstants;
+import com.cooleshow.student.contract.PianoRoomCourseContract;
+import com.cooleshow.student.databinding.FragmentPianoRoomCourseLayoutBinding;
+import com.cooleshow.student.presenter.course.PianoRoomCoursePresenter;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+import androidx.recyclerview.widget.LinearLayoutManager;
+
+/**
+ * Author by pq, Date on 2022/4/25.
+ * 我的课程->琴房课
+ */
+public class PianoRoomCourseFragment extends BaseMVPFragment<FragmentPianoRoomCourseLayoutBinding, PianoRoomCoursePresenter> implements PianoRoomCourseContract.PianoRoomCourseView, View.OnClickListener {
+    private String currentCourseFilterStatus = CourseConstants.COURSE_FILTER_ALL;
+    private String currentFilterDate;
+    private Date currentSelectDate;
+    private int currentSubjectId;
+    private int currentPage;
+    private boolean hasNext = true;
+    private PianoRoomCourseListAdapter mAdapter;
+    private EmptyViewLayout mEmptyView;
+    private TimePickerView pvTime;
+    private ArrayList<CourseFilterStatusBean> mCourseFilterStatusBeans;
+    private List<QuerySubjectBean> subjectBeanList = new ArrayList<>();
+    private boolean isFirstLoad = true;
+
+    @Override
+    protected FragmentPianoRoomCourseLayoutBinding getLayoutView() {
+        return FragmentPianoRoomCourseLayoutBinding.inflate(getLayoutInflater());
+    }
+
+    @Override
+    protected PianoRoomCoursePresenter createPresenter() {
+        return new PianoRoomCoursePresenter();
+    }
+
+    @Override
+    protected void initView(View rootView) {
+        mViewBinding.tvTime.setOnClickListener(this);
+        mViewBinding.tvCourseStatus.setOnClickListener(this);
+        mViewBinding.tvAgency.setOnClickListener(this);
+    }
+
+    @Override
+    public void refreshData() {
+        super.refreshData();
+        reBuildFilter(currentSelectDate, currentCourseFilterStatus);
+        isFirstLoad = false;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        if(isFirstLoad){
+            isFirstLoad = false;
+            reBuildFilter(null, CourseConstants.COURSE_FILTER_ALL);
+        }
+    }
+
+    private void buildDefaultCourseStatusFilterList() {
+        mCourseFilterStatusBeans = new ArrayList<>();
+        mCourseFilterStatusBeans.add(new CourseFilterStatusBean(CourseConstants.COURSE_FILTER_ALL, "全部"));
+        mCourseFilterStatusBeans.add(new CourseFilterStatusBean(CourseConstants.COURSE_FILTER_HAS_NOT_STARTED, "未开始"));
+        mCourseFilterStatusBeans.add(new CourseFilterStatusBean(CourseConstants.COURSE_FILTER_IN_PROGRESS, "进行中"));
+        mCourseFilterStatusBeans.add(new CourseFilterStatusBean(CourseConstants.COURSE_FILTER_COMPLETED, "已结束"));
+    }
+
+    private void reBuildFilter(Date date, String status) {
+        currentSelectDate = date != null ? date : TimeUtils.getNowDate();
+        String targetDateTimeStr = TimeUtils.date2String(currentSelectDate, TimeUtils.getSafeDateFormat("yyyy-MM"));
+        if (TextUtils.equals(targetDateTimeStr, currentFilterDate) && TextUtils.equals(currentCourseFilterStatus, status)) {
+            //防止重复条件触发
+            return;
+        }
+        currentFilterDate = targetDateTimeStr;
+        currentCourseFilterStatus = !TextUtils.isEmpty(status) ? status : CourseConstants.COURSE_FILTER_ALL;
+        currentPage = 1;
+        mViewBinding.tvTime.setText(currentFilterDate);
+        queryCourse(true);
+    }
+
+
+    @Override
+    protected void initData() {
+        mViewBinding.refreshLayout.setOnRefreshListener(refreshLayout -> {
+            currentPage = 1;
+            queryCourse(true);
+        });
+
+        mAdapter = new PianoRoomCourseListAdapter(R.layout.item_piano_room_course_list_layout);
+        mAdapter.getLoadMoreModule().setOnLoadMoreListener(() -> {
+            //上拉加载
+            if (hasNext) {
+                currentPage++;
+                queryCourse(false);
+            } else {
+                mAdapter.getLoadMoreModule().loadMoreEnd();
+            }
+        });
+        mAdapter.setOnItemClickListener((adapter, view, position) -> {
+            if (position < mAdapter.getData().size()) {
+                PianoRoomCourseListBean.RowsBean rowsBean = mAdapter.getData().get(position);
+                if (rowsBean != null) {
+                    ARouter.getInstance().build(RouterPath.CourseCenter.PIANO_ROOM_COURSE_DETAIL)
+                            .withString("course_id", rowsBean.courseId)
+                            .navigation();
+                }
+            }
+        });
+        mViewBinding.recyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
+        mViewBinding.recyclerView.setAdapter(mAdapter);
+        buildDefaultCourseStatusFilterList();
+    }
+
+    private void queryCourse(boolean isShowLoading) {
+        //根据默认筛选条件查询
+        LogUtils.i("pq", "currentFilterDate:" + currentFilterDate);
+        LogUtils.i("pq", "currentCourseFilterStatus:" + currentCourseFilterStatus);
+        LogUtils.i("pq", "currentSubjectId:" + currentSubjectId);
+        LogUtils.i("pq", "currentPage:" + currentPage);
+        presenter.queryPianoRoomCourseList(isShowLoading, currentFilterDate, currentCourseFilterStatus, currentSubjectId, currentPage);
+    }
+
+    @Override
+    public void onGetPianoRoomCourseListSuccess(int page, PianoRoomCourseListBean bean) {
+        if (isDetached()) {
+            return;
+        }
+        if (bean != null) {
+            if (page == 1) {
+                //第一页
+                mViewBinding.refreshLayout.finishRefresh();
+                if (mAdapter != null) {
+                    mAdapter.getData().clear();
+                    mAdapter.notifyDataSetChanged();
+                    if (bean.rows != null && bean.rows.size() > 0) {
+                        checkHasNext(bean.rows.size());
+                        mAdapter.setNewInstance(bean.rows);
+                    } else {
+                        showEmptyView();
+                    }
+                }
+            } else {
+                //加载更多
+                if (mAdapter != null) {
+                    if (bean.rows != null && bean.rows.size() > 0) {
+                        mAdapter.getLoadMoreModule().loadMoreComplete();
+                        checkHasNext(bean.rows.size());
+                        mAdapter.addData(bean.rows);
+                    } else {
+                        mAdapter.getLoadMoreModule().loadMoreEnd();
+                    }
+                }
+            }
+        }
+    }
+
+    private void checkHasNext(int dataSize) {
+        hasNext = dataSize >= Constants.DEFAULT_DATA_SIZE;
+    }
+
+    @Override
+    public void onGetCourseError(int page) {
+        if (isDetached()) {
+            return;
+        }
+        if (page == 1) {
+            mViewBinding.refreshLayout.finishRefresh();
+        } else {
+            if (mAdapter != null) {
+                currentPage--;
+                mAdapter.getLoadMoreModule().loadMoreFail();
+            }
+        }
+    }
+
+
+    private void showEmptyView() {
+        if (mEmptyView == null) {
+            mEmptyView = new EmptyViewLayout(getContext());
+        }
+        mEmptyView.setContent(com.cooleshow.base.R.drawable.icon_empty_course, "暂无课程~");
+        mAdapter.setEmptyView(mEmptyView);
+    }
+
+    private void showTimeSelectPicker() {
+        if (pvTime == null) {
+            pvTime = new TimePickerBuilder(requireContext(), (date, v) -> {//选中事件回调
+                reBuildFilter(date, currentCourseFilterStatus);
+            }).setLayoutRes(com.cooleshow.base.R.layout.pickerview_default_layout, 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(v1 -> {
+                    pvTime.returnData();
+                    pvTime.dismiss();
+                });
+                ivCancel.setOnClickListener(v12 -> pvTime.dismiss());
+
+            })
+                    .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();
+        }
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(currentSelectDate);
+        pvTime.setDate(calendar);
+        if (!pvTime.isShowing()) {
+            pvTime.show();
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.tv_time) {
+            //时间筛选
+            showTimeSelectPicker();
+            return;
+        }
+
+        if (v.getId() == R.id.tv_course_status) {
+            //课程状态筛选
+            List<PopMenuBean> popList = new ArrayList<>();
+            for (CourseFilterStatusBean bean : mCourseFilterStatusBeans) {
+                PopMenuBean popMenuBean = new PopMenuBean();
+                popMenuBean.setActionName(bean.showText);
+                popList.add(popMenuBean);
+            }
+            initCoursePop(mViewBinding.tvCourseStatus, popList, position -> {
+                CourseFilterStatusBean bean = mCourseFilterStatusBeans.get(position);
+                mViewBinding.tvCourseStatus.setText(bean.showText);
+                reBuildFilter(currentSelectDate, bean.value);
+            });
+            return;
+        }
+        if (v.getId() == R.id.tv_agency) {
+            //选择声部
+            if (subjectBeanList.size() == 0) {
+                subjectBeanList.add(new QuerySubjectBean("全部声部", 0));
+            }
+            List<PopMenuBean> popList = new ArrayList<>();
+            for (QuerySubjectBean bean : subjectBeanList) {
+                PopMenuBean popMenuBean = new PopMenuBean();
+                popMenuBean.setActionName(bean.name);
+                popList.add(popMenuBean);
+            }
+            initCoursePop(mViewBinding.tvAgency, popList, position -> {
+                QuerySubjectBean bean = subjectBeanList.get(position);
+                currentSubjectId = bean.id;
+                mViewBinding.tvAgency.setText(bean.name);
+                queryCourse(true);
+            });
+            return;
+        }
+    }
+
+    private void initCoursePop(View targetView, List<PopMenuBean> popList, PopupListWindow.PopupListListener listener) {
+        PopupListWindow popWindow = new PopupListWindow(getContext());
+        popWindow.showListPop(targetView, popList, position -> listener.onPopupListClick(position));
+    }
+
+    public void querySubjectItemSuccess(List<QuerySubjectBean> data) {
+        subjectBeanList.clear();
+        subjectBeanList.add(new QuerySubjectBean("全部声部", 0));
+        subjectBeanList.addAll(data);
+    }
+}

+ 2 - 1
student/src/main/res/layout/fragment_mine_layout.xml

@@ -55,6 +55,7 @@
             android:layout_marginTop="10dp"
             android:textColor="@color/color_333333"
             android:textSize="@dimen/sp_18"
+            android:textStyle="bold"
             app:layout_constraintLeft_toRightOf="@+id/iv_avatar"
             app:layout_constraintTop_toTopOf="@+id/iv_avatar"
             tools:text="张天乐" />
@@ -63,7 +64,7 @@
             android:id="@+id/rv_mark"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginLeft="9dp"
+            android:layout_marginLeft="@dimen/dp_11"
             app:layout_constraintLeft_toRightOf="@+id/tv_nickname"
             app:layout_constraintBottom_toBottomOf="@+id/tv_nickname"
             app:layout_constraintTop_toTopOf="@+id/tv_nickname" />

+ 86 - 0
student/src/main/res/layout/fragment_piano_room_course_layout.xml

@@ -0,0 +1,86 @@
+<?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">
+
+    <TextView
+        android:id="@+id/tv_time"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="25dp"
+        android:drawableRight="@drawable/icon_arrow_down"
+        android:drawablePadding="6dp"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:paddingTop="18dp"
+        android:paddingBottom="12dp"
+        android:textColor="@color/color_666666"
+        android:textSize="@dimen/sp_13"
+        app:layout_constraintHorizontal_chainStyle="spread_inside"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toLeftOf="@+id/tv_course_status"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="2021年9月" />
+
+    <TextView
+        android:id="@+id/tv_course_status"
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        android:drawableRight="@drawable/icon_arrow_down"
+        android:drawablePadding="6dp"
+        android:paddingTop="18dp"
+        android:paddingBottom="12dp"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:textColor="@color/color_666666"
+        android:textSize="@dimen/sp_13"
+        android:text="课程状态"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_time"
+        app:layout_constraintLeft_toRightOf="@+id/tv_time"
+        app:layout_constraintRight_toLeftOf="@+id/tv_agency"
+        app:layout_constraintTop_toTopOf="@+id/tv_time"
+        tools:text="课程状态" />
+
+    <TextView
+        android:id="@+id/tv_agency"
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        android:layout_marginEnd="23dp"
+        android:drawableRight="@drawable/icon_arrow_down"
+        android:drawablePadding="6dp"
+        android:gravity="center"
+        android:paddingTop="18dp"
+        android:paddingBottom="12dp"
+        android:includeFontPadding="false"
+        android:textColor="@color/color_666666"
+        android:textSize="@dimen/sp_13"
+        android:text="全部声部"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_time"
+        app:layout_constraintLeft_toRightOf="@+id/tv_course_status"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tv_time"
+        tools:text="课程状态" />
+
+    <com.scwang.smart.refresh.layout.SmartRefreshLayout
+        android:id="@+id/refreshLayout"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/tv_time">
+
+        <com.scwang.smart.refresh.header.ClassicsHeader
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/recyclerView"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:overScrollMode="never"
+            android:scrollbars="none" />
+    </com.scwang.smart.refresh.layout.SmartRefreshLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 136 - 0
student/src/main/res/layout/item_piano_room_course_list_layout.xml

@@ -0,0 +1,136 @@
+<?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_marginTop="12dp"
+    android:layout_marginEnd="14dp"
+    android:background="@drawable/bg_white_10dp"
+    android:paddingStart="11dp"
+    android:paddingEnd="11dp"
+    android:paddingBottom="20dp">
+
+    <ImageView
+        android:id="@+id/iv_clock_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="11dp"
+        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="10dp"
+        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:src="@drawable/icon_piano_room_course"
+        android:id="@+id/iv_avatar"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="17dp"
+        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="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="10dp"
+        android:includeFontPadding="false"
+        android:textColor="@color/color_1a1a1a"
+        android:textSize="@dimen/sp_16"
+        android:textStyle="bold"
+        app:layout_constraintBottom_toTopOf="@+id/tv_course_name"
+        app:layout_constraintLeft_toRightOf="@+id/iv_avatar"
+        app:layout_constraintTop_toTopOf="@+id/iv_avatar"
+        app:layout_constraintVertical_chainStyle="packed"
+        tools:text="张豆豆" />
+
+    <ImageView
+        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:id="@+id/tv_course_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        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/iv_avatar"
+        app:layout_constraintLeft_toLeftOf="@+id/tv_title"
+        app:layout_constraintTop_toBottomOf="@+id/tv_title"
+        tools:text="单簧管" />
+
+    <View
+        android:id="@+id/view_line2"
+        android:layout_width="1dp"
+        android:layout_height="11dp"
+        android:layout_marginStart="8dp"
+        android:background="@color/color_d3d3d3"
+        android:visibility="visible"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_course_name"
+        app:layout_constraintLeft_toRightOf="@+id/tv_course_name"
+        app:layout_constraintTop_toTopOf="@+id/tv_course_name" />
+
+    <TextView
+        android:id="@+id/tv_buy_num"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="8dp"
+        android:textColor="@color/color_6a6a6a"
+        android:textSize="@dimen/sp_11"
+        android:visibility="visible"
+        android:text="0人已购买"
+        app:layout_constraintBottom_toBottomOf="@+id/view_line2"
+        app:layout_constraintLeft_toRightOf="@+id/view_line2"
+        app:layout_constraintTop_toTopOf="@+id/view_line2"
+        tools:text="6人已购买" />
+
+    <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="未开始" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 31 - 13
teacher/src/main/java/com/cooleshow/teacher/ui/mine/MyBankCardActivity.java

@@ -1,12 +1,17 @@
 package com.cooleshow.teacher.ui.mine;
 
 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.router.RouterPath;
 import com.cooleshow.base.ui.activity.BaseMVPActivity;
+import com.cooleshow.base.utils.PermissionUtils;
 import com.cooleshow.base.utils.ToastUtils;
+import com.cooleshow.base.widgets.CommonDialog;
+import com.cooleshow.base.widgets.CommonTipDialog;
+import com.cooleshow.base.widgets.DialogUtil;
 import com.cooleshow.teacher.R;
 import com.cooleshow.teacher.bean.ResponseBankCardBean;
 import com.cooleshow.teacher.bean.ResponseBindCardBean;
@@ -34,19 +39,29 @@ public class MyBankCardActivity extends BaseMVPActivity<ActivityMyBankCardBindin
                         .navigation();
                 break;
             case R.id.tv_unbind:
-                if (null==rowsBean){
+                if (null == rowsBean) {
                     ToastUtils.showShort("还未绑定银行卡");
                     break;
                 }
-                JSONObject jsonObject = new JSONObject();
-                try {
-                    jsonObject.putOpt("id", rowsBean.id);
-                    jsonObject.putOpt("idCardNo", rowsBean.bankCard);
-                    jsonObject.putOpt("name", rowsBean.name);
-                } catch (JSONException e) {
-                    e.printStackTrace();
-                }
-                presenter.unBindBankCard(jsonObject.toString());
+                CommonTipDialog.getInstance(this)
+                        .setTitle("解绑银行卡")
+                        .setContent("解绑后将无法将收入提现,请确认是否继续解绑")
+                        .setCancel(getString(R.string.cancel), v -> {
+                            CommonTipDialog.dismissDialog();
+                        })
+                        .setConfirm(getString(R.string.sure), v -> {
+                            CommonTipDialog.dismissDialog();
+                            JSONObject jsonObject = new JSONObject();
+                            try {
+                                jsonObject.putOpt("id", rowsBean.id);
+                                jsonObject.putOpt("idCardNo", rowsBean.bankCard);
+                                jsonObject.putOpt("name", rowsBean.name);
+                            } catch (JSONException e) {
+                                e.printStackTrace();
+                            }
+                            presenter.unBindBankCard(jsonObject.toString());
+                        })
+                        .show();
                 break;
             case R.id.tv_bind_card:
                 ARouter.getInstance().build(RouterPath.MineCenter.MINE_BIND_BANKCARD)
@@ -83,16 +98,19 @@ public class MyBankCardActivity extends BaseMVPActivity<ActivityMyBankCardBindin
     }
 
     private ResponseBankCardBean.RowsBean rowsBean;
+
     @Override
     public void querySuccess(int page, ResponseBankCardBean data) {
         if (null != data && null != data.rows && data.rows.size() > 0) {
-            rowsBean=data.rows.get(0);
+            rowsBean = data.rows.get(0);
             viewBinding.includeEmpty.getRoot().setVisibility(View.GONE);
             viewBinding.clContent.setVisibility(View.VISIBLE);
             viewBinding.tvBankName.setText(rowsBean.bankName);
-            viewBinding.tvCardNum.setText(rowsBean.bankCard);
+            String bankCard = rowsBean.bankCard;
+            String temCard = bankCard.substring(0, 4) + "**** ****" + bankCard.substring(bankCard.length() - 4);
+            viewBinding.tvCardNum.setText(temCard);
             viewBinding.toolbarInclude.tvRightText.setVisibility(View.VISIBLE);
-        }else{
+        } else {
             viewBinding.includeEmpty.getRoot().setVisibility(View.VISIBLE);
             viewBinding.clContent.setVisibility(View.GONE);
             viewBinding.toolbarInclude.tvRightText.setVisibility(View.GONE);