From a0ae48243d7d7005aa73cf64c0e1593d8022d4de Mon Sep 17 00:00:00 2001 From: liyi Date: Fri, 12 Sep 2025 15:25:36 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E5=9B=A2=E9=98=9F?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/api/api_path.dart | 1 + .../request/update_team_info_request.dart | 39 ++ .../team/response/team_info_response.dart | 53 ++- lib/api/service/team_api_service.dart | 14 + lib/base/base_controller.dart | 8 + lib/common/widgets/custom_app_bar_widget.dart | 51 --- .../widgets/custom_cell_list_widget.dart | 40 ++ lib/common/widgets/custom_cell_widget.dart | 54 +++ lib/common/widgets/custom_dialog_widget.dart | 1 - .../widgets/custome_app_bar_wdiget.dart | 52 +++ lib/routes/app_pages.dart | 7 + lib/routes/app_routes.dart | 1 + lib/views/login/login_controller.dart | 1 + lib/views/main/main_binding.dart | 2 + lib/views/main/main_controller.dart | 13 + .../main/widget/main_left_drawer_widget.dart | 4 +- lib/views/team/joinTeam/join_team_view.dart | 2 +- .../teamInfo/team_info_binding.dart | 9 + .../teamInfo/team_info_controller.dart | 70 ++++ .../teamManage/teamInfo/team_info_view.dart | 389 ++++++++++++++++++ .../team/teamManage/team_manage_binding.dart | 2 +- .../teamManage/team_manage_controller.dart | 13 +- .../team/teamManage/team_manage_view.dart | 340 +++++++++++---- .../team/teamNotice/team_notice_view.dart | 28 +- 24 files changed, 1054 insertions(+), 140 deletions(-) create mode 100644 lib/api/model/team/request/update_team_info_request.dart delete mode 100644 lib/common/widgets/custom_app_bar_widget.dart create mode 100644 lib/common/widgets/custom_cell_list_widget.dart create mode 100644 lib/common/widgets/custom_cell_widget.dart create mode 100644 lib/common/widgets/custome_app_bar_wdiget.dart create mode 100644 lib/views/team/teamManage/teamInfo/team_info_binding.dart create mode 100644 lib/views/team/teamManage/teamInfo/team_info_controller.dart create mode 100644 lib/views/team/teamManage/teamInfo/team_info_view.dart diff --git a/lib/api/api_path.dart b/lib/api/api_path.dart index 34721cc..12631cd 100644 --- a/lib/api/api_path.dart +++ b/lib/api/api_path.dart @@ -7,4 +7,5 @@ class ApiPath { static const String createTeam = "/v1/team/createTeam"; static const String changeTeam = "/v1/team/changeTeam"; static const String bindTeamStarCloudAccount = "/v1/team/bindStarCloudAccount"; + static const String updateTeamInfo = "/v1/team/updateTeam"; } diff --git a/lib/api/model/team/request/update_team_info_request.dart b/lib/api/model/team/request/update_team_info_request.dart new file mode 100644 index 0000000..fae6052 --- /dev/null +++ b/lib/api/model/team/request/update_team_info_request.dart @@ -0,0 +1,39 @@ +class UpdateTeamInfoRequest { + final String? teamName; + final int? scene; + final String? sceneCustomName; + + UpdateTeamInfoRequest({ + this.teamName, + this.scene, + this.sceneCustomName, + }); + + Map toJson() { + // 要判断非null值 + Map json = {}; + if (teamName != null) { + json['teamName'] = teamName; + } + if (scene != null) { + json['scene'] = scene; + } + if (sceneCustomName != null) { + json['sceneCustomName'] = sceneCustomName; + } + return json; + } + + factory UpdateTeamInfoRequest.fromJson(Map json) { + return UpdateTeamInfoRequest( + teamName: json['teamName'] as String?, + scene: json['scene'] as int?, + sceneCustomName: json['sceneCustomName'] as String?, + ); + } + + @override + String toString() { + return 'UpdateTeamInfoRequest{teamName: $teamName, scene: $scene, sceneCustomName: $sceneCustomName}'; + } +} diff --git a/lib/api/model/team/response/team_info_response.dart b/lib/api/model/team/response/team_info_response.dart index 8a53ef3..40cb716 100644 --- a/lib/api/model/team/response/team_info_response.dart +++ b/lib/api/model/team/response/team_info_response.dart @@ -1,12 +1,14 @@ class TeamInfoResponse { - final int? id; // 团队ID - final String? teamNo; // 团队编号 - final String? teamName; // 团队名称 - final String? teamCode; // 团队邀请码 - final int? scene; // 场景ID - final String? sceneCustomName; // 其他场景名称 - final String? personNo; // 人员编号 - final bool? isOwner; // 是否我的团队 + int? id; // 团队ID + String? teamNo; // 团队编号 + String? teamName; // 团队名称 + String? teamCode; // 团队邀请码 + int? scene; // 场景ID + String? sceneName; // 场景ID + String? sceneCustomName; // 其他场景名称 + String? personNo; // 人员编号 + bool? isOwner; // 是否我的团队 + TeamCloudInfo? cloudInfo; TeamInfoResponse({ this.id, @@ -14,9 +16,11 @@ class TeamInfoResponse { this.teamName, this.teamCode, this.scene, + this.sceneName, this.sceneCustomName, this.personNo, this.isOwner, + this.cloudInfo, }); // 从JSON构造函数 @@ -27,9 +31,11 @@ class TeamInfoResponse { teamName: json['teamName'] as String?, teamCode: json['teamCode'] as String?, scene: json['scene'] as int?, + sceneName: json['sceneName'] as String?, sceneCustomName: json['sceneCustomName'] as String?, personNo: json['personNo'] as String?, isOwner: json['isOwner'] as bool?, + cloudInfo: json['cloudInfo'] != null ? TeamCloudInfo.fromJson(json['cloudInfo']) : null, ); } @@ -41,9 +47,11 @@ class TeamInfoResponse { 'teamName': teamName, 'teamCode': teamCode, 'scene': scene, + 'sceneName': sceneName, 'sceneCustomName': sceneCustomName, 'personNo': personNo, 'isOwner': isOwner, + 'cloudInfo': cloudInfo?.toJson(), }; } @@ -51,7 +59,34 @@ class TeamInfoResponse { @override String toString() { return 'TeamInfoResponse{id: $id, teamNo: $teamNo, teamName: $teamName, teamCode: $teamCode, ' - 'scene: $scene, sceneCustomName: $sceneCustomName, personNo: $personNo, ' + 'scene: $scene, sceneCustomName: $sceneCustomName,' + ' sceneName: $sceneName, ' + ' personNo: $personNo, ' + ' cloudInfo: $cloudInfo,' ' isOwner: $isOwner}'; } } + +class TeamCloudInfo { + final String? username; + final String? password; + final int? uid; + + TeamCloudInfo({this.username, this.password, this.uid}); + + factory TeamCloudInfo.fromJson(Map json) { + return TeamCloudInfo( + username: json['username'] as String?, + password: json['password'] as String?, + uid: json['cloud_uid'] as int?, + ); + } + + Map toJson() { + return { + 'username': username, + 'password': password, + 'uid': uid, + }; + } +} diff --git a/lib/api/service/team_api_service.dart b/lib/api/service/team_api_service.dart index 8ad960f..53ab5f6 100644 --- a/lib/api/service/team_api_service.dart +++ b/lib/api/service/team_api_service.dart @@ -5,6 +5,7 @@ import 'package:starwork_flutter/api/base_api_service.dart'; import 'package:starwork_flutter/api/model/team/request/bind_team_star_cloud_account_request.dart'; import 'package:starwork_flutter/api/model/team/request/change_current_team_request.dart'; import 'package:starwork_flutter/api/model/team/request/create_team_request.dart'; +import 'package:starwork_flutter/api/model/team/request/update_team_info_request.dart'; import 'package:starwork_flutter/api/model/team/response/all_team_list_response.dart'; import 'package:starwork_flutter/api/model/team/response/create_team_response.dart'; import 'package:starwork_flutter/api/model/team/response/scene_info_response.dart'; @@ -75,4 +76,17 @@ class TeamApiService { fromJson: (data) => SceneInfoResponseList.fromJson(data), ); } + + // 修改团队信息 + Future> requestUpdateTeamInfo({ + required UpdateTeamInfoRequest request, + }) { + return _api.makeRequest( + // 通过实例调用 + path: ApiPath.updateTeamInfo, + method: HttpConstant.post, + data: request, + fromJson: (data) {}, + ); + } } diff --git a/lib/base/base_controller.dart b/lib/base/base_controller.dart index 6fa1bba..920760a 100644 --- a/lib/base/base_controller.dart +++ b/lib/base/base_controller.dart @@ -9,6 +9,10 @@ class BaseController extends GetxController { EasyLoading.showToast(message); } + void showFunctionNotOpen() { + EasyLoading.showToast('功能未开放'.tr); + } + void showLoading() { EasyLoading.show(status: 'loading...'); } @@ -21,6 +25,10 @@ class BaseController extends GetxController { EasyLoading.showSuccess(message.tr); } + void showUpdateSuccess() { + EasyLoading.showSuccess('修改成功'.tr); + } + void showError({String message = '操作失败'}) { EasyLoading.showError(message.tr); } diff --git a/lib/common/widgets/custom_app_bar_widget.dart b/lib/common/widgets/custom_app_bar_widget.dart deleted file mode 100644 index 44a8135..0000000 --- a/lib/common/widgets/custom_app_bar_widget.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:get/get.dart'; - -class CustomAppBarWidget extends StatelessWidget implements PreferredSizeWidget { - final String title; - final List? actions; - final VoidCallback? onBack; - final Color? backgroundColor; - - const CustomAppBarWidget({ - Key? key, - required this.title, - this.actions, - this.onBack, - this.backgroundColor, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return AppBar( - backgroundColor: backgroundColor ?? Colors.white, - elevation: 0, - surfaceTintColor: Colors.transparent, - shadowColor: Colors.transparent, - scrolledUnderElevation: 0, - leading: IconButton( - icon: const Icon(Icons.arrow_back_ios_new_rounded), - onPressed: onBack ?? () { - Navigator.of(context).pop(); - }, - ), - title: Row( - children: [ - Text( - title.tr, - style: TextStyle( - fontSize: 18.sp, - fontWeight: FontWeight.w500, - color: Colors.black87, - ), - ), - ], - ), - actions: actions, - ); - } - - @override - Size get preferredSize => const Size.fromHeight(kToolbarHeight); -} \ No newline at end of file diff --git a/lib/common/widgets/custom_cell_list_widget.dart b/lib/common/widgets/custom_cell_list_widget.dart new file mode 100644 index 0000000..8a7ac7e --- /dev/null +++ b/lib/common/widgets/custom_cell_list_widget.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:starwork_flutter/common/widgets/custom_cell_widget.dart'; + +class CustomCellListWidget extends StatelessWidget { + const CustomCellListWidget({ + super.key, + required this.children, + }); + + final List children; + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(8.r)), + ), + padding: EdgeInsets.symmetric( + horizontal: 10.w, + ), + child: Column( + children: [ + for (int i = 0; i < children.length; i++) ...[ + children[i], + if (i < children.length - 1) + Divider( + height: 0.5.h, + thickness: 0.5.h, + color: Colors.grey[300], + ), + ], + ], + ), + ); + } +} diff --git a/lib/common/widgets/custom_cell_widget.dart b/lib/common/widgets/custom_cell_widget.dart new file mode 100644 index 0000000..dbe41d4 --- /dev/null +++ b/lib/common/widgets/custom_cell_widget.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class CustomCellWidget extends StatelessWidget { + const CustomCellWidget({ + super.key, + required this.leftText, + this.rightWidget, + this.onTap, + }); + + final String leftText; + final Widget? rightWidget; + final GestureTapCallback? onTap; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(8.r)), + ), + margin: EdgeInsets.symmetric(vertical: 10.h), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + leftText, + style: TextStyle( + fontSize: 14.sp, + color: Colors.black87, + fontWeight: FontWeight.w400, + ), + ), + rightWidget ?? + Text( + '未填写', + style: TextStyle( + fontSize: 14.sp, + color: Colors.black54, + fontWeight: FontWeight.w400, + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/common/widgets/custom_dialog_widget.dart b/lib/common/widgets/custom_dialog_widget.dart index 5bb3d25..3c3096d 100644 --- a/lib/common/widgets/custom_dialog_widget.dart +++ b/lib/common/widgets/custom_dialog_widget.dart @@ -82,7 +82,6 @@ class _CustomDialogWidgetState extends State { // 右侧文本占一半 child: GestureDetector( onTap: () { - Get.back(); widget.onConfirm(); }, child: Container( diff --git a/lib/common/widgets/custome_app_bar_wdiget.dart b/lib/common/widgets/custome_app_bar_wdiget.dart new file mode 100644 index 0000000..20c6103 --- /dev/null +++ b/lib/common/widgets/custome_app_bar_wdiget.dart @@ -0,0 +1,52 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class CustomAppBarWidget extends StatelessWidget implements PreferredSizeWidget { + final String title; + final List? actions; + final Widget? leading; + final bool centerTitle; + final Color? backgroundColor; + final double? elevation; + + const CustomAppBarWidget({ + super.key, + required this.title, + this.actions, + this.leading, + this.centerTitle = true, + this.backgroundColor = Colors.white, + this.elevation, + }); + + @override + Widget build(BuildContext context) { + // 判断是否需要显示返回按钮 + bool showBackButton = ModalRoute.of(context)?.canPop ?? false; + return AppBar( + title: Text( + title, + style: TextStyle( + fontSize: 18.sp, + fontWeight: FontWeight.w500, + ), + ), + actions: actions, + // 根据是否有自定义leading来决定使用什么 + leading: leading ?? + (showBackButton + ? IconButton( + icon: const Icon(Icons.arrow_back_ios_new_rounded), + onPressed: () => Navigator.of(context).pop(), + ) + : null), + // 当有leading时标题默认左对齐,否则按centerTitle参数决定 + centerTitle: false, + backgroundColor: backgroundColor, + elevation: elevation, + ); + } + + @override + Size get preferredSize => const Size.fromHeight(kToolbarHeight); +} diff --git a/lib/routes/app_pages.dart b/lib/routes/app_pages.dart index 737ccd1..b6f6532 100644 --- a/lib/routes/app_pages.dart +++ b/lib/routes/app_pages.dart @@ -18,6 +18,8 @@ import 'package:starwork_flutter/views/main/main_binding.dart'; import 'package:starwork_flutter/views/main/main_view.dart'; import 'package:starwork_flutter/views/team/joinTeam/join_team_binding.dart'; import 'package:starwork_flutter/views/team/joinTeam/join_team_view.dart'; +import 'package:starwork_flutter/views/team/teamManage/teamInfo/team_info_binding.dart'; +import 'package:starwork_flutter/views/team/teamManage/teamInfo/team_info_view.dart'; import 'package:starwork_flutter/views/team/teamManage/team_manage_binding.dart'; import 'package:starwork_flutter/views/team/teamManage/team_manage_view.dart'; import 'package:starwork_flutter/views/team/teamNotice/teamNoticeDetails/team_notice_details_binding.dart'; @@ -116,5 +118,10 @@ class AppPages { page: () => TeamManageView(), binding: TeamManageBinding(), ), + GetPage( + name: AppRoutes.teamInfo, + page: () => TeamInfoView(), + binding: TeamInfoBinding(), + ), ]; } diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index 138551f..ebe84e7 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -16,4 +16,5 @@ class AppRoutes{ static const String teamCreateTeam = '/team/createTeam'; static const String teamJoinTeam = '/team/joinTeam'; static const String teamManage = '/team/teamManage'; + static const String teamInfo = '/team/teamInfo'; } \ No newline at end of file diff --git a/lib/views/login/login_controller.dart b/lib/views/login/login_controller.dart index 1907acd..83e4a6c 100644 --- a/lib/views/login/login_controller.dart +++ b/lib/views/login/login_controller.dart @@ -47,6 +47,7 @@ class LoginController extends BaseController { title: '欢迎使用星勤'.tr, content: '1', onConfirm: () async { + Get.back(); isPrivacyAgreementValid.value = 1; Get.toNamed( AppRoutes.inputVerificationCode, diff --git a/lib/views/main/main_binding.dart b/lib/views/main/main_binding.dart index 033ff21..6514ac6 100644 --- a/lib/views/main/main_binding.dart +++ b/lib/views/main/main_binding.dart @@ -4,6 +4,8 @@ import 'package:starwork_flutter/views/login/login_controller.dart'; import 'package:starwork_flutter/views/main/main_controller.dart'; import 'package:starwork_flutter/views/messages/messages_controller.dart'; import 'package:starwork_flutter/views/mine/mine_controller.dart'; +import 'package:starwork_flutter/views/team/teamManage/team_manage_binding.dart'; +import 'package:starwork_flutter/views/team/teamManage/team_manage_controller.dart'; class MainBinding extends Bindings { @override diff --git a/lib/views/main/main_controller.dart b/lib/views/main/main_controller.dart index 30cb897..45931b8 100644 --- a/lib/views/main/main_controller.dart +++ b/lib/views/main/main_controller.dart @@ -4,6 +4,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:starcloud/sdk/entity/cloud_user_info.dart'; +import 'package:starcloud/sdk/starcloud.dart'; import 'package:starwork_flutter/api/model/team/request/change_current_team_request.dart'; import 'package:starwork_flutter/api/model/team/response/team_info_response.dart'; import 'package:starwork_flutter/api/service/team_api_service.dart'; @@ -132,6 +134,17 @@ class MainController extends BaseController { if (changeCurrentTeamResponse.isSuccess) { AppLogger.highlight('切换当前团队成功'); selectedTeam.value = teamInfo; + + // 如果teamInfo中的cloudInfo不为空,则设置云账号 + if (teamInfo.cloudInfo != null) { + StarCloudSDK.instance.setCloudAccounts([ + CloudUserInfo( + username: teamInfo.cloudInfo!.username!, + password: teamInfo.cloudInfo!.password!, + uid: teamInfo.cloudInfo!.uid!, + ) + ]); + } } } } diff --git a/lib/views/main/widget/main_left_drawer_widget.dart b/lib/views/main/widget/main_left_drawer_widget.dart index 88370ff..d1581c6 100644 --- a/lib/views/main/widget/main_left_drawer_widget.dart +++ b/lib/views/main/widget/main_left_drawer_widget.dart @@ -164,7 +164,9 @@ class _MainLeftDrawerWidgetState extends State { visible: team.isOwner ?? false, child: GestureDetector( onTap: () { - Get.toNamed(AppRoutes.teamManage); + Get.toNamed(AppRoutes.teamManage, arguments: { + 'teamInfo': team.toJson(), + }); }, child: Container( padding: EdgeInsets.all(8.w), diff --git a/lib/views/team/joinTeam/join_team_view.dart b/lib/views/team/joinTeam/join_team_view.dart index b469a5c..975111d 100644 --- a/lib/views/team/joinTeam/join_team_view.dart +++ b/lib/views/team/joinTeam/join_team_view.dart @@ -6,7 +6,7 @@ import 'package:pinput/pinput.dart'; import 'package:starwork_flutter/base/app_logger.dart'; import 'package:starwork_flutter/common/constant/app_colors.dart'; import 'package:starwork_flutter/common/constant/app_toast_messages.dart'; -import 'package:starwork_flutter/common/widgets/custom_app_bar_widget.dart'; +import 'package:starwork_flutter/common/widgets/custome_app_bar_wdiget.dart'; import 'package:starwork_flutter/extension/function_extension.dart'; import 'package:starwork_flutter/views/team/joinTeam/join_team_controller.dart'; diff --git a/lib/views/team/teamManage/teamInfo/team_info_binding.dart b/lib/views/team/teamManage/teamInfo/team_info_binding.dart new file mode 100644 index 0000000..4c8277c --- /dev/null +++ b/lib/views/team/teamManage/teamInfo/team_info_binding.dart @@ -0,0 +1,9 @@ +import 'package:get/get.dart'; +import 'package:starwork_flutter/views/team/teamManage/teamInfo/team_info_controller.dart'; + +class TeamInfoBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut(() => TeamInfoController()); + } +} diff --git a/lib/views/team/teamManage/teamInfo/team_info_controller.dart b/lib/views/team/teamManage/teamInfo/team_info_controller.dart new file mode 100644 index 0000000..9bce63b --- /dev/null +++ b/lib/views/team/teamManage/teamInfo/team_info_controller.dart @@ -0,0 +1,70 @@ +import 'package:flutter/widgets.dart'; +import 'package:get/get.dart'; +import 'package:starwork_flutter/api/model/team/request/update_team_info_request.dart'; +import 'package:starwork_flutter/api/model/team/response/scene_info_response.dart'; +import 'package:starwork_flutter/api/model/team/response/team_info_response.dart'; +import 'package:starwork_flutter/api/service/team_api_service.dart'; +import 'package:starwork_flutter/base/base_controller.dart'; + +class TeamInfoController extends BaseController { + final teamApi = Get.find(); + + // 接收页面传递的参数 + final teamInfo = Rx(null); + + TextEditingController teamNameInputController = TextEditingController(); + + // 用于存储选中的使用场景 + final selectedUseCase = Rx(null); + + // 用于存储场景列表 + final useCases = [].obs; + + @override + void onInit() { + super.onInit(); + requestAllSceneInfoList(); + } + + void updateTeamName(String teamName) async { + var updateTeamInfoResponse = await teamApi.requestUpdateTeamInfo( + request: UpdateTeamInfoRequest( + teamName: teamName, + ), + ); + if (updateTeamInfoResponse.isSuccess) { + showUpdateSuccess(); + // 将选中的值赋值给当前的teamInfo + teamInfo.value!.teamName = teamName; + teamInfo.refresh(); + } + } + + /// 请求团队使用场景信息 + void requestAllSceneInfoList() async { + showLoading(); + + var sceneList = await teamApi.requestAllSceneInfoList(); + if (sceneList.isSuccess) { + // 使用场景列表 + useCases.value = sceneList.data?.list ?? []; + useCases.refresh(); + } + hideLoading(); + } + + void updateTeamUseCase() async { + var updateTeamInfoResponse = await teamApi.requestUpdateTeamInfo( + request: UpdateTeamInfoRequest( + scene: selectedUseCase.value!.id, + ), + ); + if (updateTeamInfoResponse.isSuccess) { + showUpdateSuccess(); + // 将选中的值赋值给当前的teamInfo + teamInfo.value!.sceneName = selectedUseCase.value!.name; + teamInfo.value!.scene = selectedUseCase.value!.id; + teamInfo.refresh(); + } + } +} diff --git a/lib/views/team/teamManage/teamInfo/team_info_view.dart b/lib/views/team/teamManage/teamInfo/team_info_view.dart new file mode 100644 index 0000000..63b900a --- /dev/null +++ b/lib/views/team/teamManage/teamInfo/team_info_view.dart @@ -0,0 +1,389 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:starwork_flutter/api/model/team/response/team_info_response.dart'; +import 'package:starwork_flutter/common/constant/app_colors.dart'; +import 'package:starwork_flutter/common/widgets/custom_cell_list_widget.dart'; +import 'package:starwork_flutter/common/widgets/custom_cell_widget.dart'; +import 'package:starwork_flutter/common/widgets/custome_app_bar_wdiget.dart'; +import 'package:starwork_flutter/views/team/teamManage/teamInfo/team_info_controller.dart'; + +class TeamInfoView extends GetView { + @override + Widget build(BuildContext context) { + // 获取传递的参数 + final arguments = Get.arguments as Map?; + final teamInfo = arguments?['teamInfo'] as Map?; + if (teamInfo != null) { + controller.teamInfo.value = TeamInfoResponse.fromJson(teamInfo); + } + + return Scaffold( + backgroundColor: AppColors.scaffoldBackgroundColor, + appBar: CustomAppBarWidget(title: '团队信息'.tr), + body: Padding( + padding: EdgeInsets.symmetric( + horizontal: 10.w, + vertical: 10.h, + ), + child: Column( + children: [ + CustomCellListWidget( + children: [ + CustomCellWidget( + onTap: () { + controller.teamNameInputController.text = controller.teamInfo.value?.teamName ?? ''; + _showCustomDialog( + title: '修改团队名称'.tr, + onConfirm: () { + if (controller.teamNameInputController.text.isEmpty) { + controller.showToast('请先输入团队名称'.tr); + return; + } + controller.updateTeamName(controller.teamNameInputController.text); + Get.back(); + }, + ); + }, + leftText: '团队名称'.tr, + rightWidget: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Obx( + () => Text( + controller.teamInfo.value?.teamName ?? '', + style: TextStyle( + fontSize: 14.sp, + color: Colors.black54, + fontWeight: FontWeight.w400, + ), + ), + ), + SizedBox( + width: 4.w, + ), + Icon( + Icons.arrow_forward_ios_rounded, + size: 16.sp, + color: Colors.grey[300], + ) + ], + ), + ), + CustomCellWidget( + leftText: '团队ID'.tr, + onTap: () { + // 复制到剪切板 + Clipboard.setData(ClipboardData(text: controller.teamInfo.value?.teamNo ?? '')); + controller.showToast('内容已复制'.tr); + }, + rightWidget: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + controller.teamInfo.value?.teamNo ?? '', + style: TextStyle( + fontSize: 14.sp, + color: Colors.black54, + fontWeight: FontWeight.w400, + ), + ), + SizedBox( + width: 4.w, + ), + Icon( + Icons.library_books_rounded, + size: 16.sp, + color: Colors.grey, + ) + ], + ), + ), + ], + ), + SizedBox(height: 10.h), + CustomCellListWidget( + children: [ + CustomCellWidget( + onTap: () { + _showUpdateTeamUseCaseDialog(onConfirm: () { + Get.back(); + _showBottomSheet(context); + }); + }, + leftText: '使用场景'.tr, + rightWidget: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Obx( + () => Text( + controller.teamInfo.value?.sceneName ?? '', + style: TextStyle( + fontSize: 14.sp, + color: Colors.black54, + fontWeight: FontWeight.w400, + ), + ), + ), + SizedBox( + width: 4.w, + ), + Icon( + Icons.arrow_forward_ios_rounded, + size: 16.sp, + color: Colors.grey[300], + ) + ], + ), + ), + CustomCellWidget( + leftText: '团队认证'.tr, + onTap: () { + controller.showFunctionNotOpen(); + }, + rightWidget: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + '未认证', + style: TextStyle( + fontSize: 14.sp, + color: Colors.black54, + fontWeight: FontWeight.w400, + ), + ), + SizedBox( + width: 4.w, + ), + Icon( + Icons.arrow_forward_ios_rounded, + size: 16.sp, + color: Colors.grey[300], + ) + ], + ), + ), + ], + ), + SizedBox(height: 10.h), + CustomCellListWidget( + children: [ + CustomCellWidget( + leftText: 'VIP服务'.tr, + onTap: () { + controller.showFunctionNotOpen(); + }, + rightWidget: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + '未开通', + style: TextStyle( + fontSize: 14.sp, + color: Colors.black54, + fontWeight: FontWeight.w400, + ), + ), + SizedBox( + width: 4.w, + ), + Icon( + Icons.arrow_forward_ios_rounded, + size: 16.sp, + color: Colors.grey[300], + ) + ], + ), + ), + ], + ) + ], + ), + ), + ); + } + + void _showCustomDialog({ + required String title, + required VoidCallback onConfirm, + }) { + controller.showCustomDialog( + title: title, + content: Padding( + padding: EdgeInsets.symmetric( + horizontal: 10.w, + vertical: 10.h, + ), + child: TextField( + controller: controller.teamNameInputController, + keyboardType: TextInputType.text, + textInputAction: TextInputAction.done, + decoration: InputDecoration( + hintText: controller.teamInfo.value!.teamName!, + border: const UnderlineInputBorder(), + suffixIcon: controller.teamNameInputController.text.isNotEmpty + ? IconButton( + icon: const Icon(Icons.clear, color: Colors.grey), + onPressed: () { + controller.teamNameInputController.clear(); // 清空输入 + }, + ) + : null, + focusedBorder: OutlineInputBorder( + borderSide: const BorderSide( + color: Colors.blue, + width: 1.5, + ), + borderRadius: BorderRadius.circular(8.0.r), + ), + enabledBorder: OutlineInputBorder( + borderSide: const BorderSide(color: Colors.grey), + borderRadius: BorderRadius.circular(8.0.r), + ), + ), + ), + ), + onConfirm: onConfirm, + confirmText: '确认修改'.tr, + ); + } + + void _showUpdateTeamUseCaseDialog({ + required VoidCallback onConfirm, + }) { + controller.showCustomDialog( + title: '提示'.tr, + content: Padding( + padding: EdgeInsets.symmetric( + horizontal: 10.w, + vertical: 10.h, + ), + child: Text( + '每个团队仅可以修改1次使用场景,确认要修改吗?'.tr, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 14.sp, + fontWeight: FontWeight.w400, + color: Colors.black, + ), + ), + ), + onConfirm: onConfirm, + confirmText: '确认修改'.tr, + ); + } + + void _showBottomSheet(BuildContext context) { + showModalBottomSheet( + context: context, + backgroundColor: Colors.white, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.zero, + ), + builder: (context) { + return Container( + height: 448.h, + padding: EdgeInsets.symmetric( + horizontal: 10.w, + vertical: 10.h, + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + TextButton( + onPressed: () { + Get.back(); + }, + child: Text( + '取消', + style: TextStyle( + fontSize: 16.sp, + color: Colors.grey, + fontWeight: FontWeight.w500, + ), + ), + ), + Text( + '请选择使用场景', + style: TextStyle( + fontSize: 14.sp, + fontWeight: FontWeight.w400, + ), + ), + TextButton( + onPressed: () { + if (controller.selectedUseCase.value == null) { + controller.showToast('请先选择使用场景'.tr); + return; + } + controller.updateTeamUseCase(); + Get.back(); + }, + child: Text( + '确认', + style: TextStyle( + fontSize: 16.sp, + color: Colors.blue, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + SizedBox(height: 10.h), + Expanded( + child: Obx( + () => GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 3, + crossAxisSpacing: 10.h, + mainAxisSpacing: 10.w, + ), + itemCount: controller.useCases.length, + itemBuilder: (context, index) { + return Obx( + () => GestureDetector( + onTap: () { + controller.selectedUseCase.value = controller.useCases[index]; + }, + child: Container( + decoration: BoxDecoration( + color: controller.selectedUseCase.value == controller.useCases[index] + ? Colors.blue.withOpacity(0.2) + : Colors.grey[200], + borderRadius: BorderRadius.circular(8.r), + border: controller.selectedUseCase.value == controller.useCases[index] + ? Border.all(color: Colors.blue, width: 1.5) + : null, + ), + alignment: Alignment.center, + child: Text( + controller.useCases[index].name ?? '', + style: TextStyle( + color: controller.selectedUseCase.value == controller.useCases[index] + ? Colors.blue + : Colors.grey[700], + fontSize: 14.sp, + ), + ), + ), + ), + ); + }, + ), + ), + ), + ], + ), + ); + }, + ); + } +} diff --git a/lib/views/team/teamManage/team_manage_binding.dart b/lib/views/team/teamManage/team_manage_binding.dart index 8c6697e..7b12b75 100644 --- a/lib/views/team/teamManage/team_manage_binding.dart +++ b/lib/views/team/teamManage/team_manage_binding.dart @@ -6,4 +6,4 @@ class TeamManageBinding extends Bindings { void dependencies() { Get.lazyPut(() => TeamManageController()); } -} +} \ No newline at end of file diff --git a/lib/views/team/teamManage/team_manage_controller.dart b/lib/views/team/teamManage/team_manage_controller.dart index 57eb01d..0d2c2fb 100644 --- a/lib/views/team/teamManage/team_manage_controller.dart +++ b/lib/views/team/teamManage/team_manage_controller.dart @@ -1,5 +1,14 @@ +import 'package:get/get.dart'; +import 'package:starwork_flutter/api/model/team/response/team_info_response.dart'; +import 'package:starwork_flutter/base/app_logger.dart'; import 'package:starwork_flutter/base/base_controller.dart'; -class TeamManageController extends BaseController{ +class TeamManageController extends BaseController { + // 接收页面传递的参数 + final teamInfo = Rx(null); -} \ No newline at end of file + @override + void onInit() { + super.onInit(); + } +} diff --git a/lib/views/team/teamManage/team_manage_view.dart b/lib/views/team/teamManage/team_manage_view.dart index 099e86d..0eaf763 100644 --- a/lib/views/team/teamManage/team_manage_view.dart +++ b/lib/views/team/teamManage/team_manage_view.dart @@ -3,14 +3,25 @@ import 'package:flutter/material.dart'; import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:starwork_flutter/api/model/team/response/team_info_response.dart'; +import 'package:starwork_flutter/base/app_logger.dart'; import 'package:starwork_flutter/common/constant/app_colors.dart'; -import 'package:starwork_flutter/common/widgets/custom_app_bar_widget.dart'; +import 'package:starwork_flutter/common/widgets/custome_app_bar_wdiget.dart'; import 'package:starwork_flutter/extension/function_extension.dart'; +import 'package:starwork_flutter/routes/app_routes.dart'; import 'package:starwork_flutter/views/team/teamManage/team_manage_controller.dart'; class TeamManageView extends GetView { + const TeamManageView({super.key}); + @override Widget build(BuildContext context) { + // 获取传递的参数 + final arguments = Get.arguments as Map?; + final teamInfo = arguments?['teamInfo'] as Map?; + if (teamInfo != null) { + controller.teamInfo.value = TeamInfoResponse.fromJson(teamInfo); + } return Scaffold( backgroundColor: AppColors.scaffoldBackgroundColor, appBar: CustomAppBarWidget( @@ -24,6 +35,10 @@ class TeamManageView extends GetView { SizedBox( height: 10.h, ), + _buildOrganizationalStructure(), + SizedBox( + height: 10.h, + ), Expanded( child: _buildOther(), ), @@ -44,7 +59,7 @@ class TeamManageView extends GetView { child: ElevatedButton( onPressed: () {}.debounce(), style: ElevatedButton.styleFrom( - backgroundColor: Colors.grey[200], + backgroundColor: Colors.grey[100], padding: EdgeInsets.symmetric(vertical: 12.h), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.r)), ), @@ -92,89 +107,99 @@ class TeamManageView extends GetView { } _buildHeadRow() { - return Container( - padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8.r), - color: Colors.blue, - boxShadow: [ - BoxShadow( - color: Colors.blue.withOpacity(0.2), - spreadRadius: 2, - blurRadius: 3, - offset: const Offset(0, 3), // changes position of shadow - ), - ], - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - '团队名称', - style: TextStyle( - fontSize: 16.sp, - fontWeight: FontWeight.w500, - color: Colors.white, + return GestureDetector( + onTap: () { + Get.toNamed( + AppRoutes.teamInfo, + arguments: { + 'teamInfo': controller.teamInfo.value!.toJson(), + }, + ); + }, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8.r), + color: Colors.blue, + boxShadow: [ + BoxShadow( + color: Colors.blue.withOpacity(0.2), + spreadRadius: 2, + blurRadius: 3, + offset: const Offset(0, 3), // changes position of shadow + ), + ], + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + controller.teamInfo.value!.teamName!, + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.w500, + color: Colors.white, + ), ), - ), - SizedBox( - height: 8.h, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - padding: EdgeInsets.symmetric(horizontal: 4.w, vertical: 2.h), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(8.r), - color: Colors.white.withOpacity(0.3), + SizedBox( + height: 8.h, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + padding: EdgeInsets.symmetric(horizontal: 4.w, vertical: 2.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8.r), + color: Colors.white.withOpacity(0.3), + ), + child: Text( + controller.teamInfo.value!.sceneName!, + style: TextStyle( + fontSize: 10.sp, + fontWeight: FontWeight.w500, + color: Colors.white, + ), + ), ), - child: Text( - '小区/公寓'.tr, + SizedBox( + width: 4.w, + ), + Text( + controller.teamInfo.value!.teamNo!, style: TextStyle( fontSize: 10.sp, fontWeight: FontWeight.w500, color: Colors.white, ), - ), - ), - SizedBox( - width: 4.w, - ), - Text( - 'TD01022881', - style: TextStyle( - fontSize: 10.sp, - fontWeight: FontWeight.w500, - color: Colors.white, - ), - ) - ], - ) - ], - ), - const Icon( - Icons.arrow_forward_ios_rounded, - color: Colors.white, - ) - ], + ) + ], + ) + ], + ), + const Icon( + Icons.arrow_forward_ios_rounded, + color: Colors.white, + ) + ], + ), ), ); } - _buildOther() { + _buildOrganizationalStructure() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '其他', + '组织架构', style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w500, - color: Colors.grey[400], + color: Colors.grey[500], ), ), SizedBox( @@ -196,7 +221,180 @@ class TeamManageView extends GetView { Row( children: [ Icon( - Icons.assignment_outlined, + Icons.perm_contact_calendar_rounded, + color: Colors.blue.withOpacity(0.8), + ), + SizedBox( + width: 8.w, + ), + Text( + '人员配置', + style: TextStyle( + fontSize: 14.sp, + fontWeight: FontWeight.w500, + color: Colors.black87, + ), + ), + ], + ), + Icon( + Icons.arrow_forward_ios_rounded, + color: Colors.grey, + size: 14.sp, + ) + ], + ), + + SizedBox(height: 10.h), + // 分割线 + Divider( + height: 1.h, + color: Colors.grey.withOpacity(0.2), + ), + SizedBox(height: 10.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: [ + Icon( + Icons.person, + color: Colors.blue.withOpacity(0.8), + ), + SizedBox( + width: 8.w, + ), + Text( + '权限分配', + style: TextStyle( + fontSize: 14.sp, + fontWeight: FontWeight.w500, + color: Colors.black87, + ), + ), + ], + ), + Icon( + Icons.arrow_forward_ios_rounded, + color: Colors.grey, + size: 14.sp, + ) + ], + ), + SizedBox(height: 10.h), + Divider( + height: 1.h, + color: Colors.grey.withOpacity(0.2), + ), + SizedBox(height: 10.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: [ + Icon( + Icons.switch_account_rounded, + color: Colors.blue, + ), + SizedBox( + width: 8.w, + ), + Text( + '新用户审核', + style: TextStyle( + fontSize: 14.sp, + fontWeight: FontWeight.w500, + color: Colors.black87, + ), + ), + ], + ), + Icon( + Icons.arrow_forward_ios_rounded, + color: Colors.grey, + size: 14.sp, + ) + ], + ) + ], + ), + ) + ], + ); + } + + _buildOther() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '其他', + style: TextStyle( + fontSize: 14.sp, + fontWeight: FontWeight.w500, + color: Colors.grey[500], + ), + ), + SizedBox( + height: 10.h, + ), + Container( + width: double.infinity, + padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8.r), + color: Colors.white, + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: [ + Icon( + Icons.assessment_rounded, + color: Colors.blue.withOpacity(0.8), + ), + SizedBox( + width: 8.w, + ), + Text( + '设备管理', + style: TextStyle( + fontSize: 14.sp, + fontWeight: FontWeight.w500, + color: Colors.black87, + ), + ), + ], + ), + Icon( + Icons.arrow_forward_ios_rounded, + color: Colors.grey, + size: 14.sp, + ) + ], + ), + + SizedBox(height: 10.h), + // 分割线 + Divider( + height: 1.h, + color: Colors.grey.withOpacity(0.2), + ), + SizedBox(height: 10.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: [ + Icon( + Icons.assessment_rounded, color: Colors.blue.withOpacity(0.8), ), SizedBox( @@ -234,7 +432,7 @@ class TeamManageView extends GetView { Row( children: [ Icon( - Icons.assignment_outlined, + Icons.assignment, color: Colors.blue.withOpacity(0.8), ), SizedBox( @@ -270,8 +468,8 @@ class TeamManageView extends GetView { Row( children: [ Icon( - Icons.assignment_outlined, - color: Colors.blue.withOpacity(0.8), + Icons.qr_code_2_outlined, + color: Colors.blue, ), SizedBox( width: 8.w, diff --git a/lib/views/team/teamNotice/team_notice_view.dart b/lib/views/team/teamNotice/team_notice_view.dart index e3ef991..b5f1c69 100644 --- a/lib/views/team/teamNotice/team_notice_view.dart +++ b/lib/views/team/teamNotice/team_notice_view.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:starwork_flutter/common/constant/app_colors.dart'; -import 'package:starwork_flutter/common/widgets/custom_app_bar_widget.dart'; import 'package:starwork_flutter/views/team/teamNotice/team_notice_controller.dart'; class TeamNoticeView extends GetView { @@ -12,8 +11,31 @@ class TeamNoticeView extends GetView { @override Widget build(BuildContext context) { return Scaffold( - appBar: CustomAppBarWidget( - title: '公告'.tr, + appBar: AppBar( + backgroundColor: Colors.white, + elevation: 0, + surfaceTintColor: Colors.transparent, + shadowColor: Colors.transparent, + scrolledUnderElevation: 0, + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios_new_rounded), // 替换为任意图标,如关闭、菜单等 + onPressed: () { + // 自定义逻辑,例如:关闭页面、退出流程等 + Navigator.of(context).pop(); + }, + ), + title: Row( + children: [ + Text( + '公告'.tr, + style: TextStyle( + fontSize: 18.sp, + fontWeight: FontWeight.w500, + color: Colors.black87, + ), + ), + ], + ), ), body: Column( children: [