Browse Source

notice_board页面

“shanwenxin” 1 week ago
parent
commit
0ab6370a5d
25 changed files with 1590 additions and 84 deletions
  1. 126 0
      packages/cpt_notice_board/lib/modules/announ/page/announ_page.dart
  2. 49 0
      packages/cpt_notice_board/lib/modules/announ/page/announ_state.dart
  3. 70 0
      packages/cpt_notice_board/lib/modules/announ/repository/announ_repository.dart
  4. 27 0
      packages/cpt_notice_board/lib/modules/announ/repository/announ_repository.g.dart
  5. 112 0
      packages/cpt_notice_board/lib/modules/announ/vm/announ_vm.dart
  6. 26 0
      packages/cpt_notice_board/lib/modules/announ/vm/announ_vm.g.dart
  7. 148 0
      packages/cpt_notice_board/lib/modules/documents/page/documents_page.dart
  8. 49 0
      packages/cpt_notice_board/lib/modules/documents/page/documents_state.dart
  9. 70 0
      packages/cpt_notice_board/lib/modules/documents/repository/documents_repository.dart
  10. 28 0
      packages/cpt_notice_board/lib/modules/documents/repository/documents_repository.g.dart
  11. 105 0
      packages/cpt_notice_board/lib/modules/documents/vm/documents_vm.dart
  12. 25 0
      packages/cpt_notice_board/lib/modules/documents/vm/documents_vm.g.dart
  13. 130 0
      packages/cpt_notice_board/lib/modules/event/page/event_page.dart
  14. 49 0
      packages/cpt_notice_board/lib/modules/event/page/event_state.dart
  15. 70 0
      packages/cpt_notice_board/lib/modules/event/repository/event_repository.dart
  16. 27 0
      packages/cpt_notice_board/lib/modules/event/repository/event_repository.g.dart
  17. 105 0
      packages/cpt_notice_board/lib/modules/event/vm/event_vm.dart
  18. 25 0
      packages/cpt_notice_board/lib/modules/event/vm/event_vm.g.dart
  19. 148 67
      packages/cpt_notice_board/lib/modules/notice_board/page/notice_board_page.dart
  20. 99 2
      packages/cpt_notice_board/lib/modules/notice_board/vm/notice_board_view_model.dart
  21. 9 10
      packages/cpt_notice_board/lib/modules/notice_board/vm/notice_board_view_model.g.dart
  22. 25 4
      packages/cpt_notice_board/lib/router/page/notice_board_page_router.dart
  23. 61 1
      packages/cpt_notice_board/lib/router/page/notice_board_page_router.gr.dart
  24. 3 0
      packages/cs_resources/lib/generated/assets.dart
  25. 4 0
      packages/cs_router/lib/path/router_path.dart

+ 126 - 0
packages/cpt_notice_board/lib/modules/announ/page/announ_page.dart

@@ -0,0 +1,126 @@
+import 'package:cpt_notice_board/modules/notice_board/page/notice_board_page.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:shared/utils/log_utils.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/widget_export.dart';
+import 'package:cs_resources/generated/assets.dart';
+
+import '../../../router/page/notice_board_page_router.dart';
+import '../vm/announ_vm.dart';
+
+@RoutePage()
+class AnnounPage extends HookConsumerWidget {
+  const AnnounPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const AnnounPageRoute());
+    } else {
+      appRouter.push(const AnnounPageRoute());
+    }
+  }
+
+  Widget _buildItemLeftSection(BuildContext context, WidgetRef ref, item, _vm) {
+    return Container(
+      // color: Colors.blue,
+      child: Text(
+        maxLines: 2, // 设置最大行数为2
+        overflow: TextOverflow.ellipsis, // 超出部分用省略号表示
+        item['title'],
+        style: const TextStyle(
+            fontSize: 16.0,
+            color: Colors.black,
+            fontWeight: FontWeight.w700), // 设置字体大小
+      ),
+    );
+  }
+  Widget _buildItemRightSection(BuildContext context, WidgetRef ref, item, _vm) {
+    return Container(
+      // color: Colors.green,
+      child: Text(
+        item['price'],
+        style: const TextStyle(
+            fontSize: 14.0,
+            color: Colors.black,
+            fontWeight: FontWeight.w400), // 设置字体大小
+      ),
+    );
+  }
+
+  // listitem
+  Widget _buildSaleItem(BuildContext context, WidgetRef ref, item, _vm) {
+    return Container(
+      
+      decoration: const BoxDecoration(
+        color: Colors.white,
+        borderRadius: BorderRadius.all(Radius.circular(6.0)),
+        boxShadow: [BoxShadow(color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)],
+      ),
+      child: Column(
+        children: [
+          Container(
+            width: MediaQuery.of(context).size.width - 30,
+            height: 100,
+            // margin: const EdgeInsets.only(left: 15, right: 15, top: 12.5),
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: [
+                 _buildItemLeftSection(context, ref, item, _vm).marginOnly(bottom: 5),
+                _buildItemRightSection(context, ref, item, _vm),
+              ],
+            ).paddingOnly(left: 20,right: 20),
+          ).constrained(
+            minHeight: 117.5,
+          ),
+        ],
+      ).onTap(() {
+        // 去详情
+        _vm.goNewsDetail(item['title']);
+      }),
+    ).marginOnly(left: 15, bottom: 15, right: 15);
+  }
+
+  // list
+  Widget _buildSaleList(BuildContext context, WidgetRef ref, _vm) {
+    List itemsList = _vm.state.list.toList();
+    return ListView.builder(
+      itemCount: itemsList.length,
+      itemBuilder: (context, index) {
+        return _buildSaleItem(context, ref, itemsList[index], _vm);
+      },
+    );
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final _vm = ref.read(announVmProvider.notifier);
+
+    return Scaffold(
+      // appBar: AppBar(title: Text("资产")),
+      body: Container(
+          child: EasyRefresh(
+        // 上拉加载
+        onLoad: () async {
+          Log.d("----onLoad");
+          _vm.onLoadData();
+        },
+        // 下拉刷新
+        onRefresh: () async {
+          Log.d("----onRefresh");
+          _vm.refreshListData();
+        },
+        child: Container(
+            color: ColorUtils.string2Color('#F2F3F6'),
+            padding: const EdgeInsets.only(top: 15),
+            child: _buildSaleList(context, ref, _vm)),
+      )),
+    );
+  }
+}

+ 49 - 0
packages/cpt_notice_board/lib/modules/announ/page/announ_state.dart

