福哥今天要把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
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);
},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);
},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);
},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)功能的方法,福哥以同福网的标签管理功能为例,给出了全套的代码,包括前后端,大家可以参考!