cập nhật tính năng quản trị phòng ban
This commit is contained in:
parent
586be80cf6
commit
2d15fc1c14
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
/runtime
|
||||
/web/assets
|
||||
/web/data/uploads
|
||||
/vendor/
|
23
assets/DepartmentAsset.php
Normal file
23
assets/DepartmentAsset.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace app\assets;
|
||||
|
||||
use yii\web\AssetBundle;
|
||||
|
||||
class DepartmentAsset extends AssetBundle {
|
||||
|
||||
public $basePath = '@webroot';
|
||||
public $baseUrl = '@web';
|
||||
public $css = [
|
||||
];
|
||||
public $js = [
|
||||
'js/department.js'
|
||||
];
|
||||
public $depends = [
|
||||
'yii\web\YiiAsset',
|
||||
'app\assets\AppAsset',
|
||||
// 'yii\jui\JuiAsset',
|
||||
'yii\bootstrap\BootstrapAsset',
|
||||
];
|
||||
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
return [
|
||||
'class' => 'yii\db\Connection',
|
||||
'dsn' => 'mysql:host=localhost;dbname=traffic',
|
||||
'dsn' => 'mysql:host=localhost;dbname=access_control',
|
||||
'username' => 'root',
|
||||
'password' => '',
|
||||
'charset' => 'utf8',
|
||||
|
|
236
controllers/DepartmentController.php
Normal file
236
controllers/DepartmentController.php
Normal file
|
@ -0,0 +1,236 @@
|
|||
<?php
|
||||
|
||||
namespace app\controllers;
|
||||
|
||||
use Yii;
|
||||
use app\models\Department;
|
||||
use app\models\DepartmentSearch;
|
||||
use app\models\LogsDepartment;
|
||||
use app\models\common;
|
||||
use yii\web\Controller;
|
||||
use yii\web\NotFoundHttpException;
|
||||
use yii\filters\VerbFilter;
|
||||
use yii\helpers\Html;
|
||||
use yii\helpers\Url;
|
||||
|
||||
/**
|
||||
* DepartmentController implements the CRUD actions for Department model.
|
||||
*/
|
||||
class DepartmentController 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 = 'Phòng ban';
|
||||
$searchModel = new DepartmentSearch();
|
||||
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
|
||||
|
||||
return $this->render('index', [
|
||||
'searchModel' => $searchModel,
|
||||
'dataProvider' => $dataProvider,
|
||||
"departmentArray" => Department::departmentArray()
|
||||
]);
|
||||
}
|
||||
|
||||
public function actionCreate() {
|
||||
$model = new Department();
|
||||
Yii::$app->response->format = "json";
|
||||
if (Yii::$app->request->post()) {
|
||||
$data = Yii::$app->request->post();
|
||||
$check = Department::findOne(['code' => $data['Code']]);
|
||||
if ($check)
|
||||
return ["status" => false, "type" => "code"];
|
||||
|
||||
if ($model->create($data)) {
|
||||
Department::insertSystemLogs(["action" => "insert", "description" => "Thêm mới phòng ban: " . $data["Name"]]);
|
||||
return ["status" => true];
|
||||
} else
|
||||
return ["status" => false, "type" => "error"];
|
||||
} else {
|
||||
return [
|
||||
"title" => Html::tag("i", "", ["class" => "fa fa-plus-square"]) . " Thêm",
|
||||
"form" => $this->renderPartial("form", [
|
||||
"model" => $model,
|
||||
"url" => Url::to(["create"]),
|
||||
"departmentArray" => Department::departmentArray()
|
||||
])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function actionUpdate($id) {
|
||||
$model = $this->findModel($id);
|
||||
Yii::$app->response->format = "json";
|
||||
if (Yii::$app->request->post()) {
|
||||
$data = Yii::$app->request->post();
|
||||
$check = Department::findOne(['code' => $data['Code']]);
|
||||
if ($check && $check->id != $id)
|
||||
return ["status" => false, "type" => "code"];
|
||||
$oldCode = $model->code;
|
||||
$model->name = $data["Name"];
|
||||
$model->code = $data["Code"];
|
||||
$model->pid = $data["Pid"];
|
||||
$model->modified_at = time();
|
||||
if ($model->save()) {
|
||||
Department::updateAll(["pid" => $data["Code"]], ["pid" => $oldCode]);
|
||||
Department::insertSystemLogs(["action" => "update", "description" => "Chỉnh sửa phòng ban: " . $data["Name"]]);
|
||||
return ["status" => true];
|
||||
} else
|
||||
return ["status" => false, "type" => "error"];
|
||||
} else {
|
||||
return [
|
||||
"title" => Html::tag("i", "", ["class" => "fa fa-edit"]) . " Tùy chỉnh",
|
||||
"form" => $this->renderPartial("form", [
|
||||
"model" => $model,
|
||||
"url" => Url::to(["update", "id" => $id]),
|
||||
"departmentArray" => Department::departmentArray()
|
||||
])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function actionDelete() {
|
||||
if (Yii::$app->request->post()) {
|
||||
$lists = Yii::$app->request->post("lists");
|
||||
foreach ($lists as $key => $value) {
|
||||
Department::deleteDepartment($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function findModel($id) {
|
||||
if (($model = Department::findOne($id)) !== null) {
|
||||
return $model;
|
||||
}
|
||||
|
||||
throw new NotFoundHttpException('The requested page does not exist.');
|
||||
}
|
||||
|
||||
public function actionExport() {
|
||||
$objPHPExcel = new \PHPExcel();
|
||||
$objPHPExcel->setActiveSheetIndex(0);
|
||||
$toExcelFile[] = ["Mã phòng ban", "Tên phòng ban", "Trực thuộc"];
|
||||
$departments = Department::find()->all();
|
||||
$departmentArray = Department::departmentArray();
|
||||
foreach ($departments as $k => $v) {
|
||||
$ExportData[] = $v->code;
|
||||
$ExportData[] = $v->name;
|
||||
$ExportData[] = isset($departmentArray[$v->pid]) ? $departmentArray[$v->pid] : "";
|
||||
$toExcelFile[] = $ExportData;
|
||||
unset($ExportData);
|
||||
}
|
||||
$totals = count($departments) + 1;
|
||||
$activeSheet = $objPHPExcel->getActiveSheet();
|
||||
$activeSheet->getColumnDimension('A')->setWidth(15);
|
||||
$activeSheet->getColumnDimension('B')->setWidth(50);
|
||||
$activeSheet->getColumnDimension('C')->setWidth(50);
|
||||
$activeSheet->getStyle("A1:C" . $totals)->getFont()->setName('Time New Roman')->setSize(10);
|
||||
$activeSheet->getStyle("A1:C1")->applyFromArray([
|
||||
'fill' => array(
|
||||
'type' => \PHPExcel_Style_Fill::FILL_SOLID,
|
||||
'color' => array('rgb' => '7ac3ec')
|
||||
)
|
||||
]);
|
||||
$rowCount = 1;
|
||||
for ($i = 0; $i < count($toExcelFile); $i++) {
|
||||
$column = 'A';
|
||||
$row = $toExcelFile[$i];
|
||||
for ($j = 0; $j < count($row); $j++) {
|
||||
if (!isset($row[$j]))
|
||||
$value = NULL;
|
||||
elseif ($row[$j] != "")
|
||||
$value = strip_tags($row[$j]);
|
||||
else
|
||||
$value = "";
|
||||
$activeSheet->setCellValue($column . $rowCount, $value);
|
||||
$column = chr(ord($column) + 1);
|
||||
}
|
||||
$rowCount++;
|
||||
}
|
||||
$activeSheet->getStyle("A1:C" . $totals)->applyFromArray([
|
||||
'alignment' => [
|
||||
'vertical' => \PHPExcel_Style_Alignment::VERTICAL_CENTER,
|
||||
],
|
||||
'borders' => [
|
||||
'allborders' => [
|
||||
'style' => \PHPExcel_Style_Border::BORDER_THIN
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
|
||||
ob_end_clean();
|
||||
header('Content-type: application/vnd.ms-excel');
|
||||
header('Content-Disposition: attachment; filename="department_' . date("YmdHis") . '.xlsx"');
|
||||
header('Cache-Control: max-age=0');
|
||||
$objWriter->save('php://output');
|
||||
exit();
|
||||
}
|
||||
|
||||
public function actionUpload() {
|
||||
if (Yii::$app->request->post()) {
|
||||
$common = new common();
|
||||
$fileUploads = $common->UploadFile("file", ["XLS", "XLSX"], "excel");
|
||||
$file_type = \PHPExcel_IOFactory::identify($fileUploads);
|
||||
$objReader = \PHPExcel_IOFactory::createReader($file_type);
|
||||
$objPHPExcel = $objReader->load($fileUploads);
|
||||
$sheet_data = $objPHPExcel->getActiveSheet()->toArray(null, true, true, true);
|
||||
Yii::$app->response->format = 'json';
|
||||
return [
|
||||
"title" => Html::tag("i", "", ["class" => "fa fa-upload"]) . " Nhập",
|
||||
"form" => $this->renderPartial("import", [
|
||||
"data" => $sheet_data,
|
||||
"model" => new Department()
|
||||
])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function actionImport() {
|
||||
if (Yii::$app->request->post()) {
|
||||
$post = Yii::$app->request->post("lists");
|
||||
$datas = [];
|
||||
foreach ($post as $key => $value) {
|
||||
$val = json_decode($value, true);
|
||||
$parent = Department::findOne(["name" => $val["C"]]);
|
||||
$datas[] = [$val["A"], $parent ? $parent->code : 1, $val["B"], time(), time()];
|
||||
}
|
||||
$model = new Department();
|
||||
$model->multiCreate($datas);
|
||||
Department::insertSystemLogs(["action" => "import", "description" => "Nhập dữ liệu: " . count($post) . " phòng ban mới"]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public function actionLogs() {
|
||||
if (Yii::$app->request->isAjax) {
|
||||
Yii::$app->response->format = "json";
|
||||
return [
|
||||
"title" => Html::tag("i", "", ["class" => "fa fa-file"]) . " Ghi nhận hệ thống",
|
||||
"form" => $this->renderPartial("logs", [
|
||||
"logs" => LogsDepartment::find()->orderBy(['time' => SORT_DESC])->limit(30)->all(),
|
||||
"userArray" => \app\models\User::userArray()
|
||||
])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
36
helpers/DepartmentGrid.php
Normal file
36
helpers/DepartmentGrid.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace app\helpers;
|
||||
|
||||
use yii\helpers\Html;
|
||||
use yii\helpers\Url;
|
||||
|
||||
class DepartmentGrid extends CommonGrid {
|
||||
|
||||
public static function pid($departmentArray) {
|
||||
return function($model) use ($departmentArray) {
|
||||
return isset($departmentArray[$model->pid]) ? $departmentArray[$model->pid] : "";
|
||||
};
|
||||
}
|
||||
|
||||
public static function checkbox() {
|
||||
return function($model) {
|
||||
if ($model->id == 1)
|
||||
return "";
|
||||
return "<input type='checkbox' value='{$model->id}' name='checkbox-department' class='checkbox-department'>";
|
||||
};
|
||||
}
|
||||
|
||||
public static function rows() {
|
||||
return function($model, $index, $widget, $grid) {
|
||||
return [
|
||||
"onclick" => "common.form(this, 'department');",
|
||||
"style" => "cursor: pointer;",
|
||||
"data" => [
|
||||
"href" => Url::to(["update", "id" => $model->id])
|
||||
]
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
}
|
111
models/Department.php
Normal file
111
models/Department.php
Normal file
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
namespace app\models;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* This is the model class for table "department".
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $code
|
||||
* @property int $pid
|
||||
* @property string $name
|
||||
* @property int $created_at
|
||||
* @property int $modified_at
|
||||
*/
|
||||
class Department extends \yii\db\ActiveRecord {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function tableName() {
|
||||
return 'department';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rules() {
|
||||
return [
|
||||
[['code', 'pid', 'name', 'created_at', 'modified_at'], 'required'],
|
||||
[['code', 'pid', 'created_at', 'modified_at'], 'integer'],
|
||||
[['name'], 'string', 'max' => 100],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function attributeLabels() {
|
||||
return [
|
||||
'id' => 'ID',
|
||||
'code' => 'Mã phòng ban',
|
||||
'pid' => 'Trực thuộc',
|
||||
'name' => 'Tên phòng ban',
|
||||
'created_at' => 'Thời gian tạo',
|
||||
'modified_at' => 'Thời gian sửa',
|
||||
];
|
||||
}
|
||||
|
||||
public static function departmentArray() {
|
||||
$lists = self::find()->all();
|
||||
$results = [];
|
||||
foreach ($lists as $key => $value) {
|
||||
$results[$value->code] = $value->name;
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function create($data) {
|
||||
$r = $this->load([
|
||||
"code" => $data["Code"],
|
||||
"pid" => $data["Pid"],
|
||||
"name" => $data["Name"],
|
||||
"created_at" => time(),
|
||||
"modified_at" => time()
|
||||
], '');
|
||||
if ($r) {
|
||||
try {
|
||||
$this->save();
|
||||
return $this->id;
|
||||
} catch (\Exception $ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function multiCreate($datas) {
|
||||
$field = ['code', 'pid', 'name', 'created_at', 'modified_at'];
|
||||
static::getDb()->createCommand()->batchInsert($this->tableName(), $field, $datas)->execute();
|
||||
return;
|
||||
}
|
||||
|
||||
public static function deleteDepartment($id) {
|
||||
if ($id == 1)
|
||||
return;
|
||||
$model = self::findOne($id);
|
||||
if ($model) {
|
||||
$childs = self::find()->andWhere(["pid" => $model->code])->all();
|
||||
foreach ($childs as $key => $value) {
|
||||
self::deleteDepartment($value->id);
|
||||
}
|
||||
$model->delete();
|
||||
self::insertSystemLogs(["action" => "delete", "description" => "Xóa phòng ban: " . $model->name]);
|
||||
}
|
||||
}
|
||||
|
||||
public static function insertSystemLogs($data) {
|
||||
$model = new LogsDepartment();
|
||||
return $model->create($data);
|
||||
}
|
||||
|
||||
public function checkStatusImport($data) {
|
||||
if ($this->findOne(["code" => $data["A"]]))
|
||||
return ["status" => false, "description" => "Mã phòng ban đã tồn tại"];
|
||||
if (!$this->findOne(["name" => $data["C"]]))
|
||||
return ["status" => true, "description" => "Phòng ban trực thuộc không tồn tại"];
|
||||
return ["status" => true, "description" => ""];
|
||||
}
|
||||
|
||||
}
|
71
models/DepartmentSearch.php
Normal file
71
models/DepartmentSearch.php
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
namespace app\models;
|
||||
|
||||
use Yii;
|
||||
use yii\base\Model;
|
||||
use yii\data\ActiveDataProvider;
|
||||
use app\models\Department;
|
||||
|
||||
/**
|
||||
* DepartmentSearch represents the model behind the search form of `app\models\Department`.
|
||||
*/
|
||||
class DepartmentSearch extends Department {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rules() {
|
||||
return [
|
||||
[['id', 'code', 'pid'], 'integer'],
|
||||
[['name'], 'safe'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function scenarios() {
|
||||
// bypass scenarios() implementation in the parent class
|
||||
return Model::scenarios();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates data provider instance with search query applied
|
||||
*
|
||||
* @param array $params
|
||||
*
|
||||
* @return ActiveDataProvider
|
||||
*/
|
||||
public function search($params) {
|
||||
$query = Department::find();
|
||||
|
||||
// add conditions that should always apply here
|
||||
|
||||
$dataProvider = new ActiveDataProvider([
|
||||
'query' => $query,
|
||||
]);
|
||||
|
||||
$this->load($params);
|
||||
|
||||
if (!$this->validate()) {
|
||||
// uncomment the following line if you do not want to return any records when validation fails
|
||||
// $query->where('0=1');
|
||||
return $dataProvider;
|
||||
}
|
||||
|
||||
// grid filtering conditions
|
||||
$query->andFilterWhere([
|
||||
'id' => $this->id,
|
||||
'code' => $this->code,
|
||||
'pid' => $this->pid,
|
||||
'created_at' => $this->created_at,
|
||||
'modified_at' => $this->modified_at,
|
||||
]);
|
||||
|
||||
$query->andFilterWhere(['like', 'name', $this->name]);
|
||||
|
||||
return $dataProvider;
|
||||
}
|
||||
|
||||
}
|
67
models/LogsDepartment.php
Normal file
67
models/LogsDepartment.php
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace app\models;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* This is the model class for table "logs_department".
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $user_id
|
||||
* @property int $time
|
||||
* @property string $action
|
||||
* @property string $description
|
||||
*/
|
||||
class LogsDepartment extends \yii\db\ActiveRecord {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function tableName() {
|
||||
return 'logs_department';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rules() {
|
||||
return [
|
||||
[['user_id', 'time', 'action', 'description'], 'required'],
|
||||
[['user_id', 'time'], 'integer'],
|
||||
[['description'], 'string'],
|
||||
[['action'], 'string', 'max' => 10],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function attributeLabels() {
|
||||
return [
|
||||
'id' => 'ID',
|
||||
'user_id' => 'User ID',
|
||||
'time' => 'Time',
|
||||
'action' => 'Action',
|
||||
'description' => 'Description',
|
||||
];
|
||||
}
|
||||
|
||||
public function create($data) {
|
||||
$r = $this->load([
|
||||
'user_id' => Yii::$app->user->id,
|
||||
'time' => time(),
|
||||
'action' => $data['action'],
|
||||
'description' => $data['description']
|
||||
], '');
|
||||
if ($r) {
|
||||
try {
|
||||
$this->save();
|
||||
return $this->id;
|
||||
} catch (\Exception $ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -201,4 +201,13 @@ class User extends ActiveRecord implements \yii\web\IdentityInterface {
|
|||
return $this->user_image == null ? $directoryAsset . "/img/user2-160x160.jpg" : Yii::getAlias("@images_folder") . $this->user_image;
|
||||
}
|
||||
|
||||
public static function userArray() {
|
||||
$lists = self::find()->all();
|
||||
$results = [];
|
||||
foreach ($lists as $key => $value) {
|
||||
$results[$value->id] = $value->first_name;
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,13 +56,13 @@ class common extends \yii\db\ActiveRecord {
|
|||
}
|
||||
|
||||
public function formatTime($time, $format = "d/m/Y") {
|
||||
// $now = time();
|
||||
// $range = $now - $time;
|
||||
// if ($range > 60 * 60 * 12) {
|
||||
$now = time();
|
||||
$range = $now - $time;
|
||||
if ($range > 60 * 60 * 12) {
|
||||
return date($format, $time);
|
||||
// } else {
|
||||
// return Yii::$app->formatter->asRelativeTime($time);
|
||||
// }
|
||||
} else {
|
||||
return Yii::$app->formatter->asRelativeTime($time);
|
||||
}
|
||||
}
|
||||
|
||||
//Upload
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<type>org.netbeans.modules.php.project</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/php-project/1">
|
||||
<name>traffic</name>
|
||||
<name>AccessControl</name>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
|
|
|
@ -11,18 +11,42 @@ use yii\widgets\ActiveForm;
|
|||
|
||||
<?php
|
||||
if (Yii::$app->params['hideInfomation']) {
|
||||
echo Html::a('<span class="logo-mini">AIP</span><span class="logo-lg">AIParking</span>', Yii::$app->homeUrl, ['class' => 'logo']);
|
||||
echo Html::a('<span class="logo-mini">BI</span><span class="logo-lg">Access Control</span>', Yii::$app->homeUrl, ['class' => 'logo']);
|
||||
} else {
|
||||
echo Html::a('<span class="logo-mini">BI</span><span class="logo-lg"><img src="/images/logo.png" width="75%"></span>', Yii::$app->homeUrl, ['class' => 'logo']);
|
||||
}
|
||||
?>
|
||||
|
||||
<nav class="navbar navbar-static-top" role="navigation">
|
||||
|
||||
<a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
</a>
|
||||
|
||||
<div class="collapse navbar-collapse pull-left" id="navbar-collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="<?php if (in_array($this->context->id, ['department'])) echo "active"; ?>">
|
||||
<a href="<?php echo \yii\helpers\Url::to(['/department']); ?>">
|
||||
<i class="fa fa-users"></i> Nhân sự
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">
|
||||
<i class="fa fa-database"></i> Thiết bị
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">
|
||||
<i class="fa fa-check-square"></i> Kiểm soát truy cập
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">
|
||||
<i class="fa fa-bar-chart"></i> Báo cáo
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">
|
||||
<i class="fa fa-cogs"></i> Hệ thống
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="navbar-custom-menu">
|
||||
|
||||
<ul class="nav navbar-nav">
|
||||
|
|
|
@ -1,48 +1,32 @@
|
|||
<aside class="main-sidebar">
|
||||
|
||||
<section class="sidebar">
|
||||
|
||||
<!-- Sidebar user panel -->
|
||||
<div class="user-panel">
|
||||
<div class="pull-left image">
|
||||
<img src="<?php
|
||||
if (Yii::$app->user->isGuest) {
|
||||
echo $directoryAsset . "/img/user2-160x160.jpg";
|
||||
} else {
|
||||
echo Yii::$app->user->identity->user_image == null ? $directoryAsset . "/img/user2-160x160.jpg" : Yii::getAlias("@images_folder") . Yii::$app->user->identity->user_image;
|
||||
}
|
||||
?>" class="img-circle" alt="User Image"/>
|
||||
</div>
|
||||
<div class="pull-left info">
|
||||
<p>
|
||||
<?php
|
||||
if (Yii::$app->user->isGuest) {
|
||||
echo "";
|
||||
} else {
|
||||
echo Yii::$app->user->identity->first_name . " " . Yii::$app->user->identity->last_name;
|
||||
}
|
||||
?>
|
||||
</p>
|
||||
|
||||
<a href="#"><i class="fa fa-circle text-success"></i> <?php echo Yii::t("app", "Online"); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<?php
|
||||
if (in_array($this->context->id, ['department'])) {
|
||||
$items = [
|
||||
['label' => 'Phòng ban', 'url' => ['/department'], 'icon' => 'building'],
|
||||
['label' => 'Nhân viên', 'url' => ['/dashboard'], 'icon' => 'users'],
|
||||
['label' => 'Đăng ký thẻ', 'url' => ['/dashboard'], 'icon' => 'credit-card']
|
||||
];
|
||||
} else {
|
||||
$items = [
|
||||
['label' => 'Bảng điều khiển', 'url' => ['/dashboard'], 'icon' => 'dashboard'],
|
||||
[
|
||||
'label' => 'Hệ thống', 'icon' => 'cogs', 'url' => ['#'],
|
||||
'items' => [
|
||||
['label' => 'Người dùng', 'icon' => 'users', 'url' => ['/user'], 'visible' => Yii::$app->user->can('administrator')]
|
||||
],
|
||||
'visible' => Yii::$app->user->can('administrator')
|
||||
],
|
||||
['label' => 'Login', 'url' => ['site/login'], 'visible' => Yii::$app->user->isGuest],
|
||||
];
|
||||
}
|
||||
?>
|
||||
<?=
|
||||
dmstr\widgets\Menu::widget(
|
||||
[
|
||||
'options' => ['class' => 'sidebar-menu tree', 'data-widget' => 'tree'],
|
||||
'items' => [
|
||||
['label' => 'Bảng điều khiển', 'url' => ['/dashboard'], 'icon' => 'dashboard'],
|
||||
[
|
||||
'label' => 'Hệ thống', 'icon' => 'cogs', 'url' => ['#'],
|
||||
'items' => [
|
||||
['label' => 'Người dùng', 'icon' => 'users', 'url' => ['/user'], 'visible' => Yii::$app->user->can('administrator')]
|
||||
],
|
||||
'visible' => Yii::$app->user->can('administrator')
|
||||
],
|
||||
['label' => 'Login', 'url' => ['site/login'], 'visible' => Yii::$app->user->isGuest],
|
||||
],
|
||||
'items' => $items
|
||||
]
|
||||
)
|
||||
?>
|
||||
|
|
|
@ -5,4 +5,5 @@
|
|||
{DashboardAsset::register($this)|void}
|
||||
{block name='content'}
|
||||
{$tungbui}
|
||||
<a class="fa fa-credit-card"></a>
|
||||
{/block}
|
42
views/department/form.tpl
Normal file
42
views/department/form.tpl
Normal file
|
@ -0,0 +1,42 @@
|
|||
<style>
|
||||
.input-group-addon{
|
||||
width: 140px;
|
||||
text-align: left;
|
||||
}
|
||||
.input-group{
|
||||
width: 100%;
|
||||
}
|
||||
.select2{
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
<div class="form-group" id="name">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">Tên phòng ban <i class="text-red">*</i></div>
|
||||
<input type="text" class="form-control" value="{$model->name|default:""}" name="Name">
|
||||
</div>
|
||||
<span class="help-block hidden"></span>
|
||||
</div>
|
||||
<div class="form-group" id="code">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">Mã phòng ban <i class="text-red">*</i></div>
|
||||
<input type="number" class="form-control" value="{$model->code|default:""}" name="Code">
|
||||
</div>
|
||||
<span class="help-block hidden"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">Trực thuộc <i class="text-red">*</i></div>
|
||||
<select class="form-control" name="Pid" id="Pid">
|
||||
{html_options options=$departmentArray selected=$model->pid|default:1}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<button class="btn btn-primary" onclick="save(this);" data-href="{$url}">
|
||||
<i class="fa fa-floppy-o"></i> Lưu
|
||||
</button>
|
||||
<button class="btn btn-default" data-dismiss="modal">
|
||||
<span class="fa fa-remove"></span> Hủy
|
||||
</button>
|
||||
</div>
|
42
views/department/import.tpl
Normal file
42
views/department/import.tpl
Normal file
|
@ -0,0 +1,42 @@
|
|||
<table class="table table-bordered table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 5%;">#</th>
|
||||
<th style="width: 5%;" class="text-center">
|
||||
<input type='checkbox' value='0' class='checkbox-department-import' checked="" id='checkall-department-import'>
|
||||
</th>
|
||||
<th>Mã phòng ban</th>
|
||||
<th>Tên phòng ban</th>
|
||||
<th>Trực thuộc</th>
|
||||
<th>Trạng thái</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{$count=1}
|
||||
{foreach from=$data item=d key=k}
|
||||
{if $k>1}
|
||||
{$status=$model->checkStatusImport($d)}
|
||||
<tr {if !$status.status}class="warning"{/if}>
|
||||
<td>{$count++}</td>
|
||||
<td class="text-center">
|
||||
{if $status.status}
|
||||
<input type='checkbox' value='{json_encode($d)}' checked="" name='checkbox-department-import' class='checkbox-department-import'>
|
||||
{/if}
|
||||
</td>
|
||||
<td>{$d.A}</td>
|
||||
<td>{$d.B}</td>
|
||||
<td>{$d.C}</td>
|
||||
<td><i class="text-red">{$status.description}</i></td>
|
||||
</tr>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="text-right">
|
||||
<button class="btn btn-primary" onclick="_import(this);" data-href="{yii\helpers\Url::to(["import"])}">
|
||||
<i class="fa fa-floppy-o"></i> Lưu
|
||||
</button>
|
||||
<button class="btn btn-default" data-dismiss="modal">
|
||||
<span class="fa fa-remove"></span> Hủy
|
||||
</button>
|
||||
</div>
|
78
views/department/index.tpl
Normal file
78
views/department/index.tpl
Normal file
|
@ -0,0 +1,78 @@
|
|||
{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\DepartmentAsset"}
|
||||
{DepartmentAsset::register($this)|void}
|
||||
{block name='content'}
|
||||
<div class="department-index">
|
||||
<div class="">
|
||||
<label class="action-button">
|
||||
<i class="fa fa-sitemap"></i> Cây thư mục
|
||||
</label>
|
||||
<label class="action-button" onclick="common.form(this, 'department');" data-href="{Url::to(['create'])}">
|
||||
<i class="fa fa-plus-square"></i> Thêm
|
||||
</label>
|
||||
<label class="action-button" onclick="_form(this);" data-href="{Url::to(['update'])}">
|
||||
<i class="fa fa-edit"></i> Tùy chỉnh
|
||||
</label>
|
||||
<label class="action-button" onclick="_delete(this);" data-href="{Url::to(['delete'])}">
|
||||
<i class="fa fa-trash"></i> Xóa
|
||||
</label>
|
||||
<label class="action-button" onclick="$('#file').trigger('click');">
|
||||
<i class="fa fa-upload"></i> Nhập
|
||||
</label>
|
||||
<label class="action-button" onclick="_export(this);" data-href="{Url::to(['export'])}">
|
||||
<i class="fa fa-download"></i> Xuất
|
||||
</label>
|
||||
<label class="action-button" onclick="_logs(this);" data-href="{Url::to(['logs'])}">
|
||||
<i class="fa fa-file"></i> Ghi nhận hệ thống
|
||||
</label>
|
||||
</div>
|
||||
<div class="hidden">
|
||||
<input type="file" name="file" id="file">
|
||||
<input type="hidden" value="{Url::to(['upload'])}" name="upload_file_url">
|
||||
</div>
|
||||
{Pjax id="department-list"}
|
||||
{GridView::widget([
|
||||
'dataProvider' => $dataProvider,
|
||||
'filterModel' => $searchModel,
|
||||
'layout'=> \app\helpers\DepartmentGrid::getLayout(),
|
||||
'tableOptions' => [
|
||||
'class' => 'table table-striped table-bordered table-hover',
|
||||
'style' => 'background:#fff;min-width:700px;'
|
||||
],
|
||||
'rowOptions' => \app\helpers\DepartmentGrid::rows(),
|
||||
'columns' => [
|
||||
[
|
||||
'class' => 'yii\grid\SerialColumn',
|
||||
'contentOptions' => ['class' => 'text-center'],
|
||||
'headerOptions' => ['class' => 'text-center', 'style' => 'width:3%']
|
||||
],
|
||||
[
|
||||
'header' => "<input type='checkbox' value='0' class='checkbox-department' id='checkall-department'>",
|
||||
'format' => 'raw',
|
||||
'contentOptions' => ['class' => 'text-center'],
|
||||
'headerOptions' => ['class' => 'text-center', 'style' => 'width:3%'],
|
||||
'value' => \app\helpers\DepartmentGrid::checkbox()
|
||||
],
|
||||
'code',
|
||||
'name',
|
||||
[
|
||||
'attribute' => 'pid',
|
||||
'filter' => $departmentArray,
|
||||
'value' => \app\helpers\DepartmentGrid::pid($departmentArray)
|
||||
],
|
||||
[
|
||||
'attribute' => 'created_at',
|
||||
'value' => \app\helpers\DepartmentGrid::createdAt()
|
||||
],
|
||||
[
|
||||
'attribute' => 'modified_at',
|
||||
'value' => \app\helpers\DepartmentGrid::modifiedAt()
|
||||
]
|
||||
]
|
||||
])}
|
||||
{/Pjax}
|
||||
</div>
|
||||
{/block}
|
23
views/department/logs.tpl
Normal file
23
views/department/logs.tpl
Normal file
|
@ -0,0 +1,23 @@
|
|||
<table style="width: 100%;" class="table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Người dùng</th>
|
||||
<th>Thời gian</th>
|
||||
<th>Hành động</th>
|
||||
<th>Chi tiết</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{$count=1}
|
||||
{foreach from=$logs item=l}
|
||||
<tr>
|
||||
<td>{$count++}</td>
|
||||
<td>{$userArray[$l->user_id]|default:""}</td>
|
||||
<td>{$l->time|date_format:"%H:%M:%S %d/%m/%Y"}</td>
|
||||
<td>{$l->action}</td>
|
||||
<td>{$l->description}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
|
@ -31,7 +31,7 @@
|
|||
<div class="modal-content">
|
||||
<div class="modal-header" id="modalHeader">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="myModalLabel"></h4>
|
||||
<h5 class="modal-title" id="myModalLabel"></h5>
|
||||
</div>
|
||||
<div class="modal-body" id="myModalContent">
|
||||
...
|
||||
|
|
|
@ -228,4 +228,30 @@ table > tbody > tr.success >td>a {
|
|||
}
|
||||
.box-header{
|
||||
border-bottom: 1px solid #cecece;
|
||||
}
|
||||
|
||||
.skin-blue .main-header .logo{
|
||||
background-color: #3c8dbc !important;
|
||||
}
|
||||
|
||||
.content{
|
||||
padding: 0 !important;
|
||||
}
|
||||
.content-header{
|
||||
padding: 0 !important;
|
||||
}
|
||||
.action-button{
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
font-weight: inherit;
|
||||
}
|
||||
.action-button:hover{
|
||||
font-weight: bold;
|
||||
background: #b2d7ec;
|
||||
border: 1px solid #3c8dbc;
|
||||
}
|
||||
.modal-header{
|
||||
padding: 10px;
|
||||
background: #b2d7ec;
|
||||
}
|
|
@ -218,25 +218,8 @@ common.form = function (e, obj) {
|
|||
success: function (data) {
|
||||
common.modalBlock(false);
|
||||
common.modalOpen(data.form, false, data.title);
|
||||
if (obj === 'user')
|
||||
$('#role').select2({tags: true, tokenSeparators: [',']});
|
||||
|
||||
if (obj === 'gia_han_the')
|
||||
$('#GiaHan').datetimepicker({
|
||||
locale: 'vi',
|
||||
ignoreReadonly: true,
|
||||
format: 'DD/MM/YYYY'
|
||||
});
|
||||
|
||||
if (obj === 'cau_hinh_chi_phi') {
|
||||
common.dateTimePickerHour("from");
|
||||
common.dateTimePickerHour("to");
|
||||
$('.time').datetimepicker({
|
||||
locale: 'vi',
|
||||
ignoreReadonly: true,
|
||||
format: 'HH:mm'
|
||||
});
|
||||
}
|
||||
if (obj === 'department')
|
||||
$('#Pid').select2();
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
common.modalBlock(false);
|
||||
|
@ -244,6 +227,18 @@ common.form = function (e, obj) {
|
|||
}
|
||||
});
|
||||
};
|
||||
common.checkboxInit = function (id) {
|
||||
$('.checkbox-' + id).iCheck({
|
||||
checkboxClass: 'icheckbox_flat-blue'
|
||||
});
|
||||
$('#checkall-' + id).on('ifChanged', function (event) {
|
||||
if (event.target.checked) {
|
||||
$('.checkbox-' + id).iCheck('check');
|
||||
} else {
|
||||
$('.checkbox-' + id).iCheck('uncheck');
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* =========================
|
||||
*/
|
||||
|
|
200
web/js/department.js
Normal file
200
web/js/department.js
Normal file
|
@ -0,0 +1,200 @@
|
|||
$(function () {
|
||||
common.checkboxInit("department");
|
||||
btnUpload($("input[name='upload_file_url']").val(), "", '.xls,.xlsx', 3500);
|
||||
});
|
||||
|
||||
function validate() {
|
||||
var error = 0;
|
||||
var Name = $("input[name='Name']").val();
|
||||
if (Name === "") {
|
||||
common.error("name", "Tên phòng ban không được để trống");
|
||||
error++;
|
||||
} else {
|
||||
common.success("name");
|
||||
}
|
||||
|
||||
var Code = $("input[name='Code']").val();
|
||||
if (Code === "") {
|
||||
common.error("code", "Mã phòng ban không được để trống");
|
||||
error++;
|
||||
} else {
|
||||
common.success("code");
|
||||
}
|
||||
return error == 0 ? true : false;
|
||||
}
|
||||
|
||||
function save(e) {
|
||||
if (validate()) {
|
||||
common.modalBlock(true);
|
||||
$.ajax({
|
||||
url: $(e).attr('data-href'),
|
||||
type: 'POST',
|
||||
data: {
|
||||
Name: $("input[name='Name']").val(),
|
||||
Code: $("input[name='Code']").val(),
|
||||
Pid: $("select[name='Pid']").val()
|
||||
},
|
||||
success: function (data) {
|
||||
common.modalBlock(false);
|
||||
if (data.status) {
|
||||
notification.success("Đã lưu thông tin", 1000);
|
||||
$.pjax.reload({container: '#department-list'});
|
||||
$("#department-list").on('pjax:success', function () {
|
||||
common.checkboxInit("department");
|
||||
});
|
||||
$("#myModal").modal("hide");
|
||||
} else {
|
||||
if (data.type === "code") {
|
||||
common.error("code", "Mã phòng ban đã tồn tại");
|
||||
} else {
|
||||
notification.danger("Có lỗi xảy ra, không lưu được dữ liệu!", 1000);
|
||||
}
|
||||
}
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
common.modalBlock(false);
|
||||
common.ajaxError();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function _form(e) {
|
||||
var lists = [];
|
||||
$.each($("input[name='checkbox-department']:checked"), function () {
|
||||
lists.push($(this).val());
|
||||
});
|
||||
if (lists.length == 0) {
|
||||
alert("Vui lòng lựa chọn đối tượng để thay đổi!");
|
||||
return;
|
||||
}
|
||||
if (lists.length > 1) {
|
||||
alert("Tác vụ này không thể lựa chọn nhiều hơn một đối tượng!");
|
||||
return;
|
||||
}
|
||||
common.modalBlock(true);
|
||||
$.ajax({
|
||||
url: $(e).attr('data-href') + "?id=" + lists[0],
|
||||
type: 'POST',
|
||||
success: function (data) {
|
||||
common.modalBlock(false);
|
||||
common.modalOpen(data.form, false, data.title);
|
||||
$('#Pid').select2();
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
common.modalBlock(false);
|
||||
common.ajaxError();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function _delete(e) {
|
||||
var lists = [];
|
||||
$.each($("input[name='checkbox-department']:checked"), function () {
|
||||
lists.push($(this).val());
|
||||
});
|
||||
if (lists.length == 0) {
|
||||
alert("Vui lòng lựa chọn đối tượng để xóa!");
|
||||
return;
|
||||
}
|
||||
if (lists.length == 1 && lists[0] === "1") {
|
||||
alert("Danh mục gốc không thể xóa!");
|
||||
return;
|
||||
}
|
||||
if (confirm("Bạn có chắc chắn muốn xóa các đối tượng đã lựa chọn không?")) {
|
||||
common.modalBlock(true);
|
||||
$.ajax({
|
||||
url: $(e).attr('data-href'),
|
||||
type: 'POST',
|
||||
data: {
|
||||
lists: lists
|
||||
},
|
||||
success: function (data) {
|
||||
common.modalBlock(false);
|
||||
notification.danger("Đã xóa dữ liệu", 1000);
|
||||
$.pjax.reload({container: '#department-list'});
|
||||
$("#department-list").on('pjax:success', function () {
|
||||
common.checkboxInit("department");
|
||||
});
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
common.modalBlock(false);
|
||||
common.ajaxError();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function _export(e) {
|
||||
window.location = $(e).attr("data-href");
|
||||
}
|
||||
|
||||
function btnUpload(mUrl, className, extension, fileSize) {
|
||||
var fData = {
|
||||
UploadFile: true,
|
||||
Name: className
|
||||
};
|
||||
fData[common.csrfParam] = common.csrf;
|
||||
new afuButton({
|
||||
uploadURI: mUrl,
|
||||
formData: fData,
|
||||
wrap: {
|
||||
tagName: 'div',
|
||||
classes: ''
|
||||
},
|
||||
fileExtension: extension,
|
||||
fileSizeLimit: fileSize,
|
||||
classes: 'btn btn-default file-paperclip-' + className,
|
||||
fakeInputContent: '<span class=\'fa fa-upload\'></span> Nhập dữ liệu',
|
||||
onUploaded: function (data) {
|
||||
data = JSON.parse(data);
|
||||
common.modalOpen(data.form, true, data.title);
|
||||
common.uploadBlock(false);
|
||||
common.checkboxInit("department-import");
|
||||
}
|
||||
}).addInstance('file' + className);
|
||||
$(".file-paperclip-" + className).closest("div").attr("style", "display:inline-block;");
|
||||
}
|
||||
|
||||
function _import(e) {
|
||||
var lists = [];
|
||||
$.each($("input[name='checkbox-department-import']:checked"), function () {
|
||||
lists.push($(this).val());
|
||||
});
|
||||
if (lists.length == 0) {
|
||||
alert("Vui lòng lựa chọn đối tượng để nhập!");
|
||||
return;
|
||||
}
|
||||
common.modalBlock(true);
|
||||
$.ajax({
|
||||
url: $(e).attr('data-href'),
|
||||
type: 'POST',
|
||||
data: {
|
||||
lists: lists
|
||||
},
|
||||
success: function (data) {
|
||||
common.modalBlock(false);
|
||||
window.location.reload(true);
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
common.modalBlock(false);
|
||||
common.ajaxError();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function _logs(e) {
|
||||
common.modalBlock(true);
|
||||
$.ajax({
|
||||
url: $(e).attr('data-href'),
|
||||
type: 'POST',
|
||||
success: function (data) {
|
||||
common.modalBlock(false);
|
||||
common.modalOpen(data.form, true, data.title);
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
common.modalBlock(false);
|
||||
common.ajaxError();
|
||||
}
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue
Block a user