Commit 8ee5026f093162de44df0af6c497eea2e4805ac0

Authored by 常守达
1 parent 1016dd21

fix(today):验收修复

... ... @@ -164,6 +164,20 @@ class TodayController extends GetMaterialController {
if (!Get.find<UserStateService>().isVip) {
getProductList();
}
_healthApi.getHealthDataEverUploaded().then((data) {
switch (data) {
case AppSuccess(:final data):
if (data.startTime != null && data.startTime! > 0) {
final firstDayTime = DateUtils.dateOnly(
DateTime.fromMillisecondsSinceEpoch(data.startTime! * 1000),
);
if (firstDayTime.isBefore(firstSelectableDay.value)) {
firstSelectableDay.value = firstDayTime;
}
}
case AppFailure():
}
});
}
Future<void> checkHrvAdBannerVisible() async {
... ... @@ -298,14 +312,13 @@ class TodayController extends GetMaterialController {
if (showHealthDataAuthCardStatus.value == 1) {
return;
} else if (showHealthDataAuthCardStatus.value == 0) {
await Get.to(NoHealthDataNoPermissionPage(
onRequest: () =>
requestHealthAuthorization(isFromNoPermissionPage: true),
));
await requestHealthAuthorization(isFromNoPermissionPage: true);
checkHealthDataAuthCardVisible();
} else {
await Get.to(NoHealthDataPage(
onRefresh: requestHealthAuthorization,
onRefresh: () {
refreshTab();
},
onHelp: () {
Get.toNamed(Routes.HELP);
},
... ... @@ -332,36 +345,17 @@ class TodayController extends GetMaterialController {
if (result.status == 1) {
_calculateHealthDataWithoutLoading(
uploaded: () async {
await checkUploadedStatus(firstTime, result);
showHealthDataAuthCardStatus.value = result.status;
},
);
} else {
unawaited(loadDataForDate(selectedDate.value));
await checkUploadedStatus(firstTime, result);
showHealthDataAuthCardStatus.value = result.status;
}
} catch (e) {}
}
}
Future<void> checkUploadedStatus(
DateTime firstTime, HealthAuthorization result) async {
bool hasUploaded = false;
switch (await _healthApi.getHealthDataEverUploaded()) {
case AppSuccess(:final data):
hasUploaded = data.flag ?? false;
if (hasUploaded && data.startTime != null && data.startTime! > 0) {
final firstDayTime = DateUtils.dateOnly(
DateTime.fromMillisecondsSinceEpoch(data.startTime! * 1000),
);
if (firstDayTime.isBefore(firstTime)) {
firstSelectableDay.value = firstDayTime;
}
}
case AppFailure():
}
showHealthDataAuthCardStatus.value = !hasUploaded ? -1 : result.status;
}
void _calculateHealthDataWithoutLoading({VoidCallback? uploaded}) {
unawaited(
(() async {
... ...
... ... @@ -544,12 +544,9 @@ class _LatestHrvCard extends StatelessWidget {
final state = controller.v2LatestHrv.value?.state;
final stateStr = controller.v2LatestHrv.value?.stateString();
final stateColor = controller.v2LatestHrv.value?.stateColor(context);
final tip = controller.v2LatestHrv.value?.tip;
final tip = controller.v2LatestHrv.value?.tip ?? '';
if (latestHrv == null ||
latestDataTime == null ||
state == null ||
tip == null) {
if (latestHrv == null || latestDataTime == null || state == null) {
return const SizedBox.shrink();
}
... ...
... ... @@ -383,7 +383,8 @@ class TodayHrvChartCard extends StatelessWidget {
text: isWorkout == true ? '◉ ' : '○ ',
style: TextStyle(
fontSize: 14,
color: _getColorByState(state),
color:
isWorkout == true ? Color(0xFF78787D) : _getColorByState(state),
fontWeight: FontWeight.bold,
inherit: false,
fontFamilyFallback: null,
... ... @@ -396,7 +397,9 @@ class TodayHrvChartCard extends StatelessWidget {
: '${_getStatusByState(state)} ${_formatNumber(rod.toY)}%',
style: TextStyle(
fontSize: 18,
color: _getColorByState(state),
color: isWorkout == true
? const Color(0xFF78787D)
: _getColorByState(state),
fontWeight: FontWeight.bold,
),
),
... ... @@ -1144,7 +1147,7 @@ class _StressBarChartState extends State<_StressBarChart> {
),
if (customIndicator != null)
customIndicator, // 将指示线移动到 Container (BarChart) 之后绘制,防止被盖住
...sleepWidgets,
if (widget.stressPoints.isNotEmpty) ...sleepWidgets,
// 手绘 100、50、0 标签在对应的横线上方
Positioned(
right: -5,
... ... @@ -1185,15 +1188,15 @@ class _StressBarChartState extends State<_StressBarChart> {
const slotSec = 6 * 60; // 360 秒 = 6 分钟
final maxSec = widget.maxSeconds.round();
// 按槽分组,记录每槽的最大 value 及对应的 state
final slotMax = <int, ({int value, int? state})>{};
// 按槽分组,记录每槽的最大 value 及对应的 state / isWorkout
final slotMax = <int, ({int value, int? state, int? isWorkout})>{};
for (final p in stressPoints) {
final sec = TodayHrvChartCard._tsToSecondsFromMidnight(p.time).round();
final slot = (sec / slotSec).round() * slotSec;
final v = p.value ?? 0;
final existing = slotMax[slot];
if (existing == null || v > existing.value) {
slotMax[slot] = (value: v, state: p.state);
slotMax[slot] = (value: v, state: p.state, isWorkout: p.isWorkout);
}
}
... ... @@ -1211,7 +1214,9 @@ class _StressBarChartState extends State<_StressBarChart> {
toY: entry != null ? entry.value.toDouble() : 0,
width: barWidth,
color: entry != null
? widget.getColorByState(entry.state)
? (entry.isWorkout == 1
? const Color(0xFF78787D)
: widget.getColorByState(entry.state))
: Colors.transparent,
borderRadius: BorderRadius.circular(barWidth / 2),
),
... ...
... ... @@ -118,9 +118,6 @@ class LoginController extends GetxController {
@override
void onInit() {
super.onInit();
LocalStorage.open().then((local) {
termsChecked.value = local.termsAgreed;
});
phoneController.addListener(() {
phoneInput.value = phoneController.text;
... ... @@ -147,6 +144,7 @@ class LoginController extends GetxController {
} else {
needTrackWelcomepage = true;
}
termsChecked.value = Get.find<LocalStorage>().termsAgreed;
}
bool needTrackWelcomepage = false;
... ...