Skip to content

Commit

Permalink
feat: 完善联调课程表接口
Browse files Browse the repository at this point in the history
  • Loading branch information
liewstar committed Dec 7, 2024
1 parent db9ec43 commit fa1b04c
Show file tree
Hide file tree
Showing 9 changed files with 347 additions and 44 deletions.
53 changes: 53 additions & 0 deletions app/src/main/java/com/example/CQUPT/adapter/CourseAdapter.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
package com.example.CQUPT.adapter;

import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;

import com.example.CQUPT.R;
import com.example.CQUPT.model.Course;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;

import java.util.List;

Expand Down Expand Up @@ -51,6 +57,7 @@ public int getItemCount() {
}

static class CourseViewHolder extends RecyclerView.ViewHolder {
private final MaterialCardView cardView;
private final TextView courseTimeText;
private final TextView courseNameText;
private final TextView locationText;
Expand All @@ -60,6 +67,7 @@ static class CourseViewHolder extends RecyclerView.ViewHolder {

public CourseViewHolder(@NonNull View itemView) {
super(itemView);
cardView = (MaterialCardView) itemView;
courseTimeText = itemView.findViewById(R.id.courseTimeText);
courseNameText = itemView.findViewById(R.id.courseNameText);
locationText = itemView.findViewById(R.id.locationText);
Expand All @@ -69,12 +77,57 @@ public CourseViewHolder(@NonNull View itemView) {
}

public void bind(Course course, int currentWeek) {
Context context = itemView.getContext();

// 设置基本信息
courseTimeText.setText(course.getTimeRange());
courseNameText.setText(course.getName());
locationText.setText(course.getLocation());
teacherText.setText(course.getTeacher());
weekRangeText.setText(course.getWeekRange());
currentWeekText.setText(String.format("第%d周", currentWeek));

// 判断课程是否在当前周
boolean isInCurrentWeek = currentWeek >= course.getStartWeek() && currentWeek <= course.getEndWeek();

// 根据是否在当前周设置卡片样式
if (isInCurrentWeek) {
cardView.setCardBackgroundColor(ContextCompat.getColor(context, R.color.purple_50));
cardView.setStrokeColor(ContextCompat.getColor(context, R.color.purple_200));
cardView.setStrokeWidth(2);
courseNameText.setTextColor(ContextCompat.getColor(context, R.color.purple_700));
} else {
cardView.setCardBackgroundColor(Color.WHITE);
cardView.setStrokeColor(Color.TRANSPARENT);
cardView.setStrokeWidth(0);
courseNameText.setTextColor(ContextCompat.getColor(context, android.R.color.black));
}

// 设置点击事件显示详情
cardView.setOnClickListener(v -> showCourseDetail(context, course, currentWeek));
}

private void showCourseDetail(Context context, Course course, int currentWeek) {
View dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_course_detail, null);

// 设置详情对话框的内容
TextView courseNameTitle = dialogView.findViewById(R.id.courseNameTitle);
TextView timeText = dialogView.findViewById(R.id.timeText);
TextView weekRangeDetailText = dialogView.findViewById(R.id.weekRangeDetailText);
TextView locationDetailText = dialogView.findViewById(R.id.locationDetailText);
TextView teacherDetailText = dialogView.findViewById(R.id.teacherDetailText);

courseNameTitle.setText(course.getName());
timeText.setText(course.getTimeRange());
weekRangeDetailText.setText(String.format("%s(当前第%d周)", course.getWeekRange(), currentWeek));
locationDetailText.setText(course.getLocation());
teacherDetailText.setText(course.getTeacher());

// 创建并显示对话框
new MaterialAlertDialogBuilder(context)
.setView(dialogView)
.setPositiveButton("关闭", null)
.show();
}
}
}
58 changes: 57 additions & 1 deletion app/src/main/java/com/example/CQUPT/ui/home/HomeFragment.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.example.CQUPT.ui.home;

import android.app.DatePickerDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
Expand All @@ -15,7 +16,9 @@

