3 Коммиты f1c319555f ... c26ff93d01

Автор SHA1 Сообщение Дата
  liukai c26ff93d01 Merge remote-tracking branch 'origin/dev' into dev 1 неделя назад
  liukai 49fc1baad1 编辑用户信息与头像编辑弹窗 1 неделя назад
  liukai 575cf404d0 反馈的创建与详情 1 неделя назад
59 измененных файлов с 1742 добавлено и 74 удалено
  1. 253 0
      packages/cpt_main/lib/modules/feedback/create/feedback_create_page.dart
  2. 54 0
      packages/cpt_main/lib/modules/feedback/create/feedback_create_state.dart
  3. 103 0
      packages/cpt_main/lib/modules/feedback/create/feedback_create_view_model.dart
  4. 27 0
      packages/cpt_main/lib/modules/feedback/create/feedback_create_view_model.g.dart
  5. 74 0
      packages/cpt_main/lib/modules/feedback/create_success/feedback_create_success_page.dart
  6. 215 0
      packages/cpt_main/lib/modules/feedback/detail/feedback_detail_page.dart
  7. 18 0
      packages/cpt_main/lib/modules/feedback/detail/feedback_detail_state.dart
  8. 15 0
      packages/cpt_main/lib/modules/feedback/detail/feedback_detail_view_model.dart
  9. 27 0
      packages/cpt_main/lib/modules/feedback/detail/feedback_detail_view_model.g.dart
  10. 4 1
      packages/cpt_main/lib/modules/feedback/history/feedback_history.dart
  11. 2 1
      packages/cpt_main/lib/modules/feedback/item_feedback.dart
  12. 4 1
      packages/cpt_main/lib/modules/feedback/progress/feedback_progress.dart
  13. 2 1
      packages/cpt_main/lib/modules/feedback/send/feedback_send_large.dart
  14. 3 1
      packages/cpt_main/lib/modules/feedback/send/feedback_send_small.dart
  15. 3 3
      packages/cpt_main/lib/modules/me/me_view_model.dart
  16. 10 19
      packages/cpt_main/lib/modules/visitor/register/visitor_register_page.dart
  17. 0 6
      packages/cpt_main/lib/modules/visitor/register/visitor_register_state.dart
  18. 1 3
      packages/cpt_main/lib/modules/visitor/register/visitor_register_view_model.dart
  19. 1 1
      packages/cpt_main/lib/modules/visitor/register/visitor_register_view_model.g.dart
  20. 6 0
      packages/cpt_main/lib/router/page/main_page_router.dart
  21. 60 0
      packages/cpt_main/lib/router/page/main_page_router.gr.dart
  22. 32 0
      packages/cpt_profile/lib/modules/my_estate/my_estate_page.dart
  23. 3 0
      packages/cpt_profile/lib/modules/my_estate/my_estate_state.dart
  24. 13 0
      packages/cpt_profile/lib/modules/my_estate/my_estate_view_model.dart
  25. 26 0
      packages/cpt_profile/lib/modules/my_estate/my_estate_view_model.g.dart
  26. 32 0
      packages/cpt_profile/lib/modules/my_household/my_household_page.dart
  27. 3 0
      packages/cpt_profile/lib/modules/my_household/my_household_state.dart
  28. 13 0
      packages/cpt_profile/lib/modules/my_household/my_household_view_model.dart
  29. 27 0
      packages/cpt_profile/lib/modules/my_household/my_household_view_model.g.dart
  30. 210 4
      packages/cpt_profile/lib/modules/profile_edit/Profile_edit_page.dart
  31. 133 0
      packages/cpt_profile/lib/modules/profile_edit/dialog/avatar_edit_dialog.dart
  32. 49 0
      packages/cpt_profile/lib/modules/profile_edit/profile_edit_state.dart
  33. 56 3
      packages/cpt_profile/lib/modules/profile_edit/profile_edit_view_model.dart
  34. 4 4
      packages/cpt_profile/lib/modules/profile_edit/profile_edit_view_model.g.dart
  35. 1 1
      packages/cpt_profile/lib/modules/reset_password/reset_password_view_model.g.dart
  36. 1 1
      packages/cpt_profile/lib/modules/setting/setting_view_model.g.dart
  37. 8 8
      packages/cpt_profile/lib/router/component/profile_component_service_impl.dart
  38. 4 0
      packages/cpt_profile/lib/router/page/profile_page_router.dart
  39. 40 0
      packages/cpt_profile/lib/router/page/profile_page_router.gr.dart
  40. 1 0
      packages/cs_plugin_platform/lib/engine/image/image_nine_grid.dart
  41. 2 1
      packages/cs_plugin_platform/lib/platform_export.dart
  42. BIN
      packages/cs_resources/assets/profile/edit_dialog_delete.webp
  43. BIN
      packages/cs_resources/assets/profile/edit_dialog_upload.webp
  44. BIN
      packages/cs_resources/assets/profile/edit_profile_add.webp
  45. BIN
      packages/cs_resources/assets/profile/edit_profile_avatar_bottom.webp
  46. BIN
      packages/cs_resources/assets/profile/edit_profile_avatar_default.webp
  47. BIN
      packages/cs_resources/assets/profile/edit_xu_line.webp
  48. 6 0
      packages/cs_resources/lib/generated/assets.dart
  49. 11 2
      packages/cs_resources/lib/generated/intl/messages_en.dart
  50. 9 2
      packages/cs_resources/lib/generated/intl/messages_zh_CN.dart
  51. 9 2
      packages/cs_resources/lib/generated/intl/messages_zh_HK.dart
  52. 72 2
      packages/cs_resources/lib/generated/l10n.dart
  53. 8 1
      packages/cs_resources/lib/l10n/intl_en.arb
  54. 8 1
      packages/cs_resources/lib/l10n/intl_zh_CN.arb
  55. 8 1
      packages/cs_resources/lib/l10n/intl_zh_HK.arb
  56. 6 0
      packages/cs_resources/lib/theme/app_colors_theme.dart
  57. 1 0
      packages/cs_resources/pubspec.yaml
  58. 0 4
      packages/cs_router/lib/componentRouter/profile_service.dart
  59. 64 0
      packages/cs_widgets/lib/shatter/picker_container.dart

+ 253 - 0
packages/cpt_main/lib/modules/feedback/create/feedback_create_page.dart

