Compare commits

..

3 Commits

54
.gitignore vendored

@ -1,54 +0,0 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
**/.history
**/.svn/
**/migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
**/.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
**/vscode/
# Flutter/Dart/Pub related
**/src/timemanagerapp/.*
**/doc/api/
**/build/
**/ios/
**/linux/
**/macos/
**/web/
**/windows/
**/android/
**/.dart_tool/
**/.flutter-plugins
**/.flutter-plugins-dependencies
**/.packages
**/.pub-cache/
**/.pub/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
!.gitignore

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

@ -1,8 +1,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="timemanagerapp"
android:label="多为时间"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
android:icon="@mipmap/logo">
<activity
android:name=".MainActivity"
android:exported="true"
@ -30,4 +30,9 @@
android:name="flutterEmbedding"
android:value="2" />
</application>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

@ -4,4 +4,9 @@
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
</manifest>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

@ -0,0 +1,134 @@
/*
Navicat MySQL Data Transfer
Source Server : LRC_debian
Source Server Version : 50742
Source Host : 5902e9v900.zicp.fun:33006
Source Database : expressFrame02
Target Server Type : MYSQL
Target Server Version : 50742
File Encoding : 65001
Date: 2023-10-26 12:49:35
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for clocks
-- ----------------------------
DROP TABLE IF EXISTS `clocks`;
CREATE TABLE `clocks` (
`id` bigint(20) NOT NULL,
`clockId` bigint(20) NOT NULL,
`userId` bigint(20) NOT NULL,
`text` text,
`img` text,
`music` text,
PRIMARY KEY (`id`) USING BTREE,
KEY `fk_clocks_clocks_1` (`userId`),
CONSTRAINT `fk_clocks_clocks_1` FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
`id` bigint(20) NOT NULL,
`userId` bigint(20) DEFAULT NULL,
`courseId` bigint(20) NOT NULL,
`name` text NOT NULL,
`credit` double DEFAULT NULL,
`teacher` text,
`location` text,
`remark` text,
`startTime` text NOT NULL,
`endTime` text NOT NULL,
PRIMARY KEY (`id`) USING BTREE,
KEY `fk_course_course_1` (`userId`),
CONSTRAINT `fk_course_course_1` FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
-- ----------------------------
-- Table structure for tasks
-- ----------------------------
DROP TABLE IF EXISTS `tasks`;
CREATE TABLE `tasks` (
`id` bigint(20) NOT NULL,
`taskId` bigint(20) NOT NULL,
`userId` bigint(20) NOT NULL,
`content` text,
`name` text NOT NULL,
`startTime` text NOT NULL,
`endTime` text NOT NULL,
PRIMARY KEY (`id`) USING BTREE,
KEY `fk_tasks_tasks_1` (`userId`),
CONSTRAINT `fk_tasks_tasks_1` FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
-- ----------------------------
-- Table structure for teams
-- ----------------------------
DROP TABLE IF EXISTS `teams`;
CREATE TABLE `teams` (
`id` bigint(20) NOT NULL,
`leaderId` bigint(20) NOT NULL,
`teamName` varchar(200) NOT NULL,
`maxNumber` bigint(20) DEFAULT NULL,
`introduce` text,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `teamName` (`teamName`) USING BTREE,
KEY `fk_teams_teams_1` (`leaderId`),
CONSTRAINT `fk_teams_teams_1` FOREIGN KEY (`leaderId`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` bigint(20) NOT NULL,
`username` varchar(255) NOT NULL,
`password` text NOT NULL,
`role` bigint(20) NOT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `username` (`username`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
-- ----------------------------
-- Table structure for userteams
-- ----------------------------
DROP TABLE IF EXISTS `userteams`;
CREATE TABLE `userteams` (
`id` bigint(20) NOT NULL,
`userId` bigint(20) NOT NULL,
`teamId` bigint(20) NOT NULL,
PRIMARY KEY (`id`) USING BTREE,
KEY `fk_userteams_userteams_1` (`userId`),
KEY `fk_userteams_userteams_2` (`teamId`),
CONSTRAINT `fk_userteams_userteams_1` FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE CASCADE,
CONSTRAINT `fk_userteams_userteams_2` FOREIGN KEY (`teamId`) REFERENCES `teams` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
-- ----------------------------
-- Table structure for works
-- ----------------------------
DROP TABLE IF EXISTS `works`;
CREATE TABLE `works` (
`id` bigint(20) NOT NULL,
`userId` bigint(20) NOT NULL,
`workId` bigint(20) NOT NULL,
`teamId` bigint(20) NOT NULL,
`name` text NOT NULL,
`content` text,
`status` text,
`endTime` text NOT NULL,
`startTime` text NOT NULL,
PRIMARY KEY (`id`) USING BTREE,
KEY `fk_works_works_1` (`userId`),
KEY `fk_works_works_2` (`teamId`),
CONSTRAINT `fk_works_works_1` FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE CASCADE,
CONSTRAINT `fk_works_works_2` FOREIGN KEY (`teamId`) REFERENCES `teams` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

@ -12,6 +12,8 @@ class CourseController {
return new CourseController();
}
static CourseDao courseDao = CourseDao();
GetCourseByLogin getCourseByLogin = GetCourseByLogin();
IdGenerator idGenerator = IdGenerator();
List<Course> courseList = []; //courseList
@ -40,40 +42,59 @@ class CourseController {
Future<void> addCourseForm(CourseForm courseForm) async {
List<Course> courseListToInsert = [];
int allCourseId = await idGenerator.generateId();
for (int week = courseForm.getStartWeek(); week <= courseForm.getEndWeek(); week++) {
for(int day in courseForm.selectedDays){
//
final startDate = termstartdate.add(Duration(
days: (7 * (week - 1) + day! - 1),
hours: int.parse(raspiyane[courseForm.getStartTime() - 1][0].split(':')[0]),
minutes: int.parse(raspiyane[courseForm.getStartTime() - 1][0].split(':')[1]),
));
final endDate = termstartdate.add(Duration(
days: (7 * (week - 1) + day! - 1),
hours: int.parse(raspiyane[courseForm.getEndTime() - 1][1].split(':')[0]),
minutes: int.parse(raspiyane[courseForm.getEndTime() - 1][1].split(':')[1]),
));
Course course = Course(
id:await idGenerator.generateId(),
name: courseForm.getCourse(),
userId: Setting.user!.getId!,
courseId: await idGenerator.generateId(),
teacher: courseForm.getTeacher(),
location: courseForm.getLocation(),
startTime: startDate,
endTime: endDate,
credit: courseForm.getCredit(),
remark: courseForm.getNote()
);
courseListToInsert.add(course);
}
for(int day in courseForm.selectedDays){
//
final startDate = termstartdate.add(Duration(
days: (7 * (week - 1) + day! - 1),
hours: int.parse(raspiyane[courseForm.getStartTime() - 1][0].split(':')[0]),
minutes: int.parse(raspiyane[courseForm.getStartTime() - 1][0].split(':')[1]),
));
final endDate = termstartdate.add(Duration(
days: (7 * (week - 1) + day! - 1),
hours: int.parse(raspiyane[courseForm.getEndTime() - 1][1].split(':')[0]),
minutes: int.parse(raspiyane[courseForm.getEndTime() - 1][1].split(':')[1]),
));
Course course = Course(
id:await idGenerator.generateId(),
name: courseForm.getCourse(),
userId: Setting.user!.getId!,
courseId: allCourseId,
teacher: courseForm.getTeacher(),
location: courseForm.getLocation(),
startTime: startDate,
endTime: endDate,
credit: courseForm.getCredit(),
remark: courseForm.getNote()
);
courseListToInsert.add(course);
}
}
await insertCourseList(courseListToInsert);
}
Future<List<Course>> init() async {
var res = await netWorkController.getCourseList(Setting.user!.getId!);
if(res == null || res.length == 0){
courseList = [];
}else{
courseList = res;
}
for(Course course in courseList){
await courseDao.insertCourse(course);
}
return courseList;
}
Future<void> dispos() async {
courseDao.deleteAllCourses();
}
Future<List<Course>> getCourses() async {
List<Map<String, dynamic>> courseMaps = await CourseDao().getCourses();
List<Map<String, dynamic>> courseMaps = await courseDao.getCourses();
List<Course> courses = []; // Course
for (var courseMap in courseMaps) {
@ -87,8 +108,8 @@ class CourseController {
teacher: courseMap['teacher'],
location: courseMap['location'],
remark: courseMap['remark'],
startTime: DateTime.parse(courseMap['start']),
endTime: DateTime.parse(courseMap['end']),
startTime: DateTime.parse(courseMap['startTime']),
endTime: DateTime.parse(courseMap['endTime']),
);
courses.add(course);
}
@ -97,19 +118,28 @@ class CourseController {
}
Future<int> insertCourse(Course course) async {
return await CourseDao().insertCourse(course);
return await courseDao.insertCourse(course);
}
Future<bool> insertLocalCourse() async {
List<Course> localCourseList = await getCourses();
return await netWorkController.insertCourseList(localCourseList);
}
Future<int> insertCourseList(List<Course> courseList) async {
netWorkController.insertCourseList(courseList);
int result = 0;
for(Course course in courseList){
result += await CourseDao().insertCourse(course);
result += await courseDao.insertCourse(course);
}
return result;
}
Future<int> autoImportCours(int stuid,String passwd,int year, int term) async {
String jsonstr = await netWorkController.getUserCoursejson(stuid, passwd, year, term);
Future<int> autoImportCours(int userId,String passwd,int year, int term) async {
String ? jsonstr = await netWorkController.getUserCoursejson(userId, passwd, year, term);
if(jsonstr == null || jsonstr == ""){
return 0;
}
List<Course> courseList = await getCourseByLogin.dealRawString(jsonstr);
return await insertCourseList(courseList);
}
@ -122,11 +152,13 @@ class CourseController {
Future<int> deleteAllCourses() async {
return await CourseDao().deleteAllCourses();
return await courseDao.deleteAllCourses();
}
Future<int> deleteCourse(int courseId) async {
return await CourseDao().deleteCourseByCourseId(courseId);
netWorkController.deleteCourse(courseId);
return await courseDao.deleteCourseByCourseId(courseId);
}
}

@ -1,86 +1,619 @@
import 'dart:async';
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import "package:http/http.dart" as http;
import 'package:timemanagerapp/entity/Task.dart';
import '../entity/Course.dart';
import '../entity/Course.dart';
import '../entity/FreeTime.dart';
import '../entity/Team.dart';
import '../entity/User.dart';
import '../entity/Work.dart';
import 'package:http/http.dart' as http;
class NetWorkController {
Future<http.Response> login(User user) {
return http.post(
Uri.parse('http://192.168.33.140:3000/login'),
// String baseUrl = "http://192.168.111.226:3000/";
// String baseUrl = "http://5902e9v900.zicp.fun:30002/";
String baseUrl = "http://5902e9v900.zicp.fun:3000/";
//--------------------------------------------------
//getUserList
Future<List<User>?> getUserList() async {
final response = await http.get(
Uri.parse(baseUrl+'get_user'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
List<User> userList = (jsonResponse['data'] as List)
.map((user) => User.fromJson(user as Map<String, dynamic>))
.toList();
return userList;
} else {
print("获取用户列表");
return null;
}
}
Future<User?> login(User user) async {
final response = await http.post(
Uri.parse(baseUrl+'login'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(user.toMap()),
);
final jsonResponse = json.decode(response.body);
print("login response.statusCode = " + jsonResponse[0].toString());
if (jsonResponse['code'] == 200) {
return User.fromJson(jsonResponse['data']['user'][0]);
} else {
print("登录失败");
return null;
}
}
Future<bool> register(User user) async {
final response = await http.post(
Uri.parse(baseUrl+'register'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(user.toMap()),
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
return true;
} else {
print("注册失败");
return false;
}
}
//updeateUser
Future<bool> updateUser(User user) async {
final response = await http.post(
Uri.parse(baseUrl+'update_user'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(user.toMap()),
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
return true;
} else {
print("更新用户信息失败");
return false;
}
}
Future<int> register(User user) async {
return Future(() => 1);
//server todo
Future<bool> deleteAllUser() async {
final response = await http.post(
Uri.parse(baseUrl+'deleteUser'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode({}),
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
return true;
} else {
print("删除所有用户失败");
return false;
}
}
Future<List<Work>> getSameFreeWork(int teamid) {
List<Work> workList = [];
return Future(() => workList);
//--------------------------------------------------
Future<List<Team>?> getMyTeamList(int userId) async {
final response = await http.get(
Uri.parse(baseUrl + 'get_team').replace(queryParameters: {'leaderId': userId.toString()}),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
List<Team> teamList = (jsonResponse['data'] as List)
.map((team) => Team.fromJson(team as Map<String, dynamic>))
.toList();
return teamList;
} else {
print("获取My团队列表失败");
return null;
}
}
Future<List<Work>> getTeamWorkList(int teamid) {
List<Work> workList = [];
return Future(() => workList);
Future<List<Team>?> getAllTeamListByUserId(int userId) async {
final response = await http.get(
Uri.parse(baseUrl + 'get_team').replace(queryParameters: {'userId': userId.toString()}),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
List<Team> teamList = (jsonResponse['data'] as List)
.map((team) => Team.fromJson(team as Map<String, dynamic>))
.toList();
return teamList;
} else {
print("获取All团队列表ByUserId失败");
return null;
}
}
//getTeamByTeamName
Future<Team?> getTeamByTeamName(String teamName) async {
final response = await http.get(
Uri.parse(baseUrl + 'get_team').replace(queryParameters: {'teamName': teamName}),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
List<Team> teamList = (jsonResponse['data'] as List)
.map((team) => Team.fromJson(team as Map<String, dynamic>))
.toList();
if(teamList.length > 1) {
print("存在重复团队名");
return null;
}
return teamList[0];
} else {
print("获取团队列表ByTeamName失败");
return null;
}
}
Future<List<Team>> getTeamList(int userid) {
List<Team> teamList = [];
return Future(() => teamList);
Future<List<Team>> getAllTeamList() async {
final response = await http.get(
Uri.parse(baseUrl + 'get_team'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
List<Team> teamList = (jsonResponse['data'] as List)
.map((team) => Team.fromJson(team as Map<String, dynamic>))
.toList();
return teamList;
} else {
print("获取All团队列表失败");
return [];
}
}
Future<bool> insertTeam(Team team) async {
return true;
final response = await http.post(
Uri.parse(baseUrl+'add_team'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(team.toMap()),
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
return true;
} else {
print("insert team 失败:");
return false;
}
}
Future<bool> deleteTeam(int teamid) async {
return true;
Future<bool> deleteTeam(int teamId) async {
final response = await http.post(
Uri.parse(baseUrl+'delete_team'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: JsonEncoder().convert({
'teamId':teamId,
}),
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
return true;
} else {
print("delete team 失败:" + jsonResponse['data'].toString());
return false;
}
}
Future<bool> updateTeam(Team team) async {
return true;
final response = await http.post(
Uri.parse(baseUrl+'update_team'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(team.toMap()),
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
return true;
} else {
return false;
}
}
Future<List<User>> getTeamUserList(int teamid) async {
List<User> userList = [];
return userList;
//--------------------------------------------------
Future<List<User>?> getTeamUserList(int teamId) async {
final response = await http.get(
Uri.parse(baseUrl + 'get_team_member').replace(queryParameters: {'teamId': teamId.toString()}),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
List<User> teamUserList = (jsonResponse['data'] as List)
.map((user) => User.fromJson(user as Map<String, dynamic>))
.toList();
return teamUserList;
} else {
return [];
}
}
Future<bool> insertTeamUser(int teamid, int userid) async {
return true;
Future<bool> insertTeamUser(int id,int teamId, String userName) async {
final response = await http.post(
Uri.parse(baseUrl+'add_team_member'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: JsonEncoder().convert({
'id': id,
'teamId': teamId,
'userName': userName,
}),
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
return true;
} else {
return false;
}
}
Future<bool> deleteTeamUser(int teamid, int userid) async {
return true;
Future<bool> deleteTeamUser(int teamId, int userId) async {
final response = await http.post(
Uri.parse(baseUrl+'delete_team_member'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: JsonEncoder().convert({
'teamId': teamId,
'userId': userId,
}),
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
return true;
} else {
print("delete team user 失败:");
return false;
}
}
//--------------------------------------------------
Future<List<Work>?> getTeamWorkList(int teamId) async {
final response = await http.get(
Uri.parse(baseUrl + 'get_work').replace(queryParameters: {'teamId': teamId.toString()}),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
List<Work> teamWorkList = (jsonResponse['data'] as List)
.map((work) => Work.fromJson(work as Map<String, dynamic>))
.toList();
return teamWorkList;
} else {
return null;
}
}
//work
Future<List<Work>?> getALlTeamWorkList() async {
final response = await http.get(
Uri.parse(baseUrl + 'get_work'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
List<Work> teamWorkList = (jsonResponse['data'] as List)
.map((work) => Work.fromJson(work as Map<String, dynamic>))
.toList();
return teamWorkList;
} else {
return null;
}
}
Future<bool> insertTeamWork(List<Work> workList) async {
final response = await http.post(
Uri.parse(baseUrl+'add_work'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
//Mpajson
body: JsonEncoder().convert(
workList.map((work) => work.toMap()).toList(),
)
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
return true;
} else {
print("TeamWork插入失败");
print("body:"+ workList.map((work) => work.toMap()).toList().toString());
return false;
}
}
Future<bool> deleteTeamWork(workId) async {
final response = await http.post(
Uri.parse(baseUrl+'delete_work'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: JsonEncoder().convert({
'workId': workId, //
}),
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
return true;
} else {
return false;
}
}
//server todo
Future<List<FreeTime>?> getFreeTime(int teamid) async {
final response = await http.get(
Uri.parse(baseUrl + 'get_freeTime').replace(queryParameters: {'teamId': teamid.toString()}),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
List<FreeTime> freeTimeList = (jsonResponse['data'] as List)
.map((freeTime) => FreeTime.fromJson(freeTime as Map<String, dynamic>))
.toList();
return freeTimeList;
} else {
print("获取空闲时间失败");
return null;
}
}
//--------------------------------------------------
Future<List<Course>?> getCourseList(int userId) async {
final response = await http.get(
Uri.parse(baseUrl + 'get_course').replace(queryParameters: {'userId': userId.toString()}),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
List<Course> courseList = (jsonResponse['data'] as List)
.map((course) => Course.fromJson(course as Map<String, dynamic>))
.toList();
return courseList;
} else {
print("获取课程失败");
return null;
}
}
Future<bool> insertCourseList(List<Course> courseList) async {
final response = await http.post(
Uri.parse(baseUrl+'add_course'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(courseList.map((course) => course.toMap()).toList()),
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
return true;
} else {
print("插入课程失败");
return false;
}
}
//todo
// Future<bool> deleteTeamUser(int teamid,int userid) async {
// return true;
// }
//app,
Future<bool> updateCourse(List<Course> courseList) async {
return true;
final response = await http.post(
Uri.parse(baseUrl+'update_course'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(courseList.map((course) => course.toMap()).toList()),
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
return true;
} else {
print("更新课程失败");
return false;
}
}
Future<bool> updateTask(List<Work> workList) async {
return true;
Future<bool> deleteCourse(courseId) async {
final response = await http.post(
Uri.parse(baseUrl+'delete_course'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode({'courseId': courseId}),
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
return true;
} else {
print("删除课程失败");
return false;
}
}
Future<String> getUserCoursejson(
int stuid, String passwd, int year, int term) {
String res = "";
return Future(() => res);
//--------------------------------------------------
Future<List<Task>?> getTaskList(int userId) async {
final response = await http.get(
Uri.parse(baseUrl + 'get_task').replace(queryParameters: {'userId': userId.toString()}),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
List<Task> taskList = (jsonResponse['data'] as List)
.map((task) => Task.fromJson(task as Map<String, dynamic>))
.toList();
return taskList;
} else {
print("获取个人计划失败");
return null;
}
}
Future<bool> updateTask(List<Work> taskList) async {
final response = await http.post(
Uri.parse(baseUrl+'update_task'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(taskList.map((work) => work.toMap()).toList()),
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
return true;
} else {
print("更新个人计划失败");
return false;
}
}
Future<bool> insertTask(List<Task> taskList) async {
final response = await http.post(
Uri.parse(baseUrl+'add_task'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(taskList.map((task) => task.toMap()).toList()),
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
return true;
} else {
print("插入个人计划失败");
return false;
}
}
Future<bool> deleteTask(taskId) async {
final response = await http.post(
Uri.parse(baseUrl+'delete_task'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode({'taskId': taskId}),
);
final jsonResponse = json.decode(response.body);
if (jsonResponse['code'] == 200) {
return true;
} else {
print("删除个人计划失败");
return false;
}
}
//--------------------------------------------------
Future<String ?> getUserCoursejson(int userId, String passwd, int year, int term) async {
final response = await http.get(
Uri.parse(baseUrl+'get_all_course').replace(queryParameters: {
'userId': userId.toString(),
'passwd': passwd,
'year': year.toString(),
'term': term.toString(),
}),
);
final jsonResponse = json.decode(response.body);
//res
String resJson = jsonResponse['data'];
//res
//
String jsonString = resJson;
//
jsonString = jsonString.trim().replaceAll(RegExp(r"^\{|\}$"), '');
// 使 JSON
jsonString = jsonString.replaceAll(RegExp(r"'"), '"');
// JSON
Map<String, dynamic> data = Map<String, dynamic>.from(json.decode('{$jsonString}'));
if(data['code'] == 1000){
return resJson;
}else{
print("获取导入课程失败");
return null;
}
}
Future<String> getText() async{
final response=await http.get(Uri.parse("https://api.xygeng.cn/one"));
final jsonResponse = json.decode(response.body);
String content=jsonResponse['data']['content'];
print(content);
return content;
}
}

@ -7,10 +7,11 @@ import '../util/dataUtil.dart';
import 'NetWorkController.dart';
class TaskController {
IdGenerator idGenerator = IdGenerator();
List<Task> taskList = []; //courseList
NetWorkController netWorkController = NetWorkController();
late TaskDao taskDao;
static IdGenerator idGenerator = IdGenerator();
static List<Task> taskList = []; //taskList
static NetWorkController netWorkController = NetWorkController();
static late TaskDao taskDao;
DateTime termstartdate = Setting.startdate; //Setting.getStartDate();
@ -18,6 +19,23 @@ class TaskController {
taskDao = TaskDao();
}
Future<List<Task>> init() async {
var res = await netWorkController.getTaskList(Setting.user!.getId!);
if(res == null || res.length == 0){
taskList = [];
}else{
taskList = res;
}
for(Task task in taskList){
await taskDao.insertTask(task);
}
return taskList;
}
Future<void> dispos() async {
taskDao.deleteAllTasks();
}
Future<List<Task>> getTasks() async {
List<Map<String, dynamic>> taskMaps = await taskDao.getTasks();
List<Task> tasks = []; // Task
@ -42,6 +60,7 @@ class TaskController {
//addscheduleForm
Future<void> addScheduleForm(ScheduleForm scheduleForm) async {
List<Task> taskListToInsert = [];
int allTaskId = await idGenerator.generateId();
for (int week = scheduleForm.getStartWeek; week <= scheduleForm.getEndWeek; week++) {
for (int day in scheduleForm.selectedDays) {
//
@ -56,28 +75,29 @@ class TaskController {
hours: scheduleForm.getEndTime.hour,
minutes: scheduleForm.getEndTime.minute,
));
int taskId = await idGenerator.generateId();
Task task = Task(
id: await idGenerator.generateId(),
name: scheduleForm.getName,
userId: Setting.user!.getId!,
content: scheduleForm.getContent,
taskId: await idGenerator.generateId(),
taskId: allTaskId,
startTime: startDate,
endTime: endDate,
);
taskListToInsert.add(task);
}
await insertTaskList(taskListToInsert);
}
await insertTaskList(taskListToInsert);
}
Future<int> insertTask(Task task) async {
netWorkController.insertTask([task]);
return await taskDao.insertTask(task);
}
Future<int> insertTaskList(List<Task> taskList) async {
netWorkController.insertTask(taskList);
int result = 0;
for (Task task in taskList) {
result += await taskDao.insertTask(task);
@ -90,11 +110,13 @@ class TaskController {
return await taskDao.deleteTaskByid(id);
}
Future<int> deleteTaskByTaskid(int taskid) async {
return await taskDao.deleteTaskByTaskid(taskid);
Future<int> deleteTaskByTaskid(int taskId) async {
netWorkController.deleteTask(taskId);
return await taskDao.deleteTaskByTaskid(taskId);
}
Future<int> deleteAllTasks() async {
// netWorkController.deleteTask(taskId);
return await taskDao.deleteAllTasks();
}

@ -1,87 +1,269 @@
import 'package:timemanagerapp/controller/NetWorkController.dart';
import 'package:timemanagerapp/entity/User.dart';
import '../entity/FreeTime.dart';
import '../entity/ScheduleForm.dart';
import '../entity/Team.dart';
import '../entity/Work.dart';
import 'package:timemanagerapp/database/dao/TeamDao.dart';
import 'package:timemanagerapp/database/dao/WorkDao.dart';
import '../setting/Setting.dart';
import '../util/dataUtil.dart';
class TeamController {
late int leaderid;
List<Team> teamList = []; //teamList
Map<int, List<Work>> Wordmaplist = {};
NetWorkController netWorkController = NetWorkController();
static List<Team> allTeamList = []; //allTeamList
static List<Team> myTeamList = []; //myTeamList
static List<Team> joindedTeamList = []; //teamList
static List<Work> workList = []; //workList
static Map<int,Work> worKIdMap = {};
static Map<int,Team> teamIdMap = {};
static Map<int,List<Work>> woroListMapByTeamId = {};
static Map<int,List<User>> userListMapByTeamId = {};
static NetWorkController netWorkController = NetWorkController();
static IdGenerator idGenerator = IdGenerator();
DateTime termstartdate = Setting.startdate; //Setting.getStartDate();
TeamController() { //leaderidid
this.leaderid = Setting.user!.getId!;
//TODO: leaderidteamList
//TODO: leaderidmyTeamList
for (var team in teamList) {
for (var team in myTeamList) {
//TODO: team.idWorklist[team.id]
//Wordmaplist[team.id].add()
}
}
Future<List<Team>> getTeams(int userid) async {
return await netWorkController.getTeamList(userid);
}
Future<bool> createTeam(Team team) async {
return await netWorkController.insertTeam(team);
//-----------------------------------Team-------------------------------
// Future<void> deleteAllTeams() async {
// await netWorkController.deleteAllTeams();
// }
Future<List<Team>> getMyTeamList() async {
//
myTeamList = [];
List<Team>? res = await netWorkController.getMyTeamList(Setting.user!.getId!);
if(res==null){
return [];
}else{
// teamIdMap = {};
// for(Team team in res){
// teamIdMap[team.id!] = team;
// }
myTeamList = res;
return res;
}
}
Future<void> insertTeamList(List<Team> teamList) async {
for (Team team in teamList) {
await TeamDao().insertTeam(team);
Future<List<Team>> getJoinedTeamList() async {
if(myTeamList.length==0){
await getMyTeamList();
}
//
joindedTeamList = [];
allTeamList = [];
List<Team>? res = await netWorkController.getAllTeamListByUserId(Setting.user!.getId!);
if(res==null){
return [];
}else{
allTeamList = res;
teamIdMap = {};
for(Team team in allTeamList){
teamIdMap[team.id!] = team;
}
joindedTeamList.addAll(allTeamList); //=
for(Team team in myTeamList){
// myTeamList
joindedTeamList.removeWhere((element) => element.id == team.id);
}
return joindedTeamList;
}
}
Future<void> deleteAllTeams() async {
await TeamDao().deleteAllTeams();
// Future<void> insertTeamList(List<Team> myTeamList) async {
// for (Team team in myTeamList) {
// await netWorkController.insertTeam(team);
// }
// }
Future<bool> deleteTeam(Team team) async {
// List<User> memberList = await getTeamUserList(team.getId!); //
// for(User user in memberList){
// deleteTeamUser(team, user.getId!);
// }
return await netWorkController.deleteTeam(team.getId!);
}
Future<bool> deleteTeam(int teamid) async {
return await netWorkController.deleteTeam(teamid);
Future<bool> insertTeam(Team team) async {
team.id = await idGenerator.generateId();
bool res = await netWorkController.insertTeam(team);
print("insertTeam: $res");
if(res == false) return false;
//
int id = await idGenerator.generateId();
await netWorkController.insertTeamUser(id,team.id!, Setting.user!.getUsername!);
return true;
}
//joinTeam
Future<bool> joinTeam(String teamName) async {
//
for(Team team in allTeamList){
if(team.getTeamName == teamName){
return false;
}
}
Team ? team = await netWorkController.getTeamByTeamName(teamName);
if(team == null){
return false;
}
int id = await idGenerator.generateId();
return await netWorkController.insertTeamUser(id,team!.getId!, Setting.user!.getUsername!);
}
Future<bool> updateTeam(Team team) async {
return await netWorkController.updateTeam(team);
}
Future<void> insertWork(Work work) async {
// return await netWorkController.insertWork(work);
//------------------------------------TeamUser-------------------------------------
Future<List<User>> getTeamUserList(int teamid) async {
List<User>? res = await netWorkController.getTeamUserList(teamid);
if(res == null){
return [];
}else{
List<User> tmp = [];
for(User user in res){
if(user.getId != Setting.user!.getId!){ //
tmp.add(user);
}
}
res = tmp;
userListMapByTeamId[teamid] = res;
return res;
}
}
Future<void> insertWorkList(List<Work> workList) async {
for (Work work in workList) {
await WorkDao().insertWork(work);
Future<bool> insertTeamUser(int teamid, String membername) async {
if(membername == Setting.user!.getUsername){//
return false;
}
int id = await idGenerator.generateId();
return await netWorkController.insertTeamUser(id,teamid, membername);
}
Future<void> deleteAllWorks() async {
await WorkDao().deleteAllWorks();
Future<bool> deleteTeamUser(Team team, int userId) async {
if(team.getLeaderId == userId){
return await deleteTeam(team);
}else{
return await netWorkController.deleteTeamUser(team.getId!, userId);
}
}
Future<void> deleteWork(int id) async {
await WorkDao().deleteWorkByid(id);
//---------------------------Work----------------------
Future<List<Work>> getWorks() async {
workList = [];
// myTeamList = [];
// joindedTeamList = [];
// myTeamList = await getMyTeamList();
// joindedTeamList = await getJoinedTeamList();
// allTeamList = myTeamList + joindedTeamList;
var res = await getJoinedTeamList(); //team,
if(res == null) {
return [];
}
for(Team team in allTeamList){
workList.addAll(await getWorksByTeamId(team.id));
}
return workList;
}
Future<List<Work>> getWorksByTeamId(teamId) async {
var res = await netWorkController.getTeamWorkList(teamId);
if(res == null){
return [];
}else{
woroListMapByTeamId[teamId] = [];
for(int index = 0; index < res.length; index++){
res[index].teamName = teamIdMap[teamId]!.getTeamName;
woroListMapByTeamId[teamId]!.add(res[index]);
}
return res;
}
}
Future<void> updateWork(Work work) async {
await WorkDao().updateWork(work);
//addscheduleForm
Future<void> addScheduleForm(ScheduleForm scheduleForm,int teamId) async {
List<Work> WorkListToInsert = [];
int allWorkId = await idGenerator.generateId();
for (int week = scheduleForm.getStartWeek; week <= scheduleForm.getEndWeek; week++) {
for (int day in scheduleForm.selectedDays) {
//
final startDate = termstartdate.add(Duration(
days: (7 * (week - 1) + day! - 1),
hours: scheduleForm.getStartTime.hour,
minutes: scheduleForm.getStartTime.minute
));
final endDate = termstartdate.add(Duration(
days: (7 * (week - 1) + day! - 1),
hours: scheduleForm.getEndTime.hour,
minutes: scheduleForm.getEndTime.minute,
));
Work work = Work(
id: await idGenerator.generateId(),
name: scheduleForm.getName,
workId: allWorkId,
userId: Setting.user!.getId!,
status: "未完成",
content: scheduleForm.getContent,
teamId: teamId,
endTime: endDate,
startTime: startDate,
);
WorkListToInsert.add(work);
}
}
await insertWorkList(WorkListToInsert);
}
Future<List<Map<String, dynamic>>> getWorks() async {
return WorkDao().getWorks();
//
// Future<bool> insertWork(Work work) async {
// return await netWorkController.insertTeamWork(work);
// }
Future<void> insertWorkList(List<Work> workList) async {
// for (Work work in workList) {
await netWorkController.insertTeamWork(workList);
// }
}
Future<List<Map<String, dynamic>>> getWorksByTeamid(int teamid) async {
return WorkDao().getWorksByTeamid(teamid);
// Future<void> deleteAllWorks() async {
// await netWorkController.deleteAllWorks();
// }
Future<void> deleteWorkByWorkId(int workId) async {
await netWorkController.deleteTeamWork(workId);
}
Future<List<Work>> getSameFreeWork(int teamid){
return netWorkController.getSameFreeWork(teamid);
// Future<void> updateWork(Work work) async {
// await netWorkController.u(work);
// }
Future<List<FreeTime>> getFreeTime(int teamid)async{
var res = await netWorkController.getFreeTime(teamid);
if(res == null){
return [];
}else{
return res;
}
}

@ -1,15 +1,33 @@
import 'dart:ui';
import 'package:timemanagerapp/entity/Course.dart';
import 'package:timemanagerapp/entity/FreeTime.dart';
import 'package:timemanagerapp/setting/Setting.dart';
class TimetableWidgetController {
final double pixelToMinuteRatio =
0.9 * Setting.pixelToMinuteRatio_ratio; //old:0.9
late List<Course> courseList;
late DateTime mondayTime;
late int weekCount;
late DateTime termStartDate;
static late DateTime mondayTime = getmondayTime();
static late int weekCount = getWeekCount();
static late DateTime termStartDate = Setting.startdate;
static List<DateTime> timePoints = [
DateTime(2023, 9, 22, 7, 00),
DateTime(2023, 9, 22, 7, 30),
DateTime(2023, 9, 22, 8, 0), // 8:00 AM
DateTime(2023, 9, 22, 9, 35), // 8:15 PM
DateTime(2023, 9, 22, 10, 5),
DateTime(2023, 9, 22, 11, 40),
DateTime(2023, 9, 22, 12, 30),
DateTime(2023, 9, 22, 13, 30),
DateTime(2023, 9, 22, 15, 5), // 8:00 AM
DateTime(2023, 9, 22, 15, 35), // 12:30 PM
DateTime(2023, 9, 22, 17, 10),
DateTime(2023, 9, 22, 18, 30),
DateTime(2023, 9, 22, 19, 15), // 8:00 AM
DateTime(2023, 9, 22, 20, 5), // 12:30 PM
DateTime(2023, 9, 22, 20, 55),
DateTime(2023, 9, 22, 21, 40),
DateTime(2023, 9, 22, 23, 00),
];
TimetableWidgetController() {
mondayTime = getmondayTime();
@ -23,27 +41,85 @@ class TimetableWidgetController {
}
//piexl
List<Offset> convertTimeList(List<DateTime> timePoints, double deviceWidth) {
static List<Offset> convertTimeList(List<DateTime> timePoints) {
print("deviceWidth: ${Setting.deviceWidth.toString()}");
List<Offset> convertedTimes = [];
for (var time in timePoints) {
int hour = time.hour;
int minute = time.minute;
int totalMinutes = (hour - 7) * 60 + minute;
double convertedTime = totalMinutes * pixelToMinuteRatio;
convertedTimes.add(Offset(deviceWidth * 0.015, convertedTime));
double convertedTime = totalMinutes * Setting.pixelToMinuteRatio_ratio;
convertedTimes.add(Offset(Setting.deviceWidth * 0.015, convertedTime));
}
// print("convertedTimesOffset: $convertedTimes");
return convertedTimes;
}
int getWeekCount() {
weekCount = DateTime.now().difference(termStartDate).inDays ~/ 7 + 1;
//
List<FreeTime> repairFreeTimeBlockList(List freeTimeBlockList) {
List<FreeTime> repairedFreeTimeBlockList = [];
DateTime termStartDate = Setting.startdate;
DateTime termEndDate = termStartDate.add(Duration(days: 7 * Setting.termAllWeekCout));
//termEndDate23:00:00
termEndDate = DateTime(termEndDate.year, termEndDate.month, termEndDate.day, 23, 00, 00);
Set<DateTime> freeTimeBlockSet = {}; //,
for (var freeTimeBlock in freeTimeBlockList) {
//,
//
bool keepFlag = true;
if(freeTimeBlock.startTime.isBefore(termStartDate)){
keepFlag = false;
}
if(freeTimeBlock.endTime.isAfter(termEndDate)){
keepFlag = false;
}
if (freeTimeBlock.startTime.hour < 7) {
keepFlag = false;
}
if (freeTimeBlock.endTime.hour > 23) {
keepFlag = false;
}
// if(freeTimeBlock.startTime.compareTo(freeTimeBlock.endTime)==0){ //
// keepFlag = false; //,,freeTimeBlockSet,
// freeTimeBlockSet.add(DateTime(freeTimeBlock.startTime.year, freeTimeBlock.startTime.month, freeTimeBlock.startTime.day));
// }
if(keepFlag){
freeTimeBlockSet.add(DateTime(freeTimeBlock.startTime.year, freeTimeBlock.startTime.month, freeTimeBlock.startTime.day));
repairedFreeTimeBlockList.add(freeTimeBlock);
}else{
freeTimeBlockList.remove(freeTimeBlock);
}
}
//
for(var date = termStartDate; date.isBefore(termEndDate); date = date.add(Duration(days: 1))){
date = DateTime(date.year, date.month, date.day);
if(freeTimeBlockSet.contains(date)){
//,
continue;
}
DateTime startTime = DateTime(date.year, date.month, date.day, 7, 0);
DateTime endTime = DateTime(date.year, date.month, date.day, 23, 0);
FreeTime freeTime = FreeTime(startTime: startTime, endTime: endTime);
repairedFreeTimeBlockList.add(freeTime);
}
return repairedFreeTimeBlockList;
}
static int getWeekCount({DateTime ? dateTime}) {
dateTime ??= DateTime.now();
weekCount = dateTime.difference(termStartDate).inDays ~/ 7 + 1;
return weekCount;
}
DateTime getmondayTime() {
static DateTime getmondayTime() {
mondayTime = DateTime.now();
print("获取mondayTime: $mondayTime");
//
while (mondayTime.weekday != 1) {
mondayTime = mondayTime.subtract(Duration(days: 1));
@ -51,7 +127,37 @@ class TimetableWidgetController {
return mondayTime;
}
Map<int, List> transformCourseMap(List blockList) {
static List<String> getSelectDayList(DateTime date) {
List<String> selectedDayList = [];
//dataselectedDayList
int day = date.weekday;
switch (day) {
case 1:
selectedDayList.add("周一");
break;
case 2:
selectedDayList.add("周二");
break;
case 3:
selectedDayList.add("周三");
break;
case 4:
selectedDayList.add("周四");
break;
case 5:
selectedDayList.add("周五");
break;
case 6:
selectedDayList.add("周六");
break;
case 7:
selectedDayList.add("周日");
break;
}
return selectedDayList;
}
Map<int, List> transformTimeBlockMap(List blockList) {
Map<int, List> timeblockMap = {};
for (var timeBlock in blockList) {
int weekCount = timeBlock.startTime.difference(termStartDate).inDays ~/ 7 + 1; //
@ -65,23 +171,24 @@ class TimetableWidgetController {
}
//x
var weekListPixel=[0,Setting.deviceWidth*0.12,Setting.deviceWidth*0.24,Setting.deviceWidth*0.36,Setting.deviceWidth*0.48,Setting.deviceWidth*0.60,Setting.deviceWidth*0.72];
var weekListPixel=[0,0.12,0.24,0.36,0.48,0.60,0.72];
// Course(this.name, this.teacher, this.location, this.startTime, this.endTime);
double getdy(timeBlock)
{
double y=(((timeBlock.startTime.hour-7)*60+timeBlock.startTime.minute)*0.9)*Setting.pixelToMinuteRatio_ratio;
//9
double y=((timeBlock.startTime.hour-7)*60+timeBlock.startTime.minute)*Setting.pixelToMinuteRatio_ratio + 9;
return y;
}
double getdx(timeBlock)
{
int x=timeBlock.startTime.weekday-1;
return weekListPixel[x].toDouble();
return Setting.deviceWidth*weekListPixel[x].toDouble();
}
double getHeight(timeBlock){
return (((timeBlock.endTime.hour-7)*60+timeBlock.endTime.minute)*0.9-this.getdy(timeBlock))*Setting.pixelToMinuteRatio_ratio;
return ((timeBlock.endTime.hour*60+timeBlock.endTime.minute)-(timeBlock.startTime.hour*60+timeBlock.startTime.minute))*Setting.pixelToMinuteRatio_ratio;
}
}

@ -2,54 +2,104 @@ import 'package:timemanagerapp/database/dao/UserDao.dart';
import 'package:timemanagerapp/database/MyDatebase.dart';
import 'package:timemanagerapp/entity/User.dart';
import '../provider/TimeProvider.dart';
import '../setting/Setting.dart';
import '../util/dataUtil.dart';
import 'CourseController.dart';
import 'NetWorkController.dart';
import 'TaskController.dart';
/**
*
*/
class UserController {
NetWorkController netWorkController = NetWorkController();
IdGenerator idGenerator = IdGenerator();
static NetWorkController netWorkController = NetWorkController();
static IdGenerator idGenerator = IdGenerator();
//
static UserController getInstance() {
return new UserController();
}
Future<List<Map<String, dynamic>>> getUsers() async {
return await UserDao.getInstance().getUsers();
//getUserList
Future<List<User>> getUserList() async {
List<User>? res = await netWorkController.getUserList();
if(res==null){
return [];
}else{
return res;
}
}
Future<bool> login(User user) async {
Future<bool> login(User login_user) async {
//todo:
// int userid = await netWorkController.login(user);
User ?user = await netWorkController.login(login_user);
//
int userid = Setting.user!.getId!;
if(userid == -1){
// int userid = Setting.user!.getId!;
if(user == null){
return false;
}
user.id = userid;
await Setting.saveUser(user);
//
if(Setting.initFlag) {
//
await MyDatabase.reBuildDatabase();
print('从服务器初始化');
await CourseController().init();
await TaskController().init();
await Setting.saveInitFlag(false);
}
return true;
}
Future<bool> register(User user) async {
Future<bool> register(User postUser) async {
//todo:
// int userid = await netWorkController.login(user);
//
int userid = await idGenerator.generateId();
print("userid生成:"+userid.toString());
if(userid == -1){
postUser.id = userid;
bool res = await netWorkController.register(postUser);
//
if(!res){
print('注册失败');
return false;
}
user.id = userid;
await Setting.saveUser(user);
//
// await Setting.saveUser(postUser);
//todo:
return true;
}
//updateUser
Future<bool> updateUser(User postUser) async {
bool res = await netWorkController.updateUser(postUser);
if( !res ){
return false;
}else{
await Setting.saveUser(postUser);
return true;
}
}
// //
// Future<bool> deleteUser(User postUser) async {
// //todo:
// int userid = await idGenerator.generateId();
// postUser.id = userid;
// bool res = await netWorkController.register(postUser);
// //
// if(!res){
// print('注册失败');
// return false;
// }
// //
// // await Setting.saveUser(postUser);
// //todo:
// return true;
// }
Future<void> insertUser(User user) async {
await UserDao.getInstance().insertUser(user);
}

@ -1,105 +1,133 @@
import 'package:timemanagerapp/entity/ScheduleForm.dart';
import '../database/dao/WorkDao.dart';
import '../entity/Work.dart';
import '../setting/Setting.dart';
import '../util/dataUtil.dart';
import 'NetWorkController.dart';
class WorkController {
IdGenerator idGenerator = IdGenerator();
List<Work> WorkList = []; //courseList
NetWorkController netWorkController = NetWorkController();
DateTime termstartdate = Setting.startdate; //Setting.getStartDate();
Future<List<Work>> getWorks() async {
//todo http
// List<Map<String, dynamic>> WorkMaps = await WorkDao().getWorks();
// List<Work> Works = []; // Work
//
// for (var WorkMap in WorkMaps) {
// // 使WorkMapWork
// Work work = Work(
// id: WorkMap['id'],
// userId: WorkMap['userId'],
// content: WorkMap['content'],
// WorkId: WorkMap['WorkId'],
// name: WorkMap['name'],
// startTime: DateTime.parse(WorkMap['startTime']),
// endTime: DateTime.parse(WorkMap['endTime']),
// );
// Works.add(Work);
// }
// WorkList = Works; // Work
return WorkList;
}
//addscheduleForm
Future<void> addScheduleForm(ScheduleForm scheduleForm,int teamId) async {
List<Work> WorkListToInsert = [];
for (int week = scheduleForm.getStartWeek; week <= scheduleForm.getEndWeek; week++) {
for (int day in scheduleForm.selectedDays) {
//
final startDate = termstartdate.add(Duration(
days: (7 * (week - 1) + day! - 1),
hours: scheduleForm.getStartTime.hour,
minutes: scheduleForm.getStartTime.minute
));
final endDate = termstartdate.add(Duration(
days: (7 * (week - 1) + day! - 1),
hours: scheduleForm.getEndTime.hour,
minutes: scheduleForm.getEndTime.minute,
));
Work work = Work(
id: await idGenerator.generateId(),
name: scheduleForm.getName,
workId: await idGenerator.generateId(),
userId: Setting.user!.getId!,
status: "未完成",
workContent: scheduleForm.getContent,
teamId: teamId,
functionaryId: 0, //???
endTime: endDate,
startTime: startDate,
);
WorkListToInsert.add(work);
}
await insertWorkList(WorkListToInsert);
}
}
// Future<int> insertWork(Work Work) async {
// return await WorkDao().insertWork(Work);
// }
//
Future<int> insertWorkList(List<Work> WorkList) async {
int result = 0;
// for (Work Work in WorkList) {
// result += await WorkDao().insertWork(Work);
// }
return result;
}
//
// //delete
// Future<int> deleteWorkByid(int id) async {
// return await WorkDao().deleteWorkByid(id);
// }
//
// Future<int> deleteWorkByWorkid(int Workid) async {
// return await WorkDao().deleteWorkByWorkid(Workid);
// }
//
// Future<int> deleteAllWorks() async {
// return await WorkDao().deleteAllWorks();
// }
//
// //update
// Future<int> updateWork(Work Work) async {
// return await WorkDao().updateWork(Work);
// }
}
// import 'package:timemanagerapp/entity/ScheduleForm.dart';
//
// import '../database/dao/WorkDao.dart';
// import '../entity/Work.dart';
// import '../setting/Setting.dart';
// import '../util/dataUtil.dart';
// import 'NetWorkController.dart';
//
// class WorkController {
// static IdGenerator idGenerator = IdGenerator();
// static List<Work> WorkList = []; //courseList
// static NetWorkController netWorkController = NetWorkController();
//
// DateTime termstartdate = Setting.startdate; //Setting.getStartDate();
//
// Future<List<Work>> getWorks() async {
// //todo http
// List<Map<String, dynamic>> workMaps = await WorkDao().getWorks();
// List<Work> Works = []; // Work
//
// for (var workMap in workMaps) {
// // 使WorkMapWork
// Work work = Work(
// id: workMap['id'],
// userId: workMap['userId'],
// content: workMap['content'],
// workId: workMap['workId'],
// name: workMap['name'],
// startTime: DateTime.parse(workMap['startTime']),
// endTime: DateTime.parse(workMap['endTime']),
// status: workMap['status'],
// teamId: workMap['teamId'],
// );
// Works.add(work);
// }
// WorkList = Works; // Work
// return WorkList;
// }
//
// //addscheduleForm
// Future<void> addScheduleForm(ScheduleForm scheduleForm,int teamId) async {
// List<Work> WorkListToInsert = [];
// int allWorkId = await idGenerator.generateId();
// for (int week = scheduleForm.getStartWeek; week <= scheduleForm.getEndWeek; week++) {
// for (int day in scheduleForm.selectedDays) {
// //
// final startDate = termstartdate.add(Duration(
// days: (7 * (week - 1) + day! - 1),
// hours: scheduleForm.getStartTime.hour,
// minutes: scheduleForm.getStartTime.minute
// ));
//
// final endDate = termstartdate.add(Duration(
// days: (7 * (week - 1) + day! - 1),
// hours: scheduleForm.getEndTime.hour,
// minutes: scheduleForm.getEndTime.minute,
// ));
// Work work = Work(
// id: await idGenerator.generateId(),
// name: scheduleForm.getName,
// workId: allWorkId,
// userId: Setting.user!.getId!,
// status: "未完成",
// content: scheduleForm.getContent,
// teamId: teamId,
// endTime: endDate,
// startTime: startDate,
// );
// WorkListToInsert.add(work);
// }
// }
// await insertWorkList(WorkListToInsert);
// }
//
// Future<int> insertWork(Work Work) async {
// return await WorkDao().insertWork(Work);
// }
//
// Future<int> insertWorkList(List<Work> workList) async {
// int result = 0;
// for (Work work in workList) {
// result += await WorkDao().insertWork(work);
// }
// return result;
// }
//
// //仿Taskwork
// //query
// Future<List<Work>> getWorkList() async {
// List<Map<String, dynamic>> workMaps = await WorkDao().getWorks();
// List<Work> workList = []; // Work
//
// for (var workMap in workMaps) {
// // 使WorkMapWork
// Work work = Work(
// id: workMap['id'],
// userId: workMap['userId'],
// content: workMap['content'],
// workId: workMap['workId'],
// name: workMap['name'],
// startTime: DateTime.parse(workMap['startTime']),
// endTime: DateTime.parse(workMap['endTime']),
// status: workMap['status'],
// teamId: workMap['teamId'],
// );
// workList.add(work);
// }
// WorkList = workList; // Work
// return WorkList;
// }
//
// // //delete 仿Task
// // Future<int> deleteWorkByid(int id) async{
// // return await WorkDao().deleteWorkByid(id);
// // }
//
//
// Future<int> deleteWorkByWorkid(int workid) async {
// return await WorkDao().deleteWorkByWorkid(workid);
// }
//
// Future<int> deleteAllWorks() async {
// return await WorkDao().deleteAllWorks();
// }
//
// //update
// Future<int> updateWork(Work work) async {
// return await WorkDao().updateWork(work);
// }
//
//
//
// }

@ -18,8 +18,7 @@ class MyDatabase {
await openDatabase(path, version: 1, onCreate: _createTables);
//
// await _dropAllTables(database);
// await dropAllTables(database);
//
await _createTables(database, 1);
@ -27,6 +26,8 @@ class MyDatabase {
}
static Future<void> _createTables(Database db, int version) async {
// await _createAllTableBySql(db);
print("create table");
//Course
await _createCourseTable(db, version);
// User
@ -39,17 +40,83 @@ class MyDatabase {
await _createTaskTable(db, version);
// Team
await _createTeamTable(db, version);
print("create table success");
}
static Future<void> _createAllTableBySql(Database db) async{
//bug:
await db.execute('''
CREATE TABLE IF NOT EXISTS users(
id BIGINT PRIMARY KEY,
username VARCHAR(255) NOT NULL UNIQUE,
password TEXT NOT NULL,
role BIGINT NOT NULL
);
CREATE TABLE IF NOT EXISTS works (
id BIGINT PRIMARY KEY,
userId BIGINT NOT NULL,
workId BIGINT NOT NULL,
teamId BIGINT NOT NULL,
name TEXT NOT NULL,
content TEXT,
status TEXT,
endTime TEXT NOT NULL,
startTime TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS clocks (
id BIGINT PRIMARY KEY,
clockId BIGINT NOT NULL,
userId BIGINT NOT NULL,
text TEXT,
img TEXT,
music TEXT
);
CREATE TABLE IF NOT EXISTS tasks (
id BIGINT PRIMARY KEY,
taskId BIGINT NOT NULL,
userId BIGINT NOT NULL,
content TEXT,
name TEXT NOT NULL,
startTime TEXT NOT NULL,
endTime TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS course(
id BIGINT PRIMARY KEY,
userId BIGINT,
courseId BIGINT NOT NULL,
name TEXT NOT NULL,
credit REAL,
teacher TEXT,
location TEXT,
remark TEXT,
start TEXT NOT NULL,
end TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS teams (
id BIGINT PRIMARY KEY,
leaderId BIGINT NOT NULL,
teamName TEXT NOT NULL,
maxNumber BIGINT,
introduce TEXT
);
CREATE TABLE IF NOT EXISTS userteams (
id BIGINT PRIMARY KEY,
userId BIGINT NOT NULL,
teamId BIGINT NOT NULL
);
''');
}
static Future<void> _createUserTable(Database db, int version) async {
// User
await db.execute('''
CREATE TABLE IF NOT EXISTS users(
id INTEGER PRIMARY KEY,
username TEXT NOT NULL,
password TEXT NOT NULL,
role INTEGER NOT NULL
id BIGINT PRIMARY KEY,
username VARCHAR(255) NOT NULL,
password TEXT NOT NULL,
role BIGINT NOT NULL
);
''');
// print("userstable create success");
@ -59,13 +126,13 @@ class MyDatabase {
// Work
await db.execute('''
CREATE TABLE IF NOT EXISTS works (
id INTEGER PRIMARY KEY,
userId INTEGER NOT NULL,
workId INTEGER NOT NULL,
teamId INTEGER NOT NULL,
id BIGINT PRIMARY KEY,
userId BIGINT NOT NULL,
workId BIGINT NOT NULL,
teamId BIGINT NOT NULL,
name TEXT NOT NULL,
content TEXT,
status TEXT,
workContent TEXT NOT NULL,
endTime TEXT NOT NULL,
startTime TEXT NOT NULL
);
@ -77,9 +144,9 @@ class MyDatabase {
// Clock
await db.execute('''
CREATE TABLE IF NOT EXISTS clocks (
id INTEGER PRIMARY KEY,
clockId INTEGER NOT NULL,
userId INTEGER NOT NULL,
id BIGINT PRIMARY KEY,
clockId BIGINT NOT NULL,
userId BIGINT NOT NULL,
text TEXT,
img TEXT,
music TEXT
@ -91,9 +158,9 @@ class MyDatabase {
// Task
await db.execute('''
CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY,
taskId INTEGER NOT NULL,
userId INTEGER NOT NULL,
id BIGINT PRIMARY KEY,
taskId BIGINT NOT NULL,
userId BIGINT NOT NULL,
content TEXT,
name TEXT NOT NULL,
startTime TEXT NOT NULL,
@ -106,16 +173,16 @@ class MyDatabase {
// Course
await db.execute('''
CREATE TABLE IF NOT EXISTS course(
id INTEGER PRIMARY KEY,
userId INTEGER,
courseId INTEGER NOT NULL,
id BIGINT PRIMARY KEY,
userId BIGINT,
courseId BIGINT NOT NULL,
name TEXT NOT NULL,
credit REAL,
teacher TEXT,
location TEXT,
remark TEXT,
start TEXT NOT NULL,
end TEXT NOT NULL
startTime TEXT NOT NULL,
endTime TEXT NOT NULL
);
''');
}
@ -124,10 +191,10 @@ class MyDatabase {
// Team
await db.execute('''
CREATE TABLE IF NOT EXISTS teams (
id INTEGER PRIMARY KEY,
leaderId INTEGER NOT NULL,
id BIGINT PRIMARY KEY,
leaderId BIGINT NOT NULL,
teamName TEXT NOT NULL,
maxNumber INTEGER,
maxNumber BIGINT,
introduce TEXT
);
''');
@ -136,17 +203,18 @@ class MyDatabase {
static Future<void> _createUserTeamTable(Database db, int version) async {
// userTeam
await db.execute('''
CREATE TABLE IF NOT EXISTS userteams (
id INTEGER PRIMARY KEY,
userId INTEGER NOT NULL,
teamId INTEGER NOT NULL
CREATE TABLE IF NOT EXISTS userteams (
id BIGINT PRIMARY KEY,
userId BIGINT NOT NULL,
teamId BIGINT NOT NULL
);
''');
}
//
static Future<void> _dropAllTables(Database database) async {
static Future<void> dropAllTables(Database database) async {
// SQL
await database.transaction((txn) async {
// 'table1''table2''table3'
await txn.execute('DROP TABLE IF EXISTS users');
@ -158,4 +226,14 @@ class MyDatabase {
await txn.execute('DROP TABLE IF EXISTS userteams');
});
}
static Future<void> reBuildDatabase() async {
final databasePath = await getDatabasesPath();
final path = join(databasePath, 'tma.db');
final database =
await openDatabase(path, version: 1, onCreate: _createTables);
await dropAllTables(database);
await _createTables(database, 1);
}
}

@ -17,7 +17,8 @@ class CourseDao {
Future<List<Map<String, dynamic>>> getCourses() async {
final database = await _database;
if (database != null) {
return database.rawQuery('SELECT * FROM course');
return database.query('course', orderBy: 'id ASC');
// return database.rawQuery('SELECT * FROM course');
} else {
return [];
}
@ -27,14 +28,14 @@ class CourseDao {
final database = await _database;
int result = 0;
if (database != null) {
await database.transaction((txn) async {
//
//!!!
result = await txn.rawInsert('''
INSERT INTO course(userId,courseId,name,credit,teacher,location,remark,start,end)
VALUES(${course.userId},${course.courseId},"${course.name}",${course.credit},"${course.teacher}","${course.location}","${course.remark}","${course.startTime}","${course.endTime}")
''');
});
var tmp = course.toMap();
result += await database.insert('course', course.toMap());
// result = await txn.rawInsert('''
// INSERT INTO course(userId,courseId,name,credit,teacher,location,remark,start,end)
// VALUES(${course.userId},${course.courseId},"${course.name}",${course.credit},"${course.teacher}","${course.location}","${course.remark}","${course.startTime}","${course.endTime}")
// ''');
// print("课程插入 : " + course.toString());
}
return result;
@ -44,16 +45,16 @@ class CourseDao {
final database = await _database;
int result = 0;
if (database != null) {
await database.transaction((txn) async {
result = await txn.rawUpdate('''
UPDATE course SET userId = ${course.userId},courseId = ${course
.courseId},name = "${course.name}",credit = ${course
.credit},teacher = "${course.teacher}",location = "${course
.location}",remark = "${course.remark}",start = "${course
.startTime}",end = "${course.endTime}"
WHERE id = ${course.id}
''');
});
result += await database
.update('course', course.toMap(), where: 'id = ?', whereArgs: [course.id]);
// result = await txn.rawUpdate('''
// UPDATE course SET userId = ${course.userId},courseId = ${course
// .courseId},name = "${course.name}",credit = ${course
// .credit},teacher = "${course.teacher}",location = "${course
// .location}",remark = "${course.remark}",start = "${course
// .startTime}",end = "${course.endTime}"
// WHERE id = ${course.id}
// ''');
}
return result;
}
@ -62,16 +63,17 @@ class CourseDao {
final database = await _database;
int result = 0;
if (database != null) {
await database.transaction((txn) async {
result = await txn.rawUpdate('''
UPDATE course SET userId = ${course.userId},courseId = ${course
.courseId},name = "${course.name}",credit = ${course
.credit},teacher = "${course.teacher}",location = "${course
.location}",remark = "${course.remark}",start = "${course
.startTime}",end = "${course.endTime}"
WHERE courseId = ${course.courseId}
''');
});
result += await database
.update('course', course.toMap(), where: 'courseId = ?', whereArgs: [course.courseId]);
// result = await txn.rawUpdate('''
// UPDATE course SET userId = ${course.userId},courseId = ${course
// .courseId},name = "${course.name}",credit = ${course
// .credit},teacher = "${course.teacher}",location = "${course
// .location}",remark = "${course.remark}",start = "${course
// .startTime}",end = "${course.endTime}"
// WHERE courseId = ${course.courseId}
// ''');
}
return result;
}

@ -16,7 +16,7 @@ class WorkDao {
Future<List<Map<String, dynamic>>> getWorks() async {
final database = await db;
if (database != null) {
return database.query('Work', orderBy: 'id ASC');
return database.query('works', orderBy: 'id ASC');
} else {
return [];
}
@ -25,52 +25,65 @@ class WorkDao {
Future<List<Map<String, dynamic>>> getWorksByTeamid(int teamid) async {
final database = await db;
if (database != null) {
return database.query('Work', where: 'teamid = ?', whereArgs: [teamid], orderBy: 'id ASC');
return database.query('works', where: 'teamId = ?', whereArgs: [teamid], orderBy: 'id ASC');
} else {
return [];
}
}
Future<void> insertWork(Work work) async {
Future<int> insertWork(Work work) async {
final database = await db;
int res = 0;
if (database != null) {
await database.insert('Work', work.toMap());
res += await database.insert('works', work.toMap());
}
return res;
}
Future<void> updateWork(Work work) async {
Future<int> updateWork(Work work) async {
final database = await db;
int res = 0;
if (database != null) {
await database
.update('Work', work.toMap(), where: 'id = ?', whereArgs: [work.id]);
res += await database
.update('works', work.toMap(), where: 'id = ?', whereArgs: [work.id]);
}
return res;
}
Future<void> deleteWorkByid(int id) async {
Future<int> deleteWorkByid(int id) async {
final database = await db;
int res = 0;
if (database != null) {
await database.delete('Work', where: 'id = ?', whereArgs: [id]);
res += await database.delete('works', where: 'id = ?', whereArgs: [id]);
}
return res;
}
Future<void> deleteWorkByWorkid(int workid) async {
Future<int> deleteWorkByWorkid(int workid) async {
final database = await db;
int res = 0;
if (database != null) {
await database.delete('Work', where: 'workid = ?', whereArgs: [workid]);
res += await database.delete('works', where: 'workId = ?', whereArgs: [workid]);
}
return res;
}
Future<void> deleteWorkByTeamid(int teamid) async {
Future<int> deleteWorkByTeamid(int teamid) async {
final database = await db;
int res = 0;
if (database != null) {
await database.delete('Work', where: 'teamid = ?', whereArgs: [teamid]);
res += await database.delete('works', where: 'teamId = ?', whereArgs: [teamid]);
}
return res;
}
Future<void> deleteAllWorks() async {
Future<int> deleteAllWorks() async {
final database = await db;
int res = 0;
if (database != null) {
await database.delete('Work', where: '1=1');
res += await database.delete('works', where: '1=1');
}
return res;
}
}

@ -27,6 +27,7 @@ class Course {
Map<String,dynamic> toMap(){
return {
'id': id,
'userId':userId,
'courseId':courseId,
'name':"$name",
@ -39,7 +40,20 @@ class Course {
};
}
factory Course.fromJson(Map<String, dynamic> course) {
return Course(
id: course['id'],
userId: course['userId'],
courseId: course['courseId'],
name: course['name'],
credit: 1.0*course['credit'],
teacher: course['teacher'],
location: course['location'],
remark: course['remark'],
startTime: DateTime.parse(course['startTime']),
endTime: DateTime.parse(course['endTime']),
);
}
// Getter methods
int? get getId => id;
@ -58,9 +72,9 @@ class Course {
String get getRemark => remark;
DateTime get getstartTime => startTime;
DateTime get getStartTime => startTime;
DateTime get getendTime => endTime;
DateTime get getEndTime => endTime;
// Setter methods
set setId(int newId) {

@ -0,0 +1,83 @@
class FreeTime {
int? id;
int? userId;
String? content;
String? name;
DateTime startTime;
DateTime endTime;
FreeTime({
this.id,
this.userId,
this.content,
this.name,
required this.startTime,
required this.endTime,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'userId': userId,
'content': "$content",
'name': "$name",
'startTime': "${startTime.toIso8601String()}",
'endTime': "${endTime.toIso8601String()}"
};
}
factory FreeTime.fromJson(Map<String, dynamic> task) {
return FreeTime(
// id: task['id'],
// userId: task['userId'],
// content: task['content'],
// name: task['name'],
startTime: DateTime.parse(task['startTime']),
endTime: DateTime.parse(task['endTime']),
);
}
// Getter methods
int? get getId => id;
int? get getUserId => userId;
String? get getContent => content;
String? get getName => name;
DateTime get getStartTime => startTime;
DateTime get getEndTime => endTime;
// Setter methods
set setId(int newId) {
id = newId;
}
set setUserId(int newUserId) {
userId = newUserId;
}
set setContent(String newContent) {
content = newContent;
}
set setName(String newName) {
name = newName;
}
set setStartTime(DateTime newStartTime) {
startTime = newStartTime;
}
set setEndTime(DateTime newEndTime) {
endTime = newEndTime;
}
// toString method
@override
String toString() {
return 'FreeTime(id: $id, userId: $userId, content: $content, name: $name, startTime: $startTime, endTime: $endTime)';
}
}

@ -19,6 +19,7 @@ class Task {
Map<String, dynamic> toMap() {
return {
'id': id,
'userId': userId,
'content': "$content",
'taskId': taskId,
@ -28,6 +29,18 @@ class Task {
};
}
factory Task.fromJson(Map<String, dynamic> task) {
return Task(
id: task['id'],
userId: task['userId'],
content: task['content'],
taskId: task['taskId'],
name: task['name'],
startTime: DateTime.parse(task['startTime']),
endTime: DateTime.parse(task['endTime']),
);
}
// Getter methods
int? get getId => id;

@ -3,22 +3,36 @@ class Team {
int leaderId;
String teamName;
int maxNumber;
String? introduce;
Team({
this.id,
required this.leaderId,
required this.teamName,
required this.maxNumber,
this.introduce
});
Map<String, dynamic> toMap() {
return {
'id': id,
'leaderId': leaderId,
'teamName': "$teamName",
'maxNumber': maxNumber,
'introduce': "$introduce"
};
}
factory Team.fromJson(Map<String, dynamic> json) {
return Team(
id: json['id'],
leaderId: json['leaderId'],
teamName: json['teamName'],
maxNumber: json['maxNumber'],
introduce: json['introduce'],
);
}
// Getter methods
int? get getId => id;
@ -28,6 +42,8 @@ class Team {
int get getMaxNumber => maxNumber;
String? get getIntroduce => introduce;
// Setter methods
set setId(int newId) {
id = newId;
@ -45,9 +61,13 @@ class Team {
maxNumber = newMaxNumber;
}
set setIntroduce(String newIntroduce) {
introduce = newIntroduce;
}
// toString method
@override
String toString() {
return 'Team(id: $id, leaderId:$leaderId, teamName:$teamName, maxNumber: $maxNumber)';
return 'Team{id: $id, leaderId: $leaderId, teamName: $teamName, maxNumber: $maxNumber, introduce: $introduce}';
}
}

@ -14,12 +14,20 @@ class User {
Map<String, dynamic> toMap() {
return {
'id': id,
'username': "$username",
'password': "$password",
'role': role,
};
}
factory User.fromJson(Map<String, dynamic> user) {
return User(
id: user['id'],
username: user['username'],
password: user['password'],
role: user['role'],
);
}
// Getter methods
int? get getId => id;

@ -2,22 +2,22 @@ class Work {
late int? id;
late int userId;
late String status;
late String workContent;
late String content;
late String name;
late int teamId;
late int functionaryId;
late int workId;
late DateTime endTime;
late DateTime startTime;
late String? teamName;
Work({
this.id,
required this.userId,
required this.status,
required this.workContent,
required this.content,
required this.teamId,
this.teamName,
required this.name,
required this.functionaryId,
required this.workId,
required this.endTime,
required this.startTime,
@ -25,18 +25,32 @@ class Work {
Map<String, dynamic> toMap() {
return {
'id': id,
'userId': userId,
'status': "$status",
'workContent': "$workContent",
'content': "$content",
'teamId': teamId,
'name': "$name",
'functionaryId': functionaryId,
'workId': workId,
'endTime': "${endTime.toIso8601String()}",
'startTime': "${startTime.toIso8601String()}"
};
}
factory Work.fromJson(Map<String, dynamic> work) {
return Work(
id: work['id'],
userId: work['userId'],
status: work['status'],
content: work['content'],
teamId: work['teamId'],
name: work['name'],
workId: work['workId'],
endTime: DateTime.parse(work['endTime']),
startTime: DateTime.parse(work['startTime']),
);
}
// Getter methods
int? get getId => id;
@ -44,13 +58,13 @@ class Work {
String get getStatus => status;
String get getWorkContent => workContent;
String get getContent => content;
String get getName => name;
int get getTeamId => teamId;
String? get getTeamName => teamName;
int get getFunctionaryId => functionaryId;
int get getTeamId => teamId;
int get getWorkId => workId;
@ -71,20 +85,20 @@ class Work {
status = newStatus;
}
set setWorkContent(String newWorkContent) {
workContent = newWorkContent;
set setContent(String newcontent) {
content = newcontent;
}
set setTeamId(int newTeamId) {
teamId = newTeamId;
}
set setName(String newName) {
name = newName;
set setTeamName(String newTeamName) {
teamName = newTeamName;
}
set setFunctionaryId(int newFunctionaryId) {
functionaryId = newFunctionaryId;
set setName(String newName) {
name = newName;
}
set setWorkId(int newWorkId) {
@ -102,6 +116,6 @@ class Work {
// toString method
@override
String toString() {
return 'Work(id: $id, userId:$userId, name:$name, status: $status, workContent: $workContent, teamId: $teamId, functionaryId: $functionaryId, workId: $workId, endTime: $endTime, startTime: $startTime)';
return 'Work(id: $id, userId:$userId, name:$name, status: $status, content: $content, teamId: $teamId, workId: $workId, endTime: $endTime, startTime: $startTime)';
}
}

@ -1,6 +1,9 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:timemanagerapp/provider/TeamProvider.dart';
import 'package:timemanagerapp/provider/TeamUserProvider.dart';
import 'package:timemanagerapp/setting/Setting.dart';
import 'package:timemanagerapp/util/MyLogger.dart';
import 'package:timemanagerapp/widgets/HomeWidget.dart';
import 'package:timemanagerapp/provider/TimeProvider.dart';
@ -9,9 +12,10 @@ init() async {
await Setting.init();
}
void main() async {
Future<void> main() async {
await init();
runApp(MyApp());
// Logger();
}
class MyApp extends StatelessWidget {
@ -19,14 +23,25 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
Setting.deviceWidth = MediaQuery.of(context).size.width;
// print("deviceWidth获取1: ${Setting.deviceWidth}");
return MultiProvider( //Timetable
providers: [
ChangeNotifierProvider(create: (ctx) => TimeProvider()),
ChangeNotifierProvider(create: (ctx) => TeamProvider()),
ChangeNotifierProvider(create: (ctx) => TeamUserProvider()),
],
child: MaterialApp(
home: Scaffold(
body: HomeWidget(),
body: LayoutBuilder(
builder: (context, constraints) {
Setting.deviceWidth = constraints.maxWidth;
// print("deviceWidth获取2: ${Setting.deviceWidth}");
// 使
return HomeWidget();
},
),
),
),
); // MaterialApp

@ -0,0 +1,20 @@
import 'package:flutter/cupertino.dart';
class TeamProvider extends ChangeNotifier {
int _updatTeamCount = 0;
int get updatTeamCount => _updatTeamCount;
set updatTeamCount(int value) {
print("provider手动更新Team表");
_updatTeamCount = value;
notifyListeners();
}
void updatTeame() {
print("provider手动更新Team表");
_updatTeamCount = ~_updatTeamCount;
notifyListeners();
}
}

@ -0,0 +1,20 @@
import 'package:flutter/cupertino.dart';
class TeamUserProvider extends ChangeNotifier {
int _updatTeamUserCount = 0;
int get updatTeameCount => _updatTeamUserCount;
set updatTeameUserCount(int value) {
print("provider手动更新TeamUser表");
_updatTeamUserCount = value;
notifyListeners();
}
void updatTeameUser() {
print("provider手动更新TeamUser表");
_updatTeamUserCount = ~_updatTeamUserCount;
notifyListeners();
}
}

@ -2,23 +2,21 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:timemanagerapp/widgets/AddCourseFormWidget.dart';
import '../entity/Course.dart';
class AddCourseRoute extends StatelessWidget {
final VoidCallback onCourseAdded;
final Course? exitCourse;
AddCourseRoute({required this.onCourseAdded});
AddCourseRoute({this.exitCourse});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('添加自定义课程'),
title: Text('编辑自定义课程'),
),
body: AddCourseFormWidget(),
body: AddCourseFormWidget(exitCourse: exitCourse),
);
}
@override
dispose() {//
onCourseAdded();
}
}

@ -3,18 +3,19 @@ import 'package:flutter/material.dart';
import 'package:timemanagerapp/widgets/AddScheduleFormWidget.dart';
class AddScheduleRoute extends StatelessWidget {
const AddScheduleRoute({Key? key,required this.scheduleType,this.teamId}) : super(key: key);
AddScheduleRoute({Key? key, required this.scheduleType, this.teamId, this.exitSchedule}) : super(key: key);
final String scheduleType;//taskwork
final int? teamId ;
final String scheduleType; //taskwork
final int? teamId;
final exitSchedule;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('添加自定义个人计划'),
title: scheduleType == 'task' ? Text('编辑个人计划') : Text('编辑团队任务'),
),
body: AddScheduleFormWidget(scheduleType: scheduleType,teamId: teamId),
body: AddScheduleFormWidget(scheduleType: scheduleType, teamId: teamId, exitSchedule: exitSchedule),
);
}
}
}

@ -9,7 +9,7 @@ class AddTeamRoute extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('添加团队'),
title: Text('编辑团队信息'),
),
body: AddTeamWidget(),
);

@ -1,17 +1,17 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../widgets/ManageUserTeamWidget.dart';
class ManageUserTeamRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('团队成员管理'),
),
body: ManageUserTeamWidget(),
);
}
}
// import 'package:flutter/cupertino.dart';
// import 'package:flutter/material.dart';
//
// import '../widgets/ManageUserTeamWidget.dart';
//
// class ManageUserTeamRoute extends StatelessWidget {
//
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// appBar: AppBar(
// title: Text('团队成员管理'),
// ),
// // body: ManageUserTeamWidget(),
// );
// }
// }

@ -1,14 +1,27 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:timemanagerapp/controller/TeamController.dart';
import '../setting/Setting.dart';
import '../widgets/AddTeamWidget.dart';
import '../widgets/TeamWidgt.dart';
import '../widgets/JoinTeamWidget.dart';
import '../widgets/TeamWidget.dart';
class TeamRoute extends StatelessWidget {
//TeamWidgetKey
TeamController teamController = TeamController();
@override
initState() {
Setting.init();
}
@override
Widget build(BuildContext context) {
if(Setting.teamWidgetKey == null) {
Setting.teamWidgetKey =
GlobalKey(); // TeamWidgetKey,initStateStatefulWidget
}
if(Setting.user!.getId == -1){
return Scaffold(
appBar: AppBar(
@ -24,16 +37,55 @@ class TeamRoute extends StatelessWidget {
appBar: AppBar(
title: Text('我的团队'),
),
body: TeamWidget(),
body: TeamWidget(key: Setting.teamWidgetKey!),
floatingActionButton: FloatingActionButton(
//
onPressed: () async {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return AddTeamWidget();
},
),
//
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('选择操作'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: () async {
//
Navigator.of(context).pop(); //
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return JoinTeamWidget();
},
),
);
},
child: Text('加入团队'),
),
ElevatedButton(
onPressed: () async {
//
Navigator.of(context).pop();
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return AddTeamWidget();
},
),
);
Setting.teamWidgetKey!.currentState!.futureDo();
},
child: Text('创建团队'),
),
SizedBox(height: 10),
],
),
);
},
);
},
child: Icon(Icons.add),

@ -2,12 +2,17 @@ import 'package:flutter/material.dart';
import 'package:timemanagerapp/widgets/TomatoClockWidget.dart';
class TomatoClockRoute extends StatelessWidget {
final int flag;
final double selectedDuration;
const TomatoClockRoute({super.key, required this.flag,required this.selectedDuration});
@override
Widget build(BuildContext context) {
return Scaffold(
body: TomatoClockWidget()
body: TomatoClockWidget(flag:flag,selectedDuration:selectedDuration)
);
}
}

@ -1,17 +1,17 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:timemanagerapp/widgets/UserSettingWidget.dart';
import '../tests/TestWidget.dart';
class UserSettingRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('设置'),
),
body: UserSettingWidgt(),
);
}
}
// import 'package:flutter/cupertino.dart';
// import 'package:flutter/material.dart';
// import 'package:timemanagerapp/widgets/UserSettingWidget.dart';
//
// import '../tests/TestWidget.dart';
//
// class UserSettingRoute extends StatelessWidget {
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// appBar: AppBar(
// title: Text('设置'),
// ),
// body: UserSettingWidget(),
// );
// }
// }

@ -1,25 +1,43 @@
import 'dart:ffi';
import 'dart:core';
import 'package:flutter/cupertino.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../entity/User.dart';
import '../widgets/FreeTimetableWidget.dart';
import '../widgets/TeamWidget.dart';
import '../widgets/TimetableWidget.dart';
class Setting {
static SharedPreferences? prefs;
static bool initFlag = true;
static DateTime startdate_init = DateTime(2023, 8, 28);
static late DateTime startdate;
static late User? user;
static int termAllWeekCout = 20; //
static DateTime timeTableStartTime = DateTime(2023, 8, 28, 7, 00); //
static DateTime timeTableEndTime = DateTime(2023, 8, 28, 23, 00); //
static late User? user = User(id:-1, username: "null", password: "null", role: 0);
static User nullUser = User(id:-1, username: "null", password: "null", role: 0);
static double pixelToMinuteRatio_ratio = 1;
static late double deviceWidth ;
static double pixelToMinuteRatio_ratio = 300; //
static late double deviceWidth = 400; //
static bool isMusicPlaying = false; //
static bool isDeveloperButtonVisible = false; //
static GlobalKey<TimetableWidgetState>? timetableWidgetKey;
static GlobalKey<TeamWidgetState>? teamWidgetKey;
static GlobalKey<FreeTimetableWidgetState>? freeTimetableWidgeKey;
static late User testUer;
static init() async {
//
print("Setting初始化");
// prefs!.setString("startdate", startdate.toString());
prefs = await SharedPreferences.getInstance();
saveStartDate(startdate_init); //
startdate = getStartDate();
user = getUser();
getStartDate();
getUser();
getIsDeveloperButtonVisible();
getpixelToMinuteRatio_ratio();
getInitFlag();
print("Setting初始化成功");
}
@ -31,13 +49,15 @@ class Setting {
saveStartDate(startdate_init);
return startdate_init;
} else {
return DateTime.parse(res);
startdate = DateTime.parse(res);
return startdate;
}
}
static saveStartDate(DateTime startdate) {
static saveStartDate(DateTime startdate) async {
//
prefs?.setString("startdate", startdate.toString());
Setting.startdate = startdate;
await prefs?.setString("startdate", startdate.toString());
}
static User? getUser() {
@ -53,9 +73,68 @@ class Setting {
}
}
static saveUser(User newuser) {
static saveUser(User newuser) async {
//
user = newuser;
prefs?.setString("user", newuser.toString());
await prefs?.setString("user", newuser.toString());
}
//pixelToMinuteRatio_ratio
static double getpixelToMinuteRatio_ratio() {
//
double? res;
if(prefs!.containsKey("pixelToMinuteRatio_ratio")) res = prefs!.getDouble("pixelToMinuteRatio_ratio")!;
if (res == null) {
pixelToMinuteRatio_ratio = 1;
return 1;
} else {
pixelToMinuteRatio_ratio = res!;
return pixelToMinuteRatio_ratio;
}
}
static savepixelToMinuteRatio_ratio(double value) async {
//
pixelToMinuteRatio_ratio = value;
await prefs?.setDouble("pixelToMinuteRatio_ratio", value);
}
static bool getIsDeveloperButtonVisible() {
//
bool? res;
if(prefs!.containsKey("isDeveloperButtonVisible")) res = prefs!.getBool("isDeveloperButtonVisible")!;
if (res == null) {
isDeveloperButtonVisible = false;
return false;
} else {
isDeveloperButtonVisible = res!;
return isDeveloperButtonVisible;
}
}
static saveIsDeveloperButtonVisible(bool value) async {
//
isDeveloperButtonVisible = value;
await prefs?.setBool("isDeveloperButtonVisible", value);
}
static getInitFlag() {
bool? getInitFlag = prefs!.getBool("initFlag");
if (getInitFlag == null) {
initFlag = true;
return true;
} else {
initFlag = getInitFlag;
return initFlag;
}
}
static saveInitFlag(bool value) async {
initFlag = value;
await prefs?.setBool("initFlag", value);
}
}

@ -1,38 +1,38 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:timemanagerapp/setting/Setting.dart';
import 'package:timemanagerapp/util/GetCourseByLogin.dart';
import 'package:timemanagerapp/widgets/AddCourseFormWidget.dart';
import 'package:timemanagerapp/widgets/LoginWidget.dart';
import 'package:timemanagerapp/widgets/TimetableWidget.dart';
init() async {
WidgetsFlutterBinding.ensureInitialized();
await Setting.init();
}
void main() async {
await init();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('课表'),
),
body: TimetableWidget(),
),
);
}
}
// import 'dart:developer';
//
// import 'package:flutter/material.dart';
// import 'package:shared_preferences/shared_preferences.dart';
// import 'package:timemanagerapp/setting/Setting.dart';
// import 'package:timemanagerapp/util/GetCourseByLogin.dart';
// import 'package:timemanagerapp/widgets/AddCourseFormWidget.dart';
// import 'package:timemanagerapp/widgets/LoginWidget.dart';
// import 'package:timemanagerapp/widgets/TimetableWidget.dart';
//
//
// init() async {
// WidgetsFlutterBinding.ensureInitialized();
// await Setting.init();
// }
//
// void main() async {
// await init();
// runApp(MyApp());
//
//
// }
//
// class MyApp extends StatelessWidget {
//
//
// @override
// Widget build(BuildContext context) {
// return MaterialApp(
// home: Scaffold(
// appBar: AppBar(
// title: Text('课表'),
// ),
// body: TimetableWidget(),
// ),
// );
// }
// }

@ -6,9 +6,9 @@ import 'package:timemanagerapp/setting/Setting.dart';
import 'package:timemanagerapp/util/dataUtil.dart';
class GetCourseByLogin {
String id = "210340156"; //
String passwd = "123111@qaq"; //
String year = "2022"; //
String id = ""; //
String passwd = ""; //
String year = "2023"; //
String term = "1"; //
DateTime termstartdate = Setting.startdate;
List<Course> courses = []; //
@ -94,7 +94,7 @@ class GetCourseByLogin {
final courseTitle = courseData['title'];
//
final timeRegex = RegExp(r'星期([一二三四五六日])第(\d)-(\d)节\{([^{}]+)\}');
final timeRegex = RegExp(r'星期([一二三四五六日])第(\d+)-(\d+)节\{([^{}]+)\}'); //Bug:/d+
final match = timeRegex.firstMatch(courseTime);
final Iterable<Match> allMatches = timeRegex.allMatches(courseTime); //Bug:
for(var match in allMatches){
@ -150,7 +150,7 @@ class GetCourseByLogin {
credit: courseData['credit'],
teacher: courseData['teacher'],
location: courseData['place'],
remark: "schoolclass",
remark: "学校导入课程",
startTime: startdate,
endTime: endDate,
);

@ -0,0 +1,132 @@
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'dart:convert';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:logger/src/logger.dart';
import 'package:logger/src/log_output.dart';
import 'dart:io' as io;
class MyLogger extends StatefulWidget {
@override
_MyLoggerState createState() => _MyLoggerState();
}
class _MyLoggerState extends State<MyLogger> {
late File file;
late Logger logger;
@override
void initState() {
getDirectoryForLogRecord().whenComplete(
() {
FileOutput fileOutPut = FileOutput(file: file);
ConsoleOutput consoleOutput = ConsoleOutput();
List<LogOutput> multiOutput = [fileOutPut, consoleOutput];
logger = Logger(
filter: DevelopmentFilter(),
// Use the default LogFilter (-> only log in debug mode)
printer: PrettyPrinter(
methodCount: 2,
// number of method calls to be displayed
errorMethodCount: 8,
// number of method calls if stacktrace is provided
lineLength: 120,
// width of the output
colors: false,
// Colorful log messages
printEmojis: true,
// Print an emoji for each log message
printTime: true // Should each log print contain a timestamp
),
// Use the PrettyPrinter to format and print log
output:
MultiOutput(multiOutput) // Use the default LogOutput (-> send everything to console)
);
},
);
// TODO: implement initState
super.initState();
}
Future<void> getDirectoryForLogRecord() async {
final Directory directory = await getApplicationDocumentsDirectory();
file = File('${directory.path}/withMultiOutput.txt');
}
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
print("you pressed it");
// logger.v("Verbose log");
//
// logger.d("Debug log");
//
// logger.i("Info log");
//
// logger.w("Warning log");
//
// logger.e("Error log");
//
// logger.wtf("What a terrible failure log");
showDialog(
context: context,
builder: (context) {
String content = file.readAsStringSync();
return AlertDialog(
title: Text('结果'),
content: SingleChildScrollView(
child: Text(content)),
);
},
);
},
// height: 60,
// minWidth: 120,
// color: Colors.blue,
child: Text(
'TEST WITH BOTH',
style: TextStyle(color: Colors.white),
),
);
}
}
/// Writes the log output to a file.
class FileOutput extends LogOutput {
late File file;
final bool overrideExisting;
final Encoding encoding;
IOSink ? _sink;
// IOSink? _sink;
FileOutput({
required this.file,
this.overrideExisting = false,
this.encoding = utf8,
});
@override
void init() {
_sink = file.openWrite(
mode: overrideExisting ? FileMode.writeOnly : FileMode.writeOnlyAppend,
encoding: encoding,
);
}
@override
void output(OutputEvent event) {
_sink?.writeAll(event.lines, '\n');
print('log-------'+event.lines.toString()+'\n');
}
@override
void destroy() async {
await _sink?.flush();
await _sink?.close();
}
}

@ -17,6 +17,8 @@ class IdGenerator {
late int sequence = 0;
late int lastTimestamp = -1;
static int lastId = 0;//id
IdGenerator() {
//workerId = Random().nextInt(pow(2, WORKER_ID_BITS)) % 4096;
var wordidrang = pow(2, WORKER_ID_BITS).toInt();
@ -55,7 +57,13 @@ class IdGenerator {
(workerId << SEQUENCE_BITS) |
sequence;
return id;
//id
if(id == lastId){
return await generateId();
}else{
lastId = id;
return id;
}
}
int tilNextMillis(int lastTimestamp) {

@ -3,26 +3,40 @@ import 'package:multi_select_flutter/dialog/multi_select_dialog_field.dart';
import 'package:multi_select_flutter/util/multi_select_item.dart';
import 'package:provider/provider.dart';
import 'package:timemanagerapp/controller/CourseController.dart';
import 'package:timemanagerapp/entity/Course.dart';
import 'package:timemanagerapp/entity/CourseForm.dart';
import '../controller/TimetableWidgetController.dart';
import '../provider/TimeProvider.dart';
class AddCourseFormWidget extends StatefulWidget {
const AddCourseFormWidget({Key? key}) : super(key: key);
const AddCourseFormWidget({Key? key,this.exitCourse}) : super(key: key);
final Course? exitCourse;
@override
_AddCourseFormWidgetState createState() => _AddCourseFormWidgetState();
_AddCourseFormWidgetState createState() => _AddCourseFormWidgetState(exitCourse: exitCourse);
}
class _AddCourseFormWidgetState extends State<AddCourseFormWidget> {
_AddCourseFormWidgetState({this.exitCourse});
late TextEditingController _courseController;
late TextEditingController _creditController;
late TextEditingController _noteController;
late TextEditingController _startWeekController;
late TextEditingController _endWeekController;
late TextEditingController _startTimeController;
late TextEditingController _endTimeController;
late TextEditingController _teacherController;
late TextEditingController _locationController;
CourseController courseController = CourseController();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
CourseForm courseForm = CourseForm();
Course? exitCourse;
String course = '';
String credit = '';
String note = '';
String startWeek = '1';
String endWeek = '12';
String startWeek = '';
String endWeek = '';
String startTime = '1';
String endTime = '2';
String teacher = '';
@ -50,6 +64,30 @@ class _AddCourseFormWidgetState extends State<AddCourseFormWidget> {
'周日': 7,
};
@override
void initState() {
super.initState();
if(exitCourse != null){
course = exitCourse!.getName;
credit = exitCourse!.getCredit.toString();
note = exitCourse!.getRemark;
teacher = exitCourse!.getTeacher;
location = exitCourse!.getLocation;
selectedDays = TimetableWidgetController.getSelectDayList(exitCourse!.getStartTime);
startWeek = TimetableWidgetController.getWeekCount(dateTime:exitCourse!.getStartTime).toString();
endWeek = TimetableWidgetController.getWeekCount(dateTime:exitCourse!.getEndTime).toString();
}
_courseController = TextEditingController(text: course);
_creditController = TextEditingController(text: credit);
_noteController = TextEditingController(text: note);
_startWeekController = TextEditingController(text: startWeek);
_endWeekController = TextEditingController(text: endWeek);
_startTimeController = TextEditingController(text: startTime);
_endTimeController = TextEditingController(text: endTime);
_teacherController = TextEditingController(text: teacher);
_locationController = TextEditingController(text: location);
}
@override
Widget build(BuildContext context) {
@ -62,6 +100,7 @@ class _AddCourseFormWidgetState extends State<AddCourseFormWidget> {
crossAxisAlignment: CrossAxisAlignment.stretch, //
children: <Widget>[
TextFormField( //
controller: _courseController,
decoration: InputDecoration(labelText: '课程*'), //
onSaved: (value) => course = value ?? '', //
validator: (value) { //
@ -73,17 +112,20 @@ class _AddCourseFormWidgetState extends State<AddCourseFormWidget> {
),
SizedBox(height: 16.0),//
TextFormField(
controller: _creditController,
decoration: InputDecoration(labelText: '学分'),
onSaved: (value) => credit = value ?? '',
),
SizedBox(height: 16.0),
TextFormField(
controller: _noteController,
decoration: InputDecoration(labelText: '备注'),
onSaved: (value) => note = value ?? '',
),
SizedBox(height: 16.0),
MultiSelectDialogField<String>(
items: daysList,
initialValue: selectedDays, //
title: Text('上课日*'),
validator: (values) {
if (values == null || values.isEmpty) {
@ -99,6 +141,7 @@ class _AddCourseFormWidgetState extends State<AddCourseFormWidget> {
),
SizedBox(height: 16.0),
TextFormField(
controller: _startWeekController,
decoration: InputDecoration(labelText: '开始周'),
onSaved: (value) => startWeek = value ?? '',
validator: (value) {
@ -110,6 +153,7 @@ class _AddCourseFormWidgetState extends State<AddCourseFormWidget> {
),
SizedBox(height: 16.0),
TextFormField(
controller: _endWeekController,
decoration: InputDecoration(labelText: '结束周'),
onSaved: (value) => endWeek = value ?? '',
validator: (value) {
@ -121,6 +165,7 @@ class _AddCourseFormWidgetState extends State<AddCourseFormWidget> {
),
SizedBox(height: 16.0),
DropdownButtonFormField<String>(
// controller: _startTimeController,
value: startTime,
onChanged: (newValue) {
setState(() {
@ -165,11 +210,13 @@ class _AddCourseFormWidgetState extends State<AddCourseFormWidget> {
),
SizedBox(height: 16.0),
TextFormField(
controller: _teacherController,
decoration: InputDecoration(labelText: '老师'),
onSaved: (value) => teacher = value ?? '',
),
SizedBox(height: 16.0),
TextFormField(
controller: _locationController,
decoration: InputDecoration(labelText: '地点'),
onSaved: (value) => location = value ?? '',
),
@ -184,18 +231,14 @@ class _AddCourseFormWidgetState extends State<AddCourseFormWidget> {
},
child: Text('取消'),
),
Selector<TimeProvider, TimeProvider>( // time
selector: (ctx, provider) => provider,
shouldRebuild: (pre, next) => false,
builder: (ctx, timePro, child) {
return ElevatedButton(
ElevatedButton(
onPressed: () {
//
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
//
courseForm.course = course;
courseForm.credit = double.parse(credit);
courseForm.credit = double.parse(credit==''?'-1':credit);
courseForm.note = note;
courseForm.location = location;
courseForm.selectedDays = selectedDays.map((e) => weekdayMap[e]!).toList();
@ -204,20 +247,28 @@ class _AddCourseFormWidgetState extends State<AddCourseFormWidget> {
courseForm.startTime = int.parse(startTime);
courseForm.endTime = int.parse(endTime);
courseForm.teacher = teacher;
courseController.addCourseForm(courseForm).then(((value){
//
timePro.updateTimetable();
// timePro.updatTimtTablecount = 100;
Navigator.pop(context);
if(exitCourse != null){//
courseController.deleteCourse(exitCourse!.getCourseId).then((value){
courseController.addCourseForm(courseForm).then(((value){
//
// Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
// timePro.updatTimtTablecount = 100;
Navigator.pop(context);
}));
}));
});
}else{
courseController.addCourseForm(courseForm).then(((value){
//
// Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
// timePro.updatTimtTablecount = 100;
Navigator.pop(context);
}));
}
};
},
child: Text('确定'),
);
},
// child: Icon(Icons.add),
),
),
],
),
],

@ -3,29 +3,39 @@ import 'package:multi_select_flutter/dialog/multi_select_dialog_field.dart';
import 'package:multi_select_flutter/util/multi_select_item.dart';
import 'package:provider/provider.dart';
import 'package:timemanagerapp/controller/TaskController.dart';
import 'package:timemanagerapp/controller/TeamController.dart';
import 'package:timemanagerapp/controller/WorkController.dart';
import 'package:timemanagerapp/entity/ScheduleForm.dart';
import 'package:timemanagerapp/entity/Task.dart';
import '../controller/TimetableWidgetController.dart';
import '../provider/TimeProvider.dart';
class AddScheduleFormWidget extends StatefulWidget {
const AddScheduleFormWidget({Key? key,required this.scheduleType,this.teamId}) : super(key: key);
AddScheduleFormWidget({Key? key,required this.scheduleType,this.teamId,this.exitSchedule}) : super(key: key);
final String scheduleType;//taskwork
final int? teamId ;
var exitSchedule;
@override
_AddScheduleFormWidgetState createState() => _AddScheduleFormWidgetState(scheduleType:scheduleType ,teamId:teamId);
_AddScheduleFormWidgetState createState() => _AddScheduleFormWidgetState(scheduleType:scheduleType ,teamId:teamId,exitSchedule:exitSchedule);
}
class _AddScheduleFormWidgetState extends State<AddScheduleFormWidget> {
_AddScheduleFormWidgetState({required this.scheduleType,this.teamId});
_AddScheduleFormWidgetState({required this.scheduleType,this.teamId,this.exitSchedule});
late TextEditingController _nameController;
late TextEditingController _contenController;
late TextEditingController _startWeekController;
late TextEditingController _endWeekController;
final String scheduleType;//taskwork
final int? teamId ;
var exitSchedule;
TaskController taskController = TaskController();
WorkController workController = WorkController();
// WorkController workController = WorkController();
TeamController teamController = TeamController();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
ScheduleForm scheduleForm = ScheduleForm();
@ -39,7 +49,7 @@ class _AddScheduleFormWidgetState extends State<AddScheduleFormWidget> {
List<String> selectedDays = [];
List<MultiSelectItem<String>> daysList = [
static List<MultiSelectItem<String>> daysList = [
MultiSelectItem('周一', ''),
MultiSelectItem('周二', ''),
MultiSelectItem('周三', ''),
@ -59,9 +69,29 @@ class _AddScheduleFormWidgetState extends State<AddScheduleFormWidget> {
'周日': 7,
};
@override
void initState() {
super.initState();
if(exitSchedule != null){
name = exitSchedule.getName;
content = exitSchedule.getContent;
startTime = exitSchedule.getStartTime;
endTime = exitSchedule.getEndTime;
selectedDays = TimetableWidgetController.getSelectDayList(exitSchedule!.getStartTime);
startWeek = TimetableWidgetController.getWeekCount(dateTime:exitSchedule!.getStartTime).toString();
endWeek = TimetableWidgetController.getWeekCount(dateTime:exitSchedule!.getEndTime).toString();
}
_nameController = TextEditingController(text: name);
_contenController = TextEditingController(text: content);
_startWeekController = TextEditingController(text: startWeek);
_endWeekController = TextEditingController(text: endWeek);
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Padding( //
padding: const EdgeInsets.all(16.0), // 16
@ -71,6 +101,7 @@ class _AddScheduleFormWidgetState extends State<AddScheduleFormWidget> {
crossAxisAlignment: CrossAxisAlignment.stretch, //
children: <Widget>[
TextFormField( //
controller: _nameController,
decoration: InputDecoration(labelText: '计划名称*'), //
onSaved: (value) => name = value ?? '', //
validator: (value) { //
@ -82,12 +113,14 @@ class _AddScheduleFormWidgetState extends State<AddScheduleFormWidget> {
),
SizedBox(height: 16.0),
TextFormField(
controller: _contenController,
decoration: InputDecoration(labelText: '内容'),
onSaved: (value) => content = value ?? '',
),
SizedBox(height: 16.0),
MultiSelectDialogField<String>(
items: daysList,
initialValue: selectedDays, //
title: Text('星期几*'),
validator: (values) {
if (values == null || values.isEmpty) {
@ -103,6 +136,7 @@ class _AddScheduleFormWidgetState extends State<AddScheduleFormWidget> {
),
SizedBox(height: 16.0),
TextFormField(
controller: _startWeekController,
decoration: InputDecoration(labelText: '开始周'),
onSaved: (value) => startWeek = value ?? '',
validator: (value) {
@ -114,6 +148,7 @@ class _AddScheduleFormWidgetState extends State<AddScheduleFormWidget> {
),
SizedBox(height: 16.0),
TextFormField(
controller: _endWeekController,
decoration: InputDecoration(labelText: '结束周'),
onSaved: (value) => endWeek = value ?? '',
validator: (value) {
@ -130,7 +165,7 @@ class _AddScheduleFormWidgetState extends State<AddScheduleFormWidget> {
),
controller: TextEditingController(
text: startTime != null
? '${startTime!.hour}:${startTime!.minute}'
? '${startTime!.hour.toString().padLeft(2, '0')}:${startTime!.minute.toString().padLeft(2, '0')}'
: '',
),
readOnly: true,
@ -159,7 +194,7 @@ class _AddScheduleFormWidgetState extends State<AddScheduleFormWidget> {
),
controller: TextEditingController(
text: endTime != null
? '${endTime!.hour}:${endTime!.minute}'
? '${endTime!.hour.toString().padLeft(2, '0')}:${endTime!.minute.toString().padLeft(2, '0')}'
: '',
),
readOnly: true,
@ -192,45 +227,97 @@ class _AddScheduleFormWidgetState extends State<AddScheduleFormWidget> {
},
child: Text('取消'),
),
Selector<TimeProvider, TimeProvider>( // time
selector: (ctx, provider) => provider,
shouldRebuild: (pre, next) => false,
builder: (ctx, timePro, child) {
return ElevatedButton(
ElevatedButton(
onPressed: () {
//
if (_formKey.currentState!.validate()) {
if (_formKey.currentState!.validate()&&startTime!=endTime!&&startTime.isBefore(endTime!)) {
_formKey.currentState!.save();
//
scheduleForm.name = name;
scheduleForm.content = content;
scheduleForm.content = content ;
scheduleForm.selectedDays = selectedDays.map((e) => weekdayMap[e]!).toList();
scheduleForm.startWeek = int.parse(startWeek);
scheduleForm.endWeek = int.parse(endWeek);
scheduleForm.startTime = startTime;
scheduleForm.endTime = endTime;
if(scheduleType == "task") {
taskController.addScheduleForm(scheduleForm).then(((value){
//
timePro.updateTimetable();
// timePro.updatTimtTablecount++;
Navigator.pop(context);
}));
if(exitSchedule != null){//
taskController.deleteTaskByTaskid(exitSchedule!.getTaskId).then((value){
taskController.addScheduleForm(scheduleForm).then(((value){
// Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
//
// Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
// timePro.updatTimtTablecount++;
Navigator.pop(context);
}));
});
}else{
taskController.addScheduleForm(scheduleForm).then(((value){
// Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
//
// Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
// timePro.updatTimtTablecount++;
Navigator.pop(context);
}));
}
}else{
workController.addScheduleForm(scheduleForm,teamId!).then(((value){
//
timePro.updateTimetable();
// timePro.updatTimtTablecount++;
Navigator.pop(context);
}));
if(exitSchedule != null){//
teamController.deleteWorkByWorkId(exitSchedule!.getWorkId).then((value){
teamController.addScheduleForm(scheduleForm,teamId!).then(((value){
// Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
//
// Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
// timePro.updatTimtTablecount++;
Navigator.pop(context);
}));
});
}else{
teamController.addScheduleForm(scheduleForm,teamId!).then(((value){
// Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
//
// timePro.updatTimtTablecount++;
Navigator.pop(context);
}));
}
}
}else{
if(startTime==endTime){
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('时间错误'),
content: Text('开始时间和结束时间不能相同'),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('确定'),
),
],
);
},
);
}else if(startTime!.isAfter(endTime!)){
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('时间错误'),
content: Text('开始时间不能晚于结束时间'),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('确定'),
),
],
);
},
);
}
}
},
child: Text('确定'),
);
}
),
),
],
),
],

@ -1,6 +1,19 @@
import 'package:flutter/material.dart';
import 'package:timemanagerapp/controller/TeamController.dart';
import 'package:timemanagerapp/entity/Team.dart';
import '../setting/Setting.dart';
class AddTeamWidget extends StatefulWidget {
const AddTeamWidget({Key? key}) : super(key: key);
@override
_AddTeamWidgetState createState() => _AddTeamWidgetState();
}
class _AddTeamWidgetState extends State<AddTeamWidget> {
TeamController teamController = TeamController();
class AddTeamWidget extends StatelessWidget {
TextEditingController teamNameController = TextEditingController();
TextEditingController teamDescriptionController = TextEditingController();
@ -32,7 +45,14 @@ class AddTeamWidget extends StatelessWidget {
onPressed: () {
String teamName = teamNameController.text;
String teamDescription = teamDescriptionController.text;
teamController.insertTeam(Team(leaderId: Setting.user!.getId!, teamName: teamName,introduce: teamDescription, maxNumber: 1000));
//
//todo
// setState(() {
// teamNameController.text = teamName;
// teamDescriptionController.text = teamDescription;
// });
Navigator.pop(context);
},
child: Text('确定'),

@ -4,6 +4,7 @@ import 'package:timemanagerapp/controller/courseController.dart';
import '../entity/course.dart';
import '../provider/TimeProvider.dart';
import '../setting/Setting.dart';
class AutoImportWidget extends StatefulWidget {
@override
@ -11,77 +12,138 @@ class AutoImportWidget extends StatefulWidget {
}
class _AutoImportWidgetState extends State<AutoImportWidget> {
final CourseController courseController = CourseController.getInstance();
final TextEditingController stuIdController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
final TextEditingController yearController = TextEditingController();
final TextEditingController termController = TextEditingController();
late CourseController courseController = CourseController.getInstance();
late TextEditingController stuIdController = TextEditingController();
late TextEditingController passwordController = TextEditingController();
late TextEditingController yearController = TextEditingController();
late TextEditingController termController = TextEditingController();
bool loading = false;
Future<void> handleAutoImport(context) async {
Future<void> handleAutoImport(BuildContext context) async {
int stuId = int.parse(stuIdController.text);
String password = passwordController.text;
int year = int.parse(yearController.text);
int term = int.parse(termController.text);
int res = await courseController.autoImportCours(stuId, password,year,term);
if(res!=0) {
Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
Navigator.pop(context);
setState(() {
loading = true;
});
courseController.autoImportCours(stuId, password, year, term).then((res){
setState(() {
loading = false;
});
if (res != 0) {
// Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
// Setting.timetableWidgetKey!.currentState!.localFutureDo();
Navigator.pop(context);
} else {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('结果'),
content: Text('用户名或密码错误'),
actions: [
TextButton(
child: Text('确定'),
onPressed: () {
Navigator.of(context).pop(); //
},
),
],
);
},
);
}
});
}
@override
void initState() {
super.initState();
yearController = TextEditingController(text:DateTime.now().year.toString());
if(DateTime.now().month<8) {
termController = TextEditingController(text: '2D:\Myprogramfile\Flutter\TimeManager\src\timemanagerapp\build\app\outputs\flutter-apk');
}else{
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('用户名或密码错误'))
);
termController = TextEditingController(text: '1');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('自动导入校园账号课程'),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
controller: stuIdController,
decoration: InputDecoration(
labelText: '账号',
if(loading){
return Scaffold(
appBar: AppBar(
title: Text('自动导入校园账号课程'),
),
body: Center(
child:CircularProgressIndicator(),
),
);
}else
if (Setting.user!.getId! == -1) {
return Scaffold(
appBar: AppBar(
title: Text('自动导入校园账号课程'),
),
body: Center(
child: Text('请先登录'),
),
);
} else {
return Scaffold(
appBar: AppBar(
title: Text('自动导入校园账号课程'),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
controller: stuIdController,
decoration: InputDecoration(
labelText: '账号',
),
),
SizedBox(height: 16.0),
TextFormField(
controller: passwordController,
obscureText: true, //
decoration: InputDecoration(
labelText: '密码',
),
),
),
SizedBox(height: 16.0),
TextFormField(
controller: passwordController,
obscureText: true, //
decoration: InputDecoration(
labelText: '密码',
SizedBox(height: 16.0),
TextFormField(
controller: yearController,
decoration: InputDecoration(
labelText: '学年',
),
),
),
SizedBox(height: 16.0),
TextFormField(
controller: yearController,
decoration: InputDecoration(
labelText: '学年',
SizedBox(height: 16.0),
TextFormField(
controller: termController,
decoration: InputDecoration(
labelText: '学期',
),
),
),
SizedBox(height: 16.0),
TextFormField(
controller: termController,
decoration: InputDecoration(
labelText: '学期',
SizedBox(height: 24.0),
ElevatedButton(
onPressed: () => handleAutoImport(context), // context
child: Text('导入'),
),
),
SizedBox(height: 24.0),
ElevatedButton(
onPressed: () => handleAutoImport(context), // context
child: Text('导入'),
),
],
],
),
),
),
),
);
);
}
}
}

@ -0,0 +1,135 @@
import 'package:flutter/material.dart';
import 'package:timemanagerapp/controller/UserController.dart';
import 'package:timemanagerapp/setting/Setting.dart';
import '../entity/User.dart';
class ChangeUserWidget extends StatefulWidget {
@override
_ChangeUserWidgetState createState() => _ChangeUserWidgetState();
}
class _ChangeUserWidgetState extends State<ChangeUserWidget> {
UserController userController = UserController.getInstance();
final TextEditingController usernameController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
final TextEditingController confirmPasswordController = TextEditingController();
Future<void> handleRegister(context) async {
String username = usernameController.text;
String password = passwordController.text;
String confirmPassword = confirmPasswordController.text;
//
if (password == '' || confirmPassword == '') {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('结果'),
content: Text('密码不能为空'),
actions: [
TextButton(
child: Text('确定'),
onPressed: () {
Navigator.of(context).pop(); //
},
),
],
);
},
);
return;
}else if (password != confirmPassword) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('结果'),
content: Text('两次输入的密码不一致'),
actions: [
TextButton(
child: Text('确定'),
onPressed: () {
Navigator.of(context).pop(); //
},
),
],
);
},
);
return;
}else{
bool res = await userController.updateUser(User(id:Setting.user!.getId!,username:username, password:password, role:0));
if(res){
Navigator.pop(context);
}else{
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('结果'),
content: Text('修改失败'),
actions: [
TextButton(
child: Text('确定'),
onPressed: () {
Navigator.of(context).pop(); //
},
),
],
);
},
);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('修改帐户'),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
controller: usernameController,
decoration: InputDecoration(
labelText: '用户名',
),
),
SizedBox(height: 16.0),
TextFormField(
controller: passwordController,
obscureText: true,
decoration: InputDecoration(
labelText: '密码',
),
),
SizedBox(height: 16.0),
TextFormField(
controller: confirmPasswordController,
obscureText: true,
decoration: InputDecoration(
labelText: '确认密码',
),
),
SizedBox(height: 24.0),
ElevatedButton(
onPressed:()=> handleRegister(context),
child: Text('提交'),
),
],
),
),
),
);
}
}

@ -0,0 +1,559 @@
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:timemanagerapp/controller/TeamController.dart';
import '../controller/TimetableWidgetController.dart';
import '../entity/FreeTime.dart';
import '../entity/Team.dart';
import '../entity/Work.dart';
import '../provider/TimeProvider.dart';
import '../ruters/AddScheduleRoute.dart';
import '../setting/Setting.dart';
class FreeTimetableWidget extends StatefulWidget {
FreeTimetableWidget({required Key key,required this.team}) : super(key: key);
final Team team;
@override
State<StatefulWidget> createState() =>
FreeTimetableWidgetState(team: team);
}
class FreeTimetableWidgetState extends State<FreeTimetableWidget> {
FreeTimetableWidgetState({required this.team});
int firstInit = 0;
final Team team;
//
late TimetableWidgetController timetableWidgetController =
TimetableWidgetController();
late TeamController teamController = TeamController();
late List freeTimeBlockList = [];
late Map<int,List> freeTimeBlockWeekMap = {};
//
var weekList = ['', '', '', '', '', '', ''];
//
//
var dateListstr = [];
//
var currentWeekDayIndex = 0;
//
int showWeek = 0;
int currentWeek = 0;
String showWeekstr = '第1周';
int showMonth = 0;
final double hourHeight = 60.0 * 1.5;
//DateTimePiexl
//Offset
var positions = [];
bool loading = true;
Future<void> serverFutureDo() async {
print('开始serverFutureDo');
//
freeTimeBlockList = await teamController.getFreeTime(team.getId!);
//
freeTimeBlockList = timetableWidgetController
.repairFreeTimeBlockList(freeTimeBlockList);
dataCaculateAfterFutherDo();
print('serverFutureDo 完成');
setState(() {});
}
//
@override
initState() {
super.initState();
//
freeTimeBlockWeekMap = {};
freeTimeBlockList = [];
//
currentWeek = TimetableWidgetController.getWeekCount();
showWeek = currentWeek;
currentWeekDayIndex = DateTime.now().weekday - 1;
// showWeek = 1;
//
showMonth = DateTime.now().month;
dataCaculateAfterFutherDo();
serverFutureDo();
}
dataCaculateAfterFutherDo() {
freeTimeBlockWeekMap = {};
freeTimeBlockWeekMap =
timetableWidgetController.transformTimeBlockMap(freeTimeBlockList);
var mondayTime = TimetableWidgetController.getmondayTime();
//showMon
showMonth = mondayTime.add(Duration(days: 7 * (showWeek - currentWeek))).month;
//
dateListstr = [];
for (int i = 0; i < 7; i++) {
dateListstr.add(mondayTime
.add(Duration(days: i + 7 * (showWeek - currentWeek)))
.day
.toString()
);
}
//
positions =
TimetableWidgetController.convertTimeList(TimetableWidgetController.timePoints);
}
@override
Widget build(BuildContext contexvoidt) {
return Scaffold(
appBar: AppBar(
title: Text(team.getTeamName+'的空闲时间表'),
),
body: Consumer<TimeProvider>(builder: (ctx, timePro, child) {
print('Rebuild timePro');
return RefreshIndicator(
onRefresh: () {
print('下拉refresh');
return serverFutureDo().then((value){
});
},
child: GestureDetector(
onHorizontalDragEnd: (details) {
serverFutureDo();
if (details.primaryVelocity! > 0) {
//
setState(() {
showWeek--;
currentWeekDayIndex -= 7;
dataCaculateAfterFutherDo();
});
} else if (details.primaryVelocity! < 0) {
//
setState(() {
showWeek++;
currentWeekDayIndex += 7;
dataCaculateAfterFutherDo();
});
}
},
child: Column(
mainAxisAlignment: MainAxisAlignment.start, //
children: [
SizedBox(
//
//
child: GridView.builder(
shrinkWrap: true,
//
physics: NeverScrollableScrollPhysics(),
//
itemCount: 8,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 8, childAspectRatio: 1 / 1),
//
itemBuilder: (BuildContext context, int index) {
//item
return Container(
color: index == this.currentWeekDayIndex
? Color(0xf7f7f7) //
: Colors.white,
child: Center(
child: index == 0
? Column(
//
mainAxisAlignment:
MainAxisAlignment.center,
children: [
if(showWeek>0 && showWeek<Setting.termAllWeekCout)
Container(
// height: 10,
// width: 6,
child: Text(
'' +
showWeek.toString() +
'', //
style: TextStyle(
fontSize: 12,
color: currentWeek ==
showWeek //
? Colors.amber
: Colors.black87)),
),
Container(
// height: 10,
// width: 6,
child: Text(
showMonth.toString() + '', //
style: TextStyle(
fontSize: 12,
color: currentWeek ==
showWeek //
? Colors.amber
: Colors.black87)),
),
],
)
: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text(weekList[index - 1], //
style: TextStyle(
fontSize: 14,
color: index ==
currentWeekDayIndex //
? Colors.lightBlue
: Colors.black87)),
SizedBox(
height: 5,
),
Text(dateListstr[index - 1], //
style: TextStyle(
fontSize: 12,
color: index ==
currentWeekDayIndex //
? Colors.lightBlue
: Colors.black87)),
],
),
),
);
}),
),
//stack
Expanded(
child: SingleChildScrollView(
child: Row(
children: [
//stack
Container(
width: Setting.deviceWidth,
height: 2000,
child: Stack(
alignment: Alignment.center,
children: [
// Stack
Positioned(
top: 0,
left: 0,
child: Container(
width: Setting.deviceWidth,
height: 2000,
child: Stack(
children: List.generate(
//
positions.length,
(index) => Positioned(
top: positions[index].dy,
left: positions[index].dx,
child: Row(
children: [
Text(
TimetableWidgetController.timePoints[index]
.hour
.toString()
.padLeft(2, '0') +
':' +
TimetableWidgetController.timePoints[index]
.minute
.toString()
.padLeft(2, '0'),
),
Container(
width: Setting.deviceWidth * 0.04,
height: 10,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.amber,
width: 2,
),
),
),
Container(
width: Setting.deviceWidth * 0.84,
height: 2,
color: Colors.lightBlue
),
],
),
),
),
),
)),
//Stack
Container(
constraints: BoxConstraints
.expand(), // 使constraints
// width: 390,
// height: 2000,
child: Stack(
children: List.generate(
freeTimeBlockWeekMap
.containsKey(showWeek)
? freeTimeBlockWeekMap[showWeek]!
.length
: 0,
(index) {
var currentItem = freeTimeBlockWeekMap[
showWeek]![index];
return Positioned(
top: timetableWidgetController
.getdy(currentItem),
left: timetableWidgetController
.getdx(currentItem) +
Setting.deviceWidth * 0.15,
child: SingleChildScrollView(
child: Container(
width: Setting.deviceWidth * 0.115,
height:
timetableWidgetController
.getHeight(
currentItem),
decoration: BoxDecoration(
color: getItemColor(
currentItem),
borderRadius:
BorderRadius.all(
Radius.circular(10.0),
),
),
child: SingleChildScrollView(
child: Column(
children: [
FreeTimeBlockContenWidget(
currentItem:
currentItem,
team: team,
),
],
),
),
),
),
);
},
),
))
],
),
),
],
),
))
],
),
),
);
;
}),
);
}
//
Color getItemColor(dynamic item) {
return Colors.tealAccent; //
}
}
class ShowTimeTextWidget extends StatelessWidget{
const ShowTimeTextWidget({
super.key,
required this.currentItem
});
final currentItem;
@override
Widget build(BuildContext context) {
return
ListBody(
children: <Widget>[
Text(
'开始时间: ${currentItem.startTime.year}' +
'${currentItem.startTime.month}' +
'${currentItem.startTime.day.toString().padLeft(2, '0')}' +
'${currentItem.startTime.hour.toString().padLeft(2, '0')}' +
':${currentItem.startTime.minute.toString().padLeft(2, '0')}',
),
Text('结束时间: ${currentItem.endTime.year}' +
'${currentItem.endTime.month}' +
'${currentItem.endTime.day.toString().padLeft(2, '0')}' +
'${currentItem.endTime.hour.toString().padLeft(2, '0')}' +
':${currentItem.endTime.minute.toString().padLeft(2, '0')}',
)
],
);
}
}
class BlockGestureWidget extends StatelessWidget {
const BlockGestureWidget({
super.key,
required this.currentItem,
required this.blockGestureWidgetChilld,
required this.team,
});
final currentItem;
final blockGestureWidgetChilld;
final Team team;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
//
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
// currentItem
title: Text('空闲时间'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
if (currentItem is FreeTime) ...{
ShowTimeTextWidget(currentItem: currentItem),
}
],
),
),
actions: <Widget>[
TextButton(
child: Text('关闭'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
},
onLongPress: () {
//
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('菜单'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: () async {
//
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return AddScheduleRoute(
scheduleType: "work",
teamId: team.id!,
exitSchedule: Work(
startTime: currentItem.startTime,
endTime: currentItem.endTime,
teamId: team.id!,
userId: Setting.user!.id!,
status: '',
content: '',
name: '',
workId: 0,
)
);
},
),
);
Navigator.of(context).pop();
Setting.freeTimetableWidgeKey!.currentState!.serverFutureDo();
},
child: Text('添加团队任务'),
),
SizedBox(height: 10),
],
),
);
},
);
},
child: blockGestureWidgetChilld,
);
}
}
class FreeTimeBlockContenWidget extends StatelessWidget {
const FreeTimeBlockContenWidget({
super.key,
required this.currentItem, required this.team,
});
final currentItem;
final Team team;
@override
Widget build(BuildContext context) {
return BlockGestureWidget(
currentItem: currentItem,
blockGestureWidgetChilld: Column(
children: [
Text(
(currentItem as FreeTime).startTime.hour.toString().padLeft(2, '0') +
':' +
(currentItem as FreeTime).startTime.minute.toString().padLeft(2, '0'),
style: TextStyle(
fontSize: 12,
color: Colors.black,
//
fontWeight: FontWeight.bold,
),
overflow: TextOverflow.clip,
),
Text(
(currentItem as FreeTime).endTime.hour.toString().padLeft(2, '0') +
':' +
(currentItem as FreeTime).endTime.minute.toString().padLeft(2, '0'),
style: TextStyle(
fontSize: 12,
color: Colors.black,
//
fontWeight: FontWeight.bold,
),
overflow: TextOverflow.clip,
),
],
),
team: team,
);
}
}

@ -1,18 +1,24 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:timemanagerapp/controller/CourseController.dart';
import 'package:timemanagerapp/controller/UserController.dart';
import 'package:timemanagerapp/database/MyDatebase.dart';
import 'package:timemanagerapp/ruters/AddScheduleRoute.dart';
import 'package:timemanagerapp/ruters/TeamRoute.dart';
import 'package:timemanagerapp/ruters/TestRoute.dart';
import 'package:timemanagerapp/ruters/TomatoClockRoute.dart';
import 'package:timemanagerapp/widgets/AutoImportWidget.dart';
import 'package:timemanagerapp/widgets/ChangeUserWidget.dart';
import 'package:timemanagerapp/widgets/RegisterWidget.dart';
import 'package:timemanagerapp/widgets/TimetableWidget.dart';
import '../provider/TimeProvider.dart';
import '../ruters/AddCourseRoute.dart';
import '../ruters/TomatoClockRoute.dart';
import '../ruters/UserSettingRoute.dart';
import '../setting/Setting.dart';
import 'LoginWidget.dart';
import 'UserSettingWidget.dart';
class HomeWidget extends StatefulWidget {
const HomeWidget({Key? key}) : super(key: key);
@ -22,33 +28,24 @@ class HomeWidget extends StatefulWidget {
}
class _HomeWidgetState extends State<HomeWidget> {
GlobalKey<TimetableWidgetState> timetableWidgetKey = GlobalKey(); //key
late UserController userController;
late CourseController courseController;
bool isLoggedIn = false; //
late Timer? _timer = null;
double selectedDuration=0;
String durationString='0.0';
@override
void initState() {
super.initState();
userController = UserController.getInstance();
courseController = CourseController.getInstance();
}
Setting.timetableWidgetKey = GlobalKey(); //key,,TimetableWidgetState;
void handleAddCourse() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return AddCourseRoute(onCourseAdded: () {
setState(() {
//
// timetableWidgetKey.currentState?.updateWhenDataChange();
});
});
},
),
);
userController = UserController();
courseController = CourseController.getInstance();
}
void handleAddTask() {
@ -69,6 +66,7 @@ class _HomeWidgetState extends State<HomeWidget> {
appBar: AppBar(
backgroundColor: Colors.blue,
actions: [
//
IconButton(
//addIconButton
icon: const Icon(Icons.add),
@ -83,36 +81,42 @@ class _HomeWidgetState extends State<HomeWidget> {
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: () {
onPressed: () async {
Navigator.of(context).pop();//
// AddCourseFormWidget
Navigator.push(
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return AddCourseRoute(onCourseAdded: () {
setState(() {
//
// timetableWidgetKey.currentState?.updateWhenDataChange();
});
});
return AddCourseRoute();
},
),
);
// setState(() {
//
// });
//
// print("触发更新课程表");
Setting.timetableWidgetKey!.currentState!.localFutureDo();
},
child: Text('添加课程'),
),
ElevatedButton(
onPressed: () {
onPressed: () async {
Navigator.of(context).pop();//
// AddCourseFormWidget
Navigator.push(
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
//todo
return AddScheduleRoute(scheduleType: "task",); //
return AddScheduleRoute(
scheduleType: "task",
); //
},
),
);
Setting.timetableWidgetKey!.currentState!.localFutureDo();
},
child: Text('添加个人计划'),
),
@ -126,25 +130,97 @@ class _HomeWidgetState extends State<HomeWidget> {
),
IconButton(
//todo 使
icon: const Icon(Icons.more),
icon: const Icon(Icons.access_alarm),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
//todo
return TomatoClockRoute();
},
),
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('选择时长'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
children: [
Text("$durationString 分钟"),
// Slider(
// value: selectedDuration,
// min: 0,
// max: 180,
// allowedInteraction: SliderInteraction.slideOnly,
// onChanged: (double value) {
// durationString=selectedDuration.toStringAsFixed(1);
// setState(() {
// selectedDuration = value;
// durationString=selectedDuration.toStringAsFixed(1);
// });
// },
// ),
],
),
SizedBox(height: 10),
Container(
height: 30,
child: TextField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: '请输入时长(分钟)',
border: OutlineInputBorder(),
),
onChanged: (value) {
setState(() {
selectedDuration =double.parse(value);
durationString=selectedDuration.toStringAsFixed(1);
});
},
),
),
SizedBox(height: 10),
// Text('时长:$selectedDuration 分钟'),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
child: Text('返回主界面'),
onPressed: () {
Navigator.of(context).pop();
},
),
ElevatedButton(
child: Text('进入番茄时钟'),
onPressed: () {
Navigator.of(context).pop();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
//todo
return TomatoClockRoute(flag:0,selectedDuration:selectedDuration);
},
),
);
},
),
],
)
],
),
);
},
);
},
),
IconButton(
icon: const Icon(Icons.group_add),
onPressed: () {
onPressed: () async {
//
Navigator.push(
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
@ -153,7 +229,8 @@ class _HomeWidgetState extends State<HomeWidget> {
},
),
);
Setting.timetableWidgetKey!.currentState!.serverFutureDo();
Setting.timetableWidgetKey!.currentState!.localFutureDo();
},
),
Builder(
@ -167,108 +244,177 @@ class _HomeWidgetState extends State<HomeWidget> {
),
],
),
endDrawer: Drawer(
// Use endDrawer to place the drawer on the right side
child: Column(
children: [
UserAccountsDrawerHeader(
accountName: GestureDetector(
onTap: () {
if (Setting.user!.getId! == -1) {
//
Navigator.push(
endDrawer: Consumer<TimeProvider>(builder: (ctx, timePro, child) {
return Drawer(
//
child: Column(
children: [
UserAccountsDrawerHeader(
accountName: GestureDetector(
onTap: () async {
if (Setting.user!.getId! == -1) {
//
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return LoginWidget();
},
),
);
Setting.timetableWidgetKey!.currentState!.localFutureDo();
Setting.timetableWidgetKey!.currentState!.serverFutureDo();
} else {
//退
await Setting.saveUser(Setting.nullUser);
await Setting.saveInitFlag(true);
}
setState(() {});
Setting.timetableWidgetKey!.currentState!.localFutureDo();
},
child: Setting.user!.getId! != -1
? Text(Setting.user!.getUsername!)
: Text('未登录'),
),
accountEmail: GestureDetector(
onTap: () async {
if (Setting.user!.getId! == -1) {
//
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return LoginWidget(); //
},
),
);
Setting.timetableWidgetKey!.currentState!.localFutureDo();
Setting.timetableWidgetKey!.currentState!.serverFutureDo();
} else {
//退
await Setting.saveUser(Setting.nullUser);
await Setting.saveInitFlag(true);
}
setState(() {});
Setting.timetableWidgetKey!.currentState!.localFutureDo();
},
child: Setting.user!.getId! != -1
? Text('退出登录')
: SizedBox(), //
),
currentAccountPicture: CircleAvatar(
backgroundImage:
AssetImage('assets/images/userphoto.jpg'), //
),
),
ListTile(
title: Text('导入学校课程'),
onTap: () async {
//todo
//
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return AutoImportWidget();
},
),
);
Setting.timetableWidgetKey!.currentState!.localFutureDo();
},
),
GestureDetector(
//
onLongPressStart: (details) {
print('按下');
if (_timer == null) {
_timer = Timer(Duration(seconds: 10), () {
Setting.saveIsDeveloperButtonVisible(true).then((value) {
setState(() {
setState(() {
print('开发者模式开启');
});
});
});
});
}
},
onLongPressEnd: (details) {
print('抬起');
if (_timer != null) _timer!.cancel();
_timer = null;
},
child: ListTile(
title: Text('用户设置'),
onTap: () async {
//todo
// deng
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return LoginWidget(); //
return UserSettingWidget();
},
),
);
}else{
//退
Setting.saveUser(Setting.nullUser);
setState(() {
});
}
},
child: Setting.user!.getId! != -1 ? Text(Setting.user!.getUsername!) : Text('未登录'),
Setting.timetableWidgetKey!.currentState!.localFutureDo();
},
),
),
accountEmail: GestureDetector( //
onTap: () {
if (Setting.user!.getId! == -1) {
//
Navigator.push(
if (Setting.user!.getId! == -1)
ListTile(
title: Text('注册'),
onTap: () async {
//todo
// UserSettingWight
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return LoginWidget(); //
return RegisterWidget();
},
),
);
}else{
//退
Setting.saveUser(Setting.nullUser);
setState(() {
});
}
},
child: Setting.user!.getId! != -1
? Text('退出登录')
: SizedBox(), //
),
currentAccountPicture: CircleAvatar(
backgroundImage: AssetImage(
'assets/images/userphoto.jpg'), //
),
),
ListTile(
title: Text('用户设置'),
onTap: () {
//todo
// deng
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return UserSettingRoute();
},
),
);
},
),
ListTile(
title: Text('注册'),
onTap: () {
//todo
// UserSettingWight
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return RegisterWidget();
},
),
);
},
),
ListTile(
title: Text('开发者测试'),
onTap: () {
// TestWidget
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return TestRoute();
},
),
);
},
),
],
),
),
body: TimetableWidget(),
},
),
if (Setting.user!.getId! != -1)//
ListTile(
title: Text('更改账号信息'),
onTap: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return ChangeUserWidget();
},
),
);
setState(() {});
},
),
if (Setting.isDeveloperButtonVisible&&Setting.user!.getRole! >=1 )
ListTile(
title: Text('开发者测试'),
onTap: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return TestRoute();
},
),
);
Setting.timetableWidgetKey!.currentState!.localFutureDo();
},
),
],
),
);
}),
body: TimetableWidget(key: Setting.timetableWidgetKey!),
);
}
}