import com.example.CQUPT.adapter.CourseAdapter;
import com.example.CQUPT.databinding.FragmentClassesBinding;
import com.example.CQUPT.ui.settings.SettingsFragment;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.snackbar.Snackbar;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
Expand All @@ -31,7 +34,7 @@ public class HomeFragment extends Fragment {
private Calendar currentDate;
private SimpleDateFormat dateFormat;
private SimpleDateFormat weekDayFormat;
private Calendar semesterStartDate; // 添加学期开始日期
private Calendar semesterStartDate;

public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
Expand All @@ -42,6 +45,7 @@ public View onCreateView(@NonNull LayoutInflater inflater,
initializeFormats();
setupRecyclerView();
setupDateNavigation();
setupRetryButton();
observeViewModel();
updateDateDisplay();

Expand Down Expand Up @@ -81,6 +85,12 @@ private void setupDateNavigation() {
dateButton.setOnClickListener(v -> showDatePicker());
}

private void setupRetryButton() {
binding.retryButton.setOnClickListener(v -> {
loadCoursesForDate(currentDate.getTime());
});
}

private void navigateDay(int offset) {
currentDate.add(Calendar.DAY_OF_MONTH, offset);
updateDateDisplay();
Expand Down Expand Up @@ -119,9 +129,55 @@ private void loadCoursesForDate(Date date) {
}

private void observeViewModel() {
// 观察课程数据
homeViewModel.getCourses().observe(getViewLifecycleOwner(), courses -> {
courseAdapter.setCourses(courses);
updateViewVisibility(courses.isEmpty());
});

// 观察加载状态
homeViewModel.getIsLoading().observe(getViewLifecycleOwner(), isLoading -> {
binding.loadingProgress.setVisibility(isLoading ? View.VISIBLE : View.GONE);
binding.recyclerCourses.setVisibility(isLoading ? View.GONE : View.VISIBLE);
binding.errorCard.setVisibility(View.GONE);
});

// 观察错误信息
homeViewModel.getErrorMessage().observe(getViewLifecycleOwner(), errorMessage -> {
if (errorMessage != null) {
if (errorMessage.equals("请先在设置中配置学号")) {
showStudentIdError();
} else {
showError(errorMessage);
}
} else {
binding.errorCard.setVisibility(View.GONE);
}
});
}

private void updateViewVisibility(boolean isEmpty) {
binding.emptyView.setVisibility(isEmpty ? View.VISIBLE : View.GONE);
binding.recyclerCourses.setVisibility(isEmpty ? View.GONE : View.VISIBLE);
}

private void showError(String message) {
binding.errorCard.setVisibility(View.VISIBLE);
binding.errorText.setText(message);
binding.recyclerCourses.setVisibility(View.GONE);
binding.emptyView.setVisibility(View.GONE);
}

private void showStudentIdError() {
binding.errorCard.setVisibility(View.VISIBLE);
binding.errorText.setText("请先设置学号才能查看课表");
binding.retryButton.setText("去设置");
binding.retryButton.setOnClickListener(v -> {
// 跳转到设置页面
startActivity(new Intent(requireContext(), SettingsFragment.class));
});
binding.recyclerCourses.setVisibility(View.GONE);
binding.emptyView.setVisibility(View.GONE);
}

@Override
Expand Down
148 changes: 107 additions & 41 deletions app/src/main/java/com/example/CQUPT/ui/home/HomeViewModel.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,50 @@
package com.example.CQUPT.ui.home;

import android.app.Application;
import android.content.SharedPreferences;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import androidx.preference.PreferenceManager;

import com.example.CQUPT.api.RetrofitClient;
import com.example.CQUPT.api.TimetableResponse;
import com.example.CQUPT.api.CourseSchedule;
import com.example.CQUPT.model.Course;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

public class HomeViewModel extends ViewModel {
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class HomeViewModel extends AndroidViewModel {
private static final String PREF_STUDENT_ID = "student_id";
private final MutableLiveData<List<Course>> mCourses;
private final MutableLiveData<String> mCurrentDate;
private final MutableLiveData<Boolean> isLoading;
private final MutableLiveData<String> errorMessage;
private final SimpleDateFormat apiDateFormat;
private final SimpleDateFormat apiTimeFormat;
private final SharedPreferences sharedPreferences;

public HomeViewModel() {
public HomeViewModel(Application application) {
super(application);
mCourses = new MutableLiveData<>();
mCurrentDate = new MutableLiveData<>();
loadCoursesForDate(new Date()); // 加载当天课程
// 设置当前日期
mCurrentDate.setValue("2024年1月1日 星期一");
isLoading = new MutableLiveData<>(false);
errorMessage = new MutableLiveData<>();
apiDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
apiTimeFormat = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(application);

loadCoursesForDate(new Date());
}

public LiveData<List<Course>> getCourses() {
Expand All @@ -32,47 +55,90 @@ public LiveData<String> getCurrentDate() {
return mCurrentDate;
}

public LiveData<Boolean> getIsLoading() {
return isLoading;
}

public LiveData<String> getErrorMessage() {
return errorMessage;
}

public void setCurrentDate(String date) {
mCurrentDate.setValue(date);
}

public void loadCoursesForDate(Date date) {
// TODO: 在实际应用中,这里应该从数据库或网络加载指定日期的课程数据
// 现在使用模拟数据进行演示
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);

String studentId = sharedPreferences.getString(PREF_STUDENT_ID, null);
if (studentId == null || studentId.equals("未设置")) {
errorMessage.setValue("请先在设置中配置学号");
return;
}

isLoading.setValue(true);
RetrofitClient.getInstance()
.getTimetableService()
.getTimetable(studentId)
.enqueue(new Callback<TimetableResponse>() {
@Override
public void onResponse(Call<TimetableResponse> call, Response<TimetableResponse> response) {
isLoading.setValue(false);
if (response.isSuccessful() && response.body() != null && response.body().isSuccessful()) {
List<CourseSchedule> schedules = response.body().getCourseSchedules();
if (schedules != null) {
List<Course> coursesForDate = filterCoursesForDate(schedules, date);
mCourses.setValue(coursesForDate);
if (coursesForDate.isEmpty()) {
errorMessage.setValue("今天没有课程");
} else {
errorMessage.setValue(null);
}
}
} else {
String error = response.body() != null ? response.body().getMessage() : "获取课程数据失败";
errorMessage.setValue(error);
}
}

@Override
public void onFailure(Call<TimetableResponse> call, Throwable t) {
isLoading.setValue(false);
errorMessage.setValue("网络请求失败: " + t.getMessage());
}
});
}

private List<Course> filterCoursesForDate(List<CourseSchedule> schedules, Date targetDate) {
List<Course> courses = new ArrayList<>();

// 根据星期几返回不同的课程安排
switch (dayOfWeek) {
case Calendar.MONDAY:
courses.add(new Course("高等数学", "08:00", "09:40", "教学楼2-301", "张三", 1, 16));
courses.add(new Course("大学英语", "10:00", "11:40", "教学楼3-201", "李四", 1, 12));
break;
case Calendar.TUESDAY:
courses.add(new Course("Java程序设计", "14:00", "15:40", "实验楼1-501", "王五", 2, 17));
courses.add(new Course("数据结构", "16:00", "17:40", "教学楼4-401", "赵六", 3, 15));
break;
case Calendar.WEDNESDAY:
courses.add(new Course("计算机网络", "08:00", "09:40", "教学楼1-301", "孙七", 1, 14));
courses.add(new Course("操作系统", "10:00", "11:40", "实验楼2-401", "周八", 4, 16));
break;
case Calendar.THURSDAY:
courses.add(new Course("软件工程", "14:00", "15:40", "教学楼5-201", "吴九", 2, 15));
courses.add(new Course("数据库系统", "16:00", "17:40", "实验楼3-301", "郑十", 1, 13));
break;
case Calendar.FRIDAY:
courses.add(new Course("计算机组成原理", "08:00", "09:40", "教学楼6-401", "刘一", 3, 18));
courses.add(new Course("编译原理", "10:00", "11:40", "教学楼2-501", "陈二", 5, 16));
break;
// 周末没有课程
case Calendar.SATURDAY:
case Calendar.SUNDAY:
break;
String targetDateStr = apiDateFormat.format(targetDate);

for (CourseSchedule schedule : schedules) {
try {
if (schedule.getDate().equals(targetDateStr)) {
// 转换时间格式
String startTime = schedule.getStartTime().substring(0, 5); // 取"HH:mm"部分
String endTime = schedule.getEndTime().substring(0, 5); // 取"HH:mm"部分

// 获取周数范围
List<Integer> weekNums = schedule.getWeekNums();
int startWeek = weekNums.isEmpty() ? 1 : weekNums.get(0);
int endWeek = weekNums.isEmpty() ? 1 : weekNums.get(weekNums.size() - 1);

Course course = new Course(
schedule.getTitle(),
startTime,
endTime,
schedule.getLocation(),
schedule.getData().getTeacherName(),
startWeek,
endWeek
);
courses.add(course);
}
} catch (Exception e) {
e.printStackTrace();
}
}
mCourses.setValue(courses);

return courses;
}
}
Loading

0 comments on commit fa1b04c

Please sign in to comment.