소스 검색

[feat]星座恋爱分析,增加基础信息展示,对接接口

hezihao 6 달 전
부모
커밋
9687fbf203

+ 3 - 3
assets/string/base/string.xml

@@ -12,7 +12,7 @@
     <string name="personal_profile">个人档案</string>
     <string name="feedback">意见反馈</string>
     <string name="about_us">关于我们</string>
-<!--    投诉举报-->
+    <!--    投诉举报-->
     <string name="complaint_report">投诉举报</string>
     <string name="mine_account_logged_desc">用户</string>
     <string name="mine_account_no_login">游客,去登录</string>
@@ -66,6 +66,7 @@
     <string name="personal_info">个人信息</string>
     <string name="logout">退出登录</string>
 
+    <string name="user_not_set_birthday_tip">请先设置生日</string>
 
     <!-- 反馈页面-->
     <string name="feedback_content_title">问题描述</string>
@@ -76,7 +77,7 @@
     <string name="feedback_content_empty">请输入反馈内容</string>
     <string name="feedback_phone_empty">请输入联系电话</string>
     <string name="feedback_submit_success">感谢您的意见与反馈</string>
-<!--    投诉内容-->
+    <!--    投诉内容-->
     <string name="complaint_content_title">投诉内容</string>
     <string name="complaint_content_hint">我们想知道你投诉举报的原因,你可以描述遇到的问题</string>
     <string name="complaint_content_empty">请输入投诉内容</string>
@@ -247,7 +248,6 @@
     <string name="profile_select">当前选择</string>
 
 
-
     <string name="keyboard_member_open">开通会员</string>
 
     <string name="keyboard_go_to_manage">去管理</string>

+ 7 - 0
lib/data/api/atmob_api.dart

@@ -66,6 +66,7 @@ import 'package:keyboard/data/api/response/order_pay_response.dart';
 import 'package:keyboard/data/api/response/order_status_response.dart';
 import 'package:keyboard/data/api/response/user_info_response.dart';
 import 'package:keyboard/data/api/response/wechat_login_response.dart';
+import 'package:keyboard/data/api/response/zodiac_love_intimacy_love_info_response.dart';
 import 'package:keyboard/data/api/response/zodiac_love_intimacy_response.dart';
 import 'package:keyboard/data/repository/config_repository.dart';
 import 'package:retrofit/error_logger.dart';
@@ -326,6 +327,12 @@ abstract class AtmobApi {
     @Body() AppBaseRequest request,
   );
 