@ -0,0 +1,80 @@
import 'package:flutter/material.dart';
import 'package:timemanagerapp/controller/TeamController.dart';
import 'package:timemanagerapp/entity/Team.dart';
import '../setting/Setting.dart';
class JoinTeamWidget extends StatefulWidget {
const JoinTeamWidget({Key? key}) : super(key: key);
@override
_JoinTeamWidgetState createState() => _JoinTeamWidgetState();
}
class _JoinTeamWidgetState extends State<JoinTeamWidget> {
TeamController teamController = TeamController();
TextEditingController teamNameController = TextEditingController();
// TextEditingController teamDescriptionController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('加入团队'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextField(
controller: teamNameController,
decoration: InputDecoration(
labelText: '团队名称',
),
),
SizedBox(height: 10),
// TextField(
// controller: teamDescriptionController,
// decoration: InputDecoration(
// labelText: '团队描述',
// ),
// ),
SizedBox(height: 20),
ElevatedButton(
onPressed: () async {
String teamName = teamNameController.text;
// String teamDescription = teamDescriptionController.text;
bool res = await teamController.joinTeam(teamName);
if(res==false){
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('结果'),
content: Text('团队不存在或已加入'),
actions: [
TextButton(
child: Text('确定'),
onPressed: () {
Navigator.of(context).pop(); //
},
),
],
);
},
);
}else{
Setting.teamWidgetKey!.currentState!.futureDo();
Navigator.pop(context);
}
},
child: Text('确定'),
),
],
),
),
);
}
}

