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

333 lines
15 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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),
),
),
);
}
}