@@ -0,0 +1,49 @@
+/// YApi QuickType插件生成,具体参考文档:https://plugins.jetbrains.com/plugin/18847-yapi-quicktype/documentation
+
+import 'dart:convert';
+
+AnnounState announStateFromJson(String str) => AnnounState.fromJson(json.decode(str));
+
+String announStateToJson(AnnounState data) => json.encode(data.toJson());
+
+class AnnounState {
+  AnnounState({
+    required this.curPage,
+    required this.pageSize,
+    required this.list,
+    required this.filterCount,
+  });
+
+  int curPage;
+  int pageSize;
+  List<Map<String, dynamic>> list;
+  int filterCount;
+
+  factory AnnounState.fromJson(Map<dynamic, dynamic> json) => AnnounState(
+    curPage: json["curPage"],
+    pageSize: json["pageSize"],
+    list: List<Map<String, dynamic>>.from(json["list"].map((x) => x)),
+    filterCount: json["filterCount"],
+  );
+
+  Map<dynamic, dynamic> toJson() => {
+    "curPage": curPage,
+    "pageSize": pageSize,
+    "list": List<dynamic>.from(list.map((x) => x)),
+    "filterCount": filterCount,
+  };
+
+  AnnounState copyWith({
+    int? curPage,
+    int? pageSize,
+    List<Map<String, dynamic>>? list,
+    int? filterCount,
+  }) {
+    return AnnounState(
+      curPage: curPage ?? this.curPage,
+      pageSize: pageSize ?? this.pageSize,
+      list: list ?? this.list,
+      filterCount: filterCount ?? this.filterCount,
+    );
+  }
+}

+ 70 - 0
packages/cpt_notice_board/lib/modules/announ/repository/announ_repository.dart

@@ -0,0 +1,70 @@
+import 'package:domain/constants/api_constants.dart';
+import 'package:domain/entity/server_time.dart';
+import 'package:plugin_platform/platform_export.dart';
+import 'package:plugin_platform/http/dio_engine.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/util.dart';
+
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:plugin_basic/provider/http_provider/http_provider.dart';
+
+import '../page/announ_state.dart';
+part 'announ_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+AnnounRepository announRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return AnnounRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 数据仓库
+ */
+class AnnounRepository {
+  DioEngine dioEngine;
+
+  AnnounRepository({required this.dioEngine});
+
+  Future<HttpResult<Object>> fetchPropertyNewsList(
+      Map<String, dynamic>? data, {
+        CancelToken? cancelToken,
+      }) async {
+    Map<String, dynamic> params = {};
+
+    // if (!Utils.isEmpty(type)) {
+    //   params["type"] = type!;
+    // }
+
+    params = data!;
+
+
+    Map<String, String> headers = {};
+
+    headers["Content-Type"] = "application/x-www-form-urlencoded";
+    headers["Accept"] = "application/x.yyjobs-api.v1+json";
+
+    final result = await dioEngine.requestNetResult(
+      // ApiConstants.apiServerTime, // api 地址
+      '/index.php/api/employee/extra/time', // api 地址
+      params: params,
+      headers: headers,
+      method: HttpMethod.GET,
+      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
+      networkDebounce: true,   //是否防抖防止重复请求
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = AnnounState.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<AnnounState>(data: data);
+    }
+    return result.convert();
+  }
+
+
+}

