介绍
介绍
福哥今天要把TFPHP框架开发的标准CRUD功能的方法整理一遍,我们以TFUMS系统为基础,给TFUMS项目增加一个标签功能,就是可以给用户打标签的功能。
福哥会把标签模块的增、删、改查功能的开发方法逐个讲解给大家听~~
结构
模型
WEB-APP/Model/tag.inc.php
控制器
WEB-APP/Controller/admin/tag.inc.php
WEB-APP/Controller/api/admin/tag.inc.php
WEB-APP/Controller/api/admin/tag/.mapping.inc.php
WEB-APP/Controller/api/resource/tag.inc.php
WEB-APP/Controller/api/resource/tag/.mapping.inc.php
视图
WEB-APP/View/Template/admin/tag.html
js/pages/admin/tag.js
添加(Create)
错误码
1012001 - 错误请求 1012002 - 标签名称已经存在 1012003 - 保存失败 1012004 - 添加失败
模型
WEB-APP/Model/tag.inc.php
public function add(int $userID, string $title):int { // check duplicate $tagInfo = $this->getByTable("tagByName", array(tag::T_TYPE, $title)); if($tagInfo != null){ return 1; } // add $ret = $this->insert("tag", array( 'cTypeId'=>tag::T_TYPE, 'cName'=>$title, 'cUserId'=>$userID, 'createDT'=>date("Y-m-d H:i:s"), 'updateDT'=>date("Y-m-d H:i:s"), 'cStat'=>tag::T_STATE_NORMAL, )); if(!$ret){ return 2; } return 0; }
控制器
WEB-APP/Controller/api/admin/tag.inc.php
private function doAdd(){ $req = $this->tfphp->getRequest(); $post = $req->post; $tag = new tag($this->tfphp); $title = $post->get("title"); try{ // request test if($title == ""){ $this->tfphp->getResponse()->responseJSON_CM(200, 1012001, "错误请求"); } // add tag $ret = $tag->add($this->login->getLoginStatus()->mId, $title); switch ($ret){ case 1: $this->tfphp->getResponse()->responseJSON_CM(200, 1012002, "标签名称已经存在"); break; case 2: $this->tfphp->getResponse()->responseJSON_CM(200, 1012003, "保存失败"); break; } $tagId = $tag->getLastAddId(); } catch(\Exception $e){ TFLog::getDefault($this->tfphp)->error($e->getMessage()); $this->tfphp->getResponse()->responseJSON_CM(200, 1012004, "添加失败"); } // output $this->tfphp->getResponse()->responseJSON_CM(200, 0, "OK", array( 'tagid'=>$tagId, )); }
视图
HTML
<!-- add form --> <div class="dlg-box dlg-add-form"> <form class="form add-form"> <div class="dlg-header"> <div class="dlg-tool-box"> <i class="btn-close">X</i> </div> <div class="dlg-title"> 新建标签 </div> </div> <div class="dlg-content"> <div class="form-group"> <label>标签名称</label> <input class="form-control" type="text" name="title" /> </div> </div> <div class="dlg-footer"> <button class="btn btn-primary btn-sm">提交</button> </div> </form> </div>
JS
_startAddForm: function() { var ex=this; var formOpts; formOpts = { url: this.baseUri + "api/admin/tag/_add", method: "post", validations: [ {type:"empty", name:"title", msg:"请填写标签名称"} ], onSuccess: function (d) { if(d.errcode == 0){ ex._dlg_add_form.close(); ex._list.refresh(null, true); } else{ $('form.add-form').tips({ text:d.errmsg }); } }, onError: function (d) { $('form.add-form').tips({ text:"服务器响应错误" }); }, onValidationError: function (form, name, msg) { $('form.add-form').tips({ text:msg }); $('form.add-form').find('[name="'+ name +'"]').focus(); } }; this._add_form = $('form.add-form').form(formOpts); },
修改(Update)
错误码
1012011 - 错误请求 1012012 - 标签不存在 1012013 - 标签名称已经存在 1012014 - 保存失败 1012015 - 编辑失败
模型
WEB-APP/Model/tag.inc.php
public function mod(int $userID, int $tagID, string $title):int { // check exist $tagInfo = $this->getByTable("tag", array(tag::T_TYPE, $tagID)); if($tagInfo == null){ return 1; } // check duplicate $tagInfo = $this->getByTable("tagByName", array(tag::T_TYPE, $title)); if($tagInfo != null && $tagInfo['cId'] != $tagID){ return 2; } // mod $ret = $this->update("tag", array( 'cTypeId'=>tag::T_TYPE, 'cId'=>$tagID, 'cName'=>$title, 'updateDT'=>date("Y-m-d H:i:s"), )); if(!$ret){ return 3; } return 0; }
控制器
WEB-APP/Controller/api/admin/tag/.mapping.inc.php
private function doMod(){ $req = $this->tfphp->getRequest(); $post = $req->post; $pathVars = $req->server->get("PATH_VARIABLE"); $tag = new tag($this->tfphp); $tagId = $pathVars['tag']; $title = $post->get("title"); try{ if(!($tagId > 0)) { $this->tfphp->getResponse()->responseJSON_CM(200, 1012011, "错误请求"); } // request test if($title == ""){ $this->tfphp->getResponse()->responseJSON_CM(200, 1012011, "错误请求"); } // modify $ret = $tag->mod($this->login->getLoginStatus()->mId, $tagId, $title); switch ($ret){ case 1: $this->tfphp->getResponse()->responseJSON_CM(200, 1012012, "标签不存在"); break; case 2: $this->tfphp->getResponse()->responseJSON_CM(200, 1012013, "标签名称已经存在"); break; case 3: $this->tfphp->getResponse()->responseJSON_CM(200, 1012014, "保存失败"); break; } } catch(\Exception $e){ TFLog::getDefault($this->tfphp)->error($e->getMessage()); $this->tfphp->getResponse()->responseJSON_CM(200, 1012015, "编辑失败"); } // output $this->tfphp->getResponse()->responseJSON_CM(200, 0, "OK", array( 'tagid'=>$tagId, )); }
视图
HTML
<!-- modify form --> <div class="dlg-box dlg-mod-form"> <form class="form mod-form"> <div class="dlg-header"> <div class="dlg-tool-box"> <i class="btn-close">X</i> </div> <div class="dlg-title"> 修改标签 </div> </div> <div class="dlg-content"> <div class="form-group"> <label>标签名称</label> <input class="form-control" type="text" name="title" /> </div> </div> <div class="dlg-footer"> <button class="btn btn-primary btn-sm">保存</button> </div> </form> </div>
JS
_startModForm: function(id) { var ex=this; var formOpts; formOpts = { url: this.baseUri + "api/admin/tag/" + id + "/_mod", method: "post", validations: [ {type:"empty", name:"title", msg:"请填写标签名称"} ], dataUrl: this.baseUri + "api/resource/tag/" + id + "/_detail", dataMethod: "post", dataMapRules: [ {name:"title", dataKey:"cName"} ], onSuccess: function (d) { if(d.errcode == 0){ ex._dlg_mod_form.close(); ex._list.refresh(null, true); } else{ $('form.mod-form').tips({ text:d.errmsg }); } }, onError: function (d) { $('form.mod-form').tips({ text:"服务器响应错误" }); }, onValidationError: function (form, name, msg) { $('form.mod-form').tips({ text:msg }); $('form.mod-form').find('[name="'+ name +'"]').focus(); } }; this._mod_form = $('form.mod-form').form(formOpts); },
删除(Delete)
错误码
1012021 - 错误请求 1012022 - 标签不存在 1012023 - 保存失败 1012024 - 删除失败
模型
WEB-APP/Model/tag.inc.php
public function del(int $userID, int $tagID):int { // check exist $tagInfo = $this->getByTable("tag", array(tag::T_TYPE, $tagID)); if($tagInfo == null){ return 1; } // mod $ret = $this->update("tag", array( 'cTypeId'=>tag::T_TYPE, 'cId'=>$tagID, 'cStat'=>tag::T_STATE_LOCKED, 'updateDT'=>date("Y-m-d H:i:s"), )); if(!$ret){ return 2; } return 0; }
控制器
WEB-APP/Controller/api/admin/tag/.mapping.inc.php
private function doDel(){ $pathVars = $this->tfphp->getRequest()->server->get("PATH_VARIABLE"); $tag = new tag($this->tfphp); $tagId = $pathVars['tag']; try{ if(!($tagId > 0)) { $this->tfphp->getResponse()->responseJSON_CM(200, 1012021, "错误请求"); } // delete $ret = $tag->del($this->login->getLoginStatus()->mId, $tagId); switch ($ret){ case 1: $this->tfphp->getResponse()->responseJSON_CM(200, 1012022, "标签不存在"); break; case 2: $this->tfphp->getResponse()->responseJSON_CM(200, 1012023, "保存失败"); break; } } catch(\Exception $e){ TFLog::getDefault($this->tfphp)->error($e->getMessage()); $this->tfphp->getResponse()->responseJSON_CM(200, 1012024, "删除失败"); } // output $this->tfphp->getResponse()->responseJSON_CM(200, 0, "OK", array( 'tagid'=>$tagId, )); }
视图
HTML
<!-- delete form --> <div class="dlg-box dlg-del-form"> <form class="form del-form"> <div class="dlg-header"> <div class="dlg-tool-box"> <i class="btn-close">X</i> </div> <div class="dlg-title"> 删除标签 </div> </div> <div class="dlg-content"> <div class="form-group"> <label>标签名称</label> <span class="form-text" name="title"></span> </div> </div> <div class="dlg-footer"> <button class="btn btn-primary btn-sm">删除</button> </div> </form> </div>
JS
_startDelForm: function(id) { var ex=this; var formOpts; formOpts = { url: this.baseUri + "api/admin/tag/" + id + "/_del", method: "post", dataUrl: this.baseUri + "api/resource/tag/" + id + "/_detail", dataMethod: "post", onSuccess: function (d) { if(d.errcode == 0){ ex._dlg_del_form.close(); ex._list.refresh(null, true); } else{ $('form.del-form').tips({ text:d.errmsg }); } }, onError: function (d) { $('form.del-form').tips({ text:"服务器响应错误" }); }, onDataSuccess: function (d) { $('form.del-form').find('[name="title"]').text(d.cName); }, onValidationError: function (form, name, msg) { $('form.del-form').tips({ text:msg }); $('form.del-form').find('[name="'+ name +'"]').focus(); } }; this._mod_form = $('form.del-form').form(formOpts); },
查询(Retreive)
模型
WEB-APP/Model/tag.inc.php
public function loadTags(int $parentID, string $keyword, int $pageSize, int $pageNum, array $states=null):array { $tfdo = $this->tfphp->getDatabase()->getTFDO(); $sql = "SELECT a.cId, a.cName FROM tfart_categories a WHERE a.cPId = @int AND a.cStat = @int"; if($keyword != ""){ $sql .= " AND a.cName LIKE '%". str_replace("'", "\'", $keyword). "%'"; } $sql .= " ORDER BY a.cId DESC"; $params = array($parentID, tag::T_STATE_NORMAL); $total = $tfdo->fetchTotal($sql, $params); $page = new TFDataPage($this->tfphp, $total, $pageSize, $pageNum); $page->makeTeamlinkRange(6); $pageArr = $page->toArray(); $datas = $tfdo->fetchPart($sql, $pageArr['seekBegin'], $pageArr['fetchNums'], $params); if(is_array($datas)){ foreach($datas as $k => $data){ } } return array( 'page'=>$pageArr, 'data'=>$datas, ); }
控制器
WEB-APP/Controller/api/admin/tag.inc.php
private function doList(){ $req = $this->tfphp->getRequest(); $tag = new tag($this->tfphp); $keyword = $req->post->get("keyword"); $datas = $tag->loadTags(intval($req->get->get("pid")), strval($keyword), 10, intval($req->get->get("pn"))); // output $this->tfphp->getResponse()->responseJSON(200, $datas); }
视图
HTML
<div class="row"> <div class="col-12"> <div class="tag-search"> <form class="search-form form-horizontal"> <div class="row"> <div class="col-12"> <div class="float-left"> </div> <div class="float-right"> <div class="form-inline"> <span><label>关键词</label></span> <span><input class="form-control" type="text" name="keyword" /></span> <span><button class="btn btn-primary btn-sm form-control">搜索</button></span> <span><button class="btn btn-fun btn-sm form-control add-btn">新建标签</button></span> </div> </div> </div> </div> </form> </div> </div> <div class="col-12"> <div class="tag-list"> <table class="table"> <thead> <tr> <th>ID</th> <th>标签</th> <th> </th> </tr> </thead> <tbody> </tbody> </table> <ul class="pagination"> <li><a>第一页</a></li> <li><a>前一页</a></li> <li class="active"><a>1</a></li> <li><a>2</a></li> <li><a>3</a></li> <li><a>4</a></li> <li><a>5</a></li> <li><a>6</a></li> <li><a>后一页</a></li> <li><a>最后页</a></li> </ul> </div> </div> </div>
JS
_startTable: function (_pn) { var ex = this; var tableOpts; tableOpts = { dataUrl: this.baseUri + "api/admin/tag/_list?pn={pn}", dataMethod: "post", dataRenderType: "classic", pn: _pn, attachRowEvent: function (obj, id) { var item = obj.find('tr[dataid="' + id + '"]'), dataid = id; item.find('.btn-mod').click(function () { // modify ex._openModForm(dataid); }); item.find('.btn-del').click(function () { // delete ex._openDelForm(dataid); }); }, onRenderTable: function (data, table) { var obj = table.find(".table").find("tbody"); obj.find("tr").remove(); }, onRenderRow: function (row, table) { var obj = table.find(".table").find("tbody"), extraBtns, extraClass; extraBtns = ''; extraClass = ''; obj.append('<tr dataid="' + row.cId + '">' + ' <td>' + row.cId + '</td>' + ' <td><a href="">' + row.cName + '</a></td>' + ' <td class="btns">' + ' <span class="btn btn-white btn-sm btn-mod">编辑</span>' + ' <span class="btn btn-white btn-sm btn-del">删除</span>' + ' </td>' + '</tr>'); this.attachRowEvent(obj, row.cId); }, onRenderPage: function (page, table) { var obj = table.find(".pagination"), html = ""; obj.html(""); if (page.pageNum > 1) { obj.append('<li><a page-num="1">第一页</a></li>'); obj.append('<li><a page-num="' + (page.pageNum - 1) + '">前一页</a></li>'); } if (page.pageTeamlinkRange) { for (var p = page.pageTeamlinkRange.low; p <= page.pageTeamlinkRange.high; p++) { obj.append('<li><a page-num="' + p + '">' + p + '</a></li>'); } obj.find('[page-num="' + page.pageNum + '"]').parent().addClass("active"); } if (page.pageNum < page.pageTotal) { obj.append('<li><a page-num="' + (page.pageNum + 1) + '">后一页</a></li>'); obj.append('<li><a page-num="' + page.pageTotal + '">最后页</a></li>'); } }, onError: function (d) { } }; this._list = $('.tag-list').table(tableOpts); }, _startSearchForm: function() { var ex=this; var formOpts; formOpts = { method: "post", onSuccess: function (d) { if(d.page && d.data){ } else{ $('form.search').tips({ text:d.errmsg }); } }, onError: function (d) { $('form.search').tips({ text:"服务器响应错误" }); }, onValidationError: function (form, name, msg) { $('form.search').tips({ text:msg }); $('form.search').find('[name="'+ name +'"]').focus(); } }; formOpts.table = this._list; this._search_form = $('form.search-form').form(formOpts); },
效果
列表
表单
总结
今天福哥教给了童鞋们使用TFPHP框架开发一套完整的增、删、改、查(CRUD)功能的方法,福哥以同福网的标签管理功能为例,给出了全套的代码,包括前后端,大家可以参考!