@ -1,7 +1,12 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:timemanagerapp/controller/TaskController.dart';
import 'package:timemanagerapp/controller/UserController.dart';
import 'package:timemanagerapp/controller/CourseController.dart';
import '../entity/User.dart';
import '../provider/TimeProvider.dart';
import '../setting/Setting.dart';
class LoginWidget extends StatefulWidget {
@override
@ -13,15 +18,31 @@ class _LoginWidgetState extends State<LoginWidget> {
final TextEditingController usernameController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
Future<void> handleLogin() async {
Future<void> handleLogin(context) async {
String username = usernameController.text;
String password = passwordController.text;
bool res = await userController.login(User(username: username, password: password, role: 0));
if(res) {
Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
Navigator.pop(context);
}else{
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('用户名或密码错误'))
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('结果'),
content: Text('用户名或密码错误'),
actions: [
TextButton(
child: Text('确定'),
onPressed: () {
Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
Navigator.of(context).pop(); //
},
),
],
);
},
);
}
}
@ -54,7 +75,7 @@ class _LoginWidgetState extends State<LoginWidget> {
),
SizedBox(height: 24.0),
ElevatedButton(
onPressed: handleLogin,
onPressed: ()=>handleLogin(context),
child: Text('登录'),
),
],

@ -1,31 +1,72 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:timemanagerapp/controller/TeamController.dart';
import 'package:timemanagerapp/provider/TeamProvider.dart';
import '../entity/Team.dart';
import '../entity/User.dart';
import '../setting/Setting.dart';
class ManageUserTeamWidget extends StatefulWidget {
const ManageUserTeamWidget({Key? key}) : super(key: key);
const ManageUserTeamWidget({Key? key, required this.team}) : super(key: key);
final Team team;
@override
_AddTeamWidgetState createState() => _AddTeamWidgetState();
_ManageUserTeamWidgetState createState() =>
_ManageUserTeamWidgetState(team: team);
}
class _AddTeamWidgetState extends State<ManageUserTeamWidget> {
TextEditingController memberIdController = TextEditingController();
class _ManageUserTeamWidgetState extends State<ManageUserTeamWidget> {
_ManageUserTeamWidgetState({required this.team});
final Team team;
int loading = 1;
TeamController teamController = TeamController();
int firstInit = 0;
List<User> memberList = [
User(id: 1, username: '成员1', password: '123', role: 0),
];
Future<void> futureDo() async {
//
memberList = await teamController.getTeamUserList(team.getId!);
setState(() {
loading = 0;
});
}
dataInitAfterFutherDo() {
//
}
updateAfterFutherDo() {
//
}
void handleInviteButton() {
String memberId = memberIdController.text;
String memberName = memberIdController.text;
//
teamController.insertTeamUser(team.id!, memberName);
//
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('成功发送邀请'),
content: Text('已成功发送邀请给成员ID: $memberId'),
content: Text('已成功发送邀请给成员: $memberName'),
actions: [
TextButton(
child: Text('确定'),
onPressed: () {
Navigator.of(context).pop(); //
futureDo().then((value) => {setState(() {})});
},
),
],
@ -34,28 +75,115 @@ class _AddTeamWidgetState extends State<ManageUserTeamWidget> {
);
}
void removeMember(User member) {
//
teamController.deleteTeamUser(team, member.getId!).then((value) {
//
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('成功移除成员'),
content: Text('已成功移除成员: ' + member.getUsername),
actions: [
TextButton(
child: Text('确定'),
onPressed: () {
Navigator.of(context).pop(); //
futureDo().then((value) => {
setState(() {
// loading = 1;
})
});
// setState(() {
// loading = 1;
// futureDo();
// });
},
),
],
);
},
);
});
}
final memberIdController = TextEditingController();
@override
void initState() {
super.initState();
futureDo();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('添加团队成员'),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
children: [
TextField(
controller: memberIdController,
decoration: InputDecoration(labelText: '成员ID'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: handleInviteButton,
child: Text('邀请'),
),
],
),
),
);
if (loading == 1) {
loading = 0;
return Center(
child: CircularProgressIndicator(),
);
} else {
return
Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Text('团队成员'),
),
body: RefreshIndicator(
onRefresh: () {
print('下拉refresh');
return futureDo().then((value) => setState(() {}));
},
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
children: [
if (team.leaderId == Setting.user!.getId! || Setting.user!.getRole >= 2)
TextField(
controller: memberIdController,
decoration: InputDecoration(labelText: '成员ID'),
),
if (team.leaderId == Setting.user!.getId! || Setting.user!.getRole >= 2)
SizedBox(height: 20),
if (team.leaderId == Setting.user!.getId! || Setting.user!.getRole >= 2)
ElevatedButton(
onPressed: handleInviteButton,
child: Text('邀请'),
),
if (team.leaderId == Setting.user!.getId!)
SizedBox(height: 20),
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: memberList.length,
itemBuilder: (BuildContext context, int index) {
User member = memberList[index];
return ListTile(
title: Text(team.leaderId != member.getId! ?member.getUsername:member.getUsername+'(管理员)',
style: TextStyle(
color: team.leaderId != member.getId!
? Colors.black
: Colors.orange)
), //leader
trailing: team.leaderId == Setting.user!.getId! || (team.leaderId != member.getId! && Setting.user!.getRole >= 2)
? IconButton(
icon: Icon(Icons.delete),
onPressed: () {
removeMember(member);
},
)
: null,
);
},
),
],
),
),
)
),
);
}
}
}

