diff --git a/ln_jq_app/ios/Runner.xcodeproj/project.pbxproj b/ln_jq_app/ios/Runner.xcodeproj/project.pbxproj index 57618c8..bda3fee 100644 --- a/ln_jq_app/ios/Runner.xcodeproj/project.pbxproj +++ b/ln_jq_app/ios/Runner.xcodeproj/project.pbxproj @@ -294,14 +294,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; @@ -374,14 +370,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; diff --git a/ln_jq_app/lib/common/token_interceptor.dart b/ln_jq_app/lib/common/token_interceptor.dart new file mode 100644 index 0000000..81a3d7b --- /dev/null +++ b/ln_jq_app/lib/common/token_interceptor.dart @@ -0,0 +1,30 @@ +import 'package:dio/dio.dart'; +import 'package:ln_jq_app/storage_service.dart'; + +/// 专门用于处理和添加 Token 的拦截器 +class TokenInterceptor extends Interceptor { + // 定义您想要使用的 Token Key + final String tokenKey; + + // 构造函数,允许外部传入自定义的 Key,默认为 'Authorization' + TokenInterceptor({this.tokenKey = 'Authorization'}); + + @override + void onRequest(RequestOptions options, RequestInterceptorHandler handler) { + // 从 StorageService 中获取已保存的 token + final String? token = StorageService.to.token; + + // 如果 token 存在,就添加到请求头中 + if (token != null && token.isNotEmpty) { + // 检查请求头中是否已存在这个key,避免重复添加 + if (!options.headers.containsKey(tokenKey)) { + // 使用我们自定义的 key 添加 token + options.headers[tokenKey] = token; + } + } + + // 调用 handler.next(options) 以继续执行请求 + // 这一步至关重要,否则请求会被中断 + super.onRequest(options, handler); + } +} diff --git a/ln_jq_app/lib/main.dart b/ln_jq_app/lib/main.dart index a05d269..b438392 100644 --- a/ln_jq_app/lib/main.dart +++ b/ln_jq_app/lib/main.dart @@ -2,6 +2,7 @@ import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:get_storage/get_storage.dart'; import 'package:getx_scaffold/getx_scaffold.dart'; import 'package:ln_jq_app/common/model/base_model.dart'; +import 'package:ln_jq_app/common/token_interceptor.dart'; import 'package:ln_jq_app/storage_service.dart'; import 'common/styles/theme.dart'; @@ -52,7 +53,10 @@ void main() async { void initHttpSet() { // 设置基础 URL HttpService.to.setBaseUrl(AppTheme.test_service_url); - + //指定请求头 + HttpService.to.dio.interceptors.add( + TokenInterceptor(tokenKey: 'asoco-token'), + ); // 设置全局响应处理器 HttpService.to.setOnResponseHandler((response) async { try { diff --git a/ln_jq_app/lib/pages/b_page/reservation/controller.dart b/ln_jq_app/lib/pages/b_page/reservation/controller.dart index f73b99d..2a147d0 100644 --- a/ln_jq_app/lib/pages/b_page/reservation/controller.dart +++ b/ln_jq_app/lib/pages/b_page/reservation/controller.dart @@ -1,5 +1,6 @@ import 'package:get/get.dart'; import 'package:getx_scaffold/getx_scaffold.dart'; +import 'package:ln_jq_app/common/model/base_model.dart'; import 'package:ln_jq_app/pages/login/view.dart'; import '../../../storage_service.dart'; @@ -13,7 +14,7 @@ class ReservationController extends GetxController with BaseControllerMixin { final List operationStatusOptions = ['营运中', '维修中', '暂停营业', '站点关闭']; // 当前选中的值,默认为'运营中' - late String selectedOperationStatus; + String selectedOperationStatus = ""; ReservationController() { selectedOperationStatus = operationStatusOptions[0]; // 初始化选中值 @@ -26,14 +27,68 @@ class ReservationController extends GetxController with BaseControllerMixin { renderData(); } + String name = ""; + String address = ""; + String phone = ""; + String costPrice = ""; //氢气价格 + String customerPrice = ""; //官方价格 + String startBusiness = ""; + String endBusiness = ""; + String timeStr = ""; + String operatingEnterprise = ""; + String hydrogenId = ""; + Future renderData() async { showLoading("加载中"); - // 模拟网络请求延迟 - await Future.delayed(const Duration(seconds: 1)); + try { + var responseData = await HttpService.to.get( + 'appointment/station/getStationInfoById?hydrogenId=${StorageService.to.userId}', + ); - dismissLoading(); - updateUi(); + if (responseData == null && responseData!.data == null) { + dismissLoading(); + showToast('暂时无法获取站点信息'); + return; + } + + try { + var result = BaseModel.fromJson(responseData.data); + + name = result.data["name"]; + hydrogenId = result.data["hydrogenId"].toString(); + address = result.data["address"]; + costPrice = result.data["costPrice"].toString(); + customerPrice = result.data["customerPrice"].toString(); + phone = result.data["phone"]; + startBusiness = result.data["startBusiness"]; + endBusiness = result.data["endBusiness"]; + operatingEnterprise = result.data["operatingEnterprise"].toString(); + selectedOperationStatus = result.data["siteStatusName"].toString(); + + if (startBusiness.isNotEmpty && endBusiness.isNotEmpty) { + // 营业时间为24小时的特殊处理 + if (startBusiness == "00:00:00" && endBusiness == "23:59:59") { + timeStr = "24小时营业"; + } else { + timeStr = '${startBusiness.substring(0, 5)} - ${endBusiness.substring(0, 5)}'; + } + } else { + timeStr = "时间未设置"; + } + + operatingEnterprise = operatingEnterprise.isEmpty ? "暂未设置" : operatingEnterprise; + + updateUi(); + dismissLoading(); + } catch (e) { + // 如果解析 JSON 失败 + dismissLoading(); + showToast('数据异常'); + } + } catch (e) { + dismissLoading(); + } } /// 更新运营状态的方法 @@ -44,18 +99,45 @@ class ReservationController extends GetxController with BaseControllerMixin { } } - void saveInfo() { - // TODO: 在这里执行保存信息的逻辑 - // 1. 获取所有输入框和下拉框的最新值 - // 2. 调用API接口,将数据提交到服务器 - // 3. 根据接口返回结果给出提示(成功或失败) - Get.snackbar('提示', '保存成功!'); // 示例:显示一个成功的提示 + void saveInfo() async { + showLoading("保存中"); + + try { + var responseData = await HttpService.to.post( + 'appointment/station/updateStationStatus', + data: { + 'hydrogenId': hydrogenId, + 'siteStatus': selectedOperationStatus == "营运中" + ? "0" + : selectedOperationStatus == "维修中" + ? "1" + : selectedOperationStatus == "站点关闭" + ? "2" + : selectedOperationStatus == "暂停营业" + ? "3" + : 0, + 'updateTime': getNowDateTimeString(), + }, + ); + + if (responseData == null && responseData!.data == null) { + dismissLoading(); + showToast('服务暂不可用,请稍后'); + return; + } + var result = BaseModel.fromJson(responseData.data); + if (result.code == 0) { + showSuccessToast("保存成功"); + } + dismissLoading(); + } catch (e) { + dismissLoading(); + } } - void logout() async{ + void logout() async { // TODO: 在这里执行退出登录的逻辑 //清理本地缓存的用户信息 导航到登录页面 - HttpService.to.clearAuthorization(); await StorageService.to.clearLoginInfo(); Get.offAll(() => LoginPage()); diff --git a/ln_jq_app/lib/pages/b_page/reservation/view.dart b/ln_jq_app/lib/pages/b_page/reservation/view.dart index bbb7204..6320af6 100644 --- a/ln_jq_app/lib/pages/b_page/reservation/view.dart +++ b/ln_jq_app/lib/pages/b_page/reservation/view.dart @@ -44,15 +44,25 @@ class ReservationPage extends GetView { children: [ ListTile( leading: const Icon(Icons.local_gas_station, color: Colors.blue, size: 40), - title: const Text('H2加氢站', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)), - subtitle: const Text('上海市浦东新区张江高科技园区'), + title: Text( + controller.name, + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18), + ), + subtitle: Text(controller.address), trailing: Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: Colors.blue[100], borderRadius: BorderRadius.circular(12), ), - child: const Text('运营中', style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold, fontSize: 12)), + child: Text( + controller.selectedOperationStatus, + style: TextStyle( + color: Colors.blue, + fontWeight: FontWeight.bold, + fontSize: 12, + ), + ), ), ), const Divider(height: 1, indent: 16, endIndent: 16), @@ -61,8 +71,8 @@ class ReservationPage extends GetView { child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - _buildHeaderStat('¥45', '氢气价格'), - _buildHeaderStat('24h', '营业时间'), + _buildHeaderStat('¥${controller.costPrice}', '氢气价格'), + _buildHeaderStat(controller.timeStr, '营业时间'), _buildHeaderStat('98%', '设备状态'), ], ), @@ -76,7 +86,14 @@ class ReservationPage extends GetView { Widget _buildHeaderStat(String value, String label) { return Column( children: [ - Text(value, style: const TextStyle(color: Colors.blue, fontSize: 20, fontWeight: FontWeight.bold)), + Text( + value, + style: const TextStyle( + color: Colors.blue, + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), const SizedBox(height: 4), Text(label, style: const TextStyle(color: Colors.grey, fontSize: 12)), ], @@ -95,15 +112,15 @@ class ReservationPage extends GetView { children: [ // --- 基本信息 --- _buildSectionTitle('基本信息'), - _buildDisplayField(label: '站点名称', value: 'H2加氢站'), - _buildDisplayField(label: '运营企业', value: '上海氢能科技有限公司'), - _buildDisplayField(label: '站点地址', value: '上海市浦东新区张江高科技园区'), + _buildDisplayField(label: '站点名称', value: controller.name), + _buildDisplayField(label: '运营企业', value: controller.operatingEnterprise), + _buildDisplayField(label: '站点地址', value: controller.address), const SizedBox(height: 16), // --- 价格信息 --- _buildSectionTitle('价格信息'), - _buildDisplayField(label: '氢气价格 (元/kg)', value: '45'), - _buildDisplayField(label: '官方价格 (元/kg)', value: '50'), + _buildDisplayField(label: '氢气价格 (元/kg)', value: controller.costPrice), + _buildDisplayField(label: '官方价格 (元/kg)', value: controller.customerPrice), const SizedBox(height: 16), // --- 运营信息 --- @@ -114,10 +131,7 @@ class ReservationPage extends GetView { DropdownButtonFormField( value: controller.selectedOperationStatus, items: controller.operationStatusOptions.map((String value) { - return DropdownMenuItem( - value: value, - child: Text(value), - ); + return DropdownMenuItem(value: value, child: Text(value)); }).toList(), onChanged: controller.onOperationStatusChanged, decoration: InputDecoration( @@ -126,8 +140,8 @@ class ReservationPage extends GetView { ), ), const SizedBox(height: 12), - _buildDisplayField(label: '营业时间', value: '24小时营业'), - _buildDisplayField(label: '联系电话', value: '021-12345678'), + _buildDisplayField(label: '营业时间', value: controller.timeStr), + _buildDisplayField(label: '联系电话', value: controller.phone), const SizedBox(height: 24), //保存按钮 @@ -176,7 +190,10 @@ class ReservationPage extends GetView { shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)), elevation: 2, ), - child: const Text('退出登录', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), + child: const Text( + '退出登录', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + ), ); } @@ -227,7 +244,9 @@ class ReservationPage extends GetView { children: [ Icon(icon, color: Colors.blue, size: 20), const SizedBox(width: 10), - Expanded(child: Text(text, style: const TextStyle(fontSize: 14, color: Colors.black54))), + Expanded( + child: Text(text, style: const TextStyle(fontSize: 14, color: Colors.black54)), + ), ], ); } diff --git a/ln_jq_app/lib/pages/login/view.dart b/ln_jq_app/lib/pages/login/view.dart index cd0d667..42d462c 100644 --- a/ln_jq_app/lib/pages/login/view.dart +++ b/ln_jq_app/lib/pages/login/view.dart @@ -273,14 +273,13 @@ class _LoginPageState extends State with SingleTickerProviderStateMix dismissLoading(); showToast('登录成功,欢迎您'); - HttpService.to.setAuthorization(token); // 跳转到主页,并清除所有历史页面 Get.offAll(() => B_BaseWidgetsPage()); } catch (e) { // 如果解析 JSON 失败 dismissLoading(); - showToast('登录失败:返回数据解析失败${e.toString()}'); + showToast('登录失败:数据异常'); } } catch (e) { dismissLoading();