+  /// 获取星座恋爱分析-基本信息
+  @POST("/project/keyboard/v1/intimacy/love/info")
+  Future<BaseResponse<ZodiacLoveIntimacyLoveInfoResponse>> getZodiacLoveIntimacyLoveInfo(
+    @Body() AppBaseRequest request,
+  );
+
   /// 星座恋爱分析-获取今日指数分析
   @POST("/project/keyboard/v1/intimacy/today/index")
   Future<BaseResponse<ZodiacLoveIntimacyResponse>> getZodiacLoveIntimacyToday(

+ 37 - 0
lib/data/api/atmob_api.g.dart

@@ -1512,6 +1512,43 @@ class _AtmobApi implements AtmobApi {
   }
 
   @override
+  Future<BaseResponse<ZodiacLoveIntimacyLoveInfoResponse>>
+  getZodiacLoveIntimacyLoveInfo(AppBaseRequest request) async {
+    final _extra = <String, dynamic>{};
+    final queryParameters = <String, dynamic>{};
+    final _headers = <String, dynamic>{};
+    final _data = <String, dynamic>{};
+    _data.addAll(request.toJson());
+    final _options =
+        _setStreamType<BaseResponse<ZodiacLoveIntimacyLoveInfoResponse>>(
+          Options(method: 'POST', headers: _headers, extra: _extra)
+              .compose(
+                _dio.options,
+                '/project/keyboard/v1/intimacy/love/info',
+                queryParameters: queryParameters,
+                data: _data,
+              )
+              .copyWith(
+                baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl),
+              ),
+        );
+    final _result = await _dio.fetch<Map<String, dynamic>>(_options);
+    late BaseResponse<ZodiacLoveIntimacyLoveInfoResponse> _value;
+    try {
+      _value = BaseResponse<ZodiacLoveIntimacyLoveInfoResponse>.fromJson(
+        _result.data!,
+        (json) => ZodiacLoveIntimacyLoveInfoResponse.fromJson(
+          json as Map<String, dynamic>,
+        ),
+      );
+    } on Object catch (e, s) {
+      errorLogger?.logError(e, s, _options);
+      rethrow;
+    }
+    return _value;
+  }
+
+  @override
   Future<BaseResponse<ZodiacLoveIntimacyResponse>> getZodiacLoveIntimacyToday(
     AppBaseRequest request,
   ) async {

+ 59 - 0
lib/data/api/response/zodiac_love_intimacy_love_info_response.dart

@@ -0,0 +1,59 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'zodiac_love_intimacy_love_info_response.g.dart';
+
+/// 星座恋爱分析
+@JsonSerializable()
+class ZodiacLoveIntimacyLoveInfoResponse {
+  /// 用户头像
+  @JsonKey(name: "imageUrl")
+  String? imageUrl;
+
+  /// 对方用户头像
+  @JsonKey(name: "targetImageUrl")
+  String? targetImageUrl;
+
+  /// 用户生日
+  @JsonKey(name: "birthday")
+  String? birthday;
+
+  /// 对象用户生日
+  @JsonKey(name: "targetBirthday")
+  String? targetBirthday;
+
+  /// 亲密度
+  @JsonKey(name: "intimacy")
+  int? intimacy;
+
+  /// 星座梗语
+  @JsonKey(name: "explain")
+  String? explain;
+
+  /// 用户性别
+  @JsonKey(name: "gender")
+  int? gender;
+
+  /// 用户性别
+  @JsonKey(name: "targetGender")
+  int? targetGender;
+
+  /// 梗语标题
+  @JsonKey(name: "meme")
+  String? meme;
+
+  ZodiacLoveIntimacyLoveInfoResponse(
+    this.imageUrl,
+    this.targetImageUrl,
+    this.birthday,
+    this.targetBirthday,
+    this.intimacy,
+    this.explain,
+    this.gender,
+    this.targetGender,
+    this.meme,
+  );
+
+  factory ZodiacLoveIntimacyLoveInfoResponse.fromJson(
+    Map<String, dynamic> json,
+  ) => _$ZodiacLoveIntimacyLoveInfoResponseFromJson(json);
+}

+ 35 - 0
lib/data/api/response/zodiac_love_intimacy_love_info_response.g.dart

@@ -0,0 +1,35 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'zodiac_love_intimacy_love_info_response.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+ZodiacLoveIntimacyLoveInfoResponse _$ZodiacLoveIntimacyLoveInfoResponseFromJson(
+  Map<String, dynamic> json,
+) => ZodiacLoveIntimacyLoveInfoResponse(
+  json['imageUrl'] as String?,
+  json['targetImageUrl'] as String?,
+  json['birthday'] as String?,
+  json['targetBirthday'] as String?,
+  (json['intimacy'] as num?)?.toInt(),
+  json['explain'] as String?,
+  (json['gender'] as num?)?.toInt(),
+  (json['targetGender'] as num?)?.toInt(),
+  json['meme'] as String?,
+);
+
+Map<String, dynamic> _$ZodiacLoveIntimacyLoveInfoResponseToJson(
+  ZodiacLoveIntimacyLoveInfoResponse instance,
+) => <String, dynamic>{
+  'imageUrl': instance.imageUrl,
+  'targetImageUrl': instance.targetImageUrl,
+  'birthday': instance.birthday,
+  'targetBirthday': instance.targetBirthday,
+  'intimacy': instance.intimacy,
+  'explain': instance.explain,
+  'gender': instance.gender,
+  'targetGender': instance.targetGender,
+  'meme': instance.meme,
+};

+ 1 - 0
lib/data/consts/error_code.dart

