update gán lịch trình cho nhân viên

This commit is contained in:
dongpd 2020-10-14 14:00:01 +07:00
parent 620dfc75c2
commit ed061f5994
16 changed files with 2626 additions and 100 deletions

File diff suppressed because it is too large Load Diff

23
assets/AssignAsset.php Normal file
View File

@ -0,0 +1,23 @@
<?php
namespace app\assets;
use yii\web\AssetBundle;
class AssignAsset extends AssetBundle {
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [
];
public $js = [
'js/assign.js'
];
public $depends = [
'yii\web\YiiAsset',
'app\assets\AppAsset',
// 'yii\jui\JuiAsset',
'yii\bootstrap\BootstrapAsset',
];
}

View File

@ -0,0 +1,91 @@
<?php
namespace app\controllers;
use Yii;
use app\models\Department;
use app\models\Staff;
use app\models\Schedule;
use app\models\Door;
use app\models\Device;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\helpers\Html;
use yii\helpers\Url;
/**
* DeviceController implements the CRUD actions for Device model.
*/
class AssignController extends Controller {
public function init() {
parent::init();
if (Yii::$app->user->isGuest)
return $this->redirect(['/site/login']);
}
/**
* {@inheritdoc}
*/
public function behaviors() {
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
public function actionIndex() {
$this->view->title = 'Cấp quyền truy cập';
return $this->render('index', [
"company" => Department::findOne(1),
"scheduleArray" => Schedule::scheduleArray(),
"doorLists" => Door::find()->all(),
"deviceArray" => Device::deviceArray()
]);
}
public function actionStaff($id) {
if (Yii::$app->request->isAjax) {
$model = new Department();
$lsDepartment = $model->departmentChilds(intval($id));
return $this->renderPartial("staff", [
"departmentArray" => Department::departmentArray(),
"scheduleArray" => Schedule::scheduleArray(),
"staffs" => Staff::find()->andWhere(['IN', 'department_id', $lsDepartment])->all()
]);
}
}
public function actionSearchStaff() {
if (Yii::$app->request->post()) {
$post = Yii::$app->request->post();
return $this->renderPartial("staff", [
"departmentArray" => Department::departmentArray(),
"scheduleArray" => Schedule::scheduleArray(),
"staffs" => Staff::find()->andWhere(['OR', ["LIKE", "name", $post['key']], ["LIKE", "code", $post['key']]])->all()
]);
}
}
public function actionSetSchedule() {
if (Yii::$app->request->post()) {
$post = Yii::$app->request->post();
Staff::updateAll(["schedule_id" => $post["schedule"], "door_access" => json_encode($post["doors"])], ["IN", "id", $post["staffs"]]);
$doors = [];
foreach ($post["doors"] as $key => $value) {
$doors[] = Door::findOne($value)->name;
}
Yii::$app->response->format = "json";
return [
"schedule" => Schedule::findOne($post['schedule'])->name,
"doors" => implode(", ", $doors)
];
}
}
}

View File

@ -86,7 +86,7 @@ class DepartmentController extends Controller {
$oldCode = $model->code; $oldCode = $model->code;
$model->name = $data["Name"]; $model->name = $data["Name"];
$model->code = $data["Code"]; $model->code = $data["Code"];
$model->pid = $data["Pid"]; $model->pid = $data["Pid"] !== "" ? $data["Pid"] : 0;
$model->modified_at = time(); $model->modified_at = time();
if ($model->save()) { if ($model->save()) {
Department::updateAll(["pid" => $data["Code"]], ["pid" => $oldCode]); Department::updateAll(["pid" => $data["Code"]], ["pid" => $oldCode]);

View File

@ -112,4 +112,27 @@ class Department extends \yii\db\ActiveRecord {
return ["status" => true, "description" => ""]; return ["status" => true, "description" => ""];
} }
public function getChilds() {
return $this->find()->andWhere(['pid' => $this->code])->all();
}
public function getCountStaff() {
$childs = $this->childs;
$totals = 0;
foreach ($childs as $key => $value) {
$totals += $value->countStaff;
}
$totals += Staff::find()->andWhere(['department_id' => $this->code])->count();
return $totals;
}
public function departmentChilds($id, &$childs = []) {
$childs[] = $id;
$ls = $this->find()->andWhere(['pid' => $id])->all();
foreach ($ls as $key => $value) {
$this->departmentChilds($value->code, $childs);
}
return $childs;
}
} }

View File

@ -117,4 +117,13 @@ class Device extends \yii\db\ActiveRecord {
return $results; return $results;
} }
public static function deviceArray() {
$lists = self::find()->all();
$results = [];
foreach ($lists as $key => $value) {
$results[$value->id] = $value->name;
}
return $results;
}
} }

