mirror of
https://github.com/qinglong-app/qinglong_app.git
synced 2025-10-09 16:48:19 +08:00
add login log
This commit is contained in:
51
lib/module/others/dependencies/dependency_bean.dart
Normal file
51
lib/module/others/dependencies/dependency_bean.dart
Normal file
@@ -0,0 +1,51 @@
|
||||
import 'package:json_conversion_annotation/json_conversion_annotation.dart';
|
||||
|
||||
/// @author NewTab
|
||||
@JsonConversion()
|
||||
class DependencyBean {
|
||||
String? sId;
|
||||
int? created;
|
||||
int? status;
|
||||
int? type;
|
||||
String? timestamp;
|
||||
String? name;
|
||||
List<String>? log;
|
||||
String? remark;
|
||||
|
||||
DependencyBean(
|
||||
{this.sId,
|
||||
this.created,
|
||||
this.status,
|
||||
this.type,
|
||||
this.timestamp,
|
||||
this.name,
|
||||
this.log,
|
||||
this.remark});
|
||||
|
||||
DependencyBean.fromJson(Map<String, dynamic> json) {
|
||||
sId = json['_id'];
|
||||
created = json['created'];
|
||||
status = json['status'];
|
||||
type = json['type'];
|
||||
timestamp = json['timestamp'];
|
||||
name = json['name'];
|
||||
log = json['log'].cast<String>();
|
||||
remark = json['remark'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['_id'] = this.sId;
|
||||
data['created'] = this.created;
|
||||
data['status'] = this.status;
|
||||
data['type'] = this.type;
|
||||
data['timestamp'] = this.timestamp;
|
||||
data['name'] = this.name;
|
||||
data['log'] = this.log;
|
||||
data['remark'] = this.remark;
|
||||
return data;
|
||||
}
|
||||
static DependencyBean jsonConversion(Map<String, dynamic> json) {
|
||||
return DependencyBean.fromJson(json);
|
||||
}
|
||||
}
|
||||
35
lib/module/others/login_log/login_log_bean.dart
Normal file
35
lib/module/others/login_log/login_log_bean.dart
Normal file
@@ -0,0 +1,35 @@
|
||||
import 'package:json_conversion_annotation/json_conversion_annotation.dart';
|
||||
|
||||
/// @author NewTab
|
||||
@JsonConversion()
|
||||
class LoginLogBean {
|
||||
int? timestamp;
|
||||
String? address;
|
||||
String? ip;
|
||||
String? platform;
|
||||
int? status; //0代表成功,1代表失败
|
||||
|
||||
LoginLogBean({this.timestamp, this.address, this.ip, this.platform, this.status});
|
||||
|
||||
LoginLogBean.fromJson(Map<String, dynamic> json) {
|
||||
timestamp = json['timestamp'];
|
||||
address = json['address'];
|
||||
ip = json['ip'];
|
||||
platform = json['platform'];
|
||||
status = json['status'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['timestamp'] = this.timestamp;
|
||||
data['address'] = this.address;
|
||||
data['ip'] = this.ip;
|
||||
data['platform'] = this.platform;
|
||||
data['status'] = this.status;
|
||||
return data;
|
||||
}
|
||||
|
||||
static LoginLogBean jsonConversion(Map<String, dynamic> json) {
|
||||
return LoginLogBean.fromJson(json);
|
||||
}
|
||||
}
|
||||
112
lib/module/others/login_log/login_log_page.dart
Normal file
112
lib/module/others/login_log/login_log_page.dart
Normal file
@@ -0,0 +1,112 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:qinglong_app/base/http/api.dart';
|
||||
import 'package:qinglong_app/base/http/http.dart';
|
||||
import 'package:qinglong_app/base/ql_app_bar.dart';
|
||||
import 'package:qinglong_app/base/theme.dart';
|
||||
import 'package:qinglong_app/utils/extension.dart';
|
||||
import 'package:qinglong_app/utils/utils.dart';
|
||||
|
||||
import 'login_log_bean.dart';
|
||||
|
||||
/// @author NewTab
|
||||
class LoginLogPage extends ConsumerStatefulWidget {
|
||||
const LoginLogPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_LoginLogPageState createState() => _LoginLogPageState();
|
||||
}
|
||||
|
||||
class _LoginLogPageState extends ConsumerState<LoginLogPage> {
|
||||
List<LoginLogBean> list = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
loadData();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: QlAppBar(
|
||||
canBack: true,
|
||||
backCall: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
title: "任务日志",
|
||||
),
|
||||
body: ListView.builder(
|
||||
itemBuilder: (context, index) {
|
||||
LoginLogBean item = list[index];
|
||||
|
||||
return ColoredBox(
|
||||
color: ref.watch(themeProvider).themeColor.settingBgColor(),
|
||||
child: ListTile(
|
||||
isThreeLine: true,
|
||||
title: Text(
|
||||
Utils.formatMessageTime(item.timestamp ?? 0),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: ref.watch(themeProvider).themeColor.taskTitleColor(),
|
||||
),
|
||||
),
|
||||
subtitle: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"${item.address}",
|
||||
style: TextStyle(
|
||||
color: ref.watch(themeProvider).themeColor.descColor(),
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"${item.ip}",
|
||||
style: TextStyle(
|
||||
color: ref.watch(themeProvider).themeColor.descColor(),
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
trailing: item.status == 0
|
||||
? Icon(
|
||||
CupertinoIcons.checkmark_circle,
|
||||
color: primaryColor,
|
||||
size: 16,
|
||||
)
|
||||
: const Icon(
|
||||
CupertinoIcons.clear_circled,
|
||||
color: Colors.red,
|
||||
size: 16,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
itemCount: list.length,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> loadData() async {
|
||||
HttpResponse<List<LoginLogBean>> response = await Api.loginLog();
|
||||
|
||||
if (response.success) {
|
||||
list.clear();
|
||||
list.addAll(response.bean ?? []);
|
||||
setState(() {});
|
||||
} else {
|
||||
response.message?.toast();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,10 +50,7 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
||||
Text(
|
||||
"脚本管理",
|
||||
style: TextStyle(
|
||||
color: ref
|
||||
.watch(themeProvider)
|
||||
.themeColor
|
||||
.taskTitleColor(),
|
||||
color: ref.watch(themeProvider).themeColor.taskTitleColor(),
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
@@ -78,10 +75,7 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
||||
Text(
|
||||
"依赖管理",
|
||||
style: TextStyle(
|
||||
color: ref
|
||||
.watch(themeProvider)
|
||||
.themeColor
|
||||
.taskTitleColor(),
|
||||
color: ref.watch(themeProvider).themeColor.taskTitleColor(),
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
@@ -106,10 +100,7 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
||||
Text(
|
||||
"任务日志",
|
||||
style: TextStyle(
|
||||
color: ref
|
||||
.watch(themeProvider)
|
||||
.themeColor
|
||||
.taskTitleColor(),
|
||||
color: ref.watch(themeProvider).themeColor.taskTitleColor(),
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
@@ -124,29 +115,35 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
||||
const Divider(
|
||||
indent: 15,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10,
|
||||
horizontal: 15,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"登录日志",
|
||||
style: TextStyle(
|
||||
color: ref
|
||||
.watch(themeProvider)
|
||||
.themeColor
|
||||
.taskTitleColor(),
|
||||
fontSize: 16,
|
||||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
Navigator.of(context).pushNamed(
|
||||
Routes.routeLoginLog,
|
||||
);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10,
|
||||
horizontal: 15,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Text(
|
||||
"登录日志",
|
||||
style: TextStyle(
|
||||
color: ref.watch(themeProvider).themeColor.taskTitleColor(),
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
const Icon(
|
||||
CupertinoIcons.right_chevron,
|
||||
size: 16,
|
||||
),
|
||||
],
|
||||
const Spacer(),
|
||||
const Icon(
|
||||
CupertinoIcons.right_chevron,
|
||||
size: 16,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -181,10 +178,7 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
||||
Text(
|
||||
"夜间模式",
|
||||
style: TextStyle(
|
||||
color: ref
|
||||
.watch(themeProvider)
|
||||
.themeColor
|
||||
.taskTitleColor(),
|
||||
color: ref.watch(themeProvider).themeColor.taskTitleColor(),
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
@@ -204,7 +198,9 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width - 40,
|
||||
child: CupertinoButton(
|
||||
padding: const EdgeInsets.symmetric(vertical: 5,),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 5,
|
||||
),
|
||||
color: ref.watch(themeProvider).themeColor.buttonBgColor(),
|
||||
child: const Text(
|
||||
"退出登录",
|
||||
@@ -214,8 +210,7 @@ class _OtherPageState extends ConsumerState<OtherPage> {
|
||||
),
|
||||
onPressed: () {
|
||||
getIt<UserInfoViewModel>().updateToken("");
|
||||
Navigator.of(context)
|
||||
.pushReplacementNamed(Routes.routeLogin);
|
||||
Navigator.of(context).pushReplacementNamed(Routes.routeLogin);
|
||||
}),
|
||||
),
|
||||
),
|
||||
|
||||
79
lib/module/others/scripts/script_bean.dart
Normal file
79
lib/module/others/scripts/script_bean.dart
Normal file
@@ -0,0 +1,79 @@
|
||||
import 'package:json_conversion_annotation/json_conversion_annotation.dart';
|
||||
|
||||
/// @author NewTab
|
||||
@JsonConversion()
|
||||
class ScriptBean {
|
||||
String? title;
|
||||
String? value;
|
||||
String? key;
|
||||
double? mtime;
|
||||
bool? disabled;
|
||||
List<ScriptChildren>? children;
|
||||
|
||||
ScriptBean(
|
||||
{this.title,
|
||||
this.value,
|
||||
this.key,
|
||||
this.mtime,
|
||||
this.disabled,
|
||||
this.children});
|
||||
|
||||
ScriptBean.fromJson(Map<String, dynamic> json) {
|
||||
title = json['title'];
|
||||
value = json['value'];
|
||||
key = json['key'];
|
||||
mtime = json['mtime'];
|
||||
disabled = json['disabled'];
|
||||
if (json['children'] != null) {
|
||||
children = <ScriptChildren>[];
|
||||
json['children'].forEach((v) {
|
||||
children!.add(new ScriptChildren.fromJson(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['title'] = this.title;
|
||||
data['value'] = this.value;
|
||||
data['key'] = this.key;
|
||||
data['mtime'] = this.mtime;
|
||||
data['disabled'] = this.disabled;
|
||||
if (this.children != null) {
|
||||
data['children'] = this.children!.map((v) => v.toJson()).toList();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
static ScriptBean jsonConversion(Map<String, dynamic> json) {
|
||||
return ScriptBean.fromJson(json);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ScriptChildren {
|
||||
String? title;
|
||||
String? value;
|
||||
String? key;
|
||||
double? mtime;
|
||||
String? parent;
|
||||
|
||||
ScriptChildren({this.title, this.value, this.key, this.mtime, this.parent});
|
||||
|
||||
ScriptChildren.fromJson(Map<String, dynamic> json) {
|
||||
title = json['title'];
|
||||
value = json['value'];
|
||||
key = json['key'];
|
||||
mtime = json['mtime'];
|
||||
parent = json['parent'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['title'] = this.title;
|
||||
data['value'] = this.value;
|
||||
data['key'] = this.key;
|
||||
data['mtime'] = this.mtime;
|
||||
data['parent'] = this.parent;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
26
lib/module/others/scripts/script_page.dart
Normal file
26
lib/module/others/scripts/script_page.dart
Normal file
@@ -0,0 +1,26 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:qinglong_app/base/ql_app_bar.dart';
|
||||
|
||||
/// @author NewTab
|
||||
class ScriptPage extends StatefulWidget {
|
||||
const ScriptPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ScriptPageState createState() => _ScriptPageState();
|
||||
}
|
||||
|
||||
class _ScriptPageState extends State<ScriptPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: QlAppBar(
|
||||
canBack: true,
|
||||
backCall: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
title: "脚本管理",
|
||||
),
|
||||
body: Container(),
|
||||
);
|
||||
}
|
||||
}
|
||||
29
lib/module/others/task_log/task_log_bean.dart
Normal file
29
lib/module/others/task_log/task_log_bean.dart
Normal file
@@ -0,0 +1,29 @@
|
||||
import 'package:json_conversion_annotation/json_conversion_annotation.dart';
|
||||
|
||||
/// @author NewTab
|
||||
@JsonConversion()
|
||||
class TaskLogBean {
|
||||
String? name;
|
||||
bool? isDir;
|
||||
List<String>? files;
|
||||
|
||||
TaskLogBean({this.name, this.isDir, this.files});
|
||||
|
||||
TaskLogBean.fromJson(Map<String, dynamic> json) {
|
||||
name = json['name'];
|
||||
isDir = json['isDir'];
|
||||
files = json['files'].cast<String>();
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['name'] = this.name;
|
||||
data['isDir'] = this.isDir;
|
||||
data['files'] = this.files;
|
||||
return data;
|
||||
}
|
||||
|
||||
static TaskLogBean jsonConversion(Map<String, dynamic> json) {
|
||||
return TaskLogBean.fromJson(json);
|
||||
}
|
||||
}
|
||||
39
lib/module/others/task_log/task_log_page.dart
Normal file
39
lib/module/others/task_log/task_log_page.dart
Normal file
@@ -0,0 +1,39 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:qinglong_app/base/http/api.dart';
|
||||
import 'package:qinglong_app/base/http/http.dart';
|
||||
import 'package:qinglong_app/base/ql_app_bar.dart';
|
||||
import 'package:qinglong_app/module/others/login_log/login_log_bean.dart';
|
||||
import 'package:qinglong_app/utils/extension.dart';
|
||||
import 'package:qinglong_app/utils/utils.dart';
|
||||
|
||||
/// @author NewTab
|
||||
class TaskLogPage extends ConsumerStatefulWidget {
|
||||
const TaskLogPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_TaskLogPageState createState() => _TaskLogPageState();
|
||||
}
|
||||
|
||||
class _TaskLogPageState extends ConsumerState<TaskLogPage> {
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: QlAppBar(
|
||||
canBack: true,
|
||||
backCall: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
title: "任务日志",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user