This commit is contained in:
dzc committed 2025-03-10 17:43:29 +08:00
1 parent 739c45b8c3
commit c2b50b0a18
27 files changed
+489 -200

No files matched your search

-1
View File
@@ -7,7 +7,6 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
<queries>
+8 -5
View File
@@ -12,11 +12,12 @@ class MainApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScreenUtilInit(
designSize: const Size(1920, 1080),
minTextAdapt: true,
splitScreenMode: true,
builder: (_, child) {
final appTheme = Get.put(AppThemeControl());
designSize: const Size(1920, 1080),
minTextAdapt: true,
splitScreenMode: true,
builder: (_, child) {
return Obx(() {
final appTheme = Get.find<AppThemeControl>();
final fTheme = appTheme.theme.value;
final sizeScalar = appTheme.sizeScalar.value;
final themeData = FThemeData.inherit(
@@ -46,6 +47,8 @@ class MainApp extends StatelessWidget {
),
);
});
},
);
}
}
+32 -48
View File
@@ -12,61 +12,47 @@ abstract class HardApi {
}
/// 获取硬件配置信息
static Future<ServiceBase<ServiceHardware>> get(dynamic pa) async {
final res = await HttpManage().dio.get<ServiceBase<ServiceHardware>>(
static Future<ServiceHardware?> get(dynamic pa) async {
final res = await HttpManage().dio.get(
"/hard/hard-api/ad/get",
queryParameters: pa,
);
if (res.data?.data == null) {
return res.data!;
}
final map = res.data!.data as Map<String, dynamic>;
final typeData = ServiceHardware.fromJson(map);
res.data?.data = typeData;
return res.data!;
if (res.data == null) return null;
return ServiceHardware.fromJson(res.data);
}
/// 获取用户信息
static Future<ServiceBase<ServiceUser>> getUserInfoById(
static Future<ServiceUser?> getUserInfoById(
dynamic formData,
) async {
final res = await HttpManage().dio.get<ServiceBase<ServiceUser>>(
final res = await HttpManage().dio.get(
"/hard/hard-api/ad/get-user",
queryParameters: formData,
);
if (res.data?.data == null) {
return res.data!;
}
final map = res.data!.data as Map<String, dynamic>;
final typeData = ServiceUser.fromJson(map);
res.data?.data = typeData;
return res.data!;
if (res.data == null) return null;
return ServiceUser.fromJson(res.data);
}
/// 获取用户信息
static Future<ServiceBase<ServiceUser>> getUserByCard(
static Future<ServiceUser?> getUserByCard(
dynamic formData,
) async {
final res = await HttpManage().dio.get<ServiceBase<ServiceUser>>(
final res = await HttpManage().dio.get(
"/hard/hard-api/ad/get-user-by-card",
queryParameters: formData,
);
if (res.data?.data == null) {
return res.data!;
}
final map = res.data!.data as Map<String, dynamic>;
final typeData = ServiceUser.fromJson(map);
res.data?.data = typeData;
return res.data!;
if (res.data == null) return null;
return ServiceUser.fromJson(res.data);
}
/// 创建硬件订单
static Future<ServiceBase> createHardwareOrder(dynamic formData) async {
final res = await HttpManage().dio.post<ServiceBase>(
static Future<int?> createHardwareOrder(dynamic formData) async {
final res = await HttpManage().dio.post(
"/hard/hard-api/ad/create-order",
data: formData,
);
return res.data as ServiceBase;
if (res.data == null) return null;
return res.data;
}
/// 获取订单详情
@@ -92,46 +78,44 @@ abstract class HardApi {
}
/// 核销订单
static Future<ServiceBase> cancelQrCode(dynamic formData) async {
final res = await HttpManage().dio.post<ServiceBase>(
static Future<bool> cancelQrCode(dynamic formData) async {
final res = await HttpManage().dio.post(
"/hard/hard-api/ad/cancel-code",
data: formData,
);
return res.data!;
if (res.data == null) return false;
return true;
}
/// 生成发票
static Future<ServiceBase<ServiceGenerateInvoice>> generateInvoice(
static Future<ServiceGenerateInvoice?> generateInvoice(
dynamic formData,
) async {
final res = await HttpManage().dio.get<ServiceBase<ServiceGenerateInvoice>>(
final res = await HttpManage().dio.get(
"/hard/hard-api/ad/generate-invoice",
queryParameters: formData,
);
if (res.data?.data == null) {
return res.data!;
}
final map = res.data!.data as Map<String, dynamic>;
final typeData = ServiceGenerateInvoice.fromJson(map);
res.data?.data = typeData;
return res.data!;
if (res.data == null) return null;
return ServiceGenerateInvoice.fromJson(res.data);
}
/// 打印成功
static Future<ServiceBase> printInvoice(dynamic formData) async {
final res = await HttpManage().dio.get<ServiceBase>(
static Future<bool> printInvoice(dynamic formData) async {
final res = await HttpManage().dio.get(
"/hard/hard-api/ad/print-invoice",
queryParameters: formData,
);
return res.data as ServiceBase;
if (res.data == null) return false;
return true;
}
/// 离线同步
static Future<ServiceBase> syncOfflineOrder(dynamic formData) async {
final res = await HttpManage().dio.post<ServiceBase>(
static Future<List<String>?> syncOfflineOrder(dynamic formData) async {
final res = await HttpManage().dio.post(
"/hard/hard-api/ad/sync-offline-order",
data: formData,
);
return res.data as ServiceBase;
if (res.data == null) return null;
return res.data?.map<String>((e) => e.toString()).toList();
}
}
@@ -167,6 +167,9 @@ class UserSetting extends Equatable {
/// 商品时间段类型
ProductHourType? hourType;
// 全局字体大小
SettingGlobalFontSize? globalFontSize;
UserSetting({
this.username,
this.password,
+1 -1
View File
@@ -11,7 +11,7 @@ export './base/base_models.dart';
export './page/order_page_enum_models.dart';
export './page/order_page_models.dart';
export './page/panel_page_models.dart';
export './page/setting_page_models.dart';
export './page/setting_page_enum_models.dart';
export './mq/mq_enum_models.dart';
export './mq/mq_models.dart';
@@ -30,3 +30,20 @@ class SettingMenu {
required this.type,
});
}
enum SettingGlobalFontSize implements BaseEnum {
xl("1.2", "1.2", 1.2),
xl2("1.3", "1.3", 1.3),
xl3("1.4", "1.4", 1.4),
xl4("1.5", "1.5", 1.5),
;
@override
final String code;
@override
final String title;
final double fontSize;
const SettingGlobalFontSize(this.code, this.title, this.fontSize);
}
+2 -1
View File
@@ -68,7 +68,8 @@ abstract class AppFileTool {
int day = now.day;
dir = "$dir/$year-$month";
dir = await _checkAndcreateDir(dir);
return "$dir/$day.log";
dir = "$dir/$day.log";
return dir;
}
/// 创建人脸地址
@@ -43,7 +43,6 @@ class AppControl extends GetxController {
}
Future<void> initAsync() async {
final stopwatch = Stopwatch()..start();
dataBase = await AppDatabase.getDataBase();
printManage = PrintManage();
scanCodeManage = ScanCodeManage();
@@ -51,7 +50,5 @@ class AppControl extends GetxController {
srialSteelyardManage = SerialSteelyardManage();
AppNetworkTool.listenNetwork();
Get.offAllNamed(RouteNames.login);
stopwatch.stop();
logger.d('|$_tag|initAsync耗时:${stopwatch.elapsedMilliseconds}毫秒');
}
}
@@ -1,10 +1,28 @@
import 'package:forui/forui.dart';
import 'package:get/get.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
class AppThemeControl extends GetxController {
/// 主题
Rx<FThemeData> theme = FThemes.zinc.light.obs;
/// 字体大小
RxDouble sizeScalar = 1.4.obs;
RxDouble sizeScalar = SettingGlobalFontSize.xl3.fontSize.obs;
@override
void onInit() async {
super.onInit();
}
Future<void> initAsync() async {
final userInfo = await AppSettingTool.getUserSetting();
if (userInfo.globalFontSize != null) {
sizeScalar.value = userInfo.globalFontSize!.fontSize;
}
}
void setSizeScalar(SettingGlobalFontSize fontSize) {
sizeScalar.value = fontSize.fontSize;
}
}
+35 -20
View File
@@ -27,19 +27,30 @@ class ConsoleOutput extends LogOutput {
@override
Future<void> init() async {
_filePath = await AppFileTool.getLoggerBackupPath();
if (ObjectUtil.isNotEmpty(_filePath)) {
_sink = File(_filePath!).openWrite(
mode: FileMode.writeOnlyAppend,
encoding: utf8,
);
try {
_filePath = await AppFileTool.getLoggerBackupPath();
if (ObjectUtil.isNotEmpty(_filePath)) {
_sink = File(_filePath!).openWrite(
mode: FileMode.writeOnlyAppend,
encoding: utf8,
);
}
_timer = Timer.periodic(const Duration(seconds: 60 * 60 * 2),
(Timer timer) async {
final path = await AppFileTool.getLoggerBackupPath();
if (path == null) return;
// 关闭旧的sink并创建新的
await _sink?.flush();
await _sink?.close();
_filePath = path;
_sink = File(_filePath!).openWrite(
mode: FileMode.writeOnlyAppend,
encoding: utf8,
);
});
} catch (e, stack) {
print("初始化日志错误error:|$e|stack:|$stack|");
}
_timer = Timer.periodic(const Duration(seconds: 60 * 60 * 2),
(Timer timer) async {
final path = await AppFileTool.getLoggerBackupPath();
if (path == null) return;
_filePath = path;
});
}
@override
@@ -51,15 +62,19 @@ class ConsoleOutput extends LogOutput {
@override
void output(OutputEvent event) {
if (AppSysTool.isDev()) {
for (final v in event.lines) {
print(v);
try {
if (AppSysTool.isDev()) {
for (final v in event.lines) {
print(v);
}
} else {
if (_filePath == null) return;
if (_sink == null) return;
if (Level.debug == event.level) return;
_sink?.writeAll(event.lines, '\n');
}
} else {
if (_filePath == null) return;
if (_sink == null) return;
if (Level.debug == event.level) return;
_sink?.writeAll(event.lines, '\n');
} catch (e, stack) {
print("写入日志错误error:|$e|stack:|$stack|");
}
}
}
+4 -2
View File
@@ -106,8 +106,10 @@ class MqManager {
if (ObjectUtil.isEmpty(mqttClient)) {
await initMqtt();
} else if (MqManager.state != MqttConnectionState.connected) {
final res =
await mqttClient!.connect(config!.mqUsername, config.mqPassword);
final res = await mqttClient!.connect(
config!.mqUsername,
config.mqPassword,
);
if (res != null && res.state != MqManager.state) {
MqManager.state = res.state;
}
+3 -4
View File
@@ -17,12 +17,11 @@ abstract class SyncConfigTool {
if (ObjectUtil.isEmpty(sysSetting.serviceId)) return;
final serviceId = sysSetting.serviceId;
final pa = {"id": serviceId};
final res = await HardApi.get(pa);
if (res.code != 0) {
logger.e("|$_tag|同步设备信息错误serviceId:|$serviceId|;res:$res;");
final data = await HardApi.get(pa);
if (data == null) {
logger.e("|$_tag|同步设备信息错误serviceId:|$serviceId|;");
return;
}
final data = res.data as ServiceHardware;
// 基本信息
await AppSettingTool.updateSysInfoByService(data);
// 人脸sdk
+2 -3
View File
@@ -62,9 +62,8 @@ abstract class SyncOrderTool {
};
logger.i("|$_tag|同步参数:|$pa|");
try {
final res = await HardApi.syncOfflineOrder(pa);
if (res.code != 0 || res.data == null) throw Error();
final data = res.data as List<dynamic>;
final data = await HardApi.syncOfflineOrder(pa);
if (data == null) throw Error();
final batchEditCount = await handEditOfflineStatus(data);
logger.i("|$_tag|同步成功的数量为:|$batchEditCount|ids为:|$data|");
} catch (e) {
@@ -298,13 +298,10 @@ mixin OrderMixin {
logger.i("|$_tag|创建api订单,下单参数:|${json.encode(pa)}|");
try {
if (isNetwork) {
final res = await HardApi.createHardwareOrder(pa);
if (res.code != 0) {
throw Error();
}
final data = res.data;
final data = await HardApi.createHardwareOrder(pa);
if (data == null) throw Error();
if (ObjectUtil.isEmpty(data)) throw Error();
logger.i("|$_tag||有网络|创建api订单,下单成功res:|${res.toJson()}|");
logger.i("|$_tag||有网络|创建api订单,下单成功res:|$data|");
sqlOrderDetail.status = OrderStatus.pay;
sqlOrderDetail.serviceUniqueCode = data.toString();
} else {
@@ -198,11 +198,9 @@ class SelectPayTypeDialogController extends GetxController {
"id": qrCode.userId,
"type": appSetting.sysType.name,
};
final res = await HardApi.getUserInfoById(pa);
if (res.code != 0) {
throw Error();
}
payUser.value = res.data;
final data = await HardApi.getUserInfoById(pa);
if (data != null) throw Error();
payUser.value = data;
if (payUser.value != null) {
await SyncUserTool.storageUser(user: payUser.value!);
}
@@ -248,15 +246,15 @@ class SelectPayTypeDialogController extends GetxController {
final isNetwork = AppNetworkTool.isAutoNetwork();
if (isNetwork) {
final pa = {"card": card};
final res = await HardApi.getUserByCard(pa);
if (res.code != 0 || res.data == null) {
final data = await HardApi.getUserByCard(pa);
if (data == null) {
logger.e("|$_tag|饭卡识别,无效的饭卡cardId:|$card|");
isRecognition.value = false;
app.serialCardManage.close();
Toast.error(msg: "查询不到此用户");
return;
}
payUser.value = res.data;
payUser.value = data;
if (payUser.value != null) {
await SyncUserTool.storageUser(user: payUser.value!);
}
@@ -357,11 +355,9 @@ class SelectPayTypeDialogController extends GetxController {
"id": event.userId,
"type": appSetting.sysType.name,
};
final res = await HardApi.getUserInfoById(pa);
if (res.code != 0) {
throw Error();
}
payUser.value = res.data;
final data = await HardApi.getUserInfoById(pa);
if (data == null) throw Error();
payUser.value = data;
logger.i("|_tag|人脸识别|有网络|,用户信息:|${payUser.toJson()}|");
if (payUser.value != null) {
await SyncUserTool.storageUser(user: payUser.value!);
+2
View File
@@ -16,9 +16,11 @@ void main() async {
Future<void> checkSubScreen() async {
switch (window.defaultRouteName) {
case "/":
final appTheme = Get.put(AppThemeControl());
runApp(MainApp());
final app = Get.put(AppControl());
await app.initAsync();
await appTheme.initAsync();
break;
case "subMain":
await Future(() async {
+2 -2
View File
@@ -47,6 +47,7 @@ class LoginController extends GetxController {
);
}
try {
await AppSettingTool.setUserSetting(UserSetting());
final data = await UserApi.login(pa);
if (data == null) {
if (visibleMsg) EasyLoading.dismiss();
@@ -68,10 +69,9 @@ class LoginController extends GetxController {
Get.offAndToNamed(RouteNames.panel);
_clearForm();
} catch (e) {
logger.d("|$_tag|登录错误error:|$e|");
logger.e("|$_tag|登录错误error:|$e|");
EasyLoading.dismiss();
}
Get.offAllNamed(RouteNames.panel);
}
Future<void> autoLogin() async {
+8 -2
View File
@@ -16,13 +16,19 @@ class LoginPage extends GetView<LoginController> {
List<Widget> widgets = [
SizedBox(height: 30.h),
FTextField(
label: Text('用户名'),
label: Text(
'用户名',
style: theme.typography.base,
),
controller: controller.usernameC,
hint: '请输入用户名',
),
SizedBox(height: 30.h),
FTextField.password(
label: Text('密码'),
label: Text(
'密码',
style: theme.typography.base,
),
controller: controller.passwordC,
hint: '请输入密码',
),
+2 -3
View File
@@ -195,9 +195,8 @@ class OrderHistoryController extends GetxController {
try {
final orderId = int.tryParse(v.serviceUniqueCode);
final pa = {"orderId": orderId};
final res = await HardApi.generateInvoice(pa);
if (res.code != 0) throw Error();
final data = res.data as ServiceGenerateInvoice;
final data = await HardApi.generateInvoice(pa);
if (data == null) throw Error();
if (ObjectUtil.isEmpty(data.historyId) || ObjectUtil.isEmpty(data.pic)) {
throw Error();
}
+22 -1
View File
@@ -1,4 +1,6 @@
import 'package:common_utils/common_utils.dart';
import 'package:get/get.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
class PanelController extends GetxController {
@@ -35,27 +37,36 @@ class PanelController extends GetxController {
_initData();
}
void doBtn(PanelType type) {
Future<void> doBtn(PanelType type) async {
switch (type) {
case PanelType.supermarketOrder:
if (!await _checkIsBind()) return;
Get.toNamed(RouteNames.supermarketProduct);
break;
case PanelType.canteenOrder:
if (!await _checkIsBind()) return;
Get.toNamed(RouteNames.canteenProduct);
break;
case PanelType.takeFood:
if (!await _checkIsBind()) return;
Get.toNamed(RouteNames.takeFood);
break;
case PanelType.orderHistory:
if (!await _checkIsBind()) return;
Get.toNamed(RouteNames.orderHistory);
break;
case PanelType.setting:
Get.toNamed(RouteNames.setting);
break;
case PanelType.cardActive:
if (!await _checkIsBind()) return;
Get.toNamed(RouteNames.cardActive);
break;
case PanelType.logout:
final isNetwork = AppNetworkTool.isAutoNetwork();
if (isNetwork) {
await AppSettingTool.setUserSetting(UserSetting());
}
Get.offAndToNamed(RouteNames.login);
break;
default:
@@ -63,6 +74,16 @@ class PanelController extends GetxController {
}
}
Future<bool> _checkIsBind() async {
final sysSetting = await AppSettingTool.getSysSetting();
final id = sysSetting.serviceMerchantId;
if (ObjectUtil.isEmpty(id)) {
Toast.base(msg: "请前往设置绑定设备");
return false;
}
return true;
}
Future<void> _updateMenus() async {
final sysSetting = await AppSettingTool.getSysSetting();
final sysType = sysSetting.sysType;
+10 -7
View File
@@ -35,13 +35,16 @@ class PanelPage extends GetView<PanelController> {
.toList()
.toColumn(),
),
].toColumnSpace(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
space: 20.h,
),
).center();
]
.toColumnSpace(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
space: 20.h,
)
.scrollable()
.center(),
);
}
@override
+136 -1
View File
@@ -1,11 +1,25 @@
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:forui/forui.dart';
import 'package:get/get.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
class SettingController extends GetxController {
static const String _tag = "设置 Controller";
final appC = Get.find<AppControl>();
Rx<SysSetting?> sysSetting = Rx(null);
Rx<UserSetting?> userSetting = Rx(null);
var globalFontSizeC = FRadioSelectGroupController<String>(
value: SettingGlobalFontSize.xl3.code,
);
_initData() {
update(["setting"]);
getSetting();
}
RxList<SettingMenu> menuList = <SettingMenu>[
@@ -43,7 +57,18 @@ class SettingController extends GetxController {
Rx<SettingMenuType> cuurentMenuType = SettingMenuType.baseInfo.obs;
void onTap() {}
@override
void onInit() async {
super.onInit();
globalFontSizeC.addValueListener((v) {
final fontSizeType = SettingGlobalFontSize.values.fromCode(
v.first,
);
if (fontSizeType == null) return;
final appTheme = Get.find<AppThemeControl>();
appTheme.setSizeScalar(fontSizeType);
});
}
@override
void onReady() {
@@ -51,6 +76,12 @@ class SettingController extends GetxController {
_initData();
}
@override
void onClose() {
super.onClose();
globalFontSizeC.dispose();
}
void doMenu(SettingMenu v) {
if (v.type == cuurentMenuType.value) {
return;
@@ -58,4 +89,108 @@ class SettingController extends GetxController {
cuurentMenuType.value = v.type;
menuList.refresh();
}
// 同步设置
void syncConfig() async {
final isNetwork = AppNetworkTool.isAutoNetworkMsg();
if (!isNetwork) return;
EasyLoading.show(
status: '同步中...',
maskType: EasyLoadingMaskType.black,
);
try {
await SyncConfigTool.autoSyncSysInfo();
Toast.success(msg: "同步设备信息成功");
} catch (e, stack) {
Toast.error(msg: "同步设备信息错误");
logger.e("|$_tag|同步设备信息error:|$e|stack:|$stack|");
EasyLoading.dismiss();
}
}
// 重新连接长链接
void syncMq() async {
final isNetwork = AppNetworkTool.isAutoNetworkMsg();
if (!isNetwork) return;
EasyLoading.show(
status: '同步中...',
maskType: EasyLoadingMaskType.black,
);
try {
await AppMqTool.mqRefresh();
Toast.success(msg: "同步长连接成功");
} catch (e, stack) {
Toast.error(msg: "同步长连接错误");
logger.e("|$_tag|同步长连接error:|$e|stack:|$stack|");
EasyLoading.dismiss();
}
}
// 同步分类
void syncClassify() async {
final isNetwork = AppNetworkTool.isAutoNetworkMsg();
if (!isNetwork) return;
EasyLoading.show(
status: '同步中...',
maskType: EasyLoadingMaskType.black,
);
try {
await SyncProductTool.syncClassify();
Toast.success(msg: "同步分类成功");
EasyLoading.dismiss();
} catch (e, stack) {
Toast.error(msg: "同步分类错误");
logger.e("|$_tag|同步分类error:|$e|stack:|$stack|");
EasyLoading.dismiss();
}
}
// 同步商品
void syncProduct() async {
final isNetwork = AppNetworkTool.isAutoNetworkMsg();
if (!isNetwork) return;
EasyLoading.show(
status: '同步中...',
maskType: EasyLoadingMaskType.black,
);
try {
await SyncProductTool.syncProduct();
EasyLoading.dismiss();
Toast.success(msg: "同步商品成功");
EasyLoading.dismiss();
} catch (e, stack) {
Toast.error(msg: "同步商品错误");
logger.e("|$_tag|同步商品error:|$e|stack:|$stack|");
EasyLoading.dismiss();
}
}
// 同步离线订单
void syncOfflineOrder() async {
final isNetwork = AppNetworkTool.isAutoNetworkMsg();
if (!isNetwork) return;
EasyLoading.show(
status: '同步中...',
maskType: EasyLoadingMaskType.black,
);
try {
await SyncOrderTool.syncOfflineOrder();
Toast.success(msg: "同步离线订单成功");
EasyLoading.dismiss();
} catch (e) {
Toast.error(msg: "同步离线订单错误");
logger.e("|$_tag|同步离线订单error:|$e|");
EasyLoading.dismiss();
}
}
Future<void> getSetting() async {
sysSetting.value = await AppSettingTool.getSysSetting();
userSetting.value = await AppSettingTool.getUserSetting();
if (userSetting.value!.globalFontSize != null) {
globalFontSizeC = FRadioSelectGroupController(
value: SettingGlobalFontSize.xl3.code,
);
}
}
}
+42 -10
View File
@@ -7,6 +7,8 @@ import 'package:get/get.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
import '../index.dart';
Future<void> _bindServiceDialog(BuildContext context, SysSetting sys) async {
final theme = FTheme.of(context);
TextEditingController uniqueCodeC = TextEditingController();
@@ -59,6 +61,8 @@ Future<void> _bindServiceDialog(BuildContext context, SysSetting sys) async {
final flag = await AppSettingTool.bindSys(serverId!);
EasyLoading.dismiss();
if (flag) {
final settingC = Get.find<SettingController>();
await settingC.getSetting();
// 连接mq
await AppMqTool.mqRefresh();
Toast.success(msg: "绑定成功");
@@ -76,13 +80,12 @@ Future<void> _bindServiceDialog(BuildContext context, SysSetting sys) async {
}
Widget settingBaseInfo(BuildContext context) {
return FutureBuilder(
future: AppSettingTool.getSysSetting(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const SizedBox.shrink();
}
final sys = snapshot.data!;
final theme = FTheme.of(context);
return GetBuilder<SettingController>(
builder: (controller) {
return Obx(() {
final sys = controller.sysSetting.value;
if (sys == null) return const SizedBox.shrink();
return <Widget>[
appDividerTitle(context, "基本信息"),
FTile(
@@ -128,13 +131,42 @@ Widget settingBaseInfo(BuildContext context) {
onPress: () => KeywordTool.copy(sys.merchantDeptId),
),
appDividerTitle(context, "主题样式"),
FTile(
FSelectMenuTile(
groupController: controller.globalFontSizeC,
prefixIcon: appPrefixIcon(context, FAssets.icons.settings),
suffixIcon: appSuffixIcon(context, FAssets.icons.audioLines),
title: appPrefixTitle(context, "字体大小"),
details: appSuffixTitle(context, sys.merchantDeptId),
onPress: () => KeywordTool.copy(sys.merchantDeptId),
autoHide: true,
validator: (value) => value == null ? '请选择' : null,
menu: SettingGlobalFontSize.values.map((v) {
return FSelectTile(
title: Text(
v.title,
style: theme.typography.xl,
),
value: v.code,
);
}).toList(),
details: ListenableBuilder(
listenable: controller.globalFontSizeC,
builder: (context, _) {
final v = controller.globalFontSizeC.value.firstOrNull;
if (v == null) return const SizedBox();
final fontSizeType = SettingGlobalFontSize.values.fromCode(
v,
);
if (fontSizeType == null) return const SizedBox();
return Text(
fontSizeType.title,
style: theme.typography.base.copyWith(
color: theme.colorScheme.primary,
),
);
},
),
),
].toColumnSpace(space: 20.h);
});
},
);
}
+75 -63
View File
@@ -2,83 +2,95 @@ import 'package:common_utils/common_utils.dart';
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
import 'package:flutter/material.dart';
import 'package:forui/forui.dart';
import 'package:get/get.dart';
import 'package:pj_supermarket_cloud/common/index.dart';
import '../index.dart';
Widget settingSync(BuildContext context) {
String dateFormat(DateTime? dataTime) {
if (dataTime == null) return "";
return DateUtil.formatDate(dataTime);
}
return FutureBuilder(
future: AppSettingTool.getSysSetting(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const SizedBox.shrink();
}
final sys = snapshot.data!;
String getSyncClassifyTime() {
if (sys.sysType == SysType.canteen) {
return dateFormat(sys.canteenClassifySyncTime);
} else if (sys.sysType == SysType.supermarket) {
return dateFormat(sys.supermarketClassifySyncTime);
} else {
return "未同步";
}
}
return GetBuilder<SettingController>(builder: (controller) {
return Obx(() {
final sys = controller.sysSetting.value;
if (sys == null) return const SizedBox.shrink();
String getSyncProductTime() {
if (sys.sysType == SysType.canteen) {
return dateFormat(sys.canteenProductSyncTime);
} else if (sys.sysType == SysType.supermarket) {
return dateFormat(sys.supermarketProductSyncTime);
} else {
return "未同步";
}
String getSyncClassifyTime() {
if (sys.sysType == SysType.canteen) {
return dateFormat(sys.canteenClassifySyncTime);
} else if (sys.sysType == SysType.supermarket) {
return dateFormat(sys.supermarketClassifySyncTime);
} else {
return "未同步";
}
}
return <Widget>[
FTile(
prefixIcon: appPrefixIcon(context, FAssets.icons.settings),
suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw),
title: appPrefixTitle(context, "同步设备信息"),
details: appSuffixTitle(
context,
"最后同步时间:${dateFormat(sys.syncTime)}",
),
onPress: () => KeywordTool.copy(dateFormat(sys.syncTime)),
String getSyncProductTime() {
if (sys.sysType == SysType.canteen) {
return dateFormat(sys.canteenProductSyncTime);
} else if (sys.sysType == SysType.supermarket) {
return dateFormat(sys.supermarketProductSyncTime);
} else {
return "未同步";
}
}
return <Widget>[
FTile(
prefixIcon: appPrefixIcon(context, FAssets.icons.settings),
suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw),
title: appPrefixTitle(context, "同步设备信息"),
details: appSuffixTitle(
context,
"最后同步时间:${dateFormat(sys.syncTime)}",
),
FTile(
prefixIcon: appPrefixIcon(context, FAssets.icons.settings),
suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw),
title: appPrefixTitle(context, "同步长链接"),
details: appSuffixTitle(
context,
"最后同步时间:${dateFormat(sys.mqSyncTime)}",
),
onPress: () => KeywordTool.copy(dateFormat(sys.syncTime)),
onPress: () => controller.syncConfig(),
),
FTile(
prefixIcon: appPrefixIcon(context, FAssets.icons.settings),
suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw),
title: appPrefixTitle(context, "同步长链接"),
details: appSuffixTitle(
context,
"最后同步时间:${dateFormat(sys.mqSyncTime)}",
),
FTile(
prefixIcon: appPrefixIcon(context, FAssets.icons.settings),
suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw),
title: appPrefixTitle(context, "同步分类"),
details: appSuffixTitle(
context,
"最后同步时间:${getSyncClassifyTime()}",
),
onPress: () => KeywordTool.copy(dateFormat(sys.syncTime)),
onPress: () => controller.syncMq(),
),
FTile(
prefixIcon: appPrefixIcon(context, FAssets.icons.settings),
suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw),
title: appPrefixTitle(context, "同步分类"),
details: appSuffixTitle(
context,
"最后同步时间:${getSyncClassifyTime()}",
),
FTile(
prefixIcon: appPrefixIcon(context, FAssets.icons.settings),
suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw),
title: appPrefixTitle(context, "同步商品"),
details: appSuffixTitle(
context,
"最后同步时间:${getSyncProductTime()}",
),
onPress: () => KeywordTool.copy(dateFormat(sys.syncTime)),
onPress: () => controller.syncClassify(),
),
FTile(
prefixIcon: appPrefixIcon(context, FAssets.icons.settings),
suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw),
title: appPrefixTitle(context, "同步商品"),
details: appSuffixTitle(
context,
"最后同步时间:${getSyncProductTime()}",
),
].toColumnSpace(space: 20.h);
});
onPress: () => controller.syncProduct(),
),
FTile(
prefixIcon: appPrefixIcon(context, FAssets.icons.settings),
suffixIcon: appSuffixIcon(context, FAssets.icons.refreshCw),
title: appPrefixTitle(context, "同步离线订单"),
details: appSuffixTitle(
context,
"最后同步时间:${getSyncProductTime()}",
),
onPress: () => controller.syncOfflineOrder(),
),
].toColumnSpace(space: 20.h);
});
});
}
+2 -2
View File
@@ -166,8 +166,8 @@ class TakeFoodController extends GetxController {
status: '核销中...',
maskType: EasyLoadingMaskType.black,
);
final res = await HardApi.cancelQrCode(pa);
if (res.code != 0) throw Error();
final flag = await HardApi.cancelQrCode(pa);
if (flag == false) throw Error();
EasyLoading.dismiss();
Toast.error(msg: "核销成功");
_speeching("核销成功");
+48
View File
@@ -882,6 +882,54 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.4"
permission_handler:
dependency: "direct main"
description:
name: permission_handler
sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849"
url: "https://pub.flutter-io.cn"
source: hosted
version: "11.4.0"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc
url: "https://pub.flutter-io.cn"
source: hosted
version: "12.1.0"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
sha256: f84a188e79a35c687c132a0a0556c254747a08561e99ab933f12f6ca71ef3c98
url: "https://pub.flutter-io.cn"
source: hosted
version: "9.4.6"
permission_handler_html:
dependency: transitive
description:
name: permission_handler_html
sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.1.3+5"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.3.0"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.2.1"
petitparser:
dependency: transitive
description:
+2 -1
View File
@@ -31,7 +31,8 @@ dependencies:
# 分页
number_pagination: ^1.1.6
# 权限判断
permission_handler: ^11.4.0
# 串口
flutter_libserialport: 0.5.0
# 状态管理、路由