View File

@ -150,4 +150,13 @@ class Schedule extends \yii\db\ActiveRecord {
return hexdec("0" . $front . "0" . $back); return hexdec("0" . $front . "0" . $back);
} }
public static function scheduleArray() {
$lists = self::find()->all();
$results = [];
foreach ($lists as $key => $value) {
$results[$value->id] = $value->name;
}
return $results;
}
} }

View File

@ -22,6 +22,7 @@ use Yii;
* @property int $modified_at * @property int $modified_at
* @property int $card_register_time * @property int $card_register_time
* @property int $schedule_id * @property int $schedule_id
* @property string $door_access
*/ */
class Staff extends \yii\db\ActiveRecord { class Staff extends \yii\db\ActiveRecord {
@ -39,7 +40,7 @@ class Staff extends \yii\db\ActiveRecord {
return [ return [
[['code', 'name', 'gender'], 'required'], [['code', 'name', 'gender'], 'required'],
[['code', 'card_number', 'department_id', 'birthday', 'date_in', 'created_at', 'modified_at', 'card_register_time', 'schedule_id'], 'integer'], [['code', 'card_number', 'department_id', 'birthday', 'date_in', 'created_at', 'modified_at', 'card_register_time', 'schedule_id'], 'integer'],
[['address'], 'string'], [['address', 'door_access'], 'string'],
[['name', 'email'], 'string', 'max' => 100], [['name', 'email'], 'string', 'max' => 100],
[['gender'], 'string', 'max' => 10], [['gender'], 'string', 'max' => 10],
[['phone'], 'string', 'max' => 20], [['phone'], 'string', 'max' => 20],
@ -121,4 +122,15 @@ class Staff extends \yii\db\ActiveRecord {
return $results; return $results;
} }
public function getDoors() {
$doors = [];
if ($this->door_access) {
$ls = json_decode($this->door_access, true);
foreach ($ls as $key => $value) {
$doors[] = Door::findOne($value)->name;
}
}
return implode(", ", $doors);
}
} }

View File

@ -30,7 +30,7 @@ use yii\widgets\ActiveForm;
Thiết bị Thiết bị
</a> </a>
</li> </li>
<li class="<?php if (in_array($this->context->id, ['schedule'])) echo "active"; ?>"> <li class="<?php if (in_array($this->context->id, ['schedule', 'assign'])) echo "active"; ?>">
<a href="<?php echo \yii\helpers\Url::to(['/schedule']); ?>"> <a href="<?php echo \yii\helpers\Url::to(['/schedule']); ?>">
Kiểm soát truy cập Kiểm soát truy cập
</a> </a>

View File

@ -27,10 +27,10 @@
['label' => 'Tìm kiếm thiết bị', 'url' => ['/device/search'], 'icon' => 'search'] ['label' => 'Tìm kiếm thiết bị', 'url' => ['/device/search'], 'icon' => 'search']
]; ];
} }
if (in_array($this->context->id, ['schedule'])) { if (in_array($this->context->id, ['schedule', 'assign'])) {
$items = [ $items = [
['label' => 'Lịch trình', 'url' => ['/schedule'], 'icon' => 'calendar'], ['label' => 'Lịch trình', 'url' => ['/schedule'], 'icon' => 'calendar'],
['label' => 'Cấp quyền truy cập', 'url' => ['/device'], 'icon' => 'cogs'] ['label' => 'Cấp quyền truy cập', 'url' => ['/assign'], 'icon' => 'cogs']
]; ];
} }
?> ?>

133
views/assign/index.tpl Normal file
View File

