Field.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  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\cms\admin;
  12. use app\admin\controller\Admin;
  13. use app\common\builder\ZBuilder;
  14. use app\cms\model\Field as FieldModel;
  15. use think\Db;
  16. /**
  17. * 字段管理控制器
  18. * @package app\cms\admin
  19. */
  20. class Field extends Admin
  21. {
  22. /**
  23. * 字段列表
  24. * @param null $id 文档模型id
  25. * @author 蔡伟明 <314013107@qq.com>
  26. */
  27. public function index($id = null)
  28. {
  29. $id === null && $this->error('参数错误');
  30. cookie('__forward__', $_SERVER['REQUEST_URI']);
  31. // 查询
  32. $map = $this->getMap();
  33. $map[]=['model','=',$id];
  34. // 数据列表
  35. $data_list = FieldModel::where($map)->order('id desc')->paginate();
  36. // 使用ZBuilder快速创建数据表格
  37. return ZBuilder::make('table')
  38. ->setSearch(['name' => '名称', 'title' => '标题']) // 设置搜索框
  39. ->setPageTips('【显示】表示新增或编辑文档时是否显示该字段<br>【启用】表示前台是否显示')
  40. ->addColumns([ // 批量添加数据列
  41. ['id', 'ID'],
  42. ['name', '名称'],
  43. ['title', '标题'],
  44. ['type', '类型', 'text', '', config('form_item_type')],
  45. ['create_time', '创建时间', 'datetime'],
  46. ['sort', '排序', 'text.edit'],
  47. ['show', '显示', 'switch'],
  48. ['status', '启用', 'switch'],
  49. ['right_button', '操作', 'btn']
  50. ])
  51. ->addTopButton('back', ['href' => url('model/index')]) // 批量添加顶部按钮
  52. ->addTopButton('add', ['href' => url('add', ['model' => $id])]) // 添加顶部按钮
  53. ->addTopButtons('enable,disable') // 批量添加顶部按钮
  54. ->addRightButtons('edit,delete') // 批量添加右侧按钮
  55. ->replaceRightButton(['fixed' => 1], '<button class="btn btn-danger btn-xs" type="button" disabled>固定字段禁止操作</button>')
  56. ->setRowList($data_list) // 设置表格数据
  57. ->fetch(); // 渲染模板
  58. }
  59. /**
  60. * 新增字段
  61. * @param string $model 文档模型id
  62. * @author 蔡伟明 <314013107@qq.com>
  63. * @return mixed
  64. */
  65. public function add($model = '')
  66. {
  67. // 内容模型类别[0-系统,1-普通,2-独立]
  68. $model_type = get_model_type($model);
  69. if ($this->request->isPost()) {
  70. // 表单数据
  71. $data = $this->request->post();
  72. // 非独立模型需验证字段名称是否为aid
  73. if ($model_type != 2) {
  74. // 非独立模型需验证新增的字段是否被系统占用
  75. if ($data['name'] == 'aid' || is_default_field($data['name'])) {
  76. $this->error('字段名称已存在');
  77. }
  78. }
  79. $result = $this->validate($data, 'Field');
  80. if(true !== $result) $this->error($result);
  81. // 如果是快速联动
  82. switch ($data['type']) {
  83. case 'linkages':
  84. $data['key'] = $data['key'] == '' ? 'id' : $data['key'];
  85. $data['pid'] = $data['pid'] == '' ? 'pid' : $data['pid'];
  86. $data['level'] = $data['level'] == '' ? '2' : $data['level'];
  87. $data['option'] = $data['option'] == '' ? 'name' : $data['option'];
  88. break;
  89. case 'number':
  90. $data['type'] = 'text';
  91. break;
  92. case 'bmap':
  93. $data['level'] = !$data['level'] ? 12 : $data['level'];
  94. break;
  95. }
  96. if ($field = FieldModel::create($data)) {
  97. $FieldModel = new FieldModel();
  98. // 添加字段
  99. if ($FieldModel->newField($data)) {
  100. // 记录行为
  101. $details = '详情:文档模型('.get_model_title($data['model']).')、字段名称('.$data['name'].')、字段标题('.$data['title'].')、字段类型('.$data['type'].')';
  102. action_log('field_add', 'cms_field', $field['id'], UID, $details);
  103. // 清除缓存
  104. cache('cms_system_fields', null);
  105. $this->success('新增成功', cookie('__forward__'));
  106. } else {
  107. // 添加失败,删除新增的数据
  108. FieldModel::destroy($field['id']);
  109. $this->error($FieldModel->getError());
  110. }
  111. } else {
  112. $this->error('新增失败');
  113. }
  114. }
  115. if ($model_type != 2) {
  116. $field_exist = Db::name('cms_field')->where('model', 'in', [0, $model])->column('name');
  117. $field_exist[] = 'aid';
  118. } else {
  119. $field_exist = ['id','cid','uid','title','model','create_time','update_time','sort','status','view','trash'];
  120. }
  121. // 显示添加页面
  122. return ZBuilder::make('form')
  123. ->setPageTips('以下字段名称已存在,请不要建立同名的字段:<br>'. implode('、', $field_exist))
  124. ->addFormItems([
  125. ['hidden', 'model', $model],
  126. ['text', 'name', '字段名称', '由小写英文字母和下划线组成'],
  127. ['text', 'title', '字段标题', '可填写中文'],
  128. ['select', 'type', '字段类型', '', config('form_item_type')],
  129. ['text', 'define', '字段定义', '可根据实际需求自行填写或修改,但必须是正确的sql语法'],
  130. ['text', 'value', '字段默认值'],
  131. ['textarea', 'options', '额外选项', '用于单选、多选、下拉、联动等类型'],
  132. ['text', 'ajax_url', '异步请求地址', "如请求的地址是 <code>url('ajax/getCity')</code>,那么只需填写 <code>ajax/getCity</code>,或者直接填写以 <code>http</code>开头的url地址"],
  133. ['text', 'next_items', '下一级联动下拉框的表单名', "与当前有关联的下级联动下拉框名,多个用逗号隔开,如:area,other"],
  134. ['text', 'param', '请求参数名', "联动下拉框请求参数名,默认为配置名称"],
  135. ['text', 'level', '级别', '如果类型为【快速联动下拉框】则表示需要显示的级别数量,默认为2。如果类型为【百度地图】,则表示地图默认缩放级别,建议设置为12', 2],
  136. ['text', 'table', '表名', '要查询的表,里面必须含有id、name、pid三个字段,其中id和name字段可在下面重新定义'],
  137. ['text', 'pid', '父级id字段名', '即表中的父级ID字段名,如果表中的主键字段名为pid则可不填写'],
  138. ['text', 'key', '键字段名', '即表中的主键字段名,如果表中的主键字段名为id则可不填写'],
  139. ['text', 'option', '值字段名', '下拉菜单显示的字段名,如果表中的该字段名为name则可不填写'],
  140. ['text', 'ak', 'APPKEY', '百度编辑器APPKEY'],
  141. ['text', 'format', '格式'],
  142. ['textarea', 'tips', '字段说明', '字段补充说明'],
  143. ['radio', 'fixed', '是否为固定字段', '如果为 <code>固定字段</code> 则添加后不可修改', ['否', '是'], 0],
  144. ['radio', 'show', '是否显示', '新增或编辑时是否显示该字段', ['否', '是'], 1],
  145. ['radio', 'status', '立即启用', '', ['否', '是'], 1],
  146. ['text', 'sort', '排序', '', 100],
  147. ])
  148. ->setTrigger('type', 'linkage', 'ajax_url,next_items,param')
  149. ->setTrigger('type', 'linkages', 'table,pid,key,option')
  150. ->setTrigger('type', 'bmap', 'ak')
  151. ->setTrigger('type', 'linkages,bmap', 'level')
  152. ->setTrigger('type', 'masked,date,time,datetime', 'format')
  153. ->setTrigger('type', 'checkbox,radio,array,select,linkage,linkages', 'options')
  154. ->js('field')
  155. ->fetch();
  156. }
  157. /**
  158. * 编辑字段
  159. * @param null $id 字段id
  160. * @author 蔡伟明 <314013107@qq.com>
  161. * @return mixed
  162. */
  163. public function edit($id = null)
  164. {
  165. if ($id === null) $this->error('参数错误');
  166. // 保存数据
  167. if ($this->request->isPost()) {
  168. // 表单数据
  169. $data = $this->request->post();
  170. // 验证
  171. $result = $this->validate($data, 'Field');
  172. if(true !== $result) $this->error($result);
  173. // 如果是快速联动
  174. if ($data['type'] == 'linkages') {
  175. $data['key'] = $data['key'] == '' ? 'id' : $data['key'];
  176. $data['pid'] = $data['pid'] == '' ? 'pid' : $data['pid'];
  177. $data['level'] = $data['level'] == '' ? '2' : $data['level'];
  178. $data['option'] = $data['option'] == '' ? 'name' : $data['option'];
  179. }
  180. // 如果是百度地图
  181. if ($data['type'] == 'bmap') {
  182. $data['level'] = !$data['level'] ? 12 : $data['level'];
  183. }
  184. // 更新字段信息
  185. $FieldModel = new FieldModel();
  186. if ($FieldModel->updateField($data)) {
  187. if ($FieldModel->isUpdate(true)->save($data)) {
  188. // 记录行为
  189. action_log('field_edit', 'cms_field', $id, UID, $data['name']);
  190. $this->success('字段更新成功', cookie('__forward__'));
  191. }
  192. }
  193. $this->error('字段更新失败');
  194. }
  195. // 获取数据
  196. $info = FieldModel::get($id);
  197. // 显示编辑页面
  198. return ZBuilder::make('form')
  199. ->addFormItems([
  200. ['hidden', 'id'],
  201. ['hidden', 'model'],
  202. ['text', 'name', '字段名称', '由小写英文字母和下划线组成'],
  203. ['text', 'title', '字段标题', '可填写中文'],
  204. ['select', 'type', '字段类型', '', config('form_item_type')],
  205. ['text', 'define', '字段定义', '可根据实际需求自行填写或修改,但必须是正确的sql语法'],
  206. ['text', 'value', '字段默认值'],
  207. ['textarea', 'options', '额外选项', '用于单选、多选、下拉、联动等类型'],
  208. ['text', 'ajax_url', '异步请求地址', "如请求的地址是 <code>url('ajax/getCity')</code>,那么只需填写 <code>ajax/getCity</code>,或者直接填写以 <code>http</code>开头的url地址"],
  209. ['text', 'next_items', '下一级联动下拉框的表单名', "与当前有关联的下级联动下拉框名,多个用逗号隔开,如:area,other"],
  210. ['text', 'param', '请求参数名', "联动下拉框请求参数名,默认为配置名称"],
  211. ['text', 'level', '级别', '如果类型为【快速联动下拉框】则表示需要显示的级别数量,默认为2。如果类型为【百度地图】,则表示地图默认缩放级别,建议设置为12'],
  212. ['text', 'table', '表名', '要查询的表,里面必须含有id、name、pid三个字段,其中id和name字段可在下面重新定义'],
  213. ['text', 'pid', '父级id字段名', '即表中的父级ID字段名,如果表中的主键字段名为pid则可不填写'],
  214. ['text', 'key', '键字段名', '即表中的主键字段名,如果表中的主键字段名为id则可不填写'],
  215. ['text', 'option', '值字段名', '下拉菜单显示的字段名,如果表中的该字段名为name则可不填写'],
  216. ['text', 'ak', 'APPKEY', '百度编辑器APPKEY'],
  217. ['text', 'format', '格式'],
  218. ['textarea', 'tips', '字段说明', '字段补充说明'],
  219. ['radio', 'show', '是否显示', '新增或编辑时是否显示该字段', ['否', '是']],
  220. ['radio', 'status', '立即启用', '', ['否', '是']],
  221. ['text', 'sort', '排序'],
  222. ])
  223. ->setTrigger('type', 'linkage', 'ajax_url,next_items,param')
  224. ->setTrigger('type', 'linkages', 'table,pid,key,option')
  225. ->setTrigger('type', 'bmap', 'ak')
  226. ->setTrigger('type', 'linkages,bmap', 'level')
  227. ->setTrigger('type', 'masked,date,time,datetime', 'format')
  228. ->setTrigger('type', 'checkbox,radio,array,select,linkage,linkages', 'options')
  229. ->js('field')
  230. ->setFormData($info)
  231. ->fetch();
  232. }
  233. /**
  234. * 删除字段
  235. * @param null $ids 字段id
  236. * @author 蔡伟明 <314013107@qq.com>
  237. * @return mixed
  238. */
  239. public function delete($ids = null)
  240. {
  241. if ($ids === null) $this->error('参数错误');
  242. $FieldModel = new FieldModel();
  243. $field = $FieldModel->where('id', $ids)->find();
  244. if ($FieldModel->deleteField($field)) {
  245. if ($FieldModel->where('id', $ids)->delete()) {
  246. // 记录行为
  247. $details = '详情:文档模型('.get_model_title($field['model']).')、字段名称('.$field['name'].')、字段标题('.$field['title'].')、字段类型('.$field['type'].')';
  248. action_log('field_delete', 'cms_field', $ids, UID, $details);
  249. $this->success('删除成功', cookie('__forward__'));
  250. }
  251. }
  252. return $this->error('删除失败');
  253. }
  254. /**
  255. * 启用字段
  256. * @param array $record 行为日志
  257. * @author 蔡伟明 <314013107@qq.com>
  258. * @return mixed
  259. */
  260. public function enable($record = [])
  261. {
  262. return $this->setStatus('enable');
  263. }
  264. /**
  265. * 禁用字段
  266. * @param array $record 行为日志
  267. * @author 蔡伟明 <314013107@qq.com>
  268. * @return mixed
  269. */
  270. public function disable($record = [])
  271. {
  272. return $this->setStatus('disable');
  273. }
  274. /**
  275. * 设置字段状态:删除、禁用、启用
  276. * @param string $type 类型:enable/disable
  277. * @param array $record
  278. * @author 蔡伟明 <314013107@qq.com>
  279. * @return mixed
  280. */
  281. public function setStatus($type = '', $record = [])
  282. {
  283. $ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
  284. $field_delete = is_array($ids) ? '' : $ids;
  285. $field_names = FieldModel::where('id', 'in', $ids)->column('name');
  286. return parent::setStatus($type, ['field_'.$type, 'cms_field', $field_delete, UID, implode('、', $field_names)]);
  287. }
  288. /**
  289. * 快速编辑
  290. * @param array $record 行为日志
  291. * @author 蔡伟明 <314013107@qq.com>
  292. * @return mixed
  293. */
  294. public function quickEdit($record = [])
  295. {
  296. $id = input('post.pk', '');
  297. $field = input('post.name', '');
  298. $value = input('post.value', '');
  299. $config = FieldModel::where('id', $id)->value($field);
  300. $details = '字段(' . $field . '),原值(' . $config . '),新值:(' . $value . ')';
  301. return parent::quickEdit(['field_edit', 'cms_field', $id, UID, $details]);
  302. }
  303. }