@@ -6,6 +6,7 @@ class ErrorCode {
   static const int noLoginError = 1006; //未登录
   static const int noMember = 1005; //没有会员
   static const int sensitive = 1023; //敏感内容
+  static const int noSetBirthday = 1013; // 未设置生成
 
   /// 会员服务相关错误码
 

+ 8 - 0
lib/data/repository/zodiac_love_intimacy_repository.dart

@@ -3,6 +3,7 @@ import 'package:injectable/injectable.dart';
 import '../../base/app_base_request.dart';
 import '../../utils/http_handler.dart';
 import '../api/atmob_api.dart';
+import '../api/response/zodiac_love_intimacy_love_info_response.dart';
 import '../api/response/zodiac_love_intimacy_response.dart';
 
 /// 星座恋爱分析Repository层
@@ -14,6 +15,13 @@ class ZodiacLoveIntimacyRepository {
 
   ZodiacLoveIntimacyRepository(this.atmobApi);
 
+  /// 获取星座恋爱分析-基本信息
+  Future<ZodiacLoveIntimacyLoveInfoResponse> getZodiacLoveIntimacyLoveInfo() async {
+    return await atmobApi
+        .getZodiacLoveIntimacyLoveInfo(AppBaseRequest())
+        .then(HttpHandler.handle(true));
+  }
+
   /// 星座恋爱分析-获取今日指数分析
   Future<ZodiacLoveIntimacyResponse> getZodiacLoveIntimacyToday() async {
     return await atmobApi

+ 6 - 3
lib/di/get_it.config.dart

@@ -163,9 +163,6 @@ extension GetItInjectableX on _i174.GetIt {
     );
     gh.factory<_i973.SplashController>(() => _i973.SplashController());
     gh.factory<_i333.DiscountController>(() => _i333.DiscountController());
-    gh.factory<_i1060.ZodiacLoveIntimacyController>(
-      () => _i1060.ZodiacLoveIntimacyController(),
-    );
     gh.factory<_i415.KeyboardMethodHandler>(
       () => _i415.KeyboardMethodHandler(),
     );
@@ -329,6 +326,12 @@ extension GetItInjectableX on _i174.GetIt {
     gh.factory<_i866.UserInfoController>(
       () => _i866.UserInfoController(gh<_i83.AccountRepository>()),
     );
+    gh.factory<_i1060.ZodiacLoveIntimacyController>(
+      () => _i1060.ZodiacLoveIntimacyController(
+        gh<_i83.AccountRepository>(),
+        gh<_i779.ZodiacLoveIntimacyRepository>(),
+      ),
+    );
     gh.factory<_i666.IntimacyAnalyseUploadController>(
       () => _i666.IntimacyAnalyseUploadController(
         gh<_i283.IntimacyAnalyzeRepository>(),

+ 19 - 1
lib/module/zodiac_love_intimacy/future_week/zodiac_love_future_week_controller.dart

@@ -1,4 +1,5 @@
 import 'package:get/get_rx/src/rx_types/rx_types.dart';
+import 'package:get/get_rx/src/rx_workers/rx_workers.dart';
 import 'package:injectable/injectable.dart';
 import 'package:keyboard/base/base_controller.dart';
 
@@ -41,7 +42,22 @@ class ZodiacLoveFutureWeekController extends BaseController {
   @override
   void onInit() {
     super.onInit();
-    _getZodiacLoveIntimacyFutureWeek();
+    ever(memberInfo, (info) {
+      // 如果是会员了,重新拉取数据
+      if (info != null) {
+        if (info.isMember) {
+          _getZodiacLoveIntimacyFutureWeek();
+        }
+      }
+    });
+  }
+
+  @override
+  void onReady() {
+    super.onReady();
+    if (memberInfo.value?.isMember == true) {
+      _getZodiacLoveIntimacyFutureWeek();
+    }
   }
 
   /// 星座恋爱分析-获取未来一周分析
@@ -63,6 +79,8 @@ class ZodiacLoveFutureWeekController extends BaseController {
           // 需要VIP
           ToastUtil.show(StringName.needVipTip);
           NewDiscountPage.start();
+        } else {
+          ErrorHandler.toastError(error);
         }
       } else {
         ErrorHandler.toastError(error);

+ 15 - 0
lib/module/zodiac_love_intimacy/tody/zodiac_love_today_controller.dart

@@ -41,6 +41,19 @@ class ZodiacLoveTodayController extends BaseController {
   @override
   void onInit() {
     super.onInit();
+    ever(memberInfo, (info) {
+      // 如果是会员了,重新拉取数据
+      if (info != null) {
+        if (info.isMember) {
+          _getZodiacLoveIntimacyToday();
+        }
+      }
+    });
+  }
+
+  @override
+  void onReady() {
+    super.onReady();
     _getZodiacLoveIntimacyToday();
   }
 
@@ -63,6 +76,8 @@ class ZodiacLoveTodayController extends BaseController {
           // 需要VIP
           ToastUtil.show(StringName.needVipTip);
           NewDiscountPage.start();
+        } else {
+          ErrorHandler.toastError(error);
         }
       } else {
         ErrorHandler.toastError(error);

+ 3 - 1
lib/module/zodiac_love_intimacy/tody/zodiac_love_today_view.dart

@@ -18,7 +18,9 @@ class ZodiacLoveTodayView extends BaseView<ZodiacLoveTodayController> {
   Widget buildBody(BuildContext context) {
     return Obx(() {
       return ZodiacLoveIntimacyReportWidget(
-        unlock: controller.memberInfo.value?.isMember ?? false,
+        // unlock: controller.memberInfo.value?.isMember ?? false,
+        // 今日分析,不需要VIP就可以查看
+        unlock: true,
         reportResult: controller.zodiacLoveIntimacyResp.value,
         clickUnlockBtnCallback: () {
           controller.clickUnlockBtn();

+ 22 - 19
lib/module/zodiac_love_intimacy/widget/zodiac_love_intimacy_report.dart

@@ -59,29 +59,32 @@ class LockReportWidget extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return Center(
-      child: Stack(
-        children: [
-          Column(
-            // 垂直水平都居中
-            mainAxisAlignment: MainAxisAlignment.center,
-            crossAxisAlignment: CrossAxisAlignment.center,
+    return SingleChildScrollView(
+      child: Container(
+        padding: EdgeInsets.symmetric(vertical: 16.h),
+        child: Center(
+          child: Stack(
             children: [
-              // 占位图
-              Assets.images.iconZodiacLoveAnalyseReportUnlockPlaceholder.image(
-                width: 328.w,
-                height: 436.h,
+              Column(
+                // 垂直水平都居中
+                mainAxisAlignment: MainAxisAlignment.center,
+                crossAxisAlignment: CrossAxisAlignment.center,
+                children: [
+                  // 占位图
+                  Assets.images.iconZodiacLoveAnalyseReportUnlockPlaceholder
+                      .image(width: 328.w, height: 436.h),
+                ],
+              ),
+              // 解锁按钮
+              Positioned(
+                left: 0,
+                top: 147.h,
+                right: 0,
+                child: _buildUnlockBtn(context),
               ),
             ],
           ),
-          // 解锁按钮
-          Positioned(
-            left: 0,
-            top: 147.h,
-            right: 0,
-            child: _buildUnlockBtn(context),
-          ),
-        ],
+        ),
       ),
     );
   }

+ 94 - 1
lib/module/zodiac_love_intimacy/zodiac_love_intimacy_controller.dart

@@ -2,9 +2,21 @@ import 'package:flutter/Material.dart';
 import 'package:get/get.dart';
 import 'package:injectable/injectable.dart';
 import 'package:keyboard/base/base_controller.dart';
-
+import '../../data/api/response/user_info_response.dart';
+import '../../data/api/response/zodiac_love_intimacy_love_info_response.dart';
+import '../../data/consts/error_code.dart';
+import '../../data/repository/account_repository.dart';
+import '../../data/repository/zodiac_love_intimacy_repository.dart';
+import '../../dialog/login/login_dialog.dart';
+import '../../resource/string.gen.dart';
 import '../../router/app_page_arguments.dart';
+import '../../utils/age_zodiac_sign_util.dart';
 import '../../utils/atmob_log.dart';
+import '../../utils/error_handler.dart';
+import '../../utils/http_handler.dart';
+import '../../utils/toast_util.dart';
+import '../store/new_discount/new_discount_page.dart';
+import '../user_profile/user_profile_page.dart';
 import 'enums/zodiac_love_intimacy_tab.dart';
 
 /// 星座恋爱分析Controller
@@ -13,6 +25,12 @@ class ZodiacLoveIntimacyController extends BaseController
     with GetTickerProviderStateMixin {
   final String _tag = "ZodiacLoveIntimacyController";
 
+  /// 账户信息Repository
+  final AccountRepository accountRepository;
+
+  /// 星座恋爱分析Repository
+  final ZodiacLoveIntimacyRepository zodiacLoveIntimacyRepository;
+
   /// Tab列表
   RxList<ZodiacLoveIntimacyTab> tabBarList = ZodiacLoveIntimacyTab.values.obs;
 
@@ -28,10 +46,41 @@ class ZodiacLoveIntimacyController extends BaseController
   /// 当前Tab的索引
   Rx<int> currentTabIndex = 0.obs;
 
+  /// 当前用户信息
+  Rxn<UserInfoResponse> get userInfo => accountRepository.userInfo;
+
+  /// 星座恋爱分析-基础信息
+  Rxn<ZodiacLoveIntimacyLoveInfoResponse> zodiacLoveIntimacyLoveInfoResponse =
+      Rxn<ZodiacLoveIntimacyLoveInfoResponse>();
+
+  /// 我的星座信息
+  Zodiac? get myZodiacInfo {
+    String? birthday =
+        zodiacLoveIntimacyLoveInfoResponse.value?.birthday ??=
+            userInfo.value?.birthday;
+    int? gender =
+        zodiacLoveIntimacyLoveInfoResponse.value?.gender ??=
+            userInfo.value?.gender;
+    return getUserZodiacInfo(birthday, gender);
+  }
+
+  /// Ta的星座信息
+  Zodiac? get taZodiacInfo {
+    final birthday = zodiacLoveIntimacyLoveInfoResponse.value?.targetBirthday;
+    final gender = zodiacLoveIntimacyLoveInfoResponse.value?.targetGender;
+    return getUserZodiacInfo(birthday, gender);
+  }
+
+  ZodiacLoveIntimacyController(
+    this.accountRepository,
+    this.zodiacLoveIntimacyRepository,
+  );
+
   @override
   void onInit() {
     super.onInit();
     _initArgs();
+    _getZodiacLoveIntimacyLoveInfo();
   }
 
   /// 初始化参数
@@ -86,4 +135,48 @@ class ZodiacLoveIntimacyController extends BaseController
     tabController.animateTo(index, duration: const Duration(milliseconds: 300));
     currentTabIndex.value = index;
   }
+
+  /// 获取星座恋爱分析-基本信息
+  void _getZodiacLoveIntimacyLoveInfo() async {
+    try {
+      ZodiacLoveIntimacyLoveInfoResponse resp =
+          await zodiacLoveIntimacyRepository.getZodiacLoveIntimacyLoveInfo();
+      zodiacLoveIntimacyLoveInfoResponse.value = resp;
+    } catch (error) {
+      if (error is ServerErrorException) {
+        // 未登录
+        if (error.code == ErrorCode.noLoginError) {
+          ToastUtil.show(StringName.accountNoLogin);
+          LoginDialog.show();
+        } else if (error.code == ErrorCode.noMember) {
+          // 需要VIP
+          ToastUtil.show(StringName.needVipTip);
+          NewDiscountPage.start();
+        } else if (error.code == ErrorCode.noSetBirthday) {
+          // 未设置生日
+          ErrorHandler.toastError(error);
+          await UserProfilePage.start();
+        } else {
+          ErrorHandler.toastError(error);
+        }
+      } else {
+        ErrorHandler.toastError(error);
+      }
+    }
+  }
+
+  /// 获取用户的星座信息
+  Zodiac? getUserZodiacInfo(String? birthday, int? gender) {
+    if (birthday?.isEmpty != false || gender == null) {
+      return null;
+    }
+    final zodiac = AgeZodiacSignUtil.getZodiacWithGenderLabel(
+      birthday!,
+      gender,
+    );
+    if (zodiac.name == '未知星座') {
+      return null;
+    }
+    return zodiac;
+  }
 }

+ 189 - 6
lib/module/zodiac_love_intimacy/zodiac_love_intimacy_page.dart

@@ -3,16 +3,22 @@ import 'package:flutter/Material.dart';
 import 'package:flutter_screenutil/flutter_screenutil.dart';
 import 'package:get/get.dart';
 import 'package:keyboard/base/base_page.dart';
+import 'package:keyboard/data/repository/account_repository.dart';
 import 'package:keyboard/module/zodiac_love_intimacy/tody/zodiac_love_today_view.dart';
 import 'package:keyboard/module/zodiac_love_intimacy/zodiac_love_intimacy_controller.dart';
 import 'package:keyboard/resource/colors.gen.dart';
+import 'package:keyboard/utils/toast_util.dart';
+import 'package:lottie/lottie.dart';
 import 'package:nested_scroll_views/material.dart';
-
+import '../../di/get_it.dart';
 import '../../resource/assets.gen.dart';
 import '../../resource/string.gen.dart';
 import '../../router/app_pages.dart';
+import '../../utils/age_zodiac_sign_util.dart';
+import '../../widget/avatar/avatar_image_widget.dart';
 import '../../widget/status_bar_placeholder_widget.dart';
 import '../../widget/top_bar.dart';
+import '../user_profile/user_profile_page.dart';
 import 'enums/zodiac_love_intimacy_tab.dart';
 import 'future_week/zodiac_love_future_week_view.dart';
 
@@ -21,6 +27,13 @@ class ZodiacLoveIntimacyPage extends BasePage<ZodiacLoveIntimacyController> {
   const ZodiacLoveIntimacyPage({super.key});
 
   static start() {
+    var accountRepository = getIt.get<AccountRepository>();
+    // 如果用户未设置生日,则要求先设置生日,才能跳转
+    if (accountRepository.userInfo.value?.birthday == null) {
+      ToastUtil.show(StringName.userNotSetBirthdayTip);
+      UserProfilePage.start();
+      return;
+    }
     Get.toNamed(RoutePath.zodiacLoveIntimacy);
   }
 
@@ -203,8 +216,8 @@ class ZodiacLoveIntimacyPage extends BasePage<ZodiacLoveIntimacyController> {
   Widget _buildContent(BuildContext context) {
     return Column(
       children: [
-        // 顶部概览
-        _buildOverviewHeader(),
+        // 顶部基础信息
+        _buildTopBasicInfoHeader(),
         // TabBar
         _buildTabBar(),
         // PageView
@@ -213,9 +226,179 @@ class ZodiacLoveIntimacyPage extends BasePage<ZodiacLoveIntimacyController> {
     );
   }
 
-  /// 顶部概览视图
-  Widget _buildOverviewHeader() {
-    return Container(height: 270.h);
+  /// 顶部基础信息视图
+  Widget _buildTopBasicInfoHeader() {
+    return Column(
+      mainAxisAlignment: MainAxisAlignment.center,
+      crossAxisAlignment: CrossAxisAlignment.center,
+      children: [
+        SizedBox(height: 70.w),
+        // 头像布局
+        _buildAvatarLayout(),
+        SizedBox(height: 14.w),
+        // 星座梗语与解读
+        _buildZodiacDesc(),
+        SizedBox(height: 16.w),
+      ],
+    );
+  }
+
+  /// 头像布局
+  Widget _buildAvatarLayout() {
+    return Obx(() {
+      String? myAvatar =
+          controller.zodiacLoveIntimacyLoveInfoResponse.value?.imageUrl ?? "";
+      if (myAvatar.isEmpty) {
+        myAvatar = controller.userInfo.value?.imageUrl ?? "";
+      }
+      return Row(
+        mainAxisAlignment: MainAxisAlignment.center,
+        children: [
+          // 我的头像
+          _buildAvatarAndZodiac(
+            imageUrl: myAvatar,
+            zodiac: controller.myZodiacInfo,
+          ),
+          // 爱心动画
+          Lottie.asset(
+            Assets.anim.animNewUserData,
+            repeat: true,
+            width: 131.w,
+            fit: BoxFit.contain,
+          ),
+          // Ta的头像
+          _buildAvatarAndZodiac(
+            imageUrl:
+                controller
+                    .zodiacLoveIntimacyLoveInfoResponse
+                    .value
+                    ?.targetImageUrl,
+            zodiac: controller.taZodiacInfo,
+          ),
+        ],
+      );
+    });
+  }
+
+  /// 头像和星座
+  Widget _buildAvatarAndZodiac({
+    required String? imageUrl,
+    required Zodiac? zodiac,
+  }) {
+    return Column(
+      children: [
+        SizedBox(height: 20.w),
+        // 头像
+        CircleAvatarWidget(
+          image: Assets.images.iconKeyboardDefaultAvatar.provider(),
+          imageUrl: imageUrl,
+          size: 88.w,
+          borderColor: Colors.white,
+          borderWidth: 2.r,
+          placeholder: (_, __) => const SizedBox.shrink(),
+        ),
+        SizedBox(height: 14.w),
+        // 星座
+        Builder(
+          builder: (context) {
+            if (zodiac != null) {
+              return Row(
+                children: [
+                  zodiac.image.image(width: 14.w, height: 14.w),
+                  SizedBox(width: 4.w),
+                  Text(
+                    zodiac.name,
+                    style: TextStyle(
+                      color: Colors.white,
+                      fontSize: 15.sp,
+                      fontWeight: FontWeight.w700,
+                    ),
+                  ),
+                ],
+              );
+            } else {
+              return const SizedBox.shrink();
+            }
+          },
+        ),
+      ],
+    );
+  }
+
+  /// 星座梗语与解读
+  Widget _buildZodiacDesc() {
+    return Obx(() {
+      var info = controller.zodiacLoveIntimacyLoveInfoResponse.value;
+      var meme = info?.meme ?? "";
+      var explain = info?.explain ?? "";
+      if (meme.isEmpty || explain.isEmpty) {
+        return SizedBox(height: 67.h);
+      }
+      return Container(
+        width: double.infinity,
+        margin: EdgeInsets.symmetric(horizontal: 30.w),
+        child: Stack(
+          alignment: Alignment.center,
+          children: [
+            Positioned(
+              child: Container(
+                alignment: Alignment.center,
+                padding: EdgeInsets.symmetric(vertical: 8.w),
+                decoration: ShapeDecoration(
+                  color: const Color(0x29B80081),
+                  shape: RoundedRectangleBorder(
+                    borderRadius: BorderRadius.circular(16.r),
+                  ),
+                ),
+                child: Column(
+                  children: [
+                    // 梗语标题
+                    Text(
+                      meme,
+                      style: TextStyle(
+                        color: ColorName.white,
+                        fontSize: 12.sp,
+                        fontWeight: FontWeight.w500,
+                      ),
+                    ),
+                    SizedBox(height: 2.h),
+                    // 星座梗语
+                    Text(
+                      explain,
+                      style: TextStyle(
+                        color: ColorName.white,
+                        fontSize: 12.sp,
+                        fontWeight: FontWeight.w500,
+                      ),
+                    ),
+                  ],
+                ),
+              ),
+            ),
+            // 左上角的逗号
+            Positioned(
+              top: 5.w,
+              left: 8.w,
+              child: Assets.images.iconNewUserZodiacLeft.image(
+                width: 13.w,
+                height: 13.w,
+                fit: BoxFit.contain,
+              ),
+            ),
+            // 右下角的逗号
+            Positioned(
+              right: 8.w,
+              bottom: 5.w,
+              child: Assets.images.iconNewUserZodiacRight.image(
+                width: 13.w,
+                height: 13.w,
+                fit: BoxFit.contain,
+              ),
+            ),
+          ],
+        ),
+      );
+    });
   }
 
   /// PageView

+ 2 - 0
lib/resource/string.gen.dart

@@ -54,6 +54,7 @@ class StringName {
   static final String userInfo = 'user_info'.tr; // 用户信息
   static final String personalInfo = 'personal_info'.tr; // 个人信息
   static final String logout = 'logout'.tr; // 退出登录
+  static final String userNotSetBirthdayTip = 'user_not_set_birthday_tip'.tr; // 请先设置生日
   static final String feedbackContentTitle = 'feedback_content_title'.tr; // 问题描述
   static final String feedbackContentHint = 'feedback_content_hint'.tr; // 请描述您的问题或建议,或者您可以联系我们在线客服
   static final String feedbackPhone = 'feedback_phone'.tr; // 联系电话
@@ -412,6 +413,7 @@ class StringMultiSource {
       'user_info': '用户信息',
       'personal_info': '个人信息',
       'logout': '退出登录',
+      'user_not_set_birthday_tip': '请先设置生日',
       'feedback_content_title': '问题描述',
       'feedback_content_hint': '请描述您的问题或建议,或者您可以联系我们在线客服',
       'feedback_phone': '联系电话',