@ -0,0 +1,133 @@
{extends file=$smarty.current_dir|cat:'/../extends.tpl'}
{use class="yii\helpers\Url"}
{use class="yii\grid\GridView"}
{use class="yii\widgets\Pjax" type="block"}
{use class="app\assets\AssignAsset"}
{AssignAsset::register($this)|void}
{block name='content'}
<style>
.table-staff-schedule{
font-size: 13px;
}
.table-staff-schedule th,td{
padding: 3px !important;
}
.department-schedule-active{
background: #cecece;
}
#form-special-schedule .input-group-addon{
width: 120px !important;
}
#schedule-search-staff{
height: 700px;
background: #cecece;
overflow-y: scroll;
}
#schedule-search-staff::-webkit-scrollbar {
display: none;
}
#create-schedule-main{
border-left: 1px solid #cecece;
margin-bottom: -10px;
margin-top: -10px;
padding: 10px;
}
.assign-index{
padding: 10px;
}
</style>
<div class="assign-index">
<div class="row">
<div class="col-md-3">
<fieldset id='schedule-department-tree' style="overflow-y: scroll;">
<legend>Chọn phòng ban</legend>
<div style="cursor: pointer;">
<i class="fa fa-minus-square-o" onclick="schedule.tree(this);" data="1" data-stt="true"></i>
<b class="department-schedule" onclick="schedule.chooseDepartment(this);" data-href='{yii\helpers\Url::to(['/assign/staff','id'=> 1])}'>
{$company->name}
{$staff=$company->countStaff}
{if $staff>0}
[<span class="text-red">{$staff}</span>]
{/if}
</b>
<div id="sub-department-schedule-1" style="padding-left: 20px;">
{\app\widgets\ScheduleDepartment::widget(["pid"=>1])}
</div>
</div>
</fieldset>
</div>
<div class="col-md-6" id='create-schedule-main'>
<fieldset>
<legend>Danh sách nhân viên</legend>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<div class="input-group">
<input type='text' class="form-control" onchange="schedule.searchStaff(this);" data-href='{yii\helpers\Url::to(['/assign/search-staff'])}' name='ScheduleSearchStaff' placeholder="Tìm kiếm nhân viên ...">
<div class="input-group-btn">
<button class="btn btn-primary">
<i class="fa fa-search"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<div id='schedule-search-staff'>
<table class="table table-bordered table-striped table-staff-schedule">
<thead>
<tr class="info">
<th style="width: 5%;"></th>
<th style="width: 20%;">Mã nhân viên</th>
<th>Tên nhân viên</th>
<th>Phòng ban</th>
<th>Lịch trình</th>
<th>Cửa</th>
</tr>
</thead>
</table>
</div>
</fieldset>
</div>
<div class="col-md-3">
<fieldset id='schedule-door-lists' style="overflow-y: scroll;">
<legend>Cấp quyền truy cập</legend>
<div class="input-group">
<div class="input-group-addon">Chọn lịch trình</div>
<select class="form-control" name="ScheduleLists">
{html_options options=$scheduleArray}
</select>
<div class="input-group-btn">
<button class="btn btn-default" onclick="schedule.setSchedule(this);" data-href="{yii\helpers\Url::to(['/assign/set-schedule'])}">
<i class="fa fa-arrow-right"></i> Thực hiện
</button>
</div>
</div>
<br>
<table class="table table-bordered table-striped table-staff-schedule" style="background: #fff;">
<thead>
<tr class="info">
<th style="width: 10%;" class="text-center">
<input type='checkbox' value='0' class='checkbox-door-schedule' id='checkall-door-schedule'>
</th>
<th>Cửa</th>
<th>Thiết bị</th>
</tr>
</thead>
<tbody>
{foreach from=$doorLists item=door}
<tr>
<td class="text-center">
<input type='checkbox' value='{$door->id}' name='checkbox-door-schedule' class='checkbox-door-schedule'>
</td>
<td>{$door->name}</td>
<td>{$deviceArray[$door->device_id]}</td>
</tr>
{/foreach}
</tbody>
</table>
</fieldset>
</div>
</div>
</div>
{/block}

41
views/assign/staff.tpl Normal file
View File

@ -0,0 +1,41 @@
<style>
.choose-staff-schedule{
cursor: pointer;
}
.choose-staff-schedule:hover{
background: #cecece;
}
</style>
<div>
Danh sách có <b class="text-red">{count($staffs)}</b> nhân viên.
</div>
<table class="table table-bordered table-striped table-staff-schedule" style="background: #fff;">
<thead>
<tr class="info">
<th style="width: 5%;" class="text-center">
<input type='checkbox' value='0' class='checkbox-staff-schedule' id='checkall-staff-schedule'>
</th>
<th style="width: 20%;">Mã nhân viên</th>
<th>Tên nhân viên</th>
<th>Phòng ban</th>
<th>Lịch trình</th>
<th>Cửa</th>
</tr>
</thead>
<tbody>
{foreach from=$staffs item=s}
<tr>
<td class="text-center">
<input type='checkbox' value='{$s->id}' name='checkbox-staff-schedule' class='checkbox-staff-schedule'>
</td>
<td>{$s->code}</td>
<td class="choose-staff-schedule">
{$s->name}
</td>
<td>{$departmentArray[$s->department_id]|default:""}</td>
<td id="schedule-staff-results-{$s->id}">{$scheduleArray[$s->schedule_id]|default:""}</td>
<td id="schedule-door-results-{$s->id}">{$s->doors}</td>
</tr>
{/foreach}
</tbody>
</table>

View File

