feat: mine page
Before Width: | Height: | Size: 1014 KiB |
Before Width: | Height: | Size: 316 KiB |
Before Width: | Height: | Size: 510 KiB |
Before Width: | Height: | Size: 414 KiB |
Before Width: | Height: | Size: 912 KiB |
Before Width: | Height: | Size: 282 KiB |
Before Width: | Height: | Size: 372 KiB |
After Width: | Height: | Size: 86 KiB |
|
@ -96,7 +96,7 @@ final theme = ThemeData(
|
|||
iconTheme: const IconThemeData(color: Colors.black),
|
||||
backgroundColor: AppTheme.primaryColor,
|
||||
titleTextStyle: TextStyle(
|
||||
color: Colors.black,
|
||||
color: Colors.white,
|
||||
fontSize: ScreenAdaper.sp(30),
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory/inventory.dart';
|
||||
import 'package:sk_base_mobile/screens/login/login.dart';
|
||||
|
||||
import '../screens/landing/landing.dart';
|
||||
|
@ -8,9 +9,11 @@ class RouteConfig {
|
|||
static const String home = "/";
|
||||
static const String login = '/login';
|
||||
static const String userinfo = '/userinfo';
|
||||
static const String inventory = '/inventory';
|
||||
static final List<GetPage> getPages = [
|
||||
GetPage(name: login, page: () => LoginScreen()),
|
||||
GetPage(name: home, page: () => LandingPage()),
|
||||
GetPage(name: userinfo, page: () => UserInfoPage()),
|
||||
GetPage(name: inventory, page: () => InventoryPage()),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/config.dart';
|
||||
import 'package:sk_base_mobile/screens/landing/landing.dart';
|
||||
import 'package:sk_base_mobile/screens/login/login%20copy.dart';
|
||||
import 'package:sk_base_mobile/services/storage.service.dart';
|
||||
import 'package:sk_base_mobile/app_theme.dart';
|
||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/constants/bg_color.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/components/change_icon.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/components/filter_btn.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/components/today_button.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout_controller.dart';
|
||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||
|
@ -16,7 +17,7 @@ class ChangeButtonRow extends StatelessWidget {
|
|||
horizontal: MediaQuery.sizeOf(context).width * 0.06),
|
||||
child: Row(
|
||||
children: [
|
||||
const TodayButton(),
|
||||
TodayButton(),
|
||||
const Spacer(),
|
||||
ClipOval(
|
||||
child: InkWell(
|
||||
|
|
|
@ -63,8 +63,7 @@ class CustomAppBar extends StatelessWidget {
|
|||
initialDate: controller.endTime.value,
|
||||
endDate: controller.endTime.value,
|
||||
onDateTimeChanged: (date) {
|
||||
controller.endTime.value = DateTime.parse(date);
|
||||
controller.getData();
|
||||
controller.setEndTime(DateTime.parse(date));
|
||||
},
|
||||
);
|
||||
},
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// import 'package:flutter/foundation.dart';
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:flutter/widgets.dart';
|
||||
// import 'package:get/get.dart';
|
||||
// import 'package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart';
|
||||
// import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||
|
||||
// class FilterBtn extends StatelessWidget {
|
||||
// FilterBtn({super.key});
|
||||
// final controller = Get.put<FilterBtnController>();
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return Container(
|
||||
// width: ScreenAdaper.width(150),
|
||||
// constraints: BoxConstraints(minWidth: ScreenAdaper.width(150)),
|
||||
// child: Obx(
|
||||
// () => DropdownButtonFormField(
|
||||
// value: controller.hasInventoryStatus.value,
|
||||
// items: [
|
||||
// DropdownMenuItem(
|
||||
// child: Text('全部'),
|
||||
// value: -1,
|
||||
// ),
|
||||
// DropdownMenuItem(
|
||||
// child: const Text('入库'),
|
||||
// value: 0,
|
||||
// ),
|
||||
// DropdownMenuItem(
|
||||
// child: const Text('出库'),
|
||||
// value: 1,
|
||||
// ),
|
||||
// ],
|
||||
// onChanged: (value) {
|
||||
// controller.hasInventoryStatus.value = value!;
|
||||
// controller.refreshController.requestRefresh();
|
||||
// },
|
||||
// decoration: InputDecoration(
|
||||
// contentPadding: EdgeInsets.symmetric(
|
||||
// vertical: ScreenAdaper.height(15),
|
||||
// horizontal: ScreenAdaper.width(15)),
|
||||
// border: OutlineInputBorder(
|
||||
// borderRadius: BorderRadius.circular(ScreenAdaper.sp(15)),
|
||||
// ),
|
||||
// )),
|
||||
// ));
|
||||
// }
|
||||
// }
|
||||
|
||||
// class FilterBtnController extends GetxController {}
|
|
@ -6,15 +6,13 @@ import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout_controlle
|
|||
import 'package:sk_base_mobile/util/util.dart';
|
||||
|
||||
class TodayButton extends StatelessWidget {
|
||||
const TodayButton({super.key});
|
||||
|
||||
TodayButton({super.key});
|
||||
final controller = Get.find<InventoryInoutController>();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final controller = Get.find<InventoryInoutController>();
|
||||
return InkWell(
|
||||
borderRadius: BorderRadius.circular(ScreenAdaper.sp(30)),
|
||||
onTap: () => controller.pageController.animateToPage(0,
|
||||
duration: const Duration(milliseconds: 300), curve: Curves.easeIn),
|
||||
onTap: () => controller.setEndTime(DateTime.now()),
|
||||
child: Container(
|
||||
height: ScreenAdaper.height(70),
|
||||
width: ScreenAdaper.width(200),
|
||||
|
|
|
@ -41,7 +41,7 @@ class InventoryInoutController extends GetxController {
|
|||
getData();
|
||||
}
|
||||
|
||||
/// 打开出库还是入库选择框
|
||||
/// 出库还是入库picker
|
||||
Future<void> showInOrOutPickerDialog() async {
|
||||
showDialog(
|
||||
context: Get.overlayContext!,
|
||||
|
@ -203,7 +203,7 @@ class InventoryInoutController extends GetxController {
|
|||
);
|
||||
}
|
||||
|
||||
/// 打开新建库存出入库对话框
|
||||
/// 新建出入库dialog
|
||||
Future showInventoryInoutCreateDialog(int inOrOut) async {
|
||||
final isTablet = Responsive.isTablet(Get.context!);
|
||||
return isTablet
|
||||
|
@ -242,11 +242,13 @@ class InventoryInoutController extends GetxController {
|
|||
);
|
||||
}
|
||||
|
||||
// 出入库详情dialog
|
||||
Future showInventoryInoutInfoDialog(int id) async {
|
||||
ModalUtil.showGeneralDialog(
|
||||
width: ScreenAdaper.width(Get.width - 100),
|
||||
height: ScreenAdaper.height(Get.height - 100),
|
||||
content: InventoryInoutInfo(inventoryInoutId: id))
|
||||
content: InventoryInoutInfo(inventoryInoutId: id),
|
||||
offset: const Offset(0, -1))
|
||||
.then((value) => {Get.delete<InventoryInouInfoController>()});
|
||||
}
|
||||
|
||||
|
@ -279,6 +281,14 @@ class InventoryInoutController extends GetxController {
|
|||
});
|
||||
}
|
||||
|
||||
setEndTime(DateTime newEndTime) async {
|
||||
currentIndex.value = 0;
|
||||
endTime.value = newEndTime;
|
||||
pageController.jumpTo(0);
|
||||
scrollController.jumpTo(0);
|
||||
getData();
|
||||
}
|
||||
|
||||
setIndex(int value) {
|
||||
pageController.animateToPage(value,
|
||||
duration: const Duration(milliseconds: 300), curve: Curves.easeIn);
|
||||
|
|
|
@ -34,118 +34,77 @@ class _MinePageState extends State<MinePage>
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return _buildBody();
|
||||
return Container(
|
||||
color: AppTheme.nearlyWhite,
|
||||
child: _buildBody(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBody() {
|
||||
return Column(children: [
|
||||
// Container(
|
||||
// height: ScreenAdaper.height(360),
|
||||
// width: ScreenAdaper.screenWidth(),
|
||||
// decoration: const BoxDecoration(
|
||||
// image: DecorationImage(
|
||||
// fit: BoxFit.cover,
|
||||
// image: AssetImage('assets/images/mine_bg.png'))),
|
||||
// child: Padding(
|
||||
// padding: EdgeInsets.symmetric(
|
||||
// horizontal: ScreenAdaper.width(20),
|
||||
// vertical: ScreenAdaper.height(20)),
|
||||
// child: Column(children: [
|
||||
// SizedBox(
|
||||
// height: ScreenAdaper.height(30),
|
||||
// ),
|
||||
// Row(
|
||||
// children: [
|
||||
// const Spacer(),
|
||||
// Container(
|
||||
// height: ScreenAdaper.width(40),
|
||||
// width: ScreenAdaper.width(40),
|
||||
// padding: EdgeInsets.all(ScreenAdaper.width(2)),
|
||||
Container(
|
||||
height: ScreenAdaper.height(300),
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: AssetImage('assets/images/yeyazhijia_bg.jpg'))),
|
||||
// decoration: BoxDecoration(
|
||||
// borderRadius: BorderRadius.circular(ScreenAdaper.sp(40)),
|
||||
// color: const Color(0xFF000000).withOpacity(0.3)),
|
||||
// child: const SizedBox(),
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// SizedBox(
|
||||
// height: ScreenAdaper.height(120),
|
||||
// ),
|
||||
// Row(
|
||||
// children: [
|
||||
// Expanded(
|
||||
// child: Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// children: [
|
||||
// Row(
|
||||
// crossAxisAlignment: CrossAxisAlignment.center,
|
||||
// children: [
|
||||
// Obx(() => Text(
|
||||
// AuthStore.to.userInfo.value.nickname ?? '',
|
||||
// style: TextStyle(
|
||||
// fontSize: ScreenAdaper.sp(20),
|
||||
// fontWeight: FontWeight.w400),
|
||||
// )),
|
||||
// SizedBox(
|
||||
// width: ScreenAdaper.width(3),
|
||||
// ),
|
||||
// InkWell(
|
||||
// onTap: () {
|
||||
// Get.toNamed(RouteConfig.userinfo);
|
||||
// },
|
||||
// child: Image(
|
||||
// image:
|
||||
// const AssetImage('assets/images/edit_icon.png'),
|
||||
// height: ScreenAdaper.width(20),
|
||||
// ),
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// SizedBox(
|
||||
// height: ScreenAdaper.height(15),
|
||||
// ),
|
||||
// Text(StorageService.to.getString(CacheKeys.deviceUUID) ??
|
||||
// ''),
|
||||
// Row(
|
||||
// children: [
|
||||
// SizedBox(
|
||||
// width: ScreenAdaper.width(210),
|
||||
// child: Text(
|
||||
// 'ID: ${AuthStore.to.userInfo.value.id}',
|
||||
// overflow: TextOverflow.ellipsis,
|
||||
// maxLines: 2,
|
||||
// style: TextStyle(
|
||||
// fontSize: ScreenAdaper.sp(16),
|
||||
// color: Colors.grey[500]),
|
||||
// ),
|
||||
// ),
|
||||
// InkWell(
|
||||
// onTap: () {},
|
||||
// child: Container(
|
||||
// alignment: Alignment.topCenter,
|
||||
// width: ScreenAdaper.width(50),
|
||||
// height: ScreenAdaper.height(30),
|
||||
// padding: EdgeInsets.symmetric(
|
||||
// horizontal: ScreenAdaper.width(5)),
|
||||
// decoration: BoxDecoration(
|
||||
// color: const Color(0xFF454545),
|
||||
// borderRadius: BorderRadius.circular(5)),
|
||||
// child: Text('copy',
|
||||
// style: TextStyle(
|
||||
// color: AppTheme.white,
|
||||
// fontSize: ScreenAdaper.sp(16)))),
|
||||
// )
|
||||
// ],
|
||||
// )
|
||||
// ],
|
||||
// )),
|
||||
// MyAvatarWidget()
|
||||
// ],
|
||||
// )
|
||||
// ]),
|
||||
// ),
|
||||
// ),
|
||||
// gradient: LinearGradient(
|
||||
// colors: [AppTheme.primaryColorLight, AppTheme.primaryColor])),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: ScreenAdaper.width(20),
|
||||
vertical: ScreenAdaper.height(20)),
|
||||
child: Column(children: [
|
||||
SizedBox(
|
||||
height: ScreenAdaper.height(80),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
MyAvatarWidget(),
|
||||
SizedBox(
|
||||
height: ScreenAdaper.height(10),
|
||||
),
|
||||
Obx(
|
||||
() => Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Text(
|
||||
AuthStore.to.userInfo.value.nickname ?? '',
|
||||
style: TextStyle(
|
||||
letterSpacing: ScreenAdaper.width(5),
|
||||
fontSize: ScreenAdaper.sp(30),
|
||||
fontWeight: FontWeight.bold,
|
||||
foreground: Paint()
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 2
|
||||
..color = Colors.black),
|
||||
),
|
||||
Text(
|
||||
AuthStore.to.userInfo.value.nickname ?? '',
|
||||
style: TextStyle(
|
||||
letterSpacing: ScreenAdaper.width(5),
|
||||
color: Colors.white,
|
||||
fontSize: ScreenAdaper.sp(30),
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
]),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: ScreenAdaper.height(50),
|
||||
),
|
||||
Expanded(child: MineSettingsPage())
|
||||
// Expanded(
|
||||
// child: DefaultTabController(
|
||||
|
|
|
@ -14,58 +14,65 @@ class MineSettingsPage extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: ScreenAdaper.width(15)),
|
||||
child: ListView.separated(
|
||||
separatorBuilder: (_, index) => const Divider(
|
||||
color: Color(0xFFCCCCCC),
|
||||
),
|
||||
itemBuilder: ((_, index) => _buildSettingsItem(
|
||||
index,
|
||||
)),
|
||||
itemCount: 4),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSettingsItem(int index) {
|
||||
switch (index) {
|
||||
// auto translate
|
||||
case 0:
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(vertical: ScreenAdaper.width(10)),
|
||||
child: Row(
|
||||
children: [],
|
||||
));
|
||||
case 1:
|
||||
return InkWell(
|
||||
onTap: () async {
|
||||
await AuthStore.to.deleteAccount();
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(vertical: ScreenAdaper.width(10)),
|
||||
child: Row(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
'Delete acount',
|
||||
style: TextStyle(fontSize: ScreenAdaper.sp(18)),
|
||||
),
|
||||
],
|
||||
)));
|
||||
case 2:
|
||||
return InkWell(
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(),
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
color: AppTheme.nearlyWhite),
|
||||
width: ScreenAdaper.width(400),
|
||||
padding:
|
||||
EdgeInsets.symmetric(vertical: ScreenAdaper.width(10)),
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
await AuthStore.to.logout(force: true);
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(vertical: ScreenAdaper.width(10)),
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: ScreenAdaper.width(20),
|
||||
vertical: ScreenAdaper.width(20)),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
'Logout',
|
||||
style: TextStyle(fontSize: ScreenAdaper.sp(18)),
|
||||
'退出登录',
|
||||
style: TextStyle(
|
||||
fontSize: ScreenAdaper.sp(20),
|
||||
fontWeight: FontWeight.w600),
|
||||
),
|
||||
],
|
||||
)));
|
||||
default:
|
||||
return SizedBox();
|
||||
}
|
||||
))))
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
// Widget _buildSettingsItem(int index) {
|
||||
// switch (index) {
|
||||
// // auto translate
|
||||
// case 0:
|
||||
// return;
|
||||
// case 1:
|
||||
// return InkWell(
|
||||
// onTap: () async {
|
||||
// await AuthStore.to.deleteAccount();
|
||||
// },
|
||||
// child: Container(
|
||||
// padding: EdgeInsets.symmetric(vertical: ScreenAdaper.width(10)),
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Text(
|
||||
// 'Delete acount',
|
||||
// style: TextStyle(fontSize: ScreenAdaper.sp(18)),
|
||||
// ),
|
||||
// ],
|
||||
// )));
|
||||
// case 2:
|
||||
// return I;
|
||||
// default:
|
||||
// return SizedBox();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -125,25 +125,32 @@ class InventorySearch extends StatelessWidget {
|
|||
controller: controller.refreshController,
|
||||
onLoading: controller.onLoading,
|
||||
onRefresh: controller.onRefresh,
|
||||
child: controller.inventories.isEmpty
|
||||
child: controller.refreshController.isLoading
|
||||
? SizedBox()
|
||||
: controller.inventories.isEmpty
|
||||
? Center(
|
||||
child: Empty(text: '暂无库存'),
|
||||
)
|
||||
: Table(columnWidths: {
|
||||
0: FixedColumnWidth(100),
|
||||
1: FlexColumnWidth(2),
|
||||
2: MinColumnWidth(FixedColumnWidth(200), FixedColumnWidth(200)),
|
||||
3: MinColumnWidth(FixedColumnWidth(100), FixedColumnWidth(100)),
|
||||
4: MinColumnWidth(FixedColumnWidth(80), FixedColumnWidth(80)),
|
||||
2: MinColumnWidth(
|
||||
FixedColumnWidth(200), FixedColumnWidth(200)),
|
||||
3: MinColumnWidth(
|
||||
FixedColumnWidth(100), FixedColumnWidth(100)),
|
||||
4: MinColumnWidth(
|
||||
FixedColumnWidth(80), FixedColumnWidth(80)),
|
||||
}, children: [
|
||||
// table header
|
||||
TableRow(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(color: AppTheme.dividerColor))),
|
||||
bottom:
|
||||
BorderSide(color: AppTheme.dividerColor))),
|
||||
children: [
|
||||
TableCell(
|
||||
verticalAlignment: TableCellVerticalAlignment.middle,
|
||||
verticalAlignment:
|
||||
TableCellVerticalAlignment.middle,
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
height: ScreenAdaper.height(60),
|
||||
|
@ -153,27 +160,31 @@ class InventorySearch extends StatelessWidget {
|
|||
),
|
||||
)),
|
||||
TableCell(
|
||||
verticalAlignment: TableCellVerticalAlignment.middle,
|
||||
verticalAlignment:
|
||||
TableCellVerticalAlignment.middle,
|
||||
child: Text(
|
||||
'产品名称',
|
||||
style: listTitleTextStyle,
|
||||
)),
|
||||
TableCell(
|
||||
verticalAlignment: TableCellVerticalAlignment.middle,
|
||||
verticalAlignment:
|
||||
TableCellVerticalAlignment.middle,
|
||||
child: Text(
|
||||
'规格',
|
||||
style: listTitleTextStyle,
|
||||
),
|
||||
),
|
||||
TableCell(
|
||||
verticalAlignment: TableCellVerticalAlignment.middle,
|
||||
verticalAlignment:
|
||||
TableCellVerticalAlignment.middle,
|
||||
child: Text(
|
||||
'单价',
|
||||
style: listTitleTextStyle,
|
||||
),
|
||||
),
|
||||
TableCell(
|
||||
verticalAlignment: TableCellVerticalAlignment.middle,
|
||||
verticalAlignment:
|
||||
TableCellVerticalAlignment.middle,
|
||||
child: Text(
|
||||
'数量',
|
||||
textAlign: TextAlign.right,
|
||||
|
@ -185,8 +196,8 @@ class InventorySearch extends StatelessWidget {
|
|||
return TableRow(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom:
|
||||
BorderSide(color: AppTheme.dividerColor))),
|
||||
bottom: BorderSide(
|
||||
color: AppTheme.dividerColor))),
|
||||
children: [
|
||||
buildTableCell(
|
||||
Text(
|
||||
|
@ -214,7 +225,9 @@ class InventorySearch extends StatelessWidget {
|
|||
itemData: itemData),
|
||||
// 规格
|
||||
buildTableCell(
|
||||
Text(itemData.product?.productSpecification ?? '',
|
||||
Text(
|
||||
itemData.product?.productSpecification ??
|
||||
'',
|
||||
style: textStyle),
|
||||
itemData: itemData),
|
||||
// 单价
|
||||
|
@ -238,107 +251,6 @@ class InventorySearch extends StatelessWidget {
|
|||
])));
|
||||
}
|
||||
|
||||
Widget buildInventoryList1() {
|
||||
final textStyle = TextStyle(fontSize: ScreenAdaper.sp(22));
|
||||
return Obx(
|
||||
() => SmartRefresher(
|
||||
enablePullDown: true,
|
||||
enablePullUp: true,
|
||||
controller: controller.refreshController,
|
||||
onLoading: controller.onLoading,
|
||||
onRefresh: controller.onRefresh,
|
||||
child: ListView.separated(
|
||||
itemCount: controller.inventories.length,
|
||||
separatorBuilder: (context, index) => const Divider(
|
||||
height: 1,
|
||||
color: AppTheme.dividerColor,
|
||||
),
|
||||
itemBuilder: (context, index) {
|
||||
final itemData = controller.inventories[index];
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
if (onInventorySelected != null)
|
||||
onInventorySelected!(itemData);
|
||||
},
|
||||
child: Container(
|
||||
padding:
|
||||
EdgeInsets.symmetric(vertical: ScreenAdaper.height(10)),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
//最小宽度
|
||||
constraints:
|
||||
BoxConstraints(minWidth: ScreenAdaper.width(100)),
|
||||
child: Text(
|
||||
itemData.inventoryNumber!,
|
||||
style: textStyle,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: ScreenAdaper.width(10),
|
||||
),
|
||||
Expanded(
|
||||
flex: 8,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'${itemData.product?.name}',
|
||||
style: textStyle,
|
||||
),
|
||||
Text(
|
||||
'${itemData.product?.company?.name}',
|
||||
style: TextStyle(
|
||||
fontSize: ScreenAdaper.sp(15),
|
||||
color: AppTheme.grey),
|
||||
)
|
||||
],
|
||||
)),
|
||||
SizedBox(
|
||||
width: ScreenAdaper.width(10),
|
||||
),
|
||||
// 规格
|
||||
Expanded(
|
||||
child: Container(
|
||||
constraints:
|
||||
BoxConstraints(minWidth: ScreenAdaper.width(100)),
|
||||
child: Text(
|
||||
itemData.product?.productSpecification ?? '',
|
||||
style: textStyle),
|
||||
)),
|
||||
SizedBox(
|
||||
width: ScreenAdaper.width(10),
|
||||
),
|
||||
// 单价
|
||||
Container(
|
||||
constraints:
|
||||
BoxConstraints(minWidth: ScreenAdaper.width(100)),
|
||||
child: Text(
|
||||
'¥${double.parse('${itemData.unitPrice}')}${double.parse('${itemData.unitPrice}')}${double.parse('${itemData.unitPrice}')}${double.parse('${itemData.unitPrice}')}',
|
||||
style: textStyle),
|
||||
),
|
||||
SizedBox(
|
||||
width: ScreenAdaper.width(10),
|
||||
),
|
||||
// 库存数量
|
||||
Expanded(
|
||||
child: Container(
|
||||
alignment: Alignment.centerRight,
|
||||
constraints:
|
||||
BoxConstraints(minWidth: ScreenAdaper.width(80)),
|
||||
child: Text(
|
||||
'${itemData.quantity}${itemData.quantity}${itemData.product?.unit?.label ?? ''}',
|
||||
style: textStyle),
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildTableCell(Widget child,
|
||||
{required InventoryModel itemData, AlignmentGeometry? alignment}) {
|
||||
return TableCell(
|
||||
|
|
|
@ -358,10 +358,12 @@ class NewInventoryInout extends StatelessWidget {
|
|||
vertical: ScreenAdaper.height(20),
|
||||
horizontal: ScreenAdaper.width(20)),
|
||||
alignment: Alignment.center,
|
||||
child: Row(children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
'*请拍照上传照片',
|
||||
'*产品照片',
|
||||
style: TextStyle(
|
||||
fontSize: ScreenAdaper.sp(25),
|
||||
color: AppTheme.secondPrimaryColor),
|
||||
|
@ -375,20 +377,50 @@ class NewInventoryInout extends StatelessWidget {
|
|||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
...controller.uploadImgFilesPath
|
||||
.map((String path) => builderImagePreview(path))
|
||||
...controller.uploadProductImgFilesPath
|
||||
.map((String path) =>
|
||||
builderImagePreview(path, 'product'))
|
||||
.toList(),
|
||||
buildImageUploader()
|
||||
buildImageUploader('product')
|
||||
],
|
||||
),
|
||||
)),
|
||||
],
|
||||
)),
|
||||
Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
'*经办人自拍',
|
||||
style: TextStyle(
|
||||
fontSize: ScreenAdaper.sp(25),
|
||||
color: AppTheme.secondPrimaryColor),
|
||||
),
|
||||
SizedBox(
|
||||
height: ScreenAdaper.height(10),
|
||||
),
|
||||
Obx(() => SingleChildScrollView(
|
||||
controller: controller.uploadScrollController,
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
...controller.uploadAgentImgFilesPath
|
||||
.map((String path) =>
|
||||
builderImagePreview(path, 'agent'))
|
||||
.toList(),
|
||||
buildImageUploader('agent')
|
||||
],
|
||||
),
|
||||
)),
|
||||
],
|
||||
))
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
/// 照片预览队列Item
|
||||
Widget builderImagePreview(String path) {
|
||||
Widget builderImagePreview(String path, String type) {
|
||||
return Stack(
|
||||
children: [
|
||||
Container(
|
||||
|
@ -417,7 +449,11 @@ class NewInventoryInout extends StatelessWidget {
|
|||
right: ScreenAdaper.width(5),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
controller.uploadImgFilesPath.remove(path);
|
||||
if (type == 'agent') {
|
||||
controller.uploadAgentImgFilesPath.remove(path);
|
||||
} else {
|
||||
controller.uploadProductImgFilesPath.remove(path);
|
||||
}
|
||||
},
|
||||
child: Icon(
|
||||
Icons.close,
|
||||
|
@ -442,10 +478,10 @@ class NewInventoryInout extends StatelessWidget {
|
|||
}
|
||||
|
||||
// 上传照片控制器
|
||||
Widget buildImageUploader() {
|
||||
Widget buildImageUploader(String type) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
controller.photoPicker();
|
||||
controller.photoPicker(type);
|
||||
},
|
||||
child: Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: ScreenAdaper.width(5)),
|
||||
|
|
|
@ -43,7 +43,9 @@ class NewInventoryInoutController extends GetxController {
|
|||
final agentTextController = TextEditingController();
|
||||
final remarkTextController = TextEditingController();
|
||||
final positionTextController = TextEditingController();
|
||||
final uploadImgFilesPath = <String>[].obs;
|
||||
final uploadProductImgFilesPath = <String>[].obs;
|
||||
final uploadAgentImgFilesPath = <String>[].obs;
|
||||
// final uploadImgFilesPath = <String>[].obs
|
||||
final uploadScrollController = ScrollController();
|
||||
Map<String, dynamic> payload = {};
|
||||
NewInventoryInoutController({this.inOrOut});
|
||||
|
@ -114,37 +116,49 @@ class NewInventoryInoutController extends GetxController {
|
|||
/// 创建出入库记录
|
||||
Future<void> create() async {
|
||||
if (payload['projectId'] == null) {
|
||||
SnackBarUtil().info(
|
||||
SnackBarUtil().error(
|
||||
'项目不能为空',
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (payload['productId'] == null) {
|
||||
SnackBarUtil().info(
|
||||
SnackBarUtil().error(
|
||||
'产品不能为空',
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (payload['time'] == null) {
|
||||
SnackBarUtil().info(
|
||||
SnackBarUtil().error(
|
||||
'时间不能为空',
|
||||
);
|
||||
return;
|
||||
}
|
||||
payload['quantity'] = quantityTextController.text;
|
||||
if (payload['quantity'].isEmpty || payload['quantity'] == '0') {
|
||||
SnackBarUtil().info(
|
||||
SnackBarUtil().error(
|
||||
'数量必须大于1',
|
||||
);
|
||||
return;
|
||||
}
|
||||
payload['agent'] = agentTextController.text;
|
||||
if (payload['agent'].isEmpty) {
|
||||
SnackBarUtil().info(
|
||||
SnackBarUtil().error(
|
||||
'经办人不能为空',
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (uploadProductImgFilesPath.isEmpty) {
|
||||
SnackBarUtil().error(
|
||||
'请上传产品照片',
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (uploadAgentImgFilesPath.isEmpty) {
|
||||
SnackBarUtil().error(
|
||||
'请上传经办人照片',
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (unitPriceTextController.text.isEmpty) {
|
||||
payload.remove('unitPrice');
|
||||
} else {
|
||||
|
@ -163,7 +177,10 @@ class NewInventoryInoutController extends GetxController {
|
|||
try {
|
||||
// final recordId = res.data as int;
|
||||
// 批量同时上传
|
||||
final uploadRes = await Future.wait(uploadImgFilesPath
|
||||
final uploadRes = await Future.wait([
|
||||
...uploadProductImgFilesPath,
|
||||
...uploadAgentImgFilesPath
|
||||
]
|
||||
.map((filePath) => MediaUtil().uploadImg(File(filePath),
|
||||
bussinessModule: StorageBussinessModuleEnum.MaterialsInOut,
|
||||
bussinessRecordId: null))
|
||||
|
@ -189,10 +206,15 @@ class NewInventoryInoutController extends GetxController {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> photoPicker() async {
|
||||
XFile? pickedFile = await MediaUtil().getImageFromCamera();
|
||||
Future<void> photoPicker(String type) async {
|
||||
XFile? pickedFile =
|
||||
await MediaUtil().getImageFromCamera(isFront: type == 'agent');
|
||||
if (pickedFile != null) {
|
||||
uploadImgFilesPath.add(pickedFile.path);
|
||||
if (type == 'product') {
|
||||
uploadProductImgFilesPath.add(pickedFile.path);
|
||||
} else {
|
||||
uploadAgentImgFilesPath.add(pickedFile.path);
|
||||
}
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
// 滚动到最右边
|
||||
uploadScrollController.animateTo(
|
||||
|
@ -283,17 +305,17 @@ class NewInventoryInoutController extends GetxController {
|
|||
|
||||
insertTask(BuildContext context) {
|
||||
if (label.value.text.toString().isEmpty) {
|
||||
SnackBarUtil().warning(
|
||||
'Warning',
|
||||
message: 'Enter valid label',
|
||||
);
|
||||
return;
|
||||
// SnackBarUtil().error(
|
||||
// 'Warning',
|
||||
// message: 'Enter valid label',
|
||||
// );
|
||||
// return;
|
||||
}
|
||||
if (category.value.text.toString().isEmpty) {
|
||||
SnackBarUtil().warning(
|
||||
'Warning',
|
||||
message: 'Enter Correct Category',
|
||||
);
|
||||
// SnackBarUtil().error(
|
||||
// 'Warning',
|
||||
// message: 'Enter Correct Category',
|
||||
// );
|
||||
return;
|
||||
}
|
||||
if (selectedDate.isEmpty) {
|
||||
|
|
|
@ -1,49 +1,29 @@
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/app_theme.dart';
|
||||
import 'package:sk_base_mobile/constants/router.dart';
|
||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||
import 'package:sk_base_mobile/util/snack_bar.util.dart';
|
||||
|
||||
class WorkBenchModel {
|
||||
final String title;
|
||||
final String icon;
|
||||
final String route;
|
||||
WorkBenchModel(
|
||||
{required this.title, required this.icon, required this.route});
|
||||
WorkBenchModel({required this.title, required this.route});
|
||||
}
|
||||
|
||||
class WorkBenchPage extends StatelessWidget {
|
||||
WorkBenchPage({super.key});
|
||||
List<WorkBenchModel> works = [
|
||||
WorkBenchModel(
|
||||
title: '产品管理',
|
||||
icon: 'assets/images/product_manage.png',
|
||||
route: '/product'),
|
||||
WorkBenchModel(
|
||||
title: '库存管理',
|
||||
icon: 'assets/images/inventory_manage.png',
|
||||
route: '/inventory'),
|
||||
WorkBenchModel(
|
||||
title: '合同管理',
|
||||
icon: 'assets/images/contract_manage.png',
|
||||
route: '/contract'),
|
||||
WorkBenchModel(
|
||||
title: '人事管理',
|
||||
icon: 'assets/images/hr_manage.png',
|
||||
route: '/personnel'),
|
||||
WorkBenchModel(
|
||||
title: '公车管理',
|
||||
icon: 'assets/images/vehicle_usage.png',
|
||||
route: '/finance'),
|
||||
WorkBenchModel(
|
||||
title: '任务管理',
|
||||
icon: 'assets/images/task_manage.png',
|
||||
route: '/task_manage'),
|
||||
WorkBenchModel(
|
||||
title: '报表管理',
|
||||
icon: 'assets/images/report_manage.png',
|
||||
route: '/report'),
|
||||
WorkBenchModel(title: '库存', route: '/inventory'),
|
||||
WorkBenchModel(title: '产品', route: '/product'),
|
||||
WorkBenchModel(title: '合同', route: '/contract'),
|
||||
WorkBenchModel(title: '人事', route: '/personnel'),
|
||||
WorkBenchModel(title: '公车', route: '/finance'),
|
||||
WorkBenchModel(title: '任务', route: '/task_manage'),
|
||||
WorkBenchModel(title: '报表', route: '/report'),
|
||||
];
|
||||
|
||||
@override
|
||||
|
@ -78,15 +58,36 @@ class WorkBenchPage extends StatelessWidget {
|
|||
}
|
||||
|
||||
Widget buildCard(int index) {
|
||||
return Card(
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
final route = RouteConfig.getPages
|
||||
.map((e) => e.name)
|
||||
.firstWhereOrNull((name) => name == works[index].route);
|
||||
if (route != null) {
|
||||
Get.toNamed(works[index].route);
|
||||
} else {
|
||||
SnackBarUtil().info('功能待开发。');
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
shadowColor: AppTheme.black,
|
||||
elevation: 10.0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(ScreenAdaper.width(20))),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
colors: [AppTheme.primaryColorLight, AppTheme.primaryColor]),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppTheme.black.withOpacity(0.5),
|
||||
offset: Offset(0, 0),
|
||||
blurRadius: 5,
|
||||
spreadRadius: 2)
|
||||
],
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
Image.asset(works[index].icon),
|
||||
// Image.asset(works[index].icon),
|
||||
Center(
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
|
@ -95,7 +96,7 @@ class WorkBenchPage extends StatelessWidget {
|
|||
works[index].title,
|
||||
style: TextStyle(
|
||||
letterSpacing: ScreenAdaper.width(5),
|
||||
fontSize: ScreenAdaper.sp(30),
|
||||
fontSize: ScreenAdaper.sp(40),
|
||||
fontWeight: FontWeight.bold,
|
||||
foreground: Paint()
|
||||
..style = PaintingStyle.stroke
|
||||
|
@ -107,13 +108,13 @@ class WorkBenchPage extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
letterSpacing: ScreenAdaper.width(5),
|
||||
color: Colors.white,
|
||||
fontSize: ScreenAdaper.sp(30),
|
||||
fontSize: ScreenAdaper.sp(40),
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
));
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ class DioService extends Get.GetxService {
|
|||
static DioService get to => Get.Get.find();
|
||||
static Dio get dio => _dio;
|
||||
static late Dio _dio;
|
||||
List<String> whiteList = [Urls.login, Urls.uploadAttachemnt];
|
||||
List<String> whiteList = [Urls.login];
|
||||
BaseOptions dioBaseOptions = BaseOptions(
|
||||
connectTimeout: const Duration(seconds: 20),
|
||||
baseUrl: '${GloablConfig.BASE_URL}',
|
||||
|
|
|
@ -10,15 +10,19 @@ import 'package:sk_base_mobile/services/service.dart';
|
|||
|
||||
class MediaUtil {
|
||||
//拍照
|
||||
Future<XFile?> getImageFromCamera({double? maxWidth}) async {
|
||||
Future<XFile?> getImageFromCamera(
|
||||
{double? maxWidth, bool isFront = false}) async {
|
||||
XFile? pickedFile;
|
||||
try {
|
||||
if (AppInfoService.to.isCameraing.value) {
|
||||
return null;
|
||||
}
|
||||
AppInfoService.to.isCameraing.value = true;
|
||||
pickedFile = await ImagePicker()
|
||||
.pickImage(source: ImageSource.camera, maxWidth: maxWidth ?? 2000);
|
||||
pickedFile = await ImagePicker().pickImage(
|
||||
source: ImageSource.camera,
|
||||
maxWidth: maxWidth ?? 2000,
|
||||
preferredCameraDevice:
|
||||
isFront ? CameraDevice.front : CameraDevice.rear);
|
||||
AppInfoService.to.isCameraing.value = false;
|
||||
} catch (e) {
|
||||
AppInfoService.to.isCameraing.value = false;
|
||||
|
|
|
@ -68,7 +68,10 @@ class ModalUtil {
|
|||
);
|
||||
|
||||
static Future<void> showGeneralDialog(
|
||||
{required Widget content, double? width, double? height}) {
|
||||
{required Widget content,
|
||||
double? width,
|
||||
double? height,
|
||||
Offset? offset}) {
|
||||
return Get.generalDialog(
|
||||
barrierLabel: "productPicker",
|
||||
barrierDismissible: true,
|
||||
|
@ -86,7 +89,7 @@ class ModalUtil {
|
|||
},
|
||||
transitionBuilder: (_, anim, __, child) {
|
||||
Tween<Offset> tween;
|
||||
tween = Tween(begin: const Offset(0, 1), end: Offset.zero);
|
||||
tween = Tween(begin: offset ?? const Offset(0, 1), end: Offset.zero);
|
||||
return SlideTransition(
|
||||
position: tween.animate(
|
||||
CurvedAnimation(parent: anim, curve: Curves.easeInOut),
|
||||
|
|
|
@ -29,8 +29,8 @@ class MyAvatarWidget extends StatelessWidget {
|
|||
border: Border.all(
|
||||
color: AppTheme.white, width: ScreenAdaper.sp(2)),
|
||||
borderRadius: BorderRadius.circular(50)),
|
||||
height: ScreenAdaper.width(90),
|
||||
width: ScreenAdaper.width(90),
|
||||
height: ScreenAdaper.width(120),
|
||||
width: ScreenAdaper.width(120),
|
||||
child: const SizedBox(),
|
||||
)),
|
||||
Positioned(
|
||||
|
@ -42,7 +42,7 @@ class MyAvatarWidget extends StatelessWidget {
|
|||
},
|
||||
child: Image(
|
||||
height: ScreenAdaper.width(40),
|
||||
image: const AssetImage('assets/images/photo_icon.png'),
|
||||
image: const AssetImage('assets/images/company_logo.png'),
|
||||
)))
|
||||
],
|
||||
);
|
||||
|
|