+ 27 - 0
packages/cpt_notice_board/lib/modules/announ/repository/announ_repository.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'announ_repository.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$announRepositoryHash() => r'e91b26e60af186a007cb785effb50c16b4967969';
+
+/// See also [announRepository].
+@ProviderFor(announRepository)
+final announRepositoryProvider = Provider<AnnounRepository>.internal(
+  announRepository,
+  name: r'announRepositoryProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$announRepositoryHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef AnnounRepositoryRef = ProviderRef<AnnounRepository>;
+// 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

+ 112 - 0
packages/cpt_notice_board/lib/modules/announ/vm/announ_vm.dart

@@ -0,0 +1,112 @@
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import '../page/announ_state.dart';
+import '../repository/announ_repository.dart';
+part 'announ_vm.g.dart';
+
+@riverpod
+class AnnounVm extends _$AnnounVm {
+  late AnnounRepository announRepository;
+  AnnounState initState() {
+    return AnnounState(
+      curPage: 1,
+      pageSize: 10,
+      list: [
+        {
+          "id": 1,
+          "title": "Standard Operating procedure For Replacement V...",
+          "price": "Monday 14 Oct 2024, 10:19 AM",
+        },
+        {
+          "id": 2,
+          "title": "Removal Of Items In Dry Risers",
+          "price": "Monday 14 Oct 2024, 10:19 AM",
+        },
+        {
+          "id": 3,
+          "title": "Fire Safety Awareness And Guidelines",
+          "price": "Monday 14 Oct 2024, 10:19 AM",
+        },
+        {
+          "id": 4,
+          "title": "Bicycle Tagging Exercise",
+          "price": "Monday 14 Oct 2024, 10:19 AM",
+        },
+      ],
+      filterCount: 2,
+    );
+  }
+
+  @override
+  AnnounState build() {
+    // 引入数据仓库
+    announRepository = ref.read(announRepositoryProvider);
+    // 初始化状态
+    AnnounState state = initState();
+    // 初始化列表数据
+    return state;
+  }
+
+  // 初始化页面数据
+  initPageData() {
+    Log.d("----property_news_vm-----initPageData");
+    refreshListData();
+  }
+
+  // 上拉加载
+  Future onLoadData() async {
+    Log.d("----property_news_vm-----initListData");
+    // await Future.delayed(const Duration(seconds: 2));
+    // if(state.list.length >= state.filterCount){
+    //   return;
+    // }else {
+    //   int curPage = state.curPage + 1;
+    //   state = state.copyWith(curPage: curPage,);
+    //   getListData();
+    // }
+    getListData();
+  }
+// 去新闻详情页
+  void goNewsDetail(String item) {
+    Log.d(item);
+    // PropertyPage.startInstance(context: context, item: item);
+  }
+  // 获取list 列表数据
+  void getListData<T>() async {
+    Log.d("加载listData数据---------------start-----");
+    try {
+      //请求网络
+      Map<String, dynamic> params = {
+        "curPage": state.curPage,
+        "pageSize": state.pageSize,
+      };
+      Log.d("请求参数------$params");
+      final result = await announRepository.fetchPropertyNewsList(params);
+      Log.d("请求完成结果------${result.data}");
+      //校验成功失败
+      if (result.isSuccess) {
+        // state = state.copyWith(serverTime: result.data);
+        state = state;
+        ToastEngine.show("获取数据成功");
+      } else {
+        ToastEngine.show(result.errorMsg ?? "Network Load Error");
+      }
+    } catch (e) {
+      ToastEngine.show("Error: $e");
+    }
+  }
+
+  // 下拉刷新
+  Future refreshListData() async {
+    Log.d("----property_news_vm-----refreshListData ");
+
+    // await Future.delayed(const Duration(seconds: 2));
+
+    state = state.copyWith(curPage: 1, pageSize: 10);
+    // ref.invalidateSelf();
+    // ref.invalidate(propertyNewsVmProvider);
+    getListData();
+  }
+}

+ 26 - 0
packages/cpt_notice_board/lib/modules/announ/vm/announ_vm.g.dart

@@ -0,0 +1,26 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'announ_vm.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$announVmHash() => r'0defb16297b46b5b878b71beb69b7640bb35025c';
+
+/// See also [AnnounVm].
+@ProviderFor(AnnounVm)
+final announVmProvider =
+    AutoDisposeNotifierProvider<AnnounVm, AnnounState>.internal(
+  AnnounVm.new,
+  name: r'announVmProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$announVmHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$AnnounVm = AutoDisposeNotifier<AnnounState>;
+// 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

+ 148 - 0
packages/cpt_notice_board/lib/modules/documents/page/documents_page.dart

@@ -0,0 +1,148 @@
+import 'package:cpt_notice_board/modules/notice_board/page/notice_board_page.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:shared/utils/log_utils.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/widget_export.dart';
+import 'package:cs_resources/generated/assets.dart';
+
+import '../../../router/page/notice_board_page_router.dart';
+import '../vm/documents_vm.dart';
+
+@RoutePage()
+class DocumentsPage extends HookConsumerWidget {
+  const DocumentsPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const DocumentsPageRoute());
+    } else {
+      appRouter.push(const DocumentsPageRoute());
+    }
+  }
+
+  Widget _buildItemLeftSection(BuildContext context, WidgetRef ref, item, _vm) {
+    return Container(
+      // color: Colors.blue,
+      child: Text(
+        item['title'],
+        maxLines: 1, // 设置最大行数为2
+        overflow: TextOverflow.ellipsis, // 超出部分用省略号表示
+        style: const TextStyle(
+            fontSize: 16.0,
+            color: Colors.black,
+            fontWeight: FontWeight.w700), // 设置字体大小
+      ),
+    ).marginOnly(right: 17.5);
+  }
+
+  Widget _buildItemRightSection(
+      BuildContext context, WidgetRef ref, item, _vm) {
+    return Container(
+      color: Colors.white,
+      child: TextButton(
+        onPressed: () {},
+        style: TextButton.styleFrom(
+          foregroundColor: Colors.black,
+          backgroundColor: ColorUtils.string2Color('#4161D0'), // 背景颜色
+          minimumSize: const Size(91.5, 30), // 最小宽度和高度
+          padding:
+              const EdgeInsets.symmetric(horizontal: 11.0, vertical: 9), // 内边距
+          shape: RoundedRectangleBorder(
+            borderRadius: BorderRadius.circular(5), // 圆角
+            side: BorderSide(
+              color: ColorUtils.string2Color('#4161D0'),
+              width: 1.0,
+            ), // 边框
+          ),
+        ),
+        child: const Text('Open Folder',
+          style: const TextStyle(color: Colors.white,),
+        ),
+      ),
+    );
+  }
+
+  // listitem
+  Widget _buildSaleItem(BuildContext context, WidgetRef ref, item, _vm) {
+    return Container(
+      decoration: const BoxDecoration(
+        color: Colors.white,
+        borderRadius: BorderRadius.all(Radius.circular(6.0)),
+        boxShadow: [
+          BoxShadow(color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
+        ],
+      ),
+      child: Row(
+        mainAxisAlignment: MainAxisAlignment.center,
+        crossAxisAlignment: CrossAxisAlignment.center,
+        mainAxisSize: MainAxisSize.max,
+        children: [
+          Container(
+            width: MediaQuery.of(context).size.width - 30,
+            height: 70,
+            child: Row(
+              mainAxisAlignment: MainAxisAlignment.start,
+              crossAxisAlignment: CrossAxisAlignment.center,
+              children: [
+                Expanded(child: _buildItemLeftSection(context, ref, item, _vm)),
+                Container(
+                  width: 120,
+                  child: _buildItemRightSection(context, ref, item, _vm),
+                  // child: TextButton(onPressed: (){}, child: Text("fdsfds")),
+                ),
+              ],
+            ).paddingOnly(left: 20,right: 20),
+          ).constrained(
+            minHeight: 70,
+          ),
+        ],
+      ).onTap(() {
+        // 去详情
+        _vm.goNewsDetail(item);
+      }),
+    ).marginOnly(left: 15, bottom: 15, right: 15);
+  }
+
+  // list
+  Widget _buildSaleList(BuildContext context, WidgetRef ref, _vm) {
+    List itemsList = _vm.state.list.toList();
+    return ListView.builder(
+      itemCount: itemsList.length,
+      itemBuilder: (context, index) {
+        return _buildSaleItem(context, ref, itemsList[index], _vm);
+      },
+    );
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final _vm = ref.read(documentsVmProvider.notifier);
+
+    return Scaffold(
+      // appBar: AppBar(title: Text("资产")),
+      body: Container(
+          child: EasyRefresh(
+        // 上拉加载
+        onLoad: () async {
+          Log.d("----onLoad");
+          _vm.onLoadData();
+        },
+        // 下拉刷新
+        onRefresh: () async {
+          Log.d("----onRefresh");
+          _vm.refreshListData();
+        },
+        child: Container(
+            color: ColorUtils.string2Color('#F2F3F6'),
+            padding: const EdgeInsets.only(top: 15),
+            child: _buildSaleList(context, ref, _vm)),
+      )),
+    );
+  }
+}

+ 49 - 0
packages/cpt_notice_board/lib/modules/documents/page/documents_state.dart

@@ -0,0 +1,49 @@
+/// YApi QuickType插件生成,具体参考文档:https://plugins.jetbrains.com/plugin/18847-yapi-quicktype/documentation
+
+import 'dart:convert';
+
+DocumentsState documentsStateFromJson(String str) => DocumentsState.fromJson(json.decode(str));
+
+String documentsStateToJson(DocumentsState data) => json.encode(data.toJson());
+
+class DocumentsState {
+  DocumentsState({
+    required this.curPage,
+    required this.pageSize,
+    required this.list,
+    required this.filterCount,
+  });
+
+  int curPage;
+  int pageSize;
+  List<Map<String, dynamic>> list;
+  int filterCount;
+
+  factory DocumentsState.fromJson(Map<dynamic, dynamic> json) => DocumentsState(
+    curPage: json["curPage"],
+    pageSize: json["pageSize"],
+    list: List<Map<String, dynamic>>.from(json["list"].map((x) => x)),
+    filterCount: json["filterCount"],
+  );
+
+  Map<dynamic, dynamic> toJson() => {
+    "curPage": curPage,
+    "pageSize": pageSize,
+    "list": List<dynamic>.from(list.map((x) => x)),
+    "filterCount": filterCount,
+  };
+
+  DocumentsState copyWith({
+    int? curPage,
+    int? pageSize,
+    List<Map<String, dynamic>>? list,
+    int? filterCount,
+  }) {
+    return DocumentsState(
+      curPage: curPage ?? this.curPage,
+      pageSize: pageSize ?? this.pageSize,
+      list: list ?? this.list,
+      filterCount: filterCount ?? this.filterCount,
+    );
+  }
+}

+ 70 - 0
packages/cpt_notice_board/lib/modules/documents/repository/documents_repository.dart

