feat: upgrade apk.
This commit is contained in:
parent
10145b3af7
commit
1befdcb786
|
@ -43,6 +43,7 @@
|
|||
android:name="android.permission.CAMERA" />
|
||||
<uses-permission
|
||||
android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
|
||||
</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';
|
||||
|
||||
class Api {
|
||||
// 登录
|
||||
/// 登录
|
||||
static Future<Response> login(String username, String password) {
|
||||
return DioService.dio.post(
|
||||
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() {
|
||||
return DioService.dio.get(
|
||||
|
|
|
@ -28,6 +28,7 @@ class AppTheme {
|
|||
}
|
||||
|
||||
final theme = ThemeData(
|
||||
platform: TargetPlatform.iOS,
|
||||
primarySwatch: MaterialColor(AppTheme.primaryColor.value, const {
|
||||
50: AppTheme.primaryColorLight,
|
||||
100: AppTheme.primaryColorLight,
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
// Global config
|
||||
class GloablConfig {
|
||||
static const BASE_URL = "http://10.0.2.2:8001/api/";
|
||||
static const OSS_URL = "http://10.0.2.2:8001";
|
||||
// static const BASE_URL = "http://10.0.2.2:8001/api/";
|
||||
// static const OSS_URL = "http://10.0.2.2:8001";
|
||||
|
||||
// static const BASE_URL = "http://144.123.43.138:3001/api/";
|
||||
// static const OSS_URL = "http://144.123.43.138:3001";
|
||||
static const BASE_URL = "http://144.123.43.138:3001/api/";
|
||||
static const OSS_URL = "http://144.123.43.138:3001";
|
||||
// static const BASE_URL = "http://192.168.60.220:8001/api/";
|
||||
// static const OSS_URL = "http://192.168.60.220:8001";
|
||||
static const DOMAIN_NAME = "山矿通";
|
||||
|
|
|
@ -6,3 +6,4 @@ export 'global_url.dart';
|
|||
export 'cache_key.dart';
|
||||
export 'router.dart';
|
||||
export 'text_enum.dart';
|
||||
export 'system_param_config.dart';
|
||||
|
|
|
@ -13,4 +13,6 @@ class Urls {
|
|||
static String updateAvatar = 'user/updateAvatar';
|
||||
static String getDictType = 'system/dict-type/all';
|
||||
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.createdAt,
|
||||
required this.updatedAt,
|
||||
required this.inventoryNumber,
|
||||
required this.inventoryInOutNumber,
|
||||
required this.productId,
|
||||
required this.inOrOut,
|
||||
required this.time,
|
||||
|
@ -28,7 +28,7 @@ class InventoryInOutModel {
|
|||
final int? id;
|
||||
final DateTime? createdAt;
|
||||
final DateTime? updatedAt;
|
||||
final String? inventoryNumber;
|
||||
final String? inventoryInOutNumber;
|
||||
final int? productId;
|
||||
final int? inOrOut;
|
||||
final DateTime? time;
|
||||
|
@ -47,12 +47,12 @@ class InventoryInOutModel {
|
|||
factory InventoryInOutModel.fromJson(Map<String, dynamic> json) {
|
||||
return InventoryInOutModel(
|
||||
id: json["id"],
|
||||
createdAt: DateTime.tryParse(json["createdAt"] ?? ""),
|
||||
updatedAt: DateTime.tryParse(json["updatedAt"] ?? ""),
|
||||
inventoryNumber: json["inventoryNumber"],
|
||||
createdAt: DateTime.tryParse(json["createdAt"] ?? "")?.toLocal(),
|
||||
updatedAt: DateTime.tryParse(json["updatedAt"] ?? "")?.toLocal(),
|
||||
inventoryInOutNumber: json["inventoryInOutNumber"],
|
||||
productId: json["productId"],
|
||||
inOrOut: json["inOrOut"],
|
||||
time: DateTime.tryParse(json["time"] ?? ""),
|
||||
time: DateTime.tryParse(json["time"] ?? "")?.toLocal(),
|
||||
quantity: json["quantity"],
|
||||
unitPrice: json["unitPrice"],
|
||||
amount: json["amount"],
|
||||
|
@ -81,7 +81,7 @@ class InventoryInOutModel {
|
|||
"id": id,
|
||||
"createdAt": createdAt?.toIso8601String(),
|
||||
"updatedAt": updatedAt?.toIso8601String(),
|
||||
"inventoryNumber": inventoryNumber,
|
||||
"inventoryInOutNumber": inventoryInOutNumber,
|
||||
"productId": productId,
|
||||
"inOrOut": inOrOut,
|
||||
"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';
|
||||
|
||||
class InventoryPage extends StatelessWidget {
|
||||
const InventoryPage({super.key});
|
||||
final bool isPage;
|
||||
const InventoryPage({super.key, this.isPage = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: const SkAppbar(title: '库存管理'),
|
||||
appBar: SkAppbar(title: '库存管理', hideLeading: isPage),
|
||||
body: InventorySearch(),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -109,7 +109,11 @@ class InventoryInoutCard extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
Text(
|
||||
controller.list[ind][index].agent ?? '-',
|
||||
'${DateUtil.format(controller.list[ind][index].time!, formats: [
|
||||
'HH',
|
||||
':',
|
||||
"nn"
|
||||
])} ${controller.list[ind][index].agent ?? '-'}',
|
||||
style: TextStyle(
|
||||
fontSize: ScreenAdaper.height(20),
|
||||
fontWeight: FontWeight.w600),
|
||||
|
|
|
@ -63,7 +63,19 @@ class InventoryInoutInfo extends StatelessWidget {
|
|||
buildListItem(
|
||||
leading: '出入库时间',
|
||||
trailing: DateUtil.format(
|
||||
controller.inventoryInoutInfo.value!.time!)),
|
||||
controller.inventoryInoutInfo.value!.time!,
|
||||
formats: [
|
||||
'yyyy',
|
||||
'-',
|
||||
'mm',
|
||||
'-',
|
||||
'dd',
|
||||
" ",
|
||||
'HH',
|
||||
":",
|
||||
"nn"
|
||||
]),
|
||||
),
|
||||
customDivider(),
|
||||
buildListItem(
|
||||
leading: '所属公司',
|
||||
|
@ -99,6 +111,16 @@ class InventoryInoutInfo extends StatelessWidget {
|
|||
trailing:
|
||||
controller.inventoryInoutInfo.value?.remark),
|
||||
customDivider(),
|
||||
buildListItem(
|
||||
leading: '出入库单号',
|
||||
trailing: controller
|
||||
.inventoryInoutInfo.value?.inventoryInOutNumber),
|
||||
customDivider(),
|
||||
buildListItem(
|
||||
leading: '库存编号',
|
||||
trailing: controller.inventoryInoutInfo.value
|
||||
?.inventory?.inventoryNumber),
|
||||
customDivider(),
|
||||
buildListItem(
|
||||
leading: '照片',
|
||||
),
|
||||
|
@ -156,14 +178,31 @@ class InventoryInoutInfo extends StatelessWidget {
|
|||
}
|
||||
|
||||
Widget buildListItem({String? leading, dynamic trailing}) {
|
||||
return ListTile(
|
||||
leading: Text(
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: ScreenAdaper.height(20),
|
||||
horizontal: ScreenAdaper.width(20)),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'${leading ?? ''}: ',
|
||||
style: TextStyle(
|
||||
fontSize: ScreenAdaper.height(25), fontWeight: FontWeight.w600),
|
||||
fontSize: ScreenAdaper.height(30), fontWeight: FontWeight.w600),
|
||||
),
|
||||
trailing: Text('${trailing ?? ''}',
|
||||
style: TextStyle(fontSize: ScreenAdaper.height(25))));
|
||||
Spacer(),
|
||||
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/db_helper/db_help.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/services/app_info.service.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';
|
||||
|
@ -236,7 +238,7 @@ class InventoryInoutController extends GetxController {
|
|||
Future showInventoryInoutInfoDialog(int id) async {
|
||||
ModalUtil.showGeneralDialog(
|
||||
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),
|
||||
offset: const Offset(0, -1))
|
||||
.then((value) => {Get.delete<InventoryInouInfoController>()});
|
||||
|
@ -258,6 +260,7 @@ class InventoryInoutController extends GetxController {
|
|||
}
|
||||
return [];
|
||||
} catch (e) {
|
||||
print(e);
|
||||
return [];
|
||||
} finally {
|
||||
loading.value = false;
|
||||
|
@ -335,7 +338,7 @@ class InventoryInoutController extends GetxController {
|
|||
// }
|
||||
// case 2:
|
||||
// {
|
||||
// ModalUtil.confirm(
|
||||
// ModalUtil.alert(
|
||||
// 'Delete Task', 'Are you want to sure to remove', 'Confirm', () {
|
||||
// list[ind].remove(list[ind][index]);
|
||||
// db.delete(
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
import 'package:flutter/material.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/screens/inventory/inventory.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/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 {
|
||||
RxInt currentIndex = 0.obs;
|
||||
|
@ -20,7 +26,7 @@ class LandingController extends GetxController {
|
|||
icon: Icons.inventory_outlined,
|
||||
activeIcon: Icons.inventory_rounded,
|
||||
label: '库存',
|
||||
page: const InventoryPage()),
|
||||
page: const InventoryPage(isPage: true)),
|
||||
AppBottomNavItem(
|
||||
icon: Icons.widgets_outlined,
|
||||
activeIcon: Icons.widgets_rounded,
|
||||
|
@ -36,5 +42,6 @@ class LandingController extends GetxController {
|
|||
onInit() {
|
||||
super.onInit();
|
||||
pages = bottomNavItems!.map((e) => e.page!).toList();
|
||||
AppInfoService.to.checkVersion();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import 'package:flutter/widgets.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 '../../constants/constants.dart';
|
||||
import '../../store/auth.store.dart';
|
||||
// import 'package:sentry/sentry.dart';
|
||||
|
||||
|
|
|
@ -35,11 +35,14 @@ class _MinePageState extends State<MinePage>
|
|||
Widget _buildBody() {
|
||||
return Column(children: [
|
||||
Container(
|
||||
height: ScreenAdaper.height(300),
|
||||
decoration: const BoxDecoration(
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: AssetImage('assets/images/yeyazhijia_bg.jpg'))),
|
||||
height: ScreenAdaper.height(350),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [AppTheme.primaryColorLight, AppTheme.primaryColor])
|
||||
// image: DecorationImage(
|
||||
// fit: BoxFit.cover,
|
||||
// image: AssetImage('assets/images/yeyazhijia_bg.jpg'))
|
||||
),
|
||||
// decoration: BoxDecoration(
|
||||
// gradient: LinearGradient(
|
||||
// colors: [AppTheme.primaryColorLight, AppTheme.primaryColor])),
|
||||
|
@ -49,7 +52,7 @@ class _MinePageState extends State<MinePage>
|
|||
vertical: ScreenAdaper.height(20)),
|
||||
child: Column(children: [
|
||||
SizedBox(
|
||||
height: ScreenAdaper.height(80),
|
||||
height: ScreenAdaper.height(100),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
@ -69,7 +72,7 @@ class _MinePageState extends State<MinePage>
|
|||
AuthStore.to.userInfo.value.nickname ?? '',
|
||||
style: TextStyle(
|
||||
letterSpacing: ScreenAdaper.width(5),
|
||||
fontSize: ScreenAdaper.height(30),
|
||||
fontSize: ScreenAdaper.height(35),
|
||||
fontWeight: FontWeight.bold,
|
||||
foreground: Paint()
|
||||
..style = PaintingStyle.stroke
|
||||
|
@ -81,7 +84,7 @@ class _MinePageState extends State<MinePage>
|
|||
style: TextStyle(
|
||||
letterSpacing: ScreenAdaper.width(5),
|
||||
color: Colors.white,
|
||||
fontSize: ScreenAdaper.height(30),
|
||||
fontSize: ScreenAdaper.height(35),
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import 'package:flutter/material.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/util/device.util.dart';
|
||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||
|
||||
class MineSettingsPage extends StatelessWidget {
|
||||
|
@ -18,7 +21,7 @@ class MineSettingsPage extends StatelessWidget {
|
|||
border: Border.all(),
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
color: AppTheme.nearlyWhite),
|
||||
width: ScreenAdaper.width(400),
|
||||
width: ScreenAdaper.width(600),
|
||||
padding:
|
||||
EdgeInsets.symmetric(vertical: ScreenAdaper.width(10)),
|
||||
child: InkWell(
|
||||
|
@ -35,7 +38,44 @@ class MineSettingsPage extends StatelessWidget {
|
|||
Text(
|
||||
'退出登录',
|
||||
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),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -84,10 +84,10 @@ class NewInventoryInout extends StatelessWidget {
|
|||
SizedBox(
|
||||
height: ScreenAdaper.height(formVerticalGap),
|
||||
),
|
||||
buildDatePicker(),
|
||||
SizedBox(
|
||||
height: ScreenAdaper.height(formVerticalGap),
|
||||
),
|
||||
// buildDatePicker(),
|
||||
// SizedBox(
|
||||
// height: ScreenAdaper.height(formVerticalGap),
|
||||
// ),
|
||||
buildAgent(),
|
||||
SizedBox(
|
||||
height: ScreenAdaper.height(formVerticalGap),
|
||||
|
|
|
@ -128,13 +128,29 @@ class NewInventoryInoutController extends GetxController {
|
|||
);
|
||||
return;
|
||||
}
|
||||
if (payload['time'] == null) {
|
||||
SnackBarUtil().error(
|
||||
'时间不能为空',
|
||||
);
|
||||
return;
|
||||
}
|
||||
// 暂时时间定位提交时间
|
||||
// if (payload['time'] == null) {
|
||||
// SnackBarUtil().error(
|
||||
// '时间不能为空',
|
||||
// );
|
||||
// return;
|
||||
// }
|
||||
|
||||
payload['time'] = DateUtil.format(DateTime.now(), formats: [
|
||||
'yyyy',
|
||||
'-',
|
||||
'mm',
|
||||
'-',
|
||||
'dd',
|
||||
' ',
|
||||
'HH',
|
||||
':',
|
||||
'nn',
|
||||
":",
|
||||
'ss'
|
||||
]);
|
||||
payload['quantity'] = quantityTextController.text;
|
||||
|
||||
if (payload['quantity'].isEmpty || payload['quantity'] == '0') {
|
||||
SnackBarUtil().error(
|
||||
'数量必须大于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/screens/sale_quotation/components/sale_quotation_group_search.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_single_search_more.dart';
|
||||
import 'package:sk_base_mobile/util/modal.util.dart';
|
||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||
import 'package:pinyin/pinyin.dart';
|
||||
|
@ -20,19 +18,25 @@ class SaleQuotationController extends GetxController {
|
|||
final RxList editingcell = RxList([null, null, null]);
|
||||
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
RxList<SaleQuotationItemModel> products = RxList([
|
||||
SaleQuotationItemModel(name: '矿用本安型支架控制器', unit: '台', spec: 'ZDYZ-Z'),
|
||||
SaleQuotationItemModel(name: '矿用本安型电磁阀驱动器'),
|
||||
SaleQuotationItemModel(name: '矿用隔爆兼本安型电源'),
|
||||
SaleQuotationItemModel(name: '矿用本安型隔离耦合器'),
|
||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器'),
|
||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-控制器'),
|
||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-驱动器'),
|
||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-隔离耦合器'),
|
||||
SaleQuotationItemModel(name: '矿用本安型支架无线遥控器'),
|
||||
SaleQuotationItemModel(name: '矿用隔爆兼本安型电源'),
|
||||
SaleQuotationItemModel(name: '电液换向阀(10功能10接口)', remark: '中间过渡架主阀组'),
|
||||
SaleQuotationItemModel(name: '电液换向阀(20功能20接口)', remark: '端头架主阀组'),
|
||||
SaleQuotationItemModel(name: '自动反冲洗过滤装置', remark: '流量:900L/min,过滤精度25μm'),
|
||||
SaleQuotationItemModel(
|
||||
name: '矿用本安型支架控制器', unit: '台', spec: 'ZDYZ-Z', cost: 4700),
|
||||
SaleQuotationItemModel(name: '矿用本安型电磁阀驱动器', cost: 1200),
|
||||
SaleQuotationItemModel(name: '矿用隔爆兼本安型电源', cost: 5700),
|
||||
SaleQuotationItemModel(name: '矿用本安型隔离耦合器', cost: 1200),
|
||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', cost: 600),
|
||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-控制器', cost: 400),
|
||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-驱动器', cost: 500),
|
||||
SaleQuotationItemModel(
|
||||
name: '钢丝编织橡胶护套连接器', remark: '控制器-隔离耦合器', cost: 2000),
|
||||
SaleQuotationItemModel(name: '矿用本安型支架控制器', cost: 4700),
|
||||
SaleQuotationItemModel(name: '矿用本安型电磁阀驱动器', cost: 1200),
|
||||
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: '矿用本安型位移传感器'),
|
||||
SaleQuotationItemModel(name: '矿用本安型压力传感器'),
|
||||
|
@ -190,15 +194,51 @@ class SaleQuotationController extends GetxController {
|
|||
padding: EdgeInsets.symmetric(
|
||||
horizontal: ScreenAdaper.width(5),
|
||||
vertical: ScreenAdaper.height(10)),
|
||||
child: Row(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
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))
|
||||
|
@ -239,19 +279,25 @@ class ItemSearchMoreController extends GetxController
|
|||
@override
|
||||
Future<List<SaleQuotationItemModel>> getData({bool isRefresh = false}) async {
|
||||
List<SaleQuotationItemModel> newList = [
|
||||
SaleQuotationItemModel(name: '矿用本安型支架控制器', unit: '台', spec: 'ZDYZ-Z'),
|
||||
SaleQuotationItemModel(name: '矿用本安型电磁阀驱动器'),
|
||||
SaleQuotationItemModel(name: '矿用隔爆兼本安型电源'),
|
||||
SaleQuotationItemModel(name: '矿用本安型隔离耦合器'),
|
||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器'),
|
||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-控制器'),
|
||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-驱动器'),
|
||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-隔离耦合器'),
|
||||
SaleQuotationItemModel(name: '矿用本安型支架无线遥控器'),
|
||||
SaleQuotationItemModel(name: '矿用隔爆兼本安型电源'),
|
||||
SaleQuotationItemModel(name: '电液换向阀(10功能10接口)', remark: '中间过渡架主阀组'),
|
||||
SaleQuotationItemModel(name: '电液换向阀(20功能20接口)', remark: '端头架主阀组'),
|
||||
SaleQuotationItemModel(name: '自动反冲洗过滤装置', remark: '流量:900L/min,过滤精度25μm'),
|
||||
SaleQuotationItemModel(
|
||||
name: '矿用本安型支架控制器', unit: '台', spec: 'ZDYZ-Z', cost: 4700),
|
||||
SaleQuotationItemModel(name: '矿用本安型电磁阀驱动器', cost: 1200),
|
||||
SaleQuotationItemModel(name: '矿用隔爆兼本安型电源', cost: 5700),
|
||||
SaleQuotationItemModel(name: '矿用本安型隔离耦合器', cost: 1200),
|
||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', cost: 600),
|
||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-控制器', cost: 400),
|
||||
SaleQuotationItemModel(name: '钢丝编织橡胶护套连接器', remark: '控制器-驱动器', cost: 500),
|
||||
SaleQuotationItemModel(
|
||||
name: '钢丝编织橡胶护套连接器', remark: '控制器-隔离耦合器', cost: 2000),
|
||||
SaleQuotationItemModel(name: '矿用本安型支架控制器', cost: 4700),
|
||||
SaleQuotationItemModel(name: '矿用本安型电磁阀驱动器', cost: 1200),
|
||||
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: '矿用本安型位移传感器'),
|
||||
SaleQuotationItemModel(name: '矿用本安型压力传感器'),
|
||||
|
|
|
@ -35,7 +35,7 @@ class SaleQuotationPage extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
key: controller.scaffoldKey,
|
||||
endDrawer: Drawer(
|
||||
endDrawer: const Drawer(
|
||||
// 从右到左出现
|
||||
child: SaleQuotationEndDrawer(),
|
||||
),
|
||||
|
@ -47,7 +47,23 @@ class SaleQuotationPage extends StatelessWidget {
|
|||
controller.scaffoldKey.currentState?.openEndDrawer();
|
||||
},
|
||||
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(
|
||||
|
@ -65,6 +81,8 @@ class SaleQuotationPage extends StatelessWidget {
|
|||
(index, e) => buildBody(index))
|
||||
.toList(),
|
||||
))),
|
||||
// 当键盘弹起时,不显示
|
||||
|
||||
SizedBox(
|
||||
height: ScreenAdaper.height(100),
|
||||
child: buildTotalCostRow(),
|
||||
|
@ -76,7 +94,7 @@ class SaleQuotationPage extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
// Positioned(
|
||||
// bottom: ScreenAdaper.height(10),
|
||||
// bottom: ScreenAdaper.height(220),
|
||||
// right: ScreenAdaper.height(10),
|
||||
// child: IconButton(
|
||||
// padding: EdgeInsets.all(ScreenAdaper.height(20)),
|
||||
|
@ -339,8 +357,8 @@ class SaleQuotationPage extends StatelessWidget {
|
|||
const Spacer(),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
ModalUtil.confirm(
|
||||
title: '确定要删除此组吗?',
|
||||
ModalUtil.alert(
|
||||
contentText: '确定要删除此组吗?',
|
||||
onConfirm: () {
|
||||
controller.removeGroup(groupIndex);
|
||||
});
|
||||
|
@ -464,7 +482,7 @@ class SaleQuotationPage extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
),
|
||||
VerticalDivider(),
|
||||
const VerticalDivider(),
|
||||
buildEditCell<int>(
|
||||
Container(
|
||||
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/util/screen_adaper_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 {
|
||||
WorkBenchPage({super.key});
|
||||
|
@ -15,31 +16,8 @@ class WorkBenchPage extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: const SizedBox(),
|
||||
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);
|
||||
// },
|
||||
// ),
|
||||
// )
|
||||
|
||||
);
|
||||
appBar: const SkAppbar(title: '工作台', hideLeading: true),
|
||||
body: buildList());
|
||||
}
|
||||
|
||||
Widget buildList() {
|
||||
|
|
|
@ -3,7 +3,6 @@ import 'package:get/get.dart';
|
|||
import 'package:sk_base_mobile/models/workbench.model.dart';
|
||||
|
||||
class WorkBenchController extends GetxController {
|
||||
late final AnimationController animationController;
|
||||
final List<WorkBenchModel> menus = [
|
||||
WorkBenchModel(title: '库存', route: '/inventory', icon: 'inventory.svg'),
|
||||
WorkBenchModel(title: '产品', route: '/product', icon: 'product.svg'),
|
||||
|
@ -15,9 +14,4 @@ class WorkBenchController extends GetxController {
|
|||
WorkBenchModel(
|
||||
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:install_plugin/install_plugin.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/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/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 'package:dio/dio.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
class AppInfoService extends GetxService {
|
||||
static AppInfoService get to => Get.find();
|
||||
|
@ -12,14 +29,16 @@ class AppInfoService extends GetxService {
|
|||
final scale = RxDouble(1.0);
|
||||
final isLarge = RxBool(false);
|
||||
final isCameraing = RxBool(false);
|
||||
|
||||
final downloadProgress = RxDouble(0.0);
|
||||
Future<AppInfoService> init() async {
|
||||
LoggerUtil()
|
||||
.info("[service-appInfo] Register app-related information service");
|
||||
|
||||
try {
|
||||
// await Future.wait(
|
||||
// [getDeviceInfo(), getPackageInfo(), getAppConfig(), getossPolicy()]);
|
||||
await Future.wait([
|
||||
getDeviceInfo(),
|
||||
getPackageInfo() /* , getAppConfig(), getossPolicy() */
|
||||
]);
|
||||
requestPermission();
|
||||
} catch (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) {
|
||||
List<AppConfigItem> items = appConfig.items!;
|
||||
|
|
|
@ -64,7 +64,9 @@ class DioService extends get_package.GetxService {
|
|||
} else if (e.response?.statusCode == 401) {
|
||||
// dio.lock();
|
||||
LoggerUtil().error('[Service-dio] logout:${e.response}');
|
||||
await AuthStore().logout(force: true);
|
||||
Future.delayed(Duration(seconds: 1), () {
|
||||
AuthStore().logout(force: true);
|
||||
});
|
||||
SnackBarUtil().error('请重新登录');
|
||||
} else if (e.response?.statusCode == 403) {
|
||||
await SnackBarUtil().error(
|
||||
|
@ -126,6 +128,7 @@ class DioService extends get_package.GetxService {
|
|||
|
||||
void onResponse(Response response, ResponseInterceptorHandler handler) async {
|
||||
/* LoggerUtil().info('[Service-dio] ${response.data}'); */
|
||||
|
||||
if (whiteList.contains(response.requestOptions.path)) {
|
||||
handler.next(response);
|
||||
return;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:dio/dio.dart' as dio_package;
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:sk_base_mobile/apis/index.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);
|
||||
LoggerUtil().info('[Store-Auth] Logout succeed.');
|
||||
// 如果当前已经在login界面 不需要跳转
|
||||
// 判断是否Get已经注册
|
||||
if (Get.currentRoute != RouteConfig.login) {
|
||||
Get.offAllNamed(RouteConfig.login);
|
||||
}
|
||||
// 不用getx跳转登录页
|
||||
}
|
||||
|
||||
Future<void> login(
|
||||
|
@ -72,7 +75,7 @@ class AuthStore extends GetxService {
|
|||
// return;
|
||||
// }
|
||||
|
||||
LoadingUtil.to.show();
|
||||
await LoadingUtil.to.show();
|
||||
TapToDismissKeyboard.dismissOf(context: Get.context!);
|
||||
try {
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
|
@ -89,7 +92,7 @@ class AuthStore extends GetxService {
|
|||
Get.offNamed(RouteConfig.home);
|
||||
}
|
||||
} catch (e) {
|
||||
await SnackBarUtil().error('账号密码错误$e');
|
||||
await SnackBarUtil().error('账号密码错误');
|
||||
LoggerUtil().error(e);
|
||||
} finally {
|
||||
LoadingUtil.to.dismiss();
|
||||
|
|
|
@ -3,7 +3,7 @@ import 'package:date_format/date_format.dart';
|
|||
class DateUtil {
|
||||
/// 格式化日期 默认 YYYY-MM-DD
|
||||
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';
|
||||
|
||||
class ModalUtil {
|
||||
static Future<bool> confirm(
|
||||
{String? title, String? button, VoidCallback? onConfirm}) async {
|
||||
static Future<bool> alert(
|
||||
{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;
|
||||
await showDialog(
|
||||
context: Get.overlayContext!,
|
||||
builder: (context) {
|
||||
barrierDismissible: barrierDismissible,
|
||||
builder: builder ??
|
||||
(context) {
|
||||
return AlertDialog(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
backgroundColor: AppTheme.nearlyWhite,
|
||||
|
@ -20,17 +31,19 @@ class ModalUtil {
|
|||
),
|
||||
actionsPadding: EdgeInsets.zero,
|
||||
titlePadding: EdgeInsets.zero,
|
||||
contentPadding: contentPadding ??
|
||||
EdgeInsets.symmetric(
|
||||
vertical: ScreenAdaper.height(10),
|
||||
),
|
||||
title: title != null
|
||||
? Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: ScreenAdaper.height(30),
|
||||
horizontal: ScreenAdaper.width(30)),
|
||||
decoration: BoxDecoration(
|
||||
vertical: ScreenAdaper.height(20),
|
||||
),
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: AppTheme.dividerColor,
|
||||
width: ScreenAdaper.height(2)))),
|
||||
alignment: Alignment.center,
|
||||
bottom:
|
||||
BorderSide(color: AppTheme.dividerColor))),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
|
@ -43,16 +56,43 @@ class ModalUtil {
|
|||
),
|
||||
Text(
|
||||
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(
|
||||
fontSize: ScreenAdaper.height(30),
|
||||
fontWeight: FontWeight.w500),
|
||||
)
|
||||
]),
|
||||
)
|
||||
: null,
|
||||
actions: [
|
||||
))
|
||||
: null),
|
||||
actions: !showActions
|
||||
? null
|
||||
: [
|
||||
Row(
|
||||
children: [
|
||||
if (showCancel)
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
|
@ -70,7 +110,6 @@ class ModalUtil {
|
|||
fontSize: ScreenAdaper.height(30)),
|
||||
)),
|
||||
)),
|
||||
const VerticalDivider(),
|
||||
Expanded(
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
|
@ -79,11 +118,11 @@ class ModalUtil {
|
|||
confirmed = true;
|
||||
},
|
||||
child: Container(
|
||||
padding:
|
||||
EdgeInsets.symmetric(vertical: ScreenAdaper.height(15)),
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: ScreenAdaper.height(15)),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
'确定',
|
||||
confirmText ?? '确定',
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: ScreenAdaper.height(30)),
|
||||
|
|
|
@ -59,6 +59,7 @@ class SkMutilSearchMore<T extends BaseSearchMoreModel> extends StatelessWidget {
|
|||
if (isDialog) {
|
||||
Get.back();
|
||||
}
|
||||
controller.selectedIndex.clear();
|
||||
},
|
||||
buttonText: '确定',
|
||||
)
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/services.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/snack_bar.util.dart';
|
||||
|
||||
class SkNumberInput<T> extends StatefulWidget {
|
||||
final TextEditingController textController;
|
||||
|
@ -17,8 +16,8 @@ class SkNumberInput<T> extends StatefulWidget {
|
|||
final bool isRequired;
|
||||
final String labelText;
|
||||
final String? hint;
|
||||
ValueChanged<int>? onFieldSubmitted;
|
||||
SkNumberInput(
|
||||
final ValueChanged<int>? onFieldSubmitted;
|
||||
const SkNumberInput(
|
||||
{super.key,
|
||||
required this.textController,
|
||||
this.onTap,
|
||||
|
|
|
@ -15,8 +15,8 @@ class SkTextInput extends StatefulWidget {
|
|||
final String? Function(String?)? validator;
|
||||
final EdgeInsetsGeometry? contentPadding;
|
||||
final bool autoFocus;
|
||||
ValueChanged<String>? onFieldSubmitted;
|
||||
SkTextInput(
|
||||
final ValueChanged<String>? onFieldSubmitted;
|
||||
const SkTextInput(
|
||||
{super.key,
|
||||
required this.textController,
|
||||
this.onTap,
|
||||
|
|
|
@ -30,7 +30,7 @@ class GradientButton extends StatelessWidget {
|
|||
Size(double.infinity, ScreenAdaper.height(80))),
|
||||
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(0),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -22,8 +22,8 @@ class MyAvatarWidget extends StatelessWidget {
|
|||
border: Border.all(
|
||||
color: AppTheme.white, width: ScreenAdaper.sp(2)),
|
||||
borderRadius: BorderRadius.circular(50)),
|
||||
height: ScreenAdaper.width(120),
|
||||
width: ScreenAdaper.width(120),
|
||||
height: ScreenAdaper.width(150),
|
||||
width: ScreenAdaper.width(150),
|
||||
child: const SizedBox(),
|
||||
)),
|
||||
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"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -66,6 +66,7 @@ dependencies:
|
|||
flutter_slidable: ^3.1.0
|
||||
pinyin: ^3.2.0
|
||||
math_expressions: ^2.4.0
|
||||
install_plugin: ^2.1.0
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
|
Loading…
Reference in New Issue