Admin.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 海豚PHP框架 [ DolphinPHP ]
  4. // +----------------------------------------------------------------------
  5. // | 版权所有 2016~2017 河源市卓锐科技有限公司 [ http://www.zrthink.com ]
  6. // +----------------------------------------------------------------------
  7. // | 官方网站: http://dolphinphp.com
  8. // +----------------------------------------------------------------------
  9. // | 开源协议 ( http://www.apache.org/licenses/LICENSE-2.0 )
  10. // +----------------------------------------------------------------------
  11. namespace app\admin\controller;
  12. use app\common\controller\Common;
  13. use app\common\builder\ZBuilder;
  14. use app\admin\model\Menu as MenuModel;
  15. use app\admin\model\Module as ModuleModel;
  16. use app\user\model\Role as RoleModel;
  17. use think\Cache;
  18. use think\Db;
  19. use think\Loader;
  20. use think\helper\Hash;
  21. /**
  22. * 后台公共控制器
  23. * @package app\admin\controller
  24. */
  25. class Admin extends Common
  26. {
  27. /**
  28. * 初始化
  29. * @author 蔡伟明 <314013107@qq.com>
  30. */
  31. protected function _initialize()
  32. {
  33. parent::_initialize();
  34. // 是否拒绝ie浏览器访问
  35. if (config('system.deny_ie') && get_browser_type() == 'ie') {
  36. $this->redirect('admin/ie/index');
  37. }
  38. // 判断是否登录,并定义用户ID常量
  39. defined('UID') or define('UID', $this->isLogin());
  40. // 设置当前角色菜单节点权限
  41. role_auth();
  42. // 检查权限
  43. if (!RoleModel::checkAuth()) $this->error('权限不足!');
  44. // 设置分页参数
  45. $this->setPageParam();
  46. // 如果不是ajax请求,则读取菜单
  47. if (!$this->request->isAjax()) {
  48. // 读取顶部菜单
  49. $this->assign('_top_menus', MenuModel::getTopMenu(config('top_menu_max'), '_top_menus'));
  50. // 读取全部顶级菜单
  51. $this->assign('_top_menus_all', MenuModel::getTopMenu('', '_top_menus_all'));
  52. // 获取侧边栏菜单
  53. $this->assign('_sidebar_menus', MenuModel::getSidebarMenu());
  54. // 获取面包屑导航
  55. $this->assign('_location', MenuModel::getLocation('', true));
  56. // 构建侧栏
  57. $data = [
  58. 'table' => 'admin_config', // 表名或模型名
  59. 'prefix' => 1,
  60. 'module' => 'admin',
  61. 'controller' => 'system',
  62. 'action' => 'quickedit',
  63. ];
  64. $table_token = substr(sha1('_aside'), 0, 8);
  65. session($table_token, $data);
  66. $settings = [
  67. [
  68. 'title' => '站点开关',
  69. 'tips' => '站点关闭后将不能访问',
  70. 'checked' => Db::name('admin_config')->where('id', 1)->value('value'),
  71. 'table' => $table_token,
  72. 'id' => 1,
  73. 'field' => 'value'
  74. ]
  75. ];
  76. ZBuilder::make('aside')
  77. ->addBlock('switch', '系统设置', $settings);
  78. }
  79. }
  80. /**
  81. * 获取当前操作模型
  82. * @author 蔡伟明 <314013107@qq.com>
  83. * @return object|\think\db\Query
  84. */
  85. final protected function getCurrModel()
  86. {
  87. $table_token = input('param._t', '');
  88. $module = $this->request->module();
  89. $controller = parse_name($this->request->controller());
  90. $table_token == '' && $this->error('缺少参数');
  91. !session('?'.$table_token) && $this->error('参数错误');
  92. $table_data = session($table_token);
  93. $table = $table_data['table'];
  94. $Model = null;
  95. if ($table_data['prefix'] == 2) {
  96. // 使用模型
  97. try {
  98. $Model = Loader::model($table);
  99. } catch (\Exception $e) {
  100. $this->error('找不到模型:'.$table);
  101. }
  102. } else {
  103. // 使用DB类
  104. $table == '' && $this->error('缺少表名');
  105. if ($table_data['module'] != $module || $table_data['controller'] != $controller) {
  106. $this->error('非法操作');
  107. }
  108. $Model = $table_data['prefix'] == 0 ? Db::table($table) : Db::name($table);
  109. }
  110. return $Model;
  111. }
  112. /**
  113. * 设置分页参数
  114. * @author 蔡伟明 <314013107@qq.com>
  115. */
  116. final protected function setPageParam()
  117. {
  118. _system_check();
  119. $list_rows = input('?param.list_rows') ? input('param.list_rows') : config('list_rows');
  120. config('paginate.list_rows', $list_rows);
  121. config('paginate.query', input('get.'));
  122. }
  123. /**
  124. * 检查是否登录,没有登录则跳转到登录页面
  125. * @author 蔡伟明 <314013107@qq.com>
  126. * @return int
  127. */
  128. final protected function isLogin()
  129. {
  130. // 判断是否登录
  131. if ($uid = is_signin()) {
  132. // 已登录
  133. return $uid;
  134. } else {
  135. // 未登录
  136. $this->redirect('user/publics/signin');
  137. }
  138. }
  139. /**
  140. * 禁用
  141. * @param array $record 行为日志内容
  142. * @author 蔡伟明 <314013107@qq.com>
  143. * @return mixed
  144. */
  145. public function disable($record = [])
  146. {
  147. return $this->setStatus('disable', $record);
  148. }
  149. /**
  150. * 启用
  151. * @param array $record 行为日志内容
  152. * @author 蔡伟明 <314013107@qq.com>
  153. * @return mixed
  154. */
  155. public function enable($record = [])
  156. {
  157. return $this->setStatus('enable', $record);
  158. }
  159. /**
  160. * 启用
  161. * @param array $record 行为日志内容
  162. * @author 蔡伟明 <314013107@qq.com>
  163. * @return mixed
  164. */
  165. public function delete($record = [])
  166. {
  167. return $this->setStatus('delete', $record);
  168. }
  169. /**
  170. * 快速编辑
  171. * @param array $record 行为日志内容
  172. * @author 蔡伟明 <314013107@qq.com>
  173. */
  174. public function quickEdit($record = [])
  175. {
  176. $field = input('post.name', '');
  177. $value = input('post.value', '');
  178. $type = input('post.type', '');
  179. $id = input('post.pk', '');
  180. $validate = input('post.validate', '');
  181. $validate_fields = input('post.validate_fields', '');
  182. $field == '' && $this->error('缺少字段名');
  183. $id == '' && $this->error('缺少主键值');
  184. $Model = $this->getCurrModel();
  185. $protect_table = [
  186. '__ADMIN_USER__',
  187. '__ADMIN_ROLE__',
  188. config('database.prefix').'admin_user',
  189. config('database.prefix').'admin_role',
  190. ];
  191. // 验证是否操作管理员
  192. if (in_array($Model->getTable(), $protect_table) && $id == 1) {
  193. $this->error('禁止操作超级管理员');
  194. }
  195. // 验证器
  196. if ($validate != '') {
  197. $validate_fields = array_flip(explode(',', $validate_fields));
  198. if (isset($validate_fields[$field])) {
  199. $result = $this->validate([$field => $value], $validate.'.'.$field);
  200. if (true !== $result) $this->error($result);
  201. }
  202. }
  203. switch ($type) {
  204. // 日期时间需要转为时间戳
  205. case 'combodate':
  206. $value = strtotime($value);
  207. break;
  208. // 开关
  209. case 'switch':
  210. $value = $value == 'true' ? 1 : 0;
  211. break;
  212. // 开关
  213. case 'password':
  214. $value = Hash::make((string)$value);
  215. break;
  216. }
  217. // 主键名
  218. $pk = $Model->getPk();
  219. $result = $Model->where($pk, $id)->setField($field, $value);
  220. cache('hook_plugins', null);
  221. cache('system_config', null);
  222. cache('access_menus', null);
  223. if (false !== $result) {
  224. // 记录行为日志
  225. if (!empty($record)) {
  226. call_user_func_array('action_log', $record);
  227. }
  228. $this->success('操作成功');
  229. } else {
  230. $this->error('操作失败');
  231. }
  232. }
  233. /**
  234. * 自动创建添加页面
  235. * @author caiweiming <314013107@qq.com>
  236. */
  237. public function add()
  238. {
  239. // 获取表单项
  240. $cache_name = $this->request->module().'/'.parse_name($this->request->controller()).'/add';
  241. $cache_name = strtolower($cache_name);
  242. $form = Cache::get($cache_name, []);
  243. if (!$form) {
  244. $this->error('自动新增数据不存在,请重新打开此页面');
  245. }
  246. // 保存数据
  247. if ($this->request->isPost()) {
  248. // 表单数据
  249. $data = $this->request->post();
  250. $_pop = $this->request->get('_pop');
  251. // 验证
  252. if ($form['validate'] != '') {
  253. $result = $this->validate($data, $form['validate']);
  254. if(true !== $result) $this->error($result);
  255. }
  256. // 是否需要自动插入时间
  257. if ($form['auto_time'] != '') {
  258. $now_time = $this->request->time();
  259. foreach ($form['auto_time'] as $item) {
  260. if (strpos($item, '|')) {
  261. list($item, $format) = explode('|', $item);
  262. $data[$item] = date($format, $now_time);
  263. } else {
  264. $data[$item] = $form['format'] != '' ? date($form['format'], $now_time) : $now_time;
  265. }
  266. }
  267. }
  268. // 插入数据
  269. if (Db::name($form['table'])->insert($data)) {
  270. if ($_pop == 1) {
  271. $this->success('新增成功', null, '_parent_reload');
  272. } else {
  273. $this->success('新增成功', $form['go_back']);
  274. }
  275. } else {
  276. $this->error('新增失败');
  277. }
  278. }
  279. // 显示添加页面
  280. return ZBuilder::make('form')
  281. ->addFormItems($form['items'])
  282. ->fetch();
  283. }
  284. /**
  285. * 自动创建编辑页面
  286. * @param string $id 主键值
  287. * @author caiweiming <314013107@qq.com>
  288. */
  289. public function edit($id = '')
  290. {
  291. if ($id === '') $this->error('参数错误');
  292. // 获取表单项
  293. $cache_name = $this->request->module().'/'.parse_name($this->request->controller()).'/edit';
  294. $cache_name = strtolower($cache_name);
  295. $form = Cache::get($cache_name, []);
  296. if (!$form) {
  297. $this->error('自动编辑数据不存在,请重新打开此页面');
  298. }
  299. // 保存数据
  300. if ($this->request->isPost()) {
  301. // 表单数据
  302. $data = $this->request->post();
  303. $_pop = $this->request->get('_pop');
  304. // 验证
  305. if ($form['validate'] != '') {
  306. $result = $this->validate($data, $form['validate']);
  307. if(true !== $result) $this->error($result);
  308. }
  309. // 是否需要自动插入时间
  310. if ($form['auto_time'] != '') {
  311. $now_time = $this->request->time();
  312. foreach ($form['auto_time'] as $item) {
  313. if (strpos($item, '|')) {
  314. list($item, $format) = explode('|', $item);
  315. $data[$item] = date($format, $now_time);
  316. } else {
  317. $data[$item] = $form['format'] != '' ? date($form['format'], $now_time) : $now_time;
  318. }
  319. }
  320. }
  321. // 更新数据
  322. if (false !== Db::name($form['table'])->update($data)) {
  323. if ($_pop == 1) {
  324. $this->success('编辑成功', null, '_parent_reload');
  325. } else {
  326. $this->success('编辑成功', $form['go_back']);
  327. }
  328. } else {
  329. $this->error('编辑失败');
  330. }
  331. }
  332. // 获取数据
  333. $info = Db::name($form['table'])->find($id);
  334. // 使用ZBuilder快速创建表单
  335. return ZBuilder::make('form')
  336. ->setPageTitle('编辑')
  337. ->addFormItems($form['items'])
  338. ->setFormData($info)
  339. ->fetch();
  340. }
  341. /**
  342. * 设置状态
  343. * 禁用、启用、删除都是调用这个内部方法
  344. * @param string $type 操作类型:enable,disable,delete
  345. * @param array $record 行为日志内容
  346. * @author 蔡伟明 <314013107@qq.com>
  347. * @return mixed
  348. */
  349. public function setStatus($type = '', $record = [])
  350. {
  351. $ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
  352. $ids = (array)$ids;
  353. $field = input('param.field', 'status');
  354. empty($ids) && $this->error('缺少主键');
  355. $Model = $this->getCurrModel();
  356. $protect_table = [
  357. '__ADMIN_USER__',
  358. '__ADMIN_ROLE__',
  359. '__ADMIN_MODULE__',
  360. config('database.prefix').'admin_user',
  361. config('database.prefix').'admin_role',
  362. config('database.prefix').'admin_module',
  363. ];
  364. // 禁止操作核心表的主要数据
  365. if (in_array($Model->getTable(), $protect_table) && in_array('1', $ids)) {
  366. $this->error('禁止操作');
  367. }
  368. // 主键名称
  369. $pk = $Model->getPk();
  370. $map[$pk] = ['in', $ids];
  371. $result = false;
  372. switch ($type) {
  373. case 'disable': // 禁用
  374. $result = $Model->where($map)->setField($field, 0);
  375. break;
  376. case 'enable': // 启用
  377. $result = $Model->where($map)->setField($field, 1);
  378. break;
  379. case 'delete': // 删除
  380. $result = $Model->where($map)->delete();
  381. break;
  382. default:
  383. $this->error('非法操作');
  384. break;
  385. }
  386. if (false !== $result) {
  387. Cache::clear();
  388. // 记录行为日志
  389. if (!empty($record)) {
  390. call_user_func_array('action_log', $record);
  391. }
  392. $this->success('操作成功');
  393. } else {
  394. $this->error('操作失败');
  395. }
  396. }
  397. /**
  398. * 模块设置
  399. * @author 蔡伟明 <314013107@qq.com>
  400. * @return mixed
  401. */
  402. public function moduleConfig()
  403. {
  404. // 当前模块名
  405. $module = $this->request->module();
  406. // 保存
  407. if ($this->request->isPost()) {
  408. $data = $this->request->post();
  409. $data = json_encode($data);
  410. if (false !== ModuleModel::where('name', $module)->update(['config' => $data])) {
  411. cache('module_config_'.$module, null);
  412. $this->success('更新成功');
  413. } else {
  414. $this->error('更新失败');
  415. }
  416. }
  417. // 模块配置信息
  418. $module_info = ModuleModel::getInfoFromFile($module);
  419. $config = $module_info['config'];
  420. $trigger = isset($module_info['trigger']) ? $module_info['trigger'] : [];
  421. // 数据库内的模块信息
  422. $db_config = ModuleModel::where('name', $module)->value('config');
  423. $db_config = json_decode($db_config, true);
  424. // 使用ZBuilder快速创建表单
  425. return ZBuilder::make('form')
  426. ->setPageTitle('模块设置')
  427. ->addFormItems($config)
  428. ->setFormdata($db_config) // 设置表格数据
  429. ->setTrigger($trigger) // 设置触发
  430. ->fetch();
  431. }
  432. }