@@ -0,0 +1,70 @@
+import 'package:domain/constants/api_constants.dart';
+import 'package:domain/entity/server_time.dart';
+import 'package:plugin_platform/platform_export.dart';
+import 'package:plugin_platform/http/dio_engine.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/util.dart';
+
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:plugin_basic/provider/http_provider/http_provider.dart';
+
+import '../page/documents_state.dart';
+part 'documents_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+DocumentsRepository documentsRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return DocumentsRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 数据仓库
+ */
+class DocumentsRepository {
+  DioEngine dioEngine;
+
+  DocumentsRepository({required this.dioEngine});
+
+  Future<HttpResult<Object>> fetchPropertyNewsList(
+      Map<String, dynamic>? data, {
+        CancelToken? cancelToken,
+      }) async {
+    Map<String, dynamic> params = {};
+
+    // if (!Utils.isEmpty(type)) {
+    //   params["type"] = type!;
+    // }
+
+    params = data!;
+
+
+    Map<String, String> headers = {};
+
+    headers["Content-Type"] = "application/x-www-form-urlencoded";
+    headers["Accept"] = "application/x.yyjobs-api.v1+json";
+
+    final result = await dioEngine.requestNetResult(
+      // ApiConstants.apiServerTime, // api 地址
+      '/index.php/api/employee/extra/time', // api 地址
+      params: params,
+      headers: headers,
+      method: HttpMethod.GET,
+      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
+      networkDebounce: true,   //是否防抖防止重复请求
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = DocumentsState.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<DocumentsState>(data: data);
+    }
+    return result.convert();
+  }
+
+
+}

+ 28 - 0
packages/cpt_notice_board/lib/modules/documents/repository/documents_repository.g.dart

