使用TFAPI完成一个简单的增、删、改、查功能页面

发表于 2020-04-26 11:41:05
阅读 99

项目介绍

介绍

我们通过 demo-simple 项目包,开发一个用户列表页面,该页面包含增加用户、删除用户、修改用户和用户查询四个基本功能

项目资源

资源列表

用户列表

程序

users.php

模板

WEB-APP/smarty/tpls/users.html

项目开发

数据库

建立 test 数据库

CREATE DATABASE test DEFAULT CHARSET utf8;

数据表

建立 users 数据表

CREATE TABLE users (
userId INT NOT NULL AUTO_INCREMENT,
userName VARCHAR(45) NOT NULL DEFAULT '',
userPwd CHAR(32) NOT NULL DEFAULT '',
crtDT DATETIME NULL,
PRIMARY KEY (userId),
UNIQUE u_userName (userName)
);

项目配置

项目配置

打开配置文件 WEB-APP/web.inc.php

在下面的代码位置将数据库连接字符串改成自己的环境匹配的参数

switch(env_ctl::getenv('mode')){
    case 'develop':
        env_ctl::adddbs("mysql", "driver=mysql2;server=127.0.0.1;uid=root;pwd=abcdef;database=test;charset=" . PHP_CHARSET . ";tbl_prefix=;tbl_lastfix=;");
        break;
    default:
        env_ctl::adddbs("mysql", "driver=mysql2;server=127.0.0.1;uid=root;pwd=abcdef;database=test;charset=" . PHP_CHARSET . ";tbl_prefix=;tbl_lastfix=;");
        break;
}

开发模板

通过官网提供的“开发模板”工具协助我们快速完成开发

工具地址:

https://tongfu.net/tool/tfapi/template.html

用户列表

打开开发模板,选择“定义标准表格页面”,输入变量 users,会生成一套代码

9fb1c3b3cef853c4.jpg

将生成的代码复制到 /users.php 里面

require('.root.php');
require(WEBAPP_ROOT);
linking('html.form_action3');

class users_action extends table_action_ctl {
    public function __construct($name){
        parent::__construct($name);
        $this->add_usr_action("mod","修改");
        $this->add_usr_action("del","删除");
    }
}
class users_table extends table_action3 {
    public $loginUser;
    public $actionObj;
    protected function filter_row(&$row){
        $this->actionObj->set_action_link($row,"mod",$row['pmId']); // pmId - primary key id
    }
    protected function get_sql(&$sql){
        $ws = "";
        $joins = "";
        $sql = "select * from users";
    }
    protected function get_table_show_argv(table_action3_argv &$argv){
        $argv->actions = $this->actionObj->get_actions();
    }
}
class users_page extends form_action3{
    public $loginUser;
    public $actionObj;
    protected function process(){
        $tablePage = new users_table("users", $this->tableConfig, $this->pageObj, $this->smartyObj, $this->dbObj,
            array('ID'));
        $tablePage->loginUser = $this->loginUser;
        $tablePage->actionObj = $this->actionObj;
        $tablePage->make_table();
    }
}
class users extends sample_system{
    private $actionPage;
    public $actionObj;
    public function __construct($args){
        parent::__construct($args);
        $this->smartyFile = "users";
        $this->regPublicKey = "users";
        $this->page->title = "Title of 'users'";
        //
        $this->tableConfig = new table_maker_config("users");
        $this->actionObj = new users_action("users");
        $this->actionPage = new users_page($this->tableConfig, $this->page, $this->smarty, $this->dbo, $this->actionObj->get_keys(), $this->actionObj->defaultAction);
        $this->actionPage->set_no_methods($this->actionObj->get_no_methods());
        $this->actionPage->loginUser = $this->loginUser;
        $this->actionPage->actionObj = $this->actionObj;
    }
    public static function main($args){
        $myPg = new users($args);
        $myPg->actionPage->action_process();
        $myPg->done_smarty();
    }
}
users::main(array(
    'mysql'
));

复制下面的代码到 WEB-APP/smarty/tpls/users.html 里面

<html>
<head>
    <% $__header %>
</head>
<body>

<div style="display: block; margin: 100px auto 0 auto; width: 60%;">
    <% $stdTable_users %>
</div>

</body>
</html>

将 users.php 文件里的 users_table::get_sql 方法里的 sql 语句改成用户列表查询语句

protected function get_sql(&$sql){
    $ws = "";
    $joins = "";
    $sql = "select userId, userName, crtDT from users";
}

