Page.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. <?php namespace Manage\Lib;
  2. use Dever;
  3. # 通用页面
  4. class Page extends Auth
  5. {
  6. protected $db;
  7. protected $key;
  8. protected $id = false;
  9. protected $menu = array();
  10. protected $config = array();
  11. protected $field = array();
  12. public $info = array();
  13. public function __construct($key = '', $load = '', $id = false)
  14. {
  15. parent::__construct();
  16. $this->key = $key;
  17. if ($id == -1) {
  18. $this->id = false;
  19. } else {
  20. $this->id = $id ? $id : Dever::input('id');
  21. }
  22. if (!$load) {
  23. $load = Dever::input('load');
  24. }
  25. $load = explode('/', ltrim($load, '/'));
  26. if (isset($load[2])) {
  27. $app = $load[1];
  28. $table = $load[2];
  29. } else {
  30. $app = $load[0];
  31. $table = $load[1];
  32. }
  33. $parent = Dever::db('menu')->find(array('key' => $app));
  34. if ($parent) {
  35. $this->menu = Dever::db('menu')->find(array('parent_id' => $parent['id'], 'key' => $table));
  36. if ($this->menu) {
  37. $this->checkMenu($this->menu['id'], false);
  38. $app = $this->menu['app'];
  39. }
  40. }
  41. $set = Dever::project($app);
  42. $manage = $set['path'] . 'table/manage/'.$table.'.php';
  43. if (is_file($manage)) {
  44. $manage = include $manage;
  45. if ($source = Dever::isset($manage, 'source')) {
  46. if (strpos($source, '/')) {
  47. $source = explode('/', $source);
  48. $app = $source[0];
  49. $table = $source[1];
  50. } else {
  51. $table = $source;
  52. }
  53. }
  54. if ($key) {
  55. $this->config = $manage[$key] ?? array();
  56. }
  57. }
  58. $this->db = Dever::db($table, $app);
  59. $this->db->config['manage'] = $manage;
  60. if ($this->id) {
  61. $this->info = $this->db->find($this->id);
  62. }
  63. }
  64. public function setting($key, &$data, $struct = true, $type = 'show', $disable = false)
  65. {
  66. if (empty($this->config[$key]) && $struct && isset($this->db->config['struct']) && $this->db->config['struct']) {
  67. $this->config[$key] = $this->db->config['struct'];
  68. }
  69. if (empty($this->config[$key])) {
  70. return;
  71. }
  72. $setting = $this->config[$key];
  73. if (is_string($setting)) {
  74. $setting = explode(',', $setting);
  75. }
  76. $field = Dever::input('field');
  77. return $this->setData($setting, $data, $field, $type, $disable);
  78. }
  79. # 获取某个数据的具体展示值
  80. public function getValue($key, $value, $data, $field = array())
  81. {
  82. if ($show = Dever::isset($field, 'show')) {
  83. $value = $this->getShow($show, $data);
  84. } elseif ($value && isset($this->db->config['struct'][$key]['value']) && $this->db->config['struct'][$key]['value']) {
  85. $value = $this->db->value($key, $value);
  86. } elseif ($key == 'cdate') {
  87. if ($value) {
  88. $value = date('Y-m-d H:i', $value);
  89. } else {
  90. $value = '-';
  91. }
  92. }
  93. return $value;
  94. }
  95. # 获取关联数据
  96. public function getOther($key, $set, $data, $method = 'fetchAll')
  97. {
  98. $where = array();
  99. foreach ($set as $k => $v) {
  100. if (!is_array($v) && isset($data[$v])) {
  101. $where[$k] = $data[$v];
  102. } else {
  103. $where[$k] = $v;
  104. }
  105. }
  106. if ($where) {
  107. return Dever::db($key)->select($where)->$method();
  108. }
  109. return array();
  110. }
  111. public function getShow($show, $data)
  112. {
  113. if (strpos($show, '{') !== false && strpos($show, '{"') === false) {
  114. $func = function ($r) use ($data) {
  115. if (isset($data[$r[1]])) {
  116. return $data[$r[1]];
  117. }
  118. return false;
  119. };
  120. $show = preg_replace_callback('/{(.*?)}/', $func, $show);
  121. }
  122. $eval = '$show = ' . $show . ';';
  123. eval($eval);
  124. return $show;
  125. }
  126. # 获取菜单标题
  127. public function getTitle()
  128. {
  129. return $this->menu['name'];
  130. }
  131. # 获取左侧分栏
  132. protected function column(&$data, $name = '左侧分栏')
  133. {
  134. $data['column'] = false;
  135. if (isset($this->config['column'])) {
  136. $data['column'] = $this->config['column'];
  137. if (isset($this->config['column']['add'])) {
  138. $data['column']['add'] = array('name' => $this->config['column']['add'], 'func' => $this->getFunc('column_add', $name . '-' . $this->config['column']['add'], 101));
  139. }
  140. if (isset($this->config['column']['edit'])) {
  141. $data['column']['edit'] = array('name' => '编辑', 'func' => $this->getFunc('column_edit', $name . '-编辑', 102));
  142. }
  143. if (isset($this->config['column']['delete'])) {
  144. $data['column']['delete'] = array('name' => '删除', 'func' => $this->getFunc('column_delete', $name . '-删除', 103));
  145. }
  146. $data['column']['data'] = Dever::call($this->config['column']['data']);
  147. $data['height'] = '100%';
  148. }
  149. }
  150. # 通用的规则验证 一般为更新数据时使用
  151. protected function checkRules($set, $data)
  152. {
  153. if ($set['rules']) {
  154. if (!is_array($set['rules'])) {
  155. $set['rules'] = array
  156. (
  157. array
  158. (
  159. 'required' => true,
  160. 'trigger' => 'blur',
  161. 'message' => $set['name'] . '不能为空',
  162. ),
  163. );
  164. }
  165. foreach ($set['rules'] as $k => $v) {
  166. if (isset($v['required']) && $v['required'] && !$data && $data !== 0) {
  167. Dever::error($v['message']);
  168. }
  169. if ($data || $data === 0) {
  170. if (isset($v['pattern']) && $v['pattern'] && !preg_match('/' . $v['pattern'] . '/', $data)) {
  171. Dever::error($v['message']);
  172. }
  173. if (isset($v['type']) && $v['type']) {
  174. if ($v['type'] == 'number' && !is_numeric($data)) {
  175. Dever::error($v['message']);
  176. } elseif ($v['type'] == 'array' && !is_array($data)) {
  177. Dever::error($v['message']);
  178. } elseif ($v['type'] == 'integer' && !is_int($data)) {
  179. Dever::error($v['message']);
  180. } elseif ($v['type'] == 'float' && !is_float($data)) {
  181. Dever::error($v['message']);
  182. } elseif ($v['type'] == 'string' && !is_string($data)) {
  183. Dever::error($v['message']);
  184. } elseif ($v['type'] == 'boolean' && !is_bool($data)) {
  185. Dever::error($v['message']);
  186. } elseif ($v['type'] == 'url' && !filter_var($data, FILTER_VALIDATE_URL)) {
  187. Dever::error($v['message']);
  188. } elseif ($v['type'] == 'email' && !filter_var($data, FILTER_VALIDATE_EMAIL)) {
  189. Dever::error($v['message']);
  190. } elseif ($v['type'] == 'enum' && isset($v['enum']) && !in_array($data, $v['enum'])) {
  191. Dever::error($v['message']);
  192. }
  193. }
  194. if (isset($v['len']) && $v['len'] && strlen($data) > $v['len']) {
  195. Dever::error($v['message']);
  196. }
  197. if (isset($v['min']) && $v['min'] && strlen($data) < $v['min']) {
  198. Dever::error($v['message']);
  199. }
  200. if (isset($v['max']) && $v['max'] && strlen($data) > $v['max']) {
  201. Dever::error($v['message']);
  202. }
  203. }
  204. }
  205. }
  206. }
  207. private function setData($setting, &$data, $field, $type, $disable)
  208. {
  209. $result = array();
  210. foreach ($setting as $k => $v) {
  211. if (!is_array($v)) {
  212. if (is_numeric($k)) {
  213. $k = $v;
  214. $v = $type;
  215. }
  216. if ($k == 'id') {
  217. $v = array('name' => 'ID', 'type' => $v);
  218. } elseif ($k == 'cdate') {
  219. $v = array('name' => '创建时间', 'type' => $v);
  220. } elseif(isset($this->db->config['struct'][$k])) {
  221. $v = array('name' => $this->db->config['struct'][$k]['name'], 'type' => $v);
  222. } else {
  223. $v = array('name' => $v);
  224. }
  225. } else {
  226. if (isset($v['only'])) {
  227. if ($v['only'] == 'edit' && !$this->id) {
  228. continue;
  229. } elseif ($v['only'] == 'add' && $this->id) {
  230. continue;
  231. }
  232. }
  233. }
  234. if ($field) {
  235. if (is_array($field)) {
  236. if (isset($field['field']) && !Dever::check($field['field'], $k)) {
  237. continue;
  238. }
  239. if (isset($field[$k])) {
  240. $v['default'] = $field[$k];
  241. $v['type'] = 'hidden';
  242. }
  243. } elseif (!Dever::check($field, $k)) {
  244. continue;
  245. }
  246. }
  247. $info = $this->setField($data, $k, $v, $field, $type, $disable);
  248. if ($info) {
  249. $result[] = $info;
  250. }
  251. }
  252. return $result;
  253. }
  254. private function setField(&$data, $key, $value = array(), $field, $type = 'show', $disable = false)
  255. {
  256. $value['key'] = $key;
  257. $this->setName($value);
  258. # 对每个字段进行权限设置
  259. if (isset($value['func']) && $value['func']) {
  260. $func = $this->getFunc('field_' . $value['key'], '字段-' . $value['name'], 200);
  261. if (!$func) {
  262. return false;
  263. }
  264. }
  265. if (strpos($key, '/') && $this->key == 'update') {
  266. $this->setType($value, 'array');
  267. $this->setShow($value);
  268. if (strpos($key, '#')) {
  269. $key = str_replace('#', '', $key);
  270. }
  271. $sku = $value['type'] == 'sku' ? true : false;
  272. $value['value'] = $this->getOther($key, $value['where'], $this->info);
  273. $update = new \Manage\Api\Page\Update($key, -1);
  274. $value['option'] = array();
  275. $value['content'] = $update->get($value['value'], $value['option'], $sku);
  276. $data[] = $value;
  277. return $value['name'];
  278. } else {
  279. $this->setType($value, $type);
  280. $this->setDisable($value, $disable);
  281. if ($this->key == 'update') {
  282. # 一般为更新页面需要的参数
  283. $this->setShow($value);
  284. $this->setRules($value);
  285. }
  286. if ($type == 'show') {
  287. $in = array('switch', 'select', 'input');
  288. if (in_array($value['type'], $in)) {
  289. $value['func'] = $this->getFunc('list_edit_' . $value['key'], '列表更新-' . $value['name'], 104);
  290. if (!$value['func']) {
  291. $value['type'] = 'show';
  292. if (isset($value['show'])) {
  293. unset($value['show']);
  294. }
  295. }
  296. }
  297. if (isset($value['child'])) {
  298. $child = array();
  299. $this->setData($value['child'], $child, $field, $type, $disable);
  300. $value['child'] = $child;
  301. } else {
  302. $this->field[$key] = $value;
  303. }
  304. }
  305. $this->setForm($value);
  306. $data[] = $value;
  307. return $value['name'];
  308. }
  309. }
  310. private function setShow(&$value)
  311. {
  312. if ($value['type'] == 'hidden') {
  313. $value['show'] = false;
  314. } elseif (empty($value['show'])) {
  315. $value['show'] = true;
  316. }
  317. }
  318. private function setName(&$value)
  319. {
  320. if (empty($value['name']) && isset($this->db->config['struct'][$value['key']])) {
  321. $value['name'] = $this->db->config['struct'][$value['key']]['name'];
  322. }
  323. if (empty($value['placeholder'])) {
  324. $value['placeholder'] = $value['name'];
  325. }
  326. }
  327. private function setType(&$value, $type)
  328. {
  329. if (empty($value['type'])) {
  330. $value['type'] = $type;
  331. }
  332. if (strpos($value['type'], '(')) {
  333. $value['type'] = $type;
  334. }
  335. if (isset($value['upload']) && Dever::project('upload')) {
  336. $value['url'] = Dever::url('upload/save.act', array('id' => $value['upload']));
  337. $value['config'] = Dever::load('upload/save')->get($value['upload']);
  338. if (isset($value['multiple']) && $value['multiple']) {
  339. $value['limit'] = 10;
  340. } else {
  341. $value['limit'] = 1;
  342. }
  343. }
  344. if (isset($value['editorMenu'])) {
  345. if (isset($value['editorMenu']['uploadImage'])) {
  346. if (!is_array($value['editorMenu']['uploadImage'])) {
  347. $value['editorMenu']['uploadImage'] = array('upload' => $value['editorMenu']['uploadImage']);
  348. }
  349. $value['editorMenu']['uploadImage']['server'] = Dever::url('upload/save.wangEditor', array('id' => $value['editorMenu']['uploadImage']['upload']));
  350. if (empty($value['editorMenu']['uploadImage']['fieldName'])) {
  351. $value['editorMenu']['uploadImage']['fieldName'] = 'file';
  352. }
  353. }
  354. if (isset($value['editorMenu']['uploadVideo'])) {
  355. if (!is_array($value['editorMenu']['uploadVideo'])) {
  356. $value['editorMenu']['uploadVideo'] = array('upload' => $value['editorMenu']['uploadVideo']);
  357. }
  358. $value['editorMenu']['uploadVideo']['server'] = Dever::url('upload/save.wangEditor', array('id' => $value['editorMenu']['uploadVideo']['upload']));
  359. if (empty($value['editorMenu']['uploadImage']['fieldName'])) {
  360. $value['editorMenu']['uploadImage']['fieldName'] = 'file';
  361. }
  362. }
  363. }
  364. }
  365. private function setDisable(&$value, $disable)
  366. {
  367. if (isset($value['disable'])) {
  368. $disable = $value['disable'];
  369. }
  370. $value['disable'] = $disable;
  371. }
  372. private function setForm(&$value)
  373. {
  374. $value['value'] = Dever::input('search')[$value['key']] ?? '';
  375. if (!$value['value']) {
  376. if (isset($value['default'])) {
  377. $value['value'] = $value['default'];
  378. } elseif ($this->key == 'update' && isset($this->db->config['struct'][$value['key']]['default'])) {
  379. $value['value'] = $this->db->config['struct'][$value['key']]['default'];
  380. }
  381. }
  382. if (isset($value['option']) && $value['option']) {
  383. $this->db->config['struct'][$value['key']]['value'] = $value['option'];
  384. }
  385. if ($option = $this->db->value($value['key'])) {
  386. if ($value['type'] == 'checkbox') {
  387. $value['value'] = $value['value'] ? explode(',', $value['value']) : array();
  388. }
  389. $value['option'] = $option;
  390. if ($value['type'] == 'text') {
  391. $value['type'] = 'select';
  392. }
  393. }
  394. }
  395. private function setRules(&$value)
  396. {
  397. if (isset($value['rules']) && $value['rules']) {
  398. if (!is_array($value['rules'])) {
  399. $value['rules'] = array
  400. (
  401. array
  402. (
  403. 'required' => true,
  404. 'trigger' => 'blur',
  405. 'message' => $value['name'] . '不能为空',
  406. ),
  407. );
  408. }
  409. foreach ($value['rules'] as $k => $v) {
  410. if (isset($v['only'])) {
  411. if ($v['only'] == 'edit' && !$this->id) {
  412. unset($value['rules'][$k]);
  413. break;
  414. } elseif ($v['only'] == 'add' && $this->id) {
  415. unset($value['rules'][$k]);
  416. break;
  417. }
  418. }
  419. }
  420. if (!isset($value['rules'][0])) {
  421. $value['rules'] = array_values($value['rules']);
  422. }
  423. }
  424. }
  425. }