提交 cc22c4e3 authored 作者: 岳维路's avatar 岳维路

合并分支 'test' 到 'sim'

Test 查看合并请求 kiwitap/zijing-app!4
......@@ -342,5 +342,42 @@ abstract class LibraryAPI {
});
}
/// 17、评论 点赞 取消
static Future <bool> commentLove({
required num bookId,
required num type,
required num commentId,
}) async {
final result = await HttpService.to.post(
'/v1/book/Information/clickPraise',
params: {
'book_id':bookId,
'type':type,
'comment_id':commentId
},
);
if (result.data is Map && result.data['is_success'] == 1){
return true;
}
return false;
}
/// 18、删除讨论回复
static Future <bool> delComment({
required num bookId,
required num commentId,
}) async {
final result = await HttpService.to.post(
'/v1/book/Information/delComment',
params: {
'book_id':bookId,
'comment_id':commentId
},
);
if (result.data is Map && result.data['is_success'] == 1){
return true;
}
return false;
}
}
\ No newline at end of file
......@@ -222,6 +222,7 @@ class BookDetailModel {
this.chapterId,
this.chapterName,
this.readChapterId,
this.introduction,
});
BookDetailModel.fromJson(dynamic json) {
......@@ -249,6 +250,7 @@ class BookDetailModel {
chapterId = json['chapter_id'];
chapterName = json['chapter_name'];
readChapterId = json['read_chapter_id'];
introduction = json['introduction'];
}
num? bookId;
String? bookName;
......@@ -274,6 +276,7 @@ class BookDetailModel {
num? chapterId;
String? chapterName;
num? readChapterId;
String? introduction;
BookDetailModel copyWith({ num? bookId,
String? bookName,
String? img,
......@@ -298,6 +301,7 @@ class BookDetailModel {
num? chapterId,
String? chapterName,
num? readChapterId,
String? introduction,
}) => BookDetailModel( bookId: bookId ?? this.bookId,
bookName: bookName ?? this.bookName,
img: img ?? this.img,
......@@ -322,6 +326,7 @@ class BookDetailModel {
chapterId: chapterId ?? this.chapterId,
chapterName: chapterName ?? this.chapterName,
readChapterId: readChapterId?? this.readChapterId,
introduction: introduction ?? this.introduction
);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
......@@ -349,6 +354,7 @@ class BookDetailModel {
map['chapter_id'] = chapterId;
map['chapter_name'] = chapterName;
map['read_chapter_id'] = readChapterId;
map['introduction'] = introduction;
return map;
}
......
......@@ -539,6 +539,9 @@ class DiscussModel {
this.commentAll,
this.personPic,
this.isMy,
this.commentsCheck,
this.status,
this.isPraise,
});
DiscussModel.fromJson(dynamic json) {
......@@ -560,6 +563,9 @@ class DiscussModel {
personName = json['person_name'];
personPic = json['person_pic'];
isMy = json['is_my'];
isPraise = json['is_praise'];
commentsCheck = json['comments_check'];
status = json['status'];
if (json['comment_all'] != null) {
commentAll = [];
......@@ -581,6 +587,9 @@ class DiscussModel {
num? goodNum;
num? replyNum;
num? isMy;
num? isPraise;
num? commentsCheck;
num? status;
String? createTime;
String? replacePersonName;
String? replacePersonPic;
......@@ -601,6 +610,9 @@ class DiscussModel {
num? goodNum,
num? replyNum,
num? isMy,
num? isPraise,
num? commentsCheck,
num? status,
String? createTime,
String? replacePersonName,
String? replacePersonPic,
......@@ -621,6 +633,9 @@ class DiscussModel {
goodNum: goodNum ?? this.goodNum,
replyNum: replyNum ?? this.replyNum,
isMy: isMy ?? this.isMy,
isPraise: isPraise ?? this.isPraise,
status:status ?? this.status,
commentsCheck: commentsCheck ?? this.commentsCheck,
createTime: createTime ?? this.createTime,
replacePersonName: replacePersonName ?? this.replacePersonName,
replacePersonPic: replacePersonPic ?? this.replacePersonPic,
......@@ -646,6 +661,9 @@ class DiscussModel {
map['good_num'] = goodNum;
map['reply_num'] = replyNum;
map['is_my'] = isMy;
map['is_praise'] = isPraise;
map['comments_check'] = commentsCheck;
map['status'] = status;
map['create_time'] = createTime;
map['replace_person_name'] = replacePersonName;
map['replace_person_pic'] = replacePersonPic;
......@@ -664,25 +682,29 @@ class HelpCenterModel {
this.id,
this.helpTitle,
this.createTime,
this.index,
});
HelpCenterModel.fromJson(dynamic json) {
id = json['id'];
helpTitle = json['help_title'];
createTime = json['create_time'];
index = json['index'];
}
num? index;
num? id;
String? helpTitle;
String? createTime;
HelpCenterModel copyWith({
num? index,
num? id,
String? helpTitle,
String? createTime,
}) =>
HelpCenterModel(
id: id ?? this.id,
index: index ?? this.index,
helpTitle: helpTitle ?? this.helpTitle,
createTime: createTime ?? this.createTime,
);
......@@ -690,6 +712,7 @@ class HelpCenterModel {
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['index'] = index;
map['help_title'] = helpTitle;
map['create_time'] = createTime;
return map;
......
......@@ -178,7 +178,7 @@ class _BuildItemState extends State<BuildItem> {
itemBuilder: (BuildContext context, int index){
ChapterModel model = chapterModel.children![index];
return Container(
padding: EdgeInsets.only(left: 60.w,bottom: 4.w),
padding: EdgeInsets.only(left: 20.w,bottom: 4.w),
child: _buildChapter(model)
);
// GestureDetector(
......
......@@ -9,6 +9,7 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt
final PageController pageController = PageController(initialPage: 0);
List <Widget>tabs = [
const Tab(text: '目录',),
const Tab(text: '编辑推荐',),
const Tab(text: '简介',),
const Tab(text: '本书信息',),
];
......@@ -84,7 +85,14 @@ class BookDetailController extends GetxController with GetSingleTickerProviderSt
void getBookDetails() async {
bookDetails = await LibraryAPI.details(bookId:bookId);
// 将阅读最后章节写入到数据库
SqlManager.updateReadHistoryByBookId(int.parse(bookId), bookDetails.chapterId!.toInt());
try {
final result = await SqlManager.updateReadHistoryByBookId(int.parse(bookId), bookDetails.chapterId!.toInt());
Console.log('Sql-------存入数据库读到的章节----------------book_id:$bookId-----chapterId:${bookDetails.chapterId!.toInt()}---------result:$result--');
}
catch(err){
Console.log('Sql--------------err------------------$err');
}
update();
}
/// 收藏 与 取消收藏
......
......@@ -110,7 +110,7 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
final result = await context.pushNamed(Routes.bookPay,extra: buy);
if (result == true) {
controller.getChapters();
controller.getBookDetails();
}
}else{
final result = await context.pushNamed(Routes.web,queryParameters: {'book_id': controller.bookDetails.bookId.toString(),'chapter_id': chapterModel.id.toString(),'chapter_name':chapterModel.name.toString(),'note_id':'0'},extra: controller.bookDetails);
......@@ -120,11 +120,13 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
}
},
),
// Container(
// padding: EdgeInsets.only(left: 15.w,right: 15.w,top:12.w),
// color: Colors.white,
// child: Text(controller.bookDetails.content??'',style: TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c3),),
// ),
SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(left: 15.w,right: 15.w,top:12.w),
color: Colors.white,
child: Text(controller.bookDetails.introduction??'',style: const TextStyle(fontSize: 15,height: 2.1,color: Colours.c9),),
),
),
InAppWebView(
contextMenu: ContextMenu(
options: ContextMenuOptions(hideDefaultSystemContextMenuItems: true),
......@@ -227,7 +229,7 @@ class _BookDetailPageState extends State<BookDetailPage> with SingleTickerProvid
final result = await context.pushNamed(Routes.bookPay,extra: buy);
if (result == true) {
controller.getChapters();
controller.getBookDetails();
}
}
else{
......
......@@ -26,7 +26,7 @@ class _HelpCenterPageState extends State<HelpCenterPage> {
itemCount: controller.helpCenters.length,
itemBuilder: (BuildContext context, int index){
HelpCenterModel model = controller.helpCenters[index];
model.id = index +1;
model.index = index +1;
return GestureDetector(
child: BuildItem(model: model,),
onTap: (){
......
......@@ -18,7 +18,7 @@ class BuildItem extends StatelessWidget {
Row(
children: <Widget>[
Text(
'${model!.id}.',
'${model!.index}.',
style: TextStyle(
fontSize: 14.w, height: 1.5.w, color: Colours.c3),
),
......
......@@ -227,26 +227,26 @@ class LibraryController extends GetxController with GetTickerProviderStateMixin{
/// 收藏 与 取消收藏
void love({
required String bookId,
required num isCollection
required CourseModel model
}) async {
if (isCollection == 0){
num isCollection = 0;
if (model.isCollection == 0){
isCollection = 1;
}
else{
isCollection = 0;
}
bool result = await CommonAPI.love(bookId: bookId, love: isCollection.toString());
bool result = await CommonAPI.love(bookId: model.bookId.toString(), love: isCollection.toString());
if (result) {
onRefresh();
model.isCollection = isCollection;
}
update();
}
/// 批量上传离线笔记、高亮、划线的内容
void upload() async{
List<Map<String, dynamic>> data = await SqlManager.queryNoUploadData();
Console.log('查询到的数据----------------------------------------------------$data');
Console.log('Sql-----查询到的数据-----------------------$data');
if(data.isNotEmpty){
for (Map<String, dynamic> temp in data){
......
......@@ -38,7 +38,7 @@ class _LibraryContentPageState extends State<LibraryContentPage> with AutomaticK
context.pushNamed(Routes.bookDetail,queryParameters: {'book_id':model.bookId.toString()});
},
child: LibraryCell(model: model,onTap: (){
widget.controller.love(bookId: model.bookId.toString(), isCollection: model.isCollection!);
widget.controller.love(model: model);
},),
);
}
......
......@@ -83,6 +83,8 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
just_audio.AudioPlayer audioPlayer = just_audio.AudioPlayer();
late SearchAllModel sModel = SearchAllModel(bookId: '0');
///------------------------------------------ 页面 生命周期--------------------------------------------------------
......@@ -101,10 +103,13 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
netStatus = await Tools.checkCurrentNetStatus();
final exist = await _isExistFile(bookId);
// chapterId = await SqlManager.queryReadHistoryByBookId(int.parse(bookId));
// Console.log('数据库中得到最后阅读的章节----------------------$chapterId----------');
if (!netStatus && exist){
// 1、从数据库中获取读到那个章节
chapterId = await SqlManager.queryReadHistoryByBookId(int.parse(bookId));
Console.log('Sql-----------数据库中得到最后阅读的章节----------------------$chapterId----------');
chapterName = getChapterName(chapterId);
// 2、通过 chapterId 获取 对应离线的 html路径
String toReadHtmlPath = await getLocalReadHtml(chapterId);
......@@ -351,8 +356,6 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
// 重置所有信息
void reset(){
clearAllDiscussInput();
clearDiscussInputImages();
clearDiscussAudios();
}
// 播放音频
......@@ -408,11 +411,12 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
}
// 清空所有已经填写的数据
void clearAllDiscussInput(){
discussInputImages.clear();
discussInputAudios.clear();
clearDiscussInputImages();
clearDiscussAudios();
titleInput.text = '';
contentInput.text = '';
isPublic = false;
noteTitle = '';
Console.log('clearAllDiscussInput--------------------------------');
update();
}
......@@ -546,7 +550,7 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
bookId: bookId,
chapterId: chapterId,
commentId: '0',
quoteContent: '',
quoteContent: noteTitle,
title: titleInput.text,
content: jsonEncode(contentMap)
);
......@@ -579,6 +583,9 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
// 展示输入框
void setShowChat(bool value) {
showChat = value;
if(value == false){
reset();
}
update();
}
// 显示输入框类型
......@@ -605,24 +612,26 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
// 从缓存中获取 ZIP 文件
var file = await DefaultCacheManager().getSingleFile(url);
if (file != null) {
Toast.show('离线成功');
// 读取 ZIP 文件内容
Uint8List bytes = await file.readAsBytes();
// 解压缩 ZIP 文件
Archive archive = ZipDecoder().decodeBytes(bytes);
// 获取设备上的临时目录
Directory? tempDir = await getExternalStorageDirectory();
String tempPath = await Tools.getDirectory();
// 将解压缩后的文件保存到临时目录中
for (var file in archive) {
if (file.isFile) {
String fileName = file.name;
String filePath = '${tempDir!.path}/$bookId/$fileName';
String filePath = '$tempPath/$bookId/$fileName';
File(filePath)
..createSync(recursive: true)
..writeAsBytesSync(file.content as List<int>);
('解压缩文件:$fileName,保存路径:$filePath');
Console.log('解压缩文件:$fileName,保存路径:$filePath');
}
}
Toast.show('离线成功');
final exit = await _isExistFile(bookId);
update();
} else {
Console.log('未找到缓存中的文件或文件不存在');
......@@ -649,7 +658,7 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
}
Future<String> getLocalReadHtml(String chapterId) async{
String docPath = await _getDirectory();
String docPath = await Tools.getDirectory();
String filePath = '$docPath/$bookId';
Directory directory = Directory(filePath);
// 获取目录下的所有文件
......@@ -683,6 +692,7 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
// url: Uri.parse(writeFilePath),
url: WebUri.uri(Uri.parse(writeFilePath))
));
queryLocalNote();
}
// 本地阅读 读取上一章节 或 下一章节
......@@ -771,6 +781,33 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
return '';
}
// 查询本地划线高亮笔记
void queryLocalNote() async {
final result = await SqlManager.queryLocalNote(bookId: int.parse(bookId), chapterId: int.parse(chapterId));
Console.log('前端-----------queryLocalNote---------------------$result');
webViewController.evaluateJavascript(source: 'querySuccessCallBack($result)');
}
// 本地添加划线高亮笔记
void addLocalNote(Map<String, dynamic> data) async {
data['book_id'] = int.parse(bookId);
data['chapter_id'] = int.parse(chapterId);
final result = await SqlManager.addLocalNote(data);
Console.log('前端-----------addLocalNote---------------------$result');
webViewController.evaluateJavascript(source: 'addSuccessCallBack($result)');
}
// 本地删除划线高亮笔记
void delLocalNote({required int id}) async {
final result = await SqlManager.delLocalNote(id: id);
Console.log('前端-----------delLocalNote---------------------$result');
webViewController.evaluateJavascript(source: 'delSuccessCallBack($result)');
}
// 修改本地划线高亮笔记
void updateLocalNote({required int id,required Map<String, dynamic> data}) async {
final result = await SqlManager.updateLocalNote(id: id, data: data);
Console.log('前端-----------updateLocalNote---------------------$result');
webViewController.evaluateJavascript(source: 'updateSuccessCallBack($result)');
}
//获取存储目录
Future<String> _getDirectory() async {
// getTemporaryDirectory
......@@ -779,7 +816,6 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
}
/// 获取目录信息
void _getChapters() async {
chapters = await LibraryAPI.chapters(bookId: bookId);
......
......@@ -27,6 +27,8 @@ class DiscussController extends GetxController {
bool showReply = false;
// 当前要回复的模型
late DiscussModel discussModel;
// 当前要回复父级的模型
late DiscussModel fatherDiscussModel;
// 是否展示搜索结果
bool showSearch = false;
......@@ -49,18 +51,54 @@ class DiscussController extends GetxController {
void setShow() {
showReply = !showReply;
if (showReply == false) {
replyInput.text = '';
}
update();
}
void setDiscussModel(DiscussModel model){
discussModel = model;
}
void setFatherDiscussModel(DiscussModel model){
fatherDiscussModel = model;
}
void setShowSearch(bool show){
showSearch = show;
update();
}
// 点赞 取消点赞
Future<void> commentLove({required DiscussModel discussModel}) async {
num type = 0;
if (discussModel.isPraise ==0){
type = 1;
}
final result = await LibraryAPI.commentLove(bookId:bookDetailModel.bookId! , type: type, commentId: discussModel.id!);
if(result){
num goodNum = discussModel.goodNum??0;
if(type ==0){
goodNum --;
}
else{
goodNum ++;
}
discussModel.isPraise = type;
discussModel.goodNum = goodNum;
}
update();
}
// 删除回复
Future<void> delComment({required DiscussModel discussModel}) async {
final result = await LibraryAPI.delComment(bookId:bookDetailModel.bookId!, commentId: discussModel.id!);
if(result){
discuss.remove(discussModel);
Toast.show('删除成功');
}
update();
}
Future<bool> submit() async {
......@@ -79,15 +117,34 @@ class DiscussController extends GetxController {
content: jsonEncode(contentMap)
);
if(result){
Toast.show('话题发表成功');
Toast.show('发表成功');
Toast.show('发表成功');
discussModel.replyNum = discussModel.replyNum! +1;
DiscussModel tempModel = DiscussModel.fromJson(discussModel.toJson());
tempModel.status = 1;
tempModel.commentsCheck = 0;
tempModel.isMy = 1;
NoteContentModel contentModel = NoteContentModel(
text: MediaModel(content:replyInput.text,privacyStatus: 1)
);
tempModel.content= contentModel;
tempModel.content?.text?.privacyStatus = 1;
tempModel.replacePersonName = discussModel.personName;
tempModel.replacePersonPic = discussModel.personPic;
tempModel.replyNum = 0;
fatherDiscussModel.commentAll?.add(tempModel);
// fatherDiscussModel.replyNum = fatherDiscussModel.commentAll?.length;
}
else{
Toast.show('话题发表失败');
Toast.show('发表失败');
}
// 重置所有信息
// reset();
// setShowChat(false);
replyInput.text = '';
update();
return result;
}
......@@ -101,7 +158,7 @@ class DiscussController extends GetxController {
bookId: bookDetailModel.bookId.toString(),
key: searchInput.text
);
testData();
// testData();
Console.log('--------------------------------');
// 如果是刷新 清理数据
if (isRefresh) searchALlResults.clear();
......
......@@ -26,6 +26,7 @@ import 'package:just_audio/just_audio.dart' as just_audio;
import 'package:path_provider/path_provider.dart';
import 'dart:async';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'package:sqflite/sqflite.dart';
import '../../apis/index.dart';
import '../../models/index.dart';
......
......@@ -104,7 +104,7 @@ class _ReadPageState extends State<ReadPage> {
'chapter_id': readController.chapterId,
'token':UserStore.to.token
};
String str = '$kServerUrl,${readController.bookId},${readController.chapterId},${UserStore.to.token},${readController.noteId}';
String str = '$kServerUrl,${readController.bookId},${readController.chapterId},${UserStore.to.token},${readController.noteId},${readController.sModel.bookId =='0'?'':readController.sModel.combinedContent}';
Console.log('传给前端的参数--------------------------------$str');
controller.evaluateJavascript(source: 'callbackInFlutterComponent("$str");');
......@@ -159,7 +159,7 @@ class _ReadPageState extends State<ReadPage> {
Console.log('监听讨论回调------------------------------------------------$args');
readController.setShowChat(true);
readController.setChatType(0);
readController.titleInput.text = args.first.toString();
readController.noteTitle = args.first.toString();
});
controller.addJavaScriptHandler(handlerName: 'answerResultCallBack', callback: (args){
......@@ -194,7 +194,7 @@ class _ReadPageState extends State<ReadPage> {
controller.addJavaScriptHandler(handlerName: 'loadChapterCallBack', callback: (args){
String chapterId = args.first[0].toString();
String chapterName = args.first[1].toString();
readController.setChapterInfo(id: chapterId, name: chapterName);
readController.setChapterInfo(id: chapterId, name: chapterName ?? '');
Console.log('监听 上一节 下一节------------------------------------------------$args');
});
......@@ -209,6 +209,56 @@ class _ReadPageState extends State<ReadPage> {
context.pushNamed(Routes.link,queryParameters: {'url': args.first.toString()});
});
/// 离线需要参数
// //
// Map<String, dynamic> param111 = {
// 'book_id': readController.bookId,
// 'chapter_id': readController.chapterId,
// 'token':UserStore.to.token
// };
// String jsonStr = jsonEncode(param111);
// controller.evaluateJavascript(source: 'offlineCallbackInFlutterComponent($jsonStr)');
// // controller.evaluateJavascript(source: 'callbackInFlutterComponent("$str");');
// 添加高亮划线笔记
controller.addJavaScriptHandler(handlerName: 'offlineAddNoteCallBack', callback: (args){
Map<String, dynamic> data = {};
readController.addLocalNote(data);
});
// 删除高亮划线笔记
controller.addJavaScriptHandler(handlerName: 'offlineDelNoteCallBack', callback: (args){
int id = 0;
readController.delLocalNote(id: id);
});
// 更新高亮划线笔记
controller.addJavaScriptHandler(handlerName: 'offlineUpdateNoteCallBack', callback: (args){
int id = 0;
Map<String, dynamic> data = {};
readController.updateLocalNote(id: id,data: data);
});
// 查询高亮划线笔记
controller.addJavaScriptHandler(handlerName: 'offlineQueryNoteCallBack', callback: (args){
});
// 上一节下一节
controller.addJavaScriptHandler(handlerName: 'offlineReadNoteCallBack', callback: (args){
int type = 0;
// 上一节
if (type == 0){
readController.readChapter(type: 0);
}
// 下一节
else{
readController.readChapter(type: 1);
}
});
},
),
// AnimatedPositioned(
......@@ -347,10 +397,13 @@ class _ReadPageState extends State<ReadPage> {
controller.chooseTool(model);
},
// 点 搜索全部 列表 某一项 事件
onTapSearchItem: (){
onTapSearchItem: (SearchAllModel sModel){
controller.chooseTool(model);
// TODO:重新加载阅读界面 参数:chapter_id text
Console.log('-----------目录点击搜索条目---------------------');
controller.sModel = sModel;
controller.selectChapter(ChapterModel(id: sModel.chapterId,name: sModel.chapterName));
controller.webViewController.reload();
},
onTapChapter: (ChapterModel chapterModel){
Console.log('-----------选择的章节-------------${chapterModel.name}--------');
......@@ -370,10 +423,13 @@ class _ReadPageState extends State<ReadPage> {
controller.chooseTool(model);
},
// 点 搜索全部 列表 某一项 事件
onTapSearchItem: (){
onTapSearchItem: (SearchAllModel sModel){
controller.chooseTool(model);
// TODO:重新加载阅读界面 参数:chapter_id text
Console.log('-----------笔记点击搜索条目---------------------');
controller.sModel = sModel;
controller.selectChapter(ChapterModel(id: sModel.chapterId,name: sModel.chapterName));
controller.webViewController.reload();
},
bookDetailModel: controller.bookDetailModel,
chapterId: controller.chapterId,
......@@ -386,10 +442,13 @@ class _ReadPageState extends State<ReadPage> {
controller.chooseTool(model);
},
// 点 搜索全部 列表 某一项 事件
onTapSearchItem: (){
onTapSearchItem: (SearchAllModel sModel){
controller.chooseTool(model);
controller.sModel = sModel;
// TODO:重新加载阅读界面 参数:chapter_id text
Console.log('-----------讨论点击搜索条目---------------------');
controller.selectChapter(ChapterModel(id: sModel.chapterId,name: sModel.chapterName));
controller.webViewController.reload();
},
bookDetailModel: controller.bookDetailModel,
chapterId:controller.chapterId,
......@@ -402,17 +461,26 @@ class _ReadPageState extends State<ReadPage> {
Console.log('++++++++++++++++++++++++${model.tag}');
if (controller.show){
if(model.selected){
return Container(
color: const Color(0xFF000000).withOpacity(0.5),
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.2),
child: ClipRRect(
borderRadius: BorderRadius.only(topRight: Radius.circular(8.w),topLeft: Radius.circular(8.w)),
child: Container(
color: Colors.white,
child: detail(controller, model)
return GestureDetector(
onTap: (){
controller.chooseTool(model);
},
child: Container(
color: const Color(0xFF000000).withOpacity(0.5),
padding: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.2),
child: ClipRRect(
borderRadius: BorderRadius.only(topRight: Radius.circular(8.w),topLeft: Radius.circular(8.w)),
child: Container(
color: Colors.white,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: (){},
child: detail(controller, model),
)
),
),
// child: ReadCategoryPage(),
),
// child: ReadCategoryPage(),
);
}
else{
......
......@@ -4,7 +4,7 @@ class ReadCategoryPage extends StatefulWidget {
final ReadController controller;
final void Function()? onTap;
// 点击 搜索全文 中的列表事件
final void Function()? onTapSearchItem;
final void Function(SearchAllModel sModel)? onTapSearchItem;
final Function(ChapterModel chapterModel) onTapChapter;
const ReadCategoryPage({
Key? key,
......@@ -88,9 +88,9 @@ class _ReadCategoryPageState extends State<ReadCategoryPage> {
),
widget.controller.showSearch? Expanded(
child: BuildSearchAll(
onTap: (){
onTap: (SearchAllModel sModel){
if (widget.onTapSearchItem !=null) {
widget.onTapSearchItem!();
widget.onTapSearchItem!(sModel);
}
},
searchALlResults: widget.controller.searchALlResults
......
......@@ -4,7 +4,7 @@ class ReadDiscussPage extends StatefulWidget {
// 点 x 事件
final void Function()? onTap;
// 点击 搜索全文 中的列表事件
final void Function()? onTapSearchItem;
final void Function(SearchAllModel sModel)? onTapSearchItem;
final BookDetailModel bookDetailModel;
// 当前的章节id
final String chapterId;
......@@ -89,9 +89,9 @@ class _ReadDiscussPageState extends State<ReadDiscussPage> {
),
controller.showSearch? Expanded(
child: BuildSearchAll(
onTap: (){
onTap: (SearchAllModel sModel){
if (widget.onTapSearchItem !=null) {
widget.onTapSearchItem!();
widget.onTapSearchItem!(sModel);
}
},
searchALlResults: controller.searchALlResults,
......@@ -103,14 +103,21 @@ class _ReadDiscussPageState extends State<ReadDiscussPage> {
ListView.builder(
itemBuilder: (BuildContext context,int index){
DiscussModel model = controller.discuss[index];
return BuildDiscuss(model: model,controller: controller,);
return BuildDiscuss(
model: model,
controller: controller,
bookId: widget.bookDetailModel.bookId.toString(),
onTapDel: (DiscussModel dModel){
controller.delComment(discussModel: dModel);
},
);
},
itemCount: controller.discuss.length,
),
Visibility(
visible: controller.showReply,
child: Positioned(
bottom: MediaQuery.of(context).viewInsets.bottom -49 ,
bottom: MediaQuery.of(context).viewInsets.bottom -69 ,
left: 0,
right: 0,
child: Container(
......
......@@ -22,31 +22,37 @@ class _ReadInputDiscussState extends State<ReadInputDiscuss> {
children: [
Container(
margin: EdgeInsets.symmetric(vertical: 10.w),
child: widget.controller.chatType ==0?Row(
child: widget.controller.chatType ==0?Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('话题',style: TextStyle(fontSize: 14.w,color: Colours.c3,height: 1.5,fontWeight: Fonts.medium),),
Gaps.hGaps5,
Expanded(
child: ClipRRect(
borderRadius: BorderRadius.circular(4),
child: TextField(
focusNode: widget.controller.discussTitleFocusNode,
controller: widget.controller.titleInput,
autofocus: true,
decoration: InputDecoration(
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
hintText: '请输入话题名称',
hintStyle:TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c9,),
filled: true,
fillColor: Colours.cF8,
widget.controller.noteTitle.isEmpty?const SizedBox():Text('"${widget.controller.noteTitle}"',style: TextStyle(fontSize: 12.w,height: 1.4,color: Colours.c9),),
Row(
children: [
Text('话题',style: TextStyle(fontSize: 14.w,color: Colours.c3,height: 1.5,fontWeight: Fonts.medium),),
Gaps.hGaps5,
Expanded(
child: ClipRRect(
borderRadius: BorderRadius.circular(4),
child: TextField(
focusNode: widget.controller.discussTitleFocusNode,
controller: widget.controller.titleInput,
autofocus: true,
decoration: InputDecoration(
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
hintText: '请输入话题名称',
hintStyle:TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c9,),
filled: true,
fillColor: Colours.cF8,
),
onSubmitted: (_){
FocusScope.of(context).requestFocus(widget.controller.discussContentFocusNode);
},
),
),
onSubmitted: (_){
FocusScope.of(context).requestFocus(widget.controller.discussContentFocusNode);
},
),
),
],
),
],
):Text('"${widget.controller.noteTitle}"',style: TextStyle(fontSize: 12.w,height: 1.4,color: Colours.c9),),
......
......@@ -16,82 +16,171 @@ class BuildItem extends StatefulWidget {
class _BuildItemState extends State<BuildItem> {
@override
Widget build(BuildContext context) {
return _buildChapter(widget.model);
// Column(
// children: [
// /// 章节名称容器
// GestureDetector(
// onTap: (){
// if(widget.model.children!.isEmpty){
// widget.onTapChapter(widget.model);
// }
// },
// child: Container(
// padding: EdgeInsets.symmetric(horizontal: 15.w),
// height: 30.w,
// color: Colors.white,
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Row(
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// Text(widget.model.name??'',style: TextStyle(fontSize: 14.w,color: widget.model.seen ==0? Colours.c3:Colours.c9,fontWeight: Fonts.boldSemi,height: 2),),
// Gaps.hGaps5,
// widget.model.isReading == 1? Container(
// height: 18,
// width: 18,
// margin: EdgeInsets.only(top: 6.w),
// alignment: Alignment.center,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(8.5.w),
// border: Border.all(width:1,color: AppTheme.primary)
// ),
// child: Text('试',style: TextStyle(fontSize: 11.w,color: AppTheme.primary),),
// ):const SizedBox(),
// ],
// ),
// Transform.rotate(
// angle: widget.model.selected?0:-90 * (3.141592653589793 / 180),
// child: GestureDetector(
// onTap: (){
// setState(() {
// widget.model.selected = !widget.model.selected;
// });
// },
// child: SizedBox(
// width: 20.w,
// height: 20.w,
// child: Image.asset('assets/images/down.png')
// ),
// )
// )
//
// ],
// )
// ),
// ),
// /// 节的名称容器
// Visibility(
// visible: widget.model.selected,
// child: ListView.builder(
// shrinkWrap: true,
// physics: const NeverScrollableScrollPhysics(),
// itemBuilder: (BuildContext context, int index){
// ChapterModel model = widget.model.children![index];
// return GestureDetector(
// onTap: (){
// widget.onTapChapter(model);
// },
// child: _buildSection(model)
// );
// },
// itemCount: widget.model.children!.length,
// )
// )
// ],
// );
}
Widget _buildChapter(ChapterModel chapterModel){
return Column(
children: [
/// 章节名称容器
GestureDetector(
onTap: (){
if(widget.model.children!.isEmpty){
widget.onTapChapter(widget.model);
}
widget.onTapChapter(chapterModel);
// // 如果章下面没有节 点击才会跳转
// if (widget.model.children!.isEmpty){
// widget.onTap(widget.model);
// // context.pushNamed(Routes.web,queryParameters: {'book_id': widget.bookDetails.bookId.toString(),'chapter_id': widget.model.id.toString(),'chapter_name':widget.model.name.toString()},extra: widget.bookDetails);
// }
// setState(() {
// widget.model.selected = !widget.model.selected;
// });
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 15.w),
height: 30.w,
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(widget.model.name??'',style: TextStyle(fontSize: 14.w,color: widget.model.seen ==0? Colours.c3:Colours.c9,fontWeight: Fonts.boldSemi,height: 2),),
Gaps.hGaps5,
widget.model.isReading == 1? Container(
height: 18,
width: 18,
margin: EdgeInsets.only(top: 6.w),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.5.w),
border: Border.all(width:1,color: AppTheme.primary)
),
child: Text('试',style: TextStyle(fontSize: 11.w,color: AppTheme.primary),),
):const SizedBox(),
],
),
Transform.rotate(
angle: widget.model.selected?0:-90 * (3.141592653589793 / 180),
child: GestureDetector(
onTap: (){
setState(() {
widget.model.selected = !widget.model.selected;
});
},
child: SizedBox(
width: 20.w,
height: 20.w,
child: Image.asset('assets/images/down.png')
),
)
)
padding: EdgeInsets.symmetric(horizontal: 15.w),
height: 30.w,
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(chapterModel.name??'',style: TextStyle(fontSize: 14.w,color: chapterModel.seen ==0? Colours.c3:Colours.c9,fontWeight: Fonts.medium,height: 2),),
Gaps.hGaps5,
chapterModel.isReading == 1? Container(
margin: const EdgeInsets.fromLTRB(0, 6, 0, 0),
height: 18,
width: 18,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.5.w),
border: Border.all(width:1,color: AppTheme.primary)
),
child: Text('试',style: TextStyle(fontSize: 11.w,color: AppTheme.primary),),
):const SizedBox(),
],
),
Transform.rotate(
angle: chapterModel.selected?0:-90 * (3.141592653589793 / 180),
child: GestureDetector(
onTap: (){
setState(() {
chapterModel.selected = !chapterModel.selected;
});
},
child: Container(
width: 20.w,
height: 20.w,
// color: Colors.red,
child: Image.asset('assets/images/down.png')
),
)
)
],
)
],
)
),
),
/// 节的名称容器
Visibility(
visible: widget.model.selected,
visible: chapterModel.selected,
child: ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index){
ChapterModel model = widget.model.children![index];
return GestureDetector(
onTap: (){
widget.onTapChapter(model);
},
child: _buildSection(model)
);
},
itemCount: widget.model.children!.length,
itemBuilder: (BuildContext context, int index){
ChapterModel model = chapterModel.children![index];
return Container(
padding: EdgeInsets.only(left: 20.w,bottom: 4.w),
child: _buildChapter(model)
);
// GestureDetector(
// onTap: (){
// widget.onTap(model);
// // context.pushNamed(Routes.web,queryParameters: {'book_id': widget.bookDetails.bookId.toString(),'chapter_id':model.id.toString(),'chapter_name':model.name.toString()},extra: widget.bookDetails);
// },
// child: _buildSection(model)
// );
},
itemCount: chapterModel.children!.length,
)
)
],
);
}
Widget _buildSection(ChapterModel model){
return Container(
color: Colors.white,
......
......@@ -3,7 +3,7 @@ part of web;
class ReadNotePage extends StatefulWidget {
final BookDetailModel bookDetailModel;
// 点击 搜索全文 中的列表事件
final void Function()? onTapSearchItem;
final void Function(SearchAllModel sModel)? onTapSearchItem;
// 当前的章节id
final String chapterId;
final void Function()? onTap;
......@@ -86,9 +86,9 @@ class _ReadNotePageState extends State<ReadNotePage> {
],
),
controller.showSearch? Expanded(child: BuildSearchAll(
onTap: (){
onTap: (SearchAllModel sModel){
if (widget.onTapSearchItem !=null) {
widget.onTapSearchItem!();
widget.onTapSearchItem!(sModel);
}
},
searchALlResults: controller.searchALlResults
......
part of web;
class BuildSearchAll extends StatefulWidget {
final void Function()? onTap;
final void Function(SearchAllModel sModel)? onTap;
final List<SearchAllModel> searchALlResults;
const BuildSearchAll({
......@@ -23,14 +23,14 @@ class _BuildSearchAllState extends State<BuildSearchAll> {
return GestureDetector(
onTap: (){
if(widget.onTap !=null){
widget.onTap!();
widget.onTap!(model);
}
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
// color: Colors.red,
color: Colors.white,
margin: EdgeInsets.only(left: 15.w,top: 8.w),
// height: 110,
child: Column(
......
......@@ -73,7 +73,7 @@ class _AboutPageState extends State<AboutPage> {
],
),
Gaps.hGaps10,
Text('Copyright © 2024 Zijing Education. All rights reserved.\n清控紫荆(北京)教育科技股份有限公司\nICP证150431号',style: TextStyle(color: Colours.c9,fontSize:9.w),textAlign: TextAlign.center,),
Text('Copyright © 2024 Zijing Education. All rights reserved.\n清控紫荆(北京)教育科技股份有限公司\nICP证150431号',style: TextStyle(color: Colours.c9,fontSize:9.w),textAlign: TextAlign.center,),
Gaps.vGaps25,
],
),
......
......@@ -10,24 +10,123 @@ class UserDiscussDesController extends GetxController {
controlFinishLoad: true,
controlFinishRefresh: true,
);
late TextEditingController replyInput = TextEditingController();
final int _limit = 10;
int _page = 1;
bool _noMore = false;
// 展示回复输入框
bool showReply = false;
// 当前要回复的模型
late DiscussModel discussModel;
// 当前要回复父级的模型
late DiscussModel fatherDiscussModel;
@override
void onReady() {
onRefresh();
// onRefresh();
super.onReady();
}
@override
void onClose() {
refreshController.dispose();
replyInput.dispose();
super.onClose();
}
void setShow() {
showReply = !showReply;
update();
}
void setDiscussModel(DiscussModel model){
discussModel = model;
}
void setFatherDiscussModel(DiscussModel model){
fatherDiscussModel = model;
}
// 删除回复
Future<void> delComment({required DiscussModel discussModel}) async {
final result = await LibraryAPI.delComment(bookId:model.bookId!, commentId: discussModel.id!);
if(result){
discuss.remove(discussModel);
Toast.show('删除成功');
}
update();
}
Future<bool> submit() async {
Map<String,dynamic> contentMap = {
'text':replyInput.text,
'audio':[],
'image':[]
};
final result = await LibraryAPI.addDiscuss(
bookId: model.bookId.toString(),
chapterId: discussModel.chapterId.toString(),
commentId: discussModel.id.toString(),
quoteContent: '',
title: '',
content: jsonEncode(contentMap)
);
if(result){
Toast.show('发表成功');
discussModel.replyNum = discussModel.replyNum! +1;
DiscussModel tempModel = DiscussModel.fromJson(discussModel.toJson());
tempModel.status = 1;
tempModel.commentsCheck = 0;
tempModel.isMy = 1;
NoteContentModel contentModel = NoteContentModel(
text: MediaModel(content:replyInput.text,privacyStatus: 1)
);
tempModel.content= contentModel;
tempModel.content?.text?.privacyStatus = 1;
tempModel.replacePersonName = discussModel.personName;
tempModel.replacePersonPic = discussModel.personPic;
tempModel.replyNum = 0;
fatherDiscussModel.commentAll?.add(tempModel);
// fatherDiscussModel.replyNum = fatherDiscussModel.commentAll?.length;
}
else{
Toast.show('发表失败');
}
replyInput.text = '';
update();
// 重置所有信息
// reset();
// setShowChat(false);
return result;
}
Future<void> commentLove({required DiscussModel discussModel}) async {
num type = 0;
if (discussModel.isPraise ==0){
type = 1;
}
final result = await LibraryAPI.commentLove(bookId:model.bookId! , type: type, commentId: discussModel.id!);
if(result){
num goodNum = discussModel.goodNum??0;
if(type ==0){
goodNum --;
}
else{
goodNum ++;
}
discussModel.isPraise = type;
discussModel.goodNum = goodNum;
}
update();
}
/// 获取讨论详情
Future<void> _getDiscuss([bool isRefresh = false]) async {
......
library user_discuss_des;
import 'dart:convert';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart';
import 'package:flutter_book/widgets/index.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:get/get.dart';
import 'package:go_router/go_router.dart';
......
......@@ -3,10 +3,16 @@ part of user_discuss_des;
class BuildDiscuss extends StatefulWidget {
final DiscussModel model;
final DiscussController? controller;
final String bookId;
final void Function(DiscussModel dModel)? onTapDel;
final UserDiscussDesController? userDiscussDesController;
const BuildDiscuss({
Key? key,
required this.model,
this.controller
this.controller,
required this.bookId,
this.userDiscussDesController,
this.onTapDel,
}) : super(key: key);
@override
......@@ -33,205 +39,242 @@ class _BuildDiscussState extends State<BuildDiscuss> {
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RichText(text: TextSpan(
children: [
TextSpan(text: '话题:',style: TextStyle(
fontSize: 14.w,
height: 1.5.w,
color: Colours.c3,
)),
TextSpan(text: widget.model.title,style: TextStyle(
fontSize: 14.w,
height: 1.5.w,
color: Colours.c3,
fontWeight: Fonts.medium
)),
]
)),
Gaps.vGaps10,
Container(
height: 0.5.w,
color: Colours.cF2,
),
_buildItem(widget.model),
Container(
margin:EdgeInsets.only(left: 15.w),
child: _buildListView(widget.model.commentAll != null ? widget.model.commentAll!:[])
),
Gaps.vGaps13,
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(vertical: 5.w,horizontal: 10.w),
color: Colours.cF8,
child:Column(
crossAxisAlignment: CrossAxisAlignment.start,
child: Slidable(
enabled: widget.model.isMy == 1 ? true : false,
endActionPane: ActionPane(
motion: const ScrollMotion(),
children: [
SlidableAction(
// An action can be bigger than the others.
onPressed: (BuildContext context){
if (widget.onTapDel !=null) widget.onTapDel!(widget.model);
},
backgroundColor: const Color(0xFFAE1414),
foregroundColor: Colors.white,
// icon: Icons.archive,
label: '删除',
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RichText(text: TextSpan(
children: [
Text(widget.model.chapterName??'',style: TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c9),),
Text('内容:${widget.model.quoteContent??''}',style: TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c9),),
],
TextSpan(text: '话题:',style: TextStyle(
fontSize: 14.w,
height: 1.5.w,
color: Colours.c3,
)),
TextSpan(text: widget.model.title,style: TextStyle(
fontSize: 14.w,
height: 1.5.w,
color: Colours.c3,
fontWeight: Fonts.medium
)),
]
)),
Gaps.vGaps10,
Container(
height: 0.5.w,
color: Colours.cF2,
),
_buildItem(widget.model,widget.model),
Container(
margin:EdgeInsets.only(left: 15.w),
child: _buildListView(widget.model)
),
Gaps.vGaps13,
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(vertical: 5.w,horizontal: 10.w),
color: Colours.cF8,
child:Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(widget.model.chapterName??'',style: TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c9),),
Text('内容:${widget.model.quoteContent??''}',style: TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c9),),
],
)
)
)
],
],
),
),
);
}
Widget _buildItem(DiscussModel model,{int type =0}){
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.only(top: 10.w),
child: ClipRRect(
borderRadius: BorderRadius.circular(17.5.w),
child: Container(
width: 35.w,
height: 35.w,
color: Colors.red,
child: CustomImage.network(url: model.personPic??''),
Widget _buildItem(DiscussModel fatherModel, DiscussModel model,{int type =0}){
return Slidable(
enabled: type ==0?false: model.isMy == 1 ? true : false,
endActionPane: ActionPane(
motion: const ScrollMotion(),
children: [
SlidableAction(
// An action can be bigger than the others.
onPressed: (BuildContext context){
if (widget.onTapDel !=null) widget.onTapDel!(model);
},
backgroundColor: const Color(0xFFAE1414),
foregroundColor: Colors.white,
// icon: Icons.archive,
label: '删除',
),
],
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.only(top: 10.w),
child: ClipRRect(
borderRadius: BorderRadius.circular(17.5.w),
child: Container(
width: 35.w,
height: 35.w,
child: CustomImage.network(url: model.personPic??''),
),
),
),
),
Expanded(
child: Container(
margin: EdgeInsets.only(left: 10.w,top: 10.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Text(model.personName??'',style: TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c9),),
Gaps.hGaps10,
type ==1?const SizedBox(): Text('发起人',style: TextStyle(fontSize: 11.w,height: 1.5,color: AppTheme.primary),)
],
),
Text(model.createTime??'',style: TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c9),)
],
),
type ==0? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(_showText(model),style: TextStyle(fontSize: 13.w,height: 1.5,color: Colours.c3),),
Text(_showStatus(model),style: TextStyle(fontSize: 13.w,height: 1.5,color: AppTheme.primary),),
],
),
Gaps.vGaps10,
_buildImageGridView()
],
)
:RichText(text: TextSpan(
children: [
TextSpan(text: '回复 ',style: TextStyle(fontSize: 13.w,height: 1.5,color: Colours.c3)),
TextSpan(text: model.replacePersonName??'',style: TextStyle(fontSize: 13.w,height: 1.5,color: Colours.c9)),
TextSpan(text: ':${model.content?.text?.content??''}',style: TextStyle(fontSize: 13.w,height: 1.5,color: Colours.c3)),
]
)),
SizedBox(height: 10.w,),
Row(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 20.w,
width: 20.w,
// color: Colors.green,
child: Image.asset('assets/images/love.png',fit: BoxFit.cover,),
),
Text(model.goodNum.toString(),style: TextStyle(fontSize:12.w,height: 1.5,color: Colours.c9))
],
),
Gaps.hGaps15,
Row(
children: [
GestureDetector(
onTap:(){
// _showKeyboard(context);
widget.controller?.setShow();
widget.controller?.setDiscussModel(model);
},
child: Container(
height: 25.w,
width: 15.w,
// color: Colors.yellow,
child: Image.asset('assets/images/reply.png',height: 15.w,width: 15.w,fit: BoxFit.fitWidth,),
Expanded(
child: Container(
margin: EdgeInsets.only(left: 10.w,top: 10.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Text(model.personName??'',style: TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c9),),
Gaps.hGaps10,
type ==1?const SizedBox(): Text('发起人',style: TextStyle(fontSize: 11.w,height: 1.5,color: AppTheme.primary),)
],
),
Text(model.createTime??'',style: TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c9),)
],
),
type ==0? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_showText(model).isEmpty?const SizedBox():Row(
children: [
Text(_showText(model),style: TextStyle(fontSize: 13.w,height: 1.5,color: Colours.c3),),
Text(_showStatus(model),style: TextStyle(fontSize: 11.w,height: 1.5,color: AppTheme.primary),),
],
),
Gaps.vGaps10,
_buildImageGridView()
],
)
:RichText(text: TextSpan(
children: [
TextSpan(text: '回复 ',style: TextStyle(fontSize: 13.w,height: 1.5,color: Colours.c3)),
TextSpan(text: model.replacePersonName??'',style: TextStyle(fontSize: 13.w,height: 1.5,color: Colours.c9)),
TextSpan(text: ':${_showText(model)}',style: TextStyle(fontSize: 13.w,height: 1.5,color: Colours.c3)),
TextSpan(text: _showStatus(model),style: TextStyle(fontSize: 11.w,height: 1.5,color: AppTheme.primary)),
]
)),
SizedBox(height: 10.w,),
Row(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: () async{
widget.controller?.commentLove(discussModel: model);
widget.userDiscussDesController?.commentLove(discussModel: model);
},
child: SizedBox(
height: 20.w,
width: 20.w,
// color: Colors.green,
child: Image.asset(model.isPraise ==0?'assets/images/unlove.png': 'assets/images/love.png',fit: BoxFit.cover,),
),
),
),
SizedBox(width: 3.w,),
Text(model.replyNum.toString(),style: TextStyle(fontSize:12.w,height: 1.5,color: Colours.c9))
],
)
],
)
],
Text(model.goodNum.toString(),style: TextStyle(fontSize:12.w,height: 1.5,color: Colours.c9))
],
),
Gaps.hGaps15,
Row(
children: [
GestureDetector(
onTap:(){
// _showKeyboard(context);
// 阅读页讨论列表
widget.controller?.setShow();
widget.controller?.setDiscussModel(model);
widget.controller?.setFatherDiscussModel(fatherModel);
// 我的讨论详情页列表
widget.userDiscussDesController?.setShow();
widget.userDiscussDesController?.setDiscussModel(model);
widget.userDiscussDesController?.setFatherDiscussModel(fatherModel);
},
child: Container(
height: 25.w,
width: 15.w,
// color: Colors.yellow,
child: Image.asset('assets/images/reply.png',height: 15.w,width: 15.w,fit: BoxFit.fitWidth,),
),
),
SizedBox(width: 3.w,),
Text(model.replyNum.toString(),style: TextStyle(fontSize:12.w,height: 1.5,color: Colours.c9))
],
)
],
)
],
),
),
),
)
],
)
],
),
);
}
String _showText(DiscussModel discussModel){
String text = '';
// 是我的
if(discussModel.isMy == 1){
text = '${discussModel.content?.text?.content}';
}
else {
if(discussModel.content?.text?.privacyStatus ==1){
text = '${discussModel.content?.text?.content}';
}
}
// if(discussModel.isMy == 1){
// text = '${discussModel.content?.text?.content}';
// }
text = '${discussModel.content?.text?.content}';
return text;
}
String _showStatus(DiscussModel discussModel){
String text = '';
// 是我的
if(discussModel.isMy == 1){
// 审核中
if(discussModel.content?.text?.privacyStatus ==0 ||discussModel.content?.text?.privacyStatus ==2){
text = '(审核中)';
}
// 审核未通过
else if(discussModel.content?.text?.privacyStatus ==-1){
text = '(审核未通过)';
}
// 审核通过
else {
text = '';
}
}
else {
// 审核中
if(discussModel.content?.text?.privacyStatus ==0 ||discussModel.content?.text?.privacyStatus ==2){
text = '(审核中)';
}
// 审核未通过
else if(discussModel.content?.text?.privacyStatus ==-1){
text = '(审核未通过)';
}
// 审核通过
else {
text = '';
if(discussModel.commentsCheck == 1){
// 审核中
if(discussModel.content?.text?.privacyStatus ==0 ||discussModel.content?.text?.privacyStatus ==2 ||discussModel.status == 0){
text = '(审核中)';
}
// 审核未通过
else if(discussModel.content?.text?.privacyStatus ==-1 ||discussModel.status == 2){
text = '(审核未通过)';
}
}else{
// 审核中
if(discussModel.content?.text?.privacyStatus ==0 ||discussModel.content?.text?.privacyStatus ==2){
text = '(审核中)';
}
// 审核未通过
else if(discussModel.content?.text?.privacyStatus ==-1){
text = '(审核未通过)';
}
}
}
return text;
}
Widget _buildListView(List<DiscussModel> data){
Widget _buildListView(DiscussModel model){
List<DiscussModel> data = model.commentAll != null ?model.commentAll!:[];
return ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context,int index){
return _buildItem(data[index],type: 1);
return _buildItem(model,data[index],type: 1);
},
itemCount: data.length,
);
......
......@@ -24,13 +24,95 @@ class _BuildListPageState extends State<BuildListPage> with AutomaticKeepAliveCl
controller: controller.refreshController,
onRefresh: controller.onRefresh,
onLoading: controller.onLoading,
child: ListView.builder(
itemBuilder: (BuildContext context,int index){
DiscussModel model = controller.discuss[index];
return BuildDiscuss(model: model,);
},
itemCount: controller.discuss.length,
),
child: Stack(
children: [
ListView.builder(
itemBuilder: (BuildContext context,int index){
DiscussModel model = controller.discuss[index];
return BuildDiscuss(
model: model,
bookId: widget.model.bookId.toString(),
userDiscussDesController: controller,
onTapDel: (DiscussModel dModel){
controller.delComment(discussModel: dModel);
},
);
},
itemCount: controller.discuss.length,
),
Visibility(
visible: controller.showReply,
child: Positioned(
bottom: 0 ,
left: 0,
right: 0,
top: 0,
child: GestureDetector(
onTap: (){
controller.setShow();
},
child: Container(
color: const Color(0xFF000000).withOpacity(0.5),
child: SingleChildScrollView(
reverse: true,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: (){},
child: Container(
color: Colors.white,
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
autofocus: true,
maxLines: null,
controller: controller.replyInput,
decoration: InputDecoration(
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
hintText: '请输入内容',
hintStyle:TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c9,),
filled: true,
fillColor: Colours.cF8,
),
),
),
Gaps.hGaps10,
GestureDetector(
onTap: (){
controller.submit();
controller.setShow();
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.w),
color: AppTheme.primary,
gradient: LinearGradient(
colors: [const Color(0xFFD53676).withOpacity(0.9),AppTheme.primary] , // 不可点击时的颜色,透明度为0.7
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
padding: EdgeInsets.symmetric(horizontal:13.5.w,vertical: 4.w),
child: Text('发表',style: TextStyle(fontSize: 14.w,fontWeight: Fonts.medium,color: Colors.white),),
),
)
],
),
),
),
),
),
),
),
),
)
],
)
),
);
}
......
......@@ -21,8 +21,13 @@ class MsgController extends GetxController {
}
/// 消息未读变已读
Future<bool> read(String id) async {
bool result = await CommonAPI.read(id: id);
Future<bool> read(MsgModel model) async {
final result = await CommonAPI.read(id: model.id.toString());
if (result){
model.status = 1;
}
update();
return result;
}
......
......@@ -31,7 +31,7 @@ class MsgPage extends StatelessWidget {
return GestureDetector(
child: BuildItem(model:model,),
onTap: () async{
controller.read(model.id.toString());
controller.read(model);
if(model.type == 1){
// final result = await context.pushNamed(Routes.order);
......@@ -46,7 +46,7 @@ class MsgPage extends StatelessWidget {
final result = await context.pushNamed(Routes.orderAwaiting,
queryParameters: {'orderNum': model.urlId?.orderNum.toString()});
if (result == true){
controller.onRefresh();
// controller.onRefresh();
}
}
// 充值订单
......@@ -54,7 +54,7 @@ class MsgPage extends StatelessWidget {
final result = await context.pushNamed(Routes.orderCoinAwaiting,
queryParameters: {'orderNum': model.urlId?.orderNum.toString()});
if (result == true){
controller.onRefresh();
// controller.onRefresh();
}
}
......@@ -65,14 +65,14 @@ class MsgPage extends StatelessWidget {
final result = await context.pushNamed(Routes.orderCancel,
queryParameters: {'orderNum': model.urlId?.orderNum.toString()});
if (result == true){
controller.onRefresh();
// controller.onRefresh();
}
}
else {
final result = await context.pushNamed(Routes.orderCoinCancel,
queryParameters: {'orderNum': model.urlId?.orderNum.toString()});
if (result == true){
controller.onRefresh();
// controller.onRefresh();
}
}
}
......@@ -82,14 +82,14 @@ class MsgPage extends StatelessWidget {
final result = await context.pushNamed(Routes.orderCompleted,
queryParameters: {'orderNum': model.urlId?.orderNum.toString()});
if (result == true){
controller.onRefresh();
// controller.onRefresh();
}
}
else {
final result = await context.pushNamed(Routes.orderCoinCompleted,
queryParameters: {'orderNum': model.urlId?.orderNum.toString()});
if (result == true){
controller.onRefresh();
// controller.onRefresh();
}
}
}
......@@ -99,7 +99,7 @@ class MsgPage extends StatelessWidget {
final result = await context.pushNamed(Routes.orderRefunded,
queryParameters: {'orderNum': model.urlId?.orderNum.toString()});
if (result == true){
controller.onRefresh();
// controller.onRefresh();
}
}
}
......@@ -114,28 +114,28 @@ class MsgPage extends StatelessWidget {
//
final result = await context.pushNamed(Routes.order);
if (result == true){
controller.onRefresh();
// controller.onRefresh();
}
///TODO:
}else if (model.type == 3){
// 3 讨论有人回复的时候 (跳转对应书籍的讨论页面)
final result = await context.pushNamed(Routes.bookDetail,queryParameters: {'book_id':model.urlId?.bookId.toString()});
if (result == true){
controller.onRefresh();
// controller.onRefresh();
}
}
else if (model.type == 4){
// 4 订单完成后有新的积分增加(跳转用户积分记录页)
final result = await context.pushNamed(Routes.point);
if (result == true){
controller.onRefresh();
// controller.onRefresh();
}
}else if (model.type == 5){
// 5后台直接发放给指定用户优惠券(跳转到用户优惠券页)
final result = await context.pushNamed(Routes.coupon);
if (result == true){
controller.onRefresh();
// controller.onRefresh();
}
}
......
......@@ -34,8 +34,11 @@ class _UserNotePageState extends State<UserNotePage> {
// shrinkWrap: true,
itemBuilder: (BuildContext context, int index){
return GestureDetector(
onTap: (){
context.pushNamed(Routes.noteDes,extra: controller.notes[index]);
onTap: () async {
final result = await context.pushNamed(Routes.noteDes,extra: controller.notes[index]);
if(result == true){
controller.onRefresh;
}
},
child: BuildItem(model: controller.notes[index],)
);
......
......@@ -63,12 +63,13 @@ class UserNotesDesController extends GetxController {
// currentPlayMediaModel = mediaModel;
}
void delNotes({required String notesId,required String bookId}) async {
final result = await MineAPI.delNotes(notesId: notesId, bookId: bookId);
void delNotes({required NoteModel noteModel,required String bookId}) async {
final result = await MineAPI.delNotes(notesId: noteModel.notesId.toString(), bookId: bookId);
if (result){
Toast.show('删除笔记成功');
onRefresh();
notes.remove(noteModel);
}
update();
}
/// 获取笔记列表
......
......@@ -22,51 +22,57 @@ class _UserNotesDesPageState extends State<UserNotesDesPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('笔记详情'),
),
body: DefaultTabController(
length: tabs.length,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
BuildItem(model: widget.model),
ClipRRect(
borderRadius:const BorderRadius.only(topLeft: Radius.circular(5),topRight: Radius.circular(5)),
child: Container(
width: double.infinity,
color: Colors.white,
height: 35.w,
child: TabBar(
indicator: UnderlineTabIndicator(
borderRadius: BorderRadius.circular(0.75),
borderSide: BorderSide(width: 1.5.w,color: AppTheme.primary),
insets: EdgeInsets.symmetric(horizontal: 22.w), // 设置标签下面指示器的水平内边距
),
labelPadding: EdgeInsets.symmetric(horizontal: 20.w),
indicatorSize: TabBarIndicatorSize.label,
indicatorColor: AppTheme.primary,
indicatorWeight: 1.5,
labelStyle: TextStyle(color: AppTheme.primary,fontSize: 15.w,height: 1.5,fontWeight: Fonts.medium),
unselectedLabelColor: Colours.c9,
unselectedLabelStyle: TextStyle(color: Colours.c9,fontSize: 15.w,height: 1.5),
isScrollable: true,
tabs: tabs
return WillPopScope(
onWillPop: () async {
context.pop(true);
return false;
},
child: Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('笔记详情'),
),
body: DefaultTabController(
length: tabs.length,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
BuildItem(model: widget.model),
ClipRRect(
borderRadius:const BorderRadius.only(topLeft: Radius.circular(5),topRight: Radius.circular(5)),
child: Container(
width: double.infinity,
color: Colors.white,
height: 35.w,
child: TabBar(
indicator: UnderlineTabIndicator(
borderRadius: BorderRadius.circular(0.75),
borderSide: BorderSide(width: 1.5.w,color: AppTheme.primary),
insets: EdgeInsets.symmetric(horizontal: 22.w), // 设置标签下面指示器的水平内边距
),
labelPadding: EdgeInsets.symmetric(horizontal: 20.w),
indicatorSize: TabBarIndicatorSize.label,
indicatorColor: AppTheme.primary,
indicatorWeight: 1.5,
labelStyle: TextStyle(color: AppTheme.primary,fontSize: 15.w,height: 1.5,fontWeight: Fonts.medium),
unselectedLabelColor: Colours.c9,
unselectedLabelStyle: TextStyle(color: Colours.c9,fontSize: 15.w,height: 1.5),
isScrollable: true,
tabs: tabs
),
),
),
),
Expanded(
child: TabBarView(
children: List.generate(tabs.length, (index){
return BuildListPage(tag:'$index',model:widget.model);
})
),
)
],
)
Expanded(
child: TabBarView(
children: List.generate(tabs.length, (index){
return BuildListPage(tag:'$index',model:widget.model);
})
),
)
],
)
),
),
);
);
}
}
......@@ -36,7 +36,7 @@ class _BuildListPageState extends State<BuildListPage> with AutomaticKeepAliveCl
},
child: BuildLine(model: model,
onTapDel: (){
controller.delNotes(notesId: model.notesId.toString(), bookId:widget.model.bookId.toString());
controller.delNotes(noteModel: model, bookId:widget.model.bookId.toString());
},
),
);
......@@ -50,7 +50,7 @@ class _BuildListPageState extends State<BuildListPage> with AutomaticKeepAliveCl
},
child: BuildHigh(model: model,
onTapDel: (){
controller.delNotes(notesId: model.notesId.toString(), bookId:widget.model.bookId.toString());
controller.delNotes(noteModel: model, bookId:widget.model.bookId.toString());
},
),
);
......@@ -59,7 +59,7 @@ class _BuildListPageState extends State<BuildListPage> with AutomaticKeepAliveCl
else if(model.types == 3){
return BuildNote(model: model,
onTapDel: (){
controller.delNotes(notesId: model.notesId.toString(), bookId:widget.model.bookId.toString());
controller.delNotes(noteModel: model, bookId:widget.model.bookId.toString());
},
onTapEdit: (){
context.pushNamed(Routes.editNote,extra: model,queryParameters: {'book_id':widget.model.bookId.toString()});
......
......@@ -72,7 +72,7 @@ class BuildNote extends StatelessWidget {
// color: Colors.red,
color:Colours.c3
),),
Text(_showStatus(model),style: TextStyle(fontSize: 14.w,height: 1.5,color: AppTheme.primary),),
Text(_showStatus(model),style: TextStyle(fontSize: 11.w,height: 1.5,color: AppTheme.primary),),
],
),
Gaps.vGaps13,
......@@ -102,15 +102,11 @@ class BuildNote extends StatelessWidget {
String _showText(NoteModel discussModel){
String text = '';
// 是我的
if(discussModel.isMy == 1){
text = '${discussModel.noteContent?.text?.content}';
}
else {
if(discussModel.noteContent?.text?.privacyStatus ==1){
text = '${discussModel.noteContent?.text?.content}';
}
}
// // 是我的
// if(discussModel.isMy == 1){
// text = '${discussModel.noteContent?.text?.content}';
// }
text = '${discussModel.noteContent?.text?.content}';
return text;
}
String _showStatus(NoteModel discussModel){
......@@ -130,20 +126,6 @@ class BuildNote extends StatelessWidget {
text = '';
}
}
else {
// 审核中
if(discussModel.noteContent?.text?.privacyStatus ==0 ||discussModel.noteContent?.text?.privacyStatus ==2){
text = '(审核中)';
}
// 审核未通过
else if(discussModel.noteContent?.text?.privacyStatus ==-1){
text = '(审核未通过)';
}
// 审核通过
else {
text = '';
}
}
return text;
}
// 图片
......@@ -184,7 +166,7 @@ class BuildNote extends StatelessWidget {
child: Container(
alignment: Alignment.center,
color: model.isMy==1?Colours.c9.withOpacity(0.5):Colours.c9.withOpacity(1),
child: Text('(审核中)',style: TextStyle(fontSize: 14.w,height: 1.5,color: AppTheme.primary),),
child: Text('(审核中)',style: TextStyle(fontSize: 11.w,height: 1.5,color: AppTheme.primary),),
)
),
),
......
......@@ -128,7 +128,7 @@ class BuiltAwaiting extends StatelessWidget {
child: Align(
alignment: Alignment.center,
child: Text(
'${30 - (DateTime.now().difference(DateTime.parse(model.createTime.toString()))).inMinutes}分钟',
'${31 - (DateTime.now().difference(DateTime.parse(model.createTime.toString()))).inMinutes}分钟',
style: TextStyle(
color: Colours.cC31F4C,
fontSize: 10.w,
......
......@@ -21,6 +21,7 @@ const String kUserRechargeAgreement = '/html/agreement/rec_agreement.html';
// 错题详情页 html
const String kUserWrongDes = '$kServerUrl/html/app/evaluating_wrong.html';
// 阅读页 html
const String kReadTestUnderLineBook = 'http://150.158.138.40:9200/read-unline.html';
const String kReadBook = '$kServerUrl/html/app/read.html';
// 答题页
const String kAnswer = '$kServerUrl/html/app/evaluating.html';
......
......@@ -16,7 +16,7 @@ class SqlManager {
var databasesPath = await getDatabasesPath();
// var databasesPath = await Tools.getDirectory();
String dbName = _name;
Console.log('databasesPath---------$databasesPath');
Console.log('Sql-----------databasesPath---------$databasesPath');
if(databasesPath != null) {
String path = databasesPath + dbName;
if (Platform.isIOS) {
......@@ -34,6 +34,7 @@ class SqlManager {
"chapter_id INTEGER, "
"node_id INTEGER, "
"is_open INTEGER, "
"del INTEGER, "
"color TEXT, "
"content TEXT, "
"upload INTEGER, "
......@@ -50,58 +51,143 @@ class SqlManager {
}
}
static Future<Database?> getCurrentDatabase() async {
if (_database == null) {
await init();
}
return _database;
}
// 关闭数据库
static Future<void> closeDatabase() async {
await _database?.close();
}
// 查询划线高亮笔记
static Future<Map<String, dynamic>> queryLocalNote({required int bookId,required int chapterId}) async {
Database? db = await SqlManager.getCurrentDatabase();
Map<String, dynamic> returnMap = {};
// 划线
List<Map<String, dynamic>>? lineResult = await db?.query(
'members_book_notes',
where: 'book_id = ? and chapter_id = ? and types = ? and del = ?',
whereArgs: [bookId, chapterId,2,0],
);
// 高亮
List<Map<String, dynamic>>? colorResult = await db?.query(
'members_book_notes',
where: 'book_id = ? and chapter_id = ? and types = ? and del = ?',
whereArgs: [bookId, chapterId,3,0],
);
returnMap['line_list'] = lineResult;
returnMap['color_line'] = colorResult;
Console.log('Sql-----------queryLocalNote---------------------$returnMap');
return returnMap;
}
// 添加划线高亮笔记
static Future<int> addLocalNote(Map<String, dynamic> data) async {
Database? db = await SqlManager.getCurrentDatabase();
final result = await db?.insert(
'members_book_notes',
data,
conflictAlgorithm: ConflictAlgorithm.replace,
);
return result??0;
}
// 删除划线高亮笔记
static Future<int> delLocalNote({required int id}) async {
Database? db = await SqlManager.getCurrentDatabase();
final result = await db?.update(
'members_book_notes',
{'del': 1},
where: 'id = ?',
whereArgs: [id],
);
return result??0;
}
// 修改划线高亮笔记
static Future<int> updateLocalNote({required int id,required Map<String, dynamic> data}) async {
Database? db = await SqlManager.getCurrentDatabase();
final result = await db?.update(
'members_book_notes',
data,
where: 'id = ?',
whereArgs: [id],
);
return result??0;
}
// 查询所有没有上传的数据
static Future<List<Map<String, dynamic>>> queryNoUploadData() async {
List<Map<String, dynamic>> results = await _database!.query(
Database? db = await SqlManager.getCurrentDatabase();
List<Map<String, dynamic>>? results = await db?.query(
'members_book_notes',
where: 'upload = ?',
whereArgs: [0],
where: 'upload = ? and del = ?',
whereArgs: [0,0],
);
return results.isNotEmpty ? results : [];
return results ??[];
}
// 将所有 upload 为 0 的数据的 upload 字段值更新为 1
static Future<void> updateUploadStatus() async {
final result = await _database!.update(
Database? db = await SqlManager.getCurrentDatabase();
final result = await db?.update(
'members_book_notes',
{'upload': 1},
where: 'upload = ?',
whereArgs: [0],
);
Console.log('更新数据-------------------------------$result');
Console.log('Sql---------------更新数据----------------$result');
}
// 根据 book_id 查询当前读到的 章节
static Future<String> queryReadHistoryByBookId(int bookId) async {
List<Map<String, dynamic>> results = await _database!.query(
Database? db = await SqlManager.getCurrentDatabase();
List<Map<String, dynamic>>? results = await db?.query(
'read_history',
where: 'book_id = ?',
whereArgs: [bookId],
);
return results.isNotEmpty ? results.first['chapter_id'] : 0;
return results?.first['chapter_id'].toString() ?? '';
}
// 根据 book_id 写入当前读到的 章节
static Future<int> updateReadHistoryByBookId(int bookId ,int chapterId) async {
final result = await _database!.update(
'members_book_notes',
{'chapter_id':chapterId},
where: 'book_id = ?',
whereArgs: [bookId],
);
return result;
Database? db = await SqlManager.getCurrentDatabase();
final queryResult = await queryReadHistoryByBookId(bookId);
if (queryResult.isEmpty){
Console.log('Sql----------没有当前书籍的数据----------------------');
final result = await db?.insert(
'read_history',
{'chapter_id':chapterId, 'book_id':bookId},
conflictAlgorithm: ConflictAlgorithm.replace,
);
Console.log('Sql----------插入数据结果:$result----------------------');
return result??0;
}
else{
Console.log('Sql----------有当前书籍的数据----------------------');
final result = await db!.update(
'read_history',
{'chapter_id':chapterId},
where: 'book_id = ?',
whereArgs: [bookId],
);
Console.log('Sql----------更新数据结果:$result----------------------');
return result;
}
}
// 插入数据
static Future<bool> insertData(Map<String, dynamic> data) async {
final result = await _database?.insert(
Database? db = await SqlManager.getCurrentDatabase();
final result = await db?.insert(
'members_book_notes',
data,
conflictAlgorithm: ConflictAlgorithm.replace,
......@@ -116,22 +202,25 @@ class SqlManager {
// 查询所有数据
static Future<List<Map<String, dynamic>>?> queryAllData() async {
return await _database?.query('members_book_notes');
Database? db = await SqlManager.getCurrentDatabase();
return await db?.query('members_book_notes');
}
// 根据 ID 查询数据
static Future<Map<String, dynamic>?> queryDataById(int id) async {
List<Map<String, dynamic>> results = await _database!.query(
Database? db = await SqlManager.getCurrentDatabase();
List<Map<String, dynamic>>? results = await db?.query(
'members_book_notes',
where: 'id = ?',
whereArgs: [id],
);
return results.isNotEmpty ? results.first : null;
return results?.first??{};
}
// 更新数据
static Future<void> updateData(int id, Map<String, dynamic> newData) async {
await _database?.update(
Database? db = await SqlManager.getCurrentDatabase();
await db?.update(
'members_book_notes',
newData,
where: 'id = ?',
......@@ -141,7 +230,8 @@ class SqlManager {
// 删除数据
static Future<void> deleteData(int id) async {
await _database?.delete(
Database? db = await SqlManager.getCurrentDatabase();
await db?.delete(
'members_book_notes',
where: 'id = ?',
whereArgs: [id],
......
......@@ -38,7 +38,7 @@ abstract class Tools {
static Future<String> getDirectory() async {
// getTemporaryDirectory
final directory = await getApplicationSupportDirectory();
final directory = await getExternalStorageDirectory();
return directory!.path;
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论