初始化

This commit is contained in:
谢宇宁
2026-09-15 15:44:13 +07:00
commit a23ba685e9
1065 changed files with 101122 additions and 0 deletions
@@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
import '../models/ai_record_model.dart';
class AiNovelDetailPage extends StatelessWidget {
final AiRecordModel model;
const AiNovelDetailPage(this.model, {super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('小说详情')),
body: SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 12),
child: Text(
model.content ?? '',
style: TextStyle(color: Colors.white.withValues(alpha: .8), fontSize: 14, height: 1.5),
),
),
);
}
}
@@ -0,0 +1,56 @@
//ai小说
import 'package:flutter/material.dart';
import 'package:hgdj/tools_base/loading/loading_helper.dart';
import 'package:hgdj/tools_base/toast.dart';
import '../../../../hj_utils/api_service/ai_service.dart';
import '../ai_sub_type/ai_function_logic.dart';
class AINovelLogic extends AiFunctionBaseLogic {
late final personTextCtr = TextEditingController();
late final addressTextCtr = TextEditingController();
late final detailTextCtr = TextEditingController();
late final storylineTextCtr = TextEditingController();
final mods = <String>['AI小艺', 'AI小萌'];
int selectIndex = 0;
AINovelLogic(super.modList);
@override
void onClose() {
personTextCtr.dispose();
addressTextCtr.dispose();
detailTextCtr.dispose();
storylineTextCtr.dispose();
super.onClose();
}
@override
Future<void> submit() async {
if (storylineTextCtr.text.isEmpty) {
showToast('请输入故事情节描述~');
return;
}
LoadingHelper.showLoading();
final result = await AIService.generateNovel(
storylineTextCtr.text,
characterSetting: personTextCtr.text,
locationScene: addressTextCtr.text,
details: detailTextCtr.text,
modelType: selectIndex + 1,
);
LoadingHelper.dismissLoading();
if (result) {
showToast('提交成功~');
storylineTextCtr.clear();
personTextCtr.clear();
addressTextCtr.clear();
detailTextCtr.clear();
selectIndex = 0;
update();
} else {
showToast('提交失败');
}
}
}
+216
View File
@@ -0,0 +1,216 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgdj/assets_tool/app_colors.dart';
import 'package:hgdj/config/config.dart';
import 'package:hgdj/hj_utils/screen.dart';
import '../widgets/ai_draw_text_field.dart';
import 'ai_novel_logic.dart';
class AINovelSubPage extends StatelessWidget {
const AINovelSubPage({super.key});
@override
Widget build(BuildContext context) {
return Container(
color: Color(0xff030F18),
// 用默认 globalglobal:false 下 widget 销毁不会 Get.deleteonClose 不触发,输入框 controller 释放不掉
child: GetBuilder<AINovelLogic>(
init: AINovelLogic(null),
builder: (logic) {
return Column(
children: [
Expanded(
child: SingleChildScrollView(
keyboardDismissBehavior:
ScrollViewKeyboardDismissBehavior.onDrag,
padding: EdgeInsets.symmetric(horizontal: 6).copyWith(top: 12),
child: Column(
children: [
_buildInputView(
logic.personTextCtr,
),
12.sizeBoxH,
_buildInputView(
logic.addressTextCtr,
title: '地点场景(选填)',
hint: '示例:办公室、酒吧',
),
12.sizeBoxH,
_buildInputView(
logic.storylineTextCtr,
title: '故事情节(必填)',
hint: '故事大致情节,例如:35岁女强人在酒吧遇到跳钢管舞的男模后,欲火焚身、欲罢不能。',
maxLength: 200,
),
12.sizeBoxH,
_buildInputView(
logic.detailTextCtr,
title: '细节说明(选填)',
hint: '例如:请详细描写女主身材美貌,与霸总的做爱过程',
maxLength: 200,
),
12.sizeBoxH,
Align(
alignment: Alignment.centerLeft,
child: Text(
"选择模型",
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
),
10.sizeBoxH,
SizedBox(
height: 28,
child: SingleChildScrollView(
child: Row(
children: List.generate(
logic.mods.length,
(index) => Padding(
padding: EdgeInsets.only(right: 12),
child: InkWell(
enableFeedback: false,
onTap: () {
logic.selectIndex = index;
logic.update();
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 8),
alignment: Alignment.center,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: logic.selectIndex == index
? [
AppColors.actionRed,
AppColors.actionRed
]
: [
Colors.white
.withValues(alpha: .05),
Colors.white
.withValues(alpha: .05),
]),
borderRadius: BorderRadius.circular(4),
color: logic.selectIndex == index
? null
: Color(0xFF7C7C7C),
),
height: 28,
child: Text(
logic.mods[index],
style: TextStyle(
color: logic.selectIndex == index
? Colors.white
: Colors.white.withValues(alpha: .5),
fontSize: 14,
fontWeight: FontWeight.w400,
),
),
),
),
),
),
),
),
),
18.sizeBoxH,
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"生成一次AI小说费用是 ",
style: TextStyle(
color: Colors.white.withValues(alpha: .9),
fontSize: 14,
),
),
Text(
'${Config.aiNovelPrice}金币',
style: TextStyle(
color: AppColors.actionRed,
fontSize: 14,
),
)
],
),
InkWell(
enableFeedback: false,
onTap: () => logic.submit(),
child: Container(
height: 44,
margin: EdgeInsets.symmetric(vertical: 12),
alignment: Alignment.center,
decoration: BoxDecoration(
color: AppColors.actionRed,
borderRadius: BorderRadius.circular(3),
),
child: Text(
"立即提交",
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w500,
),
),
),
),
],
),
)),
// 0.5.line,
// 10.sizeBoxH,
],
).paddingSymmetric(horizontal: 10);
},
),
);
}
_buildInputView(
TextEditingController textCtr, {
String title = '人物设定(选填)',
String hint = '示例:总裁、公主、小萝莉.',
int maxLength = 20,
}) {
return Column(
children: [
Row(
children: [
Text(
title,
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
],
),
10.sizeBoxH,
Container(
margin: EdgeInsets.symmetric(horizontal: 2),
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.05),
borderRadius: BorderRadius.all(Radius.circular(5)),
boxShadow: [
BoxShadow(
color: Colors.white.withValues(alpha: .05),
blurRadius: 1, //阴影模糊程度
spreadRadius: 1.0, //阴影扩散程度
)
],
),
child: AIDrawTextField(
controller: textCtr,
hintText: hint,
maxLength: maxLength,
height: 112,
),
),
],
);
}
}