@ -15,18 +15,73 @@ class _RegisterWidgetState extends State<RegisterWidget> {
final TextEditingController passwordController = TextEditingController();
final TextEditingController confirmPasswordController = TextEditingController();
void handleRegister() {
Future<void> handleRegister(context) async {
String username = usernameController.text;
String password = passwordController.text;
String confirmPassword = confirmPasswordController.text;
if (password != confirmPassword) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('两次输入的密码不一致'))
//
if (password == '' || confirmPassword == '') {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('结果'),
content: Text('密码不能为空'),
actions: [
TextButton(
child: Text('确定'),
onPressed: () {
Navigator.of(context).pop(); //
},
),
],
);
},
);
return;
}else if(password != confirmPassword) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('结果'),
content: Text('两次输入的密码不一致'),
actions: [
TextButton(
child: Text('确定'),
onPressed: () {
Navigator.of(context).pop(); //
},
),
],
);
},
);
return;
}else{
userController.register(User(username:username, password:password, role:0)).then((value) => Navigator.pop(context));
bool res = await userController.register(User(username:username, password:password, role:0));
if(res){
Navigator.pop(context);
}else{
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('结果'),
content: Text('注册失败'),
actions: [
TextButton(
child: Text('确定'),
onPressed: () {
Navigator.of(context).pop(); //
},
),
],
);
},
);
}
}
}
@ -66,7 +121,7 @@ class _RegisterWidgetState extends State<RegisterWidget> {
),
SizedBox(height: 24.0),
ElevatedButton(
onPressed: handleRegister,
onPressed:()=> handleRegister(context),
child: Text('注册'),
),
],

