diff --git a/lib/common/api/user_api.dart b/lib/common/api/user_api.dart index 3c3e20c..2078418 100644 --- a/lib/common/api/user_api.dart +++ b/lib/common/api/user_api.dart @@ -56,4 +56,13 @@ abstract class UserApi { ?.map((e) => ServiceAsyncFace.fromJson(e)) .toList(); } + + /// 获取租户列表 + static Future?> getTenantList() async { + final res = await HttpManage().dio.get("/admin/tenant/list"); + if (res.data == null) return null; + return res.data + ?.map((e) => ServiceTenant.fromJson(e)) + .toList(); + } } diff --git a/lib/common/models/api/user_api_models.dart b/lib/common/models/api/user_api_models.dart index c044cf9..a096908 100644 --- a/lib/common/models/api/user_api_models.dart +++ b/lib/common/models/api/user_api_models.dart @@ -126,3 +126,32 @@ class ServiceAsyncFace { Map toJson() => _$ServiceAsyncFaceToJson(this); } + +@JsonSerializable() +class ServiceTenant { + /// id + final String? id; + + /// 编号 + final String? code; + + /// 编号 + final String? name; + + final String? menuId; + + final String? miniQr; + + ServiceTenant({ + this.id, + this.code, + this.name, + this.menuId, + this.miniQr, + }); + + factory ServiceTenant.fromJson(Map json) => + _$ServiceTenantFromJson(json); + + Map toJson() => _$ServiceTenantToJson(this); +} diff --git a/lib/common/models/api/user_api_models.g.dart b/lib/common/models/api/user_api_models.g.dart index 7241d4f..03aaed4 100644 --- a/lib/common/models/api/user_api_models.g.dart +++ b/lib/common/models/api/user_api_models.g.dart @@ -72,3 +72,21 @@ Map _$ServiceAsyncFaceToJson(ServiceAsyncFace instance) => 'deptId': instance.deptId, 'deptName': instance.deptName, }; + +ServiceTenant _$ServiceTenantFromJson(Map json) => + ServiceTenant( + id: json['id'] as String?, + code: json['code'] as String?, + name: json['name'] as String?, + menuId: json['menuId'] as String?, + miniQr: json['miniQr'] as String?, + ); + +Map _$ServiceTenantToJson(ServiceTenant instance) => + { + 'id': instance.id, + 'code': instance.code, + 'name': instance.name, + 'menuId': instance.menuId, + 'miniQr': instance.miniQr, + }; diff --git a/lib/common/models/database/database_models.dart b/lib/common/models/database/database_models.dart index 3a4e9aa..4908bcc 100644 --- a/lib/common/models/database/database_models.dart +++ b/lib/common/models/database/database_models.dart @@ -180,6 +180,9 @@ class UserSetting extends Equatable { /// end 服务端信息 end + /// 租户id + String? tenantId; + UserSetting({ this.username, this.password, @@ -199,6 +202,7 @@ class UserSetting extends Equatable { accessToken, refreshToken, expiresTime, + tenantId, ]; } diff --git a/lib/common/models/database/database_models.g.dart b/lib/common/models/database/database_models.g.dart index 4f112a5..df44938 100644 --- a/lib/common/models/database/database_models.g.dart +++ b/lib/common/models/database/database_models.g.dart @@ -136,7 +136,8 @@ UserSetting _$UserSettingFromJson(Map json) => UserSetting( ..userId = (json['userId'] as num?)?.toInt() ..accessToken = json['accessToken'] as String? ..refreshToken = json['refreshToken'] as String? - ..expiresTime = (json['expiresTime'] as num?)?.toInt(); + ..expiresTime = (json['expiresTime'] as num?)?.toInt() + ..tenantId = json['tenantId'] as String?; Map _$UserSettingToJson(UserSetting instance) => { @@ -147,6 +148,7 @@ Map _$UserSettingToJson(UserSetting instance) => 'accessToken': instance.accessToken, 'refreshToken': instance.refreshToken, 'expiresTime': instance.expiresTime, + 'tenantId': instance.tenantId, }; CanteenExtraPriceSetting _$CanteenExtraPriceSettingFromJson( diff --git a/lib/common/utils/app/app_setting_tool.dart b/lib/common/utils/app/app_setting_tool.dart index dc1bf3d..969d2f7 100644 --- a/lib/common/utils/app/app_setting_tool.dart +++ b/lib/common/utils/app/app_setting_tool.dart @@ -125,6 +125,10 @@ abstract class AppSettingTool { static Future setUserSetting(UserSetting userInfo) async { final globalUserInfo = await getUserSetting(); if (globalUserInfo == userInfo) return; + if (ObjectUtil.isEmpty(userInfo.tenantId) && + ObjectUtil.isNotEmpty(globalUserInfo.tenantId)) { + userInfo.tenantId = globalUserInfo.tenantId; + } await _setSetting(userJson: userInfo); } diff --git a/lib/common/utils/manage/http_manage.dart b/lib/common/utils/manage/http_manage.dart index 89c658d..c980105 100644 --- a/lib/common/utils/manage/http_manage.dart +++ b/lib/common/utils/manage/http_manage.dart @@ -30,14 +30,14 @@ class HttpManage { InterceptorsWrapper( onRequest: (RequestOptions options, handler) async { options.headers["CLIENT-TOC"] = "Y"; - options.headers["TENANT-ID"] = 1; + final userInfo = await AppSettingTool.getUserSetting(); if (!options.path.contains(Constants.oauth2AppApiUrl)) { - final userInfo = await AppSettingTool.getUserSetting(); if (ObjectUtil.isNotEmpty(userInfo.accessToken)) { options.headers['Authorization'] = "Bearer ${userInfo.accessToken}"; } } + options.headers["TENANT-ID"] = userInfo.tenantId ?? 1; return handler.next(options); }, onResponse: (e, handler) async { diff --git a/lib/common/values/constants.dart b/lib/common/values/constants.dart index 3c148e5..1a7449b 100644 --- a/lib/common/values/constants.dart +++ b/lib/common/values/constants.dart @@ -12,7 +12,7 @@ class Constants { /// 服务 url // static const apiUrl = 'https://stgl.pj.gov.cn/api'; - static const apiUrl = 'http://192.168.101.81:9999'; + static const apiUrl = 'http://192.168.101.107:9999'; /// 静态资源 url static const ossUrl = apiUrl; diff --git a/lib/common/widgets/index.dart b/lib/common/widgets/index.dart index 7abccd9..f597cf0 100644 --- a/lib/common/widgets/index.dart +++ b/lib/common/widgets/index.dart @@ -29,3 +29,4 @@ export './order/order_supermarket_common.dart'; export './setting/setting_password_dialog.dart'; export './user/user_info.dart'; +export './user/user_tenant_dialog.dart'; diff --git a/lib/common/widgets/user/user_tenant_dialog.dart b/lib/common/widgets/user/user_tenant_dialog.dart new file mode 100644 index 0000000..7fd0804 --- /dev/null +++ b/lib/common/widgets/user/user_tenant_dialog.dart @@ -0,0 +1,50 @@ +import 'package:common_utils/common_utils.dart'; +import 'package:flutter/material.dart'; +import 'package:forui/forui.dart'; + +import 'package:pj_supermarket_cloud/common/index.dart'; + +Widget appTenantDialog( + BuildContext context, + FRadioSelectGroupController controller, { + required List list, +}) { + final theme = FTheme.of(context); + final selectList = list.where((v) => ObjectUtil.isNotEmpty(v.code)); + return FSelectMenuTile( + title: Text( + "单位", + style: theme.typography.base, + ), + groupController: controller, + validator: (value) => value == null ? '请选择' : null, + autoHide: true, + prefixIcon: FIcon( + FAssets.icons.building2, + size: theme.typography.xl.fontSize, + ), + menu: selectList.map((v) { + return FSelectTile( + title: Text( + v.name!, + style: theme.typography.base, + ), + value: v.code!, + ); + }).toList(), + details: ListenableBuilder( + listenable: controller, + builder: (context, _) { + final v = controller.value.firstOrNull; + if (v == null) return const SizedBox(); + final target = selectList.firstWhere((i) => i.code == v); + return Text( + target.name!, + style: theme.typography.base.copyWith( + color: theme.colorScheme.primary, + ), + ); + }, + ), + ); +} diff --git a/lib/pages/login/controller.dart b/lib/pages/login/controller.dart index 130831d..5e9bc93 100644 --- a/lib/pages/login/controller.dart +++ b/lib/pages/login/controller.dart @@ -1,6 +1,7 @@ import 'package:common_utils/common_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:forui/forui.dart'; import 'package:get/get.dart'; @@ -11,8 +12,16 @@ class LoginController extends GetxController { late SysSetting sysSetting; + late UserSetting userSetting; + Rx sysType = SysType.CANTEEN.obs; + RxList tenantList = [].obs; + + final tenantC = FRadioSelectGroupController(); + + ServiceTenant currentTenant = ServiceTenant(); + // 用户名 final usernameC = TextEditingController(); // 密码 @@ -26,8 +35,22 @@ class LoginController extends GetxController { void onInit() async { super.onInit(); sysSetting = await AppSettingTool.getSysSetting(); + userSetting = await AppSettingTool.getUserSetting(); sysType.value = sysSetting.sysType; + await getTenantList(); await autoLogin(); + tenantC.addValueListener((v) async { + final target = tenantList.firstWhereOrNull((i) => i.code == v.first); + if (target == null) return; + EasyLoading.show( + status: '切换中...', + maskType: EasyLoadingMaskType.black, + ); + currentTenant = target; + userSetting.tenantId = target.id; + await AppSettingTool.setUserSetting(userSetting); + EasyLoading.dismiss(); + }); } @override @@ -59,7 +82,6 @@ class LoginController extends GetxController { if (visibleMsg) EasyLoading.dismiss(); return; } - final userSetting = await AppSettingTool.getUserSetting(); userSetting.userId = data['user_id']; userSetting.accessToken = data['access_token']; userSetting.refreshToken = data['refresh_token']; @@ -67,6 +89,7 @@ class LoginController extends GetxController { userSetting.sysType = sysSetting.sysType; userSetting.username = usernameC.value.text; userSetting.password = passwordC.value.text; + userSetting.tenantId = currentTenant.id; await AppSettingTool.setUserSetting(userSetting); if (visibleMsg) { Toast.success(msg: "登录成功"); @@ -82,7 +105,6 @@ class LoginController extends GetxController { } Future autoLogin() async { - final userSetting = await AppSettingTool.getUserSetting(); if (ObjectUtil.isEmpty(userSetting.username) || ObjectUtil.isEmpty(userSetting.password) || ObjectUtil.isEmpty(userSetting.sysType?.name)) { @@ -122,6 +144,23 @@ class LoginController extends GetxController { return true; } + Future getTenantList() async { + try { + final list = await UserApi.getTenantList(); + if (list == null) return; + tenantList.value = list; + if (ObjectUtil.isNotEmpty(userSetting.tenantId)) { + tenantC.value = {list.first.code!}; + } else { + if (!ObjectUtil.isEmptyList(list)) { + tenantC.value = {list.first.code!}; + } + } + } catch (e) { + logger.e("|$_tag|获取租户列表错误error:|$e|"); + } + } + void _clearForm() { usernameC.clear(); passwordC.clear(); diff --git a/lib/pages/login/view.dart b/lib/pages/login/view.dart index 3d7a074..9a65e73 100644 --- a/lib/pages/login/view.dart +++ b/lib/pages/login/view.dart @@ -13,14 +13,23 @@ class LoginPage extends GetView { // 主视图 Widget _buildView() { final theme = FTheme.of(Get.context!); + final context = Get.context!; return SizedBox( - width: Get.context!.sizes.width * 0.3, + width: context.sizes.width * 0.3, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ FCard( title: appLogo(), child: [ + SizedBox(height: 30.h), + Obx( + () => appTenantDialog( + context, + controller.tenantC, + list: controller.tenantList, + ), + ), SizedBox(height: 30.h), Obx( () => FTextField( diff --git a/lib/pages/setting/widgets/setting_baseInfo.dart b/lib/pages/setting/widgets/setting_baseInfo.dart index cd40439..e8c9d90 100644 --- a/lib/pages/setting/widgets/setting_baseInfo.dart +++ b/lib/pages/setting/widgets/setting_baseInfo.dart @@ -21,7 +21,9 @@ Future _bindServiceDialog(BuildContext context, SysSetting sys) async { // 正式环境-测试 // uniqueCodeC.text = "1896157295523049473"; // 测试环境-测试设备 - uniqueCodeC.text = "1877592554489143298"; + // uniqueCodeC.text = "1877592554489143298"; + // 测试环境-食堂-浦阳 + uniqueCodeC.text = "1914567628657778690"; } await showAdaptiveDialog( context: context,