starwork_flutter/lib/views/team/selectPerson/select_person_view.dart

333 lines
15 KiB
Dart
Raw Normal View History

import 'package:animated_tree_view/animated_tree_view.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:starwork_flutter/api/model/team/response/depart_list_reponse.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_images.dart';
import 'package:starwork_flutter/common/widgets/custome_app_bar_wdiget.dart';
import 'package:starwork_flutter/extension/function_extension.dart';
import 'select_person_controller.dart';
class SelectPersonView extends GetView<SelectPersonController> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.scaffoldBackgroundColor,
appBar: CustomAppBarWidget(
title: '选择用户'.tr,
backgroundColor: AppColors.scaffoldBackgroundColor,
leading: IconButton(
icon: const Icon(
Icons.clear_rounded,
color: Colors.black,
),
onPressed: () => Navigator.of(context).pop(),
),
),
body: SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 10.w,
vertical: 10.h,
),
child: Column(
children: [
_buildSearchBar(),
SizedBox(
height: 10.h,
),
Container(
alignment: Alignment.centerLeft,
child: Text(
'组织架构',
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.w500,
color: Colors.grey,
),
),
),
SizedBox(
height: 10.h,
),
Expanded(
child: Obx(
() {
return Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
child: RefreshIndicator(
onRefresh: () async {
await controller.requestDepartList();
},
color: const Color(0xFF4A90E2),
backgroundColor: Colors.white,
displacement: 60.0,
edgeOffset: 0.0,
triggerMode: RefreshIndicatorTriggerMode.onEdge,
strokeWidth: 2.5,
semanticsLabel: '下拉刷新首页内容',
semanticsValue: '刷新中...',
child: TreeView.simple(
tree: controller.treeData.value ?? TreeNode.root(),
showRootNode: false,
expansionIndicatorBuilder: noExpansionIndicatorBuilder,
indentation: const Indentation(style: IndentStyle.roundJoint),
onItemTap: (item) {
if (item.data is PersonItem) {
PersonItem personInfo = item.data;
// 避免重复添加
if (!controller.selectPersonNoList.contains(personInfo.personNo) &&
personInfo.personNo != null) {
controller.selectPersonNoList.add(personInfo.personNo!);
} else {
controller.selectPersonNoList.remove(personInfo.personNo);
}
controller.selectPersonNoList.refresh();
}
},
onTreeReady: (c) {
controller.treeViewController = c;
},
builder: (context, node) {
String title = "";
DepartItem departInfo = DepartItem();
PersonItem personInfo = PersonItem();
int personNum = 0;
bool hasChildren = node.childrenAsList.isNotEmpty; // 判断是否有子节点
bool isPersonItem = node.data is PersonItem; // 判断当前节点是否是人员节点
bool isOneself = false;
bool isRootNode = false;
bool isSuper = false;
if (node.data is DepartItem) {
final depart = node.data as DepartItem;
title = depart.departName ?? "未命名部门";
personNum = depart.personNum ?? 0;
departInfo = depart;
if (hasChildren) {
title = title + "$personNum";
} else {
title = title + "0";
}
if (depart.parentId == -1) {
isRootNode = true;
}
} else if (node.data is PersonItem) {
// 处理人员节点
personInfo = node.data as PersonItem;
title = personInfo.personName ?? "未命名人员";
personInfo.roles?.forEach((role) {
if (role.isSuper == 1) {
isSuper = true;
}
});
}
return Container(
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 6.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Row(
children: [
!isPersonItem
? Container(
width: 34.w,
height: 34.w,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(8.r),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.r),
child: Icon(
Icons.folder,
size: 22.w,
color: Colors.blue,
),
),
)
: Container(
width: 34.w,
height: 34.w,
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(8.r),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.r),
child: Image(
image: const AssetImage(AppImages.defaultAvatar),
width: 22.w,
height: 22.w,
fit: BoxFit.cover,
gaplessPlayback: true,
filterQuality: FilterQuality.medium,
errorBuilder: (context, error, stackTrace) {
return Icon(
Icons.person,
size: 30.sp,
color: Colors.grey[400],
);
},
),
),
),
SizedBox(
width: 10.w,
),
Expanded(
child: Text(
title,
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w500,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
Visibility(
visible: isPersonItem,
child: Obx(
() => Checkbox(
value: controller.selectPersonNoList.contains(personInfo.personNo),
activeColor: Colors.blue,
onChanged: (value) {
if (value == true) {
// 避免重复添加
if (!controller.selectPersonNoList.contains(personInfo.personNo) &&
personInfo.id != null) {
controller.selectPersonNoList.add(personInfo.personNo!);
}
} else {
controller.selectPersonNoList.remove(personInfo.personNo);
}
controller.selectPersonNoList.refresh();
},
),
),
)
],
),
),
],
),
);
},
),
),
);
},
),
),
SizedBox(
height: 10.h,
),
Row(
children: [
Obx(
() => Text(
'已选择:${controller.selectPersonNoList.length}',
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w500,
color: Colors.blue,
),
),
),
SizedBox(
width: 20.w,
),
Expanded(
flex: 1,
child: ElevatedButton(
onPressed: () {
if (controller.selectPersonNoList.isEmpty) {
controller.showToast('请先选择一个用户'.tr);
return;
}
List<PersonItem> selectPersonList = [];
// 通过controller.selectPersonNoList 判断controoler.allPersonList对应选中的personInfo
controller.selectPersonNoList.forEach((personNo) {
controller.allPersonList.forEach((personInfo) {
if (personInfo.personNo == personNo) {
selectPersonList.add(personInfo);
}
});
});
Get.back(result: selectPersonList);
}.debounce(),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
padding: EdgeInsets.symmetric(vertical: 12.h),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.r)),
),
child: Text(
'确定'.tr,
style: TextStyle(
fontSize: 16.sp,
color: Colors.white,
fontWeight: FontWeight.w500,
),
),
),
),
],
)
],
),
),
),
);
}
_buildSearchBar() {
return TextField(
controller: controller.searchInputController,
textInputAction: TextInputAction.search,
decoration: InputDecoration(
hintText: '请输入设备名称'.tr,
hintStyle: TextStyle(
fontSize: 14.sp,
color: const Color(0xFF999999),
),
prefixIcon: const Icon(
Icons.search,
color: Color(0xFF999999),
),
filled: true,
// 启用背景填充
fillColor: const Color(0xFFf0f0f0),
// 灰色背景(可调整色值)
border: InputBorder.none,
// 设置内边距
contentPadding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Colors.blue,
width: 1.5,
),
borderRadius: BorderRadius.circular(8.0.r),
),
enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.circular(8.0.r),
),
),
);
}
}