将 users.php 文件里的 users_page::process 方法的代码里的数组改成用户列表列名称

protected function process(){
    $tablePage = new users_table("users", $this->tableConfig, $this->pageObj, $this->smartyObj, $this->dbObj,
        array('ID','用户名','注册时间'));
    $tablePage->loginUser = $this->loginUser;
    $tablePage->actionObj = $this->actionObj;
    $tablePage->make_table();
}

打开浏览器访问地址 /users.php 可以看到如下界面效果

c5559945bb39dec3.jpg

用户添加

在 users.php 文件里的 users_action::__construct 方法里增加“添加”事件定义

$this->add_usr_action("add","添加");
$this->add_usr_action("mod","修改");
$this->add_usr_action("del","删除");

在 users.php 文件里的 users_page::process 方法最下面增加“添加”事件URI

// add action URI
$this->smartyObj->cfg("addUri", $this->tableConfig->get_action_uri("add"));

在 WEB-APP/smarty/tpls/users.html 里增加“添加”事件按钮和事件表单逻辑

只要有表单事件就一定会有 $_GET['pc'],所以我们用它来判断是否有表单事件触发

<div style="display: block; margin: 100px auto 0 auto; width: 60%;">
    <% if $__page->get->pc == "" %>
        <a href="<% $addUri %>">添加用户</a>
        <% $stdTable_users %>
    <% else %>
        <% $actFormS_add %>
        <% $actFormJS_add %>
    <% /if %>
</div>

打开开发模板,选择“定义事件表单”,输入变量 add,会生成一套代码

fea872e493fe448a.jpg

将生成的代码复制到 /users.php 文件的 users_page 对象定义里面

protected function validator_add(){
    $frmvObj = new form_validator_action3();
    return $frmvObj;
}
protected function form_add(){
    $frmObj = new form_maker_action3($this->tableConfig, $this->pageObj, "add");
    $frmObj->set_target();
    $frmObj->add_button("btnSubmit",1,"提交");
    return $frmObj;
}
protected function form_show_arg_add(&$arg){
    $arg['class'] = "ctongfuTableForm";
    $arg['formTitle'] = "";
    $arg['labels'] = array();
    $arg['notes'] = array();
}
protected function form_error_add($err){
    $this->pageObj->alertBack(implode("\n", $err));
}
protected function process_add($arr, &$err){

}

在 validator_add 方法里定义表单验证规则

$frmvObj = new form_validator_action3();
$frmvObj->add_rule("user", "r1()", array(), "请填写用户名");
$frmvObj->add_rule("pwd", "r1()", array(), "请填写密码");
return $frmvObj;

在 form_add 方法里定义表单项目

$frmObj = new form_maker_action3($this->tableConfig, $this->pageObj, "add");
$frmObj->set_target();
$frmObj->add_textfield("user");
$frmObj->add_password("pwd");
$frmObj->add_button("btnSubmit",1,"提交");
return $frmObj;

在 form_show_arg_add 方法里定义表单样式

$arg['class'] = "ctongfuTableForm";
$arg['formTitle'] = "添加用户";
$arg['labels'] = array('用户名','密码');
$arg['notes'] = array();

在 form_error_add 方法里定义表单错误处理逻辑

$this->pageObj->parentAlertBack(implode("\n", $err));

在 process_add 方法里编写处理表单逻辑

// duplicate check
if($this->dbObj->sr("select * from #users# where userName = @str", $arr['user']) != null){
    return $err['user'] = "用户名‘". $arr['user']. "’已经存在";
}

// write db
$iSql = $this->dbObj->ib("#users#", array(
    'userName'=>$arr['user'],
    'userPwd'=>md5($arr['pwd']),
    'crtDT'=>date("Y-m-d H:i:s"),
));
$ret = $this->dbObj->se($iSql);
if($ret === false){
    return $err['user'] = "保存失败";
}

$this->pageObj->parentAlertGoto("用户添加成功", $this->tableConfig->get_return_uri($this->pageObj->get));

刷新页面 /users.php 可以看到“添加用户”按钮

c495976719af1e65.jpg

点击“添加用户”按钮进入添加用户表单界面

99b19ce5e0a5011a.jpg

输入“用户名”和“密码”后点击“提交”按钮,可以看到添加成功提示

90f3fe2448dce4a4.jpg

点击“确定”后,自动回到用户列表界面,可以看到刚刚添加的“张三”用户信息

f7a1af6e1f9676c8.jpg

用户列表事件绑定