@@ -0,0 +1,253 @@
+import 'package:cpt_main/modules/feedback/create/feedback_create_state.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:flutter_hooks/flutter_hooks.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_platform/engine/image/image_nine_grid.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_text_field.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/shatter/form_require_text.dart';
+import 'package:widgets/shatter/picker_container.dart';
+import 'package:widgets/widget_export.dart';
+import '../../../router/page/main_page_router.dart';
+import 'feedback_create_view_model.dart';
+
+@RoutePage()
+class FeedbackCreatePage extends HookConsumerWidget {
+  const FeedbackCreatePage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const FeedbackCreatePageRoute());
+    } else {
+      appRouter.push(const FeedbackCreatePageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(feedbackCreateViewModelProvider.notifier);
+    final state = ref.watch(feedbackCreateViewModelProvider);
+    final noteCount = useState(0);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(context, S.current.create_new_feedback),
+      backgroundColor: context.appColors.whiteBG,
+      body: SingleChildScrollView(
+        scrollDirection: Axis.vertical,
+        physics: const BouncingScrollPhysics(),
+        child: Container(
+          margin: const EdgeInsets.symmetric(horizontal: 15),
+          width: double.infinity,
+          child: Column(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              //选择类型
+              FormRequireText(
+                text: S.current.full_name,
+                textColor: context.appColors.textBlack,
+                fontSize: 17,
+              ).marginOnly(top: 14.5),
+              // 选择器
+              PickerContainer(
+                content: state.selectedOption ?? "",
+                hint: S.current.choose_category,
+                margin: const EdgeInsets.only(top: 16),
+                onClick: viewModel.pickCategory,
+              ),
+
+              //Title
+              FormRequireText(
+                text: S.current.title,
+                textColor: context.appColors.textBlack,
+                fontSize: 17,
+              ).marginOnly(top: 14.5),
+              // 表单
+              _buildInputLayout(
+                context,
+                state,
+                "title",
+                marginTop: 16,
+                textInputType: TextInputType.text,
+                textInputAction: TextInputAction.next,
+                errorText: state.titleErrorText,
+                onSubmit: (formKey, value) {
+                  state.formData[formKey]!['focusNode'].unfocus();
+                  FocusScope.of(context).requestFocus(state.formData['desc']!['focusNode']);
+                },
+              ),
+
+              // DESC
+              MyTextView(
+                S.current.describe_your_feedback,
+                textColor: context.appColors.textBlack,
+                fontSize: 17,
+                marginTop: 14.5,
+                isFontMedium: true,
+              ),
+              //大文本框
+              IgnoreKeyboardDismiss(
+                child: Container(
+                  height: 177,
+                  margin: const EdgeInsets.only(top: 16),
+                  padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 15),
+                  decoration: BoxDecoration(
+                    color: context.appColors.authFiledBG,
+                    borderRadius: const BorderRadius.all(Radius.circular(5)),
+                  ),
+                  child: Stack(
+                    children: [
+                      TextField(
+                        cursorColor: context.appColors.authFiledText,
+                        cursorWidth: 1.5,
+                        autofocus: false,
+                        enabled: true,
+                        focusNode: state.formData["desc"]!['focusNode'],
+                        controller: state.formData["desc"]!['controller'],
+                        decoration: InputDecoration(
+                          isDense: true,
+                          isCollapsed: true,
+                          border: InputBorder.none,
+                          hintText: state.formData["desc"]!['hintText'],
+                          hintStyle: TextStyle(
+                            color: context.appColors.authFiledHint,
+                            fontSize: 16.0,
+                            fontWeight: FontWeight.w500,
+                          ),
+                        ),
+                        style: TextStyle(
+                          color: context.appColors.authFiledText,
+                          fontSize: 16.0,
+                          fontWeight: FontWeight.w500,
+                        ),
+                        textInputAction: TextInputAction.done,
+                        onSubmitted: (value) {
+                          FocusScope.of(context).unfocus();
+                        },
+                        maxLines: null,
+                        expands: true,
+                        onChanged: (text) {
+                          // 当文本改变时,更新字符数量
+                          noteCount.value = text.length;
+                        },
+                      ),
+                      Positioned(
+                        bottom: 0.0,
+                        right: 0.0,
+                        child: Text(
+                          S.current.characters(noteCount.value),
+                          style: TextStyle(
+                            color: context.appColors.textBlack,
+                            fontSize: 15.0,
+                          ),
+                        ),
+                      ),
+                    ],
+                  ),
+                ),
+              ),
+
+              MyTextView(
+                S.current.upload_pictures,
+                textColor: context.appColors.textBlack,
+                fontSize: 17,
+                marginTop: 14.5,
+                isFontMedium: true,
+              ),
+
+              MyTextView(
+                S.current.up_to_max_images,
+                fontSize: 13,
+                marginTop: 5,
+                marginBottom: 14,
+                isFontRegular: true,
+                textColor: context.appColors.textDarkGray999,
+              ),
+
+              ImageNineGrid(
+                isSelectEnable: true,
+                maxImages: 10,
+                spacing: 10,
+                aspectRatio: 108 / 80,
+                initialImages: state.imgList,
+                onImagesChanged: (list) {
+                  viewModel.setImgList(list);
+                },
+              ),
+
+              MyButton(
+                onPressed: viewModel.submitFeedback,
+                text: S.current.submit,
+                textColor: Colors.white,
+                backgroundColor: context.appColors.btnBgDefault,
+                fontWeight: FontWeight.w500,
+                type: ClickType.throttle,
+                fontSize: 16,
+                minHeight: 50,
+                radius: 5,
+              ).marginOnly(top: 25, bottom: 25),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+
+  /// 输入框
+  Widget _buildInputLayout(
+    BuildContext context,
+    FeedbackCreateState state,
+    String key, {
+    double marginTop = 0,
+    bool? showRightIcon = false, //是否展示右侧的布局
+    Widget? rightWidget, //右侧的布局
+    TextInputType textInputType = TextInputType.text,
+    String? errorText,
+    bool obscureText = false,
+    bool enable = true,
+    TextInputAction textInputAction = TextInputAction.done,
+    Function? onSubmit,
+  }) {
+    return IgnoreKeyboardDismiss(
+      child: MyTextField(
+        key,
+        fillBackgroundColor: context.appColors.authFiledBG,
+        state.formData[key]!['value'],
+        hintStyle: TextStyle(
+          color: context.appColors.authFiledHint,
+          fontSize: 16.0,
+          fontWeight: FontWeight.w500,
+        ),
+        controller: state.formData[key]!['controller'],
+        focusNode: state.formData[key]!['focusNode'],
+        margin: EdgeInsets.only(top: marginTop),
+        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
+        showDivider: false,
+        height: 44,
+        enabled: enable,
+        style: TextStyle(
+          color: context.appColors.authFiledText,
+          fontSize: 16.0,
+          fontWeight: FontWeight.w500,
+        ),
+        inputType: textInputType,
+        textInputAction: textInputAction,
+        onSubmit: onSubmit,
+        cursorColor: context.appColors.authFiledText,
+        obscureText: obscureText,
+        errorText: errorText,
+        showLeftIcon: true,
+        showRightIcon: showRightIcon,
+        rightWidget: rightWidget,
+      ),
+    );
+  }
+}

+ 54 - 0
packages/cpt_main/lib/modules/feedback/create/feedback_create_state.dart

@@ -0,0 +1,54 @@
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:flutter/material.dart';
+
+class FeedbackCreateState {
+//表单的校验与数据
+  final Map<String, Map<String, dynamic>> formData;
+
+  //表单的错误信息展示
+  String? titleErrorText;
+
+  //类型选项
+  final List<String> optionList = ["条件1", "条件2", "条件3", "条件4"];
+  String? selectedOption;
+
+  //选择的图片
+  List<String> imgList;
+
+  // ===================================  Begin  ↓  ===================================
+
+  FeedbackCreateState({
+    Map<String, Map<String, dynamic>>? formData,
+    this.titleErrorText,
+    required this.imgList,
+    this.selectedOption,
+  }) : formData = formData ??
+            {
+              'title': {
+                'value': '',
+                'controller': TextEditingController(),
+                'focusNode': FocusNode(),
+                'obsecure': false,
+              },
+              'desc': {
+                'value': '',
+                'controller': TextEditingController(),
+                'focusNode': FocusNode(),
+                'hintText': S.current.type_here,
+                'obsecure': false,
+              },
+            };
+
+  FeedbackCreateState copyWith({
+    String? titleErrorText,
+    String? selectedOption,
+    List<String>? imgList,
+  }) {
+    return FeedbackCreateState(
+      formData: this.formData,
+      titleErrorText: titleErrorText,
+      imgList: imgList ?? this.imgList,
+      selectedOption: selectedOption ?? this.selectedOption,
+    );
+  }
+}

+ 103 - 0
packages/cpt_main/lib/modules/feedback/create/feedback_create_view_model.dart

@@ -0,0 +1,103 @@
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:shared/utils/util.dart';
+import 'package:widgets/picker/option_pick_util.dart';
+
+import '../../main/main_page.dart';
+import '../create_success/feedback_create_success_page.dart';
+import 'feedback_create_state.dart';
+
+part 'feedback_create_view_model.g.dart';
+
+@riverpod
+class FeedbackCreateViewModel extends _$FeedbackCreateViewModel {
+  @override
+  FeedbackCreateState build() {
+    final state = FeedbackCreateState(imgList: []);
+    initListener(state);
+    ref.onDispose(() {
+      onDispose(state);
+    });
+
+    return state;
+  }
+
+  //选择选项
+  void pickCategory() {
+    _dismissKeyboard();
+
+    OptionPickerUtil.showCupertinoOptionPicker(
+      items: state.optionList,
+      initialSelectIndex: 0,
+      onPickerChanged: (_, index) {
+        state = state.copyWith(selectedOption: state.optionList[index]);
+      },
+    );
+  }
+
+  void _dismissKeyboard() {
+    final FocusNode titleFocusNode = state.formData['title']!['focusNode'];
+    final FocusNode descFocusNode = state.formData['desc']!['focusNode'];
+    titleFocusNode.unfocus();
+    descFocusNode.unfocus();
+  }
+
+  ///提交反馈
+  void submitFeedback() {
+    state = state.copyWith(titleErrorText: null);
+
+    _dismissKeyboard();
+
+    final TextEditingController titleController = state.formData['title']!['controller'];
+    final TextEditingController descController = state.formData['desc']!['controller'];
+
+    final title = titleController.text;
+    final desc = descController.text;
+
+    Log.d('当前待提交的 option:${state.selectedOption} title:$title desc:$desc imgList:${state.imgList}');
+
+    if (Utils.isEmpty(state.selectedOption)) {
+      ToastEngine.show(S.current.choose_category);
+      return;
+    }
+
+    if (Utils.isEmpty(title)) {
+      state = state.copyWith(titleErrorText: "Title cannot be empty!");
+      return;
+    }
+
+    //执行密码登录
+    ToastEngine.show('准备执行请求 option:${state.selectedOption} title:$title desc:$desc imgList:${state.imgList}');
+
+    //去成功页面
+    FeedbackCreateSuccessPage.startInstance();
+  }
+
+  //选中图片
+  void setImgList(List<String> list) {
+    state = state.copyWith(imgList: list);
+  }
+
+  //初始化监听
+  void initListener(FeedbackCreateState initState) {
+    final FocusNode titleFocusNode = initState.formData['title']!['focusNode'];
+
+    titleFocusNode.addListener(() {
+      // 获取焦点的时候清空错误文本
+      if (titleFocusNode.hasFocus) {
+        state = state.copyWith(titleErrorText: null);
+      }
+    });
+  }
+
+  //销毁资源
+  void onDispose(FeedbackCreateState initState) {
+    final FocusNode titleFocusNode = initState.formData['title']!['focusNode'];
+    titleFocusNode.dispose();
+
+    Log.d("FeedbackCreateViewModel 销毁 onDispose");
+  }
+}

+ 27 - 0
packages/cpt_main/lib/modules/feedback/create/feedback_create_view_model.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'feedback_create_view_model.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$feedbackCreateViewModelHash() =>
+    r'fc34ceec68ee5e8a6175a9a3672a4ff2f60d4c61';
+
+/// See also [FeedbackCreateViewModel].
+@ProviderFor(FeedbackCreateViewModel)
+final feedbackCreateViewModelProvider = AutoDisposeNotifierProvider<
+    FeedbackCreateViewModel, FeedbackCreateState>.internal(
+  FeedbackCreateViewModel.new,
+  name: r'feedbackCreateViewModelProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$feedbackCreateViewModelHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$FeedbackCreateViewModel = AutoDisposeNotifier<FeedbackCreateState>;
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

+ 74 - 0
packages/cpt_main/lib/modules/feedback/create_success/feedback_create_success_page.dart

@@ -0,0 +1,74 @@
+import 'package:cpt_main/modules/demo_page.dart';
+import 'package:cpt_main/modules/main/main_page.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+import '../../../router/page/main_page_router.dart';
+
+@RoutePage()
+class FeedbackCreateSuccessPage extends HookConsumerWidget {
+  const FeedbackCreateSuccessPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.popAndPush(const FeedbackCreateSuccessPageRoute());
+    } else {
+      appRouter.popAndPush(const FeedbackCreateSuccessPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    return Scaffold(
+      appBar: MyAppBar.appBar(context, S.current.published_successfully),
+      backgroundColor: context.appColors.whiteBG,
+      body: Column(
+        children: [
+          Column(
+            mainAxisSize: MainAxisSize.min,
+            children: [
+              const MyAssetImage(Assets.mainSuccessIcon, width: 54, height: 54),
+              MyTextView(
+                S.current.published_successful_txt,
+                marginTop: 12,
+                marginLeft: 55,
+                textAlign: TextAlign.center,
+                marginRight: 55,
+                fontSize: 18,
+                textColor: context.appColors.textBlack,
+                isFontMedium: true,
+              ),
+            ],
+          ).marginOnly(top: 68),
+
+          const Spacer(),
+
+          MyButton(
+            onPressed: () {
+              MainPage.startInstance(context: context);
+            },
+            text: S.current.back_home,
+            textColor: Colors.white,
+            backgroundColor: context.appColors.btnBgDefault,
+            fontWeight: FontWeight.w500,
+            type: ClickType.throttle,
+            fontSize: 16,
+            minHeight: 50,
+            radius: 0,
+          )
+        ],
+      ),
+    );
+  }
+}

+ 215 - 0
packages/cpt_main/lib/modules/feedback/detail/feedback_detail_page.dart

@@ -0,0 +1,215 @@
+import 'package:cpt_main/modules/demo_page.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:plugin_platform/engine/image/image_nine_grid.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+import '../../../router/page/main_page_router.dart';
+import 'feedback_detail_view_model.dart';
+
+@RoutePage()
+class FeedbackDetailPage extends HookConsumerWidget {
+  const FeedbackDetailPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const FeedbackDetailPageRoute());
+    } else {
+      appRouter.push(const FeedbackDetailPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(feedbackDetailViewModelProvider.notifier);
+    final state = ref.watch(feedbackDetailViewModelProvider);
+
+    return Scaffold(
+      appBar: MyAppBar.appBar(context, S.current.feedback_details, showBottomDivider: true),
+      backgroundColor: context.appColors.backgroundDark,
+      body: SingleChildScrollView(
+          scrollDirection: Axis.vertical,
+          physics: const BouncingScrollPhysics(),
+          child: Column(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Container(
+                color: context.appColors.whiteBG,
+                width: double.infinity,
+                padding: const EdgeInsets.symmetric(horizontal: 10),
+                height: 85,
+                child: Column(
+                  mainAxisAlignment: MainAxisAlignment.center,
+                  mainAxisSize: MainAxisSize.max,
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  children: [
+                    MyTextView(
+                      "Exchange old houses for new ones",
+                      fontSize: 21,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                    ),
+                    MyTextView(
+                      "18 Sep 2024 18:00  |  Security  |  In Progress",
+                      fontSize: 12,
+                      marginTop: 8,
+                      isFontRegular: true,
+                      textColor: context.appColors.textDarkGray,
+                    ),
+                  ],
+                ),
+              ),
+
+              //反馈的内容
+              Container(
+                width: double.infinity,
+                margin: const EdgeInsets.only(left: 12.5, right: 12.5, top: 12.5, bottom: 12.5),
+                padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 25),
+                decoration: BoxDecoration(
+                  color: context.appColors.whiteBG,
+                  borderRadius: BorderRadius.circular(6.0), // 圆角
+                  boxShadow: [
+                    BoxShadow(
+                      color: const Color(0xFFB8BFD9).withOpacity(0.3), // 阴影颜色
+                      offset: const Offset(0, 3), // 阴影的偏移量
+                      blurRadius: 8.0, // 模糊半径
+                      spreadRadius: 3.0, // 扩散半径
+                    ),
+                  ],
+                ),
+                child: Column(
+                  children: [
+                    MyTextView(
+                      "Why are there no implementation rules andapplication methods for exchanging old houses for new ones in Jiang han District?",
+                      fontSize: 15,
+                      marginBottom: 15,
+                      isFontRegular: true,
+                      textColor: context.appColors.textDarkGray,
+                    ),
+
+                    //九宫格展示
+                    ImageNineGrid(
+                      isSelectEnable: false,
+                      maxImages: 10,
+                      spacing: 10,
+                      aspectRatio: 108 / 80,
+                      initialImages: const [
+                        "https://img1.baidu.com/it/u=2931243091,718249849&fm=253&fmt=auto&app=120&f=JPEG?w=569&h=427",
+                        "https://inews.gtimg.com/om_bt/OE8piEBa-tbqn-wNvWZl8coi4AlzoUD43upEkoAnIkYL8AA/641",
+                        "https://inews.gtimg.com/om_bt/OVx3YS2XJc1zbndGTkjPKW9J0W7kN8M0SIidT-3K4mb2YAA/641",
+                        "https://inews.gtimg.com/om_bt/OAVMydtx9BsJxf5i_thi4Oll9sR1px-Esmtv6UHSxoisEAA/641"
+                      ],
+                      onImagesChanged: (list) {},
+                    ),
+                  ],
+                ),
+              ),
+
+              //回复的数据
+              state.isReplyState ? _buildReplyWidget(context, ref) : _buildWaitingWidget(context)
+            ],
+          )),
+    );
+  }
+
+  Widget _buildReplyWidget(BuildContext context, WidgetRef ref) {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: [
+        Row(
+          mainAxisSize: MainAxisSize.max,
+          mainAxisAlignment: MainAxisAlignment.start,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: [
+            MyTextView(
+              S.current.administrator_reply,
+              fontSize: 18,
+              isFontRegular: true,
+              textColor: context.appColors.textBlack,
+            ).expanded(),
+            MyTextView(
+              "20 sep 2024 18:00",
+              fontSize: 12,
+              isFontRegular: true,
+              textColor: context.appColors.textDarkGray,
+            )
+          ],
+        ).marginOnly(left: 12.5, right: 12.5,bottom: 14,top: 2.5),
+
+        //回复的内容
+        Container(
+          width: double.infinity,
+          margin: const EdgeInsets.only(left: 12.5, right: 12.5, bottom: 13.5),
+          padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 25),
+          decoration: BoxDecoration(
+            color: context.appColors.whiteBG,
+            borderRadius: BorderRadius.circular(6.0), // 圆角
+            boxShadow: [
+              BoxShadow(
+                color: const Color(0xFFB8BFD9).withOpacity(0.3), // 阴影颜色
+                offset: const Offset(0, 3), // 阴影的偏移量
+                blurRadius: 8.0, // 模糊半径
+                spreadRadius: 3.0, // 扩散半径
+              ),
+            ],
+          ),
+          child: Column(
+            children: [
+              MyTextView(
+                "Although the policy of exchanging old houses for new houses in Jianghan District has been released, the specific implementation details and application methods are not yet clear. According to relevant reports, Jianghan District has issued multiple measures for the development of the real estate market, including promoting the trade in policy, but the specific implementation details and application methods have not vet been announced",
+                fontSize: 15,
+                marginBottom: 15,
+                isFontRegular: true,
+                textColor: context.appColors.textDarkGray,
+              ),
+
+              //九宫格展示
+              ImageNineGrid(
+                isSelectEnable: false,
+                maxImages: 10,
+                spacing: 10,
+                aspectRatio: 108 / 80,
+                initialImages: const [
+                  "https://img1.baidu.com/it/u=2931243091,718249849&fm=253&fmt=auto&app=120&f=JPEG?w=569&h=427",
+                  "https://inews.gtimg.com/om_bt/OVx3YS2XJc1zbndGTkjPKW9J0W7kN8M0SIidT-3K4mb2YAA/641",
+                  "https://inews.gtimg.com/om_bt/OAVMydtx9BsJxf5i_thi4Oll9sR1px-Esmtv6UHSxoisEAA/641"
+                ],
+                onImagesChanged: (list) {},
+              ),
+            ],
+          ),
+        )
+      ],
+    );
+  }
+
+  Widget _buildWaitingWidget(BuildContext context) {
+    return SizedBox(
+      width: double.infinity,
+      child: Column(
+        children: [
+          const SizedBox(height: 40),
+          const MyAssetImage(Assets.mainFeedbackWaitingIcon, width: 38, height: 38),
+          MyTextView(
+            S.current.waiting_for_the_administrator,
+            fontSize: 15,
+            marginTop: 11,
+            marginBottom: 40,
+            isFontRegular: true,
+            textColor: context.appColors.textDarkGray,
+          )
+        ],
+      ),
+    );
+  }
+}

