增加作弊数据检测
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
enum DataAbnormalType {
|
||||||
|
/// 无异常
|
||||||
|
none,
|
||||||
|
|
||||||
|
/// 容量低于设计容量 60%
|
||||||
|
capacityTooLow,
|
||||||
|
|
||||||
|
/// 容量高于设计容量 115%
|
||||||
|
capacityTooHigh,
|
||||||
|
|
||||||
|
/// 电压异常(< 3.0V 或 > 5.0V)
|
||||||
|
voltageAbnormal,
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import 'package:device_info_plus/device_info_plus.dart';
|
|||||||
// --- 本地导入 ---
|
// --- 本地导入 ---
|
||||||
import '../models/device_matching.dart';
|
import '../models/device_matching.dart';
|
||||||
import '../models/saf_permission_state.dart';
|
import '../models/saf_permission_state.dart';
|
||||||
|
import '../models/data_abnormal_type.dart'; // 🆕 1.7.0
|
||||||
import '../services/database_service.dart';
|
import '../services/database_service.dart';
|
||||||
import '../services/battery_data_service.dart';
|
import '../services/battery_data_service.dart';
|
||||||
import '../services/saf_storage_service.dart';
|
import '../services/saf_storage_service.dart';
|
||||||
@@ -381,8 +382,11 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🟢 1.7.0 容量有效性校验
|
||||||
|
final validatedCap = _validateCapacity(finalCap, _designCap);
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_currentCap = (finalCap ?? _currentCap).toDouble();
|
_currentCap = (validatedCap ?? _currentCap).toDouble();
|
||||||
_cycleCount = cycle;
|
_cycleCount = cycle;
|
||||||
_batteryTemp = temp;
|
_batteryTemp = temp;
|
||||||
_batteryVolt = volt;
|
_batteryVolt = volt;
|
||||||
@@ -409,6 +413,53 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------- 🆕 1.7.0 容量有效性校验 ----------
|
||||||
|
int? _validateCapacity(int? capacity, int designCap) {
|
||||||
|
if (capacity == null) return null;
|
||||||
|
|
||||||
|
// 容量必须大于 0
|
||||||
|
if (capacity <= 0) {
|
||||||
|
dev.log('⚠️ 容量异常:<= 0,已忽略', name: 'BatteryHealth');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 容量不能低于设计容量的 60%
|
||||||
|
if (capacity < designCap * 0.6) {
|
||||||
|
dev.log(
|
||||||
|
'⚠️ 容量异常:低于设计容量 60%($capacity < ${designCap * 0.6}),已忽略',
|
||||||
|
name: 'BatteryHealth',
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 容量不能超过设计容量的 115%
|
||||||
|
if (capacity > designCap * 1.15) {
|
||||||
|
dev.log(
|
||||||
|
'⚠️ 容量异常:高于设计容量 115%($capacity > ${designCap * 1.15}),已忽略',
|
||||||
|
name: 'BatteryHealth',
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- 🆕 1.7.0 异常检测(供 UI 使用) ----------
|
||||||
|
DataAbnormalType _checkAbnormalType(
|
||||||
|
double currentCap,
|
||||||
|
int designCap,
|
||||||
|
double voltage,
|
||||||
|
) {
|
||||||
|
// 容量异常:高于 115% 或低于 60%
|
||||||
|
if (currentCap > designCap * 1.15) return DataAbnormalType.capacityTooHigh;
|
||||||
|
if (currentCap < designCap * 0.6) return DataAbnormalType.capacityTooLow;
|
||||||
|
|
||||||
|
// 电压异常:低于 3.0V 或高于 5.0V
|
||||||
|
if (voltage < 3.0 || voltage > 5.0) return DataAbnormalType.voltageAbnormal;
|
||||||
|
|
||||||
|
return DataAbnormalType.none;
|
||||||
|
}
|
||||||
|
|
||||||
// ---------- 辅助提取方法 ----------
|
// ---------- 辅助提取方法 ----------
|
||||||
int _extractCycle(String line) {
|
int _extractCycle(String line) {
|
||||||
final reg = RegExp(r'cycle=(\d+)');
|
final reg = RegExp(r'cycle=(\d+)');
|
||||||
@@ -568,6 +619,13 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
|
|||||||
? '充电中 · ${_getChargeTypeLabel()} · ${_getDisplayPower()}'
|
? '充电中 · ${_getChargeTypeLabel()} · ${_getDisplayPower()}'
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
|
// 🆕 1.7.0 异常检测
|
||||||
|
final abnormalType = _checkAbnormalType(
|
||||||
|
_currentCap,
|
||||||
|
_designCap,
|
||||||
|
_batteryVolt,
|
||||||
|
);
|
||||||
|
|
||||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||||
value: const SystemUiOverlayStyle(
|
value: const SystemUiOverlayStyle(
|
||||||
statusBarColor: Color.fromRGBO(157, 212, 237, 0.1),
|
statusBarColor: Color.fromRGBO(157, 212, 237, 0.1),
|
||||||
@@ -635,14 +693,12 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
|
|||||||
body: _hasData
|
body: _hasData
|
||||||
? Column(
|
? Column(
|
||||||
children: [
|
children: [
|
||||||
// 🟢 可滚动区域(带 RepaintBoundary)
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
padding: const EdgeInsets.all(20.0),
|
padding: const EdgeInsets.all(20.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
// 设备型号
|
|
||||||
Text(
|
Text(
|
||||||
_deviceModel,
|
_deviceModel,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
@@ -653,19 +709,19 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
|
|
||||||
// 🟢 BatterySummary 用 RepaintBoundary 隔离
|
// 🟢 BatterySummary(带异常检测)
|
||||||
RepaintBoundary(
|
RepaintBoundary(
|
||||||
child: BatterySummary(
|
child: BatterySummary(
|
||||||
healthPercent: healthPercent,
|
healthPercent: healthPercent,
|
||||||
cycleCount: _cycleCount,
|
cycleCount: _cycleCount,
|
||||||
currentCap: _currentCap,
|
currentCap: _currentCap,
|
||||||
designCap: _designCap,
|
designCap: _designCap,
|
||||||
|
abnormalType: abnormalType, // 🆕 1.7.0
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
|
|
||||||
// 🟢 TrendChart 用 RepaintBoundary 隔离
|
|
||||||
RepaintBoundary(
|
RepaintBoundary(
|
||||||
child: TrendChart(
|
child: TrendChart(
|
||||||
data: _trendData,
|
data: _trendData,
|
||||||
@@ -675,7 +731,6 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
|
|||||||
|
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
// 🟢 充电条目 - 保留 AnimatedOpacity,但加 RepaintBoundary
|
|
||||||
RepaintBoundary(
|
RepaintBoundary(
|
||||||
child: AnimatedOpacity(
|
child: AnimatedOpacity(
|
||||||
opacity: _isCharging ? 1.0 : 0.0,
|
opacity: _isCharging ? 1.0 : 0.0,
|
||||||
@@ -706,7 +761,7 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
|
|||||||
|
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
|
|
||||||
// 🟢 BatteryInfoPanel 也用 RepaintBoundary
|
// 🟢 BatteryInfoPanel(带异常检测)
|
||||||
RepaintBoundary(
|
RepaintBoundary(
|
||||||
child: BatteryInfoPanel(
|
child: BatteryInfoPanel(
|
||||||
batteryVolt: _batteryVolt,
|
batteryVolt: _batteryVolt,
|
||||||
@@ -715,6 +770,7 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
|
|||||||
minVolt: _minVolt,
|
minVolt: _minVolt,
|
||||||
maxTemp: _maxTemp,
|
maxTemp: _maxTemp,
|
||||||
minTemp: _minTemp,
|
minTemp: _minTemp,
|
||||||
|
abnormalType: abnormalType, // 🆕 1.7.0
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart'; // 🟢 添加这一行
|
import 'package:flutter/services.dart'; // 🟢 添加这一行
|
||||||
import 'package:flutter/services.dart' show rootBundle;
|
|
||||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||||
|
|
||||||
class ChangelogPage extends StatefulWidget {
|
class ChangelogPage extends StatefulWidget {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import '../models/data_abnormal_type.dart';
|
||||||
|
|
||||||
class BatteryInfoPanel extends StatelessWidget {
|
class BatteryInfoPanel extends StatelessWidget {
|
||||||
final double batteryVolt;
|
final double batteryVolt;
|
||||||
@@ -8,6 +9,7 @@ class BatteryInfoPanel extends StatelessWidget {
|
|||||||
final double minVolt;
|
final double minVolt;
|
||||||
final double maxTemp;
|
final double maxTemp;
|
||||||
final double minTemp;
|
final double minTemp;
|
||||||
|
final DataAbnormalType abnormalType;
|
||||||
|
|
||||||
const BatteryInfoPanel({
|
const BatteryInfoPanel({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -17,10 +19,15 @@ class BatteryInfoPanel extends StatelessWidget {
|
|||||||
required this.minVolt,
|
required this.minVolt,
|
||||||
required this.maxTemp,
|
required this.maxTemp,
|
||||||
required this.minTemp,
|
required this.minTemp,
|
||||||
|
this.abnormalType = DataAbnormalType.none,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final bool isVoltageAbnormal =
|
||||||
|
abnormalType == DataAbnormalType.voltageAbnormal;
|
||||||
|
final Color voltColor = isVoltageAbnormal ? Colors.red : Colors.black;
|
||||||
|
|
||||||
return Row(
|
return Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@@ -32,6 +39,7 @@ class BatteryInfoPanel extends StatelessWidget {
|
|||||||
_buildIcon('voltage'),
|
_buildIcon('voltage'),
|
||||||
'电压',
|
'电压',
|
||||||
'${batteryVolt.toStringAsFixed(3)}V',
|
'${batteryVolt.toStringAsFixed(3)}V',
|
||||||
|
textColor: voltColor,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Row(
|
Row(
|
||||||
@@ -52,7 +60,12 @@ class BatteryInfoPanel extends StatelessWidget {
|
|||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
TextSpan(text: '${maxVolt.toStringAsFixed(3)}V'),
|
TextSpan(
|
||||||
|
text: '${maxVolt.toStringAsFixed(3)}V',
|
||||||
|
style: TextStyle(
|
||||||
|
color: isVoltageAbnormal ? Colors.red : Colors.red,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -73,7 +86,12 @@ class BatteryInfoPanel extends StatelessWidget {
|
|||||||
color: Colors.blue,
|
color: Colors.blue,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
TextSpan(text: '${minVolt.toStringAsFixed(3)}V'),
|
TextSpan(
|
||||||
|
text: '${minVolt.toStringAsFixed(3)}V',
|
||||||
|
style: TextStyle(
|
||||||
|
color: isVoltageAbnormal ? Colors.red : Colors.blue,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -96,7 +114,7 @@ class BatteryInfoPanel extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
RichText(
|
RichText(
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
fontFamily: 'Flyme',
|
fontFamily: 'Flyme',
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@@ -117,7 +135,7 @@ class BatteryInfoPanel extends StatelessWidget {
|
|||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
RichText(
|
RichText(
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
fontFamily: 'Flyme',
|
fontFamily: 'Flyme',
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@@ -165,7 +183,12 @@ class BatteryInfoPanel extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildInfoItem(Widget icon, String label, String value) {
|
Widget _buildInfoItem(
|
||||||
|
Widget icon,
|
||||||
|
String label,
|
||||||
|
String value, {
|
||||||
|
Color textColor = Colors.black,
|
||||||
|
}) {
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
icon,
|
icon,
|
||||||
@@ -181,11 +204,11 @@ class BatteryInfoPanel extends StatelessWidget {
|
|||||||
const SizedBox(width: 6),
|
const SizedBox(width: 6),
|
||||||
Text(
|
Text(
|
||||||
value,
|
value,
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'Flyme',
|
fontFamily: 'Flyme',
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Colors.black,
|
color: textColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import '../models/data_abnormal_type.dart';
|
||||||
|
|
||||||
class BatterySummary extends StatelessWidget {
|
class BatterySummary extends StatelessWidget {
|
||||||
final double healthPercent;
|
final double healthPercent;
|
||||||
final int cycleCount;
|
final int cycleCount;
|
||||||
final double currentCap;
|
final double currentCap;
|
||||||
final int designCap;
|
final int designCap;
|
||||||
|
final DataAbnormalType abnormalType;
|
||||||
|
|
||||||
const BatterySummary({
|
const BatterySummary({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -12,11 +14,25 @@ class BatterySummary extends StatelessWidget {
|
|||||||
required this.cycleCount,
|
required this.cycleCount,
|
||||||
required this.currentCap,
|
required this.currentCap,
|
||||||
required this.designCap,
|
required this.designCap,
|
||||||
|
this.abnormalType = DataAbnormalType.none,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final bool isLowHealth = healthPercent < 70;
|
final bool isAbnormal = abnormalType != DataAbnormalType.none;
|
||||||
|
final bool isCapacityAbnormal =
|
||||||
|
abnormalType == DataAbnormalType.capacityTooLow ||
|
||||||
|
abnormalType == DataAbnormalType.capacityTooHigh;
|
||||||
|
|
||||||
|
// 健康度颜色:异常时红色,否则按阈值
|
||||||
|
final Color healthColor = isAbnormal
|
||||||
|
? Colors.red
|
||||||
|
: (healthPercent < 70 ? Colors.red : Colors.black);
|
||||||
|
|
||||||
|
// 容量颜色:异常时红色,否则灰色
|
||||||
|
final Color capacityColor = isCapacityAbnormal
|
||||||
|
? Colors.red
|
||||||
|
: const Color(0xFF5F5F5F);
|
||||||
|
|
||||||
return Row(
|
return Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
@@ -33,7 +49,7 @@ class BatterySummary extends StatelessWidget {
|
|||||||
fontSize: 40,
|
fontSize: 40,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
height: 1.0,
|
height: 1.0,
|
||||||
color: isLowHealth ? Colors.red : Colors.black,
|
color: healthColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 2),
|
const SizedBox(width: 2),
|
||||||
@@ -44,7 +60,9 @@ class BatterySummary extends StatelessWidget {
|
|||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w300,
|
fontWeight: FontWeight.w300,
|
||||||
height: 1.0,
|
height: 1.0,
|
||||||
color: isLowHealth ? Colors.red : Colors.grey.shade600,
|
color: healthColor == Colors.red
|
||||||
|
? Colors.red
|
||||||
|
: Colors.grey.shade600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -56,7 +74,7 @@ class BatterySummary extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
RichText(
|
RichText(
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
fontFamily: 'Flyme',
|
fontFamily: 'Flyme',
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
@@ -65,9 +83,9 @@ class BatterySummary extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
children: [
|
children: [
|
||||||
TextSpan(text: '$cycleCount'),
|
TextSpan(text: '$cycleCount'),
|
||||||
TextSpan(
|
const TextSpan(
|
||||||
text: ' cycles',
|
text: ' cycles',
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'HarmonyOS_Sans_SC',
|
fontFamily: 'HarmonyOS_Sans_SC',
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
),
|
),
|
||||||
@@ -83,7 +101,7 @@ class BatterySummary extends StatelessWidget {
|
|||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w300,
|
fontWeight: FontWeight.w300,
|
||||||
height: 1.0,
|
height: 1.0,
|
||||||
color: const Color(0xFF5F5F5F),
|
color: capacityColor,
|
||||||
),
|
),
|
||||||
children: [
|
children: [
|
||||||
TextSpan(text: currentCap.toStringAsFixed(0)),
|
TextSpan(text: currentCap.toStringAsFixed(0)),
|
||||||
@@ -91,17 +109,17 @@ class BatterySummary extends StatelessWidget {
|
|||||||
text: ' / ',
|
text: ' / ',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'HarmonyOS_Sans_SC',
|
fontFamily: 'HarmonyOS_Sans_SC',
|
||||||
color: const Color(0xFF5F5F5F).withValues(alpha: 0.5),
|
color: capacityColor.withOpacity(0.5),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
TextSpan(text: designCap.toString()),
|
TextSpan(text: designCap.toString()),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: ' mAh',
|
text: ' mAh',
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'HarmonyOS_Sans_SC',
|
fontFamily: 'HarmonyOS_Sans_SC',
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Color(0xFF5F5F5F),
|
color: capacityColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 1.6.0
|
version: 1.7.0
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.9.2
|
sdk: ^3.9.2
|
||||||
|
|||||||
Reference in New Issue
Block a user