feat: inventory inout feature developing

This commit is contained in:
louis 2024-03-20 09:37:20 +08:00
parent d1a691444c
commit 9a8b04f3e9
51 changed files with 906 additions and 290 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 KiB

BIN
assets/images/hr_manage.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 912 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

View File

@ -23,6 +23,7 @@ class AppTheme {
static const String fontName = 'NotoSans'; static const String fontName = 'NotoSans';
static const Color activeNavigationBarColor = primaryColor; static const Color activeNavigationBarColor = primaryColor;
static const Color notActiveNavigationBarColor = Colors.grey; static const Color notActiveNavigationBarColor = Colors.grey;
static const Color dividerColor = Color.fromARGB(255, 197, 197, 197);
} }
final theme = ThemeData( final theme = ThemeData(
@ -32,7 +33,7 @@ final theme = ThemeData(
primaryColorDark: AppTheme.primaryColorDark, primaryColorDark: AppTheme.primaryColorDark,
progressIndicatorTheme: progressIndicatorTheme:
const ProgressIndicatorThemeData(color: AppTheme.primaryColor), const ProgressIndicatorThemeData(color: AppTheme.primaryColor),
dividerColor: AppTheme.grey, dividerColor: AppTheme.dividerColor,
cardColor: AppTheme.white, cardColor: AppTheme.white,
scaffoldBackgroundColor: AppTheme.nearlyWhite, scaffoldBackgroundColor: AppTheme.nearlyWhite,
bottomNavigationBarTheme: BottomNavigationBarThemeData( bottomNavigationBarTheme: BottomNavigationBarThemeData(

View File

@ -1,7 +1,7 @@
/// Global config /// Global config
class GloablConfig { class GloablConfig {
// static const BASE_URL = "http://172.21.128.1:3000/api"; // static const BASE_URL = "http://10.0.2.2:7001/api/";
static const BASE_URL = "http://10.0.2.2:7001/api/"; static const BASE_URL = "http://192.168.60.220:7001/api/";
static const DOMAIN_NAME = "山矿通"; static const DOMAIN_NAME = "山矿通";
static const DEBUG = true; static const DEBUG = true;
static const PRIVACY_POLICY = 'http://h5.heeru.xyz/privacyPolicy.html'; static const PRIVACY_POLICY = 'http://h5.heeru.xyz/privacyPolicy.html';

View File

@ -2,4 +2,5 @@ class TextEnum {
static const String noInventoryInout = "今天没有出入库记录"; static const String noInventoryInout = "今天没有出入库记录";
static const String homeWelcomeText = '你好,'; static const String homeWelcomeText = '你好,';
static const String backToTodayButtonText = '今天'; static const String backToTodayButtonText = '今天';
static const String createInventoryInOutBtnText = '提交';
} }

View File

@ -1,8 +1,8 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
class AppBottomNavItem { class AppBottomNavItem {
Icon icon; IconData icon;
Icon activeIcon; IconData activeIcon;
String? label; String? label;
Widget? page; Widget? page;
AppBottomNavItem( AppBottomNavItem(

View File

@ -0,0 +1,129 @@
class ProductModel {
int? id;
String? createdAt;
String? updatedAt;
String? name;
String? remark;
int? isDelete;
int? companyId;
int? unitId;
String? namePinyin;
List<Files>? files;
Company? company;
Unit? unit;
ProductModel(
{this.id,
this.createdAt,
this.updatedAt,
this.name,
this.remark,
this.isDelete,
this.companyId,
this.unitId,
this.namePinyin,
this.files,
this.company,
this.unit});
ProductModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
createdAt = json['createdAt'];
updatedAt = json['updatedAt'];
name = json['name'];
remark = json['remark'];
isDelete = json['isDelete'];
companyId = json['companyId'];
unitId = json['unitId'];
namePinyin = json['namePinyin'];
if (json['files'] != null) {
files = <Files>[];
json['files'].forEach((v) {
files!.add(new Files.fromJson(v));
});
}
company =
json['company'] != null ? new Company.fromJson(json['company']) : null;
unit = json['unit'] != null ? new Unit.fromJson(json['unit']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['createdAt'] = this.createdAt;
data['updatedAt'] = this.updatedAt;
data['name'] = this.name;
data['remark'] = this.remark;
data['isDelete'] = this.isDelete;
data['companyId'] = this.companyId;
data['unitId'] = this.unitId;
data['namePinyin'] = this.namePinyin;
if (this.files != null) {
data['files'] = this.files!.map((v) => v.toJson()).toList();
}
if (this.company != null) {
data['company'] = this.company!.toJson();
}
if (this.unit != null) {
data['unit'] = this.unit!.toJson();
}
return data;
}
}
class Files {
int? id;
String? path;
Files({this.id, this.path});
Files.fromJson(Map<String, dynamic> json) {
id = json['id'];
path = json['path'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['path'] = this.path;
return data;
}
}
class Company {
int? id;
String? name;
Company({this.id, this.name});
Company.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
return data;
}
}
class Unit {
int? id;
String? label;
Unit({this.id, this.label});
Unit.fromJson(Map<String, dynamic> json) {
id = json['id'];
label = json['label'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['label'] = this.label;
return data;
}
}

View File

@ -1,20 +0,0 @@
import 'package:flutter/material.dart';
import 'package:sk_base_mobile/screens/home/components/task_page_holder.dart';
import 'package:sk_base_mobile/screens/home/components/upper_body.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
UperBody(),
const Expanded(
child: TaskPageBody(),
),
],
);
}
}

View File

@ -1,14 +1,14 @@
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/constants/bg_color.dart'; import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/home/components/change_icon.dart'; import 'package:sk_base_mobile/screens/inventory_inout/components/change_icon.dart';
import 'package:sk_base_mobile/screens/home/components/today_button.dart'; import 'package:sk_base_mobile/screens/inventory_inout/components/today_button.dart';
import 'package:sk_base_mobile/screens/home/home_controller.dart'; import 'package:sk_base_mobile/screens/inventory_inout/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 ChangeButtonRow extends StatelessWidget { class ChangeButtonRow extends StatelessWidget {
ChangeButtonRow({super.key}); ChangeButtonRow({super.key});
final controller = Get.put(HomeController()); final controller = Get.put(InventoryInoutController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Padding(

View File

@ -3,13 +3,13 @@ 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/bg_color.dart'; import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/constants/constants.dart'; import 'package:sk_base_mobile/constants/constants.dart';
import 'package:sk_base_mobile/screens/home/home_controller.dart'; import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout_controller.dart';
import 'package:sk_base_mobile/store/auth.store.dart'; import 'package:sk_base_mobile/store/auth.store.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart'; import 'package:sk_base_mobile/util/screen_adaper_util.dart';
class CustomAppBar extends StatelessWidget { class CustomAppBar extends StatelessWidget {
CustomAppBar({super.key}); CustomAppBar({super.key});
final controller = Get.put(HomeController()); final controller = Get.put(InventoryInoutController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Padding(

View File

@ -2,14 +2,14 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart'; 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/bg_color.dart'; import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/home/home_controller.dart'; import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout_controller.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart'; import 'package:sk_base_mobile/util/screen_adaper_util.dart';
import 'dates.dart'; import 'dates.dart';
class DateContainer extends StatelessWidget { class DateContainer extends StatelessWidget {
final int index; final int index;
DateContainer({super.key, required this.index}); DateContainer({super.key, required this.index});
final controller = Get.put(HomeController()); final controller = Get.put(InventoryInoutController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final size = MediaQuery.sizeOf(context); final size = MediaQuery.sizeOf(context);

View File

@ -2,13 +2,13 @@ import 'dart:ui';
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/screens/home/home_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/util/util.dart';
class Dates extends StatelessWidget { class Dates extends StatelessWidget {
Dates({super.key, required this.index}); Dates({super.key, required this.index});
final int index; final int index;
final controller = Get.put(HomeController()); final controller = Get.put(InventoryInoutController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(

View File

@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart'; import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/constants/data.dart'; import 'package:sk_base_mobile/constants/data.dart';
import 'package:sk_base_mobile/screens/home/home_controller.dart'; import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout_controller.dart';
class TaskTitle extends StatelessWidget { class TaskTitle extends StatelessWidget {
TaskTitle({super.key, required this.index, required this.ind}); TaskTitle({super.key, required this.index, required this.ind});
@ -12,7 +12,7 @@ class TaskTitle extends StatelessWidget {
final int ind; final int ind;
final int randomColor1 = Random().nextInt(9); final int randomColor1 = Random().nextInt(9);
final int randomColor2 = Random().nextInt(9); final int randomColor2 = Random().nextInt(9);
final controller = Get.put(HomeController()); final controller = Get.put(InventoryInoutController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(

View File

@ -2,15 +2,15 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart'; import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/constants/data.dart'; import 'package:sk_base_mobile/constants/data.dart';
import 'package:sk_base_mobile/screens/home/components/task_detail_col.dart'; import 'package:sk_base_mobile/screens/inventory_inout/components/task_detail_col.dart';
import 'package:sk_base_mobile/screens/home/home_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/util/util.dart';
class TaskDetailContainer extends StatelessWidget { class TaskDetailContainer extends StatelessWidget {
TaskDetailContainer({super.key, required this.index, required this.ind}); TaskDetailContainer({super.key, required this.index, required this.ind});
final int index; final int index;
final int ind; final int ind;
final controller = Get.put(HomeController()); final controller = Get.put(InventoryInoutController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Dismissible( return Dismissible(

View File

@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart'; 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/screens/home/components/responsive.dart'; import 'package:sk_base_mobile/screens/inventory_inout/components/responsive.dart';
import 'package:sk_base_mobile/screens/home/components/task_detail_container.dart'; import 'package:sk_base_mobile/screens/inventory_inout/components/task_detail_container.dart';
import 'package:sk_base_mobile/screens/home/home_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/util/util.dart';
class TaskList extends StatelessWidget { class TaskList extends StatelessWidget {
@ -35,7 +35,7 @@ class Grid extends StatelessWidget {
final int crossAsis; final int crossAsis;
final double ratio; final double ratio;
final int ind; final int ind;
final controller = Get.put(HomeController()); final controller = Get.put(InventoryInoutController());
Grid( Grid(
{super.key, {super.key,
required this.crossAsis, required this.crossAsis,

View File

@ -1,11 +1,11 @@
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/screens/home/components/task_list.dart'; import 'package:sk_base_mobile/screens/inventory_inout/components/task_list.dart';
import 'package:sk_base_mobile/screens/home/home_controller.dart'; import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout_controller.dart';
class TaskPageView extends StatelessWidget { class TaskPageView extends StatelessWidget {
TaskPageView({super.key}); TaskPageView({super.key});
final controller = Get.put(HomeController()); final controller = Get.put(InventoryInoutController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return PageView( return PageView(

View File

@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:sk_base_mobile/screens/home/components/change_button_roe.dart'; import 'package:sk_base_mobile/screens/inventory_inout/components/change_button_roe.dart';
import 'package:sk_base_mobile/screens/home/components/task_page_View.dart'; import 'package:sk_base_mobile/screens/inventory_inout/components/task_page_View.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart'; import 'package:sk_base_mobile/util/screen_adaper_util.dart';
class TaskPageBody extends StatelessWidget { class TaskPageBody extends StatelessWidget {

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart'; 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/screens/home/home_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/util/util.dart';
class TodayButton extends StatelessWidget { class TodayButton extends StatelessWidget {
@ -10,7 +10,7 @@ class TodayButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final controller = Get.put(HomeController()); final controller = Get.put(InventoryInoutController());
return InkWell( return InkWell(
borderRadius: BorderRadius.circular(ScreenAdaper.sp(30)), borderRadius: BorderRadius.circular(ScreenAdaper.sp(30)),
onTap: () => controller.pageController.animateToPage(0, onTap: () => controller.pageController.animateToPage(0,

View File

@ -1,14 +1,14 @@
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/constants/bg_color.dart'; import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/home/components/custom_app_bar.dart'; import 'package:sk_base_mobile/screens/inventory_inout/components/custom_app_bar.dart';
import 'package:sk_base_mobile/screens/home/components/date_container.dart'; import 'package:sk_base_mobile/screens/inventory_inout/components/date_container.dart';
import 'package:sk_base_mobile/screens/home/home_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/util/util.dart';
class UperBody extends StatelessWidget { class UperBody extends StatelessWidget {
UperBody({super.key}); UperBody({super.key});
final controller = Get.put(HomeController()); final controller = Get.put(InventoryInoutController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(

View File

@ -0,0 +1,24 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/screens/inventory_inout/components/task_page_holder.dart';
import 'package:sk_base_mobile/screens/inventory_inout/components/upper_body.dart';
import 'inventory_inout_controller.dart';
class InvenotryInoutPage extends StatelessWidget {
InvenotryInoutPage({super.key});
final inventoryInoutController =
Get.put<InventoryInoutController>(InventoryInoutController());
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
UperBody(),
const Expanded(
child: TaskPageBody(),
),
],
);
}
}

View File

@ -5,7 +5,7 @@ import 'package:sk_base_mobile/db_helper/dbHelper.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';
class HomeController extends GetxController { class InventoryInoutController extends GetxController {
RxMap userData = {}.obs; RxMap userData = {}.obs;
RxInt currentIndex = 0.obs; RxInt currentIndex = 0.obs;
final PageController pageController = PageController(); final PageController pageController = PageController();
@ -24,7 +24,7 @@ class HomeController extends GetxController {
RxList model = [].obs; RxList model = [].obs;
final ScrollController scrollController = ScrollController(); final ScrollController scrollController = ScrollController();
HomeController() {} InventoryInoutController() {}
getTasks() async { getTasks() async {
db.getData().then((value) { db.getData().then((value) {

View File

@ -14,16 +14,25 @@ class LandingPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Material( return Material(
child: Stack(children: [ child: GestureDetector(
const BackColors(), onTap: () {
SafeArea( controller.showCreateBtn.value = true;
child: Scaffold( },
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, child: Stack(children: [
floatingActionButton: const FloatingButton(), const BackColors(),
bottomNavigationBar: BottomNavBar(), SafeArea(
backgroundColor: Colors.transparent, child: Obx(() => Scaffold(
body: Obx(() => controller.pages[controller.currentIndex.value]), floatingActionButtonLocation:
)) FloatingActionButtonLocation.centerDocked,
])); floatingActionButton: controller.currentIndex.value == 0
? FloatingCreateButton()
: null,
bottomNavigationBar: BottomNavBar(),
backgroundColor: Colors.transparent,
body: Obx(() =>
controller.pages[controller.currentIndex.value]),
)))
])),
);
} }
} }

View File

@ -1,23 +1,15 @@
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/models/app_bottom_nav_item.dart';
import 'package:sk_base_mobile/services/app_info.service.dart'; import 'package:sk_base_mobile/services/app_info.service.dart';
class LandingController extends GetxController { class LandingController extends GetxController {
RxInt currentIndex = 0.obs; RxInt currentIndex = 0.obs;
List<IconData> iconList = [Icons.home_max, Icons.person_outline_rounded]; RxBool showCreateBtn = true.obs;
RxList bottomNavItems = RxList<BottomNavigationBarItem>([]);
List<Widget> pages = []; List<Widget> pages = [];
@override @override
onInit() { onInit() {
super.onInit(); super.onInit();
List<AppBottomNavItem> roleWithBottomNavItems = pages = AppInfoService.to.bottomNavItems!.map((e) => e.page!).toList();
AppInfoService.to.bottomNavItems!;
bottomNavItems.assignAll(roleWithBottomNavItems
.map((e) => BottomNavigationBarItem(
icon: e.icon, activeIcon: e.activeIcon, label: e.label))
.toList());
pages = roleWithBottomNavItems.map((e) => e.page!).toList();
} }
} }

View File

@ -46,13 +46,37 @@ class LoginScreen extends StatelessWidget {
SizedBox( SizedBox(
width: ScreenAdaper.width(10), width: ScreenAdaper.width(10),
), ),
Text( Stack(
'山矿通', alignment: Alignment.center,
style: TextStyle( children: [
fontWeight: FontWeight.w700, Text(
color: AppTheme.nearlyWhite, '山矿通',
letterSpacing: ScreenAdaper.sp(5), style: TextStyle(
fontSize: ScreenAdaper.sp(70)), shadows: [
Shadow(
color: Colors.black,
blurRadius: ScreenAdaper.sp(10),
offset: Offset(ScreenAdaper.width(5),
ScreenAdaper.height(5)),
),
],
letterSpacing: ScreenAdaper.width(5),
fontSize: ScreenAdaper.sp(70),
fontWeight: FontWeight.bold,
foreground: Paint()
..style = PaintingStyle.stroke
..strokeWidth = 2
..color = Colors.black),
),
Text(
'山矿通',
style: TextStyle(
fontWeight: FontWeight.w700,
color: AppTheme.nearlyWhite.withOpacity(0.9),
letterSpacing: ScreenAdaper.sp(5),
fontSize: ScreenAdaper.sp(70)),
),
],
) )
], ],
), ),
@ -150,21 +174,29 @@ class LoginScreen extends StatelessWidget {
Widget buildUserNameInput() { Widget buildUserNameInput() {
return TextFormField( return TextFormField(
//
keyboardType: TextInputType.text,
decoration: InputDecoration( decoration: InputDecoration(
prefixIcon: Icon( prefixIcon: Icon(
Icons.person_2_outlined, Icons.person_2_outlined,
size: ScreenAdaper.sp(40), size: ScreenAdaper.sp(40),
), ),
errorStyle: TextStyle(fontSize: ScreenAdaper.sp(20)),
contentPadding: EdgeInsets.symmetric(
horizontal: ScreenAdaper.width(30),
vertical: ScreenAdaper.height(10)),
hintText: '用户名', hintText: '用户名',
border: InputBorder.none, border: InputBorder.none,
focusedBorder: InputBorder.none), focusedBorder: InputBorder.none),
onFieldSubmitted: (value) { onFieldSubmitted: (value) {
_controller.passwordFocusNode.requestFocus(); _controller.passwordFocusNode.requestFocus();
}, },
autovalidateMode: AutovalidateMode.onUserInteraction,
style: TextStyle(fontSize: ScreenAdaper.sp(25)), style: TextStyle(fontSize: ScreenAdaper.sp(25)),
onChanged: (value) { onChanged: (value) {
_controller.username = value; _controller.username = value;
}, },
validator: (value) => value!.isEmpty ? '用户名不能为空' : null,
); );
} }
@ -175,6 +207,10 @@ class LoginScreen extends StatelessWidget {
Icons.lock_outlined, Icons.lock_outlined,
size: ScreenAdaper.sp(40), size: ScreenAdaper.sp(40),
), ),
errorStyle: TextStyle(fontSize: ScreenAdaper.sp(20)),
contentPadding: EdgeInsets.symmetric(
horizontal: ScreenAdaper.width(30),
vertical: ScreenAdaper.height(10)),
hintText: '密码', hintText: '密码',
border: InputBorder.none, border: InputBorder.none,
focusedBorder: InputBorder.none), focusedBorder: InputBorder.none),
@ -183,14 +219,12 @@ class LoginScreen extends StatelessWidget {
onFieldSubmitted: (value) { onFieldSubmitted: (value) {
_controller.doLogin(); _controller.doLogin();
}, },
style: TextStyle(fontSize: ScreenAdaper.sp(25)), style: TextStyle(fontSize: ScreenAdaper.sp(25)),
onChanged: (value) { onChanged: (value) {
_controller.password = value; _controller.password = value;
}, },
// validator: (String? value) { autovalidateMode: AutovalidateMode.onUserInteraction,
// return (value ?? '').length >= 6 ? null : '密码长度至少6位'; validator: (value) => value!.isEmpty ? '密码不能为空' : null,
// },
); );
} }

View File

@ -1,13 +1,13 @@
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/constants/bg_color.dart'; import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/new_task/components/text_input.dart'; import 'package:sk_base_mobile/screens/new_inventory_inout/components/text_input.dart';
import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart'; import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout_controller.dart';
class CategoryInput extends StatelessWidget { class CategoryInput extends StatelessWidget {
CategoryInput({super.key}); CategoryInput({super.key});
final controller = Get.put(NewTaskController()); final controller = Get.put(NewInventoryInoutController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -1,12 +1,12 @@
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/constants/bg_color.dart'; import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart'; import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout_controller.dart';
class DateTimeInput extends StatelessWidget { class DateTimeInput extends StatelessWidget {
DateTimeInput({super.key}); DateTimeInput({super.key});
final controller = Get.put(NewTaskController()); final controller = Get.put(NewInventoryInoutController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -1,11 +1,11 @@
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/constants/bg_color.dart'; import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/new_task/components/text_input.dart'; import 'package:sk_base_mobile/screens/new_inventory_inout/components/text_input.dart';
import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart'; import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout_controller.dart';
class DescriptionInput extends StatelessWidget { class DescriptionInput extends StatelessWidget {
final controller = Get.put(NewTaskController()); final controller = Get.put(NewInventoryInoutController());
DescriptionInput({super.key}); DescriptionInput({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -14,10 +14,10 @@ class DescriptionInput extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
SizedBox( const SizedBox(
height: defaultPadding / 2, height: defaultPadding / 2,
), ),
Padding( const Padding(
padding: const EdgeInsets.symmetric(vertical: 10), padding: const EdgeInsets.symmetric(vertical: 10),
child: Text( child: Text(
'Description', 'Description',

View File

@ -2,11 +2,11 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart'; import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/constants/constants.dart'; import 'package:sk_base_mobile/constants/constants.dart';
import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart'; import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout_controller.dart';
class SelectImageList extends StatelessWidget { class SelectImageList extends StatelessWidget {
SelectImageList({super.key}); SelectImageList({super.key});
final controller = Get.put(NewTaskController()); final controller = Get.put(NewInventoryInoutController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(

View File

@ -1,13 +1,13 @@
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/constants/bg_color.dart'; import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/new_task/components/periority_container.dart'; import 'package:sk_base_mobile/screens/new_inventory_inout/components/periority_container.dart';
import 'package:sk_base_mobile/screens/new_task/components/text_input.dart'; import 'package:sk_base_mobile/screens/new_inventory_inout/components/text_input.dart';
import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart'; import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout_controller.dart';
class LabelInput extends StatelessWidget { class LabelInput extends StatelessWidget {
LabelInput({super.key}); LabelInput({super.key});
final controller = Get.put(NewTaskController()); final controller = Get.put(NewInventoryInoutController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Padding(

View File

@ -1,7 +1,7 @@
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/constants/bg_color.dart'; import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart'; import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout_controller.dart';
class TextInputField extends StatelessWidget { class TextInputField extends StatelessWidget {
final TextEditingController controller; final TextEditingController controller;
@ -14,7 +14,7 @@ class TextInputField extends StatelessWidget {
required this.hint, required this.hint,
required this.focus, required this.focus,
required this.onTap}); required this.onTap});
final taskController = Get.put(NewTaskController()); final taskController = Get.put(NewInventoryInoutController());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AnimatedContainer( return AnimatedContainer(

View File

@ -0,0 +1,179 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/app_theme.dart';
import 'package:sk_base_mobile/models/product.model.dart';
import 'package:sk_base_mobile/screens/new_inventory_inout/components/category_input.dart';
import 'package:sk_base_mobile/screens/new_inventory_inout/components/date_time.dart';
import 'package:sk_base_mobile/screens/new_inventory_inout/components/description_input.dart';
import 'package:sk_base_mobile/screens/new_inventory_inout/components/lable_input.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/inventory_inout/components/responsive.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
class NewInventoryInout extends StatelessWidget {
NewInventoryInout({super.key});
final controller = Get.put(NewInventoryInoutController());
@override
Widget build(BuildContext context) {
return Container(
height: ScreenAdaper.height(800),
width: Get.width,
decoration: const BoxDecoration(
color: Colors.white,
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(
ScreenAdaper.sp(30),
),
topRight: Radius.circular(ScreenAdaper.sp(30))),
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
//
FocusScope.of(Get.context!).unfocus();
},
child: Stack(
children: [
Positioned.fill(
child: Column(
children: [
buildTitle(),
Expanded(
child: SingleChildScrollView(
child: buildForm(),
),
),
Obx(() => GradientButton(
onPressed: () => {controller.insertTask(context)},
isLoading: controller.loading.value,
))
],
))
],
))),
);
}
Widget buildTitle() {
return Container(
decoration: const BoxDecoration(
border: Border(bottom: BorderSide(color: AppTheme.dividerColor))),
padding: EdgeInsets.symmetric(
vertical: ScreenAdaper.height(5), horizontal: ScreenAdaper.width(20)),
child: Row(
children: [
Text(
'出入库登记',
style: TextStyle(
fontSize: ScreenAdaper.sp(25),
fontWeight: FontWeight.w700,
),
),
Spacer(),
IconButton(
onPressed: () {
Get.back();
},
icon: Icon(
Icons.close,
size: ScreenAdaper.sp(30),
))
],
),
);
}
Widget buildForm() {
final children = [
Row(children: [
Expanded(
flex: 1,
child: buildInoutPicker(),
),
SizedBox(
width: ScreenAdaper.width(10),
),
Expanded(
flex: 3,
child: buildProductPicker(),
)
]),
];
final child = Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: children,
);
return Form(
key: controller.formKey,
child: Container(
padding: EdgeInsets.symmetric(
vertical: ScreenAdaper.height(20),
horizontal: ScreenAdaper.width(20)),
alignment: Alignment.center,
child: child,
));
}
Widget buildInoutPicker() {
// picker
return DropdownButtonFormField<String>(
style:
TextStyle(fontSize: ScreenAdaper.sp(22), color: AppTheme.nearlyBlack),
// value: _dropdownValue,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(ScreenAdaper.sp(15))),
labelText: "出/入库",
),
onChanged: (String? newValue) {
// setState(() {
// _dropdownValue = newValue;
// });
},
items: <String>[
'入库',
'出库',
].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
);
}
Widget buildProductPicker() {
return TypeAheadField<ProductModel>(suggestionsCallback: (search) {
return [ProductModel(name: 'aaa'), ProductModel(name: 'bbb')];
}, builder: (context, controller, focusNode) {
return TextField(
controller: controller,
focusNode: focusNode,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(ScreenAdaper.sp(15))),
labelText: "选择产品",
));
}, itemBuilder: (context, product) {
return ListTile(
title: Text(product.name ?? ''),
subtitle: Text(product.name ?? ''),
);
}, onSelected: (city) {
// Navigator.of(context).push<void>(
// MaterialPageRoute(
// builder: (context) => CityPage(city: city),
// ),
// );
});
}
}

View File

@ -4,10 +4,12 @@ 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/task_model.dart'; import 'package:sk_base_mobile/models/task_model.dart';
import 'package:sk_base_mobile/screens/home/home_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/util/util.dart';
class NewTaskController extends GetxController { class NewInventoryInoutController extends GetxController {
final formKey = GlobalKey<FormState>();
DateTime? pickedDate; DateTime? pickedDate;
final DbHelper db = DbHelper(); final DbHelper db = DbHelper();
RxInt selectedImage = 0.obs; RxInt selectedImage = 0.obs;
@ -19,7 +21,7 @@ class NewTaskController extends GetxController {
RxString startTime = ''.obs; RxString startTime = ''.obs;
RxString endTime = ''.obs; RxString endTime = ''.obs;
RxBool loading = false.obs; RxBool loading = false.obs;
final homeController = Get.put(HomeController()); final inventoryInoutController = Get.put(InventoryInoutController());
final label = TextEditingController().obs; final label = TextEditingController().obs;
final description = TextEditingController().obs; final description = TextEditingController().obs;
final category = TextEditingController().obs; final category = TextEditingController().obs;
@ -129,7 +131,7 @@ class NewTaskController extends GetxController {
.then((value) { .then((value) {
Duration dif = pickedDate!.difference(DateTime( Duration dif = pickedDate!.difference(DateTime(
DateTime.now().year, DateTime.now().month, DateTime.now().day)); DateTime.now().year, DateTime.now().month, DateTime.now().day));
homeController.list[dif.inDays].add(value); inventoryInoutController.list[dif.inDays].add(value);
Timer(const Duration(seconds: 1), () { Timer(const Duration(seconds: 1), () {
loading.value = false; loading.value = false;
Get.back(); Get.back();

View File

@ -1,40 +0,0 @@
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/new_task/new_task_controller.dart';
class CreateTaskButton extends StatelessWidget {
CreateTaskButton({super.key});
final controller = Get.put(NewTaskController());
@override
Widget build(BuildContext context) {
return Container(
height: 60,
alignment: Alignment.center,
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(80), topLeft: Radius.circular(80)),
gradient: LinearGradient(colors: [
lightOrange,
darkOrange,
darkOrange,
])),
child: Obx(
() => controller.loading.value
? Container(
height: 15,
width: 15,
child: const CircularProgressIndicator(
color: Colors.white,
),
)
: const Text(
'Create Task',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16),
),
));
}
}

View File

@ -1,63 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/screens/new_task/components/category_input.dart';
import 'package:sk_base_mobile/screens/new_task/components/date_time.dart';
import 'package:sk_base_mobile/screens/new_task/components/description_input.dart';
import 'package:sk_base_mobile/screens/new_task/components/illustration_list.dart';
import 'package:sk_base_mobile/screens/new_task/components/lable_input.dart';
import 'package:sk_base_mobile/screens/new_task/components/task_button.dart';
import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart';
import 'package:sk_base_mobile/screens/home/components/responsive.dart';
class NewTask extends StatelessWidget {
NewTask({super.key});
final controller = Get.put(NewTaskController());
@override
Widget build(BuildContext context) {
return ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(
30,
),
topRight: Radius.circular(30)),
child: Container(
height: 650,
width: Responsive.isLargeTablet(context)
? MediaQuery.sizeOf(context).width / 2.5
: Responsive.isTablet(context)
? MediaQuery.sizeOf(context).width / 1.6
: MediaQuery.sizeOf(context).width,
decoration: const BoxDecoration(
color: Colors.white,
),
child: Stack(
children: [
Positioned.fill(
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SelectImageList(),
LabelInput(),
CategoryInput(),
DescriptionInput(),
DateTimeInput(),
],
),
),
),
GestureDetector(
onTap: () => controller.insertTask(context),
child: CreateTaskButton())
],
))
],
)),
);
}
}

View File

@ -0,0 +1,111 @@
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/util/screen_adaper_util.dart';
class WorkBenchModel {
final String title;
final String icon;
final String route;
WorkBenchModel(
{required this.title, required this.icon, 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'),
];
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(children: [
Container(
padding: EdgeInsets.all(ScreenAdaper.width(20)),
child: GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: works.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: Get.width > 800 ? 5 : 3,
crossAxisSpacing: ScreenAdaper.width(20),
mainAxisSpacing: ScreenAdaper.height(20),
childAspectRatio: 1.0),
itemBuilder: (BuildContext context, int index) {
return buildCard(index);
},
),
)
]));
}
Widget buildCard(int index) {
return Card(
clipBehavior: Clip.antiAlias,
shadowColor: AppTheme.black,
elevation: 10.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(ScreenAdaper.width(20))),
child: Stack(
children: [
Image.asset(works[index].icon),
Center(
child: Stack(
alignment: Alignment.center,
children: [
Text(
works[index].title,
style: TextStyle(
letterSpacing: ScreenAdaper.width(5),
fontSize: ScreenAdaper.sp(30),
fontWeight: FontWeight.bold,
foreground: Paint()
..style = PaintingStyle.stroke
..strokeWidth = 5
..color = Colors.black),
),
Text(
works[index].title,
style: TextStyle(
letterSpacing: ScreenAdaper.width(5),
color: Colors.white,
fontSize: ScreenAdaper.sp(30),
fontWeight: FontWeight.bold),
),
],
),
)
],
));
}
}

View File

@ -0,0 +1,21 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class WorkBenchController extends GetxController {
late final AnimationController animationController;
@override
void onInit() {
super.onInit();
// animationController = AnimationController(
// vsync: this,
// duration: Duration(seconds: 2),
// )..forward();
}
@override
void onClose() {
animationController.dispose();
super.onClose();
}
}

View File

@ -7,8 +7,9 @@ import 'package:package_info/package_info.dart';
import 'package:sk_base_mobile/app_theme.dart'; import 'package:sk_base_mobile/app_theme.dart';
import 'package:sk_base_mobile/models/app_bottom_nav_item.dart'; import 'package:sk_base_mobile/models/app_bottom_nav_item.dart';
import 'package:sk_base_mobile/models/app_config.dart'; import 'package:sk_base_mobile/models/app_config.dart';
import 'package:sk_base_mobile/screens/home/home.dart'; import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout.dart';
import 'package:sk_base_mobile/apis/api.dart' as Api; import 'package:sk_base_mobile/apis/api.dart' as Api;
import 'package:sk_base_mobile/screens/workbench/workbench.dart';
import 'package:sk_base_mobile/services/service.dart'; import 'package:sk_base_mobile/services/service.dart';
import 'package:sk_base_mobile/store/auth.store.dart'; import 'package:sk_base_mobile/store/auth.store.dart';
import 'package:sk_base_mobile/util/convert.dart'; import 'package:sk_base_mobile/util/convert.dart';
@ -27,17 +28,23 @@ class AppInfoService extends GetxService {
final isCameraing = RxBool(false); final isCameraing = RxBool(false);
List<AppBottomNavItem>? bottomNavItems = [ List<AppBottomNavItem>? bottomNavItems = [
AppBottomNavItem( AppBottomNavItem(
icon: const Icon(Icons.home_outlined), icon: Icons.home_max_outlined,
activeIcon: const Icon( activeIcon: Icons.home_max_outlined,
Icons.home, label: '登记',
), page: InvenotryInoutPage()),
label: '首页',
page: const HomePage()),
AppBottomNavItem( AppBottomNavItem(
icon: const Icon(Icons.person_outline_outlined), icon: Icons.inventory_outlined,
activeIcon: const Icon( activeIcon: Icons.inventory_rounded,
Icons.person, label: '库存',
), page: InvenotryInoutPage()),
AppBottomNavItem(
icon: Icons.widgets_outlined,
activeIcon: Icons.widgets_rounded,
label: '工作台',
page: WorkBenchPage()),
AppBottomNavItem(
icon: Icons.person_outline_outlined,
activeIcon: Icons.person,
label: '我的', label: '我的',
page: MinePage()), page: MinePage()),
]; ];

View File

@ -98,6 +98,7 @@ class AuthStore extends GetxController {
} }
} catch (e) { } catch (e) {
await SnackBarUtil().error('账号密码错误'); await SnackBarUtil().error('账号密码错误');
LoggerUtil().error(e);
} finally { } finally {
LoadingUtil.to.dismiss(); LoadingUtil.to.dismiss();
} }

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart'; 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/screens/landing/landing_controller.dart'; import 'package:sk_base_mobile/screens/landing/landing_controller.dart';
import 'package:sk_base_mobile/services/app_info.service.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart'; import 'package:sk_base_mobile/util/screen_adaper_util.dart';
import 'package:auto_size_text/auto_size_text.dart'; import 'package:auto_size_text/auto_size_text.dart';
@ -16,7 +17,7 @@ class BottomNavBar extends StatelessWidget {
() => AnimatedBottomNavigationBar.builder( () => AnimatedBottomNavigationBar.builder(
itemCount: controller.pages.length, itemCount: controller.pages.length,
elevation: ScreenAdaper.height(30), elevation: ScreenAdaper.height(30),
height: ScreenAdaper.height(80), height: ScreenAdaper.height(100),
activeIndex: controller.currentIndex.value, activeIndex: controller.currentIndex.value,
gapLocation: GapLocation.center, gapLocation: GapLocation.center,
notchSmoothness: NotchSmoothness.verySmoothEdge, notchSmoothness: NotchSmoothness.verySmoothEdge,
@ -34,12 +35,12 @@ class BottomNavBar extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Icon( Icon(
controller.iconList[index], AppInfoService.to.bottomNavItems![index].icon,
size: ScreenAdaper.sp(40), size: ScreenAdaper.sp(40),
color: color, color: color,
), ),
AutoSizeText( AutoSizeText(
controller.bottomNavItems[index].label, AppInfoService.to.bottomNavItems![index].label ?? '',
maxLines: 1, maxLines: 1,
style: TextStyle(color: color, fontSize: ScreenAdaper.sp(20)), style: TextStyle(color: color, fontSize: ScreenAdaper.sp(20)),
group: autoSizeGroup, group: autoSizeGroup,

View File

@ -1,73 +1,159 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
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/bg_color.dart'; import 'package:sk_base_mobile/screens/inventory_inout/components/responsive.dart';
import 'package:sk_base_mobile/screens/home/components/responsive.dart'; import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout_controller.dart';
import 'package:sk_base_mobile/screens/new_task/new_task.dart'; import 'package:sk_base_mobile/screens/landing/landing_controller.dart';
import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart'; import 'package:sk_base_mobile/util/screen_adaper_util.dart';
class FloatingButton extends StatelessWidget { class FloatingCreateButton extends StatelessWidget {
const FloatingButton({super.key}); FloatingCreateButton({super.key});
final controller = Get.find<LandingController>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return InkWell( final isTablet = Responsive.isTablet(context);
borderRadius: BorderRadius.circular(ScreenAdaper.sp(50)), return Obx(() => controller.showCreateBtn.value
onTap: () { ? InkWell(
Responsive.isTablet(context) borderRadius: BorderRadius.circular(ScreenAdaper.sp(50)),
? showGeneralDialog( onTap: () {
context: context, controller.showCreateBtn.value = false;
barrierLabel: "Barrier", return;
barrierDismissible: true, !isTablet
barrierColor: Colors.black.withOpacity(0.5), ? showGeneralDialog(
transitionDuration: const Duration(milliseconds: 400), context: context,
pageBuilder: (_, __, ___) { barrierLabel: "Barrier",
return Center( barrierDismissible: true,
child: ClipRRect( barrierColor: Colors.black.withOpacity(0.5),
borderRadius: BorderRadius.circular(30), transitionDuration: const Duration(milliseconds: 400),
child: Material(child: NewTask()), pageBuilder: (_, __, ___) {
return Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(30),
child: Material(child: NewInventoryInout()),
),
);
},
transitionBuilder: (_, anim, __, child) {
Tween<Offset> tween;
tween =
Tween(begin: const Offset(0, -1), end: Offset.zero);
return SlideTransition(
position: tween.animate(
CurvedAnimation(
parent: anim, curve: Curves.easeInOut),
),
child: child,
);
},
)
: showModalBottomSheet(
elevation: 0,
isScrollControlled: true,
backgroundColor: Colors.white,
context: context,
builder: (context) {
return NewInventoryInout();
},
);
},
child: Container(
height: ScreenAdaper.height(140),
width: ScreenAdaper.height(140),
decoration: const BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(colors: [
AppTheme.primaryColorLight,
AppTheme.primaryColor
])),
child: Icon(
Icons.add,
color: Colors.white,
size: ScreenAdaper.sp(70),
),
),
)
: TweenAnimationBuilder(
curve: Curves.easeInOut,
tween: Tween<double>(begin: 0, end: 1),
duration: const Duration(milliseconds: 200),
builder: (context, value, child) {
return Stack(
alignment: Alignment.center,
children: [
Transform.translate(
offset: Offset(-ScreenAdaper.width(120) * value,
-ScreenAdaper.height(120)),
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
height: ScreenAdaper.height(200),
width: ScreenAdaper.height(200),
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(30)),
gradient: LinearGradient(colors: [
AppTheme.primaryColorLight,
AppTheme.primaryColor
]),
),
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.add_circle_outline,
color: AppTheme.nearlyWhite,
size: ScreenAdaper.sp(70),
),
Text(
'入库',
style: TextStyle(
color: AppTheme.nearlyWhite,
fontSize: ScreenAdaper.sp(50),
letterSpacing: ScreenAdaper.width(5),
fontWeight: FontWeight.w700),
)
]),
), ),
); ),
}, Transform.translate(
transitionBuilder: (_, anim, __, child) { offset: Offset(ScreenAdaper.width(120) * value,
Tween<Offset> tween; -ScreenAdaper.height(120)),
child: AnimatedContainer(
tween = Tween(begin: const Offset(0, -1), end: Offset.zero); duration: const Duration(milliseconds: 200),
height: ScreenAdaper.height(200),
return SlideTransition( width: ScreenAdaper.height(200),
position: tween.animate( decoration: const BoxDecoration(
CurvedAnimation(parent: anim, curve: Curves.easeInOut), // shape: BoxShape.circle,
), borderRadius: BorderRadius.all(Radius.circular(30)),
// child: FadeTransition( gradient: LinearGradient(colors: [
// opacity: anim, AppTheme.primaryColorLight,
// child: child, AppTheme.primaryColor
// ), ]),
child: child, ),
); alignment: Alignment.center,
}, child: Column(
) mainAxisAlignment: MainAxisAlignment.center,
: showModalBottomSheet( children: [
elevation: 0, Icon(
isScrollControlled: true, //
backgroundColor: Colors.white, Icons.remove_circle_outline,
context: context, color: AppTheme.nearlyWhite,
builder: (context) { size: ScreenAdaper.sp(70),
return NewTask(); ),
}, Text(
'出库',
style: TextStyle(
color: AppTheme.nearlyWhite,
fontSize: ScreenAdaper.sp(50),
letterSpacing: ScreenAdaper.width(5),
fontWeight: FontWeight.w700),
)
])),
),
],
); );
}, },
child: Container( ));
height: ScreenAdaper.height(100),
width: ScreenAdaper.height(100),
decoration: const BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
colors: [AppTheme.primaryColorLight, AppTheme.primaryColor])),
child: Icon(
Icons.add,
color: Colors.white,
size: ScreenAdaper.sp(40),
),
),
);
} }
} }

View File

@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:sk_base_mobile/app_theme.dart';
import 'package:sk_base_mobile/constants/constants.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
class GradientButton extends StatelessWidget {
VoidCallback? onPressed;
bool isLoading;
String buttonText;
GradientButton(
{super.key,
this.buttonText = TextEnum.createInventoryInOutBtnText,
this.onPressed,
this.isLoading = false});
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(AppTheme.primaryColor),
padding: MaterialStateProperty.all<EdgeInsetsGeometry>(
EdgeInsets.symmetric(vertical: ScreenAdaper.height(10)),
),
minimumSize: MaterialStateProperty.all<Size>(
Size(double.infinity, ScreenAdaper.height(80))),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
),
),
onPressed: onPressed ?? () => {},
child: isLoading
? LoadingAnimationWidget.fourRotatingDots(
color: AppTheme.nearlyWhite,
size: ScreenAdaper.sp(40),
)
: Text(
buttonText,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: ScreenAdaper.sp(25),
),
),
),
);
}
}

View File

@ -262,6 +262,54 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.3.1" version: "3.3.1"
flutter_keyboard_visibility:
dependency: transitive
description:
name: flutter_keyboard_visibility
sha256: "98664be7be0e3ffca00de50f7f6a287ab62c763fc8c762e0a21584584a3ff4f8"
url: "https://pub.dev"
source: hosted
version: "6.0.0"
flutter_keyboard_visibility_linux:
dependency: transitive
description:
name: flutter_keyboard_visibility_linux
sha256: "6fba7cd9bb033b6ddd8c2beb4c99ad02d728f1e6e6d9b9446667398b2ac39f08"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
flutter_keyboard_visibility_macos:
dependency: transitive
description:
name: flutter_keyboard_visibility_macos
sha256: c5c49b16fff453dfdafdc16f26bdd8fb8d55812a1d50b0ce25fc8d9f2e53d086
url: "https://pub.dev"
source: hosted
version: "1.0.0"
flutter_keyboard_visibility_platform_interface:
dependency: transitive
description:
name: flutter_keyboard_visibility_platform_interface
sha256: e43a89845873f7be10cb3884345ceb9aebf00a659f479d1c8f4293fcb37022a4
url: "https://pub.dev"
source: hosted
version: "2.0.0"
flutter_keyboard_visibility_web:
dependency: transitive
description:
name: flutter_keyboard_visibility_web
sha256: d3771a2e752880c79203f8d80658401d0c998e4183edca05a149f5098ce6e3d1
url: "https://pub.dev"
source: hosted
version: "2.0.0"
flutter_keyboard_visibility_windows:
dependency: transitive
description:
name: flutter_keyboard_visibility_windows
sha256: fc4b0f0b6be9b93ae527f3d527fb56ee2d918cd88bbca438c478af7bcfd0ef73
url: "https://pub.dev"
source: hosted
version: "1.0.0"
flutter_launcher_icons: flutter_launcher_icons:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -307,6 +355,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_typeahead:
dependency: "direct main"
description:
name: flutter_typeahead
sha256: d64712c65db240b1057559b952398ebb6e498077baeebf9b0731dade62438a6d
url: "https://pub.dev"
source: hosted
version: "5.2.0"
flutter_web_plugins: flutter_web_plugins:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -632,6 +688,38 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.8" version: "2.1.8"
pointer_interceptor:
dependency: transitive
description:
name: pointer_interceptor
sha256: bd18321519718678d5fa98ad3a3359cbc7a31f018554eab80b73d08a7f0c165a
url: "https://pub.dev"
source: hosted
version: "0.10.1"
pointer_interceptor_ios:
dependency: transitive
description:
name: pointer_interceptor_ios
sha256: "2e73c39452830adc4695757130676a39412a3b7f3c34e3f752791b5384770877"
url: "https://pub.dev"
source: hosted
version: "0.10.0+2"
pointer_interceptor_platform_interface:
dependency: transitive
description:
name: pointer_interceptor_platform_interface
sha256: "0597b0560e14354baeb23f8375cd612e8bd4841bf8306ecb71fcd0bb78552506"
url: "https://pub.dev"
source: hosted
version: "0.10.0+1"
pointer_interceptor_web:
dependency: transitive
description:
name: pointer_interceptor_web
sha256: "9386e064097fd16419e935c23f08f35b58e6aaec155dd39bd6a003b88f9c14b4"
url: "https://pub.dev"
source: hosted
version: "0.10.1+2"
pointycastle: pointycastle:
dependency: transitive dependency: transitive
description: description:

View File

@ -56,6 +56,7 @@ dependencies:
sqflite: ^2.3.2 sqflite: ^2.3.2
path: ^1.8.3 path: ^1.8.3
path_provider: ^2.1.2 path_provider: ^2.1.2
flutter_typeahead: ^5.2.0
dev_dependencies: dev_dependencies: