Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
book-app
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
book-app
Commits
26d783a7
提交
26d783a7
authored
2月 22, 2024
作者:
yueweilu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
sqlite
上级
7d0e3e5b
显示空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
310 行增加
和
66 行删除
+310
-66
global.dart
lib/global.dart
+14
-0
main.dart
lib/main.dart
+3
-0
controller.dart
lib/pages/library/controller.dart
+15
-0
controller.dart
lib/pages/read_web/controller.dart
+100
-63
index.dart
lib/pages/read_web/index.dart
+1
-0
view.dart
lib/pages/read_web/view.dart
+2
-2
constants.dart
lib/utils/constants.dart
+2
-0
index.dart
lib/utils/index.dart
+4
-0
sql.dart
lib/utils/sql.dart
+145
-0
tools.dart
lib/utils/tools.dart
+21
-0
pubspec.lock
pubspec.lock
+1
-1
pubspec.yaml
pubspec.yaml
+2
-0
没有找到文件。
lib/global.dart
浏览文件 @
26d783a7
...
...
@@ -16,6 +16,11 @@ class Global {
// InAppLocalhostServer(documentRoot: '$documentRoot/',shared: true);
// await localhostServer.start();
// print('本地服务器已成功启动,根目录为: $documentRoot');
SqlManager
.
init
();
WidgetsBinding
.
instance
?.
addObserver
(
AppLifecycleObserver
());
await
Future
.
wait
([
// 配置存储
...
...
@@ -33,3 +38,11 @@ class Global {
});
}
}
class
AppLifecycleObserver
extends
WidgetsBindingObserver
{
@override
void
didChangeAppLifecycleState
(
AppLifecycleState
state
)
{
if
(
state
==
AppLifecycleState
.
paused
||
state
==
AppLifecycleState
.
detached
)
{
SqlManager
.
closeDatabase
();
// 应用进入后台时关闭数据库连接
}
}
}
\ No newline at end of file
lib/main.dart
浏览文件 @
26d783a7
...
...
@@ -26,8 +26,11 @@ void main() {
// print('2222222---------$name');
// final result = EncryptUtil.aesDecrypt(name);
// Console.log('解密--------------------------$result');
runApp
(
const
MyApp
());
//FlutterNativeSplash.remove();
});
});
SystemChrome
.
setSystemUIOverlayStyle
(
SystemUiOverlayStyle
.
light
);
...
...
lib/pages/library/controller.dart
浏览文件 @
26d783a7
...
...
@@ -175,6 +175,21 @@ class LibraryController extends GetxController with GetTickerProviderStateMixin{
/// 获取tab分类数据
void
_getTabs
()
async
{
Map
<
String
,
dynamic
>
data
=
{
'types'
:
1
,
'book_id'
:
123
,
'chapter_id'
:
456
,
// 'is_open': 1,
// 'color': 'blue',
// 'content': 'This is a note content',
// 'del': 0,
// 'positioning': 'top',
// 'note': 'This is a note',
};
await
SqlManager
.
insertData
(
data
);
categories
=
await
LibraryAPI
.
categories
();
tabController
.
dispose
();
tabController
=
TabController
(
length:
categories
.
length
,
vsync:
this
);
...
...
lib/pages/read_web/controller.dart
浏览文件 @
26d783a7
...
...
@@ -57,6 +57,10 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
// 网络状态
bool
netStatus
=
false
;
// 当前html名称 0-318.html
late
String
currentHtmlName
=
''
;
///------------------------------------------ 页面 生命周期--------------------------------------------------------
@override
void
onInit
()
{
...
...
@@ -73,19 +77,8 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
_getChapters
();
netStatus
=
await
Tools
.
checkCurrentNetStatus
();
// // 判断是否有离线文件 如果有使用离线阅读
// final exist = await _isExistFile(bookId);
// // 没有网并且有离线文件 离线阅读
// String path = await _getDirectory();
// String finalPath = '$path/174/0-318.html';
// final content = await readHtmlFileContent(finalPath);
// Console.log('原始内容-----------------$content');
// String htmlStr = EncryptUtil.aesDecrypt(content!);
// Console.log('解密-----------------$htmlStr');
// if (netStatus && exist){
// Console.log('-------------使用本地文件-------------------');
// webViewController.loadData(data: htmlStr??'');
// }
readLocalHtml
(
''
);
readChapter
(
type:
1
);
super
.
onReady
();
}
...
...
@@ -102,6 +95,21 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
}
///------------------------------------------ 页面 生命周期--------------------------------------------------------
void
chooseTool
(
ToolModel
selectedModel
){
for
(
var
model
in
tools
)
{
// 如果当前遍历到的工具是选中的,并且不是点击的工具,则取消选中
if
(
model
.
selected
&&
model
!=
selectedModel
)
{
model
.
selected
=
false
;
}
// 如果当前遍历到的工具是点击的工具,切换选中状态
else
if
(
model
==
selectedModel
)
{
model
.
selected
=
!
model
.
selected
;
}
}
toolModel
=
selectedModel
;
update
();
}
void
setShow
(
bool
value
)
{
_show
=
!
value
;
update
();
...
...
@@ -364,22 +372,6 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
void
chooseTool
(
ToolModel
selectedModel
){
for
(
var
model
in
tools
)
{
// 如果当前遍历到的工具是选中的,并且不是点击的工具,则取消选中
if
(
model
.
selected
&&
model
!=
selectedModel
)
{
model
.
selected
=
false
;
}
// 如果当前遍历到的工具是点击的工具,切换选中状态
else
if
(
model
==
selectedModel
)
{
model
.
selected
=
!
model
.
selected
;
}
}
toolModel
=
selectedModel
;
update
();
}
// AnimationController get controller => _controller;
void
_onCommentFocusChanged
()
{
...
...
@@ -412,45 +404,14 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
/// 获取目录信息
void
_getChapters
()
async
{
chapters
=
await
LibraryAPI
.
chapters
(
bookId:
bookId
);
update
();
}
/// 添加阅读时长
void
_addReadTime
({
required
type
})
async
{
final
result
=
await
LibraryAPI
.
addReadTime
(
bookId:
bookId
,
readTypes:
type
);
}
/// 获取离线文件路径
void
getBookDown
()
async
{
final
exit
=
await
_isExistFile
(
bookId
);
// 存在离线文件
if
(
exit
){
}
else
{
final
result
=
await
LibraryAPI
.
getbookDownloadParam
(
bookId:
bookId
);
Console
.
log
(
'----------_getBookDown------------------
${result.download}
'
);
// final String savePath = await _getDirectory();
// LibraryAPI.downBookByUrl(url: result.download!,savePath: '$savePath$bookId.zip',onReceiveProgress: (int received,int total){
// if (total !=-1){
// double progress = (received / total) * 100;
// Console.log('Download progress: $progress%');
// }
// });
extractZipFileFromCache
(
result
.
download
!);
}
}
///------------------------------------------离线逻辑--------------------------------------------------------
// 下载文件
Future
<
void
>
extractZipFileFromCache
(
String
url
)
async
{
// 从缓存中获取 ZIP 文件
var
file
=
await
DefaultCacheManager
().
getSingleFile
(
url
);
if
(
file
!=
null
)
{
Toast
.
show
(
'离线成功'
);
// 读取 ZIP 文件内容
Uint8List
bytes
=
await
file
.
readAsBytes
();
// 解压缩 ZIP 文件
...
...
@@ -468,12 +429,12 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
print
(
'解压缩文件:
$fileName
,保存路径:
$filePath
'
);
}
}
}
else
{
print
(
'未找到缓存中的文件或文件不存在'
);
}
}
// 判断是否存在离线文件
Future
<
bool
>
_isExistFile
(
String
bookId
)
async
{
String
directoryPath
=
await
_getDirectory
();
...
...
@@ -493,6 +454,48 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
}
// 本地阅读 读取上一章节 或 下一章节
// 0 上一章节
// 1 下一章节
Future
<
String
>
readChapter
({
required
int
type
})
async
{
Console
.
log
(
'---------------获取所有html---------------------------------'
);
String
docPath
=
await
_getDirectory
();
String
filePath
=
'
$docPath
/
$bookId
'
;
Directory
directory
=
Directory
(
filePath
);
// 获取目录下的所有文件
List
<
FileSystemEntity
>
files
=
directory
.
listSync
(
recursive:
true
);
int
findIndex
=
int
.
parse
(
currentHtmlName
.
split
(
'-'
).
first
);
currentHtmlName
;
if
(
type
==
0
){
findIndex
--;
if
(
findIndex
<
0
){
// 已到最前
return
'-1'
;
}
}
else
{
findIndex
++;
if
(
findIndex
>
files
.
length
-
1
){
// 已到最后
return
'1'
;
}
}
// 打印所有 HTML 文件路径
for
(
var
file
in
files
)
{
if
(
file
is
File
&&
file
.
path
.
toLowerCase
().
endsWith
(
'.html'
))
{
String
fileName
=
path
.
basename
(
file
.
path
);
if
(
int
.
parse
(
fileName
.
split
(
'-'
).
first
)
==
2
){
print
(
'HTML File--------------------------------
${file.path}
'
);
return
file
.
path
;
}
}
}
return
'0'
;
}
// 读取html内容
Future
<
String
?>
readHtmlFileContent
(
String
filePath
)
async
{
try
{
...
...
@@ -514,6 +517,40 @@ class ReadController extends FullLifeCycleController with GetSingleTickerProvide
return
directory
!.
path
;
}
/// 获取目录信息
void
_getChapters
()
async
{
chapters
=
await
LibraryAPI
.
chapters
(
bookId:
bookId
);
update
();
}
/// 添加阅读时长
void
_addReadTime
({
required
type
})
async
{
final
result
=
await
LibraryAPI
.
addReadTime
(
bookId:
bookId
,
readTypes:
type
);
}
/// 获取离线文件路径
void
getBookDown
()
async
{
final
exit
=
await
_isExistFile
(
bookId
);
// 存在离线文件
if
(
exit
){
}
else
{
final
result
=
await
LibraryAPI
.
getbookDownloadParam
(
bookId:
bookId
);
Console
.
log
(
'----------_getBookDown------------------
${result.download}
'
);
// final String savePath = await _getDirectory();
// LibraryAPI.downBookByUrl(url: result.download!,savePath: '$savePath$bookId.zip',onReceiveProgress: (int received,int total){
// if (total !=-1){
// double progress = (received / total) * 100;
// Console.log('Download progress: $progress%');
// }
// });
extractZipFileFromCache
(
result
.
download
!);
}
}
///------------------------------------------ app 生命周期--------------------------------------------------------
// 当应用程序从后台切换到前台并变为活动状态时调用。这通常在用户从其他应用程序返回到你的应用程序时发生
...
...
lib/pages/read_web/index.dart
浏览文件 @
26d783a7
...
...
@@ -34,6 +34,7 @@ import '../../widgets/index.dart';
import
'../book_category/index.dart'
;
import
'../user_discuss_des/index.dart'
;
import
'../user_notes_des/index.dart'
;
import
'package:path/path.dart'
as
path
;
part
'view.dart'
;
part
'controller.dart'
;
...
...
lib/pages/read_web/view.dart
浏览文件 @
26d783a7
...
...
@@ -64,8 +64,8 @@ class _ReadPageState extends State<ReadPage> {
children:
[
InAppWebView
(
initialUrlRequest:
URLRequest
(
//
url: Uri.parse('http://150.158.138.40:9200/read.html'),
url:
Uri
.
parse
(
"/storage/emulated/0/Android/data/com.zijin.book.flutter_book/files/174/7-325.html"
),
url:
Uri
.
parse
(
'http://150.158.138.40:9200/read.html'
),
//
url: Uri.parse("/storage/emulated/0/Android/data/com.zijin.book.flutter_book/files/174/7-325.html"),
),
contextMenu:
ContextMenu
(
options:
ContextMenuOptions
(
hideDefaultSystemContextMenuItems:
true
),
...
...
lib/utils/constants.dart
浏览文件 @
26d783a7
...
...
@@ -11,6 +11,8 @@ const String kLocalPassword = 'local_password';
const
String
kLocalUserInfo
=
'local_user_info'
;
const
String
kSearchHistory
=
'search_history'
;
const
String
kFailOrder
=
'failOrder'
;
const
String
kNoteTable
=
'members_book_notes'
;
const
String
kReadTable
=
'read_history'
;
...
...
lib/utils/index.dart
浏览文件 @
26d783a7
...
...
@@ -28,6 +28,8 @@ import 'package:flutter_oss_aliyun/flutter_oss_aliyun.dart';
import
'../models/index.dart'
;
import
'../widgets/index.dart'
;
import
'package:sqflite/sqflite.dart'
;
part
'constants.dart'
;
part
'screen.dart'
;
...
...
@@ -43,3 +45,4 @@ part 'clear_cache_util.dart';
part
'access.dart'
;
part
'assets_picker.dart'
;
part
'oss.dart'
;
part
'sql.dart'
;
\ No newline at end of file
lib/utils/sql.dart
0 → 100644
浏览文件 @
26d783a7
part of
utils
;
class
SqlManager
{
static
const
_version
=
1
;
static
const
_name
=
"zi_jing_app_flutter.db"
;
static
Database
?
_database
;
///初始化
static
init
()
async
{
// open the database
var
databasesPath
=
await
getDatabasesPath
();
// var databasesPath = await Tools.getDirectory();
String
dbName
=
_name
;
Console
.
log
(
'databasesPath---------
$databasesPath
'
);
if
(
databasesPath
!=
null
)
{
String
path
=
databasesPath
+
dbName
;
if
(
Platform
.
isIOS
)
{
path
=
"
$databasesPath
/
$dbName
"
;
}
_database
=
await
openDatabase
(
path
,
version:
_version
,
onCreate:
(
Database
db
,
int
version
)
async
{
// When creating the db, create the table
// await db.execute("CREATE TABLE Test (id INTEGER PRIMARY KEY, name TEXT, value INTEGER, num REAL)");
// 笔记表
await
db
.
execute
(
"CREATE TABLE
$kNoteTable
("
"id INTEGER PRIMARY KEY, "
"types INTEGER, "
"book_id INTEGER, "
"chapter_id INTEGER, "
"is_open INTEGER, "
"color TEXT, "
"content TEXT, "
"upload INTEGER, "
"positioning TEXT, "
"note TEXT)"
);
// // 阅读章节表
await
db
.
execute
(
"CREATE TABLE
$kReadTable
("
"id INTEGER PRIMARY KEY, "
"book_id INTEGER, "
"chapter_id INTEGER)"
);
});
}
}
// 关闭数据库
static
Future
<
void
>
closeDatabase
()
async
{
await
_database
?.
close
();
}
// 查询所有没有上传的数据
static
Future
<
List
<
Map
<
String
,
dynamic
>>>
queryNoUploadData
()
async
{
List
<
Map
<
String
,
dynamic
>>
results
=
await
_database
!.
query
(
'members_book_notes'
,
where:
'upload = ?'
,
whereArgs:
[
0
],
);
return
results
.
isNotEmpty
?
results
:
[];
}
// 将所有 upload 为 0 的数据的 upload 字段值更新为 1
static
Future
<
void
>
updateUploadStatus
()
async
{
await
_database
!.
update
(
'members_book_notes'
,
{
'upload'
:
1
},
where:
'upload = ?'
,
whereArgs:
[
0
],
);
}
// 根据 book_id 查询当前读到的 章节
static
Future
<
int
>
queryDataByBookId
(
int
bookId
)
async
{
List
<
Map
<
String
,
dynamic
>>
results
=
await
_database
!.
query
(
'read_history'
,
where:
'book_id = ?'
,
whereArgs:
[
bookId
],
);
return
results
.
isNotEmpty
?
results
.
first
[
'chapter_id'
]
:
0
;
}
// 根据 book_id 写入当前读到的 章节
static
Future
<
int
?>
updateReadHistoryBookId
(
int
bookId
,
int
chapterId
)
async
{
final
result
=
await
_database
?.
update
(
'members_book_notes'
,
{
'chapter_id'
:
chapterId
},
where:
'book_id = ?'
,
whereArgs:
[
bookId
],
);
return
result
;
}
// 插入数据
static
Future
<
void
>
insertData
(
Map
<
String
,
dynamic
>
data
)
async
{
final
result
=
await
_database
?.
insert
(
'members_book_notes'
,
data
,
conflictAlgorithm:
ConflictAlgorithm
.
replace
,
);
Console
.
log
(
'插入数据-------------------------------
$result
'
);
}
// 查询所有数据
static
Future
<
List
<
Map
<
String
,
dynamic
>>?>
queryAllData
()
async
{
return
await
_database
?.
query
(
'members_book_notes'
);
}
// 根据 ID 查询数据
static
Future
<
Map
<
String
,
dynamic
>?>
queryDataById
(
int
id
)
async
{
List
<
Map
<
String
,
dynamic
>>
results
=
await
_database
!.
query
(
'members_book_notes'
,
where:
'id = ?'
,
whereArgs:
[
id
],
);
return
results
.
isNotEmpty
?
results
.
first
:
null
;
}
// 更新数据
static
Future
<
void
>
updateData
(
int
id
,
Map
<
String
,
dynamic
>
newData
)
async
{
await
_database
?.
update
(
'members_book_notes'
,
newData
,
where:
'id = ?'
,
whereArgs:
[
id
],
);
}
// 删除数据
static
Future
<
void
>
deleteData
(
int
id
)
async
{
await
_database
?.
delete
(
'members_book_notes'
,
where:
'id = ?'
,
whereArgs:
[
id
],
);
}
}
lib/utils/tools.dart
浏览文件 @
26d783a7
...
...
@@ -75,6 +75,27 @@ abstract class Tools {
// // I am not connected to any network.
// }
}
// static void readChapter({required int type}) async {
// Console.log('---------------获取所有html---------------------------------');
// String docPath = await getDirectory();
// String filePath = '$docPath/$1';
// Directory directory = Directory(filePath);
// // 获取目录下的所有文件
// List<FileSystemEntity> files = directory.listSync(recursive: true);
//
// // 打印所有 HTML 文件路径
// for (var file in files) {
// if (file is File && file.path.toLowerCase().endsWith('.html')) {
// Console.log('HTML File: ${file.path}');
// }
// }
// Console.log('---------------获取所有html---------------------------------');
// // 先找到对应文件
// if(type == 0){
//
// }
// }
}
...
...
pubspec.lock
浏览文件 @
26d783a7
...
...
@@ -867,7 +867,7 @@ packages:
source: hosted
version: "1.9.1"
sqflite:
dependency:
transitive
dependency:
"direct main"
description:
name: sqflite
sha256: a9016f495c927cb90557c909ff26a6d92d9bd54fc42ba92e19d4e79d61e798c6
...
...
pubspec.yaml
浏览文件 @
26d783a7
...
...
@@ -113,6 +113,8 @@ dependencies:
archive
:
^3.1.2
# 判断当前网络情况
connectivity_plus
:
^5.0.2
# 数据库
sqflite
:
^2.3.2
dev_dependencies
:
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论