feat: upgrade apk.
This commit is contained in:
parent
10145b3af7
commit
1befdcb786
|
@ -43,6 +43,7 @@
|
||||||
android:name="android.permission.CAMERA" />
|
android:name="android.permission.CAMERA" />
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
After Width: | Height: | Size: 807 KiB |
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
|
@ -7,7 +7,7 @@ import 'package:sk_base_mobile/services/dio.service.dart';
|
||||||
import '../constants/constants.dart';
|
import '../constants/constants.dart';
|
||||||
|
|
||||||
class Api {
|
class Api {
|
||||||
// 登录
|
/// 登录
|
||||||
static Future<Response> login(String username, String password) {
|
static Future<Response> login(String username, String password) {
|
||||||
return DioService.dio.post(
|
return DioService.dio.post(
|
||||||
Urls.login,
|
Urls.login,
|
||||||
|
@ -15,6 +15,13 @@ class Api {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 查询参数配置信息By key
|
||||||
|
static Future<Response> getSystemParamConfigByCode(String code) {
|
||||||
|
return DioService.dio.get(
|
||||||
|
'${Urls.systemParamConfig}/key/$code',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// 获取个人信息
|
// 获取个人信息
|
||||||
static Future<Response> getUserInfo() {
|
static Future<Response> getUserInfo() {
|
||||||
return DioService.dio.get(
|
return DioService.dio.get(
|
||||||
|
|
|
@ -28,6 +28,7 @@ class AppTheme {
|
||||||
}
|
}
|
||||||
|
|
||||||
final theme = ThemeData(
|
final theme = ThemeData(
|
||||||
|
platform: TargetPlatform.iOS,
|
||||||
primarySwatch: MaterialColor(AppTheme.primaryColor.value, const {
|
primarySwatch: MaterialColor(AppTheme.primaryColor.value, const {
|
||||||
50: AppTheme.primaryColorLight,
|
50: AppTheme.primaryColorLight,
|
||||||
100: AppTheme.primaryColorLight,
|
100: AppTheme.primaryColorLight,
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
// Global config
|
// Global config
|
||||||
class GloablConfig {
|
class GloablConfig {
|
||||||
static const BASE_URL = "http://10.0.2.2:8001/api/";
|
// static const BASE_URL = "http://10.0.2.2:8001/api/";
|
||||||
static const OSS_URL = "http://10.0.2.2:8001";
|
// static const OSS_URL = "http://10.0.2.2:8001";
|
||||||
|
|
||||||
// static const BASE_URL = "http://144.123.43.138:3001/api/";
|
static const BASE_URL = "http://144.123.43.138:3001/api/";
|
||||||
// static const OSS_URL = "http://144.123.43.138:3001";
|
static const OSS_URL = "http://144.123.43.138:3001";
|
||||||
// static const BASE_URL = "http://192.168.60.220:8001/api/";
|
// static const BASE_URL = "http://192.168.60.220:8001/api/";
|
||||||
// static const OSS_URL = "http://192.168.60.220:8001";
|
// static const OSS_URL = "http://192.168.60.220:8001";
|
||||||
static const DOMAIN_NAME = "山矿通";
|
static const DOMAIN_NAME = "山矿通";
|
||||||
|
|
|
@ -6,3 +6,4 @@ export 'global_url.dart';
|
||||||
export 'cache_key.dart';
|
export 'cache_key.dart';
|
||||||
export 'router.dart';
|
export 'router.dart';
|
||||||
export 'text_enum.dart';
|
export 'text_enum.dart';
|
||||||
|
export 'system_param_config.dart';
|
||||||
|
|
|
@ -13,4 +13,6 @@ class Urls {
|
||||||
static String updateAvatar = 'user/updateAvatar';
|
static String updateAvatar = 'user/updateAvatar';
|
||||||
static String getDictType = 'system/dict-type/all';
|
static String getDictType = 'system/dict-type/all';
|
||||||
static String uploadAttachemnt = 'tools/upload';
|
static String uploadAttachemnt = 'tools/upload';
|
||||||
|
static String systemParamConfig = 'system/param-config';
|
||||||
|
static String accountMenus = 'account/menus';
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
class SystemParamConfig {
|
||||||
|
static const String appVersion = "app_version";
|
||||||
|
static const String isForceUpgrade = "is_app_force_upgrade";
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ class InventoryInOutModel {
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
required this.updatedAt,
|
required this.updatedAt,
|
||||||
required this.inventoryNumber,
|
required this.inventoryInOutNumber,
|
||||||
required this.productId,
|
required this.productId,
|
||||||
required this.inOrOut,
|
required this.inOrOut,
|
||||||
required this.time,
|
required this.time,
|
||||||
|
@ -28,7 +28,7 @@ class InventoryInOutModel {
|
||||||
final int? id;
|
final int? id;
|
||||||
final DateTime? createdAt;
|
final DateTime? createdAt;
|
||||||
final DateTime? updatedAt;
|
final DateTime? updatedAt;
|
||||||
final String? inventoryNumber;
|
final String? inventoryInOutNumber;
|
||||||
final int? productId;
|
final int? productId;
|
||||||
final int? inOrOut;
|
final int? inOrOut;
|
||||||
final DateTime? time;
|
final DateTime? time;
|
||||||
|
@ -47,12 +47,12 @@ class InventoryInOutModel {
|
||||||
factory InventoryInOutModel.fromJson(Map<String, dynamic> json) {
|
factory InventoryInOutModel.fromJson(Map<String, dynamic> json) {
|
||||||
return InventoryInOutModel(
|
return InventoryInOutModel(
|
||||||
id: json["id"],
|
id: json["id"],
|
||||||
createdAt: DateTime.tryParse(json["createdAt"] ?? ""),
|
createdAt: DateTime.tryParse(json["createdAt"] ?? "")?.toLocal(),
|
||||||
updatedAt: DateTime.tryParse(json["updatedAt"] ?? ""),
|
updatedAt: DateTime.tryParse(json["updatedAt"] ?? "")?.toLocal(),
|
||||||
inventoryNumber: json["inventoryNumber"],
|
inventoryInOutNumber: json["inventoryInOutNumber"],
|
||||||
productId: json["productId"],
|
productId: json["productId"],
|
||||||
inOrOut: json["inOrOut"],
|
inOrOut: json["inOrOut"],
|
||||||
time: DateTime.tryParse(json["time"] ?? ""),
|
time: DateTime.tryParse(json["time"] ?? "")?.toLocal(),
|
||||||
quantity: json["quantity"],
|
quantity: json["quantity"],
|
||||||
unitPrice: json["unitPrice"],
|
unitPrice: json["unitPrice"],
|
||||||
amount: json["amount"],
|
amount: json["amount"],
|
||||||
|
@ -81,7 +81,7 @@ class InventoryInOutModel {
|
||||||
"id": id,
|
"id": id,
|
||||||
"createdAt": createdAt?.toIso8601String(),
|
"createdAt": createdAt?.toIso8601String(),
|
||||||
"updatedAt": updatedAt?.toIso8601String(),
|
"updatedAt": updatedAt?.toIso8601String(),
|
||||||
"inventoryNumber": inventoryNumber,
|
"inventoryInOutNumber": inventoryInOutNumber,
|
||||||
"productId": productId,
|
"productId": productId,
|
||||||
"inOrOut": inOrOut,
|
"inOrOut": inOrOut,
|
||||||
"time": time,
|
"time": time,
|
||||||
|
|
|
@ -3,12 +3,13 @@ import 'package:sk_base_mobile/screens/new_inventory_inout/components/inventory_
|
||||||
import 'package:sk_base_mobile/widgets/sk_appbar.dart';
|
import 'package:sk_base_mobile/widgets/sk_appbar.dart';
|
||||||
|
|
||||||
class InventoryPage extends StatelessWidget {
|
class InventoryPage extends StatelessWidget {
|
||||||
const InventoryPage({super.key});
|
final bool isPage;
|
||||||
|
const InventoryPage({super.key, this.isPage = false});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: const SkAppbar(title: '库存管理'),
|
appBar: SkAppbar(title: '库存管理', hideLeading: isPage),
|
||||||
body: InventorySearch(),
|
body: InventorySearch(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,11 @@ class InventoryInoutCard extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
controller.list[ind][index].agent ?? '-',
|
'${DateUtil.format(controller.list[ind][index].time!, formats: [
|
||||||
|
'HH',
|
||||||
|
':',
|
||||||
|
"nn"
|
||||||
|
])} ${controller.list[ind][index].agent ?? '-'}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: ScreenAdaper.height(20),
|
fontSize: ScreenAdaper.height(20),
|
||||||
fontWeight: FontWeight.w600),
|
fontWeight: FontWeight.w600),
|
||||||
|
|
|
@ -63,7 +63,19 @@ class InventoryInoutInfo extends StatelessWidget {
|
||||||
buildListItem(
|
buildListItem(
|
||||||
leading: '出入库时间',
|
leading: '出入库时间',
|
||||||
trailing: DateUtil.format(
|
trailing: DateUtil.format(
|
||||||
controller.inventoryInoutInfo.value!.time!)),
|
controller.inventoryInoutInfo.value!.time!,
|
||||||
|
formats: [
|
||||||
|
'yyyy',
|
||||||
|
'-',
|
||||||
|
'mm',
|
||||||
|
'-',
|
||||||
|
'dd',
|
||||||
|
" ",
|
||||||
|
'HH',
|
||||||
|
":",
|
||||||
|
"nn"
|
||||||
|
]),
|
||||||
|
),
|
||||||
customDivider(),
|
customDivider(),
|
||||||
buildListItem(
|
buildListItem(
|
||||||
leading: '所属公司',
|
leading: '所属公司',
|
||||||
|
@ -99,6 +111,16 @@ class InventoryInoutInfo extends StatelessWidget {
|
||||||
trailing:
|
trailing:
|
||||||
controller.inventoryInoutInfo.value?.remark),
|
controller.inventoryInoutInfo.value?.remark),
|
||||||
customDivider(),
|
customDivider(),
|
||||||
|
buildListItem(
|
||||||
|
leading: '出入库单号',
|
||||||
|
trailing: controller
|
||||||
|
.inventoryInoutInfo.value?.inventoryInOutNumber),
|
||||||
|
customDivider(),
|
||||||
|
buildListItem(
|
||||||
|
leading: '库存编号',
|
||||||
|
trailing: controller.inventoryInoutInfo.value
|
||||||
|
?.inventory?.inventoryNumber),
|
||||||
|
customDivider(),
|
||||||
buildListItem(
|
buildListItem(
|
||||||
leading: '照片',
|
leading: '照片',
|
||||||
),
|
),
|
||||||
|
@ -156,14 +178,31 @@ class InventoryInoutInfo extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildListItem({String? leading, dynamic trailing}) {
|
Widget buildListItem({String? leading, dynamic trailing}) {
|
||||||
return ListTile(
|
return Container(
|
||||||
leading: Text(
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: ScreenAdaper.height(20),
|
||||||
|
horizontal: ScreenAdaper.width(20)),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
'${leading ?? ''}: ',
|
'${leading ?? ''}: ',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: ScreenAdaper.height(25), fontWeight: FontWeight.w600),
|
fontSize: ScreenAdaper.height(30), fontWeight: FontWeight.w600),
|
||||||
),
|
),
|
||||||
trailing: Text('${trailing ?? ''}',
|
Spacer(),
|
||||||
style: TextStyle(fontSize: ScreenAdaper.height(25))));
|
Text('${trailing ?? ''}',
|
||||||
|
style: TextStyle(fontSize: ScreenAdaper.height(30)))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
// return ListTile(
|
||||||
|
// leading: Text(
|
||||||
|
// '${leading ?? ''}: ',
|
||||||
|
// style: TextStyle(
|
||||||
|
// fontSize: ScreenAdaper.height(25), fontWeight: FontWeight.w600),
|
||||||
|
// ),
|
||||||
|
// trailing: Text('${trailing ?? ''}',
|
||||||
|
// style: TextStyle(fontSize: ScreenAdaper.height(25))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,9 @@ import 'package:sk_base_mobile/app_theme.dart';
|
||||||
import 'package:sk_base_mobile/constants/enum.dart';
|
import 'package:sk_base_mobile/constants/enum.dart';
|
||||||
import 'package:sk_base_mobile/db_helper/db_help.dart';
|
import 'package:sk_base_mobile/db_helper/db_help.dart';
|
||||||
import 'package:sk_base_mobile/screens/inventory_inout/components/inventory_inout_info.dart';
|
import 'package:sk_base_mobile/screens/inventory_inout/components/inventory_inout_info.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/screens/new_inventory_inout/new_inventory_inout.dart';
|
||||||
|
import 'package:sk_base_mobile/services/app_info.service.dart';
|
||||||
import 'package:sk_base_mobile/util/date.util.dart';
|
import 'package:sk_base_mobile/util/date.util.dart';
|
||||||
import 'package:sk_base_mobile/util/modal.util.dart';
|
import 'package:sk_base_mobile/util/modal.util.dart';
|
||||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
|
@ -236,7 +238,7 @@ class InventoryInoutController extends GetxController {
|
||||||
Future showInventoryInoutInfoDialog(int id) async {
|
Future showInventoryInoutInfoDialog(int id) async {
|
||||||
ModalUtil.showGeneralDialog(
|
ModalUtil.showGeneralDialog(
|
||||||
width: ScreenAdaper.screenShortDistance() - ScreenAdaper.width(100),
|
width: ScreenAdaper.screenShortDistance() - ScreenAdaper.width(100),
|
||||||
height: ScreenAdaper.height(Get.height - 100),
|
height: Get.height - 100 < 400 ? 400 : Get.height - 100,
|
||||||
content: InventoryInoutInfo(inventoryInoutId: id),
|
content: InventoryInoutInfo(inventoryInoutId: id),
|
||||||
offset: const Offset(0, -1))
|
offset: const Offset(0, -1))
|
||||||
.then((value) => {Get.delete<InventoryInouInfoController>()});
|
.then((value) => {Get.delete<InventoryInouInfoController>()});
|
||||||
|
@ -258,6 +260,7 @@ class InventoryInoutController extends GetxController {
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
return [];
|
return [];
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
@ -335,7 +338,7 @@ class InventoryInoutController extends GetxController {
|
||||||
// }
|
// }
|
||||||
// case 2:
|
// case 2:
|
||||||
// {
|
// {
|
||||||
// ModalUtil.confirm(
|
// ModalUtil.alert(
|
||||||
// 'Delete Task', 'Are you want to sure to remove', 'Confirm', () {
|
// 'Delete Task', 'Are you want to sure to remove', 'Confirm', () {
|
||||||
// list[ind].remove(list[ind][index]);
|
// list[ind].remove(list[ind][index]);
|
||||||
// db.delete(
|
// db.delete(
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:sk_base_mobile/apis/index.dart';
|
||||||
import 'package:sk_base_mobile/models/app_bottom_nav_item.dart';
|
import 'package:sk_base_mobile/models/app_bottom_nav_item.dart';
|
||||||
import 'package:sk_base_mobile/screens/inventory/inventory.dart';
|
import 'package:sk_base_mobile/screens/inventory/inventory.dart';
|
||||||
import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout.dart';
|
import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout.dart';
|
||||||
import 'package:sk_base_mobile/screens/mine/mine.dart';
|
import 'package:sk_base_mobile/screens/mine/mine.dart';
|
||||||
import 'package:sk_base_mobile/screens/workbench/workbench.dart';
|
import 'package:sk_base_mobile/screens/workbench/workbench.dart';
|
||||||
|
import 'package:sk_base_mobile/services/app_info.service.dart';
|
||||||
|
import 'package:sk_base_mobile/util/device.util.dart';
|
||||||
|
import 'package:sk_base_mobile/util/modal.util.dart';
|
||||||
|
|
||||||
|
import '../../constants/constants.dart';
|
||||||
|
|
||||||
class LandingController extends GetxController {
|
class LandingController extends GetxController {
|
||||||
RxInt currentIndex = 0.obs;
|
RxInt currentIndex = 0.obs;
|
||||||
|
@ -20,7 +26,7 @@ class LandingController extends GetxController {
|
||||||
icon: Icons.inventory_outlined,
|
icon: Icons.inventory_outlined,
|
||||||
activeIcon: Icons.inventory_rounded,
|
activeIcon: Icons.inventory_rounded,
|
||||||
label: '库存',
|
label: '库存',
|
||||||
page: const InventoryPage()),
|
page: const InventoryPage(isPage: true)),
|
||||||
AppBottomNavItem(
|
AppBottomNavItem(
|
||||||
icon: Icons.widgets_outlined,
|
icon: Icons.widgets_outlined,
|
||||||
activeIcon: Icons.widgets_rounded,
|
activeIcon: Icons.widgets_rounded,
|
||||||
|
@ -36,5 +42,6 @@ class LandingController extends GetxController {
|
||||||
onInit() {
|
onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
pages = bottomNavItems!.map((e) => e.page!).toList();
|
pages = bottomNavItems!.map((e) => e.page!).toList();
|
||||||
|
AppInfoService.to.checkVersion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:sk_base_mobile/apis/index.dart';
|
||||||
|
import 'package:sk_base_mobile/util/device.util.dart';
|
||||||
import 'package:sk_base_mobile/util/snack_bar.util.dart';
|
import 'package:sk_base_mobile/util/snack_bar.util.dart';
|
||||||
|
import '../../constants/constants.dart';
|
||||||
import '../../store/auth.store.dart';
|
import '../../store/auth.store.dart';
|
||||||
// import 'package:sentry/sentry.dart';
|
// import 'package:sentry/sentry.dart';
|
||||||
|
|
||||||
|
|
|
@ -35,11 +35,14 @@ class _MinePageState extends State<MinePage>
|
||||||
Widget _buildBody() {
|
Widget _buildBody() {
|
||||||
return Column(children: [
|
return Column(children: [
|
||||||
Container(
|
Container(
|
||||||
height: ScreenAdaper.height(300),
|
height: ScreenAdaper.height(350),
|
||||||
decoration: const BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
gradient: LinearGradient(
|
||||||
fit: BoxFit.cover,
|
colors: [AppTheme.primaryColorLight, AppTheme.primaryColor])
|
||||||
image: AssetImage('assets/images/yeyazhijia_bg.jpg'))),
|
// image: DecorationImage(
|
||||||
|
// fit: BoxFit.cover,
|
||||||
|
// image: AssetImage('assets/images/yeyazhijia_bg.jpg'))
|
||||||
|
),
|
||||||
// decoration: BoxDecoration(
|
// decoration: BoxDecoration(
|
||||||
// gradient: LinearGradient(
|
// gradient: LinearGradient(
|
||||||
// colors: [AppTheme.primaryColorLight, AppTheme.primaryColor])),
|
// colors: [AppTheme.primaryColorLight, AppTheme.primaryColor])),
|
||||||
|
@ -49,7 +52,7 @@ class _MinePageState extends State<MinePage>
|
||||||
vertical: ScreenAdaper.height(20)),
|
vertical: ScreenAdaper.height(20)),
|
||||||
child: Column(children: [
|
child: Column(children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: ScreenAdaper.height(80),
|
height: ScreenAdaper.height(100),
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
@ -69,7 +72,7 @@ class _MinePageState extends State<MinePage>
|
||||||
AuthStore.to.userInfo.value.nickname ?? '',
|
AuthStore.to.userInfo.value.nickname ?? '',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
letterSpacing: ScreenAdaper.width(5),
|
letterSpacing: ScreenAdaper.width(5),
|
||||||
fontSize: ScreenAdaper.height(30),
|
fontSize: ScreenAdaper.height(35),
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
foreground: Paint()
|
foreground: Paint()
|
||||||
..style = PaintingStyle.stroke
|
..style = PaintingStyle.stroke
|
||||||
|
@ -81,7 +84,7 @@ class _MinePageState extends State<MinePage>
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
letterSpacing: ScreenAdaper.width(5),
|
letterSpacing: ScreenAdaper.width(5),
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: ScreenAdaper.height(30),
|
fontSize: ScreenAdaper.height(35),
|
||||||
fontWeight: FontWeight.bold),
|
fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:sk_base_mobile/app_theme.dart';
|
import 'package:sk_base_mobile/app_theme.dart';
|
||||||
|
import 'package:sk_base_mobile/constants/bg_color.dart';
|
||||||
|
import 'package:sk_base_mobile/services/app_info.service.dart';
|
||||||
import 'package:sk_base_mobile/store/auth.store.dart';
|
import 'package:sk_base_mobile/store/auth.store.dart';
|
||||||
|
import 'package:sk_base_mobile/util/device.util.dart';
|
||||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
|
|
||||||
class MineSettingsPage extends StatelessWidget {
|
class MineSettingsPage extends StatelessWidget {
|
||||||
|
@ -18,7 +21,7 @@ class MineSettingsPage extends StatelessWidget {
|
||||||
border: Border.all(),
|
border: Border.all(),
|
||||||
borderRadius: BorderRadius.circular(15),
|
borderRadius: BorderRadius.circular(15),
|
||||||
color: AppTheme.nearlyWhite),
|
color: AppTheme.nearlyWhite),
|
||||||
width: ScreenAdaper.width(400),
|
width: ScreenAdaper.width(600),
|
||||||
padding:
|
padding:
|
||||||
EdgeInsets.symmetric(vertical: ScreenAdaper.width(10)),
|
EdgeInsets.symmetric(vertical: ScreenAdaper.width(10)),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
|
@ -35,7 +38,44 @@ class MineSettingsPage extends StatelessWidget {
|
||||||
Text(
|
Text(
|
||||||
'退出登录',
|
'退出登录',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: ScreenAdaper.height(20),
|
fontSize: ScreenAdaper.height(30),
|
||||||
|
fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)))),
|
||||||
|
SizedBox(
|
||||||
|
height: ScreenAdaper.height(defaultPadding),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(),
|
||||||
|
borderRadius: BorderRadius.circular(15),
|
||||||
|
color: AppTheme.nearlyWhite),
|
||||||
|
width: ScreenAdaper.width(600),
|
||||||
|
padding:
|
||||||
|
EdgeInsets.symmetric(vertical: ScreenAdaper.width(10)),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () async {
|
||||||
|
await AppInfoService.to.checkVersion();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: ScreenAdaper.width(20),
|
||||||
|
vertical: ScreenAdaper.width(20)),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'v${AppInfoService.to.versionNumber}',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: ScreenAdaper.height(25),
|
||||||
|
fontWeight: FontWeight.w400),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
Text(
|
||||||
|
'检查更新',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: ScreenAdaper.height(30),
|
||||||
fontWeight: FontWeight.w600),
|
fontWeight: FontWeight.w600),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -84,10 +84,10 @@ class NewInventoryInout extends StatelessWidget {
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: ScreenAdaper.height(formVerticalGap),
|
height: ScreenAdaper.height(formVerticalGap),
|
||||||
),
|
),
|
||||||
buildDatePicker(),
|
// buildDatePicker(),
|
||||||
SizedBox(
|
// SizedBox(
|
||||||
height: ScreenAdaper.height(formVerticalGap),
|
// height: ScreenAdaper.height(formVerticalGap),
|
||||||
),
|
// ),
|
||||||
buildAgent(),
|
buildAgent(),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: ScreenAdaper.height(formVerticalGap),
|
height: ScreenAdaper.height(formVerticalGap),
|
||||||
|
|
|
@ -128,13 +128,29 @@ class NewInventoryInoutController extends GetxController {
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (payload['time'] == null) {
|
// 暂时时间定位提交时间
|
||||||
SnackBarUtil().error(
|
// if (payload['time'] == null) {
|
||||||
'时间不能为空',
|
// SnackBarUtil().error(
|
||||||
);
|
// '时间不能为空',
|
||||||
return;
|
// );
|
||||||
}
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
payload['time'] = DateUtil.format(DateTime.now(), formats: [
|
||||||
|
'yyyy',
|
||||||
|
'-',
|
||||||
|
'mm',
|
||||||
|
'-',
|
||||||
|
'dd',
|
||||||
|
' ',
|
||||||
|
'HH',
|
||||||
|
':',
|
||||||
|
'nn',
|
||||||
|
":",
|
||||||
|
'ss'
|
||||||
|
]);
|
||||||
payload['quantity'] = quantityTextController.text;
|
payload['quantity'] = quantityTextController.text;
|
||||||
|
|
||||||
if (payload['quantity'].isEmpty || payload['quantity'] == '0') {
|
if (payload['quantity'].isEmpty || payload['quantity'] == '0') {
|
||||||
SnackBarUtil().error(
|
SnackBarUtil().error(
|
||||||
'数量必须大于1',
|
'数量必须大于1',
|
||||||
|
|
|
@ -8,9 +8,7 @@ import 'package:sk_base_mobile/models/base_search_more_controller.dart';
|
||||||
import 'package:sk_base_mobile/models/sale_quotation.model.dart';
|
import 'package:sk_base_mobile/models/sale_quotation.model.dart';
|
||||||
import 'package:sk_base_mobile/screens/sale_quotation/components/sale_quotation_group_search.dart';
|
import 'package:sk_base_mobile/screens/sale_quotation/components/sale_quotation_group_search.dart';
|
||||||
import 'package:sk_base_mobile/services/storage.service.dart';
|
import 'package:sk_base_mobile/services/storage.service.dart';
|
||||||
import 'package:sk_base_mobile/util/snack_bar.util.dart';
|
|
||||||
import 'package:sk_base_mobile/widgets/core/sk_muti_search_more.dart';
|
import 'package:sk_base_mobile/widgets/core/sk_muti_search_more.dart';
|
||||||
import 'package:sk_base_mobile/widgets/core/sk_single_search_more.dart';
|
|
||||||
import 'package:sk_base_mobile/util/modal.util.dart';
|
import 'package:sk_base_mobile/util/modal.util.dart';
|
||||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
import 'package:pinyin/pinyin.dart';
|
import 'package:pinyin/pinyin.dart';
|
||||||
|
@ -20,19 +18,25 @@ class SaleQuotationController extends GetxController {
|
||||||
final RxList editingcell = RxList([null, null, null]);
|
final RxList editingcell = RxList([null, null, null]);
|
||||||
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
RxList<SaleQuotationItemModel> products = RxList([
|
RxList<SaleQuotationItemModel> products = RxList([
|
||||||
SaleQuotationItemModel(name: '矿用本安型支架控制器', unit: '台', spec: 'ZDYZ-Z'),
|
SaleQuotationItemModel(
|
||||||
SaleQuotationItemModel(name: '矿用本安型电磁阀驱动器'),
|
name: '矿用本安型支架控制器', unit: '台', spec: 'ZDYZ-Z', cost: 4700),
|
||||||
SaleQuotationItemModel(name: '矿用隔爆兼本安型电源'),
|
SaleQuotationItemModel(name: '矿用本安型电磁阀驱动器', cost: 1200),
|
||||||
SaleQuotationItemModel(name: '矿用本安型隔离耦合器'),
|
SaleQuotationItemModel(name: '矿用隔爆兼本安型电源', cost: 5700),
|
||||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器'),
|
SaleQuotationItemModel(name: '矿用本安型隔离耦合器', cost: 1200),
|
||||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-控制器'),
|
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', cost: 600),
|
||||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-驱动器'),
|
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-控制器', cost: 400),
|
||||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-隔离耦合器'),
|
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-驱动器', cost: 500),
|
||||||
SaleQuotationItemModel(name: '矿用本安型支架无线遥控器'),
|
SaleQuotationItemModel(
|
||||||
SaleQuotationItemModel(name: '矿用隔爆兼本安型电源'),
|
name: '钢丝编织橡胶护套连接器', remark: '控制器-隔离耦合器', cost: 2000),
|
||||||
SaleQuotationItemModel(name: '电液换向阀(10功能10接口)', remark: '中间过渡架主阀组'),
|
SaleQuotationItemModel(name: '矿用本安型支架控制器', cost: 4700),
|
||||||
SaleQuotationItemModel(name: '电液换向阀(20功能20接口)', remark: '端头架主阀组'),
|
SaleQuotationItemModel(name: '矿用本安型电磁阀驱动器', cost: 1200),
|
||||||
SaleQuotationItemModel(name: '自动反冲洗过滤装置', remark: '流量:900L/min,过滤精度25μm'),
|
SaleQuotationItemModel(name: '矿用隔爆兼本安型电源', cost: 5700),
|
||||||
|
SaleQuotationItemModel(
|
||||||
|
name: '电液换向阀(10功能10接口)', remark: '中间过渡架主阀组', cost: 13200),
|
||||||
|
SaleQuotationItemModel(
|
||||||
|
name: '电液换向阀(20功能20接口)', remark: '端头架主阀组', cost: 26500),
|
||||||
|
SaleQuotationItemModel(
|
||||||
|
name: '自动反冲洗过滤装置', remark: '流量:900L/min,过滤精度25μm', cost: 2000),
|
||||||
SaleQuotationItemModel(name: '全自动反冲洗过滤器电缆', remark: '控制器-自动反冲洗'),
|
SaleQuotationItemModel(name: '全自动反冲洗过滤器电缆', remark: '控制器-自动反冲洗'),
|
||||||
SaleQuotationItemModel(name: '矿用本安型位移传感器'),
|
SaleQuotationItemModel(name: '矿用本安型位移传感器'),
|
||||||
SaleQuotationItemModel(name: '矿用本安型压力传感器'),
|
SaleQuotationItemModel(name: '矿用本安型压力传感器'),
|
||||||
|
@ -190,15 +194,51 @@ class SaleQuotationController extends GetxController {
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
horizontal: ScreenAdaper.width(5),
|
horizontal: ScreenAdaper.width(5),
|
||||||
vertical: ScreenAdaper.height(10)),
|
vertical: ScreenAdaper.height(10)),
|
||||||
child: Row(
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
controller.list[index].name,
|
controller.list[index].name,
|
||||||
style: TextStyle(fontSize: ScreenAdaper.height(25)),
|
style: TextStyle(
|
||||||
|
fontSize: ScreenAdaper.height(30)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
if (controller.list[index].spec != null)
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'型号:${controller.list[index].spec ?? ''}',
|
||||||
|
textAlign: TextAlign.start,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: ScreenAdaper.height(25)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'单价:¥${controller.list[index].cost}',
|
||||||
|
textAlign: TextAlign.start,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: ScreenAdaper.height(25)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (controller.list[index].remark != null)
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'备注:${controller.list[index].remark ?? ''}',
|
||||||
|
textAlign: TextAlign.start,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: ScreenAdaper.height(25)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
width: Get.width - ScreenAdaper.width(50))
|
width: Get.width - ScreenAdaper.width(50))
|
||||||
|
@ -239,19 +279,25 @@ class ItemSearchMoreController extends GetxController
|
||||||
@override
|
@override
|
||||||
Future<List<SaleQuotationItemModel>> getData({bool isRefresh = false}) async {
|
Future<List<SaleQuotationItemModel>> getData({bool isRefresh = false}) async {
|
||||||
List<SaleQuotationItemModel> newList = [
|
List<SaleQuotationItemModel> newList = [
|
||||||
SaleQuotationItemModel(name: '矿用本安型支架控制器', unit: '台', spec: 'ZDYZ-Z'),
|
SaleQuotationItemModel(
|
||||||
SaleQuotationItemModel(name: '矿用本安型电磁阀驱动器'),
|
name: '矿用本安型支架控制器', unit: '台', spec: 'ZDYZ-Z', cost: 4700),
|
||||||
SaleQuotationItemModel(name: '矿用隔爆兼本安型电源'),
|
SaleQuotationItemModel(name: '矿用本安型电磁阀驱动器', cost: 1200),
|
||||||
SaleQuotationItemModel(name: '矿用本安型隔离耦合器'),
|
SaleQuotationItemModel(name: '矿用隔爆兼本安型电源', cost: 5700),
|
||||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器'),
|
SaleQuotationItemModel(name: '矿用本安型隔离耦合器', cost: 1200),
|
||||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-控制器'),
|
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', cost: 600),
|
||||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-驱动器'),
|
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-控制器', cost: 400),
|
||||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-隔离耦合器'),
|
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-驱动器', cost: 500),
|
||||||
SaleQuotationItemModel(name: '矿用本安型支架无线遥控器'),
|
SaleQuotationItemModel(
|
||||||
SaleQuotationItemModel(name: '矿用隔爆兼本安型电源'),
|
name: '钢丝编织橡胶护套连接器', remark: '控制器-隔离耦合器', cost: 2000),
|
||||||
SaleQuotationItemModel(name: '电液换向阀(10功能10接口)', remark: '中间过渡架主阀组'),
|
SaleQuotationItemModel(name: '矿用本安型支架控制器', cost: 4700),
|
||||||
SaleQuotationItemModel(name: '电液换向阀(20功能20接口)', remark: '端头架主阀组'),
|
SaleQuotationItemModel(name: '矿用本安型电磁阀驱动器', cost: 1200),
|
||||||
SaleQuotationItemModel(name: '自动反冲洗过滤装置', remark: '流量:900L/min,过滤精度25μm'),
|
SaleQuotationItemModel(name: '矿用隔爆兼本安型电源', cost: 5700),
|
||||||
|
SaleQuotationItemModel(
|
||||||
|
name: '电液换向阀(10功能10接口)', remark: '中间过渡架主阀组', cost: 13200),
|
||||||
|
SaleQuotationItemModel(
|
||||||
|
name: '电液换向阀(20功能20接口)', remark: '端头架主阀组', cost: 26500),
|
||||||
|
SaleQuotationItemModel(
|
||||||
|
name: '自动反冲洗过滤装置', remark: '流量:900L/min,过滤精度25μm', cost: 2000),
|
||||||
SaleQuotationItemModel(name: '全自动反冲洗过滤器电缆', remark: '控制器-自动反冲洗'),
|
SaleQuotationItemModel(name: '全自动反冲洗过滤器电缆', remark: '控制器-自动反冲洗'),
|
||||||
SaleQuotationItemModel(name: '矿用本安型位移传感器'),
|
SaleQuotationItemModel(name: '矿用本安型位移传感器'),
|
||||||
SaleQuotationItemModel(name: '矿用本安型压力传感器'),
|
SaleQuotationItemModel(name: '矿用本安型压力传感器'),
|
||||||
|
|
|
@ -35,7 +35,7 @@ class SaleQuotationPage extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
key: controller.scaffoldKey,
|
key: controller.scaffoldKey,
|
||||||
endDrawer: Drawer(
|
endDrawer: const Drawer(
|
||||||
// 从右到左出现
|
// 从右到左出现
|
||||||
child: SaleQuotationEndDrawer(),
|
child: SaleQuotationEndDrawer(),
|
||||||
),
|
),
|
||||||
|
@ -47,7 +47,23 @@ class SaleQuotationPage extends StatelessWidget {
|
||||||
controller.scaffoldKey.currentState?.openEndDrawer();
|
controller.scaffoldKey.currentState?.openEndDrawer();
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.more_horiz_outlined, color: AppTheme.white),
|
icon: const Icon(Icons.more_horiz_outlined, color: AppTheme.white),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: ScreenAdaper.height(10),
|
||||||
|
horizontal: ScreenAdaper.width(20)),
|
||||||
|
child: Row(mainAxisAlignment: MainAxisAlignment.end, children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
controller.addGroup();
|
||||||
|
},
|
||||||
|
child: Icon(
|
||||||
|
Icons.add,
|
||||||
|
size: ScreenAdaper.height(40),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
]),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
|
@ -65,6 +81,8 @@ class SaleQuotationPage extends StatelessWidget {
|
||||||
(index, e) => buildBody(index))
|
(index, e) => buildBody(index))
|
||||||
.toList(),
|
.toList(),
|
||||||
))),
|
))),
|
||||||
|
// 当键盘弹起时,不显示
|
||||||
|
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: ScreenAdaper.height(100),
|
height: ScreenAdaper.height(100),
|
||||||
child: buildTotalCostRow(),
|
child: buildTotalCostRow(),
|
||||||
|
@ -76,7 +94,7 @@ class SaleQuotationPage extends StatelessWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
// Positioned(
|
// Positioned(
|
||||||
// bottom: ScreenAdaper.height(10),
|
// bottom: ScreenAdaper.height(220),
|
||||||
// right: ScreenAdaper.height(10),
|
// right: ScreenAdaper.height(10),
|
||||||
// child: IconButton(
|
// child: IconButton(
|
||||||
// padding: EdgeInsets.all(ScreenAdaper.height(20)),
|
// padding: EdgeInsets.all(ScreenAdaper.height(20)),
|
||||||
|
@ -339,8 +357,8 @@ class SaleQuotationPage extends StatelessWidget {
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
ModalUtil.confirm(
|
ModalUtil.alert(
|
||||||
title: '确定要删除此组吗?',
|
contentText: '确定要删除此组吗?',
|
||||||
onConfirm: () {
|
onConfirm: () {
|
||||||
controller.removeGroup(groupIndex);
|
controller.removeGroup(groupIndex);
|
||||||
});
|
});
|
||||||
|
@ -464,7 +482,7 @@ class SaleQuotationPage extends StatelessWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
VerticalDivider(),
|
const VerticalDivider(),
|
||||||
buildEditCell<int>(
|
buildEditCell<int>(
|
||||||
Container(
|
Container(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
|
|
|
@ -7,6 +7,7 @@ import 'package:sk_base_mobile/constants/router.dart';
|
||||||
import 'package:sk_base_mobile/screens/workbench/workbench_controller.dart';
|
import 'package:sk_base_mobile/screens/workbench/workbench_controller.dart';
|
||||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
import 'package:sk_base_mobile/util/snack_bar.util.dart';
|
import 'package:sk_base_mobile/util/snack_bar.util.dart';
|
||||||
|
import 'package:sk_base_mobile/widgets/sk_appbar.dart';
|
||||||
|
|
||||||
class WorkBenchPage extends StatelessWidget {
|
class WorkBenchPage extends StatelessWidget {
|
||||||
WorkBenchPage({super.key});
|
WorkBenchPage({super.key});
|
||||||
|
@ -15,31 +16,8 @@ class WorkBenchPage extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: const SkAppbar(title: '工作台', hideLeading: true),
|
||||||
leading: const SizedBox(),
|
body: buildList());
|
||||||
title: const Text(
|
|
||||||
'工作台',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: buildList()
|
|
||||||
// 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 buildList() {
|
Widget buildList() {
|
||||||
|
|
|
@ -3,7 +3,6 @@ import 'package:get/get.dart';
|
||||||
import 'package:sk_base_mobile/models/workbench.model.dart';
|
import 'package:sk_base_mobile/models/workbench.model.dart';
|
||||||
|
|
||||||
class WorkBenchController extends GetxController {
|
class WorkBenchController extends GetxController {
|
||||||
late final AnimationController animationController;
|
|
||||||
final List<WorkBenchModel> menus = [
|
final List<WorkBenchModel> menus = [
|
||||||
WorkBenchModel(title: '库存', route: '/inventory', icon: 'inventory.svg'),
|
WorkBenchModel(title: '库存', route: '/inventory', icon: 'inventory.svg'),
|
||||||
WorkBenchModel(title: '产品', route: '/product', icon: 'product.svg'),
|
WorkBenchModel(title: '产品', route: '/product', icon: 'product.svg'),
|
||||||
|
@ -15,9 +14,4 @@ class WorkBenchController extends GetxController {
|
||||||
WorkBenchModel(
|
WorkBenchModel(
|
||||||
title: '报价计算', route: '/sale_quotation', icon: 'sale_quotation.svg'),
|
title: '报价计算', route: '/sale_quotation', icon: 'sale_quotation.svg'),
|
||||||
];
|
];
|
||||||
@override
|
|
||||||
void onClose() {
|
|
||||||
animationController.dispose();
|
|
||||||
super.onClose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,26 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:decimal/decimal.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:install_plugin/install_plugin.dart';
|
||||||
import 'package:package_info/package_info.dart';
|
import 'package:package_info/package_info.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
import 'package:sk_base_mobile/apis/index.dart';
|
||||||
|
import 'package:sk_base_mobile/app_theme.dart';
|
||||||
|
import 'package:sk_base_mobile/config.dart';
|
||||||
import 'package:sk_base_mobile/models/app_config.dart';
|
import 'package:sk_base_mobile/models/app_config.dart';
|
||||||
import 'package:sk_base_mobile/services/service.dart';
|
import 'package:sk_base_mobile/services/service.dart';
|
||||||
|
import 'package:sk_base_mobile/util/device.util.dart';
|
||||||
import 'package:sk_base_mobile/util/logger_util.dart';
|
import 'package:sk_base_mobile/util/logger_util.dart';
|
||||||
|
import 'package:sk_base_mobile/util/modal.util.dart';
|
||||||
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
|
import 'package:sk_base_mobile/util/snack_bar.util.dart';
|
||||||
|
import 'package:sk_base_mobile/widgets/upgrade_confirm.dart';
|
||||||
import '../constants/constants.dart';
|
import '../constants/constants.dart';
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
|
||||||
class AppInfoService extends GetxService {
|
class AppInfoService extends GetxService {
|
||||||
static AppInfoService get to => Get.find();
|
static AppInfoService get to => Get.find();
|
||||||
|
@ -12,14 +29,16 @@ class AppInfoService extends GetxService {
|
||||||
final scale = RxDouble(1.0);
|
final scale = RxDouble(1.0);
|
||||||
final isLarge = RxBool(false);
|
final isLarge = RxBool(false);
|
||||||
final isCameraing = RxBool(false);
|
final isCameraing = RxBool(false);
|
||||||
|
final downloadProgress = RxDouble(0.0);
|
||||||
Future<AppInfoService> init() async {
|
Future<AppInfoService> init() async {
|
||||||
LoggerUtil()
|
LoggerUtil()
|
||||||
.info("[service-appInfo] Register app-related information service");
|
.info("[service-appInfo] Register app-related information service");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// await Future.wait(
|
await Future.wait([
|
||||||
// [getDeviceInfo(), getPackageInfo(), getAppConfig(), getossPolicy()]);
|
getDeviceInfo(),
|
||||||
|
getPackageInfo() /* , getAppConfig(), getossPolicy() */
|
||||||
|
]);
|
||||||
requestPermission();
|
requestPermission();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
LoggerUtil().error(e);
|
LoggerUtil().error(e);
|
||||||
|
@ -93,6 +112,125 @@ class AppInfoService extends GetxService {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
Future<void> checkVersion() async {
|
||||||
|
final res = await Future.wait([
|
||||||
|
Api.getSystemParamConfigByCode(SystemParamConfig.appVersion),
|
||||||
|
Api.getSystemParamConfigByCode(SystemParamConfig.isForceUpgrade)
|
||||||
|
]);
|
||||||
|
final newVersion = res[0].data;
|
||||||
|
final isForceUpgrade = res[1].data;
|
||||||
|
if (newVersion != null) {
|
||||||
|
final currentVersion = await DeviceUtil.getAppVersion();
|
||||||
|
if (newVersion != currentVersion) {
|
||||||
|
ModalUtil.alert(
|
||||||
|
// title: '有新版本',
|
||||||
|
builder: (_) => UpgradeConfirm(
|
||||||
|
onConfirm: () {
|
||||||
|
upgradeApp(newVersion);
|
||||||
|
},
|
||||||
|
forceUpgrade: isForceUpgrade == '1',
|
||||||
|
),
|
||||||
|
// contentText: isForceUpgrade == '1' ? '此版本非常重要,强制更新' : '请更新',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> upgradeApp(String version) async {
|
||||||
|
if (await checkPermission()) {
|
||||||
|
/// 下载安卓更新包
|
||||||
|
String url = '${GloablConfig.OSS_URL}/upload/shankuangtong_v$version.apk';
|
||||||
|
|
||||||
|
/// 创建存储文件
|
||||||
|
Directory? storageDir = await getExternalStorageDirectory();
|
||||||
|
if (storageDir != null) {
|
||||||
|
String storagePath = storageDir.path;
|
||||||
|
File file = File('$storagePath/shankuangtong_v${version}.apk');
|
||||||
|
|
||||||
|
if (!file.existsSync()) {
|
||||||
|
file.createSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
/// 下载
|
||||||
|
downloadProgress.value = 0;
|
||||||
|
Get.back();
|
||||||
|
|
||||||
|
ModalUtil.alert(
|
||||||
|
barrierDismissible: false,
|
||||||
|
contentPadding: EdgeInsets.symmetric(vertical: 0),
|
||||||
|
showActions: false,
|
||||||
|
content:
|
||||||
|
// 进度条
|
||||||
|
Obx(
|
||||||
|
() => Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: ScreenAdaper.height(40),
|
||||||
|
child: LinearProgressIndicator(
|
||||||
|
value: downloadProgress.value,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: Text(
|
||||||
|
'${downloadProgress.value * 100}%',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(fontSize: ScreenAdaper.height(30)),
|
||||||
|
))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
await DioService.dio.download(url, file.path,
|
||||||
|
onReceiveProgress: (num received, num total) =>
|
||||||
|
onReceiveProgress(received, total),
|
||||||
|
options: Options(
|
||||||
|
responseType: ResponseType.bytes,
|
||||||
|
followRedirects: false,
|
||||||
|
));
|
||||||
|
Get.back();
|
||||||
|
InstallPlugin.install(
|
||||||
|
file.path,
|
||||||
|
).then((result) {}).catchError((error) {});
|
||||||
|
} catch (e) {
|
||||||
|
SnackBarUtil().warning('暂时无法更新,请重新下载安装, 或者请联系管理员');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 展示下载进度
|
||||||
|
void onReceiveProgress(num received, num total) {
|
||||||
|
if (total != -1) {
|
||||||
|
downloadProgress.value =
|
||||||
|
Decimal.parse((received / total).toStringAsFixed(2))
|
||||||
|
.toDouble()
|
||||||
|
.toPrecision(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 检查是否有权限,用于安卓
|
||||||
|
Future<bool> checkPermission() async {
|
||||||
|
if (await DeviceUtil.getPlatForm() == 'android') {
|
||||||
|
// 检查是否有storage权限,没有的话请求权限
|
||||||
|
if (await Permission.storage.request().isGranted) {
|
||||||
|
return true;
|
||||||
|
// PermissionStatus permission = await PermissionHandler()
|
||||||
|
// .checkPermissionStatus(PermissionGroup.storage);
|
||||||
|
// if (permission != PermissionStatus.granted) {
|
||||||
|
// Map<PermissionGroup, PermissionStatus> permissions =
|
||||||
|
// await PermissionHandler()
|
||||||
|
// .requestPermissions([PermissionGroup.storage]);
|
||||||
|
// if (permissions[PermissionGroup.storage] == PermissionStatus.granted) {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
T getConfigByCode<T>(String code) {
|
T getConfigByCode<T>(String code) {
|
||||||
List<AppConfigItem> items = appConfig.items!;
|
List<AppConfigItem> items = appConfig.items!;
|
||||||
|
|
|
@ -64,7 +64,9 @@ class DioService extends get_package.GetxService {
|
||||||
} else if (e.response?.statusCode == 401) {
|
} else if (e.response?.statusCode == 401) {
|
||||||
// dio.lock();
|
// dio.lock();
|
||||||
LoggerUtil().error('[Service-dio] logout:${e.response}');
|
LoggerUtil().error('[Service-dio] logout:${e.response}');
|
||||||
await AuthStore().logout(force: true);
|
Future.delayed(Duration(seconds: 1), () {
|
||||||
|
AuthStore().logout(force: true);
|
||||||
|
});
|
||||||
SnackBarUtil().error('请重新登录');
|
SnackBarUtil().error('请重新登录');
|
||||||
} else if (e.response?.statusCode == 403) {
|
} else if (e.response?.statusCode == 403) {
|
||||||
await SnackBarUtil().error(
|
await SnackBarUtil().error(
|
||||||
|
@ -126,6 +128,7 @@ class DioService extends get_package.GetxService {
|
||||||
|
|
||||||
void onResponse(Response response, ResponseInterceptorHandler handler) async {
|
void onResponse(Response response, ResponseInterceptorHandler handler) async {
|
||||||
/* LoggerUtil().info('[Service-dio] ${response.data}'); */
|
/* LoggerUtil().info('[Service-dio] ${response.data}'); */
|
||||||
|
|
||||||
if (whiteList.contains(response.requestOptions.path)) {
|
if (whiteList.contains(response.requestOptions.path)) {
|
||||||
handler.next(response);
|
handler.next(response);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:dio/dio.dart' as dio_package;
|
import 'package:dio/dio.dart' as dio_package;
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:sk_base_mobile/apis/index.dart';
|
import 'package:sk_base_mobile/apis/index.dart';
|
||||||
import 'package:sk_base_mobile/store/dict.store.dart';
|
import 'package:sk_base_mobile/store/dict.store.dart';
|
||||||
|
@ -57,9 +58,11 @@ class AuthStore extends GetxService {
|
||||||
await StorageService.to.remove(CacheKeys.userInfo, isWithUser: false);
|
await StorageService.to.remove(CacheKeys.userInfo, isWithUser: false);
|
||||||
LoggerUtil().info('[Store-Auth] Logout succeed.');
|
LoggerUtil().info('[Store-Auth] Logout succeed.');
|
||||||
// 如果当前已经在login界面 不需要跳转
|
// 如果当前已经在login界面 不需要跳转
|
||||||
|
// 判断是否Get已经注册
|
||||||
if (Get.currentRoute != RouteConfig.login) {
|
if (Get.currentRoute != RouteConfig.login) {
|
||||||
Get.offAllNamed(RouteConfig.login);
|
Get.offAllNamed(RouteConfig.login);
|
||||||
}
|
}
|
||||||
|
// 不用getx跳转登录页
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> login(
|
Future<void> login(
|
||||||
|
@ -72,7 +75,7 @@ class AuthStore extends GetxService {
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
LoadingUtil.to.show();
|
await LoadingUtil.to.show();
|
||||||
TapToDismissKeyboard.dismissOf(context: Get.context!);
|
TapToDismissKeyboard.dismissOf(context: Get.context!);
|
||||||
try {
|
try {
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
|
@ -89,7 +92,7 @@ class AuthStore extends GetxService {
|
||||||
Get.offNamed(RouteConfig.home);
|
Get.offNamed(RouteConfig.home);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await SnackBarUtil().error('账号密码错误$e');
|
await SnackBarUtil().error('账号密码错误');
|
||||||
LoggerUtil().error(e);
|
LoggerUtil().error(e);
|
||||||
} finally {
|
} finally {
|
||||||
LoadingUtil.to.dismiss();
|
LoadingUtil.to.dismiss();
|
||||||
|
|
|
@ -3,7 +3,7 @@ import 'package:date_format/date_format.dart';
|
||||||
class DateUtil {
|
class DateUtil {
|
||||||
/// 格式化日期 默认 YYYY-MM-DD
|
/// 格式化日期 默认 YYYY-MM-DD
|
||||||
static String format(DateTime date, {List<String>? formats}) {
|
static String format(DateTime date, {List<String>? formats}) {
|
||||||
return formatDate(date, formats ?? ['yyyy', '-', 'mm', '-', 'dd']);
|
return formatDate(date, formats ?? ['yyyy', '-', 'MM', '-', 'dd']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 获取几月
|
/// 获取几月
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:package_info/package_info.dart';
|
||||||
|
|
||||||
|
class DeviceUtil {
|
||||||
|
/// 获取当前版本
|
||||||
|
static Future<String> getAppVersion() async {
|
||||||
|
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||||||
|
return packageInfo.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 获取平台信息
|
||||||
|
static Future<String> getPlatForm() async {
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
return 'android';
|
||||||
|
} else {
|
||||||
|
return 'ios';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,12 +6,23 @@ import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
import 'package:sk_base_mobile/widgets/core/sk_bottomsheet_picker.dart';
|
import 'package:sk_base_mobile/widgets/core/sk_bottomsheet_picker.dart';
|
||||||
|
|
||||||
class ModalUtil {
|
class ModalUtil {
|
||||||
static Future<bool> confirm(
|
static Future<bool> alert(
|
||||||
{String? title, String? button, VoidCallback? onConfirm}) async {
|
{String? title,
|
||||||
|
String? contentText,
|
||||||
|
String? confirmText,
|
||||||
|
Widget? content,
|
||||||
|
VoidCallback? onConfirm,
|
||||||
|
Widget Function(BuildContext)? builder,
|
||||||
|
EdgeInsetsGeometry? contentPadding,
|
||||||
|
bool showActions = true,
|
||||||
|
bool barrierDismissible = true,
|
||||||
|
bool showCancel = true}) async {
|
||||||
bool confirmed = false;
|
bool confirmed = false;
|
||||||
await showDialog(
|
await showDialog(
|
||||||
context: Get.overlayContext!,
|
context: Get.overlayContext!,
|
||||||
builder: (context) {
|
barrierDismissible: barrierDismissible,
|
||||||
|
builder: builder ??
|
||||||
|
(context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
backgroundColor: AppTheme.nearlyWhite,
|
backgroundColor: AppTheme.nearlyWhite,
|
||||||
|
@ -20,17 +31,19 @@ class ModalUtil {
|
||||||
),
|
),
|
||||||
actionsPadding: EdgeInsets.zero,
|
actionsPadding: EdgeInsets.zero,
|
||||||
titlePadding: EdgeInsets.zero,
|
titlePadding: EdgeInsets.zero,
|
||||||
|
contentPadding: contentPadding ??
|
||||||
|
EdgeInsets.symmetric(
|
||||||
|
vertical: ScreenAdaper.height(10),
|
||||||
|
),
|
||||||
title: title != null
|
title: title != null
|
||||||
? Container(
|
? Container(
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
vertical: ScreenAdaper.height(30),
|
vertical: ScreenAdaper.height(20),
|
||||||
horizontal: ScreenAdaper.width(30)),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
border: Border(
|
border: Border(
|
||||||
bottom: BorderSide(
|
bottom:
|
||||||
color: AppTheme.dividerColor,
|
BorderSide(color: AppTheme.dividerColor))),
|
||||||
width: ScreenAdaper.height(2)))),
|
|
||||||
alignment: Alignment.center,
|
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
|
@ -43,16 +56,43 @@ class ModalUtil {
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
title,
|
title,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: ScreenAdaper.height(30),
|
||||||
|
color: AppTheme.black,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
content: content ??
|
||||||
|
(contentText != null
|
||||||
|
? Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: ScreenAdaper.height(20),
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(
|
||||||
|
color: AppTheme.dividerColor,
|
||||||
|
width: ScreenAdaper.height(2)))),
|
||||||
|
child: Text(
|
||||||
|
// '${title}${title}${title}${title}${title}${title}${title}${title}${title}${title}${title}${title}${title}${title}${title}${title}${title}${title} ${title}${title}${title}${title}',
|
||||||
|
contentText,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: ScreenAdaper.height(30),
|
fontSize: ScreenAdaper.height(30),
|
||||||
fontWeight: FontWeight.w500),
|
fontWeight: FontWeight.w500),
|
||||||
)
|
))
|
||||||
]),
|
: null),
|
||||||
)
|
actions: !showActions
|
||||||
: null,
|
? null
|
||||||
actions: [
|
: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
|
if (showCancel)
|
||||||
Expanded(
|
Expanded(
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
@ -70,7 +110,6 @@ class ModalUtil {
|
||||||
fontSize: ScreenAdaper.height(30)),
|
fontSize: ScreenAdaper.height(30)),
|
||||||
)),
|
)),
|
||||||
)),
|
)),
|
||||||
const VerticalDivider(),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
@ -79,11 +118,11 @@ class ModalUtil {
|
||||||
confirmed = true;
|
confirmed = true;
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding:
|
padding: EdgeInsets.symmetric(
|
||||||
EdgeInsets.symmetric(vertical: ScreenAdaper.height(15)),
|
vertical: ScreenAdaper.height(15)),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Text(
|
child: Text(
|
||||||
'确定',
|
confirmText ?? '确定',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
fontSize: ScreenAdaper.height(30)),
|
fontSize: ScreenAdaper.height(30)),
|
||||||
|
|
|
@ -59,6 +59,7 @@ class SkMutilSearchMore<T extends BaseSearchMoreModel> extends StatelessWidget {
|
||||||
if (isDialog) {
|
if (isDialog) {
|
||||||
Get.back();
|
Get.back();
|
||||||
}
|
}
|
||||||
|
controller.selectedIndex.clear();
|
||||||
},
|
},
|
||||||
buttonText: '确定',
|
buttonText: '确定',
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:sk_base_mobile/app_theme.dart';
|
import 'package:sk_base_mobile/app_theme.dart';
|
||||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
import 'package:sk_base_mobile/util/snack_bar.util.dart';
|
|
||||||
|
|
||||||
class SkNumberInput<T> extends StatefulWidget {
|
class SkNumberInput<T> extends StatefulWidget {
|
||||||
final TextEditingController textController;
|
final TextEditingController textController;
|
||||||
|
@ -17,8 +16,8 @@ class SkNumberInput<T> extends StatefulWidget {
|
||||||
final bool isRequired;
|
final bool isRequired;
|
||||||
final String labelText;
|
final String labelText;
|
||||||
final String? hint;
|
final String? hint;
|
||||||
ValueChanged<int>? onFieldSubmitted;
|
final ValueChanged<int>? onFieldSubmitted;
|
||||||
SkNumberInput(
|
const SkNumberInput(
|
||||||
{super.key,
|
{super.key,
|
||||||
required this.textController,
|
required this.textController,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
|
|
|
@ -15,8 +15,8 @@ class SkTextInput extends StatefulWidget {
|
||||||
final String? Function(String?)? validator;
|
final String? Function(String?)? validator;
|
||||||
final EdgeInsetsGeometry? contentPadding;
|
final EdgeInsetsGeometry? contentPadding;
|
||||||
final bool autoFocus;
|
final bool autoFocus;
|
||||||
ValueChanged<String>? onFieldSubmitted;
|
final ValueChanged<String>? onFieldSubmitted;
|
||||||
SkTextInput(
|
const SkTextInput(
|
||||||
{super.key,
|
{super.key,
|
||||||
required this.textController,
|
required this.textController,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
|
|
|
@ -30,7 +30,7 @@ class GradientButton extends StatelessWidget {
|
||||||
Size(double.infinity, ScreenAdaper.height(80))),
|
Size(double.infinity, ScreenAdaper.height(80))),
|
||||||
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
||||||
RoundedRectangleBorder(
|
RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(0),
|
borderRadius: BorderRadius.circular(10),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -22,8 +22,8 @@ class MyAvatarWidget extends StatelessWidget {
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: AppTheme.white, width: ScreenAdaper.sp(2)),
|
color: AppTheme.white, width: ScreenAdaper.sp(2)),
|
||||||
borderRadius: BorderRadius.circular(50)),
|
borderRadius: BorderRadius.circular(50)),
|
||||||
height: ScreenAdaper.width(120),
|
height: ScreenAdaper.width(150),
|
||||||
width: ScreenAdaper.width(120),
|
width: ScreenAdaper.width(150),
|
||||||
child: const SizedBox(),
|
child: const SizedBox(),
|
||||||
)),
|
)),
|
||||||
Positioned(
|
Positioned(
|
||||||
|
|
|
@ -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/services/app_info.service.dart';
|
||||||
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
|
import 'package:sk_base_mobile/widgets/gradient_button.dart';
|
||||||
|
|
||||||
|
class UpgradeConfirm extends StatelessWidget {
|
||||||
|
void Function()? onConfirm;
|
||||||
|
bool forceUpgrade;
|
||||||
|
UpgradeConfirm({super.key, this.onConfirm, this.forceUpgrade = true});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(ScreenAdaper.radius(30))),
|
||||||
|
margin: EdgeInsets.only(bottom: ScreenAdaper.height(30)),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: ScreenAdaper.height(600),
|
||||||
|
constraints: BoxConstraints(maxHeight: ScreenAdaper.height(600)),
|
||||||
|
width: ScreenAdaper.width(800),
|
||||||
|
margin: EdgeInsets.only(
|
||||||
|
top: ScreenAdaper.height(100),
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
top: ScreenAdaper.height(50), bottom: ScreenAdaper.height(30)),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppTheme.nearlyWhite,
|
||||||
|
borderRadius: BorderRadius.circular(ScreenAdaper.radius(30))),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'有新的版本更新啦',
|
||||||
|
style: TextStyle(
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
fontSize: ScreenAdaper.height(35),
|
||||||
|
color: AppTheme.nearlyBlack,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: ScreenAdaper.height(30),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Text('1.修复bug',
|
||||||
|
style: TextStyle(
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
fontSize: ScreenAdaper.height(30),
|
||||||
|
color: AppTheme.grey,
|
||||||
|
fontWeight: FontWeight.w400)),
|
||||||
|
Text('2.优化体验',
|
||||||
|
style: TextStyle(
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
fontSize: ScreenAdaper.height(30),
|
||||||
|
color: AppTheme.grey,
|
||||||
|
fontWeight: FontWeight.w400)),
|
||||||
|
],
|
||||||
|
))),
|
||||||
|
SizedBox(
|
||||||
|
height: ScreenAdaper.height(30),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: ScreenAdaper.height(400),
|
||||||
|
child: GradientButton(
|
||||||
|
buttonText: '去更新',
|
||||||
|
onPressed: () {
|
||||||
|
if (onConfirm != null) onConfirm!();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (!forceUpgrade)
|
||||||
|
Positioned(
|
||||||
|
right: 0,
|
||||||
|
top: ScreenAdaper.height(100),
|
||||||
|
child: // 更新内容
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
Get.back();
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.close)),
|
||||||
|
),
|
||||||
|
// 悬浮图标
|
||||||
|
Positioned(
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Image(
|
||||||
|
image: const AssetImage('assets/images/rocket.png'),
|
||||||
|
height: ScreenAdaper.height(150),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -520,6 +520,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.1+1"
|
version: "0.2.1+1"
|
||||||
|
install_plugin:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: install_plugin
|
||||||
|
sha256: "6fb67ba0781e75de4f2f2266ed25e835bfd277c5bfc2ed034af52774355857c6"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
intl:
|
intl:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -66,6 +66,7 @@ dependencies:
|
||||||
flutter_slidable: ^3.1.0
|
flutter_slidable: ^3.1.0
|
||||||
pinyin: ^3.2.0
|
pinyin: ^3.2.0
|
||||||
math_expressions: ^2.4.0
|
math_expressions: ^2.4.0
|
||||||
|
install_plugin: ^2.1.0
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
Loading…
Reference in New Issue