ar_tourism_flutter_unity/lib/components/work_utils.dart
2025-05-14 17:04:13 +08:00

196 lines
5.7 KiB
Dart

import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:http_parser/http_parser.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
import '../apis/app.dart';
import 'dart:io';
// 这是一个工具类,主要负责处理作品的保存逻辑:
// 1. 处理编辑模式的保存
// 2. 处理新建模式的保存
// 3. 处理保存成功后的提示
// 4. 处理保存失败后的提示
// 5. 处理保存成功后的跳转
class WorkUtils {
static Future<void> handleEditSave(
BuildContext context,
Map<String, dynamic> content,
String status,
) async {
try {
final asset = content['asset'];
final isFromWorks = content['isFromWorks'] ?? false;
final originalWorkAddress = content['workAddress'];
print("原始图片地址: $originalWorkAddress");
print("处理编辑保存 - 来自作品集: $isFromWorks");
print("当前内容: $content");
// 构建workDto参数
final workDto = {
"workId": content['workId'],
"workname": content['workName'],
"detail": content['detail'],
"workstatus": status,
};
print("构建的workDto: $workDto");
FormData formData;
// 根据是否有新图片构建FormData
if (asset != null) {
// 如果有新图片,使用本地文件
final file = await asset.file;
print("文件-----------------: $file");
if (file == null) throw "文件加载失败";
formData = FormData.fromMap({
"work": await MultipartFile.fromFile(
file.path,
filename: asset.type == AssetType.video ? "video.mp4" : "img.jpg",
contentType: asset.type == AssetType.video
? MediaType("video", "mp4")
: MediaType("image", "jpg"),
),
"workDto": jsonEncode(workDto),
});
} else {
if (originalWorkAddress == null) throw "原始图片地址不能为空";
formData = FormData.fromMap({
"work": MultipartFile.fromBytes(
Uint8List(0), // 空字节数组
filename: "empty.txt",
),
"workDto": jsonEncode(workDto),
});
}
// 使用editUserWork接口更新作品
print("开始调用editUserWork接口");
final editResult = await userApi.editUserWork(formData);
print("接口返回结果: $editResult");
if (editResult['code'] != 200) {
throw editResult['msg'] ?? "保存失败";
}
if (!context.mounted) return;
_handleSaveSuccess(context, status, isEdit: true);
} catch (e) {
print("发生错误: $e");
if (!context.mounted) return;
_showErrorSnackBar(context, e.toString());
rethrow;
}
}
// 处理新建作品的保存
static Future<void> handleNewSave(
BuildContext context,
Map<String, dynamic> content,
String status,
) async {
try {
if (content['asset'] == null) {
throw "请先选择图片";
}
print("开始创建新作品");
final file = await content['asset'].file;
// 构建workDto参数
var workDto = {
"workname": content['workname'],
"detail": content['detail'],
"workstatus": status,
};
FormData formData = FormData.fromMap({
"work": await MultipartFile.fromFile(
file.path,
filename: content['asset'].type == AssetType.video ? "video.mp4" : "img.jpg",
contentType: content['asset'].type == AssetType.video
? MediaType("video", "mp4")
: MediaType("image", "jpg"),
),
"workDto": jsonEncode(workDto),
});
// 使用getUserWorks接口创建新作品
final result = await userApi.getUserWorks(formData);
print("创建作品结果:$result");
if (result['code'] != 200) {
throw result['msg'] ?? "创建失败";
}
if (!context.mounted) return;
_handleSaveSuccess(context, status, isEdit: false);
} catch (e) {
if (!context.mounted) return;
_showErrorSnackBar(context, e.toString());
rethrow;
}
}
static void _handleSaveSuccess(BuildContext context, String status, {required bool isEdit}) {
if (status == "1") {
if (isEdit) {
// 从作品集编辑进入
ScaffoldMessenger.of(context).showSnackBar(
_buildSnackBar(context, "作品修改成功"),
);
} else {
// 从相册创建新作品
ScaffoldMessenger.of(context).showSnackBar(
_buildSnackBar(context, "快来发布作品吧"),
);
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
_buildSnackBar(context, "存草稿成功"),
);
}
}
static void _showErrorSnackBar(BuildContext context, String error) {
ScaffoldMessenger.of(context).showSnackBar(
_buildSnackBar(
context,
'保存失败: $error',
backgroundColor: Colors.red,
),
);
}
static SnackBar _buildSnackBar(
BuildContext context,
String message, {
Color backgroundColor = const Color(0xFF1A1A29),
}) {
return SnackBar(
content: Text(
message,
style: const TextStyle(color: Colors.white),
textAlign: TextAlign.center,
),
backgroundColor: backgroundColor,
behavior: SnackBarBehavior.floating,
margin: EdgeInsets.only(
bottom: MediaQuery.of(context).size.height * 0.7,
left: 20,
right: 20,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
duration: const Duration(seconds: 2),
);
}
}