@ -1,27 +0,0 @@
import 'package:flutter/material.dart';
/**
* @desc 线
* @author xiedong
* @date 2020-02-24.
*/
class SpaceWidget extends StatelessWidget {
double height, width;
SpaceWidget({
this.height = 1,
this.width = 1,
}) : super();
@override
Widget build(BuildContext context) {
return
Container(
height: height,
width: width,
color: Colors.transparent,
);
}
}

@ -0,0 +1,344 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:timemanagerapp/controller/TeamController.dart';
import 'package:timemanagerapp/provider/TeamUserProvider.dart';
import 'package:timemanagerapp/ruters/AddScheduleRoute.dart';
import 'package:timemanagerapp/widgets/FreeTimetableWidget.dart';
import 'package:timemanagerapp/widgets/ManageUserTeamWidget.dart';
import '../entity/Team.dart';
import '../setting/Setting.dart';
class TeamWidget extends StatefulWidget {
const TeamWidget({required key}) : super(key: key);
@override
TeamWidgetState createState() => TeamWidgetState();
}
class TeamWidgetState extends State<TeamWidget> {
int firstInit = 0;
List<Team> myTeamList = [];
List<Team> joinTeamList = [];
// [
// Team(id:1, teamName: 'Team 1', leaderId: 1, maxNumber: 10),
// Team(id:2, teamName: 'Team 2', leaderId: 1, maxNumber: 10),
// Team(id:3, teamName: 'Team 3', leaderId: 1, maxNumber: 10)
// ];
TeamController teamController = TeamController();
Future<void> futureDo() async {
print('开始futureDo - TeamWidget');
//
myTeamList = await teamController.getMyTeamList();
joinTeamList = await teamController.getJoinedTeamList();
if(Setting.user!.role >= 2){
//
myTeamList.addAll(joinTeamList);
joinTeamList = [];
}
setState(() {
});
}
@override
initState() {
super.initState();
Setting.freeTimetableWidgeKey = GlobalKey();
futureDo();
//todo: get teamList from database
}
@override
Widget build(BuildContext context) {
print('Rebuild teamUserPro');
return RefreshIndicator(
onRefresh: () {
print('下拉refresh');
return futureDo();
},
child: CustomScrollView(
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
Team team = myTeamList[index];
return Column(
children: [
ListTile(
//
leading: Icon(Icons.group), // icon
title: GestureDetector(
onTap: () {
//
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(team.teamName),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(
'团队介绍:${team.introduce == "" ? "" : team.introduce}'),
// Add other information here if needed
],
),
),
actions: <Widget>[
TextButton(
child: Text('关闭'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
},
onLongPress: () {
//
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(team.getTeamName),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: () {
//
Navigator.of(context).pop(); //
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return FreeTimetableWidget(team: team,key:Setting.freeTimetableWidgeKey!);
},
),
);
},
child: Text('查看团队空闲时间'),
),
if (team.leaderId != Setting.user!.getId!)
SizedBox(height: 10),
if (team.leaderId != Setting.user!.getId!)
ElevatedButton(
onPressed: () {
// 退
Navigator.of(context).pop(); //
teamController.deleteTeamUser(team, Setting.user!.id!).then((value) {
futureDo();
});
},
child: Text('退出团队'),
),
],
),
);
},
);
},
child: Text(team.teamName), //
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: Icon(Icons.person_add), //
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return ManageUserTeamWidget(
team: team,
);
},
),
);
},
),
IconButton(
icon:
Icon(Icons.assignment), //
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return AddScheduleRoute(
scheduleType: "work",
teamId: team.id!
);
},
),
);
},
),
IconButton(
//
icon: Icon(Icons.delete),
onPressed: () async {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('删除团队'),
content: Text('您确定要删除团队吗?'),
actions: <Widget>[
TextButton(
child: Text('取消'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: Text('确定'),
onPressed: () async {
print('删除团队'+ team.getTeamName + ' ' + team.id.toString());
await teamController.deleteTeam(team);
futureDo();
Navigator.of(context).pop();
},
),
],
);
},
);
},
),
],
),
),
],
);
},
childCount: myTeamList.length,
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
Team team = joinTeamList[index];
return Column(
children: [
ListTile(
//
//
leading: Icon(Icons.group), // icon
title: GestureDetector(
onTap: () {
//
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(team.teamName),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(
'团队介绍:${team.introduce == "" ? "" : team.introduce}'),
// Add other information here if needed
],
),
),
actions: <Widget>[
TextButton(
child: Text('关闭'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
},
onLongPress: () {
//
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(team.getTeamName),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: () async {
//
Navigator.of(context).pop(); //
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return FreeTimetableWidget(team: team,key:Setting.freeTimetableWidgeKey!);
},
),
);
},
child: Text('查看团队空闲时间'),
),
SizedBox(height: 10),
ElevatedButton(
onPressed: () {
//
Navigator.of(context).pop(); //
teamController.deleteTeamUser(team, Setting.user!.id!).then((value) {
futureDo();
});
},
child: Text('退出团队'),
),
],
),
);
},
);
},
child: Text(team.teamName), //
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: Icon(Icons.person_add), //
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return ManageUserTeamWidget(
team: team,
);
},
),
);
},
),
],
),
),
],
);
},
childCount: joinTeamList.length,
),
),
],
),
);
}
}

