Files
slogan/lib/features/profile/photo_upload_provider.dart
T
admin ceef7bc64e feat(app): 形象照片上传 + 身形设置 + 化身构建 + 衣橱管理
- photo_upload_provider/photo_guide_page:4 类照片(大头照/正面/侧面/背面)拍照或相册上传
- body_provider/body_tune_page:身高 145-200cm / 体重 / 肤色 1-5 滑杆设置
- avatar_provider:化身构建(同步 + 异步轮询兜底)
- profile_page:形象主页聚合化身/照片/身形状态 + 登出
- wardrobe_provider/wardrobe_page/wardrobe_upload_page:网格展示 + 分类筛选 + 长按删除 + 表单上传
- AppConfig.resolveUrl 相对路径拼接;新增 /photo-guide /body-tune /wardrobe-upload 路由
2026-07-31 12:44:10 +08:00

78 lines
2.1 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../core/auth/auth_provider.dart';
/// 照片类型(与后端 consts.PhotoType 对应)
class PhotoType {
static const int headshot = 1;
static const int fullFront = 2;
static const int fullSide = 3;
static const int fullBack = 4;
static const Map<int, String> labels = {
headshot: '大头照',
fullFront: '全身正面',
fullSide: '全身侧面',
fullBack: '全身背面',
};
static const Map<int, String> descs = {
headshot: '清晰正脸、光线充足',
fullFront: '站立正面全身,拍全脚底',
fullSide: '站立侧面全身,自然放松',
fullBack: '站立背面全身,露出轮廓',
};
static const List<int> all = [headshot, fullFront, fullSide, fullBack];
}
class UserPhotoInfo {
final int id;
final int type;
final String url;
const UserPhotoInfo({
required this.id,
required this.type,
required this.url,
});
}
class PhotoNotifier extends AsyncNotifier<List<UserPhotoInfo>> {
@override
Future<List<UserPhotoInfo>> build() async {
final api = ref.read(apiClientProvider);
final list = await api.get<List<dynamic>>('/user-photo/list');
return list
.map((e) => UserPhotoInfo(
id: (e['id'] as num).toInt(),
type: (e['type'] as num).toInt(),
url: e['url'] as String? ?? '',
))
.toList();
}
Future<void> upload(int type, String filePath) async {
final api = ref.read(apiClientProvider);
await api.upload('/user-photo/upload', {'type': type}, 'file', filePath);
await refresh();
}
Future<void> delete(int id) async {
final api = ref.read(apiClientProvider);
await api.post('/user-photo/delete', {'id': id});
await refresh();
}
Future<void> refresh() async {
state = const AsyncLoading();
state = await AsyncValue.guard(build);
}
/// 某类型是否已上传
bool hasType(int type) => state.value?.any((p) => p.type == type) ?? false;
}
final photoProvider =
AsyncNotifierProvider<PhotoNotifier, List<UserPhotoInfo>>(PhotoNotifier.new);