@ -268,3 +268,18 @@ table > tbody > tr.success >td>a {
.alert{ .alert{
padding: 5px; padding: 5px;
} }
fieldset {
border: 1px groove #ddd !important;
padding: 0 5px 5px 5px !important;
margin: 0 0 1.5em 0 !important;
-webkit-box-shadow: 0px 0px 0px 0px #000;
box-shadow: 0px 0px 0px 0px #000;
}
legend {
width:inherit;
font-size: 14px;
border-bottom:none;
margin-bottom: 5px !important;
}

103
web/js/assign.js Normal file
View File

@ -0,0 +1,103 @@
$(function () {
$("#schedule-department-tree").height($("#create-schedule-main").height() - 28);
$("#schedule-door-lists").height($("#create-schedule-main").height() - 28);
common.checkboxInit("door-schedule");
});
var schedule = {};
schedule.tree = function (e) {
var stt = $(e).attr("data-stt");
if (stt === "true") {
$(e).removeClass("fa-minus-square-o").addClass("fa-plus-square-o").attr("data-stt", "false");
$("#sub-department-schedule-" + $(e).attr("data")).addClass("hidden");
} else {
$(e).removeClass("fa-plus-square-o").addClass("fa-minus-square-o").attr("data-stt", "true");
$("#sub-department-schedule-" + $(e).attr("data")).removeClass("hidden");
}
};
schedule.chooseDepartment = function (e) {
common.modalBlock(true);
$.ajax({
url: $(e).attr("data-href"),
type: 'POST',
success: function (data) {
common.modalBlock(false);
$("#schedule-search-staff").html(data);
$(".department-schedule").removeClass("department-schedule-active");
$(e).addClass("department-schedule-active");
common.checkboxInit("staff-schedule");
},
error: function (jqXHR, textStatus, errorThrown) {
common.modalBlock(false);
common.ajaxError();
}
});
};
schedule.searchStaff = function (e) {
common.modalBlock(true);
$.ajax({
url: $(e).attr("data-href"),
type: 'POST',
data: {
key: $(e).val()
},
success: function (data) {
common.modalBlock(false);
$("#schedule-search-staff").html(data);
$(".department-schedule").removeClass("department-schedule-active");
common.checkboxInit("staff-schedule");
},
error: function (jqXHR, textStatus, errorThrown) {
common.modalBlock(false);
common.ajaxError();
}
});
};
schedule.setSchedule = function (e) {
var staffs = [];
$.each($("input[name='checkbox-staff-schedule']:checked"), function () {
if ($(this).val() !== "0") {
staffs.push($(this).val());
}
});
if (staffs.length == 0) {
alert("Hãy chọn nhân viên");
return;
}
var doors = [];
$.each($("input[name='checkbox-door-schedule']:checked"), function () {
if ($(this).val() !== "0") {
doors.push($(this).val());
}
});
if (doors.length == 0) {
alert("Hãy chọn cửa");
return;
}
common.modalBlock(true);
$.ajax({
url: $(e).attr("data-href"),
type: 'POST',
data: {
staffs: staffs,
doors: doors,
schedule: $("select[name='ScheduleLists']").val()
},
success: function (data) {
common.modalBlock(false);
notification.success("Đã lưu thông tin", 1000);
$.each($("input[name='checkbox-staff-schedule']:checked"), function () {
if ($(this).val() !== "0") {
$("#schedule-staff-results-" + $(this).val()).html(data.schedule);
$("#schedule-door-results-" + $(this).val()).html(data.doors);
}
});
},
error: function (jqXHR, textStatus, errorThrown) {
common.modalBlock(false);
common.ajaxError();
}
});
};

View File

@ -0,0 +1,22 @@
<?php
namespace app\widgets;
use yii\base\Widget;
class ScheduleDepartment extends Widget {
public $pid;
public function init() {
parent::init();
}
public function run() {
return $this->render("schedule-department", [
"lists" => \app\models\Department::find()->andWhere(['pid' => $this->pid])->all()
]);
}
}

View File

@ -0,0 +1,15 @@
{foreach from=$lists item=l}
<div style="cursor: pointer;">
<i class="fa fa-minus-square-o" onclick="schedule.tree(this);" data="{$l->code}" data-stt="true"></i>
<span class="department-schedule" onclick="schedule.chooseDepartment(this);" data-href='{yii\helpers\Url::to(['/assign/staff','id'=>$l->code])}'>
{$l->name}
{$staff=$l->countStaff}
{if $staff>0}
[<span class="text-red">{$staff}</span>]
{/if}
</span>
<div id="sub-department-schedule-{$l->code}" style="padding-left: 20px;">
{\app\widgets\ScheduleDepartment::widget(["pid"=>$l->code])}
</div>
</div>
{/foreach}