@ -1,89 +0,0 @@
import 'package:flutter/material.dart';
import 'package:timemanagerapp/controller/TeamController.dart';
import 'package:timemanagerapp/ruters/AddScheduleRoute.dart';
import 'package:timemanagerapp/ruters/AddTeamRoute.dart';
import 'package:timemanagerapp/widgets/AddScheduleFormWidget.dart';
import 'package:timemanagerapp/widgets/AddTeamWidget.dart';
import 'package:flutter/material.dart';
import 'package:timemanagerapp/widgets/AddTeamWidget.dart';
import 'package:timemanagerapp/widgets/ManageUserTeamWidget.dart';
import '../entity/Team.dart';
class TeamWidget extends StatefulWidget {
const TeamWidget({Key? key}) : super(key: key);
@override
_TeamWidgetState createState() => _TeamWidgetState();
}
class _TeamWidgetState extends State<TeamWidget> {
List<Team> teamList = [
Team(teamName: 'Team 1', leaderId: 1, maxNumber: 10),
Team(teamName: 'Team 2', leaderId: 1, maxNumber: 10),
Team(teamName: 'Team 3', leaderId: 1, maxNumber: 10)
];
TeamController teamController = TeamController();
@override
initState(){
super.initState();
//todo: get teamList from database
}
@override
Widget build(BuildContext context) {
return Center(
child: ListView.builder(
itemCount: teamList.length,
itemBuilder: (BuildContext context, int index) {
Team team = teamList[index];
return Column(
children: [
ListTile(
leading: Icon(Icons.group), // icon
title: Text(team.teamName), //
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: Icon(Icons.person_add), //
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return ManageUserTeamWidget();
},
),
);
},
),
IconButton(
icon: Icon(Icons.assignment), //
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return AddScheduleRoute(
scheduleType: "work",
teamId: 1,
);
},
),
);
},
),
],
),
),
],
);
},
),
);
}
}