+ 18 - 0
packages/cpt_main/lib/modules/feedback/detail/feedback_detail_state.dart

@@ -0,0 +1,18 @@
+class FeedbackDetailState{
+
+  //是等待状态还是已完成状态(是否已经回复)
+  bool isReplyState;
+
+  FeedbackDetailState({
+     this.isReplyState = false,
+  });
+
+  FeedbackDetailState copyWith({
+    bool? isReplyState,
+  }) {
+    return FeedbackDetailState(
+      isReplyState: isReplyState ?? this.isReplyState,
+    );
+  }
+
+}

+ 15 - 0
packages/cpt_main/lib/modules/feedback/detail/feedback_detail_view_model.dart

@@ -0,0 +1,15 @@
+
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+import 'feedback_detail_state.dart';
+part 'feedback_detail_view_model.g.dart';
+
+@riverpod
+class FeedbackDetailViewModel extends _$FeedbackDetailViewModel {
+
+  @override
+  FeedbackDetailState build(){
+    return FeedbackDetailState();
+  }
+
+}

+ 27 - 0
packages/cpt_main/lib/modules/feedback/detail/feedback_detail_view_model.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'feedback_detail_view_model.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$feedbackDetailViewModelHash() =>
+    r'c319af8c4d4805a867eb1f6481c9e6267e45cc5a';
+
+/// See also [FeedbackDetailViewModel].
+@ProviderFor(FeedbackDetailViewModel)
+final feedbackDetailViewModelProvider = AutoDisposeNotifierProvider<
+    FeedbackDetailViewModel, FeedbackDetailState>.internal(
+  FeedbackDetailViewModel.new,
+  name: r'feedbackDetailViewModelProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$feedbackDetailViewModelHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$FeedbackDetailViewModel = AutoDisposeNotifier<FeedbackDetailState>;
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

+ 4 - 1
packages/cpt_main/lib/modules/feedback/history/feedback_history.dart

@@ -7,6 +7,7 @@ import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
 
+import '../detail/feedback_detail_page.dart';
 import '../item_feedback.dart';
 import 'feedback_history_view_model.dart';
 
@@ -44,7 +45,9 @@ class FeedbackHistoryScreen extends HookConsumerWidget {
             SliverList(
                 delegate: SliverChildBuilderDelegate(
                       (context, index) {
-                    return FeedbackItem(index: index, item: state.datas[index]);
+                    return FeedbackItem(index: index, item: state.datas[index]).onTap((){
+                      FeedbackDetailPage.startInstance(context: context);
+                    });
                   },
                   childCount: state.datas.length,
                 ))

+ 2 - 1
packages/cpt_main/lib/modules/feedback/item_feedback.dart

@@ -39,6 +39,7 @@ class FeedbackItem extends StatelessWidget {
             children: [
               const MyAssetImage(Assets.mainFeedbackItemIcon, width: 42.5, height: 44),
               Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
                 children: [
 
                   MyTextView(
@@ -56,7 +57,7 @@ class FeedbackItem extends StatelessWidget {
                     isFontRegular: true,
                   ),
                 ],
-              ).expanded(),
+              ).marginOnly(left: 11).expanded(),
             ],
           ),
 

+ 4 - 1
packages/cpt_main/lib/modules/feedback/progress/feedback_progress.dart

@@ -7,6 +7,7 @@ import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/load_state_layout.dart';
 import 'package:widgets/widget_export.dart';
 
+import '../detail/feedback_detail_page.dart';
 import '../item_feedback.dart';
 import 'feedback_progress_view_model.dart';
 
@@ -44,7 +45,9 @@ class FeedbackProgressScreen extends HookConsumerWidget {
             SliverList(
                 delegate: SliverChildBuilderDelegate(
                       (context, index) {
-                    return FeedbackItem(index: index, item: state.datas[index]);
+                    return FeedbackItem(index: index, item: state.datas[index]).onTap((){
+                      FeedbackDetailPage.startInstance(context: context);
+                    });
                   },
                   childCount: state.datas.length,
                 ))

+ 2 - 1
packages/cpt_main/lib/modules/feedback/send/feedback_send_large.dart

@@ -1,3 +1,4 @@
+import 'package:cpt_main/modules/feedback/create/feedback_create_page.dart';
 import 'package:cs_resources/generated/assets.dart';
 import 'package:cs_resources/generated/l10n.dart';
 import 'package:cs_resources/theme/app_colors_theme.dart';
@@ -39,7 +40,7 @@ class FeedbackSendLarge extends StatelessWidget {
             ),
             MyButton(
               onPressed: () {
-                ToastEngine.show("去填写表单");
+                FeedbackCreatePage.startInstance(context: context);
               },
               text: S.current.create_new_feedback,
               textColor: Colors.white,

+ 3 - 1
packages/cpt_main/lib/modules/feedback/send/feedback_send_small.dart

@@ -8,6 +8,8 @@ import 'package:widgets/my_button.dart';
 import 'package:widgets/my_load_image.dart';
 import 'package:widgets/my_text_view.dart';
 
+import '../create/feedback_create_page.dart';
+
 class FeedbackSendSmall extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
@@ -36,7 +38,7 @@ class FeedbackSendSmall extends StatelessWidget {
           ),
           MyButton(
             onPressed: () {
-              ToastEngine.show("去填写表单");
+              FeedbackCreatePage.startInstance(context: context);
             },
             text: S.current.create_new_feedback,
             textColor: Colors.white,

+ 3 - 3
packages/cpt_main/lib/modules/me/me_view_model.dart

@@ -11,12 +11,12 @@ class MeViewModel extends _$MeViewModel {
 
   //去我的房产页面
   void gotoMyEstatePage() {
-    ToastEngine.show("去我的房产页面");
+    ComponentServiceManager().profileService.startMyEstatePage();
   }
 
   //去我的家庭成员页面
   void gotoMyHouseholdPage() {
-    ToastEngine.show("去我的家庭成员页面");
+    ComponentServiceManager().profileService.startMyHouseHoldPage();
   }
 
   //去我的发布页面
@@ -41,6 +41,6 @@ class MeViewModel extends _$MeViewModel {
 
   //编辑附加信息
   void gotoEditProfilePage() {
-    ToastEngine.show("编辑附加信息");
+    ComponentServiceManager().profileService.startEditProfilePage();
   }
 }

+ 10 - 19
packages/cpt_main/lib/modules/visitor/register/visitor_register_page.dart

@@ -7,6 +7,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/date_time_utils.dart';
 import 'package:widgets/ext/ex_widget.dart';
 import 'package:widgets/my_appbar.dart';
 import 'package:widgets/my_button.dart';
@@ -15,6 +16,7 @@ import 'package:widgets/my_text_view.dart';
 import 'package:widgets/widget_export.dart';
 import 'package:widgets/my_text_field.dart';
 import 'package:widgets/shatter/form_require_text.dart';
+import 'package:widgets/shatter/picker_container.dart';
 
 import '../../../router/page/main_page_router.dart';
 import 'visitor_register_state.dart';
@@ -38,7 +40,7 @@ class VisitorRegisterPage extends HookConsumerWidget {
     final viewModel = ref.watch(visitorRegisterViewModelProvider.notifier);
     final state = ref.watch(visitorRegisterViewModelProvider);
     final noteCount = useState(0);
-   
+
     return Scaffold(
       appBar: MyAppBar.appBar(context, S.current.visitor_registration),
       backgroundColor: context.appColors.whiteBG,
@@ -145,24 +147,13 @@ class VisitorRegisterPage extends HookConsumerWidget {
                 marginTop: 14.5,
                 isFontMedium: true,
               ),
-              // 表单
-              _buildInputLayout(
-                context,
-                state,
-                "access_date",
-                marginTop: 15,
-                enable: false,
-                textInputType: TextInputType.text,
-                textInputAction: TextInputAction.next,
-                showRightIcon: true,
-                rightWidget: const MyAssetImage(Assets.mainVisitorRegisterDate, width: 21, height: 20).paddingOnly(top: 13, bottom: 13),
-                onSubmit: (formKey, value) {
-                  state.formData[formKey]!['focusNode'].unfocus();
-                  FocusScope.of(context).requestFocus(state.formData['note']!['focusNode']);
-                },
-              ).onTap(() {
-                viewModel.pickAccessDate();
-              }),
+              // 选择器
+              PickerContainer(
+                content: state.accessDate == null ? "" : DateTimeUtils.formatDate(state.accessDate, format: 'dd MMM yyyy'),
+                margin: const EdgeInsets.only(top: 16),
+                rightWidget: const MyAssetImage(Assets.mainVisitorRegisterDate, width: 21, height: 20),
+                onClick: viewModel.pickAccessDate,
+              ),
 
               // 备注
               MyTextView(

+ 0 - 6
packages/cpt_main/lib/modules/visitor/register/visitor_register_state.dart

@@ -46,12 +46,6 @@ class VisitorRegisterState {
                 'focusNode': FocusNode(),
                 'obsecure': false,
               },
-              'access_date': {
-                'value': '',
-                'controller': TextEditingController(),
-                'focusNode': FocusNode(),
-                'obsecure': false,
-              },
               'note': {
                 'value': '',
                 'controller': TextEditingController(),

+ 1 - 3
packages/cpt_main/lib/modules/visitor/register/visitor_register_view_model.dart

@@ -76,7 +76,7 @@ class VisitorRegisterViewModel extends _$VisitorRegisterViewModel {
     }
 
     //执行密码登录
-    ToastEngine.show('准备执行请求发送验证码 fullName:$fullName phone:$phone nric:$nric plateNumber:$plateNumber note:$note accessDate:$accessDate');
+    ToastEngine.show('准备执行请求 fullName:$fullName phone:$phone nric:$nric plateNumber:$plateNumber note:$note accessDate:$accessDate');
 
     //去首页
     MainPage.startInstance();
@@ -89,8 +89,6 @@ class VisitorRegisterViewModel extends _$VisitorRegisterViewModel {
       mode: CupertinoDatePickerMode.date,
       onDateTimeChanged: (date) {
        state = state.copyWith(accessDate: date);
-       final TextEditingController accessDateController = state.formData['access_date']!['controller'];
-       accessDateController.text = DateTimeUtils.formatDate(date,format: 'dd MMM yyyy');
       },
       title: S.current.access_date,
     );

+ 1 - 1
packages/cpt_main/lib/modules/visitor/register/visitor_register_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'visitor_register_view_model.dart';
 // **************************************************************************
 
 String _$visitorRegisterViewModelHash() =>
-    r'efcd5105243eb7a8ec68d0ff5d428e7eb72fded0';
+    r'7ce971f03307d867b5069f6abff1a28ac4eea1eb';
 
 /// See also [VisitorRegisterViewModel].
 @ProviderFor(VisitorRegisterViewModel)

+ 6 - 0
packages/cpt_main/lib/router/page/main_page_router.dart

@@ -23,6 +23,9 @@ import '../../modules/home/latest_news/publish/latest_news_publish_screen.dart';
 import '../../modules/home/latest_news/latest_news_page.dart';
 import '../../modules/home/management_guides/management_guides_page.dart';
 import '../../modules/visitor/register/visitor_register_page.dart';
+import '../../modules/feedback/create/feedback_create_page.dart';
+import '../../modules/feedback/detail/feedback_detail_page.dart';
+import '../../modules/feedback/create_success/feedback_create_success_page.dart';
 
 part 'main_page_router.gr.dart';
 
@@ -75,5 +78,8 @@ class MainPageRouter extends _$MainPageRouter {
         ),
         CustomRoute(page: ManagementGuidesPageRoute.page, path: RouterPath.homeManagementGuides, transitionsBuilder: applySlideTransition),
         CustomRoute(page: VisitorRegisterPageRoute.page, path: RouterPath.visitorRegister, transitionsBuilder: applySlideTransition),
+        CustomRoute(page: FeedbackCreatePageRoute.page, path: RouterPath.feedbackCreate, transitionsBuilder: applySlideTransition),
+        CustomRoute(page: FeedbackCreateSuccessPageRoute.page, path: RouterPath.feedbackCreateSuccess, transitionsBuilder: applySlideTransition),
+        CustomRoute(page: FeedbackDetailPageRoute.page, path: RouterPath.feedbackDetail, transitionsBuilder: applySlideTransition),
       ];
 }

+ 60 - 0
packages/cpt_main/lib/router/page/main_page_router.gr.dart

@@ -15,6 +15,24 @@ abstract class _$MainPageRouter extends RootStackRouter {
 
   @override
   final Map<String, PageFactory> pagesMap = {
+    FeedbackCreatePageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const FeedbackCreatePage(),
+      );
+    },
+    FeedbackCreateSuccessPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const FeedbackCreateSuccessPage(),
+      );
+    },
+    FeedbackDetailPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const FeedbackDetailPage(),
+      );
+    },
     FeedbackHistoryPageRoute.name: (routeData) {
       return AutoRoutePage<dynamic>(
         routeData: routeData,
@@ -139,6 +157,48 @@ abstract class _$MainPageRouter extends RootStackRouter {
 }
 
 /// generated route for
+/// [FeedbackCreatePage]
+class FeedbackCreatePageRoute extends PageRouteInfo<void> {
+  const FeedbackCreatePageRoute({List<PageRouteInfo>? children})
+      : super(
+          FeedbackCreatePageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'FeedbackCreatePageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [FeedbackCreateSuccessPage]
+class FeedbackCreateSuccessPageRoute extends PageRouteInfo<void> {
+  const FeedbackCreateSuccessPageRoute({List<PageRouteInfo>? children})
+      : super(
+          FeedbackCreateSuccessPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'FeedbackCreateSuccessPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [FeedbackDetailPage]
+class FeedbackDetailPageRoute extends PageRouteInfo<void> {
+  const FeedbackDetailPageRoute({List<PageRouteInfo>? children})
+      : super(
+          FeedbackDetailPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'FeedbackDetailPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
 /// [FeedbackHistoryScreen]
 class FeedbackHistoryPageRoute extends PageRouteInfo<void> {
   const FeedbackHistoryPageRoute({List<PageRouteInfo>? children})

+ 32 - 0
packages/cpt_profile/lib/modules/my_estate/my_estate_page.dart

@@ -0,0 +1,32 @@
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import '../../router/page/profile_page_router.dart';
+import 'my_estate_view_model.dart';
+
+@RoutePage()
+class MyEstatePage extends HookConsumerWidget {
+  const MyEstatePage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const MyEstatePageRoute());
+    } else {
+      appRouter.push(const MyEstatePageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(myEstateViewModelProvider.notifier);
+
+    return Scaffold(
+      appBar: AppBar(title: Text("Profile Edit Page")),
+      body: Center(
+        child: Text("Profile Edit Page"),
+      ),
+    );
+  }
+}

+ 3 - 0
packages/cpt_profile/lib/modules/my_estate/my_estate_state.dart

@@ -0,0 +1,3 @@
+class MyEstateState{
+
+}

+ 13 - 0
packages/cpt_profile/lib/modules/my_estate/my_estate_view_model.dart

@@ -0,0 +1,13 @@
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+import 'my_estate_state.dart';
+
+part 'my_estate_view_model.g.dart';
+
+@riverpod
+class MyEstateViewModel extends _$MyEstateViewModel {
+  @override
+  MyEstateState build() {
+    return MyEstateState();
+  }
+}

+ 26 - 0
packages/cpt_profile/lib/modules/my_estate/my_estate_view_model.g.dart

@@ -0,0 +1,26 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'my_estate_view_model.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$myEstateViewModelHash() => r'417acd58452299add50bbc494cb459bed2cee139';
+
+/// See also [MyEstateViewModel].
+@ProviderFor(MyEstateViewModel)
+final myEstateViewModelProvider =
+    AutoDisposeNotifierProvider<MyEstateViewModel, MyEstateState>.internal(
+  MyEstateViewModel.new,
+  name: r'myEstateViewModelProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$myEstateViewModelHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$MyEstateViewModel = AutoDisposeNotifier<MyEstateState>;
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

+ 32 - 0
packages/cpt_profile/lib/modules/my_household/my_household_page.dart

@@ -0,0 +1,32 @@
+import 'package:flutter/material.dart';
+import 'package:auto_route/auto_route.dart';
+import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import '../../router/page/profile_page_router.dart';
+import 'my_household_view_model.dart';
+
+@RoutePage()
+class MyHouseholdPage extends HookConsumerWidget {
+  const MyHouseholdPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const MyHouseholdPageRoute());
+    } else {
+      appRouter.push(const MyHouseholdPageRoute());
+    }
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final viewModel = ref.watch(myHouseholdViewModelProvider.notifier);
+
+    return Scaffold(
+      appBar: AppBar(title: Text("Profile Edit Page")),
+      body: Center(
+        child: Text("Profile Edit Page"),
+      ),
+    );
+  }
+}

+ 3 - 0
packages/cpt_profile/lib/modules/my_household/my_household_state.dart

@@ -0,0 +1,3 @@
+class MyHouseholdState{
+
+}

+ 13 - 0
packages/cpt_profile/lib/modules/my_household/my_household_view_model.dart

@@ -0,0 +1,13 @@
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+import 'my_household_state.dart';
+
+part 'my_household_view_model.g.dart';
+
+@riverpod
+class MyHouseholdViewModel extends _$MyHouseholdViewModel {
+  @override
+  MyHouseholdState build() {
+    return MyHouseholdState();
+  }
+}

+ 27 - 0
packages/cpt_profile/lib/modules/my_household/my_household_view_model.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'my_household_view_model.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$myHouseholdViewModelHash() =>
+    r'c36b3e12799580cca04fcf02712c8d20c44d7841';
+
+/// See also [MyHouseholdViewModel].
+@ProviderFor(MyHouseholdViewModel)
+final myHouseholdViewModelProvider = AutoDisposeNotifierProvider<
+    MyHouseholdViewModel, MyHouseholdState>.internal(
+  MyHouseholdViewModel.new,
+  name: r'myHouseholdViewModelProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$myHouseholdViewModelHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$MyHouseholdViewModel = AutoDisposeNotifier<MyHouseholdState>;
+// ignore_for_file: type=lint
+// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

+ 210 - 4
packages/cpt_profile/lib/modules/profile_edit/Profile_edit_page.dart

@@ -1,9 +1,20 @@
+import 'package:cpt_profile/modules/profile_edit/profile_edit_state.dart';
 import 'package:cpt_profile/modules/profile_edit/profile_edit_view_model.dart';
 import 'package:cpt_profile/router/page/profile_page_router.dart';
+import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
 import 'package:flutter/material.dart';
 import 'package:auto_route/auto_route.dart';
 import 'package:hooks_riverpod/hooks_riverpod.dart';
 import 'package:router/ext/auto_router_extensions.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_appbar.dart';
+import 'package:widgets/my_button.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_field.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/widget_export.dart';
 
 @RoutePage()
 class ProfileEditPage extends HookConsumerWidget {
@@ -20,12 +31,207 @@ class ProfileEditPage extends HookConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    final _viewModel = ref.watch(profileEditViewModelProvider.notifier);
+    final viewModel = ref.watch(profileEditViewModelProvider.notifier);
+    final state = ref.watch(profileEditViewModelProvider);
 
     return Scaffold(
-      appBar: AppBar(title: Text("Profile Edit Page")),
-      body: Center(
-        child: Text("Profile Edit Page"),
+      appBar: MyAppBar.appBar(context, S.current.edit_profile,backgroundColor: context.appColors.whiteBG),
+      backgroundColor: context.appColors.backgroundDefault,
+      body: SingleChildScrollView(
+        scrollDirection: Axis.vertical,
+        physics: const BouncingScrollPhysics(),
+        child: Container(
+          margin: const EdgeInsets.symmetric(horizontal: 15),
+          width: double.infinity,
+          child: Column(
+            mainAxisSize: MainAxisSize.max,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Center(
+                child: Container(
+                  width: 80,
+                  height: 80,
+                  decoration: BoxDecoration(color: context.appColors.avatarBg, shape: BoxShape.circle),
+                  child: Stack(
+                    children: [
+                      //默认的占位图
+                      Visibility(
+                        visible: true,
+                        child: const Align(
+                          alignment: Alignment.bottomCenter,
+                          child: MyAssetImage(
+                            Assets.profileEditProfileAvatarDefault,
+                            width: 49,
+                            height: 64,
+                          ),
+                        ),
+                      ),
+
+                      //用户的头像
+                      Visibility(
+                        visible: false,
+                        child: MyLoadImage(
+                          "https://img1.baidu.com/it/u=1656098746,3560654086&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800",
+                          width: 80,
+                          height: 80,
+                          isCircle: true,
+                        ),
+                      ),
+
+                      //底部的背景色
+                      const Align(
+                        alignment: Alignment.bottomCenter,
+                        child: MyAssetImage(
+                          Assets.profileEditProfileAvatarBottom,
+                          width: 71,
+                          height: 21.5,
+                        ),
+                      ),
+                      //照相机Icon
+                      const Align(
+                        alignment: Alignment.bottomCenter,
+                        child: MyAssetImage(
+                          Assets.profileEditProfileAdd,
+                          width: 12,
+                          height: 11.5,
+                        ),
+                      ).marginOnly(bottom: 4),
+                    ],
+                  ),
+                ).onTap((){
+                  viewModel.showAvatarEditDialog(context);
+                }),
+              ).marginOnly(top: 23),
+
+              // 表单 - 名
+              MyTextView(
+                S.current.first_name,
+                fontSize: 17,
+                marginTop: 33,
+                marginBottom: 16,
+                isFontMedium: true,
+                textColor: context.appColors.textBlack,
+              ),
+              //表单
+              _buildInputLayout(
+                context,
+                state,
+                "first_name",
+                textInputType: TextInputType.text,
+                textInputAction: TextInputAction.next,
+                onSubmit: (formKey, value) {
+                  state.formData[formKey]!['focusNode'].unfocus();
+                  FocusScope.of(context).requestFocus(state.formData['last_name']!['focusNode']);
+                },
+              ),
+
+              // 表单 - 姓
+              MyTextView(
+                S.current.last_name,
+                fontSize: 17,
+                marginTop: 15,
+                marginBottom: 16,
+                isFontMedium: true,
+                textColor: context.appColors.textBlack,
+              ),
+              //表单
+              _buildInputLayout(
+                context,
+                state,
+                "last_name",
+                textInputType: TextInputType.text,
+                textInputAction: TextInputAction.next,
+                onSubmit: (formKey, value) {
+                  state.formData[formKey]!['focusNode'].unfocus();
+                  FocusScope.of(context).requestFocus(state.formData['email']!['focusNode']);
+                },
+              ),
+
+              // 表单 - 邮箱
+              MyTextView(
+                S.current.email,
+                fontSize: 17,
+                marginTop: 15,
+                marginBottom: 16,
+                isFontMedium: true,
+                textColor: context.appColors.textBlack,
+              ),
+              //表单
+              _buildInputLayout(
+                context,
+                state,
+                "email",
+                textInputType: TextInputType.emailAddress,
+                textInputAction: TextInputAction.next,
+                onSubmit: (formKey, value) {
+                  state.formData[formKey]!['focusNode'].unfocus();
+                },
+              ),
+
+              //提交
+              MyButton(
+                onPressed: viewModel.submitEdit,
+                text: S.current.submit,
+                textColor: Colors.white,
+                backgroundColor: context.appColors.btnBgDefault,
+                fontWeight: FontWeight.w500,
+                type: ClickType.throttle,
+                fontSize: 16,
+                minHeight: 50,
+                radius: 5,
+              ).marginOnly(top: 50, bottom: 50),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+
+  /// 输入框
+  Widget _buildInputLayout(
+    BuildContext context,
+    ProfileEditState state,
+    String key, {
+    double marginTop = 0,
+    bool? showRightIcon = false, //是否展示右侧的布局
+    Widget? rightWidget, //右侧的布局
+    TextInputType textInputType = TextInputType.text,
+    String? errorText,
+    bool obscureText = false,
+    TextInputAction textInputAction = TextInputAction.done,
+    Function? onSubmit,
+  }) {
+    return IgnoreKeyboardDismiss(
+      child: MyTextField(
+        key,
+        fillBackgroundColor: context.appColors.authFiledBG,
+        state.formData[key]!['value'],
+        hintText: state.formData[key]!['hintText'],
+        hintStyle: TextStyle(
+          color: context.appColors.authFiledHint,
+          fontSize: 16.0,
+          fontWeight: FontWeight.w500,
+        ),
+        controller: state.formData[key]!['controller'],
+        focusNode: state.formData[key]!['focusNode'],
+        margin: EdgeInsets.only(top: marginTop),
+        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 3),
+        showDivider: false,
+        height: 44,
+        style: TextStyle(
+          color: context.appColors.authFiledText,
+          fontSize: 16.0,
+          fontWeight: FontWeight.w500,
+        ),
+        inputType: textInputType,
+        textInputAction: textInputAction,
+        onSubmit: onSubmit,
+        cursorColor: context.appColors.authFiledText,
+        obscureText: obscureText,
+        errorText: errorText,
+        showLeftIcon: true,
+        showRightIcon: showRightIcon,
+        rightWidget: rightWidget,
       ),
     );
   }

+ 133 - 0
packages/cpt_profile/lib/modules/profile_edit/dialog/avatar_edit_dialog.dart

@@ -0,0 +1,133 @@
+import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+import 'package:widgets/widget_export.dart';
+
+class AvatarEditDialog extends StatelessWidget {
+  void Function(String path) otherAction;
+  void Function() photoAction;
+
+  final List<String> otherImages = [
+    "https://pic.rmb.bdstatic.com/bjh/bc3fcc5fadee3ab70dc6f941ae3eb4a21534.jpeg@h_1280",
+    "https://img0.baidu.com/it/u=3885044482,1194334042&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800",
+    "https://q0.itc.cn/q_70/images03/20240508/64f00aea4daa4b808e59fdadb939ff41.jpeg",
+    "https://ww3.sinaimg.cn/mw690/d315af46ly1h7wfnspdomj20u00u0tef.jpg",
+    "https://ww2.sinaimg.cn/mw690/006A8Z5cly1hrhndmtmuaj30he0htq55.jpg",
+    "https://ww1.sinaimg.cn/mw690/d315af46ly1h7wfnuxn91j20j60j60uk.jpg",
+    "https://img0.baidu.com/it/u=80291486,3068765574&fm=253&fmt=auto&app=138&f=JPEG?w=380&h=380",
+    "https://img0.baidu.com/it/u=528233043,1559727912&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500",
+    "https://img0.baidu.com/it/u=691481429,1364097496&fm=253&fmt=auto?w=500&h=500"
+  ];
+
+  AvatarEditDialog({
+    required this.photoAction,
+    required this.otherAction,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.center,
+      mainAxisAlignment: MainAxisAlignment.center,
+      children: [
+        Container(
+          width: double.infinity,
+          padding: const EdgeInsets.only(top: 31.5, bottom: 30.5, left: 27.5, right: 27.5),
+          decoration: BoxDecoration(
+            color: context.appColors.whiteBG,
+            borderRadius: const BorderRadius.all(Radius.circular(15)),
+          ),
+          child: Column(
+            mainAxisSize: MainAxisSize.min,
+            children: [
+              Container(
+                width: double.infinity,
+                height: 50,
+                decoration: const BoxDecoration(
+                  color: Color(0XFFE9ECF8),
+                  borderRadius: BorderRadius.all(Radius.circular(5)),
+                ),
+                child: Row(
+                  mainAxisSize: MainAxisSize.max,
+                  crossAxisAlignment: CrossAxisAlignment.center,
+                  mainAxisAlignment: MainAxisAlignment.center,
+                  children: [
+                    const MyAssetImage(
+                      Assets.profileEditDialogUpload,
+                      width: 27.5,
+                      height: 27.5,
+                    ),
+                    MyTextView(
+                      S.current.upload_a_photo, 
+                      fontSize: 16,
+                      isFontMedium: true,
+                      textColor: context.appColors.textBlack,
+                      marginLeft: 12,
+                    ),
+                  ],
+                ).onTap((){
+                  onCancel();
+                  photoAction.call();
+                }),
+              ),
+
+              //分割线
+              Stack(
+                children: [
+                  const MyAssetImage(Assets.profileEditXuLine, width: 270, height: 1).marginOnly(top: 10),
+                  Align(
+                    alignment: Alignment.center,
+                    child: MyTextView(
+                      S.current.or,
+                      textColor: context.appColors.textDarkGray,
+                      fontSize: 16,
+                      isFontMedium: true,
+                    ),
+                  ),
+                ],
+              ).marginOnly(top: 26, bottom: 6),
+
+              //图片九宫格
+              GridView.builder(
+                shrinkWrap: true,
+                physics: const NeverScrollableScrollPhysics(),
+                gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
+                  crossAxisCount: 3, // 每行显示的列数
+                  mainAxisSpacing: 20.0, // 主轴(上下)的间距
+                  crossAxisSpacing: 15.0, // 交叉轴(左右)的间距
+                  childAspectRatio: 1, // 宽高比例
+                ),
+                itemCount: otherImages.length,
+                itemBuilder: (context, index) {
+                  return Center(
+                    child: MyLoadImage(otherImages[index]).onTap((){
+                      onCancel();
+                      otherAction.call(otherImages[index]);
+                    }),
+                  );
+                },
+              ),
+            ],
+          ),
+        ),
+        const MyAssetImage(
+          Assets.profileEditDialogDelete,
+          width: 25,
+          height: 25.5,
+        ).onTap(() {
+          onCancel();
+        }).marginOnly(top: 23.5),
+      ],
+    ).constrained(width: 325);
+  }
+
+//取消弹框
+  void onCancel() async {
+    SmartDialog.dismiss();
+  }
+}

+ 49 - 0
packages/cpt_profile/lib/modules/profile_edit/profile_edit_state.dart

@@ -0,0 +1,49 @@
+import 'package:cs_resources/generated/l10n.dart';
+import 'package:flutter/material.dart';
+
+class ProfileEditState{
+  //表单的校验与数据
+  final Map<String, Map<String, dynamic>> formData;
+
+  String? avatarPath;  //头像的路径或Uri
+
+  // ===================================  Begin  ↓  ===================================
+
+  ProfileEditState({
+    Map<String, Map<String, dynamic>>? formData,
+    this.avatarPath,
+  }) : formData = formData ??
+      {
+        'first_name': {
+          'value': '',
+          'controller': TextEditingController(),
+          'hintText': S.current.first_name,
+          'focusNode': FocusNode(),
+          'obsecure': false,
+        },
+        'last_name': {
+          'value': '',
+          'controller': TextEditingController(),
+          'hintText': S.current.last_name,
+          'focusNode': FocusNode(),
+          'obsecure': false,
+        },
+        'email': {
+          'value': '',
+          'controller': TextEditingController(),
+          'hintText': S.current.email,
+          'focusNode': FocusNode(),
+          'obsecure': false,
+        },
+      };
+
+  ProfileEditState copyWith({
+    String? avatarPath,
+  }) {
+    return ProfileEditState(
+      formData: this.formData,
+      avatarPath: avatarPath ?? this.avatarPath,
+    );
+  }
+
+}

+ 56 - 3
packages/cpt_profile/lib/modules/profile_edit/profile_edit_view_model.dart

@@ -1,13 +1,66 @@
-
+import 'package:cpt_profile/modules/profile_edit/dialog/avatar_edit_dialog.dart';
+import 'package:flutter/material.dart';
+import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
 import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:router/ext/auto_router_extensions.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'profile_edit_state.dart';
+import 'package:plugin_platform/platform_export.dart';
+
 part 'profile_edit_view_model.g.dart';
 
 @riverpod
 class ProfileEditViewModel extends _$ProfileEditViewModel {
-
   @override
-  void build(){
+  ProfileEditState build() {
+    return ProfileEditState();
+  }
+
+  /// 提交编辑用户信息
+  void submitEdit() {
+    final FocusNode firstNameFocusNode = state.formData['first_name']!['focusNode'];
+    final FocusNode lastNameFocusNode = state.formData['last_name']!['focusNode'];
+    final FocusNode emailFocusNode = state.formData['email']!['focusNode'];
+
+    firstNameFocusNode.unfocus();
+    lastNameFocusNode.unfocus();
+    emailFocusNode.unfocus();
+
+    final TextEditingController firstNameController = state.formData['first_name']!['controller'];
+    final TextEditingController lastNameController = state.formData['last_name']!['controller'];
+    final TextEditingController emailController = state.formData['email']!['controller'];
 
+    final firstName = firstNameController.text;
+    final lastName = lastNameController.text;
+    final email = emailController.text;
+
+    Log.d('当前待提交的 firstName:$firstName lastName:$lastName email:$email');
+
+    //执行密码登录
+    ToastEngine.show('准备执行请求发送验证码 firstName:$firstName lastName:$lastName email:$email ');
+
+    appRouter.maybePop();
   }
 
+  //去编辑头像页面
+  void showAvatarEditDialog(BuildContext context) {
+    DialogEngine.show(
+        widget: AvatarEditDialog(
+      otherAction: (path) {
+        ToastEngine.show("点击了图片:$path");
+      },
+      photoAction: () {
+        //选择相机相册
+        _pickPhoto(context);
+      },
+    ));
+  }
+
+  //相机相册选择
+  void _pickPhoto(BuildContext context) {
+    ImagePickerUtils().show(context, (path) {
+      ToastEngine.show("选中了图片:$path");
+    });
+  }
 }

+ 4 - 4
packages/cpt_profile/lib/modules/profile_edit/profile_edit_view_model.g.dart

@@ -7,12 +7,12 @@ part of 'profile_edit_view_model.dart';
 // **************************************************************************
 
 String _$profileEditViewModelHash() =>
-    r'acfbe7986503c631d7107a9309c85e768b1067f2';
+    r'077ce4db8df95158eed8dfb5a207c1f472271d13';
 
 /// See also [ProfileEditViewModel].
 @ProviderFor(ProfileEditViewModel)
-final profileEditViewModelProvider =
-    AutoDisposeNotifierProvider<ProfileEditViewModel, void>.internal(
+final profileEditViewModelProvider = AutoDisposeNotifierProvider<
+    ProfileEditViewModel, ProfileEditState>.internal(
   ProfileEditViewModel.new,
   name: r'profileEditViewModelProvider',
   debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
@@ -22,6 +22,6 @@ final profileEditViewModelProvider =
   allTransitiveDependencies: null,
 );
 
-typedef _$ProfileEditViewModel = AutoDisposeNotifier<void>;
+typedef _$ProfileEditViewModel = AutoDisposeNotifier<ProfileEditState>;
 // ignore_for_file: type=lint
 // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package

+ 1 - 1
packages/cpt_profile/lib/modules/reset_password/reset_password_view_model.g.dart

@@ -7,7 +7,7 @@ part of 'reset_password_view_model.dart';
 // **************************************************************************
 
 String _$resetPasswordViewModelHash() =>
-    r'4b6b7ea5f180d679389a10da92758d39ea9f86e3';
+    r'909d66fe8a4977520cc6d2d5d0607e3d979a74b4';
 
 /// See also [ResetPasswordViewModel].
 @ProviderFor(ResetPasswordViewModel)

+ 1 - 1
packages/cpt_profile/lib/modules/setting/setting_view_model.g.dart

@@ -6,7 +6,7 @@ part of 'setting_view_model.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$settingViewModelHash() => r'e008ce2120bd069243f13ad1502eba8992950a63';
+String _$settingViewModelHash() => r'14220f4fbd357cfd7f80abccc4db5ec17814c539';
 
 /// See also [SettingViewModel].
 @ProviderFor(SettingViewModel)

+ 8 - 8
packages/cpt_profile/lib/router/component/profile_component_service_impl.dart

@@ -1,6 +1,8 @@
 /*
  * Profile 组件的组件路由
  */
+import 'package:cpt_profile/modules/my_estate/my_estate_page.dart';
+import 'package:cpt_profile/modules/my_household/my_household_page.dart';
 import 'package:cpt_profile/modules/setting/setting_page.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:router/componentRouter/profile_service.dart';
@@ -14,16 +16,14 @@ class ProfileComponentServiceImpl extends ProfileService {
   }
 
   @override
-  void startMyEstatePage({BuildContext? context}) {}
-
-  @override
-  void startMyFollowPage({BuildContext? context}) {}
-
-  @override
-  void startMyHouseHoldPage({BuildContext? context}) {}
+  void startMyEstatePage({BuildContext? context}) {
+    MyEstatePage.startInstance(context: context);
+  }
 
   @override
-  void startMyPostPage({BuildContext? context}) {}
+  void startMyHouseHoldPage({BuildContext? context}) {
+    MyHouseholdPage.startInstance(context: context);
+  }
 
   @override
   void startSettingPage({BuildContext? context}) {

+ 4 - 0
packages/cpt_profile/lib/router/page/profile_page_router.dart

@@ -7,6 +7,8 @@ import '../../modules/profile_edit/Profile_edit_page.dart';
 import '../../modules/setting/setting_page.dart';
 import '../../modules/change_mobile/change_mobile_page.dart';
 import '../../modules/reset_password/reset_password_page.dart';
+import '../../modules/my_estate/my_estate_page.dart';
+import '../../modules/my_household/my_household_page.dart';
 
 
 part 'profile_page_router.gr.dart';
@@ -23,5 +25,7 @@ class ProfilePageRouter extends _$ProfilePageRouter {
     CustomRoute(page: SettingPageRoute.page, path: RouterPath.settings, transitionsBuilder: applySlideTransition),
     CustomRoute(page: ChangeMobilePageRoute.page, path: RouterPath.settingsChangeMobile, transitionsBuilder: applySlideTransition),
     CustomRoute(page: ResetPasswordPageRoute.page, path: RouterPath.settingsResetPassword, transitionsBuilder: applySlideTransition),
+    CustomRoute(page: MyEstatePageRoute.page, path: RouterPath.profileEstate, transitionsBuilder: applySlideTransition),
+    CustomRoute(page: MyHouseholdPageRoute.page, path: RouterPath.profileHousehold, transitionsBuilder: applySlideTransition),
   ];
 }

+ 40 - 0
packages/cpt_profile/lib/router/page/profile_page_router.gr.dart

@@ -21,6 +21,18 @@ abstract class _$ProfilePageRouter extends RootStackRouter {
         child: const ChangeMobilePage(),
       );
     },
+    MyEstatePageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const MyEstatePage(),
+      );
+    },
+    MyHouseholdPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const MyHouseholdPage(),
+      );
+    },
     ProfileEditPageRoute.name: (routeData) {
       return AutoRoutePage<dynamic>(
         routeData: routeData,
@@ -57,6 +69,34 @@ class ChangeMobilePageRoute extends PageRouteInfo<void> {
 }
 
 /// generated route for
+/// [MyEstatePage]
+class MyEstatePageRoute extends PageRouteInfo<void> {
+  const MyEstatePageRoute({List<PageRouteInfo>? children})
+      : super(
+          MyEstatePageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'MyEstatePageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [MyHouseholdPage]
+class MyHouseholdPageRoute extends PageRouteInfo<void> {
+  const MyHouseholdPageRoute({List<PageRouteInfo>? children})
+      : super(
+          MyHouseholdPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'MyHouseholdPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
 /// [ProfileEditPage]
 class ProfileEditPageRoute extends PageRouteInfo<void> {
   const ProfileEditPageRoute({List<PageRouteInfo>? children})

+ 1 - 0
packages/cs_plugin_platform/lib/engine/image/image_nine_grid.dart

@@ -9,6 +9,7 @@ import 'package:widgets/my_text_view.dart';
 import 'image_preview.dart';
 import 'package:cs_resources/generated/l10n.dart';
 
+/// 九宫格的图片选择与图片展示
 class ImageNineGrid extends StatefulWidget {
   final bool isSelectEnable; // 是否能选择
   final List<String> initialImages; // 初始化图片集合

+ 2 - 1
packages/cs_plugin_platform/lib/platform_export.dart

@@ -1,3 +1,4 @@
 export 'package:dio/dio.dart';
 export 'package:permission_handler/permission_handler.dart';
-export 'engine/image/image_nine_grid.dart';
+export 'engine/image/image_nine_grid.dart';
+export 'engine/media/image_picker_utils.dart';

BIN
packages/cs_resources/assets/profile/edit_dialog_delete.webp


BIN
packages/cs_resources/assets/profile/edit_dialog_upload.webp


BIN
packages/cs_resources/assets/profile/edit_profile_add.webp


BIN
packages/cs_resources/assets/profile/edit_profile_avatar_bottom.webp


BIN
packages/cs_resources/assets/profile/edit_profile_avatar_default.webp


BIN
packages/cs_resources/assets/profile/edit_xu_line.webp


+ 6 - 0
packages/cs_resources/lib/generated/assets.dart

@@ -99,6 +99,12 @@ class Assets {
   static const String noticeBoardAnnouncementIcon = 'assets/notice_board/announcement_icon.png';
   static const String noticeBoardDocumentsIcon = 'assets/notice_board/documents_icon.png';
   static const String noticeBoardEventIcon = 'assets/notice_board/event_icon.png';
+  static const String profileEditDialogDelete = 'assets/profile/edit_dialog_delete.webp';
+  static const String profileEditDialogUpload = 'assets/profile/edit_dialog_upload.webp';
+  static const String profileEditProfileAdd = 'assets/profile/edit_profile_add.webp';
+  static const String profileEditProfileAvatarBottom = 'assets/profile/edit_profile_avatar_bottom.webp';
+  static const String profileEditProfileAvatarDefault = 'assets/profile/edit_profile_avatar_default.webp';
+  static const String profileEditXuLine = 'assets/profile/edit_xu_line.webp';
   static const String propertyAdvicePic = 'assets/property/advice_pic.webp';
   static const String propertyApproval = 'assets/property/approval.webp';
   static const String propertyCollection = 'assets/property/collection.webp';

+ 11 - 2
packages/cs_resources/lib/generated/intl/messages_en.dart

@@ -26,13 +26,13 @@ class MessageLookup extends MessageLookupByLibrary {
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
-        "Up_to_max_images": MessageLookupByLibrary.simpleMessage(
-            "(Up to 10 images can be uploaded)"),
         "access_date": MessageLookupByLibrary.simpleMessage("Access Date"),
         "account_deactivate_alert": MessageLookupByLibrary.simpleMessage(
             "Are you sure you want to deactivate your account? You will not be able to login into the app once you proceed with the request."),
         "account_deactivation":
             MessageLookupByLibrary.simpleMessage("Account Deactivation"),
+        "active": MessageLookupByLibrary.simpleMessage("ACTIVE"),
+        "add": MessageLookupByLibrary.simpleMessage("Add"),
         "administrator_reply":
             MessageLookupByLibrary.simpleMessage("Administrator Reply"),
         "agree_to": MessageLookupByLibrary.simpleMessage("Agree to"),
@@ -65,6 +65,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Describe Your FeedBack"),
         "did_not_receive":
             MessageLookupByLibrary.simpleMessage("Did Not Receive?"),
+        "edit_profile": MessageLookupByLibrary.simpleMessage("Edit Profile"),
         "email": MessageLookupByLibrary.simpleMessage("Email"),
         "enable_notification":
             MessageLookupByLibrary.simpleMessage("Enable Notification"),
@@ -75,6 +76,8 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Estate or Building Name?"),
         "facility": MessageLookupByLibrary.simpleMessage("Facility"),
         "feedback": MessageLookupByLibrary.simpleMessage("FeedBack"),
+        "feedback_details":
+            MessageLookupByLibrary.simpleMessage("FeedBack Details"),
         "feedback_msg_1": MessageLookupByLibrary.simpleMessage(
             "Help us keep your estate beautiful"),
         "feedback_msg_2": MessageLookupByLibrary.simpleMessage(
@@ -124,6 +127,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "nric_fin": MessageLookupByLibrary.simpleMessage("NRIC/FIN"),
         "old_mobile_phone":
             MessageLookupByLibrary.simpleMessage("Old Mobile Phone"),
+        "or": MessageLookupByLibrary.simpleMessage("or"),
         "other": MessageLookupByLibrary.simpleMessage("Other"),
         "owner": MessageLookupByLibrary.simpleMessage("Owner"),
         "owner_or_tenant":
@@ -155,6 +159,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "published_successfully":
             MessageLookupByLibrary.simpleMessage("Published Successfully"),
         "rate_us": MessageLookupByLibrary.simpleMessage("Rate Us"),
+        "remove": MessageLookupByLibrary.simpleMessage("Remove"),
         "resend_code": MessageLookupByLibrary.simpleMessage("Resend Code"),
         "reset_password":
             MessageLookupByLibrary.simpleMessage("Reset Password"),
@@ -191,7 +196,11 @@ class MessageLookup extends MessageLookupByLibrary {
         "tries_left": MessageLookupByLibrary.simpleMessage("Tries Left"),
         "type_here": MessageLookupByLibrary.simpleMessage("Type Here"),
         "unit_number": MessageLookupByLibrary.simpleMessage("Unit Number"),
+        "up_to_max_images": MessageLookupByLibrary.simpleMessage(
+            "(Up to 10 images can be uploaded)"),
         "upload": MessageLookupByLibrary.simpleMessage("Upload"),
+        "upload_a_photo":
+            MessageLookupByLibrary.simpleMessage("Upload a Photo"),
         "upload_doc_desc": MessageLookupByLibrary.simpleMessage(
             "The Management requires that you upload the following documents to verify your tenancy. You may redact sensitive financia information"),
         "upload_doc_desc1": MessageLookupByLibrary.simpleMessage(

+ 9 - 2
packages/cs_resources/lib/generated/intl/messages_zh_CN.dart

@@ -26,12 +26,12 @@ class MessageLookup extends MessageLookupByLibrary {
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
-        "Up_to_max_images":
-            MessageLookupByLibrary.simpleMessage("(您最多可以上传10张图片)"),
         "access_date": MessageLookupByLibrary.simpleMessage("访问日期"),
         "account_deactivate_alert": MessageLookupByLibrary.simpleMessage(
             "您确定要停用您的帐户吗?一旦您继续执行请求,您将无法登录应用程序。"),
         "account_deactivation": MessageLookupByLibrary.simpleMessage("删除账号"),
+        "active": MessageLookupByLibrary.simpleMessage("可用"),
+        "add": MessageLookupByLibrary.simpleMessage("添加"),
         "administrator_reply": MessageLookupByLibrary.simpleMessage("管理员回复"),
         "agree_to": MessageLookupByLibrary.simpleMessage("同意"),
         "alert": MessageLookupByLibrary.simpleMessage("提示"),
@@ -56,6 +56,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "describe_your_feedback":
             MessageLookupByLibrary.simpleMessage("描述您的反馈"),
         "did_not_receive": MessageLookupByLibrary.simpleMessage("没有收到验证码?"),
+        "edit_profile": MessageLookupByLibrary.simpleMessage("编辑个人信息"),
         "email": MessageLookupByLibrary.simpleMessage("邮箱"),
         "enable_notification": MessageLookupByLibrary.simpleMessage("允许通知"),
         "estate": MessageLookupByLibrary.simpleMessage("房产"),
@@ -65,6 +66,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("房产或建筑名称?"),
         "facility": MessageLookupByLibrary.simpleMessage("设施"),
         "feedback": MessageLookupByLibrary.simpleMessage("反馈"),
+        "feedback_details": MessageLookupByLibrary.simpleMessage("反馈详情"),
         "feedback_msg_1": MessageLookupByLibrary.simpleMessage("帮助我们保持您的房产美丽"),
         "feedback_msg_2": MessageLookupByLibrary.simpleMessage(
             "有些事情需要我们关注,或者如果你有一个很棒的建议,我们想听听你的意见!"),
@@ -105,6 +107,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "notification": MessageLookupByLibrary.simpleMessage("通知"),
         "nric_fin": MessageLookupByLibrary.simpleMessage("身份证/签证"),
         "old_mobile_phone": MessageLookupByLibrary.simpleMessage("旧的手机号码"),
+        "or": MessageLookupByLibrary.simpleMessage("或者"),
         "other": MessageLookupByLibrary.simpleMessage("其他"),
         "owner": MessageLookupByLibrary.simpleMessage("业主"),
         "owner_or_tenant": MessageLookupByLibrary.simpleMessage("您是业主还是租户?"),
@@ -127,6 +130,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("您的反馈已发送成功,我们会尽快回复您的反馈,谢谢!"),
         "published_successfully": MessageLookupByLibrary.simpleMessage("发布成功"),
         "rate_us": MessageLookupByLibrary.simpleMessage("评价我们"),
+        "remove": MessageLookupByLibrary.simpleMessage("移除"),
         "resend_code": MessageLookupByLibrary.simpleMessage("重新发送"),
         "reset_password": MessageLookupByLibrary.simpleMessage("重置密码"),
         "rewards": MessageLookupByLibrary.simpleMessage("奖励"),
@@ -156,7 +160,10 @@ class MessageLookup extends MessageLookupByLibrary {
         "tries_left": MessageLookupByLibrary.simpleMessage("次尝试机会"),
         "type_here": MessageLookupByLibrary.simpleMessage("在此输入"),
         "unit_number": MessageLookupByLibrary.simpleMessage("单元"),
+        "up_to_max_images":
+            MessageLookupByLibrary.simpleMessage("(您最多可以上传10张图片)"),
         "upload": MessageLookupByLibrary.simpleMessage("上传"),
+        "upload_a_photo": MessageLookupByLibrary.simpleMessage("上传照片"),
         "upload_doc_desc": MessageLookupByLibrary.simpleMessage(
             "管理员要求您上传以下文件以验证您的租约。您可以编辑敏感的财务信息"),
         "upload_doc_desc1": MessageLookupByLibrary.simpleMessage(

+ 9 - 2
packages/cs_resources/lib/generated/intl/messages_zh_HK.dart

@@ -26,12 +26,12 @@ class MessageLookup extends MessageLookupByLibrary {
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
-        "Up_to_max_images":
-            MessageLookupByLibrary.simpleMessage("(您最多可以上传10张图片)"),
         "access_date": MessageLookupByLibrary.simpleMessage("访问日期"),
         "account_deactivate_alert": MessageLookupByLibrary.simpleMessage(
             "您确定要停用您的帐户吗?一旦您继续执行请求,您将无法登录应用程序。"),
         "account_deactivation": MessageLookupByLibrary.simpleMessage("删除账号"),
+        "active": MessageLookupByLibrary.simpleMessage("可用"),
+        "add": MessageLookupByLibrary.simpleMessage("添加"),
         "administrator_reply": MessageLookupByLibrary.simpleMessage("管理员回复"),
         "agree_to": MessageLookupByLibrary.simpleMessage("同意"),
         "alert": MessageLookupByLibrary.simpleMessage("提示"),
@@ -56,6 +56,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "describe_your_feedback":
             MessageLookupByLibrary.simpleMessage("描述您的反馈"),
         "did_not_receive": MessageLookupByLibrary.simpleMessage("没有收到验证码?"),
+        "edit_profile": MessageLookupByLibrary.simpleMessage("编辑个人信息"),
         "email": MessageLookupByLibrary.simpleMessage("邮箱"),
         "enable_notification": MessageLookupByLibrary.simpleMessage("允许通知"),
         "estate": MessageLookupByLibrary.simpleMessage("房产"),
@@ -65,6 +66,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("房产或建筑名称?"),
         "facility": MessageLookupByLibrary.simpleMessage("設施"),
         "feedback": MessageLookupByLibrary.simpleMessage("反馈"),
+        "feedback_details": MessageLookupByLibrary.simpleMessage("反馈详情"),
         "feedback_msg_1": MessageLookupByLibrary.simpleMessage("帮助我们保持您的房产美丽"),
         "feedback_msg_2": MessageLookupByLibrary.simpleMessage(
             "有些事情需要我们关注,或者如果你有一个很棒的建议,我们想听听你的意见!"),
@@ -105,6 +107,7 @@ class MessageLookup extends MessageLookupByLibrary {
         "notification": MessageLookupByLibrary.simpleMessage("通知"),
         "nric_fin": MessageLookupByLibrary.simpleMessage("身份证/签证"),
         "old_mobile_phone": MessageLookupByLibrary.simpleMessage("旧的手机号码"),
+        "or": MessageLookupByLibrary.simpleMessage("或者"),
         "other": MessageLookupByLibrary.simpleMessage("其他"),
         "password": MessageLookupByLibrary.simpleMessage("密码"),
         "password_format": MessageLookupByLibrary.simpleMessage("8位数字或字母"),
@@ -119,6 +122,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("您的反馈已发送成功,我们会尽快回复您的反馈,谢谢!"),
         "published_successfully": MessageLookupByLibrary.simpleMessage("发布成功"),
         "rate_us": MessageLookupByLibrary.simpleMessage("评价我们"),
+        "remove": MessageLookupByLibrary.simpleMessage("移除"),
         "resend_code": MessageLookupByLibrary.simpleMessage("重新发送"),
         "reset_password": MessageLookupByLibrary.simpleMessage("重置密码"),
         "rewards": MessageLookupByLibrary.simpleMessage("獎勵"),
@@ -143,7 +147,10 @@ class MessageLookup extends MessageLookupByLibrary {
         "tries_left": MessageLookupByLibrary.simpleMessage("次尝试机会"),
         "type_here": MessageLookupByLibrary.simpleMessage("在此输入"),
         "unit_number": MessageLookupByLibrary.simpleMessage("单元"),
+        "up_to_max_images":
+            MessageLookupByLibrary.simpleMessage("(您最多可以上传10张图片)"),
         "upload": MessageLookupByLibrary.simpleMessage("上传"),
+        "upload_a_photo": MessageLookupByLibrary.simpleMessage("上传照片"),
         "upload_doc_desc": MessageLookupByLibrary.simpleMessage(
             "管理员要求您上传以下文件以验证您的租约。您可以编辑敏感的财务信息"),
         "upload_doc_desc1": MessageLookupByLibrary.simpleMessage(

+ 72 - 2
packages/cs_resources/lib/generated/l10n.dart

@@ -1321,10 +1321,10 @@ class S {
   }
 
   /// `(Up to 10 images can be uploaded)`
-  String get Up_to_max_images {
+  String get up_to_max_images {
     return Intl.message(
       '(Up to 10 images can be uploaded)',
-      name: 'Up_to_max_images',
+      name: 'up_to_max_images',
       desc: '',
       args: [],
     );
@@ -1380,6 +1380,76 @@ class S {
     );
   }
 
+  /// `FeedBack Details`
+  String get feedback_details {
+    return Intl.message(
+      'FeedBack Details',
+      name: 'feedback_details',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Upload a Photo`
+  String get upload_a_photo {
+    return Intl.message(
+      'Upload a Photo',
+      name: 'upload_a_photo',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `or`
+  String get or {
+    return Intl.message(
+      'or',
+      name: 'or',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Edit Profile`
+  String get edit_profile {
+    return Intl.message(
+      'Edit Profile',
+      name: 'edit_profile',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `ACTIVE`
+  String get active {
+    return Intl.message(
+      'ACTIVE',
+      name: 'active',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Remove`
+  String get remove {
+    return Intl.message(
+      'Remove',
+      name: 'remove',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Add`
+  String get add {
+    return Intl.message(
+      'Add',
+      name: 'add',
+      desc: '',
+      args: [],
+    );
+  }
+
   /// `Other`
   String get other {
     return Intl.message(

+ 8 - 1
packages/cs_resources/lib/l10n/intl_en.arb

@@ -126,11 +126,18 @@
   "describe_your_feedback": "Describe Your FeedBack",
   "upload_pictures": "Upload Pictures",
   "send_feedback": "Send FeedBack",
-  "Up_to_max_images": "(Up to 10 images can be uploaded)",
+  "up_to_max_images": "(Up to 10 images can be uploaded)",
   "published_successfully": "Published Successfully",
   "published_successful_txt": "Your feedback has been successfully sent! We will reply to you as soon as possible! thank you!",
   "back_home": "Back Home",
   "waiting_for_the_administrator": "Waiting for the administrator",
   "administrator_reply": "Administrator Reply",
+  "feedback_details": "FeedBack Details",
+  "upload_a_photo": "Upload a Photo",
+  "or": "or",
+  "edit_profile": "Edit Profile",
+  "active": "ACTIVE",
+  "remove": "Remove",
+  "add": "Add",
   "other": "Other"
 }

+ 8 - 1
packages/cs_resources/lib/l10n/intl_zh_CN.arb

@@ -126,11 +126,18 @@
   "describe_your_feedback": "描述您的反馈",
   "upload_pictures": "上传图片",
   "send_feedback": "发送反馈",
-  "Up_to_max_images": "(您最多可以上传10张图片)",
+  "up_to_max_images": "(您最多可以上传10张图片)",
   "published_successfully": "发布成功",
   "published_successful_txt": "您的反馈已发送成功,我们会尽快回复您的反馈,谢谢!",
   "back_home": "返回首页",
   "waiting_for_the_administrator": "等待管理员回复",
   "administrator_reply": "管理员回复",
+  "feedback_details": "反馈详情",
+  "upload_a_photo": "上传照片",
+  "or": "或者",
+  "edit_profile": "编辑个人信息",
+  "active": "可用",
+  "remove": "移除",
+  "add": "添加",
   "other": "其他"
 }

+ 8 - 1
packages/cs_resources/lib/l10n/intl_zh_HK.arb

@@ -112,11 +112,18 @@
   "describe_your_feedback": "描述您的反馈",
   "upload_pictures": "上传图片",
   "send_feedback": "发送反馈",
-  "Up_to_max_images": "(您最多可以上传10张图片)",
+  "up_to_max_images": "(您最多可以上传10张图片)",
   "published_successfully": "发布成功",
   "published_successful_txt": "您的反馈已发送成功,我们会尽快回复您的反馈,谢谢!",
   "back_home": "返回首页",
   "waiting_for_the_administrator": "等待管理员回复",
   "administrator_reply": "管理员回复",
+  "feedback_details": "反馈详情",
+  "upload_a_photo": "上传照片",
+  "or": "或者",
+  "edit_profile": "编辑个人信息",
+  "active": "可用",
+  "remove": "移除",
+  "add": "添加",
   "other": "其他"
 }

+ 6 - 0
packages/cs_resources/lib/theme/app_colors_theme.dart

@@ -29,6 +29,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
   static const _colorDFF0FF = Color(0xFFDFF0FF);
   static const _color1B61CA = Color(0X4D1B61CA);
   static const _color8B96BA = Color(0xFF8B96BA);
+  static const _colorB4C5FF = Color(0xFFB4C5FF);
 
   //暗色主题的一些自定义颜色值
   static const _darkBlackBg = Color(0xFF0F0F0F);
@@ -66,6 +67,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
   final Color tabTextUnSelectedDefault; //Tab文本,未选中 亮色为黑色,黑暗模式为灰色
   final Color tabLightBlueShadow; //Tab的淡蓝色阴影
   final Color textLightPurple; //文本淡紫色
+  final Color avatarBg; //头像框的淡蓝色
 
   // 私有的构造函数
   const AppColorsTheme._internal({
@@ -96,6 +98,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
     required this.tabTextSelectedDefault,
     required this.tabTextUnSelectedDefault,
     required this.textLightPurple,
+    required this.avatarBg,
   });
 
   // 浅色主题工厂方法
@@ -128,6 +131,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
       tabTextSelectedDefault: _colorPrimary,
       tabTextUnSelectedDefault: Colors.black,
       textLightPurple: _color8B96BA,
+      avatarBg: _colorB4C5FF,
     );
   }
 
@@ -161,6 +165,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
       tabTextSelectedDefault: Colors.white,
       tabTextUnSelectedDefault: _darkBlackItemLightMost,
       textLightPurple: Colors.white,
+      avatarBg: _darkBlackItemLight,
     );
   }
 
@@ -203,6 +208,7 @@ class AppColorsTheme extends ThemeExtension<AppColorsTheme> {
       tabLightBlueShadow: Color.lerp(tabLightBlueShadow, other.tabLightBlueShadow, t)!,
       tabTextUnSelectedDefault: Color.lerp(tabTextUnSelectedDefault, other.tabTextUnSelectedDefault, t)!,
       textLightPurple: Color.lerp(textLightPurple, other.textLightPurple, t)!,
+      avatarBg: Color.lerp(avatarBg, other.avatarBg, t)!,
     );
   }
 }

+ 1 - 0
packages/cs_resources/pubspec.yaml

@@ -31,6 +31,7 @@ flutter:
     - assets/auth/
     - assets/community/
     - assets/main/
+    - assets/profile/
 
 
 flutter_intl:

+ 0 - 4
packages/cs_router/lib/componentRouter/profile_service.dart

@@ -8,10 +8,6 @@ abstract class ProfileService {
 
   void startEditProfilePage({BuildContext? context});
 
-  void startMyPostPage({BuildContext? context});
-
-  void startMyFollowPage({BuildContext? context});
-
   void startMyHouseHoldPage({BuildContext? context});
 
   void startMyEstatePage({BuildContext? context});

+ 64 - 0
packages/cs_widgets/lib/shatter/picker_container.dart

@@ -0,0 +1,64 @@
+import 'package:cs_resources/generated/assets.dart';
+import 'package:cs_resources/theme/app_colors_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/my_text_view.dart';
+
+//下拉选的默认样式
+class PickerContainer extends StatelessWidget {
+  final bool enable;
+  final String? hint;
+  final String? content;
+  final Widget? rightWidget;
+  final double height;
+  final Color? bgColor;
+  final EdgeInsetsGeometry? margin;
+  final VoidCallback onClick;
+
+  const PickerContainer({
+    required this.onClick,
+    this.enable = true,
+    this.hint,
+    this.content,
+    this.margin,
+    this.rightWidget,
+    this.bgColor,
+    this.height = 55,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+        height: height,
+        margin: margin,
+        padding: const EdgeInsets.symmetric(horizontal: 15),
+        decoration: BoxDecoration(
+          color: context.appColors.authFiledBG,
+          borderRadius: const BorderRadius.all(Radius.circular(5)),
+        ),
+        child: Row(
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: [
+            MyTextView(
+              content ?? "",
+              hint: hint,
+              textColor: context.appColors.textBlack,
+              isFontMedium: true,
+              fontSize: 16,
+            ).expanded(),
+            rightWidget != null
+                ? rightWidget!
+                : const MyAssetImage(
+                    Assets.baseServiceTriangleDropDownIcon,
+                    width: 11.5,
+                    height: 6.5,
+                  ),
+          ],
+        )).onTap(() {
+      if (enable) {
+        onClick.call();
+      }
+    });
+  }
+}