feat: develop core form field component
This commit is contained in:
parent
7f309e999b
commit
09385a4d77
|
@ -2,6 +2,7 @@ import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:sk_base_mobile/constants/global_url.dart';
|
import 'package:sk_base_mobile/constants/global_url.dart';
|
||||||
|
import 'package:sk_base_mobile/models/base_response.dart';
|
||||||
import 'package:sk_base_mobile/services/dio.service.dart';
|
import 'package:sk_base_mobile/services/dio.service.dart';
|
||||||
import '../constants/constants.dart';
|
import '../constants/constants.dart';
|
||||||
|
|
||||||
|
@ -20,6 +21,12 @@ Future<Response> getUserInfo() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取项目信息
|
||||||
|
Future<Response<PaginationData>> getProjects(Map params) {
|
||||||
|
return DioService.dio.get<PaginationData>(Urls.getProjects,
|
||||||
|
queryParameters: {'page': 1, 'pageSize': 10, ...params});
|
||||||
|
}
|
||||||
|
|
||||||
Future<Response> logout() {
|
Future<Response> logout() {
|
||||||
return DioService.dio.post(
|
return DioService.dio.post(
|
||||||
Urls.logout,
|
Urls.logout,
|
||||||
|
|
|
@ -6,5 +6,6 @@ class Urls {
|
||||||
static String deleteAccount = 'user/deleteAccount';
|
static String deleteAccount = 'user/deleteAccount';
|
||||||
static String saveUserInfo = 'user/saveUserInfo';
|
static String saveUserInfo = 'user/saveUserInfo';
|
||||||
static String getUserInfo = 'account/profile';
|
static String getUserInfo = 'account/profile';
|
||||||
|
static String getProjects = 'project';
|
||||||
static String updateAvatar = 'user/updateAvatar';
|
static String updateAvatar = 'user/updateAvatar';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,101 @@
|
||||||
|
/// 封装http请求基础返回体
|
||||||
class BaseResponse {
|
class BaseResponse {
|
||||||
int? code;
|
int? code;
|
||||||
dynamic data;
|
dynamic data;
|
||||||
bool? fail;
|
String? message;
|
||||||
String? key;
|
|
||||||
String? msg;
|
|
||||||
bool? success;
|
|
||||||
|
|
||||||
BaseResponse(
|
BaseResponse({this.code, this.data, this.message});
|
||||||
{this.code, this.data, this.fail, this.key, this.msg, this.success});
|
|
||||||
|
|
||||||
BaseResponse.fromJson(Map<String, dynamic> json) {
|
BaseResponse.fromJson(Map<String, dynamic> json) {
|
||||||
code = json['code'];
|
code = json['code'];
|
||||||
fail = json['fail'];
|
|
||||||
key = json['key'];
|
|
||||||
data = json['data'];
|
data = json['data'];
|
||||||
msg = json['msg'];
|
message = json['message'];
|
||||||
success = json['success'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
data['code'] = code;
|
data['code'] = code;
|
||||||
data['fail'] = fail;
|
|
||||||
data['data'] = data;
|
data['data'] = data;
|
||||||
data['key'] = key;
|
data['message'] = message;
|
||||||
data['msg'] = msg;
|
|
||||||
data['success'] = success;
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 封装http请求基础返回体
|
||||||
|
class PaginationResponse {
|
||||||
|
int? code;
|
||||||
|
PaginationData? data;
|
||||||
|
String? message;
|
||||||
|
|
||||||
|
PaginationResponse({this.code, this.data, this.message});
|
||||||
|
|
||||||
|
PaginationResponse.fromJson(Map<String, dynamic> json) {
|
||||||
|
code = json['code'];
|
||||||
|
data = json['data'];
|
||||||
|
message = json['message'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['code'] = code;
|
||||||
|
data['data'] = data;
|
||||||
|
data['message'] = message;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PaginationData {
|
||||||
|
PaginationData({
|
||||||
|
required this.items,
|
||||||
|
required this.meta,
|
||||||
|
});
|
||||||
|
|
||||||
|
final List<dynamic> items;
|
||||||
|
final Meta? meta;
|
||||||
|
|
||||||
|
factory PaginationData.fromJson(Map<String, dynamic> json) {
|
||||||
|
return PaginationData(
|
||||||
|
items: json["items"],
|
||||||
|
meta: json["meta"] == null ? null : Meta.fromJson(json["meta"]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
"items": items,
|
||||||
|
"meta": meta?.toJson(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class Meta {
|
||||||
|
Meta({
|
||||||
|
required this.totalItems,
|
||||||
|
required this.itemCount,
|
||||||
|
required this.itemsPerPage,
|
||||||
|
required this.totalPages,
|
||||||
|
required this.currentPage,
|
||||||
|
});
|
||||||
|
|
||||||
|
final int? totalItems;
|
||||||
|
final int? itemCount;
|
||||||
|
final int? itemsPerPage;
|
||||||
|
final int? totalPages;
|
||||||
|
final int? currentPage;
|
||||||
|
|
||||||
|
factory Meta.fromJson(Map<String, dynamic> json) {
|
||||||
|
return Meta(
|
||||||
|
totalItems: json["totalItems"],
|
||||||
|
itemCount: json["itemCount"],
|
||||||
|
itemsPerPage: json["itemsPerPage"],
|
||||||
|
totalPages: json["totalPages"],
|
||||||
|
currentPage: json["currentPage"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
"totalItems": totalItems,
|
||||||
|
"itemCount": itemCount,
|
||||||
|
"itemsPerPage": itemsPerPage,
|
||||||
|
"totalPages": totalPages,
|
||||||
|
"currentPage": currentPage,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
class ProjectModel {
|
||||||
|
ProjectModel({
|
||||||
|
required this.id,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.updatedAt,
|
||||||
|
required this.name,
|
||||||
|
required this.isDelete,
|
||||||
|
});
|
||||||
|
|
||||||
|
final int? id;
|
||||||
|
final DateTime? createdAt;
|
||||||
|
final DateTime? updatedAt;
|
||||||
|
final String? name;
|
||||||
|
final int? isDelete;
|
||||||
|
|
||||||
|
factory ProjectModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return ProjectModel(
|
||||||
|
id: json["id"],
|
||||||
|
createdAt: DateTime.tryParse(json["createdAt"] ?? ""),
|
||||||
|
updatedAt: DateTime.tryParse(json["updatedAt"] ?? ""),
|
||||||
|
name: json["name"],
|
||||||
|
isDelete: json["isDelete"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
"id": id,
|
||||||
|
"createdAt": createdAt?.toIso8601String(),
|
||||||
|
"updatedAt": updatedAt?.toIso8601String(),
|
||||||
|
"name": name,
|
||||||
|
"isDelete": isDelete,
|
||||||
|
};
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ import 'package:get/get.dart';
|
||||||
import 'package:sk_base_mobile/app_theme.dart';
|
import 'package:sk_base_mobile/app_theme.dart';
|
||||||
import 'package:sk_base_mobile/db_helper/dbHelper.dart';
|
import 'package:sk_base_mobile/db_helper/dbHelper.dart';
|
||||||
import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout.dart';
|
import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout.dart';
|
||||||
|
import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout_controller.dart';
|
||||||
import 'package:sk_base_mobile/util/date.util.dart';
|
import 'package:sk_base_mobile/util/date.util.dart';
|
||||||
import 'package:sk_base_mobile/util/modal.util.dart';
|
import 'package:sk_base_mobile/util/modal.util.dart';
|
||||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
|
@ -27,14 +28,8 @@ class InventoryInoutController extends GetxController {
|
||||||
RxInt barIndex = 0.obs;
|
RxInt barIndex = 0.obs;
|
||||||
RxList model = [].obs;
|
RxList model = [].obs;
|
||||||
final ScrollController scrollController = ScrollController();
|
final ScrollController scrollController = ScrollController();
|
||||||
// decoration: const BoxDecoration(
|
|
||||||
// borderRadius:
|
/// 打开出库还是入库选择框
|
||||||
// BorderRadius.all(Radius.circular(30)),
|
|
||||||
// gradient: LinearGradient(colors: [
|
|
||||||
// AppTheme.primaryColorLight,
|
|
||||||
// AppTheme.primaryColor
|
|
||||||
// ]),
|
|
||||||
// ),
|
|
||||||
Future<void> showInOrOutPickerDialog() async {
|
Future<void> showInOrOutPickerDialog() async {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: Get.overlayContext!,
|
context: Get.overlayContext!,
|
||||||
|
@ -62,10 +57,7 @@ class InventoryInoutController extends GetxController {
|
||||||
child: Ink(
|
child: Ink(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
colors: [
|
colors: [Colors.green[300]!, Colors.green],
|
||||||
AppTheme.primaryColorLight,
|
|
||||||
AppTheme.primaryColor
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
borderRadius:
|
borderRadius:
|
||||||
BorderRadius.all(Radius.circular(30)),
|
BorderRadius.all(Radius.circular(30)),
|
||||||
|
@ -130,15 +122,12 @@ class InventoryInoutController extends GetxController {
|
||||||
const BorderRadius.all(Radius.circular(30)),
|
const BorderRadius.all(Radius.circular(30)),
|
||||||
child: Material(
|
child: Material(
|
||||||
child: Ink(
|
child: Ink(
|
||||||
decoration: const BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
colors: [
|
colors: [Colors.red[300]!, Colors.red],
|
||||||
AppTheme.primaryColorLight,
|
|
||||||
AppTheme.primaryColor
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
borderRadius:
|
borderRadius:
|
||||||
BorderRadius.all(Radius.circular(30)),
|
const BorderRadius.all(Radius.circular(30)),
|
||||||
),
|
),
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
@ -167,7 +156,7 @@ class InventoryInoutController extends GetxController {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
Icon(
|
||||||
Icons.add_circle_outline,
|
Icons.remove_circle_outline,
|
||||||
color: AppTheme.nearlyWhite,
|
color: AppTheme.nearlyWhite,
|
||||||
size: ScreenAdaper.sp(80),
|
size: ScreenAdaper.sp(80),
|
||||||
),
|
),
|
||||||
|
@ -212,7 +201,7 @@ class InventoryInoutController extends GetxController {
|
||||||
return Container(
|
return Container(
|
||||||
margin: EdgeInsets.symmetric(
|
margin: EdgeInsets.symmetric(
|
||||||
horizontal: ScreenAdaper.width(100),
|
horizontal: ScreenAdaper.width(100),
|
||||||
vertical: ScreenAdaper.height(100)),
|
vertical: ScreenAdaper.height(60)),
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(30),
|
borderRadius: BorderRadius.circular(30),
|
||||||
child: Material(child: NewInventoryInout())),
|
child: Material(child: NewInventoryInout())),
|
||||||
|
@ -228,7 +217,7 @@ class InventoryInoutController extends GetxController {
|
||||||
child: child,
|
child: child,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
)
|
).then((value) => Get.delete<NewInventoryInoutController>())
|
||||||
: showModalBottomSheet(
|
: showModalBottomSheet(
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
|
|
|
@ -4,12 +4,15 @@ import 'package:get/get.dart';
|
||||||
import 'package:sk_base_mobile/app_theme.dart';
|
import 'package:sk_base_mobile/app_theme.dart';
|
||||||
import 'package:sk_base_mobile/constants/constants.dart';
|
import 'package:sk_base_mobile/constants/constants.dart';
|
||||||
import 'package:sk_base_mobile/models/product.model.dart';
|
import 'package:sk_base_mobile/models/product.model.dart';
|
||||||
|
import 'package:sk_base_mobile/models/project.model.dart';
|
||||||
|
import 'package:sk_base_mobile/widgets/core/search_select.dart';
|
||||||
|
import 'package:sk_base_mobile/widgets/empty.dart';
|
||||||
import 'package:sk_base_mobile/widgets/gradient_button.dart';
|
import 'package:sk_base_mobile/widgets/gradient_button.dart';
|
||||||
import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout_controller.dart';
|
import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout_controller.dart';
|
||||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
|
|
||||||
class NewInventoryInout extends StatelessWidget {
|
class NewInventoryInout extends StatelessWidget {
|
||||||
String inOrOut;
|
final String inOrOut;
|
||||||
NewInventoryInout({super.key, this.inOrOut = 'in'});
|
NewInventoryInout({super.key, this.inOrOut = 'in'});
|
||||||
|
|
||||||
final controller = Get.put(NewInventoryInoutController());
|
final controller = Get.put(NewInventoryInoutController());
|
||||||
|
@ -89,8 +92,8 @@ class NewInventoryInout extends StatelessWidget {
|
||||||
final children = [
|
final children = [
|
||||||
Row(children: [
|
Row(children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 1,
|
flex: 2,
|
||||||
child: buildInoutPicker(),
|
child: buildProjectPicker(),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: ScreenAdaper.width(10),
|
width: ScreenAdaper.width(10),
|
||||||
|
@ -119,49 +122,113 @@ class NewInventoryInout extends StatelessWidget {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildInoutPicker() {
|
Widget buildProjectPicker() {
|
||||||
// 选择下拉框表单项 两个选项 picker
|
return SearchSelectComponent(
|
||||||
return DropdownButtonFormField<String>(
|
textController: controller.projectTextController,
|
||||||
style:
|
labelText: '项目',
|
||||||
TextStyle(fontSize: ScreenAdaper.sp(22), color: AppTheme.nearlyBlack),
|
itemTextBuilder: <ProjectModel>(ProjectModel itemData) =>
|
||||||
// value: _dropdownValue,
|
Text('${itemData?.name}'),
|
||||||
decoration: InputDecoration(
|
);
|
||||||
floatingLabelBehavior: FloatingLabelBehavior.always,
|
// return TypeAheadField<ProjectModel>(
|
||||||
border: OutlineInputBorder(
|
// hideOnUnfocus: false,
|
||||||
borderRadius: BorderRadius.circular(ScreenAdaper.sp(15))),
|
// controller: controller.projectTextController,
|
||||||
label: const Row(
|
// suggestionsCallback: (String keyword) {
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
// return controller.getProjects(keyword: keyword);
|
||||||
mainAxisSize: MainAxisSize.min,
|
// },
|
||||||
children: [
|
// builder: (context, _, focusNode) {
|
||||||
Text(
|
// return TextFormField(
|
||||||
"*",
|
// focusNode: focusNode,
|
||||||
style: TextStyle(color: Colors.red),
|
// controller: _,
|
||||||
),
|
// decoration: InputDecoration(
|
||||||
Text("出/入库"),
|
// focusedBorder: OutlineInputBorder(
|
||||||
]),
|
// borderSide: const BorderSide(
|
||||||
),
|
// color: AppTheme.primaryColorLight, width: 2),
|
||||||
onChanged: (String? newValue) {
|
// borderRadius: BorderRadius.circular(ScreenAdaper.sp(15))),
|
||||||
// setState(() {
|
// suffixIcon: _.text.isNotEmpty && focusNode.hasFocus
|
||||||
// _dropdownValue = newValue;
|
// ? IconButton(
|
||||||
|
// icon: const Icon(Icons.clear),
|
||||||
|
// // 当点击这个按钮时,清除TextFormField的值
|
||||||
|
// onPressed: () => _.clear(),
|
||||||
|
// )
|
||||||
|
// : const SizedBox(),
|
||||||
|
// floatingLabelBehavior: FloatingLabelBehavior.always,
|
||||||
|
// label: const Row(
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
// mainAxisSize: MainAxisSize.min,
|
||||||
|
// children: [
|
||||||
|
// Text(
|
||||||
|
// "*",
|
||||||
|
// style: TextStyle(color: Colors.red),
|
||||||
|
// ),
|
||||||
|
// Text(
|
||||||
|
// "项目",
|
||||||
|
// ),
|
||||||
|
// ])));
|
||||||
|
// },
|
||||||
|
// emptyBuilder: (_) => Container(
|
||||||
|
// alignment: Alignment.center,
|
||||||
|
// width: ScreenAdaper.width(200),
|
||||||
|
// height: ScreenAdaper.height(50),
|
||||||
|
// child: Text(
|
||||||
|
// '未找到项目',
|
||||||
|
// style: TextStyle(fontSize: ScreenAdaper.sp(20)),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// itemBuilder: (context, project) {
|
||||||
|
// return ListTile(
|
||||||
|
// title: Text(project.name ?? ''),
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// onSelected: (ProjectModel project) {
|
||||||
|
// controller.projectTextController.text = project.name ?? '';
|
||||||
|
// controller.payload['project'] = project.id;
|
||||||
// });
|
// });
|
||||||
},
|
// return Obx(() => DropdownButtonFormField<int>(
|
||||||
icon: Icon(
|
// isExpanded: true,
|
||||||
Icons.arrow_drop_down_outlined,
|
// isDense: false,
|
||||||
size: ScreenAdaper.sp(40),
|
// style: TextStyle(
|
||||||
),
|
// fontSize: ScreenAdaper.sp(22), color: AppTheme.nearlyBlack),
|
||||||
items: <String>[
|
// // value: _dropdownValue,
|
||||||
'入库',
|
// decoration: InputDecoration(
|
||||||
'出库',
|
// contentPadding: EdgeInsets.symmetric(
|
||||||
].map<DropdownMenuItem<String>>((String value) {
|
// vertical: ScreenAdaper.height(10),
|
||||||
return DropdownMenuItem<String>(
|
// horizontal: ScreenAdaper.width(10)),
|
||||||
value: value,
|
// floatingLabelBehavior: FloatingLabelBehavior.always,
|
||||||
child: Text(
|
// border: OutlineInputBorder(
|
||||||
value,
|
// borderRadius: BorderRadius.circular(ScreenAdaper.sp(15))),
|
||||||
style: TextStyle(fontSize: ScreenAdaper.sp(30)),
|
// label: const Row(
|
||||||
),
|
// crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
);
|
// mainAxisSize: MainAxisSize.min,
|
||||||
}).toList(),
|
// children: [
|
||||||
);
|
// Text(
|
||||||
|
// "*",
|
||||||
|
// style: TextStyle(color: Colors.red),
|
||||||
|
// ),
|
||||||
|
// Text("项目"),
|
||||||
|
// ]),
|
||||||
|
// ),
|
||||||
|
// onChanged: (int? newValue) {
|
||||||
|
// // setState(() {
|
||||||
|
// // _dropdownValue = newValue;
|
||||||
|
// // });
|
||||||
|
// },
|
||||||
|
// // icon: Icon(
|
||||||
|
// // Icons.arrow_drop_down_outlined,
|
||||||
|
// // size: ScreenAdaper.sp(40),
|
||||||
|
// // ),
|
||||||
|
// items: controller.projects
|
||||||
|
// .map<DropdownMenuItem<int>>((ProjectModel model) {
|
||||||
|
// return DropdownMenuItem<int>(
|
||||||
|
// value: model.id,
|
||||||
|
// child: Text(
|
||||||
|
// model.name ?? '',
|
||||||
|
// style: TextStyle(
|
||||||
|
// fontSize: ScreenAdaper.sp(30),
|
||||||
|
// overflow: TextOverflow.ellipsis),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }).toList(),
|
||||||
|
// ));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildProductPicker() {
|
Widget buildProductPicker() {
|
||||||
|
|
|
@ -3,9 +3,13 @@ import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:sk_base_mobile/db_helper/dbHelper.dart';
|
import 'package:sk_base_mobile/db_helper/dbHelper.dart';
|
||||||
|
import 'package:sk_base_mobile/models/base_response.dart';
|
||||||
|
import 'package:sk_base_mobile/models/project.model.dart';
|
||||||
import 'package:sk_base_mobile/models/task_model.dart';
|
import 'package:sk_base_mobile/models/task_model.dart';
|
||||||
import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout_controller.dart';
|
import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout_controller.dart';
|
||||||
import 'package:sk_base_mobile/util/util.dart';
|
import 'package:sk_base_mobile/apis/api.dart' as Api;
|
||||||
|
import 'package:sk_base_mobile/util/date.util.dart';
|
||||||
|
import 'package:sk_base_mobile/util/snack_bar.util.dart';
|
||||||
|
|
||||||
class NewInventoryInoutController extends GetxController {
|
class NewInventoryInoutController extends GetxController {
|
||||||
final formKey = GlobalKey<FormState>();
|
final formKey = GlobalKey<FormState>();
|
||||||
|
@ -25,6 +29,24 @@ class NewInventoryInoutController extends GetxController {
|
||||||
final label = TextEditingController().obs;
|
final label = TextEditingController().obs;
|
||||||
final description = TextEditingController().obs;
|
final description = TextEditingController().obs;
|
||||||
final category = TextEditingController().obs;
|
final category = TextEditingController().obs;
|
||||||
|
RxList<ProjectModel> projects = <ProjectModel>[].obs;
|
||||||
|
final projectTextController = TextEditingController();
|
||||||
|
Map<String, dynamic> payload = {};
|
||||||
|
@override
|
||||||
|
void onReady() {
|
||||||
|
super.onReady();
|
||||||
|
getProjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<ProjectModel>> getProjects({String? keyword}) async {
|
||||||
|
final res =
|
||||||
|
await Api.getProjects({'page': 1, 'pageSize': 10, 'name': keyword});
|
||||||
|
if (res.data != null) {
|
||||||
|
projects.assignAll(
|
||||||
|
res.data!.items.map((e) => ProjectModel.fromJson(e)).toList());
|
||||||
|
}
|
||||||
|
return projects;
|
||||||
|
}
|
||||||
|
|
||||||
picStartTime(BuildContext context) async {
|
picStartTime(BuildContext context) async {
|
||||||
var picker =
|
var picker =
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||||
|
|
||||||
import 'package:get/get.dart' as Get;
|
import 'package:get/get.dart' as Get;
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:sk_base_mobile/models/base_response.dart';
|
||||||
import 'package:sk_base_mobile/util/logger_util.dart';
|
import 'package:sk_base_mobile/util/logger_util.dart';
|
||||||
import 'package:sk_base_mobile/config.dart';
|
import 'package:sk_base_mobile/config.dart';
|
||||||
import 'package:sk_base_mobile/services/storage.service.dart';
|
import 'package:sk_base_mobile/services/storage.service.dart';
|
||||||
|
@ -134,9 +135,14 @@ class DioService extends Get.GetxService {
|
||||||
}
|
}
|
||||||
if (response.data != null) {
|
if (response.data != null) {
|
||||||
try {
|
try {
|
||||||
dynamic responseData = response.data;
|
if (response.data['code'] == 200) {
|
||||||
if (response.data is String) {
|
if (GloablConfig.DEBUG) print(response.data['data']);
|
||||||
responseData = jsonDecode(response.data);
|
response.data = response.data['data'];
|
||||||
|
|
||||||
|
// 分页数据处理
|
||||||
|
if (response.data['meta'] != null && response.data['items'] != null) {
|
||||||
|
response.data = PaginationData.fromJson(response.data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
printError(info: e.toString());
|
printError(info: e.toString());
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
||||||
|
import 'package:sk_base_mobile/app_theme.dart';
|
||||||
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
|
|
||||||
|
class SearchSelectComponent extends StatelessWidget {
|
||||||
|
final TextEditingController textController;
|
||||||
|
final Function? suggestionsCallback;
|
||||||
|
final Function? onSelected;
|
||||||
|
final String labelText;
|
||||||
|
final bool isRequired;
|
||||||
|
final Widget Function<T>(T itemData)? itemTextBuilder;
|
||||||
|
const SearchSelectComponent(
|
||||||
|
{super.key,
|
||||||
|
required this.textController,
|
||||||
|
required this.labelText,
|
||||||
|
required this.itemTextBuilder,
|
||||||
|
this.suggestionsCallback,
|
||||||
|
this.onSelected,
|
||||||
|
this.isRequired = false});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return TypeAheadField(
|
||||||
|
hideOnUnfocus: false,
|
||||||
|
controller: textController,
|
||||||
|
suggestionsCallback: (String keyword) {
|
||||||
|
return suggestionsCallback != null
|
||||||
|
? suggestionsCallback!(keyword)
|
||||||
|
: [];
|
||||||
|
},
|
||||||
|
builder: (context, _, focusNode) {
|
||||||
|
return TextFormField(
|
||||||
|
focusNode: focusNode,
|
||||||
|
controller: _,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: const BorderSide(
|
||||||
|
color: AppTheme.primaryColorLight, width: 2),
|
||||||
|
borderRadius: BorderRadius.circular(ScreenAdaper.sp(15))),
|
||||||
|
suffixIcon: _.text.isNotEmpty && focusNode.hasFocus
|
||||||
|
? IconButton(
|
||||||
|
icon: const Icon(Icons.clear),
|
||||||
|
// 当点击这个按钮时,清除TextFormField的值
|
||||||
|
onPressed: () => _.clear(),
|
||||||
|
)
|
||||||
|
: const SizedBox(),
|
||||||
|
floatingLabelBehavior: FloatingLabelBehavior.always,
|
||||||
|
label: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
if (isRequired)
|
||||||
|
const Text(
|
||||||
|
"*",
|
||||||
|
style: TextStyle(color: Colors.red),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
labelText,
|
||||||
|
),
|
||||||
|
])));
|
||||||
|
},
|
||||||
|
emptyBuilder: (_) => Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
width: ScreenAdaper.width(200),
|
||||||
|
height: ScreenAdaper.height(50),
|
||||||
|
child: Text(
|
||||||
|
'未找到记录',
|
||||||
|
style: TextStyle(fontSize: ScreenAdaper.sp(20)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
itemBuilder: (context, itemData) {
|
||||||
|
return ListTile(
|
||||||
|
title: itemTextBuilder!(itemData),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onSelected: (selectedItemData) {
|
||||||
|
onSelected ?? onSelected!(selectedItemData);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue