DolphinPHP实战,开发一个简单的员工管理系统.
主要有emp_employee员工表,emp_status_info员工状态表,emp_dept员工部门表,emp_position员工职位表,员工地址表:
create table emp_employee( id int(10) primary key auto_increment, name varchar(10) comment '姓名', age int(2) comment '年龄', phone varchar(30) not null comment '电话', salary decimal not null comment '工资', p_id int(10) not null comment '领导id', position_id int(10) not null comment '职位id', addr_id int(10) not null comment '地址id', status_id int(10) not null comment '员工当前状态id', join_in_time datetime not null comment '入职时间', leave_out_time datetime comment '离职时间', create_time datetime, update_time datetime ); create table emp_status_info( id int(10) primary key auto_increment, status int(1) not null comment '员工当前状态 -1离职 0正常 1请假 2调休', reason text comment '事由', begin_time datetime comment '开始时间', end_time datetime comment '结束时间', create_time datetime, update_time datetime ); create table emp_dept ( id int(10) primary key auto_increment, name varchar(30) not null comment '部门名称', manger_id int(10) comment '部门主管id', create_time datetime, update_time datetime ); create table emp_position( id int(10) primary key auto_increment, name varchar(30) not null comment '职位名称', dept_id int(10) not null comment '所属部门', create_time datetime, update_time datetime ); create table emp_addr( id int(10) primary key auto_increment, street varchar(50) comment '街道', number int(6) comment '门牌编号', province varchar(50) comment '省', city varchar(50) comment '市', create_time datetime, update_time datetime );向数据库中插入数据:
-- emp_employee INSERT INTO dolphin.emp_employee (id, name, age, phone, salary, p_id, position_id, addr_id, status_id, join_in_time, leave_out_time, create_time, update_time) VALUES (1, '张三', 18, '13232323232', 8000, 0, 1, 1, 0, '2019-07-18 06:39:28', null, '2019-07-18 06:39:40', '2019-07-18 06:39:45'); INSERT INTO dolphin.emp_employee (id, name, age, phone, salary, p_id, position_id, addr_id, status_id, join_in_time, leave_out_time, create_time, update_time) VALUES (2, '李四', 20, '13443433333', 9000, 0, 2, 2, 0, '2019-07-18 06:41:22', null, '2019-07-18 06:41:25', '2019-07-18 06:41:26'); INSERT INTO dolphin.emp_employee (id, name, age, phone, salary, p_id, position_id, addr_id, status_id, join_in_time, leave_out_time, create_time, update_time) VALUES (3, '王五', 18, '13232323232', 8000, 0, 3, 3, 0, '2019-07-18 06:39:28', null, '2019-07-18 06:39:40', '2019-07-18 06:39:45'); -- emp_dept INSERT INTO dolphin.emp_dept (id, name, manger_id, create_time, update_time) VALUES (1, '技术部', 0, '2019-07-18 06:50:13', '2019-07-18 06:50:16'); INSERT INTO dolphin.emp_dept (id, name, manger_id, create_time, update_time) VALUES (2, '财物部', 0, '2019-07-18 06:50:41', '2019-07-18 06:50:43'); INSERT INTO dolphin.emp_dept (id, name, manger_id, create_time, update_time) VALUES (3, '市场部', 0, '2019-07-18 06:51:09', '2019-07-18 06:51:15'); INSERT INTO dolphin.emp_dept (id, name, manger_id, create_time, update_time) VALUES (4, '运营部', 0, '2019-07-18 06:51:28', '2019-07-18 06:51:30'); -- emp_position INSERT INTO dolphin.emp_position (id, name, dept_id, create_time, update_time) VALUES (1, 'Java开发工程师', 1, '2019-07-18 06:53:16', '2019-07-18 06:53:17'); INSERT INTO dolphin.emp_position (id, name, dept_id, create_time, update_time) VALUES (2, '前端开发工程师', 1, '2019-07-18 06:53:47', '2019-07-18 06:53:50'); INSERT INTO dolphin.emp_position (id, name, dept_id, create_time, update_time) VALUES (3, 'PHP开发工程师', 1, '2019-07-18 06:54:18', '2019-07-18 06:54:20'); INSERT INTO dolphin.emp_position (id, name, dept_id, create_time, update_time) VALUES (4, 'Golang开发工程师', 1, '2019-07-18 06:54:55', '2019-07-18 06:54:56'); -- emp_addr INSERT INTO dolphin.emp_addr (id, street, number, province, city, create_time, update_time) VALUES (1, '西乡街道', 1002, '广东', '深圳', '2019-07-18 06:56:47', '2019-07-18 06:56:49'); INSERT INTO dolphin.emp_addr (id, street, number, province, city, create_time, update_time) VALUES (2, '宝安大道', 2004, '广东', '深圳', '2019-07-18 06:57:36', '2019-07-18 06:57:37'); INSERT INTO dolphin.emp_addr (id, street, number, province, city, create_time, update_time) VALUES (3, '南山大道', 2012, '广东', '深圳', '2019-07-18 06:59:38', '2019-07-18 06:59:40');在application目录下新建一个employee目录,并在employee目录下新建一个info.php文件:
<?php /** * 员工表模块信息 */ return [ // 模块名[必填] 'name' => 'employee', // 模块标题[必填] 'title' => '员工', // 模块唯一标识[必填],格式:模块名.开发者标识.module 'identifier' => 'emp.xx.module', // 开发者[必填] 'author' => 'xxx', // 版本[必填],格式采用三段式:主版本号.次版本号.修订版本号 'version' => '1.0.0', // 模块描述[必填] 'description' => '员工模块', ];我们进入系统->扩展中心->模块管理中可以查看到当前的模块信息: 我样可以通过点击安装来安装当前模块. 安装完模块后,我们要让模块展示出来,类似其他模块一样: 我们要通过系统->系统功能->节点管理->新增来添加节点: 然后在新增界面添加如下信息,并提交: 待页面刷新后我们就可以看到刚才添加的节点信息了: 如果此时点击它会提示无任何节权限. 接下来我们要做的就是为当前节点添加子节点,以同样的方式来到新增节点的页面,并填写这样如下的节点信息,并提交: 添加完成后我们再点击员工,会看到如下信息:
在employee目录下新建一个admin目录,并在admin目录下新建一个Index.php,注意这里I是大写的.并在Index.php下面输入以下内容:
<?php namespace app\employee\admin; use app\admin\controller\Admin; class Index extends Admin { public function index() { dump('员工列表'); } }此时,我们再点员工就会看到如下页面:
我们根据需要,修改员工界面的展示信息,首先我们要知道框架用的是use app\common\builder\ZBuilder;来构建页面信息的.所以我们在构建页面的时候要使用它.
<?php namespace app\employee\admin; use app\admin\controller\Admin; use app\common\builder\ZBuilder; // 引入ZBuilder class Index extends Admin { public function index() { dump('员工列表'); } }由于当前页面要展示员工信息,所示我们要构建一个表格:
<?php namespace app\employee\admin; use app\admin\controller\Admin; use app\common\builder\ZBuilder; // 引入ZBuilder class Index extends Admin { public function index() { // 构建表格展示 return ZBuilder::make('table')->fetch(); } }我们再次访问可以看到当前页面类似如下(由于没有配置表格信息,所以没有展示出表格来): 现在为我们的表格添加表头,我们要展示内容有"数字编号/员工名字/年龄/电话/职位/工资/状态",由于这里只是修改index()方法中的内容,这里只展示index()中的代码:
public function index() { return ZBuilder::make('table') ->addColumns([ ['__INDEX__', '#'], ['name', '姓名'], ['age', '年龄'], ['phone', '电话'], ['position', '职位'], ['salary', '工资'], ['status', '状态'] ]) ->fetch(); }['name', '姓名'],其中name就是要传入数据(数组)的key,我们看一下现在的页面: 查询数据并展示到表格中,注意这里引用了use think\Db命名空间用于查询数据:
public function index() { $join = [ [['emp_position' => 'p'],'e.position_id = p.id', 'LEFT'], [['emp_status_info' => 's'], 's.id = e.status_id', 'LEFT'], ]; $dataList = Db::field('e.name, e.age, e.phone, p.name position, e.salary, s.status status') -> table('emp_employee')->alias('e') -> join($join) ->select(); for ($i = 0 ; $i < count($dataList); $i++) { foreach($dataList[$i] as $k => $v) { if ($k == 'status' && $v== NULL) { $dataList[$i][$k] = '在职'; } } } return ZBuilder::make('table') ->addColumns([ ['__INDEX__', '#'], ['name', '姓名'], ['age', '年龄'], ['phone', '电话'], ['position', '职位'], ['salary', '工资'], ['status', '状态'] ]) -> setRowList($dataList) ->fetch(); }修改后的效果: 我们看到每一列前都有一个多选框,现在我们将它隐藏:
public function index() { $join = [ [['emp_position' => 'p'],'e.position_id = p.id', 'LEFT'], [['emp_status_info' => 's'], 's.id = e.status_id', 'LEFT'], ]; $dataList = Db::field('e.name, e.age, e.phone, p.name position, e.salary, s.status status') -> table('emp_employee')->alias('e') -> join($join) ->select(); for ($i = 0 ; $i < count($dataList); $i++) { foreach($dataList[$i] as $k => $v) { if ($k == 'status' && $v== NULL) { $dataList[$i][$k] = '在职'; } } } return ZBuilder::make('table') ->addColumns([ ['__INDEX__', '#'], ['name', '姓名'], ['age', '年龄'], ['phone', '电话'], ['position', '职位'], ['salary', '工资'], ['status', '状态'] ]) -> setRowList($dataList) // 隐藏多选框 ->hideCheckbox() ->fetch(); }为表头添加排序:
public function index() { // 获取排序方式 $order = $this->getOrder(); $join = [ [['emp_position' => 'p'],'e.position_id = p.id', 'LEFT'], [['emp_status_info' => 's'], 's.id = e.status_id', 'LEFT'], ]; $dataList = Db::field('e.name, e.age, e.phone, p.name position, e.salary, s.status status') -> table('emp_employee')->alias('e') -> join($join) // 查询时,设置排序方式 ->order($order) ->select(); for ($i = 0 ; $i < count($dataList); $i++) { foreach($dataList[$i] as $k => $v) { if ($k == 'status' && $v== NULL) { $dataList[$i][$k] = '在职'; } } } return ZBuilder::make('table') ->addColumns([ ['__INDEX__', '#'], ['name', '姓名'], ['age', '年龄'], ['phone', '电话'], ['position', '职位'], ['salary', '工资'], ['status', '状态'] ]) // 设置要排序的字段 ->addOrder('name,salary') -> setRowList($dataList) // 隐藏多选框 ->hideCheckbox() ->fetch(); }记录:关于添加筛选,表名始终会被加上前缀,未解决!
为新增页面添加一个节点: 在顶部增加一个新增按钮:
public function index() { $order = $this->getOrder(); $join = [ [['emp_position' => 'p'],'e.position_id = p.id', 'LEFT'], [['emp_status_info' => 's'], 's.id = e.status_id', 'LEFT'], ]; $dataList = Db::field('e.name, e.age, e.phone, p.name position, e.salary, s.status status') -> table('emp_employee')->alias('e') -> join($join) ->order($order) ->select(); for ($i = 0 ; $i < count($dataList); $i++) { foreach($dataList[$i] as $k => $v) { if ($k == 'status' && $v== NULL) { $dataList[$i][$k] = '在职'; } } } return ZBuilder::make('table') ->addColumns([ ['__INDEX__', '#'], ['name', '姓名'], ['age', '年龄'], ['phone', '电话'], ['position', '职位'], ['salary', '工资'], ['status', '状态'] ]) ->addOrder('name,salary') -> setRowList($dataList) // 隐藏多选框 ->hideCheckbox() // 添加新增按钮,并以弹窗形式打开(第三个参数存在),且设定title ->addTopButton('add', [],['title'=>'添加员工']) ->fetch(); }添加后的效果: 添加add方法,构建页面信息:
public function add() { return ZBuilder::make('form') ->fetch(); }点击添加后会跳到新增页面,效果: 为新增界面构建表单:
public function add() { $dept = Db::table('emp_dept')->field('id,name')->select(); $list = []; for ($i = 0; $i < count($dept); $i++) { $list[$dept[$i]['id']] = $dept[$i]['name']; } return ZBuilder::make('form') // 添加单行文本框,输入姓名,并设置 placeHolder 请输入员工的姓名 ->addText('name', '姓名[:请输入员工的姓名]', '', '', ['<i class="fa fa-user"></i>']) ->addText('age', '年龄[:请输入员工的年龄]', '', '', ['<i class="fa fa-birthday-cake"></i>']) ->addText('phone', '电话[:请输入员工的电话]', '', '', ['<i class="fa fa-phone"></i>']) ->addLinkage('dept ', '选择部门', '请选择部门', $list, '', url('getPosition'), 'position', 'dept') ->addSelect('position', '选择职位') ->addText('salary', '工资[:请输入员工的工资]', '', '', ['<i class="fa fa-money"></i>']) ->addDatetime('join_in_time', '入职时间','', '', 'YYYY-MM-DD') ->fetch(); } public function getPosition($dept = '') { $res = Db::query('select p.id, p.name from emp_position p left join emp_dept d on p.dept_id = d.id where d.name = ? ', [$dept]); $list = []; for ($i = 0; $i < count($res); $i++) { array_push($list, ['key' => $res[$i]['id'], 'value' => $res[$i]['name']]); } $arr['code'] = '1'; //判断状态 $arr['msg'] = '请求成功'; //回传信息 $arr['list'] = $list; return json($arr); }页面效果: 为新增员工添加url请求链接,并创建save方法:
public function add() { $dept = Db::table('emp_dept')->field('id,name')->select(); $list = []; for ($i = 0; $i < count($dept); $i++) { $list[$dept[$i]['id']] = $dept[$i]['name']; } return ZBuilder::make('form') // 添加单行文本框,输入姓名,并设置 placeHolder 请输入员工的姓名 ->addText('name', '姓名[:请输入员工的姓名]', '', '', ['<i class="fa fa-user"></i>']) ->addText('age', '年龄[:请输入员工的年龄]', '', '', ['<i class="fa fa-birthday-cake"></i>']) ->addText('phone', '电话[:请输入员工的电话]', '', '', ['<i class="fa fa-phone"></i>']) ->addLinkage('dept ', '选择部门', '请选择部门', $list, '', url('getPosition'), 'position', 'dept') ->addSelect('position', '选择职位') ->addText('salary', '工资[:请输入员工的工资]', '', '', ['<i class="fa fa-money"></i>']) ->addDatetime('join_in_time', '入职时间','', '', 'YYYY-MM-DD') // 设置提交地址 ->setUrl(url('save')) ->submitConfirm() ->fetch(); } public function save() { // 获取请求参数 $arr['code'] = '1'; //判断状态 $arr['msg'] = '添加成功'; //回传信息 $arr['list'] = []; return json($arr); }在save()方法中获取请求数据并入库:
public function save() { $post = request()->post(); $data = [ 'name' => $post['name'], 'age' => $post['age'], 'phone' => $post['phone'], 'position_id' => $post['position'], 'salary' => $post['salary'], 'join_in_time' => $post['join_in_time'], // 为not null字段添加默认值 'status_id' => 0, 'addr_id' => 0, 'p_id' => 0 ]; $id = Db::table('emp_employee')->insert($data); $id = Db::table('emp_employee')->getLastInsID(); // 获取请求参数 $arr['code'] = '1'; //判断状态 $arr['msg'] = '添加成功'; //回传信息 $arr['data'] = $id; return json($arr); }现在我们要为员工数据每一栏添加操作按钮,先看看没添加时的样子: 添加操作代码(由于代码较长,只在新加代码处加了注释),请注意注释处代码:
public function index() { $order = $this->getOrder(); $join = [ [['emp_position' => 'p'],'e.position_id = p.id', 'LEFT'], [['emp_status_info' => 's'], 's.id = e.status_id', 'LEFT'], ]; // 添加 e.id 为数据指定id,否则报错 $dataList = Db::field('e.id, e.name, e.age, e.phone, p.name position, e.salary, s.status status') -> table('emp_employee')->alias('e') -> join($join) ->order($order) ->select(); for ($i = 0 ; $i < count($dataList); $i++) { foreach($dataList[$i] as $k => $v) { if ($k == 'status' && $v== NULL) { $dataList[$i][$k] = '在职'; } } } return ZBuilder::make('table') ->addColumns([ ['__INDEX__', '#'], ['name', '姓名'], ['age', '年龄'], ['phone', '电话'], ['position', '职位'], ['salary', '工资'], ['status', '状态'] ]) ->addOrder('name,salary') -> setRowList($dataList) // 添加操作 表头 ->addColumn('right_button', '操作', 'btn') // 添加edit操作按钮 ->addRightButton('edit', ['href' => url('edit', ['id' => '__id__', 'group' => 'normal'])]) // 隐藏多选框 ->hideCheckbox() ->addTopButton('add', [],['title'=>'添加员工']) ->fetch(); }添加操作按钮后,我们的页面长这样子: 注意->addRightButton('edit', ['href' => url('edit', ['id' => '__id__', 'group' => 'normal'])])我们在指定编辑按钮时已经设置了跳转的url:**/模块名/edit/id/1/group/normal.html.所以,我们应该添加一个edit方法和配置一个修改员工的节点! 配置节点: 添加edit方法:
public function edit($id = '') { dump('edit'); }上诉操作完成后,点击编辑按钮就可以跳到如下页面: 此时,我们应该为编辑页面创建布局,编辑页面主要是用来更改员工状态的,比如请假/调休/高职等操作,所以我们在edit中添加如下代码:
public function edit($id = '', $group = 'normal') { // tab 信息 $tabInfo = [ // edit 表示页面跳转的方法, group 是参数 normal是参数值 ,也就是每次点击都会跳到edit方法,并且传递group参数 'normal' => ['title' => '正常工作', 'url' => url('edit', ['group' => 'normal'])], 'qj' => ['title' => '请假', 'url' => url('edit', ['group' => 'qj'])], 'tx' => ['title' => '调休', 'url' => url('edit', ['group' => 'tx'])], 'lz' => ['title' => '离职', 'url' => url('edit', ['group' => 'lz'])], ]; // 状态单选按钮信息 $radioInfo = [ 0 => '事假', 1 => '病假', 2 => '其它' ]; // 是否开启开关 $isOpen = 1; $canOpt = ''; // 如果 if ($isOpen == 1) { $canOpt = 'disabled'; } // 根据不同的group参数 构建不同的form表单 switch ($group) { case 'normal' : return ZBuilder::make('form') // 构建tab ->setTabNav($tabInfo, $group) // 添加单选按钮, 最后一个参数是默认选中值 ->addSwitch('status', '修改员工状态为正常', '', $isOpen, '', $canOpt) ->fetch(); // 请假表单样式 case 'qj' : return ZBuilder::make('form') ->setTabNav($tabInfo, $group) ->addRadio('type', '请假类型', '', $radioInfo, '0') ->addDaterange('begin,end', '请假时间', '', date("Y-m-d",time())) ->fetch(); // 调休表单样式 case 'tx' : return ZBuilder::make('form') ->setTabNav($tabInfo, $group) ->addDaterange('begin,end', '调休时间', '', date("Y-m-d",time())) ->fetch(); // 离职表单样式 case 'lz' : return ZBuilder::make('form') ->setTabNav($tabInfo, $group) ->addDatetime('leave_time', '离职时间', '', date("Y-m-d H:i",time())) ->addTextarea('reason', '离职原因') ->fetch(); } }添加后的样式如下: