一个考勤系统的开发笔记
DutySystem
开发周期7月20号到8月1号,8月20号到8月25号左右
A duty system for xxxxxxx.
-
- 3.1. Model Relationship
-
- 7.1. table name:
employees
- 7.2. table names:
records
- 7.3. table name:
users
- 7.4. table name:
user_action_records
- 7.1. table name:
-
- 11.1. Default Timezone
-
- 13.1. Error message:
- 13.2. Solution
- 13.3. Change Server Timezone
-
- 14.1. modal position
- 14.2. positionmethod
-
- 15.1. general page
- 15.2. graph page
- 15.3. valid records
- 15.4. holiday page(option)
- 15.5. timeedit page
Runtime Enviornment
运行环境
Enviornment | Version |
---|---|
Laravel | 5.4 |
PHP | 7.0.10 |
MySQL | 5.7.17 |
Nginx | 1.11.9 |
1. Initialize
系统初始化
php artisan key:generate
php artisan make:auth
php artisan migrate
2. MySQL authentication
account:
**
password:
**
remote database:
- IP:
**.**.**.**:**
- Account:
**
- Password:
**
Service Logic
业务逻辑
3. Model
模型
- User
- Employee
- Record (For employees)
- ActionRecord (For admins)
- CarRecord
- CardRecord
- TimeNode
- DailyCheckStatus
- HolidayDate
- AbsenceValidRecord
3.1. Model Relationship
模型间关系
$user->actions; // 返回某个指定管理员操作记录
$actions->user; // 返回某条指定记录的管理员信息
$employee->records; // 返回某个指定雇员的签到记录
$employee->special_records(); // 以数组返回某个指定雇员的重要签到记录
$employee->month_report_data(); // 以数组返回某个指定雇员的月记录数据
$record->employee; // 返回某条指定签到记录的雇员信息
$absenceValidRecord->employee;// 返回某条指定请假记录的雇员信息
4. Controller
控制器
- Controller
- IndexController
- HomeController
- RouteController
- EmployeeController
- RecordController
- TimeNodeController
- ActionRecordController
- AbsenceValidRecordController
-
Auth
- RegisterController
- LoginController
- ForgetPasswordController
- ResetPasswordController
5. Middleware
中间件
- EncryptCookies
- RedirectIfAuthenticated
- TrimStrings
- VerifyCsrfToken
Listener
监听器
6. API
应用程序接口
- GET
/
: 返回所有记录界面 - POST
/
: 返回指定日期内记录界面
请求变量:
$start_time // 开始时间 $end_time // 结束时间
- GET
/home
: 返回普通管理员登录界面 - GET
/superhome
: 返回超级管理员登录界面
- GET
/valid
: 返回当日出勤情况界面 -
POST
/valid
: 返回指定某个日期的出勤情况界面请求变量:
$date // 请求日期
- GET
/report
: 返回月报表界面 -
POST
/report
: 返回某个指定月份的月报表界面请求变量:
$month // 格式为 "YYYY-MM" 的某个指定月份
- GET
/holidays
: 返回假期日历界面 -
GET
/holidays/dates
: 请求当前年的假期信息返回
JSON
数据:{ "year": "2017", "dates": [ { "date": "2017-08-01" }, { "date": "2017-08-02" }, { "date": "2017-08-03" }, { "date": "2017-08-04" }, { "date": "2017-08-05" }, { "date": "2017-08-06" } ] }
- POST
/holidays
: 请求指定月的假期信息
请求内容:
$month = "2017-07"
返回
JSON
数据:{ "month": "2017-07", "dates": [ { "date": "2017-07-01" }, { "date": "2017-07-02" }, { "date": "2017-07-03" }, { "date": "2017-07-04" }, { "date": "2017-07-05" }, { "date": "2017-07-06" } ] }
- PUT
/holidays
: 添加指定月的假期日期
请求变量:
$month = "2017-08"; // 格式为 YYYY-MM 的月份 $day = "1, 2, 3, 4, 5"; // 以英文逗号分隔的数字(在 1 到 $maxDay 之间)
- DELETE
/holidays
: 删除指定月的假期日期
请求
JSON
数据:$month = "2017-08"; // 格式为 YYYY-MM 的月份 $day = "1, 2, 3, 4, 5"; // 以英文逗号分隔的数字(在 1 到 $maxDay 之间)
- GET
/leave
: 返回请假界面 -
POST
/leave
: 请求指定日期的请假信息请求变量:
// Undeterminated
- PUT
/leave
: 添加请假信息
请求变量:
$start_date = '2017-08-03'; // 起始日期,格式为 YYYY-MM-DD $end_date = '2017-08-14'; // 结束日期, 格式为 YYYY-MM-DD (包括该日期) $employee_id = 21; // 雇员唯一 ID 号 $type = '病假'; // 请假类型 $note = '这是一条备注'; // 备注
- DELETE
/leave
: 删除指定请假信息
请求变量:
$start_date = '2017-08-10'; // 起始日期,格式为 YYYY-MM-DD $end_date = '2017-08-19'; // 结束日期, 格式为 YYYY-MM-DD (包括该日期) $employee_id = 21; // 雇员唯一 ID 号 $type = '病假'; // 请假类型
- GET
/timeedit
: 返回有效时间编辑界面 -
PUT
/timeedit/update
: 更改出勤时间设置请求变量:
$am_start_['day', 'hour', 'minute', 'second'] // 上班开始时间(时、分、秒) $am_end_['day', 'hour', 'minute', 'second'] // 上班结束时间(时、分、秒) $pm_start_['day', 'hour', 'minute', 'second'] // 下午开始时间(时、分、秒) $pm_end_['day', 'hour', 'minute', 'second'] // 下午结束时间(时、分、秒) $am_ddl_['day', 'hour', 'minute', 'second'] // 上午上班时间(时、分、秒) $am_late_ddl_['day', 'hour', 'minute', 'second'] // 上午迟到最晚时间(时、分、秒) $pm_ddl_['day', 'hour', 'minute', 'second'] // 下午上班时间(时、分、秒) $pm_early_ddl_['day', 'hour', 'minute', 'second'] // 下午早退最早时间(时、分、秒) $pm_away_['day', 'hour', 'minute', 'second'] // 下午下班时间(时、分、秒)
- GET
/employees/{work_number}
: 返回某个指定雇员信息 -
PUT
/employees/{work_number}/records/{id}
: 更改某个指定雇员的某条指定出勤记录请求变量:
$check_direction // 签到方向 $check_method // 签到方式(car || card || 请假) $card_gate // 刷卡机器编号(可为空) $note // 备注
- GET
/admin/actions
: 返回当前管理员操作信息
返回
JSON
数据:{ "current_page": 1, "data": [ { "id": 29, "user_id": 1, "action": "login", "timestamp": "2017-08-21 08:50:20" }, { "id": 28, "user_id": 1, "action": "logout", "timestamp": "2017-08-21 08:50:18" }, { "id": 27, "user_id": 1, "action": "login", "timestamp": "2017-08-21 08:41:59" } ], "from": 1, "last_page": 2, "next_page_url": "http://homestead.app/admin/actions?page=2", "path": "http://homestead.app/admin/actions", "per_page": 15, "prev_page_url": null, "to": 15, "total": 19 }
- GET
/admin/actions/{id}
(SuperAdmin ONLY): 返回某个指定管理员的操作信息 -
GET
/admin/users
(SuperAdmin ONLY): 返回所有管理员信息返回
JSON
数据:{ "current_page": 1, "data": [ { "id": 3, "name": "Foxwest", "email": "foxwest@403forbidden.website", "admin": 1, "phone_number": "6666666666", "created_at": "2017-08-02 21:31:24", "updated_at": "2017-08-02 21:31:24" }, { "id": 1, "name": "TripleZ", "email": "me@triplez.cn", "admin": 1, "phone_number": "888888888", "created_at": "2017-08-02 21:31:24", "updated_at": "2017-08-02 21:31:24" }, { "id": 2, "name": "test", "email": "test@triplez.cn", "admin": 0, "phone_number": "***********", "created_at": "2017-08-02 21:31:24", "updated_at": "2017-08-02 21:31:24" } ], "from": 1, "last_page": 1, "next_page_url": null, "path": "http://homestead.app/admin/users", "per_page": 15, "prev_page_url": null, "to": 3, "total": 3 }
- POST
/admin/resetpassword
: 重置管理员密码
请求变量:
$oldpassword // 旧密码 $password // 新密码 $password_confirmation // 确认密码
7. Database tables
数据表
symbol | means |
---|---|
* | primary key |
^ | foreign key |
7.1. table name: employees
columns:
ID* | name | gender | eamil | phone_number | work_title | department | car_number |
---|---|---|---|---|---|---|---|
1 | TripleZ | man | me@triplez.cn | 15240241051 | CEO | Develop Department | null |
7.2. table names: records
columns:
ID* | employee_id^ | check_direction(Y/N) | check_method | check_time |
---|---|---|---|---|
1 | 3 | 1 | card | 2017-07-21 13:22:13 |
2 | 3 | 0 | card | 2017-07-21 17:22:13 |
3 | 1 | 1 | car | 2017-07-22 07:22:13 |
4 | 1 | 0 | car | 2017-07-22 12:22:13 |
7.3. table name: users
columns:
ID* | name | password | admin(Y/N) | phone_number | created_at | updated_at | |
---|---|---|---|---|---|---|---|
1 | TripleZ | me@triplez.cn | ****** | 1 | 66666666 | ||
2 | test | test@triplez.cn | ****** | 0 | 88888888 |
7.4. table name: user_action_records
columns:
ID* | user_id^ | action | timestamp |
---|---|---|---|
1 | 1 | login | 2017-07-23 15:47:35 |
2 | 1 | logout | 2017-07-23 15:47:39 |
8. Migrations
- 2014_10_12_000000_create_xx_table
php artisan migrate:reset
php artisan migrate
9. Seeds
填充假数据
- UsersTableSeeder
- EmployeeSeeder
- RecordSeeder
- ActionRecordSeeder
- CarRecordSeeder
- CardRecordSeeder
- TimeNodeSeeder
- DailyCheckStatusSeeder
- HolidayDateSeeder
- AbsenceValidRecordSeeder
composer dump-autoload
php artisan db:seed
记得将需要 seed 的数据在 database/seeds/DatabaseSeeder.php
中注册。
10. Employee Status
雇员状态
- 正常
- 迟到
- 早退
- 迟到早退
- 缺勤
- 事假
- 病假
- 暂无
11. Important Timestamp
重要时间戳
- Global
$am_start = `3:00` // 上午记录开始时间
$am_end = `14:00` // 上午记录结束时间
$pm_start = `12:00` // 下午记录开始时间
$pm_end = `+1Day 3:00` // 下午记录结束时间
- AM
$am_ddl = `8:00` // 上午签到最晚时间
$am_late_ddl = `10:00` // 上午签到迟到最晚时间
- PM
$pm_ddl = `14:00` // 下午签到最晚时间
$pm_away = `18:00` // 下午离开最早时间
$pm_early_ddl = `16:00` // 下午离开早退最早时间
11.1. Default Timezone
默认时区
UTC+8
Asia/Shanghai
12. Scheduling task
计划任务
13. note
13.1. Error message:
$ php artisan migrate
Migration table created successfully.
[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was t
oo long; max key length is 1000 bytes (SQL: alter table `users` add unique
`users_email_unique`(`email`))
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was t
oo long; max key length is 1000 bytes
13.2. Solution
in file: config\database.php
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',
13.3. Change Server Timezone
sudo timedatectl set-timezone Asia/Shanghai
date
Add timezone when written data into database!
Caron::now('Asia/Shanghai')
ORCarbon::now('CST')
14. Source Code rewrite
14.1. modal position
demand:
make the modal box be at a right position
14.2. positionmethod
find the function 'Modal.prototype.adjustDialog' bootstrap.js(in this project is included in public/js/app.js),then replace them as the follow code:
Modal.prototype.adjustDialog = function () {
var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
this.$element.css({
paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
});
var $modal_dialog = $(this.$element[0]).find('.modal-dialog');
//get the view heigh
var clientHeight = (document.body.clientHeight < document.documentElement.clientHeight) ? document.body.clientHeight: document.documentElement.clientHeight;
//get dialog heigh
var dialogHeight = $modal_dialog.height();
//compute the distance to the top
var m_top = (clientHeight - dialogHeight)/3;
// console.log("clientHeight : " + clientHeight);
// console.log("dialogHeight : " + dialogHeight);
// console.log("m_top : " + m_top);
$modal_dialog.css({'margin': m_top + 'px auto'});
}
15. Web-view Layouts Design
15.1. general page
function:display all the records ordered by time stamp
demand:
- day/week/month
- export as excel
- correct records
- search by employee name
view structure:
_____________________________
| export |
|display option | search box |
|-----------------------------|
|records |
|record 1 correct|
|record 2 correct|
| . . |
| . . |
|_____________________________|
15.2. graph page
function: build a calendar, and display each employee duty status.
demand:
- a calendar can show as day/week/month.
- mark up the time/date that has record
view structure:
_____________________________
| |
|display option | search box |
|-----------------------------|
|calendar option |
| . . |
| . . |
| . calendar . |
| . . |
|_____________________________|
15.3. valid records
function: display all records by day.
demand:
- display single record(included in and out) of each employee devided by day
- should include arrive&leave time,also,a status indicate valid(invalid) should be shown
view structure:
_____________________________
| export |
| | search box | |
|-----------------------------|
|records status |
|record 1 Y correct|
|record 2 Y correct|
| . . |
| pagination by day |
|_____________________________|
15.4. holiday page(option)
function: mark up holiday.
demand:
- decide which day has no duty
- mark up the time/date in the calendar view
view structure:
_____________________________
| |
| ???????????? |
|-----------------------------|
|calendar option |
| . . |
| . . |
| . calendar . |
| . . |
|_____________________________|
15.5. timeedit page
function:define legal time
demand:
- define valid time of records
view structure:
_____________________________
| |
| ???????????? |
|-----------------------------|
| |
| . . |
| . post form . |
| . . |
| . . |
|_____________________________|
Copyright
版权信息
Copyright (c) 2017 TripleZ DoubleMice