feat: inventory inout history
This commit is contained in:
parent
f725a72a9d
commit
b0c51290cf
15
.metadata
15
.metadata
|
@ -15,24 +15,9 @@ migration:
|
|||
- platform: root
|
||||
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||
- platform: android
|
||||
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||
- platform: ios
|
||||
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||
- platform: linux
|
||||
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||
- platform: macos
|
||||
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||
- platform: web
|
||||
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||
- platform: windows
|
||||
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||
|
||||
# User provided section
|
||||
|
||||
|
|
|
@ -33,6 +33,12 @@ Future<Response<PaginationData>> getProducts(Map params) {
|
|||
queryParameters: {'page': 1, 'pageSize': 10, ...params});
|
||||
}
|
||||
|
||||
// 分页获取原材料出入库列表
|
||||
Future<Response<PaginationData>> getInventoryInout(Map params) {
|
||||
return DioService.dio.get<PaginationData>(Urls.getInventoryInout,
|
||||
queryParameters: {'page': 1, 'pageSize': 10, ...(params)});
|
||||
}
|
||||
|
||||
Future<Response> logout() {
|
||||
return DioService.dio.post(
|
||||
Urls.logout,
|
||||
|
|
|
@ -39,7 +39,13 @@ final theme = ThemeData(
|
|||
800: AppTheme.primaryColorDark,
|
||||
900: AppTheme.primaryColorDark,
|
||||
}),
|
||||
primaryColorLight: AppTheme.primaryColorLight,
|
||||
fontFamily: AppTheme.fontName,
|
||||
textButtonTheme: TextButtonThemeData(
|
||||
style: ButtonStyle(
|
||||
foregroundColor:
|
||||
MaterialStateProperty.all<Color>(AppTheme.primaryColor), // 设置文本颜色为红色
|
||||
)),
|
||||
datePickerTheme: DatePickerThemeData(
|
||||
confirmButtonStyle: ButtonStyle(
|
||||
textStyle: MaterialStateProperty.resolveWith<TextStyle?>(
|
||||
|
@ -57,7 +63,7 @@ final theme = ThemeData(
|
|||
return null;
|
||||
},
|
||||
),
|
||||
rangeSelectionBackgroundColor: AppTheme.primaryColor,
|
||||
// rangeSelectionBackgroundColor: AppTheme.primaryColor,
|
||||
dayBackgroundColor: MaterialStateProperty.resolveWith<Color?>(
|
||||
(Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.selected)) {
|
||||
|
@ -91,7 +97,7 @@ final theme = ThemeData(
|
|||
backgroundColor: AppTheme.primaryColor,
|
||||
titleTextStyle: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: ScreenAdaper.sp(25),
|
||||
fontSize: ScreenAdaper.sp(30),
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
|
|
|
@ -8,5 +8,6 @@ class Urls {
|
|||
static String getUserInfo = 'account/profile';
|
||||
static String getProjects = 'project';
|
||||
static String getProducts = 'product';
|
||||
static String getInventoryInout = 'materials-in-out';
|
||||
static String updateAvatar = 'user/updateAvatar';
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/app_theme.dart';
|
||||
|
@ -5,6 +6,7 @@ import 'package:sk_base_mobile/constants/constants.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';
|
||||
import 'package:sk_base_mobile/widgets/core/zt_base_date_picker.dart';
|
||||
|
||||
class CustomAppBar extends StatelessWidget {
|
||||
CustomAppBar({super.key});
|
||||
|
@ -44,27 +46,69 @@ class CustomAppBar extends StatelessWidget {
|
|||
const Spacer(
|
||||
flex: 10,
|
||||
),
|
||||
Container(
|
||||
height: ScreenAdaper.height(70),
|
||||
width: ScreenAdaper.width(70),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
color: AppTheme.primaryColorLight,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppTheme.primaryColor,
|
||||
blurRadius: ScreenAdaper.sp(20),
|
||||
offset: Offset(0, ScreenAdaper.height(10)))
|
||||
]),
|
||||
child: Icon(
|
||||
Icons.account_circle_outlined,
|
||||
size: ScreenAdaper.sp(40),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
buildDatePicker(),
|
||||
if (ScreenAdaper.isLandspace()) const Spacer(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildDatePicker() {
|
||||
return InkWell(
|
||||
onTap: () async {
|
||||
showCupertinoModalPopup(
|
||||
context: Get.overlayContext!,
|
||||
builder: (BuildContext context) {
|
||||
return ZtBaseDatePicker();
|
||||
},
|
||||
);
|
||||
// showCupertinoModalPopup(
|
||||
// context: Get.overlayContext!,
|
||||
// builder: (BuildContext context) {
|
||||
// return Container(
|
||||
// height: 200,
|
||||
// color: Colors.white,
|
||||
// child: CupertinoDatePicker(
|
||||
// mode: CupertinoDatePickerMode.date,
|
||||
// initialDateTime: DateTime.now(),
|
||||
// onDateTimeChanged: (DateTime newDateTime) {
|
||||
// // 处理用户选择的日期
|
||||
// },
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// );
|
||||
// final picker = await CupertinoDatePicker(
|
||||
// context: Get.overlayContext!,
|
||||
// initialDate: DateTime.now(),
|
||||
// helpText: '选择的日期',
|
||||
// confirmText: '确定',
|
||||
// cancelText: '取消',
|
||||
// firstDate: DateTime(2000, 1, 1),
|
||||
// lastDate: DateTime.now().add(const Duration(days: 7)));
|
||||
},
|
||||
child: Container(
|
||||
height: ScreenAdaper.height(70),
|
||||
width: ScreenAdaper.width(70),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
color: AppTheme.primaryColorLight,
|
||||
gradient: LinearGradient(colors: [
|
||||
AppTheme.primaryColorLight,
|
||||
AppTheme.primaryColor,
|
||||
]),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppTheme.primaryColor,
|
||||
blurRadius: ScreenAdaper.sp(20),
|
||||
offset: Offset(0, ScreenAdaper.height(10)))
|
||||
]),
|
||||
child: Icon(
|
||||
Icons.calendar_month_outlined,
|
||||
size: ScreenAdaper.sp(40),
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ class DateContainer extends StatelessWidget {
|
|||
duration: const Duration(milliseconds: 200),
|
||||
height: ScreenAdaper.height(120),
|
||||
width: ScreenAdaper.width(110),
|
||||
margin: EdgeInsets.only(left: ScreenAdaper.width(size.width) * 0.05),
|
||||
margin: EdgeInsets.only(right: ScreenAdaper.width(size.width) * 0.05),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(ScreenAdaper.sp(20)),
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout_controller.dart';
|
||||
|
@ -16,37 +14,37 @@ class Dates extends StatelessWidget {
|
|||
children: [
|
||||
Obx(
|
||||
() => Text(
|
||||
DateUtil.getMonth(DateTime.now().add(Duration(days: index))),
|
||||
DateUtil.getMonth(DateTime.now().add(Duration(days: -index))),
|
||||
style: TextStyle(
|
||||
color: controller.currentIndex.value == index
|
||||
? Colors.white
|
||||
: Colors.black,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: ScreenAdaper.sp(16),
|
||||
fontSize: ScreenAdaper.sp(18),
|
||||
height: 0),
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() => Text(
|
||||
DateUtil.getDate(DateTime.now().add(Duration(days: index))),
|
||||
DateUtil.getDate(DateTime.now().add(Duration(days: -index))),
|
||||
style: TextStyle(
|
||||
color: controller.currentIndex.value == index
|
||||
? Colors.white
|
||||
: Colors.black,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 26,
|
||||
fontSize: ScreenAdaper.sp(30),
|
||||
height: 0),
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() => Text(
|
||||
DateUtil.getDay(DateTime.now().add(Duration(days: index))),
|
||||
DateUtil.getDay(DateTime.now().add(Duration(days: -index))),
|
||||
style: TextStyle(
|
||||
color: controller.currentIndex.value == index
|
||||
? Colors.white
|
||||
: Colors.black,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 13),
|
||||
fontSize: ScreenAdaper.sp(16)),
|
||||
),
|
||||
)
|
||||
],
|
||||
|
|
|
@ -56,6 +56,7 @@ class Grid extends StatelessWidget {
|
|||
)
|
||||
: GridView.builder(
|
||||
padding: const EdgeInsets.only(top: 40),
|
||||
reverse: true,
|
||||
itemCount: controller.list[ind].length,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: crossAsis, childAspectRatio: ratio),
|
||||
|
|
|
@ -9,32 +9,36 @@ class TaskPageBody extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(top: ScreenAdaper.height(25)),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(ScreenAdaper.sp(40)),
|
||||
topLeft: Radius.circular(ScreenAdaper.sp(40))),
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
Colors.white.withOpacity(.6),
|
||||
Colors.white.withOpacity(.5),
|
||||
Colors.white.withOpacity(.4),
|
||||
Colors.white.withOpacity(.3),
|
||||
Colors.white.withOpacity(.2),
|
||||
Colors.white.withOpacity(.0),
|
||||
Colors.white.withOpacity(.0),
|
||||
Colors.white.withOpacity(.0),
|
||||
Colors.white.withOpacity(.0),
|
||||
Colors.white.withOpacity(.0),
|
||||
])),
|
||||
child: TaskPageView(),
|
||||
)),
|
||||
buildBackground(),
|
||||
ChangeButtonRow(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildBackground() {
|
||||
return Positioned.fill(
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(top: ScreenAdaper.height(25)),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(ScreenAdaper.sp(40)),
|
||||
topLeft: Radius.circular(ScreenAdaper.sp(40))),
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
Colors.white.withOpacity(.6),
|
||||
Colors.white.withOpacity(.5),
|
||||
Colors.white.withOpacity(.4),
|
||||
Colors.white.withOpacity(.3),
|
||||
Colors.white.withOpacity(.2),
|
||||
Colors.white.withOpacity(.0),
|
||||
Colors.white.withOpacity(.0),
|
||||
Colors.white.withOpacity(.0),
|
||||
Colors.white.withOpacity(.0),
|
||||
Colors.white.withOpacity(.0),
|
||||
])),
|
||||
child: TaskPageView(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,9 @@ class UperBody extends StatelessWidget {
|
|||
height: ScreenAdaper.height(150),
|
||||
child: ListView.builder(
|
||||
controller: controller.scrollController,
|
||||
itemCount: 7,
|
||||
shrinkWrap: true,
|
||||
reverse: true,
|
||||
itemCount: 20,
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: EdgeInsets.only(
|
||||
bottom: ScreenAdaper.height(20), top: defaultPadding),
|
||||
|
|
|
@ -3,11 +3,10 @@ import 'package:get/get.dart';
|
|||
import 'package:sk_base_mobile/app_theme.dart';
|
||||
import 'package:sk_base_mobile/db_helper/dbHelper.dart';
|
||||
import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout.dart';
|
||||
import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout_controller.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/screen_adaper_util.dart';
|
||||
|
||||
import 'package:sk_base_mobile/apis/api.dart' as Api;
|
||||
import 'components/responsive.dart';
|
||||
|
||||
class InventoryInoutController extends GetxController {
|
||||
|
@ -192,20 +191,12 @@ class InventoryInoutController extends GetxController {
|
|||
Future<void> showInventoryInoutCreateDialog(String inOrOut) async {
|
||||
final isTablet = Responsive.isTablet(Get.context!);
|
||||
isTablet
|
||||
? showGeneralDialog(
|
||||
context: Get.overlayContext!,
|
||||
? Get.generalDialog(
|
||||
barrierLabel: "CreateInventoryInout",
|
||||
barrierDismissible: true,
|
||||
transitionDuration: const Duration(milliseconds: 400),
|
||||
pageBuilder: (_, __, ___) {
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: ScreenAdaper.width(100),
|
||||
vertical: ScreenAdaper.height(60)),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
child: Material(child: NewInventoryInout())),
|
||||
);
|
||||
return NewInventoryInout();
|
||||
},
|
||||
transitionBuilder: (_, anim, __, child) {
|
||||
Tween<Offset> tween;
|
||||
|
@ -217,7 +208,7 @@ class InventoryInoutController extends GetxController {
|
|||
child: child,
|
||||
);
|
||||
},
|
||||
).then((value) => Get.delete<NewInventoryInoutController>())
|
||||
)
|
||||
: showModalBottomSheet(
|
||||
elevation: 0,
|
||||
isScrollControlled: true,
|
||||
|
@ -229,6 +220,14 @@ class InventoryInoutController extends GetxController {
|
|||
);
|
||||
}
|
||||
|
||||
Future<void> getInoutHistory() async {
|
||||
final res = await Api.getInventoryInout({});
|
||||
|
||||
// final List<Map<String, Object?>> queryResult =
|
||||
// await dbClient!.query('Tasks');
|
||||
// return queryResult.map((e) => TaskModel.fromMap(e)).toList();
|
||||
}
|
||||
|
||||
getTasks() async {
|
||||
db.getData().then((value) {
|
||||
model.value = value;
|
||||
|
@ -262,14 +261,14 @@ class InventoryInoutController extends GetxController {
|
|||
}
|
||||
|
||||
onMoveNextPage() {
|
||||
if (currentIndex.value < 7) {
|
||||
setIndex(currentIndex.value + 1);
|
||||
if (currentIndex.value > 0) {
|
||||
setIndex(currentIndex.value - 1);
|
||||
}
|
||||
}
|
||||
|
||||
onMoveBack() {
|
||||
if (currentIndex.value > 0) {
|
||||
setIndex(currentIndex.value - 1);
|
||||
if (currentIndex.value < 20) {
|
||||
setIndex(currentIndex.value + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ class LandingPage extends StatelessWidget {
|
|||
child: Stack(children: [
|
||||
const BackColors(),
|
||||
SafeArea(
|
||||
top: false,
|
||||
child: Obx(() => Scaffold(
|
||||
floatingActionButtonLocation:
|
||||
FloatingActionButtonLocation.centerDocked,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
@ -22,74 +24,32 @@ class NewInventoryInout extends StatelessWidget {
|
|||
|
||||
@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),
|
||||
return SafeArea(
|
||||
top: false, // 设置为false以避免保留顶部状态栏的空间
|
||||
child: Scaffold(
|
||||
appBar: PreferredSize(
|
||||
preferredSize: Size.fromHeight(ScreenAdaper.height(
|
||||
kToolbarHeight)), // 这里使用kToolbarHeight,它是不包含状态栏的AppBar的推荐高度
|
||||
child: AppBar(
|
||||
title: const Text('出入库登记'),
|
||||
),
|
||||
topRight: Radius.circular(ScreenAdaper.sp(30))),
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onTap: () {
|
||||
// 点击空白处时收起键盘
|
||||
// FocusScope.of(Get.context!).unfocus();
|
||||
},
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
buildTitle(),
|
||||
SingleChildScrollView(
|
||||
child: buildForm(),
|
||||
),
|
||||
Spacer(),
|
||||
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(
|
||||
TextEnum.inventoryInOutDialogTitle,
|
||||
style: TextStyle(
|
||||
fontSize: ScreenAdaper.sp(25),
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.close,
|
||||
size: ScreenAdaper.sp(30),
|
||||
))
|
||||
],
|
||||
),
|
||||
);
|
||||
resizeToAvoidBottomInset: true,
|
||||
body: SingleChildScrollView(
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
buildForm(),
|
||||
Obx(() => GradientButton(
|
||||
onPressed: () => {controller.create()},
|
||||
isLoading: controller.loading.value,
|
||||
))
|
||||
],
|
||||
),
|
||||
))));
|
||||
}
|
||||
|
||||
Widget buildForm() {
|
||||
|
@ -114,25 +74,27 @@ class NewInventoryInout extends StatelessWidget {
|
|||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(flex: 1, child: buildQuantity()),
|
||||
SizedBox(
|
||||
width: ScreenAdaper.width(formHorizontalGap),
|
||||
),
|
||||
Expanded(flex: 1, child: buildDatePicker()),
|
||||
SizedBox(
|
||||
width: ScreenAdaper.width(formHorizontalGap),
|
||||
),
|
||||
Expanded(flex: 1, child: buildQuantity()),
|
||||
Expanded(flex: 1, child: buildAgent()),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: ScreenAdaper.height(formVerticalGap),
|
||||
),
|
||||
Row(
|
||||
children: [Expanded(child: buildAgent())],
|
||||
),
|
||||
SizedBox(
|
||||
height: ScreenAdaper.height(formVerticalGap),
|
||||
),
|
||||
Row(
|
||||
children: [Expanded(child: buildRemark())],
|
||||
),
|
||||
SizedBox(
|
||||
height: ScreenAdaper.height(formVerticalGap),
|
||||
),
|
||||
buildImageUploadQueue()
|
||||
];
|
||||
|
||||
final child = Column(
|
||||
|
@ -239,8 +201,120 @@ class NewInventoryInout extends StatelessWidget {
|
|||
return ZtTextInput(
|
||||
textController: controller.remarkTextController,
|
||||
labelText: '备注',
|
||||
isRequired: true,
|
||||
isTextArea: true,
|
||||
);
|
||||
}
|
||||
|
||||
/// 照片上传
|
||||
Widget buildImageUploadQueue() {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: ScreenAdaper.height(20),
|
||||
horizontal: ScreenAdaper.width(20)),
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
'*请拍照上传产品照片',
|
||||
style: TextStyle(
|
||||
fontSize: ScreenAdaper.sp(30),
|
||||
color: AppTheme.secondPrimaryColor),
|
||||
),
|
||||
SizedBox(
|
||||
height: ScreenAdaper.height(10),
|
||||
),
|
||||
Obx(() => SingleChildScrollView(
|
||||
controller: controller.uploadScrollController,
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
...controller.uploadImgFilesPath
|
||||
.map((String path) => builderImagePreview(path))
|
||||
.toList(),
|
||||
buildImageUploader()
|
||||
],
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 照片预览队列Item
|
||||
Widget builderImagePreview(String path) {
|
||||
return Stack(
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: ScreenAdaper.width(5)),
|
||||
width: ScreenAdaper.width(200),
|
||||
height: ScreenAdaper.width(200),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: Border.all(width: 1.0, color: AppTheme.dividerColor),
|
||||
// color: AppTheme.primaryColor,
|
||||
),
|
||||
child: Center(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: FileImage(File(path)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: ScreenAdaper.height(5),
|
||||
right: ScreenAdaper.width(5),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
controller.uploadImgFilesPath.remove(path);
|
||||
},
|
||||
child: Icon(
|
||||
Icons.close,
|
||||
shadows: [
|
||||
Shadow(
|
||||
color: Colors.black,
|
||||
offset: Offset(1, 1),
|
||||
blurRadius: 3,
|
||||
),
|
||||
Shadow(
|
||||
color: Colors.black,
|
||||
offset: Offset(-1, -1),
|
||||
blurRadius: 3,
|
||||
),
|
||||
],
|
||||
size: ScreenAdaper.sp(40),
|
||||
color: AppTheme.nearlyWhite,
|
||||
),
|
||||
))
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
// 上传照片控制器
|
||||
Widget buildImageUploader() {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
controller.photoPicker();
|
||||
},
|
||||
child: Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: ScreenAdaper.width(5)),
|
||||
width: ScreenAdaper.width(200),
|
||||
height: ScreenAdaper.width(200),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: Border.all(width: 1.0, color: AppTheme.dividerColor),
|
||||
// color: AppTheme.primaryColor,
|
||||
),
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.add_a_photo_rounded,
|
||||
size: ScreenAdaper.sp(60),
|
||||
color: AppTheme.primaryColor,
|
||||
))));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:sk_base_mobile/db_helper/dbHelper.dart';
|
||||
import 'package:sk_base_mobile/models/base_response.dart';
|
||||
import 'package:sk_base_mobile/models/product.model.dart';
|
||||
|
@ -10,6 +12,10 @@ import 'package:sk_base_mobile/models/task_model.dart';
|
|||
import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout_controller.dart';
|
||||
import 'package:sk_base_mobile/apis/api.dart' as Api;
|
||||
import 'package:sk_base_mobile/util/date.util.dart';
|
||||
import 'package:sk_base_mobile/util/loading_util.dart';
|
||||
import 'package:sk_base_mobile/util/logger_util.dart';
|
||||
import 'package:sk_base_mobile/util/media_util.dart';
|
||||
import 'package:sk_base_mobile/util/photo_picker_util.dart';
|
||||
import 'package:sk_base_mobile/util/snack_bar.util.dart';
|
||||
|
||||
class NewInventoryInoutController extends GetxController {
|
||||
|
@ -38,6 +44,8 @@ class NewInventoryInoutController extends GetxController {
|
|||
final quantityTextController = TextEditingController();
|
||||
final agentTextController = TextEditingController();
|
||||
final remarkTextController = TextEditingController();
|
||||
final uploadImgFilesPath = <String>[].obs;
|
||||
final uploadScrollController = ScrollController();
|
||||
Map<String, dynamic> payload = {};
|
||||
|
||||
Future<List<ProjectModel>> getProjects({String? keyword}) async {
|
||||
|
@ -60,6 +68,82 @@ class NewInventoryInoutController extends GetxController {
|
|||
return products;
|
||||
}
|
||||
|
||||
@override
|
||||
onReady() {
|
||||
super.onReady();
|
||||
dateTextController.text = DateUtil.format(DateTime.now());
|
||||
}
|
||||
|
||||
/// 创建出入库记录
|
||||
create() {
|
||||
if (payload['projectId'] == null) {
|
||||
SnackBarUtil().info(
|
||||
'项目不能为空',
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (payload['productId'] == null) {
|
||||
SnackBarUtil().info(
|
||||
'产品不能为空',
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (payload['time'] == null) {
|
||||
SnackBarUtil().info(
|
||||
'时间不能为空',
|
||||
);
|
||||
return;
|
||||
}
|
||||
payload['quantity'] = quantityTextController.text;
|
||||
if (payload['quantity'].isEmpty) {
|
||||
SnackBarUtil().info(
|
||||
'数量不能为空',
|
||||
);
|
||||
return;
|
||||
}
|
||||
payload['agent'] = agentTextController.text;
|
||||
if (payload['agent'].isEmpty) {
|
||||
SnackBarUtil().info(
|
||||
'经办人不能为空',
|
||||
);
|
||||
return;
|
||||
}
|
||||
LoggerUtil().info(payload);
|
||||
}
|
||||
|
||||
Future<void> photoPicker() async {
|
||||
XFile? pickedFile = await MediaUtil().getImageFromCamera();
|
||||
if (pickedFile != null) {
|
||||
uploadImgFilesPath.add(pickedFile.path);
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
// 滚动到最右边
|
||||
uploadScrollController.animateTo(
|
||||
uploadScrollController.position.maxScrollExtent,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.easeOut,
|
||||
);
|
||||
});
|
||||
}
|
||||
// await PhotoPickerUtil().showPicker(callback: (XFile pickedFile) async {
|
||||
// await LoadingUtil.to.show(status: '上传中...');
|
||||
// try {
|
||||
// String? filename = await MediaUtil().uploadImg(File(pickedFile.path));
|
||||
// if (filename.isNotEmpty) {
|
||||
// final res = await Api.updateAvatar(filename);
|
||||
// if (res.data != null) {
|
||||
// SnackBarUtil().success('上传成功');
|
||||
// }
|
||||
// }
|
||||
// // uploadImgFilePath(pickedFile.path);
|
||||
// Get.back();
|
||||
// } catch (e) {
|
||||
// SnackBarUtil().error('上传失败,请重试');
|
||||
// } finally {
|
||||
// await LoadingUtil.to.dismiss();
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
picStartTime(BuildContext context) async {
|
||||
var picker =
|
||||
await showTimePicker(context: context, initialTime: TimeOfDay.now());
|
||||
|
|
|
@ -48,25 +48,33 @@ class WorkBenchPage extends StatelessWidget {
|
|||
|
||||
@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);
|
||||
},
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: const SizedBox(),
|
||||
title: const Text(
|
||||
'工作台',
|
||||
),
|
||||
)
|
||||
]));
|
||||
),
|
||||
body: 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) {
|
||||
|
|
|
@ -7,25 +7,25 @@ import 'package:sk_base_mobile/util/media_util.dart';
|
|||
import 'package:sk_base_mobile/app_theme.dart';
|
||||
|
||||
class PhotoPickerUtil {
|
||||
showPicker({Function? callback}) async {
|
||||
showPicker({Function? callback, String title = '请选择上传方式'}) async {
|
||||
return showCupertinoModalPopup(
|
||||
context: Get.context!,
|
||||
builder: (BuildContext ctx) {
|
||||
return CupertinoActionSheet(
|
||||
title: const Text('Change avatar'),
|
||||
title: Text(title),
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
child: const Text(
|
||||
'Cancel',
|
||||
'取消',
|
||||
style: TextStyle(color: Color(0xffcdcdcd)),
|
||||
)),
|
||||
actions: ['Photography', 'Album']
|
||||
actions: ['拍照', '相册']
|
||||
.map((item) => CupertinoActionSheetAction(
|
||||
onPressed: () async {
|
||||
Get.back();
|
||||
XFile? pickedFile = item == 'Photography'
|
||||
XFile? pickedFile = item == '拍照'
|
||||
? await MediaUtil().getImageFromCamera()
|
||||
: await MediaUtil().getImageFromGallery();
|
||||
if (pickedFile != null) {
|
||||
|
|
|
@ -8,10 +8,15 @@ class ZtDatePicker extends StatelessWidget {
|
|||
final TextEditingController textController;
|
||||
final VoidCallback? onClear;
|
||||
final Function? onDateSelected;
|
||||
final bool isRequired;
|
||||
final String labelText;
|
||||
|
||||
const ZtDatePicker({
|
||||
super.key,
|
||||
this.onClear,
|
||||
this.onDateSelected,
|
||||
this.labelText = '日期',
|
||||
this.isRequired = false,
|
||||
required this.textController,
|
||||
});
|
||||
|
||||
|
@ -41,16 +46,19 @@ class ZtDatePicker extends StatelessWidget {
|
|||
)
|
||||
: const SizedBox(),
|
||||
hintText: '请选择',
|
||||
label: const Row(
|
||||
label: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (isRequired)
|
||||
Text(
|
||||
"*",
|
||||
style: TextStyle(
|
||||
color: Colors.red, fontSize: ScreenAdaper.sp(30)),
|
||||
),
|
||||
Text(
|
||||
"*",
|
||||
style: TextStyle(color: Colors.red),
|
||||
),
|
||||
Text(
|
||||
'日期',
|
||||
labelText,
|
||||
style: TextStyle(fontSize: ScreenAdaper.sp(30)),
|
||||
),
|
||||
])),
|
||||
keyboardType: TextInputType.none,
|
||||
|
@ -63,6 +71,7 @@ class ZtDatePicker extends StatelessWidget {
|
|||
cancelText: '取消',
|
||||
firstDate: DateTime(2000, 1, 1),
|
||||
lastDate: DateTime.now().add(const Duration(days: 7)));
|
||||
|
||||
if (onDateSelected != null) {
|
||||
onDateSelected!(picker);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/util/logger_util.dart';
|
||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||
|
||||
class ZtBaseDatePicker extends StatelessWidget {
|
||||
final Function? onDateTimeChanged;
|
||||
final yearController =
|
||||
FixedExtentScrollController(initialItem: DateTime.now().year - 2000);
|
||||
final monthController =
|
||||
FixedExtentScrollController(initialItem: DateTime.now().month - 1);
|
||||
final dayController =
|
||||
FixedExtentScrollController(initialItem: DateTime.now().day - 1);
|
||||
ZtBaseDatePicker({super.key, this.onDateTimeChanged});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: ScreenAdaper.height(250),
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
child: Text(
|
||||
'取消',
|
||||
style: TextStyle(fontSize: ScreenAdaper.sp(25)),
|
||||
)),
|
||||
const Spacer(),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
final year = 2000 + yearController.selectedItem;
|
||||
String month = '${monthController.selectedItem + 1}';
|
||||
if (int.parse(month) < 10) {
|
||||
month = '0$month';
|
||||
}
|
||||
final day = dayController.selectedItem + 1;
|
||||
if (onDateTimeChanged != null) {
|
||||
onDateTimeChanged!('$year-$month-$day');
|
||||
}
|
||||
LoggerUtil().info('$year-$month-$day');
|
||||
},
|
||||
child: Text(
|
||||
'确定',
|
||||
style: TextStyle(fontSize: ScreenAdaper.sp(25)),
|
||||
))
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: CupertinoPicker(
|
||||
scrollController: yearController,
|
||||
itemExtent: ScreenAdaper.height(60),
|
||||
onSelectedItemChanged: (int index) {
|
||||
// 处理用户选择的年份
|
||||
},
|
||||
children: List<Widget>.generate(DateTime.now().year - 1999,
|
||||
(int index) {
|
||||
return Center(child: Text('${2000 + index}年'));
|
||||
}),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: CupertinoPicker(
|
||||
scrollController: monthController,
|
||||
itemExtent: ScreenAdaper.height(60),
|
||||
onSelectedItemChanged: (int index) {
|
||||
// 处理用户选择的月份
|
||||
},
|
||||
children: List<Widget>.generate(12, (int index) {
|
||||
return Center(child: Text('${index + 1}月'));
|
||||
}),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: CupertinoPicker(
|
||||
scrollController: dayController,
|
||||
itemExtent: ScreenAdaper.height(60),
|
||||
onSelectedItemChanged: (int index) {
|
||||
// 处理用户选择的日期
|
||||
},
|
||||
children: List<Widget>.generate(31, (int index) {
|
||||
return Center(child: Text('${index + 1}日'));
|
||||
}),
|
||||
),
|
||||
),
|
||||
],
|
||||
))
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/app_theme.dart';
|
||||
import 'package:sk_base_mobile/constants/bg_color.dart';
|
||||
|
@ -26,20 +27,28 @@ class ZtNumberInput extends StatelessWidget {
|
|||
FocusScope.of(context).unfocus();
|
||||
},
|
||||
onTap: onTap ?? () {},
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(fontSize: ScreenAdaper.sp(30)),
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
FilteringTextInputFormatter.digitsOnly // 限制输入内容只能是数字
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.symmetric(vertical: ScreenAdaper.height(18)),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.always,
|
||||
label: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (isRequired)
|
||||
const Text(
|
||||
Text(
|
||||
"*",
|
||||
style: TextStyle(color: Colors.red),
|
||||
style: TextStyle(
|
||||
color: Colors.red, fontSize: ScreenAdaper.sp(30)),
|
||||
),
|
||||
Text(
|
||||
labelText,
|
||||
style: TextStyle(fontSize: ScreenAdaper.sp(30)),
|
||||
),
|
||||
]),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
|
|
|
@ -67,12 +67,15 @@ class ZtSearchSelect extends StatelessWidget {
|
|||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (isRequired)
|
||||
const Text(
|
||||
Text(
|
||||
"*",
|
||||
style: TextStyle(color: Colors.red),
|
||||
style: TextStyle(
|
||||
color: Colors.red,
|
||||
fontSize: ScreenAdaper.sp(30)),
|
||||
),
|
||||
Text(
|
||||
labelText,
|
||||
style: TextStyle(fontSize: ScreenAdaper.sp(30)),
|
||||
),
|
||||
])));
|
||||
},
|
||||
|
|
|
@ -27,7 +27,7 @@ class ZtTextInput extends StatelessWidget {
|
|||
onTapOutside: (event) {
|
||||
FocusScope.of(context).unfocus();
|
||||
},
|
||||
maxLines: isTextArea ? null : 1, // 添加这行代码
|
||||
maxLines: isTextArea ? 3 : 1, // 添加这行代码
|
||||
onTap: onTap ?? () {},
|
||||
decoration: InputDecoration(
|
||||
floatingLabelBehavior: FloatingLabelBehavior.always,
|
||||
|
@ -36,12 +36,14 @@ class ZtTextInput extends StatelessWidget {
|
|||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (isRequired)
|
||||
const Text(
|
||||
Text(
|
||||
"*",
|
||||
style: TextStyle(color: Colors.red),
|
||||
style: TextStyle(
|
||||
color: Colors.red, fontSize: ScreenAdaper.sp(30)),
|
||||
),
|
||||
Text(
|
||||
labelText,
|
||||
style: TextStyle(fontSize: ScreenAdaper.sp(30)),
|
||||
),
|
||||
]),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
|
|
|
@ -41,7 +41,7 @@ class GradientButton extends StatelessWidget {
|
|||
: Text(
|
||||
buttonText,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
color: AppTheme.nearlyWhite,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: ScreenAdaper.sp(25),
|
||||
),
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
// This is a basic Flutter widget test.
|
||||
//
|
||||
// To perform an interaction with a widget in your test, use the WidgetTester
|
||||
// utility in the flutter_test package. For example, you can send tap and scroll
|
||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
||||
// tree, read text, and verify that the values of widget properties are correct.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:sk_base_mobile/main.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||
// Build our app and trigger a frame.
|
||||
await tester.pumpWidget(const MyApp());
|
||||
|
||||
// Verify that our counter starts at 0.
|
||||
expect(find.text('0'), findsOneWidget);
|
||||
expect(find.text('1'), findsNothing);
|
||||
|
||||
// Tap the '+' icon and trigger a frame.
|
||||
await tester.tap(find.byIcon(Icons.add));
|
||||
await tester.pump();
|
||||
|
||||
// Verify that our counter has incremented.
|
||||
expect(find.text('0'), findsNothing);
|
||||
expect(find.text('1'), findsOneWidget);
|
||||
});
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 917 B |
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
|
@ -0,0 +1,59 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<!--
|
||||
If you are serving your web app in a path other than the root, change the
|
||||
href value below to reflect the base path you are serving from.
|
||||
|
||||
The path provided below has to start and end with a slash "/" in order for
|
||||
it to work correctly.
|
||||
|
||||
For more details:
|
||||
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
|
||||
|
||||
This is a placeholder for base href that will be replaced by the value of
|
||||
the `--base-href` argument provided to `flutter build`.
|
||||
-->
|
||||
<base href="$FLUTTER_BASE_HREF">
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
|
||||
<meta name="description" content="A new Flutter project.">
|
||||
|
||||
<!-- iOS meta tags & icons -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-title" content="sk_base_mobile">
|
||||
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/png" href="favicon.png"/>
|
||||
|
||||
<title>sk_base_mobile</title>
|
||||
<link rel="manifest" href="manifest.json">
|
||||
|
||||
<script>
|
||||
// The value below is injected by flutter build, do not touch.
|
||||
const serviceWorkerVersion = null;
|
||||
</script>
|
||||
<!-- This script adds the flutter initialization JS code -->
|
||||
<script src="flutter.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
window.addEventListener('load', function(ev) {
|
||||
// Download main.dart.js
|
||||
_flutter.loader.loadEntrypoint({
|
||||
serviceWorker: {
|
||||
serviceWorkerVersion: serviceWorkerVersion,
|
||||
},
|
||||
onEntrypointLoaded: function(engineInitializer) {
|
||||
engineInitializer.initializeEngine().then(function(appRunner) {
|
||||
appRunner.runApp();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": "sk_base_mobile",
|
||||
"short_name": "sk_base_mobile",
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"background_color": "#0175C2",
|
||||
"theme_color": "#0175C2",
|
||||
"description": "A new Flutter project.",
|
||||
"orientation": "portrait-primary",
|
||||
"prefer_related_applications": false,
|
||||
"icons": [
|
||||
{
|
||||
"src": "icons/Icon-192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "icons/Icon-512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "icons/Icon-maskable-192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "icons/Icon-maskable-512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue