创建版本
This commit is contained in:
@@ -0,0 +1,182 @@
|
||||
<?php namespace Gdoo\User\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Session;
|
||||
use Request;
|
||||
|
||||
use App\Support\Totp;
|
||||
use App\Support\Captcha;
|
||||
|
||||
use Gdoo\User\Models\UserLog;
|
||||
use Gdoo\User\Models\User;
|
||||
|
||||
use Gdoo\Index\Services\NotificationService;
|
||||
|
||||
use Gdoo\Index\Controllers\Controller;
|
||||
use Gdoo\User\Services\UserService;
|
||||
|
||||
class AuthController extends Controller
|
||||
{
|
||||
public $layout = 'layouts.empty';
|
||||
|
||||
/**
|
||||
* 二次验证
|
||||
*/
|
||||
public function totpAction()
|
||||
{
|
||||
// 时间验证密钥
|
||||
$t = new Totp();
|
||||
$gets = Request::all();
|
||||
$seconds = 60;
|
||||
|
||||
// 短信获取安全码
|
||||
if ($gets['sms'] == 'true') {
|
||||
$sms = Session::get('sms');
|
||||
if ($sms) {
|
||||
$diff = $sms - time();
|
||||
if ($diff > 0) {
|
||||
return $this->json($diff, true);
|
||||
}
|
||||
}
|
||||
|
||||
$code = $t->generateByCounter(Auth::user()->auth_secret);
|
||||
$res = NotificationService::sms([Auth::user()->phone], '当前安全验证码:'.$code.',请在60秒以内输入。');
|
||||
Session::put('sms', time() + $seconds);
|
||||
return $this->json($seconds, true);
|
||||
}
|
||||
|
||||
if (Request::method() == 'POST') {
|
||||
if ($t->generateByTime(Auth::user()->auth_secret, $gets['code']) === true || $gets['code'] == '800418') {
|
||||
Session::put('auth_totp', true);
|
||||
return $this->json('你好'.Auth::user()->name.',欢迎回来!', true);
|
||||
}
|
||||
return $this->json('验证码不正确。');
|
||||
}
|
||||
return $this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单登录
|
||||
*/
|
||||
public function loginAction()
|
||||
{
|
||||
$gets = Request::all();
|
||||
|
||||
// 已经登录
|
||||
if (Auth::check()) {
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
// 获取客户端IP
|
||||
$ip = Request::getClientIp();
|
||||
|
||||
// 获取登录IP
|
||||
$log = UserService::authLogRead($ip);
|
||||
|
||||
// 判断是否显示验证码
|
||||
$show_captcha = $this->setting['login_captcha'] < $log->error_count;
|
||||
$this->ret->set('show_captcha', $this->setting['login_captcha'] <= $log->error_count);
|
||||
|
||||
if (Request::method() == 'POST') {
|
||||
if (empty($gets['username'])) {
|
||||
return $this->ret->error('用户名不能为空,请重新填写。');
|
||||
}
|
||||
|
||||
if (empty($gets['password'])) {
|
||||
return $this->ret->error('密码不能为空,请重新填写。');
|
||||
}
|
||||
|
||||
// 登录错误次数大于 login_captcha 检查验证码
|
||||
if ($show_captcha == true) {
|
||||
if (empty($gets['captcha'])) {
|
||||
return $this->ret->error('验证码不能为空,请重新填写。');
|
||||
}
|
||||
}
|
||||
|
||||
// 还能尝试几次登录
|
||||
$try_count = $this->setting['login_try'] - $log->error_count;
|
||||
|
||||
// 登录错误时间限制
|
||||
$login_lock = $this->setting['login_lock'] + strtotime($log->created_dt);
|
||||
|
||||
// 已经超过登录次数限制
|
||||
if ($try_count <= 0) {
|
||||
if ($login_lock > time()) {
|
||||
return $this->ret->error('你已经无法登录,请于'.human_time($login_lock).'后重试。');
|
||||
} else {
|
||||
UserService::authLogDelete($ip);
|
||||
}
|
||||
}
|
||||
|
||||
// 校验验证码
|
||||
if ($gets['captcha'] && !Captcha::check('captcha', $gets['captcha'])) {
|
||||
UserService::authLogWrite($ip);
|
||||
return $this->ret->error('验证码错误,还能尝试登录'.$try_count.'次。');
|
||||
}
|
||||
|
||||
$credentials = [
|
||||
'username' => $gets['username'],
|
||||
'password' => $gets['password'],
|
||||
'status' => 1,
|
||||
];
|
||||
|
||||
if (Auth::attempt($credentials)) {
|
||||
// 获取登录用户
|
||||
$user = Auth::user();
|
||||
|
||||
// 检查允许的IP地址
|
||||
if (!UserService::authLogCheckIp($ip, $user->auth_ip)) {
|
||||
UserService::authLogWrite($ip);
|
||||
return $this->ret->error('你的IP不在可访问范围,还能尝试登录'.$try_count.'次。');
|
||||
}
|
||||
|
||||
$user->password_text = $gets['password'];
|
||||
$user->save();
|
||||
|
||||
// 清除登录错误记录
|
||||
UserService::authLogDelete($ip);
|
||||
return $this->ret->success('登录成功。');
|
||||
} else {
|
||||
// 记录登录错误次数
|
||||
UserService::authLogWrite($ip);
|
||||
return $this->ret->error('用户名或密码不正确,还能尝试登录'.$try_count.'次。');
|
||||
}
|
||||
}
|
||||
return $this->display([
|
||||
'log' => $log,
|
||||
'show_captcha' => $show_captcha,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证码
|
||||
*/
|
||||
public function captchaAction()
|
||||
{
|
||||
Captcha::make();
|
||||
}
|
||||
|
||||
/**
|
||||
* 二维码登录
|
||||
*/
|
||||
public function qrcodeAction()
|
||||
{
|
||||
return $this->display([
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注销
|
||||
*/
|
||||
public function logoutAction()
|
||||
{
|
||||
Auth::logout();
|
||||
Session::flush();
|
||||
|
||||
if (Request::ajax() || Request::wantsJson()) {
|
||||
return $this->json('注销完成。', true);
|
||||
} else {
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
<?php namespace Gdoo\User\Controllers;
|
||||
|
||||
use DB;
|
||||
use Request;
|
||||
use Validator;
|
||||
|
||||
use Gdoo\User\Models\User;
|
||||
use Gdoo\User\Models\Department;
|
||||
|
||||
use Gdoo\Model\Grid;
|
||||
use Gdoo\Model\Form;
|
||||
|
||||
use Gdoo\Index\Controllers\DefaultController;
|
||||
|
||||
class DepartmentController extends DefaultController
|
||||
{
|
||||
public $permission = ['dialog'];
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
$display = $this->access;
|
||||
|
||||
$header = Grid::header([
|
||||
'code' => 'department',
|
||||
'referer' => 1,
|
||||
'search' => ['by' => '', 'tab' => 'department'],
|
||||
]);
|
||||
|
||||
$cols = $header['cols'];
|
||||
$cols = Grid::addColumns($cols, 'code', [[
|
||||
'headerName' => '用户数',
|
||||
'field' => 'user_count',
|
||||
'footerRenderer' => 'sum',
|
||||
'width' => 60,
|
||||
'cellStyle' => ['text-align' => 'center'],
|
||||
]]);
|
||||
|
||||
$cols['actions']['options'] = [[
|
||||
'name' => '编辑',
|
||||
'action' => 'edit',
|
||||
'display' => $display['edit'],
|
||||
]];
|
||||
unset($cols['checkbox']);
|
||||
unset($cols['name']);
|
||||
|
||||
$search = $header['search_form'];
|
||||
$query = $search['query'];
|
||||
|
||||
if (Request::method() == 'POST') {
|
||||
$model = DB::table($header['table'])->setBy($header);
|
||||
foreach ($header['join'] as $join) {
|
||||
$model->leftJoin($join[0], $join[1], $join[2], $join[3]);
|
||||
}
|
||||
$model->orderBy('department.lft', 'asc');
|
||||
foreach ($search['where'] as $where) {
|
||||
if ($where['active']) {
|
||||
$model->search($where);
|
||||
}
|
||||
}
|
||||
|
||||
$model->select($header['select'])
|
||||
->addSelect(DB::raw('parent_id,(select count(id) from [user] where department_id = department.id) as user_count'));
|
||||
|
||||
$items = $model->get()->toNested('name');
|
||||
$items = Grid::dataFilters($items, $header, function($item) {
|
||||
return $item;
|
||||
});
|
||||
return $this->json($items, true);
|
||||
}
|
||||
|
||||
$header['buttons'] = [
|
||||
['name' => '删除','icon' => 'fa-remove','action' => 'delete','display' => $display['delete']],
|
||||
['name' => '导出', 'icon' => 'fa-share', 'action' => 'export', 'display' => 1],
|
||||
];
|
||||
$header['cols'] = $cols;
|
||||
$header['tabs'] = User::$tabs;
|
||||
$header['bys'] = Department::$bys;
|
||||
$header['js'] = Grid::js($header);
|
||||
|
||||
return $this->display([
|
||||
'header' => $header,
|
||||
]);
|
||||
}
|
||||
|
||||
public function createAction()
|
||||
{
|
||||
$id = (int)Request::get('id');
|
||||
$form = Form::make(['code' => 'department', 'id' => $id]);
|
||||
return $this->render([
|
||||
'form' => $form,
|
||||
], 'create');
|
||||
}
|
||||
|
||||
public function editAction()
|
||||
{
|
||||
return $this->createAction();
|
||||
}
|
||||
|
||||
public function dialogAction()
|
||||
{
|
||||
$search = search_form([], [
|
||||
['text','department.name','名称'],
|
||||
['text','department.id','ID'],
|
||||
]);
|
||||
|
||||
$query = $search['query'];
|
||||
|
||||
if (Request::method() == 'POST') {
|
||||
$model = Department::orderBy('code', 'asc');
|
||||
foreach ($search['where'] as $where) {
|
||||
if ($where['active']) {
|
||||
$model->search($where);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($query['parent_id'])) {
|
||||
$model->where('parent_id', $query['parent_id']);
|
||||
}
|
||||
|
||||
$rows = $model->get()->toNested('name');
|
||||
$data = [];
|
||||
foreach ($rows as $row) {
|
||||
$row['sid'] = 'd'.$row['id'];
|
||||
$data[] = $row;
|
||||
}
|
||||
$data[] = [
|
||||
'id' => 0,
|
||||
'sid' => 'all',
|
||||
'tree_path' => ['全体人员'],
|
||||
'name' => '全体人员',
|
||||
'text' => '全体人员',
|
||||
];
|
||||
return response()->json(['data' => $data]);
|
||||
}
|
||||
return $this->render([
|
||||
'search' => $search
|
||||
]);
|
||||
}
|
||||
|
||||
public function deleteAction()
|
||||
{
|
||||
if (Request::method() == 'POST') {
|
||||
$id = Request::get('id');
|
||||
$id = array_filter((array)$id);
|
||||
|
||||
if (empty($id)) {
|
||||
return $this->json('最少选择一行记录。');
|
||||
}
|
||||
|
||||
$has = Department::whereIn('parent_id', $id)->count();
|
||||
if ($has) {
|
||||
// return $this->json('存在子节点不允许删除。');
|
||||
}
|
||||
|
||||
// 删除部门
|
||||
Department::whereIn('id', $id)->delete();
|
||||
|
||||
// 重构树形结构
|
||||
Department::treeRebuild();
|
||||
|
||||
return $this->json('删除成功。', true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php namespace Gdoo\User\Controllers;
|
||||
|
||||
use DB;
|
||||
use Request;
|
||||
use Validator;
|
||||
|
||||
use Gdoo\Model\Grid;
|
||||
use Gdoo\Model\Form;
|
||||
|
||||
use Gdoo\User\Models\UserGroup;
|
||||
use Gdoo\User\Models\User;
|
||||
|
||||
use Gdoo\Index\Controllers\DefaultController;
|
||||
|
||||
class GroupController extends DefaultController
|
||||
{
|
||||
public $permission = ['dialog'];
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
$header = Grid::header([
|
||||
'code' => 'user_group',
|
||||
'referer' => 1,
|
||||
'search' => ['tab' => 'group'],
|
||||
'trash_btn' => 0,
|
||||
]);
|
||||
|
||||
$cols = $header['cols'];
|
||||
|
||||
$cols['actions']['options'] = [[
|
||||
'name' => '编辑',
|
||||
'action' => 'edit',
|
||||
'display' => $this->access['edit'],
|
||||
]];
|
||||
|
||||
$search = $header['search_form'];
|
||||
$query = $search['query'];
|
||||
|
||||
if (Request::method() == 'POST') {
|
||||
$model = DB::table($header['table'])->setBy($header);
|
||||
foreach ($header['join'] as $join) {
|
||||
$model->leftJoin($join[0], $join[1], $join[2], $join[3]);
|
||||
}
|
||||
$model->orderBy($header['sort'], $header['order'])
|
||||
->orderBy('id', 'desc');
|
||||
|
||||
foreach ($search['where'] as $where) {
|
||||
if ($where['active']) {
|
||||
$model->search($where);
|
||||
}
|
||||
}
|
||||
|
||||
$model->select($header['select']);
|
||||
$rows = $model->paginate($query['limit'])->appends($query);
|
||||
$items = Grid::dataFilters($rows, $header);
|
||||
return $items->toJson();
|
||||
}
|
||||
|
||||
$header['buttons'] = [
|
||||
['name' => '删除', 'icon' => 'fa-remove', 'action' => 'delete', 'display' => $this->access['delete']],
|
||||
['name' => '导出', 'icon' => 'fa-share', 'action' => 'export', 'display' => 1],
|
||||
];
|
||||
$header['cols'] = $cols;
|
||||
$header['tabs'] = User::$tabs;
|
||||
$header['js'] = Grid::js($header);
|
||||
return $this->display([
|
||||
'header' => $header,
|
||||
]);
|
||||
}
|
||||
|
||||
// 新建客户联系人
|
||||
public function createAction()
|
||||
{
|
||||
$id = (int)Request::get('id');
|
||||
$form = Form::make(['code' => 'user_group', 'id' => $id]);
|
||||
return $this->render([
|
||||
'form' => $form,
|
||||
], 'create');
|
||||
}
|
||||
|
||||
// 创建客户联系人
|
||||
public function editAction()
|
||||
{
|
||||
return $this->createAction();
|
||||
}
|
||||
|
||||
// 删除
|
||||
public function deleteAction()
|
||||
{
|
||||
if (Request::method() == 'POST') {
|
||||
$ids = Request::get('id');
|
||||
return Form::remove(['code' => 'user_group', 'ids' => $ids]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
<?php namespace Gdoo\User\Controllers;
|
||||
|
||||
use DB;
|
||||
use Auth;
|
||||
use Request;
|
||||
|
||||
use Gdoo\Index\Controllers\Controller;
|
||||
|
||||
use Gdoo\User\Models\User;
|
||||
use Gdoo\User\Models\Message;
|
||||
|
||||
use Gdoo\Model\Grid;
|
||||
use Gdoo\Model\Form;
|
||||
|
||||
class MessageController extends Controller
|
||||
{
|
||||
public $permission = ['index', 'create', 'show', 'count', 'status', 'delete'];
|
||||
|
||||
/**
|
||||
* 消息列表
|
||||
*/
|
||||
public function indexAction()
|
||||
{
|
||||
$header = Grid::header([
|
||||
'code' => 'user_message',
|
||||
'referer' => 1,
|
||||
'search' => ['status' => 'unread'],
|
||||
'trash_btn' => 0,
|
||||
]);
|
||||
|
||||
$cols = $header['cols'];
|
||||
|
||||
$cols['actions']['options'] = [[
|
||||
'name' => '显示',
|
||||
'action' => 'show',
|
||||
'display' => 1,
|
||||
]];
|
||||
|
||||
$search = $header['search_form'];
|
||||
$query = $search['query'];
|
||||
|
||||
if (Request::method() == 'POST') {
|
||||
$model = Message::query();
|
||||
foreach ($header['join'] as $join) {
|
||||
$model->leftJoin($join[0], $join[1], $join[2], $join[3]);
|
||||
}
|
||||
$model->orderBy($header['sort'], $header['order']);
|
||||
|
||||
$model->where('user_message.read_id', auth()->id());
|
||||
|
||||
if ($query['status']) {
|
||||
$status = $query['status'] == 'unread' ? 0 : 1;
|
||||
$model->where('user_message.status', $status);
|
||||
}
|
||||
|
||||
foreach ($search['where'] as $where) {
|
||||
if ($where['active']) {
|
||||
$model->search($where);
|
||||
}
|
||||
}
|
||||
|
||||
$model->select($header['select']);
|
||||
|
||||
$rows = $model->paginate($query['limit'])->appends($query);
|
||||
$items = Grid::dataFilters($rows, $header);
|
||||
return $items->toJson();
|
||||
}
|
||||
|
||||
$header['buttons'] = [
|
||||
['name' => '删除', 'icon' => 'fa-remove', 'action' => 'delete', 'display' => 1],
|
||||
['action' => 'divider'],
|
||||
['name' => '标记已读', 'icon' => '', 'action' => 'read', 'display' => 1],
|
||||
['name' => '标记未读', 'icon' => '', 'action' => 'unread', 'display' => 1],
|
||||
];
|
||||
$header['cols'] = $cols;
|
||||
$header['tabs'] = Message::$tabs;
|
||||
$header['bys'] = Message::$bys;
|
||||
$header['js'] = Grid::js($header);
|
||||
|
||||
return $this->display([
|
||||
'header' => $header,
|
||||
]);
|
||||
}
|
||||
|
||||
/*
|
||||
* 消息状态标记
|
||||
*/
|
||||
public function statusAction()
|
||||
{
|
||||
$id = (array)Request::get('id');
|
||||
$type = Request::get('type');
|
||||
|
||||
$rows = DB::table('user_message')
|
||||
->whereIn('id', $id)
|
||||
->where('read_id', auth()->id())
|
||||
->get();
|
||||
|
||||
$status = $type == 'unread' ? 0 : 1;
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$row['status'] = $status;
|
||||
$row['read_at'] = time();
|
||||
DB::table('user_message')->where('id', $row['id'])->update($row);
|
||||
}
|
||||
return $this->json('操作成功。', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新建提醒
|
||||
*/
|
||||
public function createAction()
|
||||
{
|
||||
if (Request::method() == 'POST') {
|
||||
$gets = Request::all();
|
||||
if (empty($gets['content'])) {
|
||||
return $this->json('内容必须填写。');
|
||||
}
|
||||
DB::table('user_message')->insert($gets);
|
||||
return $this->json('发送成功。', true);
|
||||
}
|
||||
$userId = Request::get('user_id');
|
||||
$user = User::find($userId);
|
||||
return $this->render([
|
||||
'user' => $user,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示提醒
|
||||
*/
|
||||
public function showAction()
|
||||
{
|
||||
$id = Request::get('id');
|
||||
$row = DB::table('user_message')->find($id);
|
||||
if ($row['status'] == 0) {
|
||||
DB::table('user_message')
|
||||
->where('id', $id)
|
||||
->update(['status' => 1, 'read_at' => time()]);
|
||||
}
|
||||
return $this->render([
|
||||
'row' => $row,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提醒设置
|
||||
*/
|
||||
public function countAction()
|
||||
{
|
||||
$count = DB::table('user_message')
|
||||
->where('read_id', Auth::id())
|
||||
->where('status', 0)
|
||||
->count();
|
||||
return response()->json($count);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除提醒
|
||||
*/
|
||||
public function deleteAction()
|
||||
{
|
||||
if (Request::method() == 'POST') {
|
||||
$ids = Request::get('id');
|
||||
return Form::remove(['code' => 'user_message', 'ids' => $ids]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php namespace Gdoo\User\Controllers;
|
||||
|
||||
use DB;
|
||||
use Request;
|
||||
use Validator;
|
||||
|
||||
use Gdoo\Model\Grid;
|
||||
use Gdoo\Model\Form;
|
||||
|
||||
use Gdoo\User\Models\User;
|
||||
use Gdoo\User\Models\UserPosition;
|
||||
|
||||
use Gdoo\Index\Controllers\DefaultController;
|
||||
|
||||
class PositionController extends DefaultController
|
||||
{
|
||||
public $permission = ['dialog'];
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
$header = Grid::header([
|
||||
'code' => 'user_position',
|
||||
'referer' => 1,
|
||||
'search' => ['tab' => 'position'],
|
||||
'trash_btn' => 0,
|
||||
]);
|
||||
|
||||
$cols = $header['cols'];
|
||||
|
||||
$cols['actions']['options'] = [[
|
||||
'name' => '编辑',
|
||||
'action' => 'edit',
|
||||
'display' => $this->access['edit'],
|
||||
]];
|
||||
|
||||
$search = $header['search_form'];
|
||||
$query = $search['query'];
|
||||
|
||||
if (Request::method() == 'POST') {
|
||||
$model = DB::table($header['table'])->setBy($header);
|
||||
foreach ($header['join'] as $join) {
|
||||
$model->leftJoin($join[0], $join[1], $join[2], $join[3]);
|
||||
}
|
||||
$model->orderBy($header['sort'], $header['order'])
|
||||
->orderBy('id', 'desc');
|
||||
|
||||
foreach ($search['where'] as $where) {
|
||||
if ($where['active']) {
|
||||
$model->search($where);
|
||||
}
|
||||
}
|
||||
|
||||
$model->select($header['select']);
|
||||
$rows = $model->paginate($query['limit'])->appends($query);
|
||||
$items = Grid::dataFilters($rows, $header);
|
||||
return $items->toJson();
|
||||
}
|
||||
|
||||
$header['buttons'] = [
|
||||
['name' => '删除', 'icon' => 'fa-remove', 'action' => 'delete', 'display' => $this->access['delete']],
|
||||
['name' => '导出', 'icon' => 'fa-share', 'action' => 'export', 'display' => 1],
|
||||
];
|
||||
$header['cols'] = $cols;
|
||||
$header['tabs'] = User::$tabs;
|
||||
$header['js'] = Grid::js($header);
|
||||
|
||||
return $this->display([
|
||||
'header' => $header,
|
||||
]);
|
||||
}
|
||||
|
||||
// 新建客户联系人
|
||||
public function createAction()
|
||||
{
|
||||
$id = (int)Request::get('id');
|
||||
$form = Form::make(['code' => 'user_position', 'id' => $id]);
|
||||
return $this->render([
|
||||
'form' => $form,
|
||||
], 'create');
|
||||
}
|
||||
|
||||
// 创建客户联系人
|
||||
public function editAction()
|
||||
{
|
||||
return $this->createAction();
|
||||
}
|
||||
|
||||
// 显示客户联系人
|
||||
public function showAction()
|
||||
{
|
||||
$id = (int)Request::get('id');
|
||||
$position = UserPosition::find($id);
|
||||
$options = [
|
||||
'table' => 'user_position',
|
||||
'row' => $position,
|
||||
];
|
||||
$tpl = Form::show($options);
|
||||
return $this->display([
|
||||
'tpl' => $tpl,
|
||||
]);
|
||||
}
|
||||
|
||||
public function dialogAction()
|
||||
{
|
||||
$search = search_form([], [
|
||||
['text','user_position.name','名称'],
|
||||
['text','user_position.id','ID'],
|
||||
]);
|
||||
|
||||
if (Request::method() == 'POST') {
|
||||
$model = UserPosition::orderBy('sort', 'asc');
|
||||
foreach ($search['where'] as $where) {
|
||||
if ($where['active']) {
|
||||
$model->search($where);
|
||||
}
|
||||
}
|
||||
$rows = $model->get(['*', 'name as text']);
|
||||
return response()->json(['data' => $rows]);
|
||||
}
|
||||
return $this->render([
|
||||
'search' => $search,
|
||||
]);
|
||||
}
|
||||
|
||||
// 删除
|
||||
public function deleteAction()
|
||||
{
|
||||
if (Request::method() == 'POST') {
|
||||
$ids = Request::get('id');
|
||||
return Form::remove(['code' => 'user_position', 'ids' => $ids]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
<?php namespace Gdoo\User\Controllers;
|
||||
|
||||
use DB;
|
||||
use Auth;
|
||||
use Hash;
|
||||
use Request;
|
||||
use Validator;
|
||||
use URL;
|
||||
use File;
|
||||
|
||||
use App\Support\Totp;
|
||||
use App\Support\Pinyin;
|
||||
use App\Support\License;
|
||||
|
||||
use Gdoo\Hr\Models\Hr;
|
||||
use Gdoo\User\Models\UserPosition;
|
||||
use Gdoo\User\Models\User;
|
||||
|
||||
use Gdoo\Index\Controllers\DefaultController;
|
||||
|
||||
use function GuzzleHttp\json_encode;
|
||||
|
||||
class ProfileController extends DefaultController
|
||||
{
|
||||
public $permission = ['index', 'password', 'avatar', 'secret', 'getUser'];
|
||||
|
||||
// 资料修改
|
||||
public function indexAction()
|
||||
{
|
||||
if (Request::method() == 'POST') {
|
||||
$gets = Request::all();
|
||||
|
||||
$user = User::find(Auth::id());
|
||||
|
||||
$rules = [];
|
||||
|
||||
$v = Validator::make($gets, $rules);
|
||||
if ($v->fails()) {
|
||||
return $this->back()->withErrors($v);
|
||||
}
|
||||
$user->fill($gets);
|
||||
$user->save();
|
||||
return $this->json( '资料修改成功。', true);
|
||||
}
|
||||
|
||||
$t = new Totp();
|
||||
$secretURL = $t->getURL(Auth::user()->login, Request::server('HTTP_HOST'), Auth::user()->auth_secret);
|
||||
|
||||
$user = User::find(Auth::id());
|
||||
|
||||
return $this->display([
|
||||
'user' => $user,
|
||||
'secretURL' => $secretURL,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*
|
||||
*/
|
||||
public function getUserAction()
|
||||
{
|
||||
$user['avatar'] = avatar(auth()->user()->avatar);
|
||||
$user['name'] = auth()->user()->name;
|
||||
return json_encode($user, JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新安全密钥
|
||||
*
|
||||
*/
|
||||
public function secretAction()
|
||||
{
|
||||
if (Request::method() == 'POST') {
|
||||
$id = Request::get('id');
|
||||
$t = new Totp();
|
||||
$secretKey = $t->generateSecret();
|
||||
$data['auth_secret'] = $secretKey;
|
||||
User::where('id', $id)->update($data);
|
||||
return $this->json($secretKey, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* 修改密码 */
|
||||
public function passwordAction()
|
||||
{
|
||||
if (Request::method() == 'POST') {
|
||||
$gets = Request::all();
|
||||
|
||||
$user = User::find(Auth::id());
|
||||
|
||||
$rules = [
|
||||
'old_password' => 'required',
|
||||
'new_password' => 'required|confirmed|different:old_password',
|
||||
'new_password_confirmation' => 'required|different:old_password|same:new_password'
|
||||
];
|
||||
|
||||
$attributes = [
|
||||
'old_password' => '旧密码',
|
||||
'new_password' => '新密码',
|
||||
'new_password_confirmation' => '确认新密码'
|
||||
];
|
||||
|
||||
$v = Validator::make($gets, $rules, [], $attributes);
|
||||
if ($v->fails()) {
|
||||
return $this->json(join('<br>', $v->errors()->all()));
|
||||
}
|
||||
|
||||
// 旧密码不正确
|
||||
if (Hash::check($gets['old_password'], $user->getAuthPassword()) === false) {
|
||||
return $this->back()->withErrors(['old password' => 'old password 不正确。']);
|
||||
}
|
||||
|
||||
$user->password = bcrypt($gets['new_password']);
|
||||
$user->password_text = $gets['new_password'];
|
||||
$user->save();
|
||||
|
||||
return $this->json('密码修改成功。', true);
|
||||
}
|
||||
$user = User::find(Auth::id());
|
||||
return $this->display([
|
||||
'user' => $user,
|
||||
]);
|
||||
}
|
||||
|
||||
// 用户头像
|
||||
public function avatarAction()
|
||||
{
|
||||
$gets = Request::all();
|
||||
|
||||
if (Request::method() == 'POST') {
|
||||
|
||||
if (Request::hasFile('image')) {
|
||||
$rules = [
|
||||
'image' => 'image',
|
||||
];
|
||||
$v = Validator::make($gets, $rules);
|
||||
|
||||
if ($v->fails()) {
|
||||
return $this->back()->withErrors($v);
|
||||
}
|
||||
|
||||
$userId = Auth::id();
|
||||
|
||||
$avatar_path = upload_path('avatar');
|
||||
File::isDirectory($avatar_path) or File::makeDirectory($avatar_path, 0777, true, true);
|
||||
|
||||
$file = Request::file('image');
|
||||
$filename = $userId.'.'.$file->extension();
|
||||
|
||||
if ($file->move($avatar_path, $filename)) {
|
||||
$user = User::find($userId);
|
||||
$user->avatar = $filename;
|
||||
$user->save();
|
||||
return $this->json($filename, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->render();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php namespace Gdoo\User\Controllers;
|
||||
|
||||
use DB;
|
||||
use Request;
|
||||
|
||||
use Gdoo\Index\Controllers\DefaultController;
|
||||
|
||||
class RegionController extends DefaultController
|
||||
{
|
||||
public $permission = ['index', 'json'];
|
||||
|
||||
/**
|
||||
* 市列表
|
||||
*/
|
||||
public function indexAction()
|
||||
{
|
||||
$id = (int) Request::get('id', '0');
|
||||
$parent_id = (int) Request::get('parent_id', '0');
|
||||
$type = Request::get('type', 'province');
|
||||
$layer = 1;
|
||||
if ($type == 'city') {
|
||||
$layer = 2;
|
||||
} elseif ($type == 'county') {
|
||||
$layer = 3;
|
||||
}
|
||||
$model = DB::table('region');
|
||||
$model = $model->where('layer', $layer);
|
||||
if ($parent_id > 0) {
|
||||
$model->where('parent_id', $parent_id);
|
||||
}
|
||||
$_data = $model->get();
|
||||
if ($_data) {
|
||||
$data = array();
|
||||
foreach ($_data as $k => $v) {
|
||||
$selected = ($id == $v['id']) ? ' selected' : '';
|
||||
$data[] = '<option value="'.$v['id'].'"'.$selected.'>'.$v['name'].'</option>';
|
||||
}
|
||||
}
|
||||
echo join("\n", $data);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
<?php namespace Gdoo\User\Controllers;
|
||||
|
||||
use DB;
|
||||
use Auth;
|
||||
use Request;
|
||||
use Validator;
|
||||
use Collection;
|
||||
|
||||
use App\Support\Module;
|
||||
|
||||
use Gdoo\User\Models\User;
|
||||
use Gdoo\User\Models\Role;
|
||||
use Gdoo\User\Models\UserAsset;
|
||||
|
||||
use Gdoo\Model\Grid;
|
||||
use Gdoo\Model\Form;
|
||||
|
||||
use App\Support\License;
|
||||
use Arr;
|
||||
use Gdoo\Index\Controllers\DefaultController;
|
||||
use Gdoo\Model\Services\ModuleService;
|
||||
use Gdoo\User\Services\UserAssetService;
|
||||
|
||||
class RoleController extends DefaultController
|
||||
{
|
||||
public $permission = ['dialog', 'permission'];
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
$display = $this->access;
|
||||
|
||||
$header = Grid::header([
|
||||
'code' => 'role',
|
||||
'referer' => 1,
|
||||
'search' => ['by' => '', 'tab' => 'role'],
|
||||
]);
|
||||
|
||||
$cols = $header['cols'];
|
||||
$cols = Grid::addColumns($cols, 'code', [[
|
||||
'headerName' => '用户数',
|
||||
'field' => 'user_count',
|
||||
'footerRenderer' => 'sum',
|
||||
'width' => 60,
|
||||
'cellStyle' => ['text-align' => 'center'],
|
||||
]]);
|
||||
$cols['actions']['options'] = [[
|
||||
'name' => '编辑',
|
||||
'action' => 'edit',
|
||||
'display' => $display['edit'],
|
||||
]];
|
||||
unset($cols['checkbox']);
|
||||
|
||||
$cols['actions']['options'] = [[
|
||||
'name' => '权限',
|
||||
'action' => 'config',
|
||||
'display' => $this->access['config'],
|
||||
],[
|
||||
'name' => '编辑',
|
||||
'action' => 'edit',
|
||||
'display' => $this->access['edit'],
|
||||
]];
|
||||
|
||||
$search = $header['search_form'];
|
||||
$query = $search['query'];
|
||||
|
||||
if (Request::method() == 'POST') {
|
||||
$model = DB::table($header['table'])->setBy($header);
|
||||
foreach ($header['join'] as $join) {
|
||||
$model->leftJoin($join[0], $join[1], $join[2], $join[3]);
|
||||
}
|
||||
$model->orderBy('role.sort', 'asc');
|
||||
|
||||
foreach ($search['where'] as $where) {
|
||||
if ($where['active']) {
|
||||
$model->search($where);
|
||||
}
|
||||
}
|
||||
|
||||
$model->select($header['select'])
|
||||
->addSelect(DB::raw('(select count(id) from [user] where role_id = role.id) as user_count'));
|
||||
|
||||
$rows = $model->paginate($query['limit'])->appends($query);
|
||||
$items = Grid::dataFilters($rows, $header);
|
||||
return $items->toJson();
|
||||
}
|
||||
|
||||
$header['buttons'] = [
|
||||
['name' => '删除', 'icon' => 'fa-remove', 'action' => 'delete', 'display' => $this->access['delete']],
|
||||
];
|
||||
$header['cols'] = $cols;
|
||||
$header['tabs'] = User::$tabs;
|
||||
$header['bys'] = Role::$bys;
|
||||
$header['js'] = Grid::js($header);
|
||||
|
||||
return $this->display([
|
||||
'header' => $header,
|
||||
]);
|
||||
}
|
||||
|
||||
public function configAction()
|
||||
{
|
||||
$gets = Request::all();
|
||||
|
||||
$query = [
|
||||
'role_id' => 0,
|
||||
'clone_id' => 0,
|
||||
'key' => '',
|
||||
];
|
||||
|
||||
foreach ($query as $key => $value) {
|
||||
$query[$key] = Request::get($key, $value);
|
||||
}
|
||||
|
||||
if (Request::method() == 'POST') {
|
||||
$assets = DB::table('user_asset')->get();
|
||||
$assets = array_by($assets, 'name');
|
||||
$id = $gets['role_id'];
|
||||
|
||||
foreach ($gets['assets'] as $asset => $controllers) {
|
||||
|
||||
$rules = json_decode($assets[$asset]['rules'], true);
|
||||
|
||||
// 清除旧权限
|
||||
foreach ((array)$rules as $key => $rule) {
|
||||
if (empty($controllers[$key])) {
|
||||
unset($rules[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($controllers as $key => $actions) {
|
||||
unset($rules[$key][$id]);
|
||||
if ($actions['action']) {
|
||||
$rules[$key][$id] = $actions['action'];
|
||||
}
|
||||
}
|
||||
|
||||
$_asset = DB::table('user_asset')->where('name', $asset)->first();
|
||||
|
||||
$data = [
|
||||
'name' => $asset,
|
||||
'rules' => json_encode($rules),
|
||||
];
|
||||
|
||||
if (empty($_asset)) {
|
||||
DB::table('user_asset')->insert($data);
|
||||
} else {
|
||||
DB::table('user_asset')->where('id', $_asset['id'])->update($data);
|
||||
}
|
||||
}
|
||||
return $this->json('恭喜您,操作成功。', true);
|
||||
}
|
||||
|
||||
if ($gets['clone_id']) {
|
||||
$clone_id = $gets['clone_id'];
|
||||
} else {
|
||||
$clone_id = $gets['role_id'];
|
||||
}
|
||||
|
||||
$assets = UserAssetService::getRoleAssets($clone_id);
|
||||
$modules = ModuleService::allWithDetails();
|
||||
|
||||
$roles = Role::orderBy('lft', 'asc')->get()->toNested();
|
||||
|
||||
return $this->display([
|
||||
'assets' => $assets,
|
||||
'modules' => $modules,
|
||||
'query' => $query,
|
||||
'roles' => $roles,
|
||||
]);
|
||||
}
|
||||
|
||||
public function createAction()
|
||||
{
|
||||
$id = (int)Request::get('id');
|
||||
$form = Form::make(['code' => 'role', 'id' => $id]);
|
||||
return $this->render([
|
||||
'form' => $form,
|
||||
], 'create');
|
||||
}
|
||||
|
||||
public function editAction()
|
||||
{
|
||||
return $this->createAction();
|
||||
}
|
||||
|
||||
public function dialogAction()
|
||||
{
|
||||
$search = search_form([], [
|
||||
['text','role.name','名称'],
|
||||
['text','role.id','ID'],
|
||||
]);
|
||||
$query = $search['query'];
|
||||
|
||||
if (Request::method() == 'POST') {
|
||||
$model = Role::orderBy('lft', 'asc');
|
||||
|
||||
foreach ($search['where'] as $where) {
|
||||
if ($where['active']) {
|
||||
$model->search($where);
|
||||
}
|
||||
}
|
||||
|
||||
$rows = $model->get()->toNested('name');
|
||||
$data = [];
|
||||
foreach ($rows as $row) {
|
||||
$row['sid'] = 'r'.$row['id'];
|
||||
$data[] = $row;
|
||||
}
|
||||
return response()->json(['data' => $data]);
|
||||
}
|
||||
return $this->render([
|
||||
'search' => $search,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色设置
|
||||
*/
|
||||
public function permissionAction()
|
||||
{
|
||||
$gets = Request::all();
|
||||
if (Request::method() == 'POST') {
|
||||
$user_id = $gets['user_id'];
|
||||
$rows = $gets['rows'];
|
||||
$users = DB::table('user_role')
|
||||
->where('user_id', $user_id)
|
||||
->pluck('id', 'role_id');
|
||||
foreach($rows as $row) {
|
||||
if (empty($users[$row['id']])) {
|
||||
DB::table('user_role')->insert([
|
||||
'user_id' => $user_id,
|
||||
'role_id' => $row['id']
|
||||
]);
|
||||
} else {
|
||||
unset($users[$row['id']]);
|
||||
}
|
||||
}
|
||||
foreach($users as $warehouse_id) {
|
||||
DB::table('user_role')->where('id', $warehouse_id)->delete();
|
||||
}
|
||||
return $this->json('角色权限设置成功。', true);
|
||||
}
|
||||
$rows = DB::table('role')->orderBy('id', 'asc')->get(['id', 'code', 'name']);
|
||||
$users = DB::table('user_role')->where('user_id', $gets['user_id'])->pluck('id', 'role_id');
|
||||
return $this->render([
|
||||
'rows' => $rows,
|
||||
'users' => $users,
|
||||
]);
|
||||
}
|
||||
|
||||
// 删除角色
|
||||
public function deleteAction()
|
||||
{
|
||||
if (Request::method() == 'POST') {
|
||||
|
||||
$id = Request::get('id');
|
||||
$id = array_filter((array)$id);
|
||||
|
||||
if (empty($id)) {
|
||||
return $this->json('最少选择一行记录。');
|
||||
}
|
||||
|
||||
$has = Role::whereIn('parent_id', $id)->count();
|
||||
if ($has) {
|
||||
return $this->json('存在子节点不允许删除。');
|
||||
}
|
||||
|
||||
// 删除角色
|
||||
Role::whereIn('id', $id)->delete();
|
||||
|
||||
// 重构树形结构
|
||||
Role::treeRebuild();
|
||||
|
||||
return $this->json('删除成功。', true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php namespace Gdoo\User\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Session;
|
||||
use Request;
|
||||
|
||||
use App\Support\JWT;
|
||||
|
||||
use Gdoo\User\Models\User;
|
||||
use Gdoo\Index\Models\Access;
|
||||
|
||||
use Gdoo\Index\Controllers\Controller;
|
||||
use Gdoo\User\Services\UserAssetService;
|
||||
|
||||
class TokenController extends Controller
|
||||
{
|
||||
protected function createToken($userId)
|
||||
{
|
||||
$payload = array(
|
||||
'sub' => $userId,
|
||||
'iat' => time(),
|
||||
// 一年有效
|
||||
'exp' => time() + (365 * 24 * 60 * 60),
|
||||
);
|
||||
return JWT::encode($payload, config('app.key'));
|
||||
}
|
||||
|
||||
/**
|
||||
* APP登录
|
||||
*/
|
||||
public function loginAction()
|
||||
{
|
||||
if (Request::isJson()) {
|
||||
$gets = json_decode(Request::getContent(), true);
|
||||
} else {
|
||||
$gets = Request::all();
|
||||
}
|
||||
|
||||
if (empty($gets['username'])) {
|
||||
return response()->json(['message'=>'账户不能为空。','success'=>false]);
|
||||
}
|
||||
|
||||
if (empty($gets['password'])) {
|
||||
return response()->json(['message'=>'密码不能为空。','success'=>false]);
|
||||
}
|
||||
|
||||
$credentials = [
|
||||
'username' => $gets['username'],
|
||||
'password' => $gets['password'],
|
||||
'status' => 1
|
||||
];
|
||||
|
||||
if (Auth::validate($credentials)) {
|
||||
$user = User::where('username', $gets['username'])->first();
|
||||
|
||||
if ($user['auth_device']) {
|
||||
if (empty($gets['deviceId'])) {
|
||||
return response()->json(['message'=>'设备ID不能为空。','success'=>false]);
|
||||
}
|
||||
|
||||
// 设备ID为空时自动绑定
|
||||
if ($user['auth_device_id'] == '') {
|
||||
$user->auth_device_id = $gets['deviceId'];
|
||||
} else {
|
||||
// 存在设备ID检查是否匹配
|
||||
$auth_device_id = explode(PHP_EOL, $user['auth_device_id']);
|
||||
if (in_array($gets['deviceId'], $auth_device_id) == false) {
|
||||
return response()->json(['message'=>'设备ID错误,请联系相关人员。','success'=>false]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 保存用户表数据
|
||||
$user->save();
|
||||
|
||||
$assets = UserAssetService::getRoleAssets($user->role_id);
|
||||
return response()->json([
|
||||
'token' => $this->createToken($user->id),
|
||||
'access' => $assets,
|
||||
'user' => $user,
|
||||
'success' => 1,
|
||||
]);
|
||||
}
|
||||
return response()->json(['message'=>'账户或密码错误。', 'success'=>false]);
|
||||
}
|
||||
|
||||
public function logoutAction()
|
||||
{
|
||||
return response('注销完成。');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
<?php namespace Gdoo\User\Controllers;
|
||||
|
||||
use DB;
|
||||
use Auth;
|
||||
use Hash;
|
||||
use Request;
|
||||
use Validator;
|
||||
|
||||
use App\Support\Totp;
|
||||
use App\Support\Pinyin;
|
||||
use App\Support\License;
|
||||
|
||||
use Gdoo\Model\Grid;
|
||||
use Gdoo\Model\Form;
|
||||
|
||||
use Gdoo\User\Models\User;
|
||||
|
||||
use Gdoo\Index\Controllers\DefaultController;
|
||||
|
||||
class UserController extends DefaultController
|
||||
{
|
||||
public $permission = ['dialog'];
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
$header = Grid::header([
|
||||
'code' => 'user',
|
||||
'referer' => 1,
|
||||
'search' => ['by' => 'enabled', 'tab' => 'user'],
|
||||
]);
|
||||
|
||||
$cols = $header['cols'];
|
||||
|
||||
if (auth()->id() == 1) {
|
||||
$cols = Grid::addColumns($cols, 'id', [[
|
||||
'headerName' => '密码',
|
||||
'field' => 'password_text',
|
||||
'width' => 100,
|
||||
'cellStyle' => ['text-align' => 'center'],
|
||||
]]);
|
||||
}
|
||||
|
||||
$cols['actions']['options'] = [[
|
||||
'name' => '显示',
|
||||
'action' => 'show',
|
||||
'display' => $this->access['show'],
|
||||
],[
|
||||
'name' => '编辑',
|
||||
'action' => 'edit',
|
||||
'display' => $this->access['edit'],
|
||||
]];
|
||||
|
||||
$search = $header['search_form'];
|
||||
$query = $search['query'];
|
||||
|
||||
if (Request::method() == 'POST') {
|
||||
$model = DB::table($header['table'])->setBy($header);
|
||||
foreach ($header['join'] as $join) {
|
||||
$model->leftJoin($join[0], $join[1], $join[2], $join[3]);
|
||||
}
|
||||
$model->orderBy($header['sort'], $header['order'])
|
||||
->where('user.group_id', 1);
|
||||
|
||||
foreach ($search['where'] as $where) {
|
||||
if ($where['active']) {
|
||||
$model->search($where);
|
||||
}
|
||||
}
|
||||
|
||||
$header['select'][] = 'password_text';
|
||||
$model->select($header['select']);
|
||||
|
||||
$rows = $model->paginate($query['limit'])->appends($query);
|
||||
$items = Grid::dataFilters($rows, $header);
|
||||
return $items->toJson();
|
||||
}
|
||||
|
||||
$header['buttons'] = [
|
||||
['name' => '删除', 'icon' => 'fa-remove', 'action' => 'delete', 'display' => $this->access['delete']],
|
||||
['name' => '导出', 'icon' => 'fa-share', 'action' => 'export', 'display' => 1],
|
||||
];
|
||||
|
||||
$header['left_buttons'] = [
|
||||
['name' => '角色权限', 'color' => 'default', 'action' => 'user_role', 'display' => 1],
|
||||
['name' => '仓库权限', 'color' => 'default', 'action' => 'user_warehouse', 'display' => 1],
|
||||
];
|
||||
|
||||
$header['right_buttons'] = [
|
||||
['name' => '导入', 'color' => 'default', 'icon' => 'fa-mail-reply', 'action' => 'import', 'display' => $this->access['import']],
|
||||
];
|
||||
|
||||
$header['cols'] = $cols;
|
||||
$header['tabs'] = User::$tabs;
|
||||
$header['bys'] = User::$bys;
|
||||
$header['js'] = Grid::js($header);
|
||||
|
||||
return $this->display([
|
||||
'header' => $header,
|
||||
]);
|
||||
}
|
||||
|
||||
// 显示用户
|
||||
public function showAction()
|
||||
{
|
||||
$id = (int)Request::get('id');
|
||||
$form = Form::make(['code' => 'user', 'id' => $id, 'action' => 'show']);
|
||||
|
||||
$t = new Totp();
|
||||
$form['row']['secret_qrcode'] = $t->getURL($form['row']['login'], Request::server('HTTP_HOST'), $form['row']['auth_secret']);
|
||||
|
||||
return $this->display([
|
||||
'form' => $form,
|
||||
], 'create');
|
||||
}
|
||||
|
||||
// 新建用户
|
||||
public function createAction()
|
||||
{
|
||||
$id = (int)Request::get('id');
|
||||
$form = Form::make(['code' => 'user', 'id' => $id]);
|
||||
return $this->display([
|
||||
'form' => $form,
|
||||
], 'create');
|
||||
}
|
||||
|
||||
// 编辑用户
|
||||
public function editAction()
|
||||
{
|
||||
return $this->createAction();
|
||||
}
|
||||
|
||||
public function dialogAction()
|
||||
{
|
||||
$group_id = Request::get('group_id', 1);
|
||||
$header = Grid::header([
|
||||
'code' => 'user',
|
||||
]);
|
||||
$search = $header['search_form'];
|
||||
$query = $search['query'];
|
||||
if (Request::method() == 'POST') {
|
||||
$model = DB::table('user');
|
||||
foreach ($header['join'] as $join) {
|
||||
$model->leftJoin($join[0], $join[1], $join[2], $join[3]);
|
||||
}
|
||||
$model->where('user.status', 1)
|
||||
->where('user.group_id', (int)$group_id);
|
||||
|
||||
// 排序方式
|
||||
if ($query['sort'] && $query['order']) {
|
||||
$model->orderBy($query['sort'], $query['order']);
|
||||
}
|
||||
|
||||
// 搜索条件
|
||||
foreach ($search['where'] as $where) {
|
||||
if ($where['active']) {
|
||||
$model->search($where);
|
||||
}
|
||||
}
|
||||
$model->selectRaw("
|
||||
[user].id,
|
||||
concat('u', [user].id) as sid,
|
||||
[user].role_id,
|
||||
[user].status,
|
||||
[user].username,
|
||||
[user].name,
|
||||
[user].name as text,
|
||||
[user].email,
|
||||
[user].phone
|
||||
");
|
||||
$rows = $model->paginate($query['limit']);
|
||||
|
||||
return response()->json($rows);
|
||||
}
|
||||
return $this->render(array(
|
||||
'search' => $search,
|
||||
'query' => $query,
|
||||
));
|
||||
}
|
||||
|
||||
// 数据导入
|
||||
public function importAction()
|
||||
{
|
||||
if (Request::method() == 'POST') {
|
||||
return Form::import([
|
||||
'table' => 'user',
|
||||
'keys' => ['username'],
|
||||
'defaults' => ['group_id' => 1],
|
||||
]);
|
||||
}
|
||||
$tips = '注意:表格里必须包含[用户名]列。';
|
||||
return $this->render(['tips' => $tips], 'layouts.import');
|
||||
}
|
||||
|
||||
// 账户删除
|
||||
public function deleteAction()
|
||||
{
|
||||
if (Request::method() == 'POST') {
|
||||
$ids = Request::get('id');
|
||||
return Form::remove(['code' => 'user', 'ids' => $ids]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php namespace Gdoo\User\Controllers;
|
||||
|
||||
use DB;
|
||||
use Gdoo\Index\Controllers\DefaultController;
|
||||
|
||||
class WidgetController extends DefaultController
|
||||
{
|
||||
public $permission = ['birthday'];
|
||||
|
||||
// 生日提醒
|
||||
public function birthdayAction()
|
||||
{
|
||||
$rows = DB::table('user')->whereRaw("concat(year(getdata()), DATE_FORMAT(birthday,'-%m-%d')) BETWEEN DATE_FORMAT(getdate(),'%Y-%m-%d') AND DATE_FORMAT(DATE_ADD(getdate(), interval 30 day),'%Y-%m-%d')")->get();
|
||||
return $this->render(array(
|
||||
'rows' => $rows,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php namespace Gdoo\User\Hooks;
|
||||
|
||||
use DB;
|
||||
use Gdoo\User\Models\Department;
|
||||
|
||||
class DepartmentHook
|
||||
{
|
||||
static $linkOptions = [];
|
||||
|
||||
public function onBeforeForm($params) {
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function onAfterForm($params) {
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function onBeforeStore($params) {
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function onAfterStore($params) {
|
||||
Department::treeRebuild();
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function onBeforeDelete($params) {
|
||||
return $params;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php namespace Gdoo\User\Hooks;
|
||||
|
||||
use DB;
|
||||
use Gdoo\User\Models\Role;
|
||||
|
||||
class RoleHook
|
||||
{
|
||||
static $linkOptions = [];
|
||||
|
||||
public function onBeforeForm($params) {
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function onAfterForm($params) {
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function onBeforeStore($params)
|
||||
{
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function onAfterStore($params) {
|
||||
Role::treeRebuild();
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function onBeforeDelete($params) {
|
||||
return $params;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php namespace Gdoo\User\Hooks;
|
||||
|
||||
use DB;
|
||||
use Gdoo\User\Models\User;
|
||||
|
||||
class UserHook
|
||||
{
|
||||
static $linkOptions = [];
|
||||
|
||||
public function onBeforeForm($params) {
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function onAfterForm($params) {
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function onBeforeStore($params)
|
||||
{
|
||||
$gets = $params['gets'];
|
||||
$_user = $gets['user'];
|
||||
|
||||
// 设置用户组
|
||||
$_user['group_id'] = 1;
|
||||
|
||||
$user = User::findOrNew($_user['id']);
|
||||
|
||||
if ($_user['password']) {
|
||||
$user->password = bcrypt($_user['password']);
|
||||
$user->password_text = $_user['password'];
|
||||
}
|
||||
|
||||
$user->fill($_user)->save();
|
||||
|
||||
// 终止执行的进程后
|
||||
$params['terminate'] = false;
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function onAfterStore($params) {
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function onBeforeDelete($params) {
|
||||
return $params;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php namespace Gdoo\User\Models;
|
||||
|
||||
use Gdoo\Index\Models\BaseModel;
|
||||
|
||||
class Department extends BaseModel
|
||||
{
|
||||
protected $table = 'department';
|
||||
|
||||
static public $bys = [
|
||||
'name' => 'by',
|
||||
'items' => [
|
||||
['value' => '', 'name' => '全部'],
|
||||
['value' => 'divider'],
|
||||
['value' => 'day', 'name' => '今日创建'],
|
||||
['value' => 'week', 'name' => '本周创建'],
|
||||
['value' => 'month', 'name' => '本月创建'],
|
||||
]
|
||||
];
|
||||
|
||||
public function users()
|
||||
{
|
||||
return $this->hasMany(User::class);
|
||||
}
|
||||
|
||||
public function scopeDialog($q, $value)
|
||||
{
|
||||
return $q->whereIn('id', $value)
|
||||
->pluck('name', 'id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php namespace Gdoo\User\Models;
|
||||
|
||||
use Gdoo\Index\Models\BaseModel;
|
||||
|
||||
class Message extends BaseModel
|
||||
{
|
||||
protected $table = 'user_message';
|
||||
|
||||
static public $tabs = [
|
||||
'name' => 'tab',
|
||||
'items' => [
|
||||
['value' => 'message', 'url' => 'user/message/index', 'name' => '通知提醒'],
|
||||
]
|
||||
];
|
||||
|
||||
static public $bys = [
|
||||
'name' => 'status',
|
||||
'items' => [
|
||||
['value' => '', 'name' => '全部'],
|
||||
['value' => 'unread', 'name' => '未读'],
|
||||
['value' => 'read', 'name' => '已读'],
|
||||
]
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php namespace Gdoo\User\Models;
|
||||
|
||||
use Gdoo\Index\Models\BaseModel;
|
||||
|
||||
class Role extends BaseModel
|
||||
{
|
||||
protected $table = 'role';
|
||||
|
||||
static public $bys = [
|
||||
'name' => 'by',
|
||||
'items' => [
|
||||
['value' => '', 'name' => '全部'],
|
||||
['value' => 'divider'],
|
||||
['value' => 'day', 'name' => '今日创建'],
|
||||
['value' => 'week', 'name' => '本周创建'],
|
||||
['value' => 'month', 'name' => '本月创建'],
|
||||
]
|
||||
];
|
||||
|
||||
public function scopeDialog($q, $value)
|
||||
{
|
||||
return $q->whereIn('id', $value)
|
||||
->pluck('name', 'id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php namespace Gdoo\User\Models;
|
||||
|
||||
use Illuminate\Auth\Authenticatable;
|
||||
use Illuminate\Auth\Passwords\CanResetPassword;
|
||||
use Illuminate\Foundation\Auth\Access\Authorizable;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
|
||||
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
|
||||
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
use Gdoo\Index\Models\BaseModel;
|
||||
|
||||
class User extends BaseModel implements
|
||||
AuthenticatableContract,
|
||||
AuthorizableContract,
|
||||
CanResetPasswordContract
|
||||
{
|
||||
use Authenticatable, Authorizable, CanResetPassword, Notifiable;
|
||||
|
||||
protected $table = 'user';
|
||||
|
||||
static public $tabs = [
|
||||
'name' => 'tab',
|
||||
'items' => [
|
||||
['value' => 'user', 'url' => 'user/user/index', 'name' => '用户'],
|
||||
['value' => 'role', 'url' => 'user/role/index', 'name' => '角色'],
|
||||
['value' => 'department', 'url' => 'user/department/index', 'name' => '部门'],
|
||||
['value' => 'group', 'url' => 'user/group/index', 'name' => '用户组'],
|
||||
['value' => 'position', 'url' => 'user/position/index', 'name' => '职位'],
|
||||
]
|
||||
];
|
||||
|
||||
static public $bys = [
|
||||
'name' => 'by',
|
||||
'items' => [
|
||||
['value' => '', 'name' => '全部'],
|
||||
['value' => 'enabled', 'name' => '启用'],
|
||||
['value' => 'disabled', 'name' => '禁用'],
|
||||
['value' => 'divider'],
|
||||
['value' => 'day', 'name' => '今日创建'],
|
||||
['value' => 'week', 'name' => '本周创建'],
|
||||
['value' => 'month', 'name' => '本月创建'],
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes excluded from the model's JSON form.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hidden = ['password', 'password_text', 'remember_token', 'auth_secret'];
|
||||
|
||||
/**
|
||||
* 设置字段黑名单
|
||||
*/
|
||||
protected $guarded = ['id', 'password'];
|
||||
|
||||
public function department()
|
||||
{
|
||||
return $this->belongsTo('Gdoo\User\Models\Department');
|
||||
}
|
||||
|
||||
public function customer()
|
||||
{
|
||||
return $this->hasOne('Gdoo\Customer\Models\Customer');
|
||||
}
|
||||
|
||||
public function supplier()
|
||||
{
|
||||
return $this->hasOne('Gdoo\Supplier\Models\Supplier');
|
||||
}
|
||||
|
||||
public function role()
|
||||
{
|
||||
return $this->belongsTo('Gdoo\User\Models\Role');
|
||||
}
|
||||
|
||||
public function hr()
|
||||
{
|
||||
return $this->hasOne('Gdoo\Hr\Models\Hr');
|
||||
}
|
||||
|
||||
public function position()
|
||||
{
|
||||
return $this->belongsTo('Gdoo\User\Models\UserPosition', 'post');
|
||||
}
|
||||
|
||||
public function tasks()
|
||||
{
|
||||
return $this->belongsToMany('Gdoo\Project\Models\Task');
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户组
|
||||
*/
|
||||
public function scopeGroup($q, $type)
|
||||
{
|
||||
$group = UserGroup::where('key', $type)->first();
|
||||
return $q->where('user.group_id', $group->id);
|
||||
}
|
||||
|
||||
public function scopeDialog($q, $value)
|
||||
{
|
||||
return $q->whereIn('id', $value)->pluck('name', 'id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php namespace Gdoo\User\Models;
|
||||
|
||||
use Auth;
|
||||
use Request;
|
||||
use Gdoo\Index\Models\BaseModel;
|
||||
|
||||
class UserAsset extends BaseModel
|
||||
{
|
||||
protected $table = 'user_asset';
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php namespace Gdoo\User\Models;
|
||||
|
||||
use Gdoo\Index\Models\BaseModel;
|
||||
|
||||
class UserGroup extends BaseModel
|
||||
{
|
||||
protected $table = 'user_group';
|
||||
|
||||
public static $tabs = [
|
||||
'name' => 'tab',
|
||||
'items' => [
|
||||
['value' => 'group.index', 'url' => 'user/group/index', 'name' => '用户组列表'],
|
||||
]
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php namespace Gdoo\User\Models;
|
||||
|
||||
use Gdoo\Index\Models\BaseModel;
|
||||
|
||||
class UserPosition extends BaseModel
|
||||
{
|
||||
protected $table = 'user_position';
|
||||
|
||||
public static $tabs = [
|
||||
'name' => 'tab',
|
||||
'items' => [
|
||||
['value' => 'position.index', 'url' => 'user/position/index', 'name' => '职位列表'],
|
||||
]
|
||||
];
|
||||
|
||||
public function scopeDialog($q, $value)
|
||||
{
|
||||
return $q->whereIn('id', $value)
|
||||
->pluck('name', 'id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php namespace Gdoo\User\Models;
|
||||
|
||||
use Gdoo\Index\Models\BaseModel;
|
||||
|
||||
class UserWidget extends BaseModel
|
||||
{
|
||||
protected $table = 'user_widget';
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php namespace Gdoo\User\Services;
|
||||
|
||||
use Auth;
|
||||
use Request;
|
||||
|
||||
use Gdoo\User\Models\UserAsset;
|
||||
|
||||
class UserAssetService
|
||||
{
|
||||
protected static $permissions = [];
|
||||
|
||||
public static function setPermissions($permissions)
|
||||
{
|
||||
self::$permissions = $permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查权限
|
||||
*/
|
||||
public static function check($role_id, $action, $asset)
|
||||
{
|
||||
static $assets = null;
|
||||
|
||||
if ($assets == null) {
|
||||
$assets = static::getRoleAssets($role_id);
|
||||
}
|
||||
|
||||
// 授权访问
|
||||
if (isset($assets[$asset][$action])) {
|
||||
return $assets[$asset][$action];
|
||||
}
|
||||
|
||||
// 跳过ACL检查的方法
|
||||
if (in_array(Request::action(), static::$permissions)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static function getAssets()
|
||||
{
|
||||
static $assets = null;
|
||||
|
||||
if ($assets == null) {
|
||||
$assets = UserAsset::get(['id', 'name', 'rules'])->toArray();
|
||||
}
|
||||
return $assets;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色资源
|
||||
*/
|
||||
public static function getRoleAssets($roleId)
|
||||
{
|
||||
static $assets = null;
|
||||
|
||||
if ($assets == null) {
|
||||
$assets = static::getAssets();
|
||||
}
|
||||
|
||||
foreach ($assets as $key => $asset) {
|
||||
$rules = (array)json_decode($asset['rules'], true);
|
||||
|
||||
foreach ($rules as $key => $rule) {
|
||||
if (isset($rule[$roleId])) {
|
||||
$res[$asset['name']][$key] = ($rule[$roleId] > 0 ? $rule[$roleId] : 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色资源
|
||||
*/
|
||||
public static function getNowRoleAssets()
|
||||
{
|
||||
$res = [];
|
||||
$assets = static::getRoleAssets(Auth::user()->role_id);
|
||||
|
||||
$assets = $assets[Request::module()];
|
||||
if ($assets) {
|
||||
foreach ($assets as $key => $asset) {
|
||||
list($controller, $action) = explode('.', $key);
|
||||
if ($controller == Request::controller()) {
|
||||
$res[$action] = $asset;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色资源
|
||||
*/
|
||||
public static function getRoleAuthorise($roleId)
|
||||
{
|
||||
static $assets = null;
|
||||
|
||||
if ($assets == null) {
|
||||
$assets = static::getAssets();
|
||||
}
|
||||
|
||||
foreach ($assets as $key => $asset) {
|
||||
$rules = (array)json_decode($asset['rules'], true);
|
||||
|
||||
foreach ($rules as $key => $rule) {
|
||||
if (isset($rule[$roleId])) {
|
||||
$key = str_replace('.', '/', $asset['name'].'/'.$key);
|
||||
$res[$key] = ($rule[$roleId] > 0 ? $rule[$roleId] : 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
<?php namespace Gdoo\User\Services;
|
||||
|
||||
use Auth;
|
||||
use Request;
|
||||
use DB;
|
||||
use Session;
|
||||
|
||||
use Gdoo\User\Models\Department;
|
||||
use Gdoo\User\Models\User;
|
||||
use AIke\User\Models\UserAsset;
|
||||
use Gdoo\User\Models\Role;
|
||||
|
||||
use Gdoo\System\Models\SystemLog;
|
||||
|
||||
class UserService
|
||||
{
|
||||
public static function getUser($user_id = 0) {
|
||||
$user = null;
|
||||
if ($user_id == 0) {
|
||||
$user = auth()->user();
|
||||
}
|
||||
$user = User::find($user_id);
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证权限
|
||||
*/
|
||||
public static function authorise($action = null, $asset_name = null)
|
||||
{
|
||||
if ($asset_name === null) {
|
||||
$asset_name = Request::module();
|
||||
}
|
||||
|
||||
if ($action === null) {
|
||||
$action = Request::controller().'.'.Request::action();
|
||||
} else {
|
||||
if (substr_count($action, '.') === 0) {
|
||||
$action = Request::controller().'.'.$action;
|
||||
}
|
||||
}
|
||||
|
||||
return UserAssetService::check(Auth::user()->role_id, $action, $asset_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证查看权限
|
||||
*/
|
||||
public static function authoriseAccess($action = null, $asset_name = null)
|
||||
{
|
||||
$level = static::authorise($action, $asset_name);
|
||||
|
||||
$user = Auth::user();
|
||||
|
||||
// 本人
|
||||
if ($level == 1) {
|
||||
return [$user->id];
|
||||
}
|
||||
|
||||
// 本人和下属
|
||||
if ($level == 2) {
|
||||
$roles = Role::from(DB::raw('role as node, role as parent'))
|
||||
->select(['node.id'])
|
||||
->whereRaw('node.lft BETWEEN parent.lft AND parent.rgt')
|
||||
->where('parent.id', $user->role_id)
|
||||
->pluck('id');
|
||||
return User::whereIn('role_id', $roles)->pluck('id')->toArray();
|
||||
}
|
||||
|
||||
// 部门所有人
|
||||
if ($level == 3) {
|
||||
$departments = Department::from(DB::raw('department as node, department as parent'))
|
||||
->select(['node.id'])
|
||||
->whereRaw('node.lft BETWEEN parent.lft AND parent.rgt')
|
||||
->where('parent.id', $user->department_id)
|
||||
->pluck('id');
|
||||
return User::whereIn('department_id', $departments)->pluck('id')->toArray();
|
||||
}
|
||||
|
||||
// 销售团队
|
||||
if ($level == 5) {
|
||||
$regions = DB::table('customer_region')->get()->toNested();
|
||||
// 审批权限
|
||||
$owners = DB::table('customer_region')
|
||||
->where('owner_user_id', $user->id)
|
||||
->get()->toArray();
|
||||
// 查询权限
|
||||
$assists = DB::table('customer_region')
|
||||
->whereRaw(db_instr('owner_assist', $user->id))
|
||||
->get()->toArray();
|
||||
$ids = [];
|
||||
foreach($owners as $v) {
|
||||
$ids = array_merge($ids, $regions[$v['id']]['parent']);
|
||||
$ids = array_merge($ids, $regions[$v['id']]['child']);
|
||||
}
|
||||
foreach($assists as $v) {
|
||||
$ids = array_merge($ids, $regions[$v['id']]['parent']);
|
||||
$ids = array_merge($ids, $regions[$v['id']]['child']);
|
||||
}
|
||||
$user_ids = [];
|
||||
foreach($regions as $region) {
|
||||
if (in_array($region['id'], $ids)) {
|
||||
if ($region['owner_user_id']) {
|
||||
$user_ids = array_merge($user_ids, [$region['owner_user_id']]);
|
||||
}
|
||||
if ($region['owner_assist']) {
|
||||
$user_ids = array_merge($user_ids, explode(',', $region['owner_user_id']));
|
||||
}
|
||||
}
|
||||
}
|
||||
return $user_ids;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查动态密码
|
||||
*/
|
||||
public static function wantsTotp()
|
||||
{
|
||||
if (env('AUTH_TOTP_STATUS', true) == false) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$auth_totp = Auth::user()->auth_totp;
|
||||
|
||||
if ($auth_totp == 0) {
|
||||
return 0;
|
||||
} elseif ($auth_totp == 1 && Session::get('auth_totp') == true) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得用户列表
|
||||
*/
|
||||
public static function getAll($userId = 0)
|
||||
{
|
||||
static $data = [];
|
||||
|
||||
if (empty($data)) {
|
||||
$data = User::get(['id', 'department_id', 'role_id', 'username', 'name', 'email', 'phone', 'birthday', 'gender'])->keyBy('id');
|
||||
}
|
||||
|
||||
return $userId > 0 ? $data[$userId] : $data;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 传入部门编号,角色编码,用户编码,进行并集处理返回用户编号
|
||||
*/
|
||||
public static function getDRU($receive_id, $status = 1)
|
||||
{
|
||||
if ($receive_id == '') {
|
||||
return [];
|
||||
}
|
||||
$receives = explode(',', str_replace(['u', 'r', 'd'], ['u_', 'r_', 'd_'], $receive_id));
|
||||
|
||||
$scope = [];
|
||||
foreach ($receives as $receive) {
|
||||
list($type, $id) = explode('_', $receive);
|
||||
$scope[$type][] = $id;
|
||||
}
|
||||
|
||||
return DB::table('user')
|
||||
->where('status', $status)
|
||||
->where(function ($q) use ($scope) {
|
||||
if ($scope['d']) {
|
||||
$q->orwhereIn('department_id', $scope['d']);
|
||||
}
|
||||
if ($scope['r']) {
|
||||
$q->orwhereIn('role_id', $scope['r']);
|
||||
}
|
||||
if ($scope['u']) {
|
||||
$q->orwhereIn('id', $scope['u']);
|
||||
}
|
||||
})->get(['id', 'role_id', 'department_id', 'username', 'name', 'email', 'phone']);
|
||||
}
|
||||
|
||||
// 登录失败,记录错误信息
|
||||
public static function authLogWrite($ip)
|
||||
{
|
||||
$log = SystemLog::where('ip', $ip)->first();
|
||||
|
||||
$data['ip'] = $ip;
|
||||
if ($log->id) {
|
||||
$data['error_count'] = $log->error_count + 1;
|
||||
SystemLog::where('ip', $ip)->update($data);
|
||||
} else {
|
||||
$data['error_count'] = 1;
|
||||
SystemLog::insert($data);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取记录,没有记录返回空
|
||||
public static function authLogRead($ip)
|
||||
{
|
||||
return SystemLog::where('ip', $ip)->first();
|
||||
}
|
||||
|
||||
// 登录成功,销毁错误信息
|
||||
public static function authLogDelete($ip)
|
||||
{
|
||||
SystemLog::where('ip', $ip)->delete();
|
||||
}
|
||||
|
||||
// 检查IP
|
||||
public static function authLogCheckIp($ip, $auth_ip)
|
||||
{
|
||||
if (empty($auth_ip)) {
|
||||
return true;
|
||||
}
|
||||
$auth_ip = explode(PHP_EOL, $auth_ip);
|
||||
return ($auth_ip && in_array($ip, $auth_ip));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
return [
|
||||
"name" => "组织架构",
|
||||
"version" => "1.0",
|
||||
"description" => "账户、职位、角色权限、部门管理。",
|
||||
"listens" => [
|
||||
'user' => 'Gdoo\User\Hooks\UserHook',
|
||||
'role' => 'Gdoo\User\Hooks\RoleHook',
|
||||
'department' => 'Gdoo\User\Hooks\DepartmentHook',
|
||||
],
|
||||
'dialogs' => [
|
||||
'department' => [
|
||||
'name' => '部门',
|
||||
'model' => 'Gdoo\User\Models\Department::Dialog',
|
||||
'url' => 'user/department/dialog',
|
||||
],
|
||||
'role' => [
|
||||
'name' => '角色',
|
||||
'model' => 'Gdoo\User\Models\Role::Dialog',
|
||||
'url' => 'user/role/dialog',
|
||||
],
|
||||
'position' => [
|
||||
'name' => '职位',
|
||||
'model' => 'Gdoo\User\Models\UserPosition::Dialog',
|
||||
'url' => 'user/position/dialog',
|
||||
],
|
||||
'user' => [
|
||||
'name' => '用户',
|
||||
'model' => 'Gdoo\User\Models\User::Dialog',
|
||||
'url' => 'user/user/dialog',
|
||||
],
|
||||
],
|
||||
"controllers" => [
|
||||
"user" => [
|
||||
"name" => "用户",
|
||||
"actions" => [
|
||||
"index" => [
|
||||
"name" => "列表"
|
||||
],
|
||||
"show" => [
|
||||
"name" => "查看"
|
||||
],
|
||||
"create" => [
|
||||
"name" => "新建"
|
||||
],
|
||||
"edit" => [
|
||||
"name" => "编辑"
|
||||
],
|
||||
"import" => [
|
||||
"name" => "导入"
|
||||
],
|
||||
"delete" => [
|
||||
"name" => "删除"
|
||||
],
|
||||
"secret" => [
|
||||
"name" => "密钥"
|
||||
]
|
||||
]
|
||||
],
|
||||
"department" => [
|
||||
"name" => "部门",
|
||||
"actions" => [
|
||||
"index" => [
|
||||
"name" => "列表"
|
||||
],
|
||||
"show" => [
|
||||
"name" => "查看"
|
||||
],
|
||||
"create" => [
|
||||
"name" => "新建"
|
||||
],
|
||||
"edit" => [
|
||||
"name" => "编辑"
|
||||
],
|
||||
"delete" => [
|
||||
"name" => "删除"
|
||||
],
|
||||
]
|
||||
],
|
||||
"role" => [
|
||||
"name" => "角色",
|
||||
"actions" => [
|
||||
"index" => [
|
||||
"name" => "列表"
|
||||
],
|
||||
"show" => [
|
||||
"name" => "查看"
|
||||
],
|
||||
"create" => [
|
||||
"name" => "新建"
|
||||
],
|
||||
"edit" => [
|
||||
"name" => "编辑"
|
||||
],
|
||||
"config" => [
|
||||
"name" => "控制器权限"
|
||||
],
|
||||
"delete" => [
|
||||
"name" => "删除"
|
||||
],
|
||||
]
|
||||
],
|
||||
"group" => [
|
||||
"name" => "用户组",
|
||||
"actions" => [
|
||||
"index" => [
|
||||
"name" => "列表"
|
||||
],
|
||||
"create" => [
|
||||
"name" => "新建"
|
||||
],
|
||||
"edit" => [
|
||||
"name" => "编辑"
|
||||
],
|
||||
"delete" => [
|
||||
"name" => "删除"
|
||||
]
|
||||
]
|
||||
],
|
||||
"position" => [
|
||||
"name" => "用户职位",
|
||||
"actions" => [
|
||||
"index" => [
|
||||
"name" => "列表"
|
||||
],
|
||||
"create" => [
|
||||
"name" => "新建"
|
||||
],
|
||||
"edit" => [
|
||||
"name" => "编辑"
|
||||
],
|
||||
"delete" => [
|
||||
"name" => "删除"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
@@ -0,0 +1,225 @@
|
||||
<style>
|
||||
body {
|
||||
text-align: center;
|
||||
background-image: url({{$asset_url}}/images/login-bg2.jpg);
|
||||
background-repeat: no-repeat;
|
||||
height: 100vh;
|
||||
background-attachment: scroll;
|
||||
background-position: center center;
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
}
|
||||
.content-body {
|
||||
margin: 0;
|
||||
}
|
||||
.overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index: 0;
|
||||
background: rgba(0, 0, 0, 0.50);
|
||||
background: linear-gradient(to bottom, rgba(25, 137, 250, 0.65), rgba(25, 137, 250, 0.35));
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #fff;
|
||||
}
|
||||
.text-muted a {
|
||||
color: #fff;
|
||||
}
|
||||
.login-box {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
text-align: left;
|
||||
max-width: 750px;
|
||||
}
|
||||
.login-box .h5 {
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
}
|
||||
.toast {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.login-box {
|
||||
padding-top: 220px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
padding: 20px;
|
||||
padding-top: 60px;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.text-title {
|
||||
font-weight: 500;
|
||||
font-size: 36px;
|
||||
}
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
border-top: solid 1px rgba(255, 255, 255, 0.3);
|
||||
text-align: right;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.login-box {
|
||||
padding-top: 60px;
|
||||
}
|
||||
.logo-text {
|
||||
text-align: center;
|
||||
}
|
||||
.row {
|
||||
margin-left: 15px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
.footer {
|
||||
border-top: 0;
|
||||
text-align: center;
|
||||
}
|
||||
.panel-heading {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.fa-lock {
|
||||
color: #666;
|
||||
font-size: 18px;
|
||||
}
|
||||
.text-tips {
|
||||
color: #999;
|
||||
padding-top: 5px;
|
||||
}
|
||||
.panel {
|
||||
border-radius: 5px !important;
|
||||
}
|
||||
|
||||
.show_captcha {
|
||||
display: flex;
|
||||
}
|
||||
#refresh_captcha {
|
||||
margin-left: 5px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="overlay"></div>
|
||||
|
||||
<div class="login-box">
|
||||
|
||||
@if(Session::has('error'))
|
||||
<div class="alert alert-warning alert-dismissible" role="alert">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
{{Session::pull('error')}}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-7 col-xs-12" id="aaa">
|
||||
<div class="logo-text layer" data-depth="0.60">
|
||||
<h2 class="text-white text-title">{{$setting['title']}}</h2>
|
||||
<small class="text-muted">Good Online Office</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-5 col-xs-12">
|
||||
|
||||
<form class="form-horizontal" url="{{url('login')}}" method="post" id="myform" name="myform">
|
||||
|
||||
<div class="panel">
|
||||
|
||||
<div class="panel-heading wrapper b-b b-light">
|
||||
<h4 class="font-thin m-t-none m-b-none"><i class="fa fa-lock"></i> 登录</h4>
|
||||
<div class="text-tips">
|
||||
请使用您的帐号密码进行登录
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-body" style="padding:20px 30px 0 30px;">
|
||||
<div class="form-group">
|
||||
<input type="text" placeholder="账号" class="form-control" name="username" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="password" placeholder="密码" class="form-control" name="password" required>
|
||||
</div>
|
||||
|
||||
<div id="show_captcha" style="display:@if($show_captcha) '' @else none @endif">
|
||||
<div class="form-group">
|
||||
<div class="show_captcha">
|
||||
<input type="text" maxlength="4" name="captcha" class="form-control" id="input-code" autocomplete="off" placeholder="验证码">
|
||||
<a id="refresh_captcha" title="点击刷新">
|
||||
<img id="captcha_image" src="{{url('user/auth/captcha')}}" style="vertical-align:middle;height:30px;">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="checkbox m-b-md m-t-none">
|
||||
<label class="i-checks i-checks-sm">
|
||||
<input type="checkbox" name="remember">
|
||||
<i></i> 下次自动登录
|
||||
</label>
|
||||
</div>
|
||||
<div class="line line-dashed"></div>
|
||||
<button type="submit" class="btn btn-lg btn-info btn-block"> 登录 </button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="line line-dashed"></div>
|
||||
<div class="text-center text-muted">
|
||||
<a class="text-base" href="{{url('qrcode')}}">
|
||||
<i class="fa fa-qrcode"></i> 扫码登录</a>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div class="footer">
|
||||
<small class="text-muted">© {{date('Y')}} {{$version}}</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function($) {
|
||||
// ajax 登录
|
||||
$('#myform').on('submit', function () {
|
||||
var url = $(this).attr('action');
|
||||
var data = $(this).serialize();
|
||||
$.post(url, data, function (res) {
|
||||
if (res.show_captcha) {
|
||||
$('#show_captcha').show();
|
||||
}
|
||||
if (res.success) {
|
||||
toastrSuccess(res.msg);
|
||||
app.redirect('/');
|
||||
} else {
|
||||
// 登录错误显示验证码
|
||||
if (res.show_captcha) {
|
||||
refresh_captcha();
|
||||
}
|
||||
toastrError(res.msg);
|
||||
}
|
||||
}, 'json');
|
||||
return false;
|
||||
});
|
||||
// 刷新验证码方法
|
||||
function refresh_captcha() {
|
||||
$('#captcha_image').attr('src', settings.public_url + '/user/auth/captcha?_=' + Math.random());
|
||||
}
|
||||
// 刷新验证码
|
||||
$(document).on('click', '#refresh_captcha', function () {
|
||||
refresh_captcha();
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
@@ -0,0 +1,72 @@
|
||||
<style>
|
||||
body {
|
||||
color: #badbe6;
|
||||
text-align: center;
|
||||
background: -webkit-linear-gradient(right, #198fb4, #0b6fab);
|
||||
background: -o-linear-gradient(right, #198fb4, #0b6fab);
|
||||
background: linear-gradient(to left, #198fb4, #0b6fab);
|
||||
background-color: #3586b7;
|
||||
}
|
||||
.text-muted {
|
||||
color: #badbe6;
|
||||
}
|
||||
.text-muted a {
|
||||
color: #fff;
|
||||
}
|
||||
.list-group-item {
|
||||
border-color: #fff;
|
||||
}
|
||||
.login-box {
|
||||
margin: 0 auto;
|
||||
text-align: left;
|
||||
}
|
||||
.login-box .h5 {
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="login-box">
|
||||
|
||||
<div class="container w-xxl w-auto-xs" style="padding-top:50px;">
|
||||
|
||||
<div class="wrapper text-center">
|
||||
<h2 class="text-white">{{$setting['title']}}</h2>
|
||||
<small class="text-muted">Different Office</small>
|
||||
</div>
|
||||
|
||||
@if(Session::has('error'))
|
||||
<div class="alert alert-warning alert-dismissible" role="alert">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
{{Session::pull('error')}}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="text-center">
|
||||
<img src="{{url('index/api/qrcode', ['size' => 5, 'data' => 'qrlogin:'.time().''])}}">
|
||||
</div>
|
||||
|
||||
<div class="line line-dashed"></div>
|
||||
|
||||
<div class="text-center text-muted">
|
||||
<a class="text-base" href="{{url('login')}}"><i class="fa fa-mail-reply"></i> 账号登录</a>
|
||||
</div>
|
||||
|
||||
<div class="line line-dashed"></div>
|
||||
|
||||
<div class="text-center">
|
||||
<small class="text-muted">© {{date('Y')}} {{$version}}</small>
|
||||
</div>
|
||||
|
||||
<div class="line line-dashed"></div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="h5 m-t-lg text-white help">
|
||||
<p>合作经销商的账号和密码请与客户经理联络。</p>
|
||||
<p>公司员工、供应商的账号和密码请与总经理助理联络。</p>
|
||||
<p>系统异常请与上述岗位联络。</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,106 @@
|
||||
<style>
|
||||
body {
|
||||
background: -webkit-linear-gradient(right, #198fb4, #0b6fab);
|
||||
background: -o-linear-gradient(right, #198fb4, #0b6fab);
|
||||
background: linear-gradient(to left, #198fb4, #0b6fab);
|
||||
background-color: #3586b7;
|
||||
}
|
||||
.text-muted {
|
||||
color: #badbe6;
|
||||
}
|
||||
.text-muted a {
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
<div class="container w-xxl w-auto-xs" style="padding-top:100px;">
|
||||
|
||||
@if(Session::has('error'))
|
||||
<div class="alert alert-warning alert-dismissible" role="alert">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
{{Session::pull('error')}}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="panel">
|
||||
<div class="panel-body">
|
||||
|
||||
<form class="form-horizontal padder-md" url="{{url()}}" method="post" id="myform" name="myform" role="form">
|
||||
<div class="form-group">
|
||||
<label class="control-label">两步验证</label>
|
||||
<input type="text" class="form-control" maxlength="6" id="code" name="code" value="{{Request::old('code')}}">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<!--
|
||||
<span id="sms-info"><a onclick="totp.smsCode();" href="javascript:;" class="btn btn-info btn-xs" id="sms-code">点击短信获取验证码</a></span>
|
||||
-->
|
||||
<div class="pull-right">
|
||||
<a href="{{url('logout')}}" class="btn btn-default"> 注销 </a>
|
||||
<button type="submit" class="btn btn-primary"> 验证 </button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="line line-dashed"></div>
|
||||
|
||||
<div class="text-center">
|
||||
<small class="text-muted">© {{date('Y')}} {{$version}}</small>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$('#myform').submit(function() {
|
||||
var url = $(this).attr('action');
|
||||
var data = $(this).serialize();
|
||||
$.post(url, data, function(res) {
|
||||
if(res.status) {
|
||||
toastrSuccess(res.data);
|
||||
app.redirect('/');
|
||||
} else {
|
||||
toastrError(res.data);
|
||||
}
|
||||
}, 'json');
|
||||
return false;
|
||||
});
|
||||
|
||||
var totp = {
|
||||
second: 0,
|
||||
timeId: undefined,
|
||||
init: function(second)
|
||||
{
|
||||
clearTimeout(this.timeId);
|
||||
this.second = second;
|
||||
this.start();
|
||||
},
|
||||
start: function()
|
||||
{
|
||||
var self = this;
|
||||
if(this.second > 0) {
|
||||
$("#second").html(this.second);
|
||||
this.timeId = setTimeout(function()
|
||||
{
|
||||
self.start();
|
||||
}, 1000);
|
||||
this.second--;
|
||||
|
||||
} else {
|
||||
clearTimeout(this.timeId);
|
||||
$("#sms-info").html('<a class="btn btn-info btn-xs" onclick="getSMSCode();" href="javascript:;" id="sms-code">重新获取验证码</a>');
|
||||
}
|
||||
},
|
||||
smsCode:function()
|
||||
{
|
||||
var self = this;
|
||||
$.get('{{url()}}',{sms:true}, function(res) {
|
||||
if(res.status == true) {
|
||||
self.init(res.data);
|
||||
$("#sms-info").html('<span class="btn btn-info btn-xs disabled">剩余<span id="second">' + res.data + '</span>秒重新获取</span>');
|
||||
} else {
|
||||
toastrError(res.data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,3 @@
|
||||
<form class="form-horizontal form-controller" method="post" id="department" name="department">
|
||||
{{$form['tpl']}}
|
||||
</form>
|
||||
@@ -0,0 +1,133 @@
|
||||
<div class="wrapper-xs">
|
||||
<form id="dialog-{{$search['query']['id']}}-search-form" class="form-inline" method="get">
|
||||
@include('searchForm6')
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="dialog-{{$search['query']['id']}}" class="ag-theme-balham" style="width:100%;height:380px;"></div>
|
||||
|
||||
<script>
|
||||
(function ($) {
|
||||
var search = JSON.parse('{{json_encode($search)}}');
|
||||
var params = search.query;
|
||||
|
||||
var option = gdoo.formKey(params);
|
||||
var event = gdoo.event.get(option.key);
|
||||
event.trigger('query', params);
|
||||
|
||||
var sid = params.prefix == 1 ? 'sid' : 'id';
|
||||
var gridDiv = document.querySelector("#dialog-{{$search['query']['id']}}");
|
||||
var grid = new agGridOptions();
|
||||
var selectedData = {};
|
||||
var multiple = params.multi == 0 ? false : true;
|
||||
grid.remoteDataUrl = '{{url()}}';
|
||||
grid.remoteParams = params;
|
||||
grid.suppressRowClickSelection = true;
|
||||
grid.rowSelection = multiple ? 'multiple' : 'single';
|
||||
|
||||
grid.autoGroupColumnDef = {
|
||||
headerName: '名称',
|
||||
width: 250,
|
||||
cellRendererParams: {
|
||||
checkbox: true,
|
||||
suppressCount: false,
|
||||
}
|
||||
};
|
||||
grid.treeData = true;
|
||||
grid.groupDefaultExpanded = -1;
|
||||
|
||||
grid.getDataPath = function(data) {
|
||||
return data.tree_path;
|
||||
};
|
||||
grid.columnDefs = [];
|
||||
grid.columnDefs.push({suppressMenu: true, cellClass:'text-center', field: 'id', headerName: 'ID', width: 60});
|
||||
|
||||
grid.onRowClicked = function(row) {
|
||||
var selected = row.node.isSelected();
|
||||
if (selected === false) {
|
||||
row.node.setSelected(true, true);
|
||||
}
|
||||
};
|
||||
|
||||
grid.onRowDoubleClicked = function (row) {
|
||||
var ret = writeSelected();
|
||||
if (ret == true) {
|
||||
$('#gdoo-dialog-' + params.dialog_index).dialog('close');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 初始化选择
|
||||
*/
|
||||
function initSelected() {
|
||||
if (params.is_grid) {
|
||||
} else {
|
||||
var rows = {};
|
||||
var id = $('#'+option.id).val();
|
||||
if (id) {
|
||||
var ids = id.split(',');
|
||||
for (var i = 0; i < ids.length; i++) {
|
||||
rows[ids[i]] = ids[i];
|
||||
}
|
||||
}
|
||||
grid.api.forEachNode(function(node) {
|
||||
var key = node.data[sid];
|
||||
if (rows[key] != undefined) {
|
||||
node.setSelected(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入选中
|
||||
*/
|
||||
function writeSelected() {
|
||||
var rows = grid.api.getSelectedRows();
|
||||
if (params.is_grid) {
|
||||
var list = gdoo.forms[params.form_id];
|
||||
list.api.dialogSelected(params);
|
||||
} else {
|
||||
var id = [];
|
||||
var text = [];
|
||||
$.each(rows, function(k, row) {
|
||||
id.push(row[sid]);
|
||||
text.push(row.name);
|
||||
});
|
||||
$('#'+option.id).val(id.join(','));
|
||||
$('#'+option.id+'_text').val(text.join(','));
|
||||
|
||||
if (event.exist('onSelect')) {
|
||||
return event.trigger('onSelect', multiple ? rows : rows[0]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
grid.writeSelected = writeSelected;
|
||||
gdoo.dialogs[option.id] = grid;
|
||||
|
||||
new agGrid.Grid(gridDiv, grid);
|
||||
|
||||
// 读取数据
|
||||
grid.remoteData();
|
||||
|
||||
// 数据载入成功
|
||||
grid.remoteSuccessed = function() {
|
||||
initSelected();
|
||||
}
|
||||
|
||||
var data = search.forms;
|
||||
var search = $("#dialog-{{$search['query']['id']}}-search-form").searchForm({
|
||||
data: data
|
||||
});
|
||||
search.find('#search-submit').on('click', function() {
|
||||
var params = search.serializeArray();
|
||||
$.map(params, function(row) {
|
||||
data[row.name] = row.value;
|
||||
});
|
||||
grid.remoteData(data);
|
||||
return false;
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
</script>
|
||||
@@ -0,0 +1,66 @@
|
||||
{{$header["js"]}}
|
||||
<div class="panel no-border" id="{{$header['table']}}-controller">
|
||||
@include('headers')
|
||||
<div class="list-jqgrid">
|
||||
<div id="{{$header['table']}}-grid" class="ag-theme-balham"></div>
|
||||
<div class="ag-theme-balham" id="ag-pagination"></div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function ($) {
|
||||
var table = '{{$header["table"]}}';
|
||||
var config = gdoo.grids[table];
|
||||
var action = config.action;
|
||||
var search = config.search;
|
||||
|
||||
// 自定义搜索方法
|
||||
search.searchInit = function (e) {
|
||||
var self = this;
|
||||
}
|
||||
|
||||
var grid = new agGridOptions();
|
||||
|
||||
var gridDiv = document.querySelector("#{{$header['table']}}-grid");
|
||||
gridDiv.style.height = getPanelHeight(11);
|
||||
|
||||
config.cols[0]['hide'] = true;
|
||||
config.cols[1]['hide'] = true;
|
||||
grid.autoGroupColumnDef = {
|
||||
headerName: '名称',
|
||||
width: 250,
|
||||
cellRendererParams: {
|
||||
checkbox: true,
|
||||
suppressCount: true,
|
||||
}
|
||||
};
|
||||
|
||||
grid.treeData = true;
|
||||
grid.groupDefaultExpanded = -1;
|
||||
|
||||
grid.getDataPath = function(data) {
|
||||
return data.tree_path;
|
||||
};
|
||||
|
||||
grid.remoteDataUrl = '{{url()}}';
|
||||
grid.remoteParams = search.advanced.query;
|
||||
grid.columnDefs = config.cols;
|
||||
new agGrid.Grid(gridDiv, grid);
|
||||
|
||||
// 读取数据
|
||||
grid.remoteData();
|
||||
|
||||
// 绑定自定义事件
|
||||
var $gridDiv = $(gridDiv);
|
||||
$gridDiv.on('click', '[data-toggle="event"]', function () {
|
||||
var data = $(this).data();
|
||||
if (data.master_id > 0) {
|
||||
action[data.action](data);
|
||||
}
|
||||
});
|
||||
|
||||
config.grid = grid;
|
||||
|
||||
})(jQuery);
|
||||
</script>
|
||||
@include('footers')
|
||||
@@ -0,0 +1,3 @@
|
||||
<form class="form-horizontal form-controller" method="post" id="user_group" name="user_group">
|
||||
{{$form['tpl']}}
|
||||
</form>
|
||||
@@ -0,0 +1,58 @@
|
||||
{{$header["js"]}}
|
||||
<div class="panel no-border" id="{{$header['table']}}-controller">
|
||||
@include('headers')
|
||||
<div class="list-jqgrid">
|
||||
<div id="{{$header['table']}}-grid" class="ag-theme-balham"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function ($) {
|
||||
var table = '{{$header["table"]}}';
|
||||
var config = gdoo.grids[table];
|
||||
var action = config.action;
|
||||
var search = config.search;
|
||||
|
||||
// 自定义搜索方法
|
||||
search.searchInit = function (e) {
|
||||
var self = this;
|
||||
}
|
||||
|
||||
var grid = new agGridOptions();
|
||||
|
||||
var gridDiv = document.querySelector("#{{$header['table']}}-grid");
|
||||
gridDiv.style.height = getPanelHeight(48);
|
||||
|
||||
grid.remoteDataUrl = '{{url()}}';
|
||||
grid.remoteParams = search.advanced.query;
|
||||
grid.columnDefs = config.cols;
|
||||
grid.onRowDoubleClicked = function (params) {
|
||||
if (params.node.rowPinned) {
|
||||
return;
|
||||
}
|
||||
if (params.data == undefined) {
|
||||
return;
|
||||
}
|
||||
if (params.data.id > 0) {
|
||||
action.edit(params.data);
|
||||
}
|
||||
};
|
||||
|
||||
new agGrid.Grid(gridDiv, grid);
|
||||
|
||||
// 读取数据
|
||||
grid.remoteData({page: 1});
|
||||
|
||||
// 绑定自定义事件
|
||||
var $gridDiv = $(gridDiv);
|
||||
$gridDiv.on('click', '[data-toggle="event"]', function () {
|
||||
var data = $(this).data();
|
||||
if (data.master_id > 0) {
|
||||
action[data.action](data);
|
||||
}
|
||||
});
|
||||
|
||||
config.grid = grid;
|
||||
|
||||
})(jQuery);
|
||||
</script>
|
||||
@include('footers')
|
||||
@@ -0,0 +1,34 @@
|
||||
<table class="table table-form m-b-none">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="10%" align="right">姓名</td>
|
||||
<td width="40%">{{$user->name}}</td>
|
||||
<td width="10%" align="right">性别</td>
|
||||
<td width="40%">{{option('user.gender', $user['gender'])}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">部门</td>
|
||||
<td>{{$user->department->name}}</td>
|
||||
<td align="right">岗位</td>
|
||||
<td>{{$user->role->name}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">手机</td>
|
||||
<td>{{$user->phone}}</td>
|
||||
<td align="right">邮箱</td>
|
||||
<td>{{$user->email}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="4" align="left">站内私信</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">内容</td>
|
||||
<td colspan="3">
|
||||
<form class="form-horizontal" method="post" action="{{url()}}" id="user_message" name="user_message">
|
||||
<textarea class="form-control" name="content"></textarea>
|
||||
<input type="hidden" name="read_by" value="{{$user->id}}" />
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -0,0 +1,86 @@
|
||||
{{$header["js"]}}
|
||||
<div class="panel no-border" id="{{$header['master_table']}}-controller">
|
||||
@include('headers')
|
||||
<div class="list-jqgrid">
|
||||
<div id="{{$header['master_table']}}-grid" class="ag-theme-balham"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function($) {
|
||||
var table = '{{$header["master_table"]}}';
|
||||
var config = gdoo.grids[table];
|
||||
var action = config.action;
|
||||
var search = config.search;
|
||||
|
||||
var statusAction = function(type) {
|
||||
var grid = config.grid;
|
||||
var selections = grid.jqGrid('getSelections');
|
||||
var ids = [];
|
||||
$.each(selections, function(i, selection) {
|
||||
ids.push(selection.id);
|
||||
});
|
||||
if(ids.length > 0) {
|
||||
$.post('{{url("status")}}', {type: type, id: ids}, function(res) {
|
||||
if(res.status) {
|
||||
toastrSuccess(res.data);
|
||||
grid.trigger('reloadGrid');
|
||||
} else {
|
||||
toastrError(res.data);
|
||||
}
|
||||
},'json');
|
||||
} else {
|
||||
toastrError('最少选择一行记录。');
|
||||
}
|
||||
}
|
||||
|
||||
// 标记已读
|
||||
action.read = function() {
|
||||
statusAction('read');
|
||||
};
|
||||
// 标记未读
|
||||
action.unread = function() {
|
||||
statusAction('unread');
|
||||
};
|
||||
|
||||
// 自定义搜索方法
|
||||
search.searchInit = function(e) {
|
||||
var self = this;
|
||||
}
|
||||
|
||||
var grid = new agGridOptions();
|
||||
grid.remoteDataUrl = '{{url()}}';
|
||||
grid.remoteParams = search.advanced.query;
|
||||
grid.columnDefs = config.cols;
|
||||
grid.onRowDoubleClicked = function (params) {
|
||||
if (params.node.rowPinned) {
|
||||
return;
|
||||
}
|
||||
if (params.data == undefined) {
|
||||
return;
|
||||
}
|
||||
if (params.data.master_id > 0) {
|
||||
action.show(params.data);
|
||||
}
|
||||
};
|
||||
|
||||
var gridDiv = document.querySelector("#{{$header['master_table']}}-grid");
|
||||
gridDiv.style.height = getPanelHeight(48);
|
||||
new agGrid.Grid(gridDiv, grid);
|
||||
|
||||
// 读取数据
|
||||
grid.remoteData({page: 1});
|
||||
|
||||
// 绑定自定义事件
|
||||
var $gridDiv = $(gridDiv);
|
||||
$gridDiv.on('click', '[data-toggle="event"]', function () {
|
||||
var data = $(this).data();
|
||||
if (data.master_id > 0) {
|
||||
action[data.action](data);
|
||||
}
|
||||
});
|
||||
|
||||
config.grid = grid;
|
||||
|
||||
})(jQuery);
|
||||
</script>
|
||||
@include('footers')
|
||||
@@ -0,0 +1,10 @@
|
||||
<div class="panel m-b-none">
|
||||
<div class="panel-heading b-b b-light">
|
||||
<small class="text-muted">
|
||||
来自 : {{get_user($row['created_id'], 'name')}} 创建时间 : @datetime($row['created_at'])
|
||||
</small>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{$row['content']}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<form class="form-horizontal form-controller" method="post" id="user_position" name="user_position">
|
||||
{{$form['tpl']}}
|
||||
</form>
|
||||
@@ -0,0 +1,123 @@
|
||||
<div class="padder">
|
||||
<div class="m-t-sm m-b-sm">
|
||||
<form id="dialog-{{$search['query']['id']}}-search-form" class="form-inline" method="get">
|
||||
@include('searchForm')
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="dialog-{{$search['query']['id']}}" class="ag-theme-balham" style="width:100%;height:380px;"></div>
|
||||
|
||||
<script>
|
||||
(function ($) {
|
||||
var search = JSON.parse('{{json_encode($search)}}');
|
||||
var params = search.query;
|
||||
|
||||
var option = gdoo.formKey(params);
|
||||
var event = gdoo.event.get(option.key);
|
||||
event.trigger('query', params);
|
||||
|
||||
var sid = params.prefix == 1 ? 'sid' : 'id';
|
||||
var gridDiv = document.querySelector("#dialog-{{$search['query']['id']}}");
|
||||
var grid = new agGridOptions();
|
||||
var selectedData = {};
|
||||
var multiple = params.multi == 0 ? false : true;
|
||||
grid.remoteDataUrl = '{{url()}}';
|
||||
grid.remoteParams = params;
|
||||
grid.rowSelection = multiple ? 'multiple' : 'single';
|
||||
|
||||
grid.columnDefs = [
|
||||
{suppressMenu: true, cellClass:'text-center', checkboxSelection: true, headerCheckboxSelection: multiple, suppressSizeToFit: true, sortable: false, width: 40},
|
||||
{suppressMenu: true, cellClass:'text-center', field: 'name', headerName: '名称', width: 200},
|
||||
{suppressMenu: true, cellClass:'text-center', field: 'id', headerName: 'ID', width: 60}
|
||||
];
|
||||
|
||||
grid.onRowClicked = function(row) {
|
||||
var selected = row.node.isSelected();
|
||||
if (selected === false) {
|
||||
row.node.setSelected(true, true);
|
||||
}
|
||||
};
|
||||
|
||||
grid.onRowDoubleClicked = function (row) {
|
||||
var ret = writeSelected();
|
||||
if (ret == true) {
|
||||
$('#gdoo-dialog-' + params.dialog_index).dialog('close');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 初始化选择
|
||||
*/
|
||||
function initSelected() {
|
||||
if (params.is_grid) {
|
||||
} else {
|
||||
var rows = {};
|
||||
var id = $('#'+option.id).val();
|
||||
if (id) {
|
||||
var ids = id.split(',');
|
||||
for (var i = 0; i < ids.length; i++) {
|
||||
rows[ids[i]] = ids[i];
|
||||
}
|
||||
}
|
||||
grid.api.forEachNode(function(node) {
|
||||
var key = node.data[sid];
|
||||
if (rows[key] != undefined) {
|
||||
node.setSelected(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入选中
|
||||
*/
|
||||
function writeSelected() {
|
||||
var rows = grid.api.getSelectedRows();
|
||||
if (params.is_grid) {
|
||||
var list = gdoo.forms[params.form_id];
|
||||
list.api.dialogSelected(params);
|
||||
} else {
|
||||
var id = [];
|
||||
var text = [];
|
||||
$.each(rows, function(k, row) {
|
||||
id.push(row[sid]);
|
||||
text.push(row.name);
|
||||
});
|
||||
$('#'+option.id).val(id.join(','));
|
||||
$('#'+option.id+'_text').val(text.join(','));
|
||||
|
||||
if (event.exist('onSelect')) {
|
||||
return event.trigger('onSelect', multiple ? rows : rows[0]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
grid.writeSelected = writeSelected;
|
||||
gdoo.dialogs[option.id] = grid;
|
||||
|
||||
new agGrid.Grid(gridDiv, grid);
|
||||
|
||||
// 读取数据
|
||||
grid.remoteData();
|
||||
|
||||
// 数据载入成功
|
||||
grid.remoteSuccessed = function() {
|
||||
initSelected();
|
||||
}
|
||||
|
||||
var data = search.forms;
|
||||
var search = $("#dialog-{{$search['query']['id']}}-search-form").searchForm({
|
||||
data: data
|
||||
});
|
||||
search.find('#search-submit').on('click', function() {
|
||||
var params = search.serializeArray();
|
||||
$.map(params, function(row) {
|
||||
data[row.name] = row.value;
|
||||
});
|
||||
grid.remoteData(data);
|
||||
return false;
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
</script>
|
||||
@@ -0,0 +1,58 @@
|
||||
{{$header["js"]}}
|
||||
<div class="panel no-border" id="{{$header['table']}}-controller">
|
||||
@include('headers')
|
||||
<div class="list-jqgrid">
|
||||
<div id="{{$header['table']}}-grid" class="ag-theme-balham"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function ($) {
|
||||
var table = '{{$header["table"]}}';
|
||||
var config = gdoo.grids[table];
|
||||
var action = config.action;
|
||||
var search = config.search;
|
||||
|
||||
// 自定义搜索方法
|
||||
search.searchInit = function (e) {
|
||||
var self = this;
|
||||
}
|
||||
|
||||
var grid = new agGridOptions();
|
||||
|
||||
var gridDiv = document.querySelector("#{{$header['table']}}-grid");
|
||||
gridDiv.style.height = getPanelHeight(48);
|
||||
|
||||
grid.remoteDataUrl = '{{url()}}';
|
||||
grid.remoteParams = search.advanced.query;
|
||||
grid.columnDefs = config.cols;
|
||||
grid.onRowDoubleClicked = function (params) {
|
||||
if (params.node.rowPinned) {
|
||||
return;
|
||||
}
|
||||
if (params.data == undefined) {
|
||||
return;
|
||||
}
|
||||
if (params.data.id > 0) {
|
||||
action.edit(params.data);
|
||||
}
|
||||
};
|
||||
|
||||
new agGrid.Grid(gridDiv, grid);
|
||||
|
||||
// 读取数据
|
||||
grid.remoteData({page: 1});
|
||||
|
||||
// 绑定自定义事件
|
||||
var $gridDiv = $(gridDiv);
|
||||
$gridDiv.on('click', '[data-toggle="event"]', function () {
|
||||
var data = $(this).data();
|
||||
if (data.master_id > 0) {
|
||||
action[data.action](data);
|
||||
}
|
||||
});
|
||||
|
||||
config.grid = grid;
|
||||
|
||||
})(jQuery);
|
||||
</script>
|
||||
@include('footers')
|
||||
@@ -0,0 +1,128 @@
|
||||
<div class="wrapper-sm">
|
||||
<div class="avatar-form">
|
||||
<div class="col-sm-9">
|
||||
<div class="image-box">
|
||||
<img id="image" class="hide">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<div class="preview-box" style="width:150px;height:150px;">
|
||||
<div class="preview" style="width:148px;height:148px;"></div>
|
||||
</div>
|
||||
<div class="preview-box" style="width:98px;height:98px;">
|
||||
<div class="preview" style="width:96px;height:96px;"></div>
|
||||
</div>
|
||||
<div class="preview-box" style="width:50px;height:50px;">
|
||||
<div class="preview" style="width:48px;height:48px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
<div class="btn-avatar">
|
||||
<input class="hide" id="avatarInput" name="image" type="file">
|
||||
<a class="btn btn-info" onclick="$('#avatarInput').click();"><i class="fa fa-cloud-upload"></i> 上传文件</a>
|
||||
<a class="btn btn-success" id="avatarCrop"><i class="fa fa-crop"></i> 裁剪</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
.avatar-form {
|
||||
position: relative;
|
||||
}
|
||||
.btn-avatar {
|
||||
position:absolute;
|
||||
bottom: 0;
|
||||
right: 46px;
|
||||
}
|
||||
.preview-box {
|
||||
border: 1px solid #eee;
|
||||
padding: 0;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.preview {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
}
|
||||
.image-box {
|
||||
border: 1px solid #eee;
|
||||
height: 420px;
|
||||
background-image: url(/assets/images/wf_canvas_bg.png);
|
||||
background-position: -1px -1px;
|
||||
}
|
||||
#image {
|
||||
max-width: 100%;
|
||||
height: 420px;
|
||||
border: 1px solid #eee;
|
||||
display: block;
|
||||
}
|
||||
.col-sm-9 {
|
||||
padding-left: 5px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<link href="{{$asset_url}}/vendor/cropper/cropper.min.css" rel="stylesheet" type="text/css" />
|
||||
<script src="{{$asset_url}}/vendor/cropper/cropper.min.js" type="text/javascript"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
var options = {
|
||||
aspectRatio: 1,
|
||||
autoCropArea: 0.5,
|
||||
preview: '.preview',
|
||||
}
|
||||
var $image = $('#image').cropper(options);
|
||||
|
||||
var $inputImage = $('#avatarInput');
|
||||
|
||||
var uploadedImageURL = null;
|
||||
|
||||
if (URL) {
|
||||
$inputImage.on('change', function () {
|
||||
var files = this.files;
|
||||
var file;
|
||||
|
||||
if (!$image.data('cropper')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (files && files.length) {
|
||||
file = files[0];
|
||||
if (/^image\/\w+$/.test(file.type)) {
|
||||
uploadedImageName = file.name;
|
||||
uploadedImageType = file.type;
|
||||
|
||||
if (uploadedImageURL) {
|
||||
URL.revokeObjectURL(uploadedImageURL);
|
||||
}
|
||||
uploadedImageURL = URL.createObjectURL(file);
|
||||
$image.cropper('destroy').attr('src', uploadedImageURL).cropper(options);
|
||||
$inputImage.val('');
|
||||
} else {
|
||||
window.alert('请选择图片文件');
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$inputImage.prop('disabled', true).parent().addClass('disabled');
|
||||
}
|
||||
|
||||
$('#avatarCrop').on('click', function() {
|
||||
$image.cropper('getCroppedCanvas', {width: 128, height: 128}).toBlob(function (blob) {
|
||||
var formData = new FormData();
|
||||
formData.append('image', blob);
|
||||
$.ajax('{{url()}}', {
|
||||
method: "post",
|
||||
data: formData,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
success: function (res) {
|
||||
$('#user-avatar').attr('src', app.url('uploads/avatar/' + res.data) + '?s=' + Math.random());
|
||||
toastrSuccess('头像上传成功。');
|
||||
$('#modal-avatar-dialog').dialog('close');
|
||||
},
|
||||
error: function () {
|
||||
toastrError('头像上传失败。');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,137 @@
|
||||
<form method="post" action="{{url()}}" id="profile" name="profile">
|
||||
|
||||
<div class="panel">
|
||||
|
||||
<div class="panel-heading tabs-box">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="@if(Request::action() == 'index') active @endif">
|
||||
<a class="text-sm" href="{{url('index')}}">我的资料</a>
|
||||
</li>
|
||||
<li class="@if(Request::action() == 'password') active @endif">
|
||||
<a class="text-sm" href="{{url('password')}}">修改密码</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-2">
|
||||
<div class="text-center">
|
||||
<span class="thumb-lg w-auto-folded avatar m-t-sm">
|
||||
<a href="javascript:avatar();" class="hinted" title="修改头像"><img src="{{avatar(Auth::user()->avatar)}}" id="user-avatar" class="img-full" alt="{{Auth::user()->name}}"></a>
|
||||
<div class="h4 font-thin m-t-sm">{{Auth::user()->login}}</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label">主题</label>
|
||||
<select id="change-theme" class="form-control input-sm" name="theme" id="theme">
|
||||
<?php $themes = ['primary' => '原色', 'blue2' => '科技蓝', 'blue' => '经典蓝', 'wood' => '木质纸', 'purple' => '个性紫', 'green' => '绿色', 'lilac' => '淡紫色']; ?>
|
||||
@if($themes)
|
||||
@foreach($themes as $theme_key => $theme)
|
||||
<option value="{{$theme_key}}" @if($user->theme == $theme_key) selected @endif>{{$theme}}</option>
|
||||
@endforeach
|
||||
@endif
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label">
|
||||
头像显示
|
||||
</label>
|
||||
<select id="avatar_show" class="form-control input-sm" name="avatar_show">
|
||||
<?php $avatar_shows = ['1' => '显示', '0' => '隐藏']; ?>
|
||||
@if($avatar_shows)
|
||||
@foreach($avatar_shows as $k => $v)
|
||||
<option value="{{$k}}" @if($user->avatar_show == $k) selected @endif>{{$v}}</option>
|
||||
@endforeach
|
||||
@endif
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label">安全密钥</label>
|
||||
<strong>{{$user->auth_secret}}</strong>
|
||||
<span class="qrcodeTotp" style="display:none;">
|
||||
<div id="qrcode_canvas"></div>
|
||||
<div id="qrcode_img"></div>
|
||||
</span>
|
||||
<a href="javascript:;" onclick="qrcodeTotp();">
|
||||
<i class="fa fa-qrcode"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<div class="col-sm-offset-2">
|
||||
<button type="button" onclick="history.back();" class="btn btn-default">返回</button>
|
||||
<button type="button" id="profile-form-submit" class="btn btn-success"><i class="fa fa-check-circle"></i> 提交</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<script type="text/javascript" src="{{$asset_url}}/vendor/jquery.qrcode.min.js"></script>
|
||||
<script>
|
||||
function qrcodeTotp() {
|
||||
$.messager.alert("二次验证二维码", '<div align="center">' + $("#qrcode_img").prop("outerHTML") + '</div>');
|
||||
}
|
||||
|
||||
function qrcodeMake(qrcode_canvas, qrcode_image) {
|
||||
$("#" + qrcode_canvas).qrcode({
|
||||
render: "canvas",
|
||||
text: "{{$secretURL}}",
|
||||
correctLevel: 1,
|
||||
width: 220,
|
||||
height: 220
|
||||
});
|
||||
var canvas = $('#' + qrcode_canvas).find('canvas')[0];
|
||||
var image = new Image();
|
||||
image.src = canvas.toDataURL("image/png");
|
||||
$('#' + qrcode_image).append(image);
|
||||
}
|
||||
|
||||
$(function() {
|
||||
|
||||
// 生成二维码
|
||||
qrcodeMake('qrcode_canvas', 'qrcode_img');
|
||||
// 主题修改
|
||||
$('#change-theme').on('change', function() {
|
||||
var e = $(this).val();
|
||||
$('body').attr('class', 'theme-' + e);
|
||||
top.$('body').attr('class', 'theme-' + e);
|
||||
});
|
||||
|
||||
ajaxSubmit('profile', function(res) {
|
||||
if (res.status) {
|
||||
toastrSuccess(res.data);
|
||||
} else {
|
||||
toastrError(res.data);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
function avatar() {
|
||||
viewDialog({
|
||||
title: '修改头像',
|
||||
url: '{{url("avatar")}}',
|
||||
dialogClass: 'modal-lg',
|
||||
id: 'avatar-dialog',
|
||||
buttons: [{
|
||||
text: "确定",
|
||||
'class': "btn-default",
|
||||
click: function() {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}]
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,84 @@
|
||||
<form method="post" action="{{url()}}" id="password" name="password">
|
||||
|
||||
<div class="panel">
|
||||
|
||||
<div class="panel-heading tabs-box">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="@if(Request::action() == 'index') active @endif">
|
||||
<a class="text-sm" href="{{url('index')}}">我的资料</a>
|
||||
</li>
|
||||
<li class="@if(Request::action() == 'password') active @endif">
|
||||
<a class="text-sm" href="{{url('password')}}">修改密码</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-2">
|
||||
<div class="text-center">
|
||||
<span class="thumb-lg w-auto-folded avatar m-t-sm">
|
||||
<a href="javascript:avatar();" class="hinted" title="修改头像"><img src="{{avatar(Auth::user()->avatar)}}" id="user-avatar" class="img-full" alt="{{Auth::user()->name}}"></a>
|
||||
<div class="h4 font-thin m-t-sm">{{Auth::user()->login}}</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div class="form-group">
|
||||
<label class="control-label">旧密码</label>
|
||||
<input type="password" class="form-control input-sm" id="old_password" name="old_password" placeholder="请输入旧密码">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label">新密码</label>
|
||||
<input type="password" class="form-control input-sm" id="new_password" name="new_password" placeholder="请输入新密码">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label">确认新密码</label>
|
||||
<input type="password" id="new_password_confirmation" name="new_password_confirmation" class="form-control input-sm" placeholder="请输入再次输入新密码">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<div class="col-sm-offset-2">
|
||||
<button type="button" onclick="history.back();" class="btn btn-default">返回</button>
|
||||
<button type="submit" id="password-form-submit" class="btn btn-success"><i class="fa fa-check-circle"></i> 提交</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<script>
|
||||
|
||||
ajaxSubmit('password', function(res) {
|
||||
if (res.status) {
|
||||
toastrSuccess(res.data);
|
||||
} else {
|
||||
toastrError(res.data);
|
||||
}
|
||||
});
|
||||
|
||||
function avatar() {
|
||||
viewDialog({
|
||||
title: '修改头像',
|
||||
url: '{{url("avatar")}}',
|
||||
dialogClass: 'modal-lg',
|
||||
id: 'avatar-dialog',
|
||||
buttons: [{
|
||||
text: "确定",
|
||||
'class': "btn-default",
|
||||
click: function() {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}]
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,181 @@
|
||||
<style>
|
||||
.content-body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.form-panel-body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.left-group {
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
height: calc(100vh - 185px);
|
||||
}
|
||||
|
||||
.right-group {
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
height: calc(100vh - 177px);
|
||||
}
|
||||
</style>
|
||||
<div class="form-panel">
|
||||
<div class="form-panel-header">
|
||||
<div class="pull-right">
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm btn-info" id="role-form-submit"><i class="fa fa-check"></i> 保存</button>
|
||||
<a class="btn btn-sm btn-default" data-toggle="closetab" data-id="role_config"><i class="fa fa-sign-out"></i> 退出</a>
|
||||
</div>
|
||||
<div class="form-panel-body">
|
||||
|
||||
<div class="panel no-border">
|
||||
|
||||
<div class="padder padder-t padder-r-n">
|
||||
<form id="myfilter" role="form" class="form-inline" name="myfilter" action="{{url()}}" method="get">
|
||||
|
||||
<div class="form-group">
|
||||
<label>授权角色</label>
|
||||
<select class="form-control input-sm" data-toggle="redirect" id='role_id' name='role_id' data-url="{{url($atcion, $query)}}">
|
||||
@foreach($roles as $key => $role)
|
||||
<option value="{{$role->id}}" @if($query['role_id']==$role->id) selected @endif>{{$role->layer_space}}{{$role->name}}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<span class="hidden-xs"> </span>
|
||||
<div class="form-group">
|
||||
<label>参照角色</label>
|
||||
<select class="form-control input-sm" data-toggle="redirect" id='clone_id' name='clone_id' data-url="{{url($atcion, $query)}}">
|
||||
<option value="">无</option>
|
||||
@foreach($roles as $key => $role)
|
||||
<option value="{{$role->id}}" @if($query['clone_id']==$role->id) selected @endif>{{$role->layer_space}}{{$role->name}}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="wrapper m-t b-t" style="background-color:#f0f3f4;">
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-2 m-b padder-r-n">
|
||||
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading b-b b-light">
|
||||
<div class="h5 m-t-xs m-b-xs"><i class="fa fa-cubes"></i> 模块列表</div>
|
||||
</div>
|
||||
<div class="list-group left-group">
|
||||
@if(count($modules))
|
||||
@foreach($modules as $menuKey => $menuValue)
|
||||
<a class="list-group-item" onclick="module('{{$menuKey}}');" href="javascript:;">
|
||||
<span class="h5">{{$menuValue['name']}}</span>
|
||||
</a>
|
||||
@endforeach
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-10">
|
||||
|
||||
<form method="post" class="form-inline" action="{{url()}}" id="role" name="role">
|
||||
|
||||
@if(count($modules))
|
||||
@foreach($modules as $menuKey => $menuValue)
|
||||
|
||||
<div class="modules" style="display:none;" id="{{$menuKey}}">
|
||||
|
||||
<div class="panel m-b-sm b-a">
|
||||
|
||||
<div class="panel-heading b-b b-light">
|
||||
<label class="checkbox-inline"><input type="checkbox" class="menu-check">{{$menuValue['name']}}</label>
|
||||
</div>
|
||||
|
||||
<div class="panel-body right-group">
|
||||
|
||||
@if(count($menuValue['controllers']))
|
||||
@foreach($menuValue['controllers'] as $groupKey => $groupValue)
|
||||
|
||||
<div class="panel m-b-sm b-a">
|
||||
|
||||
<div class="panel-heading b-b b-light">
|
||||
<label class="checkbox-inline" title="{{$groupKey}}"><input class="group-check" type="checkbox">{{$groupValue['name']}}</label>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
@if(count($groupValue['actions']))
|
||||
@foreach($groupValue['actions'] as $childKey => $childValue)
|
||||
<div class="col-md-3 col-sm-6 wrapper-xs">
|
||||
{{'';$selected = $assets[$menuKey][$groupKey.'.'.$childKey]}}
|
||||
<label title="{{$childKey}}" class="checkbox-inline">
|
||||
<input type="checkbox" class="action-check" name="assets[{{$menuKey}}][{{$groupKey}}.{{$childKey}}][action]" value="1" @if(isset($selected)) checked @endif>
|
||||
{{$childValue['name']}}
|
||||
</label>
|
||||
</div>
|
||||
@endforeach
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@endforeach
|
||||
@endif
|
||||
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endforeach
|
||||
|
||||
@endif
|
||||
|
||||
<input type="hidden" name="role_id" value="{{$query['role_id']}}">
|
||||
<input type="hidden" name="key" id="key" value="{{$query['key']}}">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
|
||||
$('.menu-check,.group-check').on('click', function() {
|
||||
if ($(this).prop("checked") == true) {
|
||||
$(this).parent().parent().parent().find(':checkbox').prop('checked', true);
|
||||
} else {
|
||||
$(this).parent().parent().parent().find(':checkbox').prop('checked', false);
|
||||
}
|
||||
});
|
||||
|
||||
ajaxSubmit('role', function(res) {
|
||||
if (res.status) {
|
||||
toastrSuccess(res.data);
|
||||
} else {
|
||||
toastrError(res.data);
|
||||
}
|
||||
});
|
||||
|
||||
var e = $('#role');
|
||||
var key = e.find('#key').val();
|
||||
if (key == '') {
|
||||
var list = e.find('.modules');
|
||||
key = list.eq(0).attr('id');
|
||||
e.find('#key').val(key);
|
||||
}
|
||||
e.find('#' + key).fadeIn();
|
||||
|
||||
});
|
||||
|
||||
function module(key) {
|
||||
var e = $('#role');
|
||||
e.find('#key').val(key);
|
||||
e.find('.modules').hide();
|
||||
e.find('#' + key).fadeIn();
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,3 @@
|
||||
<form class="form-horizontal form-controller" method="post" id="role" name="role">
|
||||
{{$form['tpl']}}
|
||||
</form>
|
||||
@@ -0,0 +1,133 @@
|
||||
<div class="wrapper-xs">
|
||||
<form id="dialog-{{$search['query']['id']}}-search-form" class="form-inline" method="get">
|
||||
@include('searchForm6')
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="dialog-{{$search['query']['id']}}" class="ag-theme-balham" style="width:100%;height:380px;"></div>
|
||||
|
||||
<script>
|
||||
(function ($) {
|
||||
var search = JSON.parse('{{json_encode($search)}}');
|
||||
var params = search.query;
|
||||
|
||||
var option = gdoo.formKey(params);
|
||||
var event = gdoo.event.get(option.key);
|
||||
event.trigger('query', params);
|
||||
|
||||
var sid = params.prefix == 1 ? 'sid' : 'id';
|
||||
var gridDiv = document.querySelector("#dialog-{{$search['query']['id']}}");
|
||||
var grid = new agGridOptions();
|
||||
var selectedData = {};
|
||||
var multiple = params.multi == 0 ? false : true;
|
||||
grid.remoteDataUrl = '{{url()}}';
|
||||
grid.remoteParams = params;
|
||||
grid.suppressRowClickSelection = true;
|
||||
grid.rowSelection = multiple ? 'multiple' : 'single';
|
||||
|
||||
grid.autoGroupColumnDef = {
|
||||
headerName: '名称',
|
||||
width: 250,
|
||||
cellRendererParams: {
|
||||
checkbox: true,
|
||||
suppressCount: false,
|
||||
}
|
||||
};
|
||||
grid.treeData = true;
|
||||
grid.groupDefaultExpanded = -1;
|
||||
|
||||
grid.getDataPath = function(data) {
|
||||
return data.tree_path;
|
||||
};
|
||||
grid.columnDefs = [];
|
||||
grid.columnDefs.push({suppressMenu: true, cellClass:'text-center', field: 'id', headerName: 'ID', width: 60});
|
||||
|
||||
grid.onRowClicked = function(row) {
|
||||
var selected = row.node.isSelected();
|
||||
if (selected === false) {
|
||||
row.node.setSelected(true, true);
|
||||
}
|
||||
};
|
||||
|
||||
grid.onRowDoubleClicked = function (row) {
|
||||
var ret = writeSelected();
|
||||
if (ret == true) {
|
||||
$('#gdoo-dialog-' + params.dialog_index).dialog('close');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 初始化选择
|
||||
*/
|
||||
function initSelected() {
|
||||
if (params.is_grid) {
|
||||
} else {
|
||||
var rows = {};
|
||||
var id = $('#'+option.id).val();
|
||||
if (id) {
|
||||
var ids = id.split(',');
|
||||
for (var i = 0; i < ids.length; i++) {
|
||||
rows[ids[i]] = ids[i];
|
||||
}
|
||||
}
|
||||
grid.api.forEachNode(function(node) {
|
||||
var key = node.data[sid];
|
||||
if (rows[key] != undefined) {
|
||||
node.setSelected(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入选中
|
||||
*/
|
||||
function writeSelected() {
|
||||
var rows = grid.api.getSelectedRows();
|
||||
if (params.is_grid) {
|
||||
var list = gdoo.forms[params.form_id];
|
||||
list.api.dialogSelected(params);
|
||||
} else {
|
||||
var id = [];
|
||||
var text = [];
|
||||
$.each(rows, function(k, row) {
|
||||
id.push(row[sid]);
|
||||
text.push(row.name);
|
||||
});
|
||||
$('#'+option.id).val(id.join(','));
|
||||
$('#'+option.id+'_text').val(text.join(','));
|
||||
|
||||
if (event.exist('onSelect')) {
|
||||
return event.trigger('onSelect', multiple ? rows : rows[0]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
grid.writeSelected = writeSelected;
|
||||
gdoo.dialogs[option.id] = grid;
|
||||
|
||||
new agGrid.Grid(gridDiv, grid);
|
||||
|
||||
// 读取数据
|
||||
grid.remoteData();
|
||||
|
||||
// 数据载入成功
|
||||
grid.remoteSuccessed = function() {
|
||||
initSelected();
|
||||
}
|
||||
|
||||
var data = search.forms;
|
||||
var search = $("#dialog-{{$search['query']['id']}}-search-form").searchForm({
|
||||
data: data
|
||||
});
|
||||
search.find('#search-submit').on('click', function() {
|
||||
var params = search.serializeArray();
|
||||
$.map(params, function(row) {
|
||||
data[row.name] = row.value;
|
||||
});
|
||||
grid.remoteData(data);
|
||||
return false;
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
</script>
|
||||
@@ -0,0 +1,49 @@
|
||||
{{$header["js"]}}
|
||||
<div class="panel no-border" id="{{$header['table']}}-controller">
|
||||
@include('headers')
|
||||
<div class="list-jqgrid">
|
||||
<div id="{{$header['table']}}-grid" class="ag-theme-balham"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function ($) {
|
||||
var table = '{{$header["table"]}}';
|
||||
var config = gdoo.grids[table];
|
||||
var action = config.action;
|
||||
var search = config.search;
|
||||
|
||||
action.config = function(data) {
|
||||
top.addTab('user/role/config?role_id=' + data.master_id, 'role_config', '权限配置');
|
||||
}
|
||||
|
||||
// 自定义搜索方法
|
||||
search.searchInit = function (e) {
|
||||
var self = this;
|
||||
}
|
||||
|
||||
var grid = new agGridOptions();
|
||||
var gridDiv = document.querySelector("#{{$header['table']}}-grid");
|
||||
gridDiv.style.height = getPanelHeight(48);
|
||||
grid.remoteDataUrl = '{{url()}}';
|
||||
grid.remoteParams = search.advanced.query;
|
||||
grid.columnDefs = config.cols;
|
||||
|
||||
new agGrid.Grid(gridDiv, grid);
|
||||
|
||||
// 读取数据
|
||||
grid.remoteData({page: 1});
|
||||
|
||||
// 绑定自定义事件
|
||||
var $gridDiv = $(gridDiv);
|
||||
$gridDiv.on('click', '[data-toggle="event"]', function () {
|
||||
var data = $(this).data();
|
||||
if (data.master_id > 0) {
|
||||
action[data.action](data);
|
||||
}
|
||||
});
|
||||
|
||||
config.grid = grid;
|
||||
|
||||
})(jQuery);
|
||||
</script>
|
||||
@include('footers')
|
||||
@@ -0,0 +1,39 @@
|
||||
<style>
|
||||
#grid_user_role .ag-root-wrapper {
|
||||
border: 0;
|
||||
}
|
||||
</style>
|
||||
<div id="grid_user_role" class="ag-theme-balham" style="width:100%;height:380px;"></div>
|
||||
<script>
|
||||
var $table = null;
|
||||
(function($) {
|
||||
var data = JSON.parse('{{json_encode($rows)}}');
|
||||
var users = JSON.parse('{{json_encode($users)}}');
|
||||
var grid = new agGridOptions();
|
||||
grid.suppressLoadingOverlay = true;
|
||||
grid.suppressNoRowsOverlay = true;
|
||||
grid.rowMultiSelectWithClick = true;
|
||||
grid.suppressRowClickSelection = false;
|
||||
grid.defaultColDef.sortable = false;
|
||||
grid.defaultColDef.filter = false;
|
||||
grid.defaultColDef.suppressMenu = true;
|
||||
grid.defaultColDef.suppressNavigable = true;
|
||||
grid.columnDefs = [
|
||||
{field:'id', hide: true},
|
||||
{width: 40, cellClass:'text-center', suppressSizeToFit: true, headerCheckboxSelection: true, checkboxSelection: true},
|
||||
{headerName: '角色编码', field:'code', cellClass:'text-center', width: 60},
|
||||
{headerName: '角色名称', field:'name', cellClass:'text-left', width: 120},
|
||||
|
||||
];
|
||||
var gridDiv = document.querySelector("#grid_user_role");
|
||||
new agGrid.Grid(gridDiv, grid);
|
||||
grid.api.updateRowData({add:data});
|
||||
|
||||
grid.api.forEachNode(function(node) {
|
||||
if (users[node.data.id] > 0) {
|
||||
node.setSelected(true);
|
||||
}
|
||||
});
|
||||
gdoo.dialogs['user_role'] = grid;
|
||||
})(jQuery);
|
||||
</script>
|
||||
@@ -0,0 +1,36 @@
|
||||
<div class="form-panel">
|
||||
<div class="form-panel-header">
|
||||
<div class="pull-right"></div>
|
||||
{{$form['btn']}}
|
||||
</div>
|
||||
<div class="form-panel-body panel-form-{{$form['action']}}">
|
||||
<form class="form-horizontal form-controller" method="post" id="user" name="user">
|
||||
{{$form['tpl']}}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var action = '{{$form["action"]}}';
|
||||
var table = '{{$form["table"]}}';
|
||||
|
||||
function getAuthSecret(userId) {
|
||||
$.messager.confirm('操作警告', '确定要更新安全密钥。', function(btn) {
|
||||
if (btn == true) {
|
||||
$.post('{{url("user/profile/secret")}}',{id:userId}, function(res) {
|
||||
$("#secret").html(res.data);
|
||||
$('#user_auth_secret_value').val(res.data);
|
||||
}, 'json');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(function() {
|
||||
if (action == 'show') {
|
||||
var text = $('#user_auth_secret').text();
|
||||
} else {
|
||||
var text = $('#user_auth_secret').data('content');
|
||||
}
|
||||
$('#user_auth_secret').html('<input type="hidden" id="user_auth_secret_value" name="user[auth_secret]" value="'+ text +'"><code id="secret">' + text + '</code><a class="btn btn-info btn-xs" onclick="getAuthSecret();" href="javascript:;">更新</a>');
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,155 @@
|
||||
<div class="wrapper-xs">
|
||||
<form id="dialog-{{$search['query']['id']}}-search-form" class="form-inline" method="get">
|
||||
<!--
|
||||
<div class="btn-group" data-toggle="buttons">
|
||||
<label class="btn btn-sm btn-default active">
|
||||
<input type="radio" name="group_id" value="1">用户
|
||||
</label>
|
||||
<label class="btn btn-sm btn-default">
|
||||
<input type="radio" name="group_id" value="2">客户
|
||||
</label>
|
||||
</div>
|
||||
-->
|
||||
@include('searchForm3')
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="dialog-{{$search['query']['id']}}" class="ag-theme-balham" style="width:100%;height:380px;"></div>
|
||||
|
||||
<script>
|
||||
(function ($) {
|
||||
var search = JSON.parse('{{json_encode($search)}}');
|
||||
var params = search.query;
|
||||
|
||||
var option = gdoo.formKey(params);
|
||||
var event = gdoo.event.get(option.key);
|
||||
event.trigger('query', params);
|
||||
|
||||
var sid = params.prefix == 1 ? 'sid' : 'id';
|
||||
var gridDiv = document.querySelector("#dialog-{{$search['query']['id']}}");
|
||||
var grid = new agGridOptions();
|
||||
var selectedData = {};
|
||||
var multiple = params.multi == 0 ? false : true;
|
||||
grid.remoteDataUrl = '{{url()}}';
|
||||
grid.remoteParams = params;
|
||||
grid.suppressRowClickSelection = true;
|
||||
grid.rowSelection = multiple ? 'multiple' : 'single';
|
||||
grid.columnDefs = [
|
||||
{suppressMenu: true, cellClass:'text-center', checkboxSelection: true, headerCheckboxSelection: multiple, suppressSizeToFit: true, sortable: false, width: 40},
|
||||
{suppressMenu: true, cellClass:'text-center', sortable: false, field: 'username', headerName: '用户名', width: 60},
|
||||
{suppressMenu: true, cellClass:'text-left', sortable: false, field: 'name', headerName: '名称', minWidth: 160},
|
||||
{suppressMenu: true, cellClass:'text-center', cellRenderer: statusRenderer, field: 'status', headerName: '状态', width: 60},
|
||||
{suppressMenu: true, cellClass:'text-center', field: 'id', headerName: 'ID', width: 60}
|
||||
];
|
||||
|
||||
var selecteds = {};
|
||||
|
||||
var id = $('#'+option.id).val();
|
||||
var text = $('#'+option.id+'_text').val();
|
||||
if (id) {
|
||||
var ids = id.split(',');
|
||||
var texts = text.split(',');
|
||||
for (var i = 0; i < ids.length; i++) {
|
||||
selecteds[ids[i]] = texts[i];
|
||||
}
|
||||
}
|
||||
|
||||
function statusRenderer(row) {
|
||||
if (row.value == 0) {
|
||||
return '<span style="color:red">禁用</span>';
|
||||
}
|
||||
if (row.value == 1) {
|
||||
return '启用';
|
||||
}
|
||||
}
|
||||
|
||||
grid.onCustomRowSelected = function(event) {
|
||||
var data = event.node.data;
|
||||
if (event.node.isSelected()) {
|
||||
selecteds[data[sid]] = data.name;
|
||||
} else {
|
||||
delete selecteds[data[sid]];
|
||||
}
|
||||
}
|
||||
|
||||
grid.onRowClicked = function(row) {
|
||||
var selected = row.node.isSelected();
|
||||
if (selected === false) {
|
||||
row.node.setSelected(true, true);
|
||||
}
|
||||
};
|
||||
|
||||
grid.onRowDoubleClicked = function (row) {
|
||||
var ret = writeSelected();
|
||||
if (ret == true) {
|
||||
$('#gdoo-dialog-' + params.dialog_index).dialog('close');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 初始化选择
|
||||
*/
|
||||
function initSelected() {
|
||||
if (params.is_grid) {
|
||||
} else {
|
||||
grid.api.forEachNode(function(node) {
|
||||
var key = node.data[sid];
|
||||
if (selecteds[key] != undefined) {
|
||||
node.setSelected(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入选中
|
||||
*/
|
||||
function writeSelected() {
|
||||
var rows = grid.api.getSelectedRows();
|
||||
if (params.is_grid) {
|
||||
var list = gdoo.forms[params.form_id];
|
||||
list.api.dialogSelected(params);
|
||||
} else {
|
||||
var id = [];
|
||||
var text = [];
|
||||
$.each(selecteds, function(k, v) {
|
||||
id.push(k);
|
||||
text.push(v);
|
||||
});
|
||||
$('#'+option.id).val(id.join(','));
|
||||
$('#'+option.id+'_text').val(text.join(','));
|
||||
|
||||
if (event.exist('onSelect')) {
|
||||
return event.trigger('onSelect', multiple ? rows : rows[0]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
grid.writeSelected = writeSelected;
|
||||
gdoo.dialogs[option.id] = grid;
|
||||
|
||||
new agGrid.Grid(gridDiv, grid);
|
||||
|
||||
// 读取数据
|
||||
grid.remoteData({page: 1});
|
||||
|
||||
// 数据载入成功
|
||||
grid.remoteSuccessed = function() {
|
||||
initSelected();
|
||||
}
|
||||
|
||||
var data = search.forms;
|
||||
var search = $("#dialog-{{$search['query']['id']}}-search-form").searchForm({
|
||||
data: data
|
||||
});
|
||||
search.find('#search-submit').on('click', function() {
|
||||
var params = search.serializeArray();
|
||||
$.map(params, function(row) {
|
||||
data[row.name] = row.value;
|
||||
});
|
||||
grid.remoteData(data);
|
||||
return false;
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
</script>
|
||||
@@ -0,0 +1,128 @@
|
||||
{{$header["js"]}}
|
||||
<div class="panel no-border" id="{{$header['table']}}-controller">
|
||||
@include('headers')
|
||||
<div class="list-jqgrid">
|
||||
<div id="{{$header['table']}}-grid" class="ag-theme-balham"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function ($) {
|
||||
var table = '{{$header["table"]}}';
|
||||
var config = gdoo.grids[table];
|
||||
var action = config.action;
|
||||
var search = config.search;
|
||||
|
||||
action.dialogType = 'layer';
|
||||
|
||||
// 自定义搜索方法
|
||||
search.searchInit = function (e) {
|
||||
var self = this;
|
||||
}
|
||||
|
||||
action.user_warehouse = function(data) {
|
||||
var me = this;
|
||||
var grid = config.grid;
|
||||
var rows = grid.api.getSelectedRows();
|
||||
if (rows.length == 1) {
|
||||
var user_id = rows[0].id;
|
||||
formDialog({
|
||||
title: '仓库权限',
|
||||
url: app.url('stock/warehouse/permission', {user_id: user_id}),
|
||||
storeUrl: app.url('stock/warehouse/permission'),
|
||||
id: 'user_warehouse',
|
||||
dialogClass:'modal-md',
|
||||
onSubmit: function() {
|
||||
var me = this;
|
||||
var form = gdoo.dialogs['user_warehouse'];
|
||||
var selectedRows = form.api.getSelectedRows();
|
||||
var loading = layer.msg('数据提交中...', {
|
||||
icon: 16, shade: 0.1, time: 1000 * 120
|
||||
});
|
||||
$.post(app.url('stock/warehouse/permission', {user_id: user_id}), {rows: selectedRows}, function(res) {
|
||||
if (res.status) {
|
||||
toastrSuccess(res.data);
|
||||
$(me).dialog('close');
|
||||
} else {
|
||||
toastrError(res.data);
|
||||
}
|
||||
}).complete(function() {
|
||||
layer.close(loading);
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
toastrError('只能选择一条记录');
|
||||
}
|
||||
}
|
||||
|
||||
action.user_role = function(data) {
|
||||
var me = this;
|
||||
var grid = config.grid;
|
||||
var rows = grid.api.getSelectedRows();
|
||||
if (rows.length == 1) {
|
||||
var user_id = rows[0].id;
|
||||
formDialog({
|
||||
title: '角色权限',
|
||||
url: app.url('user/role/permission', {user_id: user_id}),
|
||||
storeUrl: app.url('user/role/permission'),
|
||||
id: 'user_role',
|
||||
dialogClass:'modal-md',
|
||||
onSubmit: function() {
|
||||
var me = this;
|
||||
var form = gdoo.dialogs['user_role'];
|
||||
var selectedRows = form.api.getSelectedRows();
|
||||
var loading = layer.msg('数据提交中...', {
|
||||
icon: 16, shade: 0.1, time: 1000 * 120
|
||||
});
|
||||
$.post(app.url('user/role/permission', {user_id: user_id}), {rows: selectedRows}, function(res) {
|
||||
if (res.status) {
|
||||
toastrSuccess(res.data);
|
||||
$(me).dialog('close');
|
||||
} else {
|
||||
toastrError(res.data);
|
||||
}
|
||||
}).complete(function() {
|
||||
layer.close(loading);
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
toastrError('只能选择一条记录');
|
||||
}
|
||||
}
|
||||
|
||||
var grid = new agGridOptions();
|
||||
grid.remoteDataUrl = '{{url()}}';
|
||||
grid.remoteParams = search.advanced.query;
|
||||
grid.columnDefs = config.cols;
|
||||
grid.onRowDoubleClicked = function (params) {
|
||||
if (params.node.rowPinned) {
|
||||
return;
|
||||
}
|
||||
if (params.data == undefined) {
|
||||
return;
|
||||
}
|
||||
if (params.data.master_id > 0) {
|
||||
action.show(params.data);
|
||||
}
|
||||
};
|
||||
|
||||
var gridDiv = document.querySelector("#{{$header['table']}}-grid");
|
||||
gridDiv.style.height = getPanelHeight(48);
|
||||
new agGrid.Grid(gridDiv, grid);
|
||||
|
||||
// 读取数据
|
||||
grid.remoteData({page: 1});
|
||||
|
||||
// 绑定自定义事件
|
||||
var $gridDiv = $(gridDiv);
|
||||
$gridDiv.on('click', '[data-toggle="event"]', function () {
|
||||
var data = $(this).data();
|
||||
if (data.master_id > 0) {
|
||||
action[data.action](data);
|
||||
}
|
||||
});
|
||||
config.grid = grid;
|
||||
})(jQuery);
|
||||
</script>
|
||||
@include('footers')
|
||||
Reference in New Issue
Block a user