diff --git a/android-app/app/src/main/java/com/example/livestreaming/ProfileActivity.java b/android-app/app/src/main/java/com/example/livestreaming/ProfileActivity.java index 06e75efd..0c6bbb1d 100644 --- a/android-app/app/src/main/java/com/example/livestreaming/ProfileActivity.java +++ b/android-app/app/src/main/java/com/example/livestreaming/ProfileActivity.java @@ -557,7 +557,8 @@ public class ProfileActivity extends AppCompatActivity { worksAdapter = new UserWorksAdapter(); worksAdapter.setOnWorkClickListener(workItem -> { if (workItem != null && !TextUtils.isEmpty(workItem.getId())) { - WorkDetailActivity.start(this, workItem.getId()); + // 从"我"页面进入,显示编辑删除菜单 + WorkDetailActivity.start(this, workItem.getId(), true); } }); binding.worksRecycler.setLayoutManager(new GridLayoutManager(this, 3)); diff --git a/android-app/app/src/main/java/com/example/livestreaming/PublishWorkActivity.java b/android-app/app/src/main/java/com/example/livestreaming/PublishWorkActivity.java index b4c88378..5c7bbf98 100644 --- a/android-app/app/src/main/java/com/example/livestreaming/PublishWorkActivity.java +++ b/android-app/app/src/main/java/com/example/livestreaming/PublishWorkActivity.java @@ -86,6 +86,10 @@ public class PublishWorkActivity extends AppCompatActivity { // 天地图定位服务继续 private TianDiTuLocationService locationService; private ActivityResultLauncher requestLocationPermissionLauncher; + + // 编辑模式相关 + private boolean isEditMode = false; + private String editWorkId = null; public static void start(Context context) { Intent intent = new Intent(context, PublishWorkActivity.class); @@ -102,6 +106,16 @@ public class PublishWorkActivity extends AppCompatActivity { return; } + // 检查是否是编辑模式 + isEditMode = getIntent().getBooleanExtra("edit_mode", false); + if (isEditMode) { + editWorkId = getIntent().getStringExtra("work_id"); + if (TextUtils.isEmpty(editWorkId)) { + Toast.makeText(this, "作品ID不能为空", Toast.LENGTH_SHORT).show(); + finish(); + return; + } + } binding = ActivityPublishWorkBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); @@ -112,6 +126,74 @@ public class PublishWorkActivity extends AppCompatActivity { setupMediaAdapter(); setupLaunchers(); setupClickListeners(); + + // 如果是编辑模式,预填充数据 + if (isEditMode) { + loadEditData(); + } + } + + /** + * 加载编辑数据 + */ + private void loadEditData() { + if (TextUtils.isEmpty(editWorkId)) { + return; + } + + // 从Intent中获取作品数据 + String workTitle = getIntent().getStringExtra("work_title"); + String workDescription = getIntent().getStringExtra("work_description"); + String workType = getIntent().getStringExtra("work_type"); + String workCoverUrl = getIntent().getStringExtra("work_cover_url"); + String workVideoUrl = getIntent().getStringExtra("work_video_url"); + ArrayList workImageUrls = getIntent().getStringArrayListExtra("work_image_urls"); + + // 填充标题和描述 + if (!TextUtils.isEmpty(workTitle)) { + binding.titleEditText.setText(workTitle); + } + if (!TextUtils.isEmpty(workDescription)) { + binding.descriptionEditText.setText(workDescription); + } + + // 设置作品类型和媒体 + if ("VIDEO".equals(workType)) { + currentWorkType = WorkItem.WorkType.VIDEO; + if (!TextUtils.isEmpty(workVideoUrl)) { + selectedVideoUri = Uri.parse(workVideoUrl); + selectedMediaUris.clear(); + selectedMediaUris.add(selectedVideoUri); + } + } else { + currentWorkType = WorkItem.WorkType.IMAGE; + if (workImageUrls != null && !workImageUrls.isEmpty()) { + selectedMediaUris.clear(); + for (String url : workImageUrls) { + if (!TextUtils.isEmpty(url)) { + selectedMediaUris.add(Uri.parse(url)); + } + } + } + } + + // 设置封面 + if (!TextUtils.isEmpty(workCoverUrl)) { + selectedCoverUri = Uri.parse(workCoverUrl); + } + + // 更新UI显示 + updateMediaDisplay(); + updateCoverPreview(); + + // 更新按钮文本 + binding.publishButton.setText("保存"); + + // 更新标题 + if (getSupportActionBar() != null) { + getSupportActionBar().setTitle("编辑作品"); + } + } } private void setupToolbar() { @@ -943,6 +1025,17 @@ public class PublishWorkActivity extends AppCompatActivity { request.setStatus(1); // 默认状态为正常 request.setLocation(selectedLocation); // 设置位置信息 + // 如果是编辑模式,设置作品ID + if (isEditMode && !TextUtils.isEmpty(editWorkId)) { + try { + request.setId(Long.parseLong(editWorkId)); + } catch (NumberFormatException e) { + progressDialog.dismiss(); + Toast.makeText(this, "作品ID格式错误", Toast.LENGTH_SHORT).show(); + return; + } + } + // 设置可见范围 String visibilityValue = "PUBLIC"; // 默认所有人可见 if ("所有人可见".equals(selectedVisibility)) { @@ -966,34 +1059,68 @@ public class PublishWorkActivity extends AppCompatActivity { request.setCommentSetting(commentSettingValue); ApiService apiService = ApiClient.getService(this); - Call> call = apiService.publishWork(request); - - call.enqueue(new retrofit2.Callback>() { - @Override - public void onResponse(Call> call, retrofit2.Response> response) { - progressDialog.dismiss(); - - if (response.isSuccessful() && response.body() != null) { - ApiResponse apiResponse = response.body(); - if (apiResponse.getCode() == 200) { - Toast.makeText(PublishWorkActivity.this, "发布成功", Toast.LENGTH_SHORT).show(); - finish(); + + // 根据模式选择不同的API调用 + if (isEditMode) { + // 编辑模式:调用更新接口 + Call> call = apiService.updateWork(request); + call.enqueue(new retrofit2.Callback>() { + @Override + public void onResponse(Call> call, retrofit2.Response> response) { + progressDialog.dismiss(); + + if (response.isSuccessful() && response.body() != null) { + ApiResponse apiResponse = response.body(); + if (apiResponse.getCode() == 200 && Boolean.TRUE.equals(apiResponse.getData())) { + Toast.makeText(PublishWorkActivity.this, "保存成功", Toast.LENGTH_SHORT).show(); + setResult(RESULT_OK); + finish(); + } else { + Toast.makeText(PublishWorkActivity.this, + apiResponse.getMessage() != null ? apiResponse.getMessage() : "保存失败", + Toast.LENGTH_SHORT).show(); + } } else { - Toast.makeText(PublishWorkActivity.this, - apiResponse.getMessage() != null ? apiResponse.getMessage() : "发布失败", - Toast.LENGTH_SHORT).show(); + Toast.makeText(PublishWorkActivity.this, "保存失败", Toast.LENGTH_SHORT).show(); } - } else { - Toast.makeText(PublishWorkActivity.this, "发布失败", Toast.LENGTH_SHORT).show(); } - } - @Override - public void onFailure(Call> call, Throwable t) { - progressDialog.dismiss(); - Toast.makeText(PublishWorkActivity.this, "网络错误: " + t.getMessage(), Toast.LENGTH_SHORT).show(); - } - }); + @Override + public void onFailure(Call> call, Throwable t) { + progressDialog.dismiss(); + Toast.makeText(PublishWorkActivity.this, "网络错误: " + t.getMessage(), Toast.LENGTH_SHORT).show(); + } + }); + } else { + // 发布模式:调用发布接口 + Call> call = apiService.publishWork(request); + call.enqueue(new retrofit2.Callback>() { + @Override + public void onResponse(Call> call, retrofit2.Response> response) { + progressDialog.dismiss(); + + if (response.isSuccessful() && response.body() != null) { + ApiResponse apiResponse = response.body(); + if (apiResponse.getCode() == 200) { + Toast.makeText(PublishWorkActivity.this, "发布成功", Toast.LENGTH_SHORT).show(); + finish(); + } else { + Toast.makeText(PublishWorkActivity.this, + apiResponse.getMessage() != null ? apiResponse.getMessage() : "发布失败", + Toast.LENGTH_SHORT).show(); + } + } else { + Toast.makeText(PublishWorkActivity.this, "发布失败", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + progressDialog.dismiss(); + Toast.makeText(PublishWorkActivity.this, "网络错误: " + t.getMessage(), Toast.LENGTH_SHORT).show(); + } + }); + } } /** diff --git a/android-app/app/src/main/java/com/example/livestreaming/WorkDetailActivity.java b/android-app/app/src/main/java/com/example/livestreaming/WorkDetailActivity.java index a44f7475..6e21da11 100644 --- a/android-app/app/src/main/java/com/example/livestreaming/WorkDetailActivity.java +++ b/android-app/app/src/main/java/com/example/livestreaming/WorkDetailActivity.java @@ -47,10 +47,16 @@ public class WorkDetailActivity extends AppCompatActivity { private int commentCount = 0; private static final String EXTRA_WORK_ID = "work_id"; + private static final String EXTRA_SHOW_MENU = "show_menu"; public static void start(Context context, String workId) { + start(context, workId, false); + } + + public static void start(Context context, String workId, boolean showMenu) { Intent intent = new Intent(context, WorkDetailActivity.class); intent.putExtra(EXTRA_WORK_ID, workId); + intent.putExtra(EXTRA_SHOW_MENU, showMenu); context.startActivity(intent); } @@ -61,12 +67,21 @@ public class WorkDetailActivity extends AppCompatActivity { setContentView(binding.getRoot()); String workId = getIntent().getStringExtra(EXTRA_WORK_ID); + boolean showMenu = getIntent().getBooleanExtra(EXTRA_SHOW_MENU, false); + if (TextUtils.isEmpty(workId)) { Toast.makeText(this, "作品ID不能为空", Toast.LENGTH_SHORT).show(); finish(); return; } + // 根据showMenu参数控制菜单显示 + if (showMenu) { + binding.actionButton.setVisibility(View.VISIBLE); + } else { + binding.actionButton.setVisibility(View.GONE); + } + // 加载作品详情 loadWorkDetail(workId); } @@ -1130,3 +1145,225 @@ public class WorkDetailActivity extends AppCompatActivity { } } + } + }); + } catch (NumberFormatException e) { + android.util.Log.e("WorkDetail", "workId格式错误: " + workId, e); + Toast.makeText(this, "作品ID格式错误", Toast.LENGTH_SHORT).show(); + finish(); + } catch (Exception e) { + android.util.Log.e("WorkDetail", "加载作品详情异常", e); + Toast.makeText(this, "加载失败: " + e.getMessage(), Toast.LENGTH_SHORT).show(); + finish(); + } + } + + /** + * 将WorksResponse转换为WorkItem + */ + private WorkItem convertToWorkItem(WorksResponse response) { + WorkItem item = new WorkItem(); + item.setId(String.valueOf(response.getId())); + item.setTitle(response.getTitle()); + item.setDescription(response.getDescription()); + item.setLikeCount(response.getLikeCount()); + item.setCollectCount(response.getCollectCount()); + item.setViewCount(response.getViewCount()); + // 防止 publishTime 为 null 导致 NullPointerException + item.setPublishTime(response.getPublishTime() != null ? response.getPublishTime() : 0L); + + // 设置作者信息 + item.setAuthorId(response.getUserId() != null ? response.getUserId() : 0); + item.setAuthorName(response.getAuthorName() != null ? response.getAuthorName() : response.getUserName()); + item.setAuthorAvatar(response.getAuthorAvatar() != null ? response.getAuthorAvatar() : response.getUserAvatar()); + + // 设置作品类型 + if ("VIDEO".equals(response.getType())) { + item.setType(WorkItem.WorkType.VIDEO); + item.setVideoUrl(response.getVideoUrl()); + if (!TextUtils.isEmpty(response.getVideoUrl())) { + item.setVideoUri(Uri.parse(response.getVideoUrl())); + } + } else { + item.setType(WorkItem.WorkType.IMAGE); + item.setImageUrls(response.getImageUrls()); + if (response.getImageUrls() != null && !response.getImageUrls().isEmpty()) { + List imageUris = new ArrayList<>(); + for (String url : response.getImageUrls()) { + if (!TextUtils.isEmpty(url)) { + imageUris.add(Uri.parse(url)); + } + } + item.setImageUris(imageUris); + } + } + + // 设置封面 + item.setCoverUrl(response.getCoverUrl()); + if (!TextUtils.isEmpty(response.getCoverUrl())) { + item.setCoverUri(Uri.parse(response.getCoverUrl())); + } + + return item; + } + + private void setupActionButton() { + // 检查是否应该显示菜单 + boolean showMenu = getIntent().getBooleanExtra(EXTRA_SHOW_MENU, false); + if (!showMenu) { + binding.actionButton.setVisibility(View.GONE); + return; + } + + // 检查是否是当前用户的作品 + String currentUserIdStr = AuthStore.getUserId(this); + if (currentUserIdStr == null || workItem == null) { + binding.actionButton.setVisibility(View.GONE); + return; + } + + try { + int currentUserId = Integer.parseInt(currentUserIdStr); + int authorId = workItem.getAuthorId(); + + if (currentUserId != authorId) { + // 不是自己的作品,隐藏菜单 + binding.actionButton.setVisibility(View.GONE); + return; + } + } catch (NumberFormatException e) { + binding.actionButton.setVisibility(View.GONE); + return; + } + + // 是自己的作品且需要显示菜单,设置点击事件 + binding.actionButton.setVisibility(View.VISIBLE); + binding.actionButton.setOnClickListener(new DebounceClickListener() { + @Override + public void onDebouncedClick(View v) { + showActionMenu(); + } + }); + } + + private void showActionMenu() { + // 检查是否是当前用户的作品 + String currentUserIdStr = AuthStore.getUserId(this); + if (currentUserIdStr == null || workItem == null) { + return; + } + + try { + int currentUserId = Integer.parseInt(currentUserIdStr); + int authorId = workItem.getAuthorId(); + + if (currentUserId != authorId) { + Toast.makeText(this, "只能编辑自己的作品", Toast.LENGTH_SHORT).show(); + return; + } + } catch (NumberFormatException e) { + return; + } + + String[] options = {"编辑", "删除"}; + new AlertDialog.Builder(this) + .setItems(options, (dialog, which) -> { + if (which == 0) { + // 编辑 + editWork(); + } else if (which == 1) { + // 删除 + deleteWork(); + } + }) + .show(); + } + + private void editWork() { + // 检查登录状态 + if (!AuthHelper.requireLogin(this, "编辑作品需要登录")) { + return; + } + + if (workItem == null) { + Toast.makeText(this, "作品信息不完整", Toast.LENGTH_SHORT).show(); + return; + } + + // 跳转到编辑页面(复用PublishWorkActivity) + Intent intent = new Intent(this, PublishWorkActivity.class); + intent.putExtra("edit_mode", true); + intent.putExtra("work_id", workItem.getId()); + intent.putExtra("work_title", workItem.getTitle()); + intent.putExtra("work_description", workItem.getDescription()); + intent.putExtra("work_type", workItem.getType().name()); + intent.putExtra("work_cover_url", workItem.getCoverUrl()); + + if (workItem.getType() == WorkItem.WorkType.VIDEO) { + intent.putExtra("work_video_url", workItem.getVideoUrl()); + } else if (workItem.getImageUrls() != null) { + intent.putStringArrayListExtra("work_image_urls", new ArrayList<>(workItem.getImageUrls())); + } + + startActivityForResult(intent, 1001); + } + + private void deleteWork() { + new AlertDialog.Builder(this) + .setTitle("删除作品") + .setMessage("确定要删除这个作品吗?") + .setPositiveButton("删除", (dialog, which) -> { + // 检查登录状态 + if (!AuthHelper.requireLogin(this, "删除作品需要登录")) { + return; + } + + try { + long worksId = Long.parseLong(workItem.getId()); + ApiService apiService = ApiClient.getService(this); + Call> call = apiService.deleteWork(worksId); + + call.enqueue(new retrofit2.Callback>() { + @Override + public void onResponse(Call> call, retrofit2.Response> response) { + if (response.isSuccessful() && response.body() != null) { + ApiResponse apiResponse = response.body(); + if (apiResponse.getCode() == 200 && Boolean.TRUE.equals(apiResponse.getData())) { + Toast.makeText(WorkDetailActivity.this, "删除成功", Toast.LENGTH_SHORT).show(); + finish(); + } else { + Toast.makeText(WorkDetailActivity.this, + apiResponse.getMessage() != null ? apiResponse.getMessage() : "删除失败", + Toast.LENGTH_SHORT).show(); + } + } else { + Toast.makeText(WorkDetailActivity.this, "删除失败", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + Toast.makeText(WorkDetailActivity.this, "网络错误: " + t.getMessage(), Toast.LENGTH_SHORT).show(); + } + }); + } catch (NumberFormatException e) { + Toast.makeText(this, "作品ID格式错误", Toast.LENGTH_SHORT).show(); + } + }) + .setNegativeButton("取消", null) + .show(); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == 1001 && resultCode == RESULT_OK) { + // 编辑成功,重新加载作品详情 + String workId = getIntent().getStringExtra(EXTRA_WORK_ID); + if (!TextUtils.isEmpty(workId)) { + loadWorkDetail(workId); + Toast.makeText(this, "作品更新成功", Toast.LENGTH_SHORT).show(); + } + } + } +} \ No newline at end of file diff --git a/android-app/app/src/main/java/com/example/livestreaming/net/ApiService.java b/android-app/app/src/main/java/com/example/livestreaming/net/ApiService.java index 0594e2fe..8a47ed8b 100644 --- a/android-app/app/src/main/java/com/example/livestreaming/net/ApiService.java +++ b/android-app/app/src/main/java/com/example/livestreaming/net/ApiService.java @@ -374,6 +374,9 @@ public interface ApiService { @POST("api/front/works/publish") Call> publishWork(@Body WorksRequest body); + @POST("api/front/works/update") + Call> updateWork(@Body WorksRequest body); + @GET("api/front/works/detail/{id}") Call> getWorkDetail(@Path("id") long id);