feat: fix bugs
This commit is contained in:
parent
665c9e6049
commit
c40f6acc36
|
|
@ -2,7 +2,9 @@ targets:
|
|||
$default:
|
||||
sources:
|
||||
- "lib/**"
|
||||
- "generator/**"
|
||||
builders:
|
||||
json_serializable:
|
||||
generate_for:
|
||||
- "lib/**"
|
||||
- "generator/**"
|
||||
|
|
@ -60,10 +60,10 @@ class EndpointCodeGenerator extends BaseGenerator {
|
|||
|
||||
// 生成注释
|
||||
if (path.summary.isNotEmpty) {
|
||||
buffer.writeln(' /// ${path.summary}');
|
||||
buffer.writeln(' ${StringUtils.generateComment(path.summary)}');
|
||||
}
|
||||
if (path.description.isNotEmpty && path.description != path.summary) {
|
||||
buffer.writeln(' /// ${path.description}');
|
||||
buffer.writeln(' ${StringUtils.generateComment(path.description)}');
|
||||
}
|
||||
|
||||
buffer.writeln(' static const String $constantName = \'$cleanPath\';');
|
||||
|
|
@ -171,7 +171,7 @@ class EndpointCodeGenerator extends BaseGenerator {
|
|||
final constantName = _generateConstantName(path);
|
||||
|
||||
if (path.summary.isNotEmpty) {
|
||||
buffer.writeln(' /// ${path.summary}');
|
||||
buffer.writeln(' ${StringUtils.generateComment(path.summary)}');
|
||||
}
|
||||
buffer.writeln(
|
||||
' $enumName(ApiPaths.$constantName, \'${path.method.value}\'),');
|
||||
|
|
|
|||
|
|
@ -181,10 +181,10 @@ class RetrofitApiGenerator extends BaseGenerator {
|
|||
|
||||
// 生成方法注释
|
||||
if (path.summary.isNotEmpty) {
|
||||
buffer.writeln(' /// ${path.summary}');
|
||||
buffer.writeln(' ${StringUtils.generateComment(path.summary)}');
|
||||
}
|
||||
if (path.description.isNotEmpty && path.description != path.summary) {
|
||||
buffer.writeln(' /// ${path.description}');
|
||||
buffer.writeln(' ${StringUtils.generateComment(path.description)}');
|
||||
}
|
||||
|
||||
// 生成 HTTP 方法注解
|
||||
|
|
@ -226,8 +226,8 @@ class RetrofitApiGenerator extends BaseGenerator {
|
|||
if (operationId.toLowerCase().startsWith(method)) {
|
||||
return StringUtils.toCamelCase(operationId);
|
||||
}
|
||||
// 否则添加 HTTP 方法前缀
|
||||
return '$method${StringUtils.toPascalCase(operationId)}';
|
||||
// 否则直接使用 operationId,不添加 HTTP 方法前缀
|
||||
return StringUtils.toCamelCase(operationId);
|
||||
}
|
||||
|
||||
// 清理路径,移除 /api/v1 前缀
|
||||
|
|
@ -247,34 +247,18 @@ class RetrofitApiGenerator extends BaseGenerator {
|
|||
// 如 /TaskSummarize/GetSummarizeTaskByDate -> getSummarizeTaskByDate
|
||||
final action = StringUtils.toPascalCase(pathParts[1]);
|
||||
|
||||
// 如果方法名已经以HTTP方法开头,移除重复前缀
|
||||
final actionLower = action.toLowerCase();
|
||||
if (actionLower.startsWith(method)) {
|
||||
// 移除重复的HTTP方法前缀
|
||||
final cleanAction = action.substring(method.length);
|
||||
return '$method${StringUtils.toPascalCase(cleanAction)}';
|
||||
}
|
||||
|
||||
return '$method$action';
|
||||
return StringUtils.toCamelCase(action);
|
||||
} else if (pathParts.length == 1) {
|
||||
// 只有一个部分:如 /HealthCheck -> getHealthCheck
|
||||
// 只有一个部分:如 /HealthCheck -> healthCheck
|
||||
final action = StringUtils.toPascalCase(pathParts[0]);
|
||||
|
||||
// 如果方法名已经以HTTP方法开头,移除重复前缀
|
||||
final actionLower = action.toLowerCase();
|
||||
if (actionLower.startsWith(method)) {
|
||||
// 移除重复的HTTP方法前缀
|
||||
final cleanAction = action.substring(method.length);
|
||||
return '$method${StringUtils.toPascalCase(cleanAction)}';
|
||||
}
|
||||
|
||||
return '$method$action';
|
||||
return StringUtils.toCamelCase(action);
|
||||
}
|
||||
|
||||
// 最后的备用方案:使用完整路径
|
||||
final sanitizedPath =
|
||||
pathParts.map((part) => StringUtils.toPascalCase(part)).join('');
|
||||
return '$method$sanitizedPath';
|
||||
return StringUtils.toCamelCase(sanitizedPath);
|
||||
}
|
||||
|
||||
/// 生成返回类型
|
||||
|
|
@ -649,7 +633,7 @@ class RetrofitApiGenerator extends BaseGenerator {
|
|||
.toList();
|
||||
for (final param in pathParams) {
|
||||
parameters.add(ApiMethodParameter(
|
||||
name: StringUtils.toCamelCase(param.name),
|
||||
name: StringUtils.toDartPropertyName(param.name),
|
||||
type: _getDartType(param.type),
|
||||
annotation: useRetrofit ? '@Path(\'${param.name}\')' : '',
|
||||
required: param.required,
|
||||
|
|
@ -680,7 +664,7 @@ class RetrofitApiGenerator extends BaseGenerator {
|
|||
for (final param in queryParams) {
|
||||
final nullable = param.required ? '' : '?';
|
||||
parameters.add(ApiMethodParameter(
|
||||
name: StringUtils.toCamelCase(param.name),
|
||||
name: StringUtils.toDartPropertyName(param.name),
|
||||
type: '${_getDartType(param.type)}$nullable',
|
||||
annotation: useRetrofit ? '@Query(\'${param.name}\')' : '',
|
||||
required: param.required,
|
||||
|
|
@ -695,7 +679,7 @@ class RetrofitApiGenerator extends BaseGenerator {
|
|||
for (final param in bodyParams) {
|
||||
final bodyType = _inferRequestBodyType(path);
|
||||
parameters.add(ApiMethodParameter(
|
||||
name: StringUtils.toCamelCase(
|
||||
name: StringUtils.toDartPropertyName(
|
||||
param.name.isNotEmpty ? param.name : 'request'),
|
||||
type: bodyType,
|
||||
annotation: useRetrofit ? '@Body()' : '',
|
||||
|
|
@ -1037,7 +1021,7 @@ class RetrofitApiGenerator extends BaseGenerator {
|
|||
for (final tagName in tagGroups.keys) {
|
||||
final className = _generateTagClassName(tagName);
|
||||
buffer.writeln(
|
||||
' late final $className _${StringUtils.toCamelCase(tagName)}Api;');
|
||||
' late final $className _${StringUtils.toDartPropertyName(tagName)}Api;');
|
||||
}
|
||||
|
||||
buffer.writeln('');
|
||||
|
|
@ -1046,7 +1030,7 @@ class RetrofitApiGenerator extends BaseGenerator {
|
|||
buffer.writeln(' $className(this._dio, {String? baseUrl}) {');
|
||||
for (final tagName in tagGroups.keys) {
|
||||
final className = _generateTagClassName(tagName);
|
||||
final fieldName = '_${StringUtils.toCamelCase(tagName)}Api';
|
||||
final fieldName = '_${StringUtils.toDartPropertyName(tagName)}Api';
|
||||
buffer.writeln(' $fieldName = $className(_dio, baseUrl: baseUrl);');
|
||||
}
|
||||
buffer.writeln(' }');
|
||||
|
|
@ -1056,10 +1040,10 @@ class RetrofitApiGenerator extends BaseGenerator {
|
|||
// 为每个 tag 生成一个获取器
|
||||
for (final tagName in tagGroups.keys) {
|
||||
final className = _generateTagClassName(tagName);
|
||||
final fieldName = '_${StringUtils.toCamelCase(tagName)}Api';
|
||||
final fieldName = '_${StringUtils.toDartPropertyName(tagName)}Api';
|
||||
buffer.writeln(' /// ${tagName}相关API');
|
||||
buffer.writeln(
|
||||
' $className get ${StringUtils.toCamelCase(tagName)} => $fieldName;');
|
||||
' $className get ${StringUtils.toDartPropertyName(tagName)} => $fieldName;');
|
||||
buffer.writeln('');
|
||||
}
|
||||
|
||||
|
|
@ -1343,9 +1327,9 @@ class RetrofitApiGenerator extends BaseGenerator {
|
|||
final buffer = StringBuffer();
|
||||
|
||||
// 生成文件头注释
|
||||
buffer.writeln('/// 参数实体类 - $className');
|
||||
buffer.writeln('// 参数实体类 - $className');
|
||||
buffer.writeln(
|
||||
'/// 用于 ${path.method.value.toUpperCase()} ${path.path} 的查询参数');
|
||||
'// 用于 ${path.method.value.toUpperCase()} ${path.path} 的查询参数');
|
||||
buffer.writeln('');
|
||||
|
||||
// 导入语句
|
||||
|
|
@ -1361,7 +1345,7 @@ class RetrofitApiGenerator extends BaseGenerator {
|
|||
|
||||
// 生成属性
|
||||
for (final param in queryParams) {
|
||||
final dartName = StringUtils.toCamelCase(param.name);
|
||||
final dartName = StringUtils.toDartPropertyName(param.name);
|
||||
final dartType = _getDartType(param.type);
|
||||
final nullable = param.required ? '' : '?';
|
||||
|
||||
|
|
@ -1381,7 +1365,7 @@ class RetrofitApiGenerator extends BaseGenerator {
|
|||
// 生成构造函数
|
||||
buffer.writeln(' const $className({');
|
||||
for (final param in queryParams) {
|
||||
final dartName = StringUtils.toCamelCase(param.name);
|
||||
final dartName = StringUtils.toDartPropertyName(param.name);
|
||||
final required = param.required ? 'required ' : '';
|
||||
buffer.writeln(' ${required}this.$dartName,');
|
||||
}
|
||||
|
|
@ -1404,7 +1388,7 @@ class RetrofitApiGenerator extends BaseGenerator {
|
|||
buffer.writeln(' Map<String, dynamic> toQueryMap() {');
|
||||
buffer.writeln(' final map = <String, dynamic>{};');
|
||||
for (final param in queryParams) {
|
||||
final dartName = StringUtils.toCamelCase(param.name);
|
||||
final dartName = StringUtils.toDartPropertyName(param.name);
|
||||
buffer.writeln(
|
||||
' if ($dartName != null) map[\'${param.name}\'] = $dartName;');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,17 @@ class StringUtils {
|
|||
static String toCamelCase(String input) {
|
||||
if (input.isEmpty) return input;
|
||||
|
||||
// 如果输入已经是camelCase格式(首字母小写),直接返回
|
||||
if (RegExp(r'^[a-z][a-zA-Z0-9]*$').hasMatch(input)) {
|
||||
return input;
|
||||
}
|
||||
|
||||
// 如果输入是PascalCase格式(首字母大写),转换为camelCase
|
||||
if (RegExp(r'^[A-Z][a-zA-Z0-9]*$').hasMatch(input)) {
|
||||
return input[0].toLowerCase() + input.substring(1);
|
||||
}
|
||||
|
||||
// 处理下划线分隔的字符串
|
||||
final parts = input.split('_').where((p) => p.isNotEmpty).toList();
|
||||
if (parts.isEmpty) return input;
|
||||
|
||||
|
|
@ -95,6 +106,7 @@ class StringUtils {
|
|||
///
|
||||
/// - 支持 snake_case、kebab-case、空格、特殊字符自动转为 camelCase
|
||||
/// - 已经是驼峰命名的字符串保持不变
|
||||
/// - PascalCase(首字母大写)转换为camelCase(首字母小写)
|
||||
/// - 数字开头自动加前缀 n
|
||||
/// - 空字符串返回 'property'
|
||||
///
|
||||
|
|
@ -104,33 +116,32 @@ class StringUtils {
|
|||
/// StringUtils.toDartPropertyName('user-id'); // userId
|
||||
/// StringUtils.toDartPropertyName('1st_field'); // n1stField
|
||||
/// StringUtils.toDartPropertyName('classCadreId'); // classCadreId
|
||||
/// StringUtils.toDartPropertyName('PageIndex'); // pageIndex
|
||||
/// StringUtils.toDartPropertyName(''); // property
|
||||
/// ```
|
||||
static String toDartPropertyName(String propName) {
|
||||
// 如果已经是驼峰命名(没有下划线且首字母小写),直接返回
|
||||
// 如果已经是camelCase命名(没有下划线且首字母小写),直接返回
|
||||
if (RegExp(r'^[a-z][a-zA-Z0-9]*$').hasMatch(propName)) {
|
||||
return propName;
|
||||
}
|
||||
|
||||
// PascalCase 直接转 camelCase
|
||||
if (RegExp(r'^[A-Z][a-zA-Z0-9]*$').hasMatch(propName)) {
|
||||
return propName[0].toLowerCase() + propName.substring(1);
|
||||
}
|
||||
// 处理特殊字符和数字开头的情况
|
||||
String result = propName;
|
||||
|
||||
// 如果以数字开头,添加前缀
|
||||
if (RegExp(r'^[0-9]').hasMatch(result)) {
|
||||
result = 'n$result';
|
||||
}
|
||||
|
||||
// 替换特殊字符为下划线
|
||||
result = result.replaceAll(RegExp(r'[^a-zA-Z0-9_]'), '_');
|
||||
|
||||
// 转换为camelCase
|
||||
result = toCamelCase(result);
|
||||
|
||||
// 确保不为空
|
||||
if (result.isEmpty) {
|
||||
result = 'property';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -146,7 +157,7 @@ class StringUtils {
|
|||
|
||||
// 移除可能引起语法错误的特殊字符
|
||||
cleaned = cleaned
|
||||
.replaceAll(RegExp(r'[^\w\s\u4e00-\u9fa5()(),,.。::;;!!??_/\\-]'), '')
|
||||
.replaceAll(RegExp(r'[^\w\s\u4e00-\u9fa5,,.。::;;!!??_/\\-]'), '')
|
||||
.replaceAll(RegExp(r'\s+'), ' ')
|
||||
.trim();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
import 'lib/utils/string_utils.dart';
|
||||
|
||||
void main() {
|
||||
print('Testing function name generation:');
|
||||
print(
|
||||
'GetClassesTaskChecklistUsers -> ${StringUtils.toCamelCase('GetClassesTaskChecklistUsers')}');
|
||||
print('GetUserInfo -> ${StringUtils.toCamelCase('GetUserInfo')}');
|
||||
print('CreateTask -> ${StringUtils.toCamelCase('CreateTask')}');
|
||||
print('UpdateUserProfile -> ${StringUtils.toCamelCase('UpdateUserProfile')}');
|
||||
print('DeleteTaskById -> ${StringUtils.toCamelCase('DeleteTaskById')}');
|
||||
|
||||
print('\nTesting existing camelCase:');
|
||||
print(
|
||||
'getClassesTaskChecklistUsers -> ${StringUtils.toCamelCase('getClassesTaskChecklistUsers')}');
|
||||
print('getUserInfo -> ${StringUtils.toCamelCase('getUserInfo')}');
|
||||
|
||||
print('\nTesting snake_case:');
|
||||
print(
|
||||
'get_classes_task_checklist_users -> ${StringUtils.toCamelCase('get_classes_task_checklist_users')}');
|
||||
print('get_user_info -> ${StringUtils.toCamelCase('get_user_info')}');
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import 'lib/utils/string_utils.dart';
|
||||
|
||||
void main() {
|
||||
// 测试属性名转换
|
||||
print('Testing property name conversion:');
|
||||
print('classCadreId -> ${StringUtils.toDartPropertyName('classCadreId')}');
|
||||
print('meetingTitle -> ${StringUtils.toDartPropertyName('meetingTitle')}');
|
||||
|
|
@ -11,10 +10,67 @@ void main() {
|
|||
print(
|
||||
'sunTaskFileResults -> ${StringUtils.toDartPropertyName('sunTaskFileResults')}');
|
||||
|
||||
// 测试下划线格式
|
||||
print('\nTesting snake_case conversion:');
|
||||
print(
|
||||
'class_cadre_id -> ${StringUtils.toDartPropertyName('class_cadre_id')}');
|
||||
print('meeting_title -> ${StringUtils.toDartPropertyName('meeting_title')}');
|
||||
print('task_info -> ${StringUtils.toDartPropertyName('task_info')}');
|
||||
|
||||
print('\nTesting problematic field names:');
|
||||
print('PageIndex -> ${StringUtils.toDartPropertyName('PageIndex')}');
|
||||
print('ProblemTitle -> ${StringUtils.toDartPropertyName('ProblemTitle')}');
|
||||
print('ProblemObj -> ${StringUtils.toDartPropertyName('ProblemObj')}');
|
||||
print(
|
||||
'ProblemPhenomenon -> ${StringUtils.toDartPropertyName('ProblemPhenomenon')}');
|
||||
print('ClassesId -> ${StringUtils.toDartPropertyName('ClassesId')}');
|
||||
print(
|
||||
'ProblemTaskType -> ${StringUtils.toDartPropertyName('ProblemTaskType')}');
|
||||
print('PageSize -> ${StringUtils.toDartPropertyName('PageSize')}');
|
||||
|
||||
print('\nTesting parameter name conversion:');
|
||||
print('api-version -> ${StringUtils.toDartPropertyName('api-version')}');
|
||||
print('user-id -> ${StringUtils.toDartPropertyName('user-id')}');
|
||||
print('file_name -> ${StringUtils.toDartPropertyName('file_name')}');
|
||||
print('with space -> ${StringUtils.toDartPropertyName('with space')}');
|
||||
|
||||
print('\nTesting kebab-case conversion:');
|
||||
print('api-version -> ${StringUtils.toDartPropertyName('api-version')}');
|
||||
print('user-id -> ${StringUtils.toDartPropertyName('user-id')}');
|
||||
print('page-size -> ${StringUtils.toDartPropertyName('page-size')}');
|
||||
print('to-camel-case -> ${StringUtils.toDartPropertyName('to-camel-case')}');
|
||||
|
||||
print('\nTesting tag names:');
|
||||
print(
|
||||
'Follow Manager -> ${StringUtils.toDartPropertyName('Follow Manager')}');
|
||||
print('Health Check -> ${StringUtils.toDartPropertyName('Health Check')}');
|
||||
print(
|
||||
'Mobile Manager -> ${StringUtils.toDartPropertyName('Mobile Manager')}');
|
||||
print('My Info -> ${StringUtils.toDartPropertyName('My Info')}');
|
||||
print(
|
||||
'Task Class Cadre Meeting -> ${StringUtils.toDartPropertyName('Task Class Cadre Meeting')}');
|
||||
print(
|
||||
'Task Class Meeting -> ${StringUtils.toDartPropertyName('Task Class Meeting')}');
|
||||
print(
|
||||
'Task Coach Sub -> ${StringUtils.toDartPropertyName('Task Coach Sub')}');
|
||||
print('Task Cultural -> ${StringUtils.toDartPropertyName('Task Cultural')}');
|
||||
print(
|
||||
'Task Data Collect -> ${StringUtils.toDartPropertyName('Task Data Collect')}');
|
||||
print('Task Follow -> ${StringUtils.toDartPropertyName('Task Follow')}');
|
||||
print('Task Info -> ${StringUtils.toDartPropertyName('Task Info')}');
|
||||
print('Task Meeting -> ${StringUtils.toDartPropertyName('Task Meeting')}');
|
||||
print('Task Other -> ${StringUtils.toDartPropertyName('Task Other')}');
|
||||
print('Task Solution -> ${StringUtils.toDartPropertyName('Task Solution')}');
|
||||
print('Task Spot -> ${StringUtils.toDartPropertyName('Task Spot')}');
|
||||
print(
|
||||
'Task Summarize -> ${StringUtils.toDartPropertyName('Task Summarize')}');
|
||||
print('Task Talk -> ${StringUtils.toDartPropertyName('Task Talk')}');
|
||||
print(
|
||||
'Task Teacher Behavior -> ${StringUtils.toDartPropertyName('Task Teacher Behavior')}');
|
||||
print(
|
||||
'Task Teacher Talk -> ${StringUtils.toDartPropertyName('Task Teacher Talk')}');
|
||||
|
||||
print('\nTesting comment cleaning:');
|
||||
print('部长新增工作任务指标(会删除所有管理的班级任务指标)-删除所有管理的学习官的通用任务指标');
|
||||
print(
|
||||
'Cleaned: ${StringUtils.cleanDescription('部长新增工作任务指标(会删除所有管理的班级任务指标)-删除所有管理的学习官的通用任务指标')}');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,23 @@ void main() {
|
|||
expect(StringUtils.toCamelCase('api_version'), 'apiVersion');
|
||||
});
|
||||
|
||||
test('converts PascalCase to camelCase', () {
|
||||
expect(StringUtils.toCamelCase('GetClassesTaskChecklistUsers'),
|
||||
'getClassesTaskChecklistUsers');
|
||||
expect(StringUtils.toCamelCase('GetUserInfo'), 'getUserInfo');
|
||||
expect(StringUtils.toCamelCase('CreateTask'), 'createTask');
|
||||
expect(
|
||||
StringUtils.toCamelCase('UpdateUserProfile'), 'updateUserProfile');
|
||||
expect(StringUtils.toCamelCase('DeleteTaskById'), 'deleteTaskById');
|
||||
});
|
||||
|
||||
test('preserves existing camelCase', () {
|
||||
expect(StringUtils.toCamelCase('getClassesTaskChecklistUsers'),
|
||||
'getClassesTaskChecklistUsers');
|
||||
expect(StringUtils.toCamelCase('getUserInfo'), 'getUserInfo');
|
||||
expect(StringUtils.toCamelCase('createTask'), 'createTask');
|
||||
});
|
||||
|
||||
test('handles single word', () {
|
||||
expect(StringUtils.toCamelCase('user'), 'user');
|
||||
expect(StringUtils.toCamelCase(''), '');
|
||||
|
|
|
|||
Loading…
Reference in New Issue