@ -25,10 +25,14 @@ import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'package:timemanagerapp/controller/CourseController.dart';
import 'package:timemanagerapp/controller/NetWorkController.dart';
import 'package:timemanagerapp/controller/TeamController.dart';
import 'package:timemanagerapp/controller/UserController.dart';
import 'package:timemanagerapp/database/dao/WorkDao.dart';
import 'package:timemanagerapp/entity/Course.dart';
import 'package:timemanagerapp/entity/Team.dart';
import 'package:timemanagerapp/entity/User.dart';
import 'package:timemanagerapp/database/MyDatebase.dart';
import 'package:timemanagerapp/util/MyLogger.dart';
import '../controller/TaskController.dart';
import '../controller/WorkController.dart';
@ -47,7 +51,7 @@ class _TestWidgetState extends State<TestWidget> {
late UserController userController;
late CourseController courseController;
late TaskController taskController;
late WorkController WwrkController;
// Logger logger = Logger();
@override
void initState() {
@ -65,6 +69,13 @@ class _TestWidgetState extends State<TestWidget> {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Setting.saveIsDeveloperButtonVisible(false);
print('关闭开发者模式');
},
child: Text('关闭开发者模式'),
),
ElevatedButton(
onPressed: () {
showDialog(
@ -84,19 +95,121 @@ class _TestWidgetState extends State<TestWidget> {
},
child: Text('当前用户信息'),
),
ElevatedButton(
onPressed: () {
UserController().getUserList().then((userList) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('用户列表'),
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: userList
.map((user) => ListTile(
title: Text(user.getUsername),
subtitle: Text(user.toString()),
))
.toList(),
),
),
);
},
);
});
},
child: Text('显示所有用户'),
),
ElevatedButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('删除所有用户'),
content: Text('您确定要删除所有的用户吗?'),
actions: <Widget>[
TextButton(
child: Text('取消'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: Text('确定'),
onPressed: () {
NetWorkController()
.deleteAllUser();
Navigator.of(context).pop();
},
),
],
);
},
);
},
child: Text('!删除所有用户'),
),
ElevatedButton(
onPressed: courseController.deleteAllCourses,
child: Text('删除所有课程'),
child: Text('!删除所有课程'),
),
ElevatedButton(
onPressed: taskController.deleteAllTasks,
child: Text('删除所有个人计划'),
child: Text('!删除所有个人计划'),
),
ElevatedButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('重置数据库'),
content: Text('您确定要重置数据库吗?'),
actions: <Widget>[
TextButton(
child: Text('取消'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: Text('确定'),
onPressed: () {
MyDatabase.reBuildDatabase();
Navigator.of(context).pop();
},
),
],
);
},
);
},
child: Text('!重置数据库'),
),
// ElevatedButton(
// onPressed: () => courseController.autoImportCours(jsonstr),
// child: Text('导入课程(待开发)'),
// ),
ElevatedButton(
onPressed: () {
NetWorkController().getText().then((res) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('结果'),
content: Text(res)
);
},
);
});
},
child: Text('番茄时钟文字获取'),
),
ElevatedButton(
onPressed: () => courseController.insertCourse(Course(
userId: 1,
@ -133,9 +246,9 @@ class _TestWidgetState extends State<TestWidget> {
mainAxisSize: MainAxisSize.min,
children: courses
.map((course) => ListTile(
title: Text(course.getName),
subtitle: Text(course.toString()),
))
title: Text(course.getName),
subtitle: Text(course.toString()),
))
.toList(),
),
),
@ -159,9 +272,9 @@ class _TestWidgetState extends State<TestWidget> {
mainAxisSize: MainAxisSize.min,
children: tasks
.map((task) => ListTile(
title: Text(task.getName),
subtitle: Text(task.toString()),
))
title: Text(task.getName),
subtitle: Text(task.toString()),
))
.toList(),
),
),
@ -172,43 +285,171 @@ class _TestWidgetState extends State<TestWidget> {
},
child: Text('显示个人计划列表'),
),
ElevatedButton(
onPressed: () {
TeamController().getWorks().then((works) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('团队任务列表'),
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: works
.map((work) => ListTile(
title: Text(work.getName),
subtitle: Text(work.toString()),
))
.toList(),
),
),
);
},
);
});
},
child: Text('显示团队任务列表'),
),
// ElevatedButton(
// onPressed: () {
// UserController()
// .login(User(username: 'root', password: 'root', role: 1))
// .then((resUser) {
// showDialog(
// context: context,
// builder: (context) {
// return AlertDialog(
// title: Text('登录信息'),
// content: SingleChildScrollView(
// child: Text(resUser!.toString())),
// );
// },
// );
// });
// },
// child: Text('登录'),
// ),
// ElevatedButton(
// onPressed: () {
// NetWorkController()
// .register(User(id: Setting.user!.getId!, username:'testReg' , password: '123', role: 0))
// .then((res) {
// showDialog(
// context: context,
// builder: (context) {
// return AlertDialog(
// title: Text('注册'),
// content: SingleChildScrollView(
// child: Text(res.toString())),
// );
// },
// );
// });
// },
// child: Text('注册'),
// ),
ElevatedButton(
onPressed: () {
NetWorkController().getAllTeamList().then((teamList) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('团队列表'),
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: teamList
.map((team) => ListTile(
title: Text(team.getTeamName),
subtitle: Text(team.toString()),
))
.toList(),
),
),
);
},
);
});
},
child: Text('显示数据库所有团队列表(不可用)'),
),
// ElevatedButton(
// onPressed: () {
// TeamController()
// .insertTeam(Team(leaderId: Setting.user!.getId!, teamName: "test3", maxNumber: 5))
// .then((resTeam) {
// showDialog(
// context: context,
// builder: (context) {
// return AlertDialog(
// title: Text(''),
// content: SingleChildScrollView(
// child: Text(resTeam.toString())),
// );
// },
// );
// });
// },
// child: Text('增加团队'),
// ),
ElevatedButton(
onPressed: () {
User user = Setting.user!;
if(user.role == 1) user.role = 2;
else user.role = 1;
Setting.saveUser(user);
},
child: Text('修改role为2or!2(团队管理员)'),
),
ElevatedButton(
onPressed: () {
NetWorkController()
.login(User(username: 'test', password: '123', role: 1))
.then((resUser) {
.updateTeam(Team(id:1,leaderId: 1, teamName: 'test改', maxNumber: 2))
.then((resTeam) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text(''),
content: SingleChildScrollView(
child: Text(resUser.body)),
child: Text(resTeam.toString())),
);
},
);
});
},
child: Text('更新团队'),
),
ElevatedButton(
onPressed: () {
CourseController()
.insertLocalCourse()
.then((res) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('结果'),
content: SingleChildScrollView(
child: Text(res.toString())),
);
},
);
});
},
child: Text('录0'),
child: Text('插入本地课程'),
),
ElevatedButton(
onPressed: () async => await Setting.saveInitFlag(true),
child: Text('重置initFlag'),
),
MyLogger(),
AddCourseButton(onCourseAdded: (jsonstr) {
// addCourse()
courseController.test_autoImportCours(jsonstr);
}),
// ElevatedButton(
// onPressed: () {
// // AddCourseFormWidget
// //
// showDialog(
// context: context,
// builder: (context) async {
// return AlertDialog(
// title: Text('数据库ID 生成器测试'),
// content: Text((await IdGenerator().generateId()).toString())
//
// },
// child: Text('数据库ID 生成器测试'),
// ),
],
),
),