现在用户列表里有了用户数据,如果我们要对已存在的数据进行修改、删除,需要先进行“列表事件绑定”操作

在 users.php 文件里的 users_table::get_table_show_argv 方法里指定列表数据主键

$argv->tm_checkbox_field = "userId";

在 users.php 文件里的 users_table::fileter_row 方法里添加“列表事件绑定”逻辑

$this->actionObj->set_action_link($row,"mod",$row['userId']);
$this->actionObj->set_action_link($row,"del",$row['userId'], "confirm('确定要删除用户‘". $row['userName']. "’吗?')");

刷新页面 /users.php 可以看到每行用户信息最后都出现了“修改”、“删除”按钮

f05e9f8d3444c21e.jpg

用户修改

用户修改表单的代码编写方法和用户添加表单本地基本一致,这里就不再详述了

下面我们给出完整的用户修改表单后台代码和模板代码供大家参考

用户修改表单后台代码

protected function validator_mod(){
    $frmvObj = new form_validator_action3();
    $frmvObj->add_rule("user", "r1()", array(), "请填写用户名");
    $frmvObj->add_rule("pwd", "r1()", array(), "请填写密码");
    return $frmvObj;
}
protected function form_mod(){
    $frmObj = new form_maker_action3($this->tableConfig, $this->pageObj, "mod");
    $frmObj->set_target();
    $frmObj->add_textfield("user");
    $frmObj->add_password("pwd");
    $frmObj->add_button("btnSubmit",1,"提交");
    return $frmObj;
}
protected function form_show_arg_mod(&$arg){
    $arg['class'] = "ctongfuTableForm";
    $arg['formTitle'] = "修改用户";
    $arg['labels'] = array('用户名','密码');
    $arg['notes'] = array();
}
protected function form_error_mod($err){
    $this->pageObj->parentAlertBack(implode("\n", $err));
}
protected function process_mod($arr, &$err){
    // duplicate check
    if($this->dbObj->sr("select * from #users# where userName = @str
        and userId <> @int", $arr['user'], $this->pageObj->get->curId) != null){
        return $err['user'] = "用户名‘". $arr['user']. "’已经存在";
    }

    // write db
    $uSql = $this->dbObj->ub("#users#", array(
        'userName'=>$arr['user'],
        'userPwd'=>md5($arr['pwd']),
    ), "userId = @int", $this->pageObj->get->curId);
    $ret = $this->dbObj->se($uSql);
    if($ret === false){
        return $err['user'] = "保存失败";
    }

    $this->pageObj->parentAlertGoto("用户修改成功", $this->tableConfig->get_return_uri($this->pageObj->get));
}

用户修改表单模板代码

<% if $__page->get->pc == "" %>
    <a href="<% $addUri %>">添加用户</a>
    <% $stdTable_users %>
<% else %>
    <% $actFormS_add %>
    <% $actFormJS_add %>
    <% $actFormS_mod %>
    <% $actFormJS_mod %>
<% /if %>

注意事项

这里面有两点需要注意的地方
1、修改数据的主键信息如何传递?
2、修改表单需要在表单项目内设置被修改数据的当前值,怎么办?

修改数据主键信息

首先,问题1,因为前面我们做了一步“列表事件绑定”,所以在对行内数据进行处理时候系统会自动带上一个 $_GET['curId'] 参数,这个参数的值就是“列表事件绑定”时候指定的主键对应的数据字段的值

数据绑定事件绑定项目

其次,问题2,我们需要重载一个方法用来将当前被处理的数据进行提取以备显示表单时候使用,接着我们还需要将提取处理的数据绑定到事件表单项目上

当前数据提取代码,需要放到 users_page 对象定义里面

protected function load_info($curId){
    $currentUserInfo = $this->dbObj->sr("select * from #users# where userId = @int", $curId);
    return $currentUserInfo;
}

数据绑定事件表单项目,需要放到 users_page::form_mod 里面(绑定哪个事件的表单就在哪个事件的表单的 form_xxx 里操作)增加 set_values 方法进行表单项目表单

$frmObj = new form_maker_action3($this->tableConfig, $this->pageObj, "mod");
$frmObj->set_target();
$frmObj->add_textfield("user");
$frmObj->add_password("pwd");
$frmObj->add_button("btnSubmit",1,"提交");
$frmObj->set_values(array(
    'user'=>$this->curInfo['userName'],
));
return $frmObj;

用户删除

用户修改表单编写方法和用户添加本地基本一致,区别在于不需要展示一个表单界面给用户,直接处理删除操作

下面我们给出完整的表单后台代码和模板代码供大家参考

用户删除表单后台代码

protected function validator_del(){
    $frmvObj = new form_validator_action3();
    return $frmvObj;
}
protected function form_del(){
    $frmObj = new form_maker_action3($this->tableConfig, $this->pageObj, "del");
    $frmObj->set_target();
    $frmObj->add_button("btnSubmit",1,"提交");
    return $frmObj;
}
protected function form_show_arg_del(&$arg){
    $arg['class'] = "ctongfuTableForm";
    $arg['formTitle'] = "";
    $arg['labels'] = array();
    $arg['notes'] = array();
}
protected function form_error_del($err){
    $this->pageObj->alertBack(implode("\n", $err));
}
protected function process_del($arr, &$err){
    // write db
    $ret = $this->dbObj->se("delete from #users# where userId = @int", $this->pageObj->get->curId);
    if($ret === false){
        return $err['user'] = "保存失败";
    }

    $this->pageObj->parentAlertGoto("用户删除成功", $this->tableConfig->get_return_uri($this->pageObj->get));
}

用户删除表单模板代码

<% if $__page->get->pc == "" %>
    <a href="<% $addUri %>">添加用户</a>
    <% $stdTable_users %>
<% else %>
    <% $actFormS_add %>
    <% $actFormJS_add %>
    <% $actFormS_mod %>
    <% $actFormJS_mod %>
    <% $actFormS_del %>
    <% $actFormJS_del %>
<% /if %>

注意事项

除了做前面的处理,我们还需要在事件定义位置进行一个小调整,告诉系统我们的删除事件是不需要显示表单的

在 users.php 文件的 users_action::__construct 方法里调整用户删除事件定义的参数

$this->add_usr_action("add","添加");
$this->add_usr_action("mod","修改");
$this->add_usr_action("del","删除", null, null, true);

用户查询

最后我们来给用户列表增加“查询”功能

打开开发模板,选择“定义工具表单”,输入变量 search,会生成一套代码

206ca12e144e11bf.jpg

将生成的代码复制到 users.php 文件的 users_action 对象前面

class search_tool extends form_action_item3{
    protected function create_validator(){
        $this->validator = new form_validator_action3();
    }
    protected function create_form(){
        $this->form = new form_maker_action3($this->tableConfig, $this->pageObj, "search_tool", "", 135, 0, "GET");
        $this->form->add_date("dtS");
        $this->form->add_date("dtE");
        $this->form->add_textfield("keywords");
        $this->form->set_formaters(array('dtS'=>"从 %dtS% 到 %dtE%"));
        $this->form->add_button("btnS",1,"查询");
    }
    protected function get_arg(&$arg){
        $arg['class'] = "ctongfuTableForm";
    }
}

打开开发模板,选择“调用工具表单”,输入变量 search,会生成一套代码

be73f9f680329cc5.jpg

将生成的代码复制到 users.php 文件的 users_page::process 方法的最前面

$toolPage = new search_tool("search", $this->smartyObj, $this->dbObj,
    array('日期', '关键字'), "查询");
$toolPage->tableConfig = $this->tableConfig;
$toolPage->make_form();

在 WEB-APP/smarty/tpls/users.html 里增加查询表单

<% if $__page->get->pc == "" %>
    <% $actFormS_search %>
    <% $actFormJS_search %>
    <a href="<% $addUri %>">添加用户</a>
    <% $stdTable_users %>
<% else %>
    <% $actFormS_add %>
    <% $actFormJS_add %>
    <% $actFormS_mod %>
    <% $actFormJS_mod %>
    <% $actFormS_del %>
    <% $actFormJS_del %>
<% /if %>

在 users.php 文件的 users_table::get_sql 方法里增加搜索逻辑

$gvs = $this->pageObj->get;
$ws = "";
$joins = "";
$ws .= $this->tableConfig->get_distence_condition_str("crtDT", $gvs->dtS, $gvs->dtE, true, true);
if($gvs->keywords != ""){
    $ws .= " and userName like '%". $gvs->keywords. "%' ";
}
if($ws != ""){
    $ws = " where ". substr($ws, 5);
}
$sql = "select userId, userName, crtDT from users". $ws;

刷新页面 /users.php 可以看到搜索表单

f05d4d52bce0b83f.jpg

输入查询条件,可以查询到符合条件的结果了

8c40da6379ebaba1.jpg

总结

配合开发模板工具,就可以使用 tongfuapi 框架快速的完成功能开发了!!!