@@ -0,0 +1,28 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'documents_repository.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$documentsRepositoryHash() =>
+    r'68370656250ee691445b4293c3b30568d4ebf20b';
+
+/// See also [documentsRepository].
+@ProviderFor(documentsRepository)
+final documentsRepositoryProvider = Provider<DocumentsRepository>.internal(
+  documentsRepository,
+  name: r'documentsRepositoryProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$documentsRepositoryHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef DocumentsRepositoryRef = ProviderRef<DocumentsRepository>;
+// 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

+ 105 - 0
packages/cpt_notice_board/lib/modules/documents/vm/documents_vm.dart

@@ -0,0 +1,105 @@
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import '../page/documents_state.dart';
+import '../repository/documents_repository.dart';
+part 'documents_vm.g.dart';
+
+@riverpod
+class DocumentsVm extends _$DocumentsVm {
+  late DocumentsRepository documentsRepository;
+  DocumentsState initState() {
+    return DocumentsState(
+      curPage: 1,
+      pageSize: 10,
+      list: [
+        {
+          "id": 1,
+          "title": "18 Sep 2024 BIK 39#09-XX 1337 psd 1001 sqft",
+          "price": "\$1.338 M",
+        },
+        {
+          "id": 2,
+          "title": "18 Sep 2024 BIK 39#09-XX 1337 psd 1001 sqft",
+          "price": "\$1.338 M",
+        },
+      ],
+      filterCount: 2,
+    );
+  }
+
+  @override
+  DocumentsState build() {
+    // 引入数据仓库
+    documentsRepository = ref.read(documentsRepositoryProvider);
+    // 初始化状态
+    DocumentsState state = initState();
+    // 初始化列表数据
+    return state;
+  }
+
+  // 初始化页面数据
+  initPageData() {
+    Log.d("----property_news_vm-----initPageData");
+    refreshListData();
+  }
+
+  // 上拉加载
+  Future onLoadData() async {
+    Log.d("----property_news_vm-----initListData");
+    // await Future.delayed(const Duration(seconds: 2));
+    // if(state.list.length >= state.filterCount){
+    //   return;
+    // }else {
+    //   int curPage = state.curPage + 1;
+    //   state = state.copyWith(curPage: curPage,);
+    //   getListData();
+    // }
+    getListData();
+  }
+// 去新闻详情页
+  void goNewsDetail(String item) {
+    Log.d(item);
+    // PropertyPage.startInstance(context: context, item: item);
+  }
+  // 获取list 列表数据
+  void getListData<T>() async {
+    Log.d("加载listData数据---------------start-----");
+    try {
+      //请求网络
+      Map<String, dynamic>  params = {
+        "curPage": state.curPage,
+        "pageSize": state.pageSize,
+      };
+      Log.d("请求参数------$params");
+      final result = await documentsRepository.fetchPropertyNewsList(params);
+      Log.d("请求完成结果------${result.data}");
+      //校验成功失败
+      if (result.isSuccess) {
+        // state = state.copyWith(serverTime: result.data);
+        state = state;
+        ToastEngine.show("获取数据成功");
+      } else {
+        ToastEngine.show(result.errorMsg ?? "Network Load Error");
+      }
+    } catch (e) {
+      ToastEngine.show("Error: $e");
+    }
+  }
+
+
+  // 下拉刷新
+  Future refreshListData() async {
+    Log.d("----property_news_vm-----refreshListData ");
+
+    // await Future.delayed(const Duration(seconds: 2));
+
+    state = state.copyWith(curPage: 1, pageSize: 10);
+    // ref.invalidateSelf();
+    // ref.invalidate(propertyNewsVmProvider);
+    getListData();
+
+  }
+
+}

+ 25 - 0
packages/cpt_notice_board/lib/modules/documents/vm/documents_vm.g.dart

@@ -0,0 +1,25 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'documents_vm.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$documentsVmHash() => r'17fac5225fa9da020cd0a78c745412eb3ded2770';
+
+/// See also [DocumentsVm].
+@ProviderFor(DocumentsVm)
+final documentsVmProvider =
+    AutoDisposeNotifierProvider<DocumentsVm, DocumentsState>.internal(
+  DocumentsVm.new,
+  name: r'documentsVmProvider',
+  debugGetCreateSourceHash:
+      const bool.fromEnvironment('dart.vm.product') ? null : _$documentsVmHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$DocumentsVm = AutoDisposeNotifier<DocumentsState>;
+// 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

+ 130 - 0
packages/cpt_notice_board/lib/modules/event/page/event_page.dart

@@ -0,0 +1,130 @@
+import 'package:cpt_notice_board/modules/notice_board/page/notice_board_page.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:shared/utils/log_utils.dart';
+import 'package:shared/utils/color_utils.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_load_image.dart';
+import 'package:widgets/widget_export.dart';
+import 'package:cs_resources/generated/assets.dart';
+
+import '../../../router/page/notice_board_page_router.dart';
+import '../vm/event_vm.dart';
+
+@RoutePage()
+class EventPage extends HookConsumerWidget {
+  const EventPage({Key? key}) : super(key: key);
+
+  //启动当前页面
+  static void startInstance({BuildContext? context}) {
+    if (context != null) {
+      context.router.push(const EventPageRoute());
+    } else {
+      appRouter.push(const EventPageRoute());
+    }
+  }
+
+  Widget _buildItemLeftSection(BuildContext context, WidgetRef ref, item, _vm) {
+    return Container(
+      // color: Colors.blue,
+      child: Text(
+        maxLines: 2, // 设置最大行数为2
+        overflow: TextOverflow.ellipsis, // 超出部分用省略号表示
+        item['title'],
+        style: const TextStyle(
+            fontSize: 16.0,
+            color: Colors.black,
+            fontWeight: FontWeight.w700), // 设置字体大小
+      ),
+    );
+  }
+
+  Widget _buildItemRightSection(
+      BuildContext context, WidgetRef ref, item, _vm) {
+    return Container(
+      // color: Colors.green,
+      child: Text(
+        item['price'],
+        style: const TextStyle(
+            fontSize: 14.0,
+            color: Colors.black,
+            fontWeight: FontWeight.w400), // 设置字体大小
+      ),
+    );
+  }
+
+  // listitem
+  Widget _buildSaleItem(BuildContext context, WidgetRef ref, item, _vm) {
+    return Container(
+      decoration: const BoxDecoration(
+        color: Colors.white,
+        borderRadius: BorderRadius.all(Radius.circular(6.0)),
+        boxShadow: [
+          BoxShadow(color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
+        ],
+      ),
+      child: Column(
+        children: [
+          Container(
+            width: MediaQuery.of(context).size.width - 30,
+            height: 100,
+            // margin: const EdgeInsets.only(left: 15, right: 15, top: 12.5),
+            child: Column(
+              crossAxisAlignment: CrossAxisAlignment.start,
+              mainAxisAlignment: MainAxisAlignment.center,
+              children: [
+                _buildItemLeftSection(context, ref, item, _vm)
+                    .marginOnly(bottom: 5),
+                _buildItemRightSection(context, ref, item, _vm),
+              ],
+            ).paddingOnly(left: 20, right: 20),
+          ).constrained(
+            minHeight: 117.5,
+          ),
+        ],
+      ).onTap(() {
+        // 去详情
+        _vm.goNewsDetail(item['title']);
+      }),
+    ).marginOnly(left: 15, bottom: 15, right: 15);
+  }
+
+  // list
+  Widget _buildSaleList(BuildContext context, WidgetRef ref, _vm) {
+    List itemsList = _vm.state.list.toList();
+    return ListView.builder(
+      itemCount: itemsList.length,
+      itemBuilder: (context, index) {
+        return _buildSaleItem(context, ref, itemsList[index], _vm);
+      },
+    );
+  }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final _vm = ref.read(eventVmProvider.notifier);
+
+    return Scaffold(
+      // appBar: AppBar(title: Text("资产")),
+      body: Container(
+          child: EasyRefresh(
+        // 上拉加载
+        onLoad: () async {
+          Log.d("----onLoad");
+          _vm.onLoadData();
+        },
+        // 下拉刷新
+        onRefresh: () async {
+          Log.d("----onRefresh");
+          _vm.refreshListData();
+        },
+        child: Container(
+            color: ColorUtils.string2Color('#F2F3F6'),
+            padding: const EdgeInsets.only(top: 15),
+            child: _buildSaleList(context, ref, _vm)),
+      )),
+    );
+  }
+}

+ 49 - 0
packages/cpt_notice_board/lib/modules/event/page/event_state.dart

@@ -0,0 +1,49 @@
+/// YApi QuickType插件生成,具体参考文档:https://plugins.jetbrains.com/plugin/18847-yapi-quicktype/documentation
+
+import 'dart:convert';
+
+EventState eventStateFromJson(String str) => EventState.fromJson(json.decode(str));
+
+String eventStateToJson(EventState data) => json.encode(data.toJson());
+
+class EventState {
+  EventState({
+    required this.curPage,
+    required this.pageSize,
+    required this.list,
+    required this.filterCount,
+  });
+
+  int curPage;
+  int pageSize;
+  List<Map<String, dynamic>> list;
+  int filterCount;
+
+  factory EventState.fromJson(Map<dynamic, dynamic> json) => EventState(
+    curPage: json["curPage"],
+    pageSize: json["pageSize"],
+    list: List<Map<String, dynamic>>.from(json["list"].map((x) => x)),
+    filterCount: json["filterCount"],
+  );
+
+  Map<dynamic, dynamic> toJson() => {
+    "curPage": curPage,
+    "pageSize": pageSize,
+    "list": List<dynamic>.from(list.map((x) => x)),
+    "filterCount": filterCount,
+  };
+
+  EventState copyWith({
+    int? curPage,
+    int? pageSize,
+    List<Map<String, dynamic>>? list,
+    int? filterCount,
+  }) {
+    return EventState(
+      curPage: curPage ?? this.curPage,
+      pageSize: pageSize ?? this.pageSize,
+      list: list ?? this.list,
+      filterCount: filterCount ?? this.filterCount,
+    );
+  }
+}

+ 70 - 0
packages/cpt_notice_board/lib/modules/event/repository/event_repository.dart

@@ -0,0 +1,70 @@
+import 'package:domain/constants/api_constants.dart';
+import 'package:domain/entity/server_time.dart';
+import 'package:plugin_platform/platform_export.dart';
+import 'package:plugin_platform/http/dio_engine.dart';
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/util.dart';
+
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:plugin_basic/provider/http_provider/http_provider.dart';
+
+import '../page/event_state.dart';
+part 'event_repository.g.dart';
+
+@Riverpod(keepAlive: true)
+EventRepository eventRepository(Ref ref) {
+  final dioEngine = ref.watch(dioEngineProvider);
+  return EventRepository(dioEngine: dioEngine);
+}
+
+/*
+ * 数据仓库
+ */
+class EventRepository {
+  DioEngine dioEngine;
+
+  EventRepository({required this.dioEngine});
+
+  Future<HttpResult<Object>> fetchPropertyNewsList(
+      Map<String, dynamic>? data, {
+        CancelToken? cancelToken,
+      }) async {
+    Map<String, dynamic> params = {};
+
+    // if (!Utils.isEmpty(type)) {
+    //   params["type"] = type!;
+    // }
+
+    params = data!;
+
+
+    Map<String, String> headers = {};
+
+    headers["Content-Type"] = "application/x-www-form-urlencoded";
+    headers["Accept"] = "application/x.yyjobs-api.v1+json";
+
+    final result = await dioEngine.requestNetResult(
+      // ApiConstants.apiServerTime, // api 地址
+      '/index.php/api/employee/extra/time', // api 地址
+      params: params,
+      headers: headers,
+      method: HttpMethod.GET,
+      isShowLoadingDialog: true,  //是否展示默认的Loading弹窗
+      networkDebounce: true,   //是否防抖防止重复请求
+      cancelToken: cancelToken,
+    );
+
+    //根据返回的结果,封装原始数据为Bean/Entity对象
+    if (result.isSuccess) {
+      //重新赋值data或list
+      final json = result.getDataJson();
+      var data = EventState.fromJson(json!);
+      //重新赋值data或list
+      return result.convert<EventState>(data: data);
+    }
+    return result.convert();
+  }
+
+
+}

+ 27 - 0
packages/cpt_notice_board/lib/modules/event/repository/event_repository.g.dart

@@ -0,0 +1,27 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'event_repository.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$eventRepositoryHash() => r'e91b26e60af186a007cb785effb50c16b4967969';
+
+/// See also [eventRepository].
+@ProviderFor(eventRepository)
+final eventRepositoryProvider = Provider<EventRepository>.internal(
+  eventRepository,
+  name: r'eventRepositoryProvider',
+  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
+      ? null
+      : _$eventRepositoryHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+@Deprecated('Will be removed in 3.0. Use Ref instead')
+// ignore: unused_element
+typedef EventRepositoryRef = ProviderRef<EventRepository>;
+// 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

+ 105 - 0
packages/cpt_notice_board/lib/modules/event/vm/event_vm.dart

@@ -0,0 +1,105 @@
+import 'package:plugin_platform/http/http_result.dart';
+import 'package:riverpod_annotation/riverpod_annotation.dart';
+import 'package:shared/utils/log_utils.dart';
+import 'package:plugin_platform/engine/toast/toast_engine.dart';
+import '../page/event_state.dart';
+import '../repository/event_repository.dart';
+part 'event_vm.g.dart';
+
+@riverpod
+class EventVm extends _$EventVm {
+  late EventRepository eventRepository;
+  EventState initState() {
+    return EventState(
+      curPage: 1,
+      pageSize: 10,
+      list: [
+        {
+          "id": 1,
+          "title":
+              "The community will hold the activity of making Zongzi on the Loong Boat ……",
+          "price": "Monday 14 0ct 2024, 15:00 PM~18:00PM",
+        },
+        {
+          "id": 2,
+          "title": "Community basketball competition activities",
+          "price": "Monday 14 Oct 2024, 10:19 AM",
+        },
+      ],
+      filterCount: 2,
+    );
+  }
+
+  @override
+  EventState build() {
+    // 引入数据仓库
+    eventRepository = ref.read(eventRepositoryProvider);
+    // 初始化状态
+    EventState state = initState();
+    // 初始化列表数据
+    return state;
+  }
+
+  // 初始化页面数据
+  initPageData() {
+    Log.d("----property_news_vm-----initPageData");
+    refreshListData();
+  }
+
+  // 上拉加载
+  Future onLoadData() async {
+    Log.d("----property_news_vm-----initListData");
+    // await Future.delayed(const Duration(seconds: 2));
+    // if(state.list.length >= state.filterCount){
+    //   return;
+    // }else {
+    //   int curPage = state.curPage + 1;
+    //   state = state.copyWith(curPage: curPage,);
+    //   getListData();
+    // }
+    getListData();
+  }
+
+// 去新闻详情页
+  void goNewsDetail(String item) {
+    Log.d(item);
+    // PropertyPage.startInstance(context: context, item: item);
+  }
+
+  // 获取list 列表数据
+  void getListData<T>() async {
+    Log.d("加载listData数据---------------start-----");
+    try {
+      //请求网络
+      Map<String, dynamic> params = {
+        "curPage": state.curPage,
+        "pageSize": state.pageSize,
+      };
+      Log.d("请求参数------$params");
+      final result = await eventRepository.fetchPropertyNewsList(params);
+      Log.d("请求完成结果------${result.data}");
+      //校验成功失败
+      if (result.isSuccess) {
+        // state = state.copyWith(serverTime: result.data);
+        state = state;
+        ToastEngine.show("获取数据成功");
+      } else {
+        ToastEngine.show(result.errorMsg ?? "Network Load Error");
+      }
+    } catch (e) {
+      ToastEngine.show("Error: $e");
+    }
+  }
+
+  // 下拉刷新
+  Future refreshListData() async {
+    Log.d("----property_news_vm-----refreshListData ");
+
+    // await Future.delayed(const Duration(seconds: 2));
+
+    state = state.copyWith(curPage: 1, pageSize: 10);
+    // ref.invalidateSelf();
+    // ref.invalidate(propertyNewsVmProvider);
+    getListData();
+  }
+}

+ 25 - 0
packages/cpt_notice_board/lib/modules/event/vm/event_vm.g.dart

@@ -0,0 +1,25 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'event_vm.dart';
+
+// **************************************************************************
+// RiverpodGenerator
+// **************************************************************************
+
+String _$eventVmHash() => r'49b73a9a511244c2542f2d4d831070a7996484ff';
+
+/// See also [EventVm].
+@ProviderFor(EventVm)
+final eventVmProvider =
+    AutoDisposeNotifierProvider<EventVm, EventState>.internal(
+  EventVm.new,
+  name: r'eventVmProvider',
+  debugGetCreateSourceHash:
+      const bool.fromEnvironment('dart.vm.product') ? null : _$eventVmHash,
+  dependencies: null,
+  allTransitiveDependencies: null,
+);
+
+typedef _$EventVm = AutoDisposeNotifier<EventState>;
+// 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

+ 148 - 67
packages/cpt_notice_board/lib/modules/notice_board/page/notice_board_page.dart

@@ -1,11 +1,15 @@
-import 'package:cs_resources/theme/theme_config.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:shared/utils/color_utils.dart';
+import 'package:shared/utils/log_utils.dart';
 import 'package:widgets/my_load_image.dart';
-import 'package:cs_resources/generated/assets.dart';
+import 'package:widgets/ext/ex_widget.dart';
+import 'package:widgets/my_text_view.dart';
 import 'package:widgets/my_appbar.dart';
+import 'package:cs_resources/generated/assets.dart';
+
 import '../../../router/page/notice_board_page_router.dart';
 import '../../notice_board/vm/notice_board_view_model.dart';
 
@@ -22,76 +26,153 @@ class NoticeBoardPage extends HookConsumerWidget {
     }
   }
 
-  @override
-  Widget build(BuildContext context, WidgetRef ref) {
-    final _viewModel = ref.read(noticeBoardViewModelProvider.notifier);
-
-    return Scaffold(
-      // appBar: MyAppBar.titleBar(context, "Test Title"),
-      body: Container(
-        child: Column(
-          children: [
-
-            MyAppBar.titleBar(context, "Test Title"),
-            const Padding(
-              padding: EdgeInsets.fromLTRB(15, 0, 15, 30),
-              child: Row(
-                mainAxisAlignment: MainAxisAlignment.spaceBetween,
+  // 顶部tab 切换
+  Widget _buildTopSection(BuildContext context, WidgetRef ref, _vm) {
+    final topSectionsData = _vm.topSectionsData;
+    // 监听 curIdx 的变化
+    final curIdx =
+        ref.watch(noticeBoardVmProvider.select((value) => value.curIdx));
+    return Container(
+      color: Colors.white,
+      child: Center(
+        child: Row(
+          mainAxisAlignment: MainAxisAlignment.center,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: List.generate(topSectionsData.length, (index) {
+            final item = topSectionsData[index];
+            return Flexible(
+              flex: 1,
+              child: Column(
                 children: [
-                  Column(children: [
-                    MyAssetImage(
-                      Assets.noticeBoardAnnouncementIcon,
-                      height: 70,
-                      width: 70,
-                    ),
-                    Text(
-                      "Announcement",
-                      style: TextStyle(
-                        color: Colors.black,
-                        fontSize: 15,
-                        fontWeight: FontWeight.bold,
-                        height: 1.5,
-                      ),
-                    )
-                  ]),
-                  Column(children: [
-                    MyAssetImage(
-                      Assets.noticeBoardEventIcon,
-                      height: 70,
-                      width: 70,
-                    ),
-                    Text(
-                      "Event",
-                      style: TextStyle(
-                        color: Colors.black,
-                        fontSize: 15,
-                        fontWeight: FontWeight.bold,
-                        height: 1.5,
-                      ),
-                    )
-                  ]),
-                  Column(children: [
-                    MyAssetImage(
-                      Assets.noticeBoardDocumentsIcon,
-                      height: 70,
-                      width: 70,
-                    ),
-                    Text(
-                      "Documents",
-                      style: TextStyle(
-                        color: Colors.black,
-                        fontSize: 15,
-                        fontWeight: FontWeight.bold,
-                        height: 1.5,
-                      ),
-                    )
-                  ]),
+                  MyAssetImage(
+                    item['icon'],
+                    width: MediaQuery.of(context).size.width /
+                            topSectionsData.length -
+                        36,
+                    height: 70,
+                  ).onTap(
+                    () {
+                      _vm.switchPage(index, context);
+                    },
+                    type: ClickType.throttle,
+                  ),
+                  SizedBox.fromSize(size: const Size(0, 9)),
+                  Text(
+                    item['title'],
+                    maxLines: 1, // 设置最大行数为2
+                    overflow: TextOverflow.ellipsis, // 超出部分用省略号表示
+                    style: TextStyle(
+                        fontSize: 13.0,
+                        color: curIdx == index
+                            ? ColorUtils.string2Color('#4161D0')
+                            : Colors.black,
+                        fontWeight: FontWeight.w500), // 设置字体大小
+                  ),
                 ],
               ),
-            ),
-          ],
+            ).marginOnly(left: 18, right: 18, top: 10, bottom: 10);
+          }),
         ),
       ),
     );
   }
+
+  @override
+  Widget build(BuildContext context, WidgetRef ref) {
+    final _vm = ref.read(noticeBoardVmProvider.notifier);
+    return DefaultTabController(
+      length: 4,
+      child: Scaffold(
+          appBar: AppBar(
+            title: const Text("Property"),
+            bottomOpacity: 0.0, // 取消下横线
+            titleTextStyle: const TextStyle(color: Colors.black),
+          ),
+          body: Row(
+            children: [
+              Expanded(
+                child: Column(
+                  children: [
+                    _buildTopSection(context, ref, _vm),
+                    const Expanded(
+                      child: AutoRouter(),
+                    )
+                  ],
+                ),
+              )
+            ],
+          )),
+    );
+  }
+  // @override
+  // Widget build(BuildContext context, WidgetRef ref) {
+  //   final _viewModel = ref.read(noticeBoardVmProvider.notifier);
+  //   return Scaffold(
+  //     // appBar: MyAppBar.titleBar(context, "Test Title"),
+  //     body: Container(
+  //       child: Column(
+  //         children: [
+
+  //           MyAppBar.titleBar(context, "Test Title"),
+  //           const Padding(
+  //             padding: EdgeInsets.fromLTRB(15, 0, 15, 30),
+  //             child: Row(
+  //               mainAxisAlignment: MainAxisAlignment.spaceBetween,
+  //               children: [
+  //                 Column(children: [
+  //                   MyAssetImage(
+  //                     Assets.noticeBoardAnnouncementIcon,
+  //                     height: 70,
+  //                     width: 70,
+  //                   ),
+  //                   Text(
+  //                     "Announcement",
+  //                     style: TextStyle(
+  //                       color: Colors.black,
+  //                       fontSize: 15,
+  //                       fontWeight: FontWeight.bold,
+  //                       height: 1.5,
+  //                     ),
+  //                   )
+  //                 ]),
+  //                 Column(children: [
+  //                   MyAssetImage(
+  //                     Assets.noticeBoardEventIcon,
+  //                     height: 70,
+  //                     width: 70,
+  //                   ),
+  //                   Text(
+  //                     "Event",
+  //                     style: TextStyle(
+  //                       color: Colors.black,
+  //                       fontSize: 15,
+  //                       fontWeight: FontWeight.bold,
+  //                       height: 1.5,
+  //                     ),
+  //                   )
+  //                 ]),
+  //                 Column(children: [
+  //                   MyAssetImage(
+  //                     Assets.noticeBoardDocumentsIcon,
+  //                     height: 70,
+  //                     width: 70,
+  //                   ),
+  //                   Text(
+  //                     "Documents",
+  //                     style: TextStyle(
+  //                       color: Colors.black,
+  //                       fontSize: 15,
+  //                       fontWeight: FontWeight.bold,
+  //                       height: 1.5,
+  //                     ),
+  //                   )
+  //                 ]),
+  //               ],
+  //             ),
+  //           ),
+  //         ],
+  //       ),
+  //     ),
+  //   );
+  // }
 }

+ 99 - 2
packages/cpt_notice_board/lib/modules/notice_board/vm/notice_board_view_model.dart

@@ -1,14 +1,111 @@
 
+// import 'package:riverpod_annotation/riverpod_annotation.dart';
+
+// part 'notice_board_view_model.g.dart';
+
+// @riverpod
+// class NoticeBoardViewModel extends _$NoticeBoardViewModel {
+
+//   @override
+//   void build(){
+
+//   }
+
+// }
+
+
+import 'package:cs_resources/generated/assets.dart';
+import 'package:flutter/cupertino.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 '../../ioan/property_ioan_page.dart';
+import '../../announ/page/announ_page.dart';
+import '../../documents/page/documents_page.dart';
+import '../../event/page/event_page.dart';
 
 part 'notice_board_view_model.g.dart';
 
+
+class NoticeBoardVmState {
+  List<Map<String, dynamic>>? topSectionsData;
+  int? curIdx;
+
+  NoticeBoardVmState({
+    List<Map<String, dynamic>>? topSectionsData,
+    this.curIdx = 0,
+  }) : topSectionsData = topSectionsData?? [
+    {
+      "title": "Announcement",
+      "icon": Assets.noticeBoardAnnouncementIcon,
+      "pageStartInstanceFn": AnnounPage.startInstance,
+      "page": const AnnounPage(),
+    },
+    {
+      "title": "Event",
+      "icon": Assets.noticeBoardEventIcon,
+      "pageStartInstanceFn": EventPage.startInstance,
+      "page": const EventPage(),
+    },
+    {
+      "title": "Documents",
+      "icon": Assets.noticeBoardDocumentsIcon,
+      "pageStartInstanceFn": DocumentsPage.startInstance,
+      "page": const DocumentsPage(),
+    },
+  ];
+
+  NoticeBoardVmState copyWith({
+    List<Map<String, dynamic>>? topSectionsData,
+    int? curIdx = 0,
+  }) {
+    return NoticeBoardVmState(
+      topSectionsData: topSectionsData ?? this.topSectionsData,
+      curIdx: curIdx ?? 0,
+    );
+  }
+}
+
 @riverpod
-class NoticeBoardViewModel extends _$NoticeBoardViewModel {
+class NoticeBoardVm extends _$NoticeBoardVm {
+  get topSectionsData => state.topSectionsData;
+
+  NoticeBoardVmState initState() {
+    return NoticeBoardVmState();
+  }
 
   @override
-  void build(){
+  NoticeBoardVmState build(){
+    final state = initState();
+    Log.d("--------------------------build---------------------");
 
+    // 初始时导航到子路由
+    WidgetsBinding.instance.addPostFrameCallback((_) {
+      switchPage(state.curIdx ?? 0, null, true);
+    });
+
+    return state;
+  }
+
+  // 页面切换
+  switchPage(int index,BuildContext? context, [bool? isFirstInitSwitch] ){
+    if(state.curIdx != index){
+      state = state.copyWith(curIdx: index);
+      final List<Map<String, dynamic>>? topSectionsData = state.topSectionsData;
+      // Log.d("当前页面${topSectionsData?[index]['pageStartInstanceFn']}");
+      final pageStartInstanceFn = topSectionsData?[index]['pageStartInstanceFn'] as Function({BuildContext? context});
+      pageStartInstanceFn(context:context);
+    }else {
+      if(isFirstInitSwitch??false){
+        final List<Map<String, dynamic>>? topSectionsData = state.topSectionsData;
+        // Log.d("当前页面${topSectionsData?[index]['pageStartInstanceFn']}");
+        final pageStartInstanceFn = topSectionsData?[index]['pageStartInstanceFn'] as Function({BuildContext? context});
+        pageStartInstanceFn(context:context);
+      }
+    }
   }
 
 }
+
+

+ 9 - 10
packages/cpt_notice_board/lib/modules/notice_board/vm/notice_board_view_model.g.dart

@@ -6,22 +6,21 @@ part of 'notice_board_view_model.dart';
 // RiverpodGenerator
 // **************************************************************************
 
-String _$noticeBoardViewModelHash() =>
-    r'ef467d39ec1baea3c118dbb21e348acb2d219e83';
+String _$noticeBoardVmHash() => r'35dfbf4845c7dca80ef6f737fbc529cb1f232a4f';
 
-/// See also [NoticeBoardViewModel].
-@ProviderFor(NoticeBoardViewModel)
-final noticeBoardViewModelProvider =
-    AutoDisposeNotifierProvider<NoticeBoardViewModel, void>.internal(
-  NoticeBoardViewModel.new,
-  name: r'noticeBoardViewModelProvider',
+/// See also [NoticeBoardVm].
+@ProviderFor(NoticeBoardVm)
+final noticeBoardVmProvider =
+    AutoDisposeNotifierProvider<NoticeBoardVm, NoticeBoardVmState>.internal(
+  NoticeBoardVm.new,
+  name: r'noticeBoardVmProvider',
   debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
       ? null
-      : _$noticeBoardViewModelHash,
+      : _$noticeBoardVmHash,
   dependencies: null,
   allTransitiveDependencies: null,
 );
 
-typedef _$NoticeBoardViewModel = AutoDisposeNotifier<void>;
+typedef _$NoticeBoardVm = AutoDisposeNotifier<NoticeBoardVmState>;
 // 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

+ 25 - 4
packages/cpt_notice_board/lib/router/page/notice_board_page_router.dart

@@ -4,7 +4,9 @@ import 'package:router/ext/auto_router_extensions.dart';
 import 'package:router/path/router_path.dart';
 
 import '../../modules/notice_board/page/notice_board_page.dart';
-
+import '../../modules/announ/page/announ_page.dart';
+import '../../modules/event/page/event_page.dart';
+import '../../modules/documents/page/documents_page.dart';
 
 part 'notice_board_page_router.gr.dart';
 
@@ -15,7 +17,26 @@ part 'notice_board_page_router.gr.dart';
 class NoticeBoardPageRouter extends _$NoticeBoardPageRouter {
   @override
   List<AutoRoute> get routes => [
-
-    CustomRoute(page: NoticeBoardPageRoute.page, path: RouterPath.noticeBoard, transitionsBuilder: applySlideTransition),
-  ];
+        CustomRoute(
+            page: NoticeBoardPageRoute.page,
+            path: RouterPath.noticeBoard,
+            transitionsBuilder: applySlideTransition,
+            children: [
+              CustomRoute(
+                page: AnnounPageRoute.page,
+                path: RouterPath.announ,
+                transitionsBuilder: applySlideTransition,
+              ),
+              CustomRoute(
+                page: EventPageRoute.page,
+                path: RouterPath.event,
+                transitionsBuilder: applySlideTransition,
+              ),
+              CustomRoute(
+                page: DocumentsPageRoute.page,
+                path: RouterPath.documents,
+                transitionsBuilder: applySlideTransition,
+              ),
+            ]),
+      ];
 }

+ 61 - 1
packages/cpt_notice_board/lib/router/page/notice_board_page_router.gr.dart

@@ -15,16 +15,76 @@ abstract class _$NoticeBoardPageRouter extends RootStackRouter {
 
   @override
   final Map<String, PageFactory> pagesMap = {
+    AnnounPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const AnnounPage(),
+      );
+    },
+    DocumentsPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const DocumentsPage(),
+      );
+    },
+    EventPageRoute.name: (routeData) {
+      return AutoRoutePage<dynamic>(
+        routeData: routeData,
+        child: const EventPage(),
+      );
+    },
     NoticeBoardPageRoute.name: (routeData) {
       return AutoRoutePage<dynamic>(
         routeData: routeData,
         child: const NoticeBoardPage(),
       );
-    }
+    },
   };
 }
 
 /// generated route for
+/// [AnnounPage]
+class AnnounPageRoute extends PageRouteInfo<void> {
+  const AnnounPageRoute({List<PageRouteInfo>? children})
+      : super(
+          AnnounPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'AnnounPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [DocumentsPage]
+class DocumentsPageRoute extends PageRouteInfo<void> {
+  const DocumentsPageRoute({List<PageRouteInfo>? children})
+      : super(
+          DocumentsPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'DocumentsPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
+/// [EventPage]
+class EventPageRoute extends PageRouteInfo<void> {
+  const EventPageRoute({List<PageRouteInfo>? children})
+      : super(
+          EventPageRoute.name,
+          initialChildren: children,
+        );
+
+  static const String name = 'EventPageRoute';
+
+  static const PageInfo<void> page = PageInfo<void>(name);
+}
+
+/// generated route for
 /// [NoticeBoardPage]
 class NoticeBoardPageRoute extends PageRouteInfo<void> {
   const NoticeBoardPageRoute({List<PageRouteInfo>? children})

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

@@ -73,6 +73,9 @@ class Assets {
   static const String mainTabMeUnselected = 'assets/main/tab_me_unselected.webp';
   static const String mainTabVisitorSelected = 'assets/main/tab_visitor_selected.webp';
   static const String mainTabVisitorUnselected = 'assets/main/tab_visitor_unselected.webp';
+  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 propertyAdvicePic = 'assets/property/advice_pic.webp';
   static const String propertyApproval = 'assets/property/approval.webp';
   static const String propertyCollection = 'assets/property/collection.webp';

+ 4 - 0
packages/cs_router/lib/path/router_path.dart

@@ -42,6 +42,10 @@ class RouterPath {
 
   //消息板
   static const noticeBoard = '/notice_board';
+  static const announ = 'notice_board/announ';
+  static const event = 'notice_board/event';
+  static const documents = 'notice_board/documents';
+  
 
   //支付
   static const payment = '/payment';