feat: inventory inout feature developing
After Width: | Height: | Size: 1014 KiB |
After Width: | Height: | Size: 316 KiB |
After Width: | Height: | Size: 510 KiB |
After Width: | Height: | Size: 414 KiB |
After Width: | Height: | Size: 912 KiB |
After Width: | Height: | Size: 282 KiB |
After Width: | Height: | Size: 372 KiB |
|
@ -23,6 +23,7 @@ class AppTheme {
|
|||
static const String fontName = 'NotoSans';
|
||||
static const Color activeNavigationBarColor = primaryColor;
|
||||
static const Color notActiveNavigationBarColor = Colors.grey;
|
||||
static const Color dividerColor = Color.fromARGB(255, 197, 197, 197);
|
||||
}
|
||||
|
||||
final theme = ThemeData(
|
||||
|
@ -32,7 +33,7 @@ final theme = ThemeData(
|
|||
primaryColorDark: AppTheme.primaryColorDark,
|
||||
progressIndicatorTheme:
|
||||
const ProgressIndicatorThemeData(color: AppTheme.primaryColor),
|
||||
dividerColor: AppTheme.grey,
|
||||
dividerColor: AppTheme.dividerColor,
|
||||
cardColor: AppTheme.white,
|
||||
scaffoldBackgroundColor: AppTheme.nearlyWhite,
|
||||
bottomNavigationBarTheme: BottomNavigationBarThemeData(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// Global config
|
||||
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 DEBUG = true;
|
||||
static const PRIVACY_POLICY = 'http://h5.heeru.xyz/privacyPolicy.html';
|
||||
|
|
|
@ -2,4 +2,5 @@ class TextEnum {
|
|||
static const String noInventoryInout = "今天没有出入库记录";
|
||||
static const String homeWelcomeText = '你好,';
|
||||
static const String backToTodayButtonText = '今天';
|
||||
static const String createInventoryInOutBtnText = '提交';
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
class AppBottomNavItem {
|
||||
Icon icon;
|
||||
Icon activeIcon;
|
||||
IconData icon;
|
||||
IconData activeIcon;
|
||||
String? label;
|
||||
Widget? page;
|
||||
AppBottomNavItem(
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
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/home/components/change_icon.dart';
|
||||
import 'package:sk_base_mobile/screens/home/components/today_button.dart';
|
||||
import 'package:sk_base_mobile/screens/home/home_controller.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/components/change_icon.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';
|
||||
|
||||
class ChangeButtonRow extends StatelessWidget {
|
||||
ChangeButtonRow({super.key});
|
||||
final controller = Get.put(HomeController());
|
||||
final controller = Get.put(InventoryInoutController());
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
|
@ -3,13 +3,13 @@ import 'package:get/get.dart';
|
|||
import 'package:sk_base_mobile/app_theme.dart';
|
||||
import 'package:sk_base_mobile/constants/bg_color.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/util/screen_adaper_util.dart';
|
||||
|
||||
class CustomAppBar extends StatelessWidget {
|
||||
CustomAppBar({super.key});
|
||||
final controller = Get.put(HomeController());
|
||||
final controller = Get.put(InventoryInoutController());
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
|
@ -2,14 +2,14 @@ import 'package:flutter/material.dart';
|
|||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/app_theme.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 'dates.dart';
|
||||
|
||||
class DateContainer extends StatelessWidget {
|
||||
final int index;
|
||||
DateContainer({super.key, required this.index});
|
||||
final controller = Get.put(HomeController());
|
||||
final controller = Get.put(InventoryInoutController());
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final size = MediaQuery.sizeOf(context);
|
|
@ -2,13 +2,13 @@ import 'dart:ui';
|
|||
|
||||
import 'package:flutter/material.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';
|
||||
|
||||
class Dates extends StatelessWidget {
|
||||
Dates({super.key, required this.index});
|
||||
final int index;
|
||||
final controller = Get.put(HomeController());
|
||||
final controller = Get.put(InventoryInoutController());
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
|
@ -4,7 +4,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/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 {
|
||||
TaskTitle({super.key, required this.index, required this.ind});
|
||||
|
@ -12,7 +12,7 @@ class TaskTitle extends StatelessWidget {
|
|||
final int ind;
|
||||
final int randomColor1 = Random().nextInt(9);
|
||||
final int randomColor2 = Random().nextInt(9);
|
||||
final controller = Get.put(HomeController());
|
||||
final controller = Get.put(InventoryInoutController());
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
|
@ -2,15 +2,15 @@ import 'package:flutter/material.dart';
|
|||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/constants/bg_color.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/home/home_controller.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/components/task_detail_col.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout_controller.dart';
|
||||
import 'package:sk_base_mobile/util/util.dart';
|
||||
|
||||
class TaskDetailContainer extends StatelessWidget {
|
||||
TaskDetailContainer({super.key, required this.index, required this.ind});
|
||||
final int index;
|
||||
final int ind;
|
||||
final controller = Get.put(HomeController());
|
||||
final controller = Get.put(InventoryInoutController());
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Dismissible(
|
|
@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
|
|||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/app_theme.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/home/components/task_detail_container.dart';
|
||||
import 'package:sk_base_mobile/screens/home/home_controller.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/components/responsive.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/components/task_detail_container.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout_controller.dart';
|
||||
import 'package:sk_base_mobile/util/util.dart';
|
||||
|
||||
class TaskList extends StatelessWidget {
|
||||
|
@ -35,7 +35,7 @@ class Grid extends StatelessWidget {
|
|||
final int crossAsis;
|
||||
final double ratio;
|
||||
final int ind;
|
||||
final controller = Get.put(HomeController());
|
||||
final controller = Get.put(InventoryInoutController());
|
||||
Grid(
|
||||
{super.key,
|
||||
required this.crossAsis,
|
|
@ -1,11 +1,11 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/screens/home/components/task_list.dart';
|
||||
import 'package:sk_base_mobile/screens/home/home_controller.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/components/task_list.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout_controller.dart';
|
||||
|
||||
class TaskPageView extends StatelessWidget {
|
||||
TaskPageView({super.key});
|
||||
final controller = Get.put(HomeController());
|
||||
final controller = Get.put(InventoryInoutController());
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PageView(
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:sk_base_mobile/screens/home/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/change_button_roe.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/components/task_page_View.dart';
|
||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||
|
||||
class TaskPageBody extends StatelessWidget {
|
|
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/app_theme.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';
|
||||
|
||||
class TodayButton extends StatelessWidget {
|
||||
|
@ -10,7 +10,7 @@ class TodayButton extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final controller = Get.put(HomeController());
|
||||
final controller = Get.put(InventoryInoutController());
|
||||
return InkWell(
|
||||
borderRadius: BorderRadius.circular(ScreenAdaper.sp(30)),
|
||||
onTap: () => controller.pageController.animateToPage(0,
|
|
@ -1,14 +1,14 @@
|
|||
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/home/components/custom_app_bar.dart';
|
||||
import 'package:sk_base_mobile/screens/home/components/date_container.dart';
|
||||
import 'package:sk_base_mobile/screens/home/home_controller.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/components/custom_app_bar.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/components/date_container.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout_controller.dart';
|
||||
import 'package:sk_base_mobile/util/util.dart';
|
||||
|
||||
class UperBody extends StatelessWidget {
|
||||
UperBody({super.key});
|
||||
final controller = Get.put(HomeController());
|
||||
final controller = Get.put(InventoryInoutController());
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
|
@ -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(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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/modal.util.dart';
|
||||
|
||||
class HomeController extends GetxController {
|
||||
class InventoryInoutController extends GetxController {
|
||||
RxMap userData = {}.obs;
|
||||
RxInt currentIndex = 0.obs;
|
||||
final PageController pageController = PageController();
|
||||
|
@ -24,7 +24,7 @@ class HomeController extends GetxController {
|
|||
RxList model = [].obs;
|
||||
final ScrollController scrollController = ScrollController();
|
||||
|
||||
HomeController() {}
|
||||
InventoryInoutController() {}
|
||||
|
||||
getTasks() async {
|
||||
db.getData().then((value) {
|
|
@ -14,16 +14,25 @@ class LandingPage extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
child: Stack(children: [
|
||||
const BackColors(),
|
||||
SafeArea(
|
||||
child: Scaffold(
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
|
||||
floatingActionButton: const FloatingButton(),
|
||||
bottomNavigationBar: BottomNavBar(),
|
||||
backgroundColor: Colors.transparent,
|
||||
body: Obx(() => controller.pages[controller.currentIndex.value]),
|
||||
))
|
||||
]));
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
controller.showCreateBtn.value = true;
|
||||
},
|
||||
child: Stack(children: [
|
||||
const BackColors(),
|
||||
SafeArea(
|
||||
child: Obx(() => Scaffold(
|
||||
floatingActionButtonLocation:
|
||||
FloatingActionButtonLocation.centerDocked,
|
||||
floatingActionButton: controller.currentIndex.value == 0
|
||||
? FloatingCreateButton()
|
||||
: null,
|
||||
bottomNavigationBar: BottomNavBar(),
|
||||
backgroundColor: Colors.transparent,
|
||||
body: Obx(() =>
|
||||
controller.pages[controller.currentIndex.value]),
|
||||
)))
|
||||
])),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,15 @@
|
|||
import 'package:flutter/material.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';
|
||||
|
||||
class LandingController extends GetxController {
|
||||
RxInt currentIndex = 0.obs;
|
||||
List<IconData> iconList = [Icons.home_max, Icons.person_outline_rounded];
|
||||
RxList bottomNavItems = RxList<BottomNavigationBarItem>([]);
|
||||
RxBool showCreateBtn = true.obs;
|
||||
List<Widget> pages = [];
|
||||
|
||||
@override
|
||||
onInit() {
|
||||
super.onInit();
|
||||
List<AppBottomNavItem> roleWithBottomNavItems =
|
||||
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();
|
||||
pages = AppInfoService.to.bottomNavItems!.map((e) => e.page!).toList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,13 +46,37 @@ class LoginScreen extends StatelessWidget {
|
|||
SizedBox(
|
||||
width: ScreenAdaper.width(10),
|
||||
),
|
||||
Text(
|
||||
'山矿通',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppTheme.nearlyWhite,
|
||||
letterSpacing: ScreenAdaper.sp(5),
|
||||
fontSize: ScreenAdaper.sp(70)),
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'山矿通',
|
||||
style: TextStyle(
|
||||
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() {
|
||||
return TextFormField(
|
||||
// 英文数字键盘
|
||||
keyboardType: TextInputType.text,
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: Icon(
|
||||
Icons.person_2_outlined,
|
||||
size: ScreenAdaper.sp(40),
|
||||
),
|
||||
errorStyle: TextStyle(fontSize: ScreenAdaper.sp(20)),
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: ScreenAdaper.width(30),
|
||||
vertical: ScreenAdaper.height(10)),
|
||||
hintText: '用户名',
|
||||
border: InputBorder.none,
|
||||
focusedBorder: InputBorder.none),
|
||||
onFieldSubmitted: (value) {
|
||||
_controller.passwordFocusNode.requestFocus();
|
||||
},
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
style: TextStyle(fontSize: ScreenAdaper.sp(25)),
|
||||
onChanged: (value) {
|
||||
_controller.username = value;
|
||||
},
|
||||
validator: (value) => value!.isEmpty ? '用户名不能为空' : null,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -175,6 +207,10 @@ class LoginScreen extends StatelessWidget {
|
|||
Icons.lock_outlined,
|
||||
size: ScreenAdaper.sp(40),
|
||||
),
|
||||
errorStyle: TextStyle(fontSize: ScreenAdaper.sp(20)),
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: ScreenAdaper.width(30),
|
||||
vertical: ScreenAdaper.height(10)),
|
||||
hintText: '密码',
|
||||
border: InputBorder.none,
|
||||
focusedBorder: InputBorder.none),
|
||||
|
@ -183,14 +219,12 @@ class LoginScreen extends StatelessWidget {
|
|||
onFieldSubmitted: (value) {
|
||||
_controller.doLogin();
|
||||
},
|
||||
|
||||
style: TextStyle(fontSize: ScreenAdaper.sp(25)),
|
||||
onChanged: (value) {
|
||||
_controller.password = value;
|
||||
},
|
||||
// validator: (String? value) {
|
||||
// return (value ?? '').length >= 6 ? null : '密码长度至少6位';
|
||||
// },
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
validator: (value) => value!.isEmpty ? '密码不能为空' : null,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
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/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/components/text_input.dart';
|
||||
import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout_controller.dart';
|
||||
|
||||
class CategoryInput extends StatelessWidget {
|
||||
CategoryInput({super.key});
|
||||
|
||||
final controller = Get.put(NewTaskController());
|
||||
final controller = Get.put(NewInventoryInoutController());
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
|
@ -1,12 +1,12 @@
|
|||
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';
|
||||
import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout_controller.dart';
|
||||
|
||||
class DateTimeInput extends StatelessWidget {
|
||||
DateTimeInput({super.key});
|
||||
|
||||
final controller = Get.put(NewTaskController());
|
||||
final controller = Get.put(NewInventoryInoutController());
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
|
@ -1,11 +1,11 @@
|
|||
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/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/components/text_input.dart';
|
||||
import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout_controller.dart';
|
||||
|
||||
class DescriptionInput extends StatelessWidget {
|
||||
final controller = Get.put(NewTaskController());
|
||||
final controller = Get.put(NewInventoryInoutController());
|
||||
DescriptionInput({super.key});
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -14,10 +14,10 @@ class DescriptionInput extends StatelessWidget {
|
|||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
const SizedBox(
|
||||
height: defaultPadding / 2,
|
||||
),
|
||||
Padding(
|
||||
const Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Text(
|
||||
'Description',
|
|
@ -2,11 +2,11 @@ import 'package:flutter/material.dart';
|
|||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/constants/bg_color.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 {
|
||||
SelectImageList({super.key});
|
||||
final controller = Get.put(NewTaskController());
|
||||
final controller = Get.put(NewInventoryInoutController());
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
|
@ -1,13 +1,13 @@
|
|||
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/components/periority_container.dart';
|
||||
import 'package:sk_base_mobile/screens/new_task/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/components/periority_container.dart';
|
||||
import 'package:sk_base_mobile/screens/new_inventory_inout/components/text_input.dart';
|
||||
import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout_controller.dart';
|
||||
|
||||
class LabelInput extends StatelessWidget {
|
||||
LabelInput({super.key});
|
||||
final controller = Get.put(NewTaskController());
|
||||
final controller = Get.put(NewInventoryInoutController());
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
|
@ -1,7 +1,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/new_task/new_task_controller.dart';
|
||||
import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout_controller.dart';
|
||||
|
||||
class TextInputField extends StatelessWidget {
|
||||
final TextEditingController controller;
|
||||
|
@ -14,7 +14,7 @@ class TextInputField extends StatelessWidget {
|
|||
required this.hint,
|
||||
required this.focus,
|
||||
required this.onTap});
|
||||
final taskController = Get.put(NewTaskController());
|
||||
final taskController = Get.put(NewInventoryInoutController());
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnimatedContainer(
|
|
@ -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),
|
||||
// ),
|
||||
// );
|
||||
});
|
||||
}
|
||||
}
|
|
@ -4,10 +4,12 @@ import 'package:flutter/material.dart';
|
|||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/db_helper/dbHelper.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';
|
||||
|
||||
class NewTaskController extends GetxController {
|
||||
class NewInventoryInoutController extends GetxController {
|
||||
final formKey = GlobalKey<FormState>();
|
||||
|
||||
DateTime? pickedDate;
|
||||
final DbHelper db = DbHelper();
|
||||
RxInt selectedImage = 0.obs;
|
||||
|
@ -19,7 +21,7 @@ class NewTaskController extends GetxController {
|
|||
RxString startTime = ''.obs;
|
||||
RxString endTime = ''.obs;
|
||||
RxBool loading = false.obs;
|
||||
final homeController = Get.put(HomeController());
|
||||
final inventoryInoutController = Get.put(InventoryInoutController());
|
||||
final label = TextEditingController().obs;
|
||||
final description = TextEditingController().obs;
|
||||
final category = TextEditingController().obs;
|
||||
|
@ -129,7 +131,7 @@ class NewTaskController extends GetxController {
|
|||
.then((value) {
|
||||
Duration dif = pickedDate!.difference(DateTime(
|
||||
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), () {
|
||||
loading.value = false;
|
||||
Get.back();
|
|
@ -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),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
|
@ -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())
|
||||
],
|
||||
))
|
||||
],
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
));
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -7,8 +7,9 @@ import 'package:package_info/package_info.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_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/screens/workbench/workbench.dart';
|
||||
import 'package:sk_base_mobile/services/service.dart';
|
||||
import 'package:sk_base_mobile/store/auth.store.dart';
|
||||
import 'package:sk_base_mobile/util/convert.dart';
|
||||
|
@ -27,17 +28,23 @@ class AppInfoService extends GetxService {
|
|||
final isCameraing = RxBool(false);
|
||||
List<AppBottomNavItem>? bottomNavItems = [
|
||||
AppBottomNavItem(
|
||||
icon: const Icon(Icons.home_outlined),
|
||||
activeIcon: const Icon(
|
||||
Icons.home,
|
||||
),
|
||||
label: '首页',
|
||||
page: const HomePage()),
|
||||
icon: Icons.home_max_outlined,
|
||||
activeIcon: Icons.home_max_outlined,
|
||||
label: '登记',
|
||||
page: InvenotryInoutPage()),
|
||||
AppBottomNavItem(
|
||||
icon: const Icon(Icons.person_outline_outlined),
|
||||
activeIcon: const Icon(
|
||||
Icons.person,
|
||||
),
|
||||
icon: Icons.inventory_outlined,
|
||||
activeIcon: Icons.inventory_rounded,
|
||||
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: '我的',
|
||||
page: MinePage()),
|
||||
];
|
||||
|
|
|
@ -98,6 +98,7 @@ class AuthStore extends GetxController {
|
|||
}
|
||||
} catch (e) {
|
||||
await SnackBarUtil().error('账号密码错误');
|
||||
LoggerUtil().error(e);
|
||||
} finally {
|
||||
LoadingUtil.to.dismiss();
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/app_theme.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:auto_size_text/auto_size_text.dart';
|
||||
|
||||
|
@ -16,7 +17,7 @@ class BottomNavBar extends StatelessWidget {
|
|||
() => AnimatedBottomNavigationBar.builder(
|
||||
itemCount: controller.pages.length,
|
||||
elevation: ScreenAdaper.height(30),
|
||||
height: ScreenAdaper.height(80),
|
||||
height: ScreenAdaper.height(100),
|
||||
activeIndex: controller.currentIndex.value,
|
||||
gapLocation: GapLocation.center,
|
||||
notchSmoothness: NotchSmoothness.verySmoothEdge,
|
||||
|
@ -34,12 +35,12 @@ class BottomNavBar extends StatelessWidget {
|
|||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
controller.iconList[index],
|
||||
AppInfoService.to.bottomNavItems![index].icon,
|
||||
size: ScreenAdaper.sp(40),
|
||||
color: color,
|
||||
),
|
||||
AutoSizeText(
|
||||
controller.bottomNavItems[index].label,
|
||||
AppInfoService.to.bottomNavItems![index].label ?? '',
|
||||
maxLines: 1,
|
||||
style: TextStyle(color: color, fontSize: ScreenAdaper.sp(20)),
|
||||
group: autoSizeGroup,
|
||||
|
|
|
@ -1,73 +1,159 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/app_theme.dart';
|
||||
import 'package:sk_base_mobile/constants/bg_color.dart';
|
||||
import 'package:sk_base_mobile/screens/home/components/responsive.dart';
|
||||
import 'package:sk_base_mobile/screens/new_task/new_task.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/components/responsive.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout_controller.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';
|
||||
|
||||
class FloatingButton extends StatelessWidget {
|
||||
const FloatingButton({super.key});
|
||||
class FloatingCreateButton extends StatelessWidget {
|
||||
FloatingCreateButton({super.key});
|
||||
final controller = Get.find<LandingController>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
borderRadius: BorderRadius.circular(ScreenAdaper.sp(50)),
|
||||
onTap: () {
|
||||
Responsive.isTablet(context)
|
||||
? showGeneralDialog(
|
||||
context: context,
|
||||
barrierLabel: "Barrier",
|
||||
barrierDismissible: true,
|
||||
barrierColor: Colors.black.withOpacity(0.5),
|
||||
transitionDuration: const Duration(milliseconds: 400),
|
||||
pageBuilder: (_, __, ___) {
|
||||
return Center(
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
child: Material(child: NewTask()),
|
||||
final isTablet = Responsive.isTablet(context);
|
||||
return Obx(() => controller.showCreateBtn.value
|
||||
? InkWell(
|
||||
borderRadius: BorderRadius.circular(ScreenAdaper.sp(50)),
|
||||
onTap: () {
|
||||
controller.showCreateBtn.value = false;
|
||||
return;
|
||||
!isTablet
|
||||
? showGeneralDialog(
|
||||
context: context,
|
||||
barrierLabel: "Barrier",
|
||||
barrierDismissible: true,
|
||||
barrierColor: Colors.black.withOpacity(0.5),
|
||||
transitionDuration: const Duration(milliseconds: 400),
|
||||
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),
|
||||
)
|
||||
]),
|
||||
),
|
||||
);
|
||||
},
|
||||
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: FadeTransition(
|
||||
// opacity: anim,
|
||||
// child: child,
|
||||
// ),
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
)
|
||||
: showModalBottomSheet(
|
||||
elevation: 0,
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.white,
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return NewTask();
|
||||
},
|
||||
),
|
||||
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(
|
||||
// shape: BoxShape.circle,
|
||||
borderRadius: BorderRadius.all(Radius.circular(30)),
|
||||
gradient: LinearGradient(colors: [
|
||||
AppTheme.primaryColorLight,
|
||||
AppTheme.primaryColor
|
||||
]),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
// 减号、
|
||||
Icons.remove_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),
|
||||
)
|
||||
])),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
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),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
88
pubspec.lock
|
@ -262,6 +262,54 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
|
@ -307,6 +355,14 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
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:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
@ -632,6 +688,38 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -56,6 +56,7 @@ dependencies:
|
|||
sqflite: ^2.3.2
|
||||
path: ^1.8.3
|
||||
path_provider: ^2.1.2
|
||||
flutter_typeahead: ^5.2.0
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
|