@ -2,11 +2,16 @@ import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:provider/provider.dart';
import 'package:timemanagerapp/controller/CourseController.dart';
import 'package:timemanagerapp/controller/TaskController.dart';
import 'package:timemanagerapp/controller/TeamController.dart';
import 'package:timemanagerapp/controller/TimetableWidgetController.dart';
import 'package:timemanagerapp/ruters/AddCourseRoute.dart';
import 'package:timemanagerapp/ruters/AddScheduleRoute.dart';
import '../ruters/TomatoClockRoute.dart';
import '../controller/WorkController.dart';
import '../entity/Course.dart';
import '../entity/Task.dart';
import '../entity/Work.dart';
@ -14,14 +19,13 @@ import '../provider/TimeProvider.dart';
import '../setting/Setting.dart';
class TimetableWidget extends StatefulWidget {
final double deviceWidth = Setting.deviceWidth;
TimetableWidget({required Key key}) : super(key: key);
@override
State<StatefulWidget> createState() =>
TimetableWidgetState(deviceWidth: deviceWidth);
TimetableWidgetState();
}
class TimetableWidgetState extends State<TimetableWidget> {
late double deviceWidth;
int firstInit = 0;
//
@ -29,9 +33,12 @@ class TimetableWidgetState extends State<TimetableWidget> {
TimetableWidgetController();
late CourseController courseController = CourseController.getInstance();
late TaskController taskController = TaskController();
late TeamController teamController = TeamController();
// late WorkController workController = WorkController();
late List timeBlockList = [];
List taskList = [];
List workList = [];
Map<int, List> timeBlockWeekMap = {};
//
@ -46,76 +53,103 @@ class TimetableWidgetState extends State<TimetableWidget> {
var currentWeekDayIndex = 0;
//
int weekCount = 0;
int showWeek = 0;
int currentWeek = 0;
String weekCountstr = '第1周';
String showWeekstr = '第1周';
int showMonth = 0;
final double hourHeight = 60.0 * 1.5;
//DateTimePiexl
List<DateTime> timePoints = [
DateTime(2023, 9, 22, 7, 30),
DateTime(2023, 9, 22, 8, 0), // 8:00 AM
DateTime(2023, 9, 22, 9, 35), // 8:15 PM
DateTime(2023, 9, 22, 10, 5),
DateTime(2023, 9, 22, 11, 40),
DateTime(2023, 9, 22, 13, 30),
DateTime(2023, 9, 22, 15, 5), // 8:00 AM
DateTime(2023, 9, 22, 15, 35), // 12:30 PM
DateTime(2023, 9, 22, 17, 10),
DateTime(2023, 9, 22, 18, 30),
DateTime(2023, 9, 22, 19, 15), // 8:00 AM
DateTime(2023, 9, 22, 20, 5), // 12:30 PM
DateTime(2023, 9, 22, 20, 55),
];
//Offset
var positions = [];
bool loading = true;
TimetableWidgetState({required this.deviceWidth});
TimetableWidgetState();
updateDateByWeekCount() {}
Future<void> futureDo() async {
print('开始futureDo');
Future<void> localFutureDo() async {
print('开始localFutureDo');
//
courseList = await courseController.getCourses();
taskList = await taskController.getTasks();
dataCaculateAfterFutherDo();
print('localFutureDo 完成');
setState(() {});
}
Future<void> serverFutureDo() async {
print('开始serverFutureDo');
//
workList = await teamController.getWorks();
dataCaculateAfterFutherDo();
print('serverFutureDo 完成');
setState(() {});
}
//
@override
initState() {
super.initState();
}
dataInitAfterFutherDo() {
//
timeBlockWeekMap = {};
timeBlockList = [];
currentWeek = timetableWidgetController.getWeekCount();
weekCount = currentWeek;
//
currentWeek = TimetableWidgetController.getWeekCount();
showWeek = currentWeek;
currentWeekDayIndex = DateTime.now().weekday - 1;
// showWeek = 1;
//
showMonth = DateTime.now().month;
dataCaculateAfterFutherDo();
serverFutureDo();
localFutureDo();
}
@override
dispose() {
super.dispose();
// Setting.saveInitFlag(false);
}
dataCaculateAfterFutherDo() {
timeBlockWeekMap = {};
timeBlockList = [];
timeBlockList.addAll(courseList);
timeBlockList.addAll(taskList);
timeBlockList.addAll(workList);
timeBlockWeekMap =
timetableWidgetController.transformCourseMap(timeBlockList);
timetableWidgetController.transformTimeBlockMap(timeBlockList);
var mondayTime = TimetableWidgetController.getmondayTime();
//showMon
showMonth =
mondayTime.add(Duration(days: 7 * (showWeek - currentWeek))).month;
//
var mondayTime = timetableWidgetController.getmondayTime();
//
dateListstr = [];
for (int i = 0; i < 7; i++) {
dateListstr.add((mondayTime.day + i).toString());
if ((mondayTime.day + i) == DateTime.now().day) {
currentWeekDayIndex = i + 1;
}
dateListstr.add(mondayTime
.add(Duration(days: i + 7 * (showWeek - currentWeek)))
.day
.toString());
}
//
positions =
timetableWidgetController.convertTimeList(timePoints, deviceWidth);
positions = TimetableWidgetController.convertTimeList(
TimetableWidgetController.timePoints);
}
updateAfterFutherDo() {
@ -124,273 +158,270 @@ class TimetableWidgetState extends State<TimetableWidget> {
timeBlockList.addAll(courseList);
timeBlockList.addAll(taskList);
timeBlockList.addAll(workList);
timeBlockWeekMap =
timetableWidgetController.transformCourseMap(timeBlockList); //
timetableWidgetController.transformTimeBlockMap(timeBlockList); //
var mondayTime = TimetableWidgetController.getmondayTime();
//showMon
showMonth =
mondayTime.add(Duration(days: 7 * (showWeek - currentWeek))).month;
var mondayTime = timetableWidgetController.getmondayTime();
//
for (int i = 0; i < 7; i++) {
dateListstr[i] = mondayTime
.add(Duration(days: i + 7 * (weekCount - currentWeek)))
.add(Duration(days: i + 7 * (showWeek - currentWeek)))
.day
.toString();
}
//
positions = TimetableWidgetController.convertTimeList(
TimetableWidgetController.timePoints);
// print('Recent monday '+DateTime.now().day.toString());
}
@override
Widget build(BuildContext contexvoidt) {
return Consumer<TimeProvider>(builder: (ctx, timePro, child) {
print('Rebuild timePro');
return FutureBuilder<void>(
future: futureDo(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
//
if (snapshot.connectionState == ConnectionState.done) {
if (firstInit == 0) {
//
dataInitAfterFutherDo();
firstInit = 1;
} else {
//
updateAfterFutherDo();
}
return RefreshIndicator(
onRefresh: () {
print('下拉refresh');
return futureDo().then((value) => setState(() {}));
},
child: GestureDetector(
onHorizontalDragEnd: (details) {
if (details.primaryVelocity! > 0) {
//
setState(() {
weekCount--;
updateDateByWeekCount();
});
} else if (details.primaryVelocity! < 0) {
//
setState(() {
weekCount++;
updateDateByWeekCount();
});
}
},
child: Column(
mainAxisAlignment: MainAxisAlignment.start, //
return RefreshIndicator(
onRefresh: () {
print('下拉refresh');
return serverFutureDo().then((value) {
// Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
});
},
child: GestureDetector(
onHorizontalDragEnd: (details) {
teamController.getWorks().then((value) {
workList = value;
setState(() {});
});
if (details.primaryVelocity! > 0) {
//
setState(() {
showWeek--;
currentWeekDayIndex -= 7;
dataCaculateAfterFutherDo();
// updateDateByWeekCount();
});
} else if (details.primaryVelocity! < 0) {
//
setState(() {
showWeek++;
currentWeekDayIndex += 7;
dataCaculateAfterFutherDo();
// updateDateByWeekCount();
});
}
},
child: Column(
mainAxisAlignment: MainAxisAlignment.start, //
children: [
SizedBox(
//
//
child: GridView.builder(
shrinkWrap: true,
//
physics: NeverScrollableScrollPhysics(),
//
itemCount: 8,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 8, childAspectRatio: 1 / 1),
//
itemBuilder: (BuildContext context, int index) {
//item
return Container(
color: index == this.currentWeekDayIndex
? Color(0xf7f7f7) //
: Colors.white,
child: Center(
child: index == 0
? Column(
//
mainAxisAlignment: MainAxisAlignment.center,
children: [
if(showWeek>0 && showWeek<Setting.termAllWeekCout)
Container(
// height: 10,
// width: 6,
child: Text(
'' +
showWeek.toString() +
'', //
style: TextStyle(
fontSize: 12,
color: currentWeek ==
showWeek //
? Colors.amber
: Colors.black87)),
),
Container(
// height: 10,
// width: 6,
child: Text(
showMonth.toString() + '', //
style: TextStyle(
fontSize: 12,
color: currentWeek ==
showWeek //
? Colors.amber
: Colors.black87)),
),
],
)
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(weekList[index - 1], //
style: TextStyle(
fontSize: 14,
color: index ==
currentWeekDayIndex //
? Colors.lightBlue
: Colors.black87)),
SizedBox(
height: 5,
),
Text(dateListstr[index - 1], //
style: TextStyle(
fontSize: 12,
color: index ==
currentWeekDayIndex //
? Colors.lightBlue
: Colors.black87)),
],
),
),
);
}),
),
//stack
Expanded(
child: SingleChildScrollView(
child: Row(
children: [
SizedBox(
//
//
child: GridView.builder(
shrinkWrap: true,
//
physics: NeverScrollableScrollPhysics(),
//
itemCount: 8,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 8, childAspectRatio: 1 / 1),
//
itemBuilder: (BuildContext context, int index) {
//item
return Container(
color: index == this.currentWeekDayIndex
? Color(0xf7f7f7) //
: Colors.white,
child: Center(
child: index == 0
? Column(
//
mainAxisAlignment:
MainAxisAlignment.center,
//stack
Container(
width: Setting.deviceWidth,
height: 2000,
child: Stack(
alignment: Alignment.center,
children: [
// Stack
Positioned(
top: 0,
left: 0,
child: Container(
width: Setting.deviceWidth,
height: 2000,
child: Stack(
children: List.generate(
//
positions.length,
(index) => Positioned(
top: positions[index].dy,
left: positions[index].dx,
child: Row(
children: [
Container(
// height: 10,
// width: 6,
child: Text(
'' +
weekCount.toString() +
'', //
style: TextStyle(
fontSize: 12,
color: currentWeek ==
weekCount //
? Colors.amber
: Colors.black87)),
Text(
TimetableWidgetController
.timePoints[index].hour
.toString()
.padLeft(2, '0') +
':' +
TimetableWidgetController
.timePoints[index].minute
.toString()
.padLeft(2, '0'),
),
],
)
: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text(weekList[index - 1], //
style: TextStyle(
fontSize: 14,
color: index ==
currentWeekDayIndex //
? Colors.lightBlue
: Colors.black87)),
SizedBox(
height: 5,
Container(
//
width: Setting.deviceWidth * 0.04,
height: 10,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.amber,
width: 2,
),
),
),
Text(dateListstr[index - 1], //
style: TextStyle(
fontSize: 12,
color: index ==
currentWeekDayIndex //
? Colors.lightBlue
: Colors.black87)),
Container(
//线
width: Setting.deviceWidth * 0.90,//old:0.84
height: 2,
color: Colors.lightBlue),
],
),
),
);
}),
),
//stack
Expanded(
child: SingleChildScrollView(
child: Row(
children: [
//stack
),
),
),
)),
//Stack
Container(
width: deviceWidth,
height: 2000,
child: Stack(
alignment: Alignment.center,
children: [
// Stack
Positioned(
top: 0,
left: 0,
child: Container(
width: deviceWidth,
height: 2000,
child: Stack(
children: List.generate(
//
positions.length,
(index) => Positioned(
top: positions[index].dy,
left: positions[index].dx,
child: Row(
constraints:
BoxConstraints.expand(), // 使constraints
// width: 390,
// height: 2000,
child: Stack(
children: List.generate(
timeBlockWeekMap.containsKey(showWeek)
? timeBlockWeekMap[showWeek]!.length
: 0,
(index) {
var currentItem =
timeBlockWeekMap[showWeek]![index];
return Positioned(
top: timetableWidgetController
.getdy(currentItem),
left: timetableWidgetController
.getdx(currentItem) +
Setting.deviceWidth * 0.15,
child: SingleChildScrollView(
child: Container(
width: Setting.deviceWidth * 0.115,
height: timetableWidgetController
.getHeight(currentItem),
decoration: BoxDecoration(
color: getItemColor(currentItem),
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
),
child: SingleChildScrollView(
child: Column(
children: [
Text(
timePoints[index]
.hour
.toString()
.padLeft(2, '0') +
':' +
timePoints[index]
.minute
.toString()
.padLeft(2, '0'),
),
Container(
width: deviceWidth * 0.04,
height: 10,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.amber,
width: 2,
),
),
),
Container(
width: deviceWidth * 0.84,
height: 2,
color: const Color.fromARGB(
255, 136, 61, 61),
),
if (currentItem is Course)
CouresBlockContenWidget(
currentItem: currentItem),
if (currentItem is Task)
TaskBlockContentWidget(
currentItem: currentItem),
if (currentItem is Work)
WorkBlockContentWidget(
currentItem: currentItem),
],
),
),
),
),
)),
//Stack
Container(
constraints: BoxConstraints
.expand(), // 使constraints
// width: 390,
// height: 2000,
child: Stack(
children: List.generate(
timeBlockWeekMap
.containsKey(weekCount)
? timeBlockWeekMap[weekCount]!
.length
: 0,
(index) {
var currentItem = timeBlockWeekMap[
weekCount]![index];
return Positioned(
top: timetableWidgetController
.getdy(currentItem) +
10,
left: timetableWidgetController
.getdx(currentItem) +
deviceWidth * 0.15,
child: SingleChildScrollView(
child: Container(
width: deviceWidth * 0.115,
height:
timetableWidgetController
.getHeight(
currentItem),
decoration: BoxDecoration(
color: getItemColor(
currentItem),
borderRadius:
BorderRadius.all(
Radius.circular(10.0),
),
),
child: SingleChildScrollView(
child: Column(
children: [
if (currentItem
is Course)
CouresBlockContenWidget(
currentItem:
currentItem),
if (currentItem is Task)
TaskBlockContentWidget(
currentItem:
currentItem),
if (currentItem is Work)
WorkBlockContentWidget(
currentItem:
currentItem),
],
),
),
),
),
);
},
),
))
],
),
),
);
},
),
))
],
),
))
),
],
),
),
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
});
});
))
],
),
),
);
}
//
@ -406,8 +437,36 @@ class TimetableWidgetState extends State<TimetableWidget> {
}
}
class ShowTimeTextWidget extends StatelessWidget {
const ShowTimeTextWidget({super.key, required this.currentItem});
final currentItem;
@override
Widget build(BuildContext context) {
return ListBody(
children: <Widget>[
Text(
'开始时间: ${currentItem.startTime.year}' +
'${currentItem.startTime.month}' +
'${currentItem.startTime.day.toString().padLeft(2, '0')}' +
'${currentItem.startTime.hour.toString().padLeft(2, '0')}' +
':${currentItem.startTime.minute.toString().padLeft(2, '0')}',
),
Text(
'结束时间: ${currentItem.endTime.year}' +
'${currentItem.endTime.month}' +
'${currentItem.endTime.day.toString().padLeft(2, '0')}' +
'${currentItem.endTime.hour.toString().padLeft(2, '0')}' +
':${currentItem.endTime.minute.toString().padLeft(2, '0')}',
)
],
);
}
}
class BlockGestureWidget extends StatelessWidget {
const BlockGestureWidget({
BlockGestureWidget({
super.key,
required this.currentItem,
required this.blockGestureWidgetChilld,
@ -431,19 +490,29 @@ class BlockGestureWidget extends StatelessWidget {
child: ListBody(
children: <Widget>[
if (currentItem is Course) ...{
Text('老师: ${(currentItem as Course).teacher ?? ""}'),
Text('地点: ${(currentItem as Course).location ?? ""}'),
Text('开始时间: ${(currentItem as Course).startTime.toString()}'),
Text('结束时间: ${(currentItem as Course).endTime.toString()}'),
Text('备注: ${(currentItem as Course).remark ?? ""}'),
Text(
'老师: ${currentItem.teacher == '' || currentItem.teacher == null ? "" : currentItem.teacher}'),
Text(
'地点: ${currentItem.location == '' || currentItem.location == null ? "" : currentItem.location}'),
ShowTimeTextWidget(currentItem: currentItem),
Text(
'学分: ${currentItem.credit == -1 || currentItem.credit == null ? "" : currentItem.credit.toString()}'),
Text(
'备注: ${currentItem.remark == '' || currentItem.remark == null ? "" : currentItem.remark}'),
} else if (currentItem is Task) ...{
Text('内容: ${(currentItem as Task).content ?? ""}'),
Text('开始时间: ${(currentItem as Task).startTime.toString()}'),
Text('结束时间: ${(currentItem as Task).endTime.toString()}'),
Text(
'内容: ${currentItem.content == "" || currentItem.content == null ? "" : currentItem.content}'),
ShowTimeTextWidget(currentItem: currentItem),
} else if (currentItem is Work) ...{
Text('工作内容: ${(currentItem as Work).workContent ?? ""}'),
Text('开始时间: ${(currentItem as Work).startTime.toString()}'),
Text('结束时间: ${(currentItem as Work).endTime.toString()}'),
//0
// Text('团队名: ${(currentItem as Work).ge ?? ""}'),
if ((currentItem as Work).teamName != null) ...{
Text(
'团队名: ${currentItem.teamName == "" || currentItem.teamName == null ? "" : currentItem.teamName}'),
},
Text(
'工作内容: ${currentItem.content == "" || currentItem.content == null ? "" : currentItem.content}'),
ShowTimeTextWidget(currentItem: currentItem),
}
],
),
@ -471,12 +540,53 @@ class BlockGestureWidget extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: () {
// TODO:
onPressed: () async {
//
Navigator.of(context).pop(); //
if (currentItem is Course) {
// AddCourseFormWidget
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return AddCourseRoute(exitCourse: currentItem);
},
),
);
Setting.timetableWidgetKey!.currentState!
.localFutureDo();
} else if (currentItem is Task) {
} else {}
Navigator.of(context).pop();
// AddTaskFormWidget
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return AddScheduleRoute(
exitSchedule: currentItem,
scheduleType: 'task');
},
),
);
Setting.timetableWidgetKey!.currentState!
.localFutureDo();
} else {
// AddWorkFormWidget
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return AddScheduleRoute(
exitSchedule: currentItem,
scheduleType: 'work',
teamId: (currentItem as Work).getTeamId);
},
),
);
Setting.timetableWidgetKey!.currentState!
.localFutureDo();
Setting.timetableWidgetKey!.currentState!
.serverFutureDo();
}
},
child: Text('编辑'),
),
@ -485,16 +595,61 @@ class BlockGestureWidget extends StatelessWidget {
// TODO:
if (currentItem is Course) {
CourseController()
.deleteCourse((currentItem as Course).getCourseId);
.deleteCourse((currentItem as Course).getCourseId)
.then((value) {
// Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
// Navigator.of(context).pop()
Setting.timetableWidgetKey!.currentState!
.localFutureDo();
});
} else if (currentItem is Task) {
TaskController().deleteTaskByTaskid(
(currentItem as Task).getTaskId);
} else {}
TaskController()
.deleteTaskByTaskid((currentItem as Task).getTaskId)
.then((value) {
// Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
// Navigator.of(context).pop()
Setting.timetableWidgetKey!.currentState!
.localFutureDo();
});
} else {
TeamController()
.deleteWorkByWorkId((currentItem as Work).getWorkId)
.then((value) {
// Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
// Navigator.of(context).pop()
Setting.timetableWidgetKey!.currentState!
.localFutureDo();
Setting.timetableWidgetKey!.currentState!
.serverFutureDo();
});
}
Navigator.of(context).pop();
},
child: Text('删除'),
),
SizedBox(height: 10),
Visibility(
visible: currentItem is Task,
child: ElevatedButton(
child:Text("进入番茄时钟"),
onPressed:(){
Navigator.of(context).pop();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
int time=(currentItem as Task).getEndTime.difference((currentItem as Task).getStartTime).inMinutes;
double selectedDuration=time.toDouble();
return TomatoClockRoute(flag:(currentItem as Task).getId as int,selectedDuration:selectedDuration);
},
),
);
}
)
)
],
),
);
@ -543,30 +698,38 @@ class CouresBlockContenWidget extends StatelessWidget {
overflow: TextOverflow.clip,
),
Text(
(currentItem as Course).startTime.hour.toString() +
(currentItem as Course).startTime.hour.toString().padLeft(2, '0') +
':' +
(currentItem as Course).startTime.minute.toString(),
(currentItem as Course)
.startTime
.minute
.toString()
.padLeft(2, '0'),
style: TextStyle(
fontSize: 10,
),
overflow: TextOverflow.clip,
),
Text(
(currentItem as Course).endTime.hour.toString() +
(currentItem as Course).endTime.hour.toString().padLeft(2, '0') +
':' +
(currentItem as Course).endTime.minute.toString(),
style: TextStyle(
fontSize: 10,
),
overflow: TextOverflow.clip,
),
Text(
(currentItem as Course).remark,
(currentItem as Course)
.endTime
.minute
.toString()
.padLeft(2, '0'),
style: TextStyle(
fontSize: 10,
),
overflow: TextOverflow.clip,
),
// Text( //
// (currentItem as Course).remark,
// style: TextStyle(
// fontSize: 10,
// ),
// overflow: TextOverflow.clip,
// ),
],
),
);
@ -603,14 +766,22 @@ class TaskBlockContentWidget extends StatelessWidget {
overflow: TextOverflow.clip,
),
Text(
(currentItem as Task).startTime.toString(),
(currentItem as Task).startTime.hour.toString().padLeft(2, '0') +
':' +
(currentItem as Task)
.startTime
.minute
.toString()
.padLeft(2, '0'),
style: TextStyle(
fontSize: 10,
),
overflow: TextOverflow.clip,
),
Text(
(currentItem as Task).endTime.toString(),
(currentItem as Task).endTime.hour.toString().padLeft(2, '0') +
':' +
(currentItem as Task).endTime.minute.toString().padLeft(2, '0'),
style: TextStyle(
fontSize: 10,
),
@ -645,21 +816,29 @@ class WorkBlockContentWidget extends StatelessWidget {
overflow: TextOverflow.clip,
),
Text(
currentItem.workContent,
currentItem.content,
style: TextStyle(
fontSize: 8,
),
overflow: TextOverflow.clip,
),
Text(
currentItem.startTime.toString(),
(currentItem as Work).startTime.hour.toString().padLeft(2, '0') +
':' +
(currentItem as Work)
.startTime
.minute
.toString()
.padLeft(2, '0'),
style: TextStyle(
fontSize: 10,
),
overflow: TextOverflow.clip,
),
Text(
currentItem.endTime.toString(),
(currentItem as Work).endTime.hour.toString().padLeft(2, '0') +
':' +
(currentItem as Work).endTime.minute.toString().padLeft(2, '0'),
style: TextStyle(
fontSize: 10,
),

@ -1,25 +1,91 @@
import 'dart:async';
import 'dart:math';
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:timemanagerapp/controller/TaskController.dart';
import 'package:timemanagerapp/setting/Setting.dart';
class TomatoClockWidget extends StatefulWidget {
final int flag;
final double selectedDuration;
const TomatoClockWidget({super.key, required this.flag,required this.selectedDuration});
@override
_TomatoClockWidgetState createState() => _TomatoClockWidgetState();
_TomatoClockWidgetState createState() => _TomatoClockWidgetState(flag:flag,selectedDuration:selectedDuration);
}
class _TomatoClockWidgetState extends State<TomatoClockWidget> {
AudioPlayer audioPlayer = AudioPlayer();
final int flag;
final double selectedDuration;
static AudioPlayer audioPlayer = AudioPlayer();
_TomatoClockWidgetState({required this.flag,required this.selectedDuration}); //
bool isMusicPlaying = false;
int currentTextIndex = 0;
static bool isMusicPlaying = false;//
List<String> texts = [
"趁此时风华正茂埋头苦干,免他年两鬓苍苍仰面奉承。",
"我的肩上是风,风上是闪烁的星群。",
"使人疲惫的不是远方的高山,而是鞋里的一粒沙子。",
"世界上 ,没有一拳解决不了的事,如果有,那就两拳。",
"就算一次也好,我想在这颗星球上尽情奔跑。",
"只要努力活下去,总有一天会笑着回忆。",
"这世界是个好地方,值得为它奋斗。后半句我同意。",
"秉忠贞之志,守谦退之德。君子仁以爱人,不宜如此",
"只顾着追求新事物,却不回顾历史,怎么会有未来。",
"今日已成往昔,明日即将到来,为此理所当然之事,感到无比痛心。",
"云深夜阑拥月色,少年携酒晚归程,酒香醉情抬眸间,白衣翩立似惊鸿。",
"也许我们都没有长大,只是世界变小了。",
"我们终此一生,就是要摆脱他人的期待,找到真正的自己。",
"我与我周旋久,宁做我。 ",
"就算没人赏识还是选择坚持就像三十岁的梵高。",
"不管是哪种结果,我都坦然接受。因为无论是哪种结果,这都是一次非凡的旅行。",
"时间不在于你拥有多少,而在于你怎样使用。",
"正因为有忘也忘不了的回忆,才会变得坚强,这就是所谓的成长吧!",
"选择道路的时候怎么犹豫都没有关系,但决定之后就一定要坚持到底!",
"休息对于生存而言,也是紧要问题",
];
List<Map<String, String>> data = [
{
'image': 'assets/images/rain.jpg',
'text': '雨声',
'music': 'musics/rain.mp3'
},
{
'image': 'assets/images/clock.jpg',
'text': '时钟滴答',
'music': 'musics/clock.mp3'
},
{
'image': 'assets/images/beach.jpg',
'text': '阳光沙滩',
'music': 'musics/beach.mp3'
},
{
'image': 'assets/images/river.jpg',
'text': '小河流水',
'music': 'musics/river.mp3'
},
{
'image': 'assets/images/jungle.jpg',
'text': '热带雨林',
'music': 'musics/jungle.mp3'
},
{
'image': 'assets/images/village.jpg',
'text': '夏日蝉鸣',
'music': 'musics/village.mp3'
},
{
'image': 'assets/images/coffee.jpg',
'text': '悠闲咖啡',
'music': 'musics/coffee.mp3'
},
];
List<String> backgroundImages = [
"assets/images/image1.jpg",
"assets/images/image2.jpg",
@ -27,11 +93,9 @@ class _TomatoClockWidgetState extends State<TomatoClockWidget> {
];
String currentBackgroundImage = "assets/images/image1.jpg";
int totalTime = 40 * 60; //
int remainingTime = 40 * 60; //
double progress = 1.0; // 1.0
late Timer timer; //
void toggleBackgroundImage() {
int currentIndex = backgroundImages.indexOf(currentBackgroundImage);
int nextIndex = (currentIndex + 1) % backgroundImages.length;
@ -40,43 +104,119 @@ class _TomatoClockWidgetState extends State<TomatoClockWidget> {
});
}
void startTimer() {
timer = Timer.periodic(Duration(seconds: 1), (Timer timer) {
setState(() {
if (remainingTime > 0) {
remainingTime--;
progress = remainingTime / totalTime;
} else {
timer.cancel();
Navigator.pop(context);
//
}
void startTimer() {
timer = Timer.periodic(Duration(seconds: 1), (Timer timer) {
setState(() {
if (remainingTime > 0) {
remainingTime--;
progress = remainingTime / totalTime;
} else {
timer.cancel();
audioPlayer.stop();
if(flag==0){
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('定时已结束'),
content: Text('你的定时已结束'),
actions: [
TextButton(
child: Text('关闭'),
onPressed: () {
Navigator.pop(context); //
Navigator.pop(context); //
},
),
],
);
},
);
}
else
{
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('当前任务'),
content: Text('您的当前任务是否需要从当前界面删除?'),
actions: [
TextButton(
child: Text(''),
onPressed: () {
TaskController()
.deleteTaskByid(flag)
.then((value) {
Setting.timetableWidgetKey!.currentState!
.localFutureDo();
});
//
Navigator.pop(context); //
Navigator.pop(context); //
},
),
TextButton(
child: Text(''),
onPressed: () {
Navigator.pop(context); //
Navigator.pop(context);
},
),
],
);
},
);
}
}
});
});
});
}
}
void toggleText() {
int nextIndex = (currentTextIndex + 1) % texts.length;
var random = Random();
var nextIndex = random.nextInt(texts.length);
setState(() {
currentTextIndex = nextIndex;
});
}
Source source=AssetSource("musics/music.mp3");
late Source source;
void playPauseMusic() {
setState(() {
isMusicPlaying = !isMusicPlaying;
if (isMusicPlaying) {
audioPlayer.play(source,volume: 1);
} else {
audioPlayer.stop();
}
});
}
if (isMusicPlaying == false) {
audioPlayer.setReleaseMode(ReleaseMode.loop);
audioPlayer.play(source,volume: 1).then((value){
setState(() {
isMusicPlaying = !isMusicPlaying;
});
});
} else {
audioPlayer.stop().then((value){
setState(() {
isMusicPlaying = !isMusicPlaying;
});
});
}
}
late int totalTime ; //
late int remainingTime ; //
double progress = 1.0; // 1.0
late Timer timer;
@override
void initState() {
super.initState();
totalTime=(selectedDuration*60).toInt();
remainingTime=(selectedDuration*60).toInt();
startTimer();
}
@ -90,7 +230,7 @@ Source source=AssetSource("musics/music.mp3");
child: Container(
width: Setting.deviceWidth,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(currentBackgroundImage),
fit: BoxFit.cover,
@ -100,18 +240,35 @@ Source source=AssetSource("musics/music.mp3");
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
GestureDetector(
onTap: () {
toggleText();
},
child: Padding(
onTap: () {
toggleText();
},
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 20),
child: Text(
texts[currentTextIndex],
style: TextStyle(
fontSize: 24,
color: Colors.white,
),
),
child:
Column(
children:[
Row(
mainAxisAlignment: MainAxisAlignment.start,
children:[
Icon(
Icons.bubble_chart_outlined,
size:40,
color:Colors.white
),
]
),
Text(
" "+texts[currentTextIndex],
style: TextStyle(
fontSize: 24,
color: Colors.white,
),
),
]
)
)
),
@ -129,7 +286,7 @@ Source source=AssetSource("musics/music.mp3");
valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
),
),
Text(
'${(remainingTime ~/ 60).toString().padLeft(2, '0')}:${(remainingTime % 60).toString().padLeft(2, '0')}',
style: TextStyle(
@ -142,34 +299,193 @@ Source source=AssetSource("musics/music.mp3");
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children:<Widget>[
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children:<Widget>[
IconButton(//
icon: Icon(
Icons.batch_prediction,
color:Colors.white,
size:48
),
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ListView.builder(
shrinkWrap: true,
itemCount: data.length,
// prototypeItem:SizedBox(height: 0,),
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () {
source=AssetSource(data[index]['music'] as String);
audioPlayer.stop();
//
isMusicPlaying=false;
playPauseMusic();
},
child: Column(
children: [
SizedBox(height: 10,),
Container(
color:Colors.grey,
child: Row(
children: [
SizedBox(width:20),
Image.asset(
data[index]['image'] as String,
width: 50,
fit: BoxFit.contain,
height: 30,
),
SizedBox(width: 10),
Text(data[index]['text'] as String),
],
),
)
],)
);
},
),
ElevatedButton(
child: Text('关闭'),
onPressed: () {
Navigator.pop(context);
},
),
],
),
);
},
);
},),
IconButton(
icon: Icon(
isMusicPlaying ? Icons.pause : Icons.play_arrow,
color: Colors.white,
size:48
IconButton(//
icon: Icon(
Icons.audiotrack_rounded,
color: isMusicPlaying?Colors.white:Colors.grey,
size:48
),
onPressed: () {
var random = Random();
var next = random.nextInt(data.length);
source=AssetSource(data[next]['music'] as String);
playPauseMusic();
},
),
onPressed: () {
playPauseMusic();
},
),
IconButton(
icon: Icon(
Icons.stop,
color: Colors.white,
size:48
IconButton(
icon: Icon(
Icons.stop,
color: Colors.white,
size:48
),
onPressed: () {
isMusicPlaying=false;
audioPlayer.stop();
if(flag==0)
{
showDialog(
context: context,
builder: (BuildContext context){
return AlertDialog(
title: Text('提示'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text("是否确认要关闭当前时钟?关闭后将会返回课程主界面"),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
onPressed: () async {
audioPlayer.stop();
Navigator.of(context).pop();//
// AddCourseFormWidget
},
child: Text('取消'),
),
ElevatedButton(
onPressed: () async {
Navigator.of(context).pop();//
// AddCourseFormWidget
Navigator.pop(context);
},
child: Text('确定'),
),
],
)
],)
);
}
);
}
else
{
showDialog(
context: context,
builder: (BuildContext context){
return AlertDialog(
title: Text('提示'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text("是否确认要关闭当前时钟?关闭后将会返回课程主界面并删除当前任务"),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
onPressed: () async {
Navigator.of(context).pop();//
// AddCourseFormWidget
},
child: Text('取消'),
),
ElevatedButton(
onPressed: () async {
TaskController()
.deleteTaskByid(flag)
.then((value) {
// Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
// Navigator.of(context).pop()
Setting.timetableWidgetKey!.currentState!
.localFutureDo();
});
Navigator.of(context).pop();//
// AddCourseFormWidget
Navigator.pop(context);
},
child: Text('确定'),
),
],
)
],)
);
}
);
}
},
),
onPressed: () {
Navigator.pop(context);
},
),
]
]
)
],
),
),

@ -1,17 +1,102 @@
//Wight
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:timemanagerapp/setting/Setting.dart';
class UserSettingWidgt extends StatefulWidget {
import '../provider/TimeProvider.dart';
class UserSettingWidget extends StatefulWidget {
@override
_UserSettingWightState createState() => _UserSettingWightState();
}
//Wight
//todo:Widget
class _UserSettingWightState extends State<UserSettingWidgt> {
class _UserSettingWightState extends State<UserSettingWidget> {
TextEditingController _controller = TextEditingController();
TextEditingController _startDateController = TextEditingController();
Future<void> savepixelToMinuteRatio_ratio(double value) async {
// savepixelToMinuteRatio_ratio
await Setting.savepixelToMinuteRatio_ratio(value);
print('savepixelToMinuteRatio_ratio触发$value');
}
Future<void> saveStartDate(DateTime date) async {
// saveStartDate
await Setting.saveStartDate(date);
print('saveStartDate触发$date');
}
Future<void> handleSave() async {
double number = double.tryParse(_controller.text) ?? 0;
// number
if(number < 0.1) number = 0.1;
if(number > 2) number = 2;
await savepixelToMinuteRatio_ratio(number);
print('DateTime.tryParse'+DateTime.tryParse(_startDateController.text).toString());
var res = DateTime.tryParse(_startDateController.text);
DateTime date = res ?? Setting.startdate;// dateDateTime
print('date: $date');
date = date.weekday == 1 ? date : Setting.startdate; // date
await saveStartDate(date);
// Provider.of<TimeProvider>(context, listen: false).updateTimetable(); //
setState(() {
});
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
_controller.text = Setting.pixelToMinuteRatio_ratio.toString();
_startDateController.text = Setting.startdate.toString().substring(0, 10);
return Scaffold(
appBar: AppBar(
title: Text('设置'),
actions: [
IconButton(
icon: Icon(Icons.save),
onPressed: handleSave,
),
],
),
body: Container(
padding: EdgeInsets.all(16.0),
child: Column(
children: [
Row(
children: [
Text('时间轴比例: ', style: TextStyle(fontSize: 20.0)),
Expanded(
child: TextField(
controller: _controller,
style: TextStyle(fontSize: 20.0), // 20
keyboardType: TextInputType.number,
decoration: InputDecoration(),
),
),
],
),
Row(
children: [
Text('本学期第一周周一日期: ', style: TextStyle(fontSize: 20.0)),
Expanded(
child: TextField(
controller: _startDateController,
keyboardType: TextInputType.datetime,
style: TextStyle(fontSize: 20.0), // 20
decoration: InputDecoration(),
),
),
],
),
],
),
),
);
}
}
}

@ -13,58 +13,58 @@ packages:
dependency: "direct main"
description:
name: audioplayers
sha256: d9f6ca8e9b3e5af5e73d4c814404566f72698ee7ba35487bdf2baa6749e7503f
sha256: "61583554386721772f9309f509e17712865b38565a903c761f96b1115a979282"
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.2.0"
version: "4.1.0"
audioplayers_android:
dependency: transitive
description:
name: audioplayers_android
sha256: fb01b9481f431fe04ac60f1f97ce8158383f2dc754558820592f795d81ca9d53
sha256: dbdc9b7f2aa2440314c638aa55aadd45c7705e8340d5eddf2e3fb8da32d4ae2c
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.0.2"
version: "3.0.2"
audioplayers_darwin:
dependency: transitive
description:
name: audioplayers_darwin
sha256: "3034e99a6df8d101da0f5082dcca0a2a99db62ab1d4ddb3277bed3f6f81afe08"
sha256: "6aea96df1d12f7ad5a71d88c6d1b22a216211a9564219920124c16768e456e9d"
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.0.2"
version: "4.1.0"
audioplayers_linux:
dependency: transitive
description:
name: audioplayers_linux
sha256: "60787e73fefc4d2e0b9c02c69885402177e818e4e27ef087074cf27c02246c9e"
sha256: "396b62ac62c92dd26c3bc5106583747f57a8b325ebd2b41e5576f840cfc61338"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.1.0"
version: "2.1.0"
audioplayers_platform_interface:
dependency: transitive
description:
name: audioplayers_platform_interface
sha256: "365c547f1bb9e77d94dd1687903a668d8f7ac3409e48e6e6a3668a1ac2982adb"
sha256: f7daaed4659143094151ecf6bacd927d29ab8acffba98c110c59f0b81ae51143
url: "https://pub.flutter-io.cn"
source: hosted
version: "6.1.0"
version: "5.0.1"
audioplayers_web:
dependency: transitive
description:
name: audioplayers_web
sha256: "22cd0173e54d92bd9b2c80b1204eb1eb159ece87475ab58c9788a70ec43c2a62"
sha256: ec84fd46eed1577148ed4113f5998a36a18da4fce7170c37ce3e21b631393339
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.1.0"
version: "3.1.0"
audioplayers_windows:
dependency: transitive
description:
name: audioplayers_windows
sha256: "9536812c9103563644ada2ef45ae523806b0745f7a78e89d1b5fb1951de90e1a"
sha256: "1d3aaac98a192b8488167711ba1e67d8b96333e8d0572ede4e2912e5bbce69a3"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.1.0"
version: "2.0.2"
boolean_selector:
dependency: transitive
description:
@ -149,10 +149,10 @@ packages:
dependency: transitive
description:
name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
url: "https://pub.flutter-io.cn"
source: hosted
version: "7.0.0"
version: "6.1.4"
flutter:
dependency: "direct main"
description: flutter
@ -166,6 +166,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.3"
flutter_pickers:
dependency: "direct main"
description:
name: flutter_pickers
sha256: f38a9d9229afed75f76bae64e628b78b9c20194873e3c141783523cf21ac8a95
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.9"
flutter_test:
dependency: "direct dev"
description: flutter
@ -180,10 +188,10 @@ packages:
dependency: "direct main"
description:
name: http
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.0"
version: "0.13.6"
http_parser:
dependency: transitive
description:
@ -208,6 +216,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
logger:
dependency: "direct main"
description:
name: logger
sha256: "7ad7215c15420a102ec687bb320a7312afd449bac63bfb1c60d9787c27b9767f"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.4.0"
matcher:
dependency: transitive
description:
@ -511,4 +527,4 @@ packages:
version: "1.0.3"
sdks:
dart: ">=3.1.0 <4.0.0"
flutter: ">=3.10.0"
flutter: ">=3.7.0"

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save