介绍
介绍
上一课福哥带着大家使用TFPHP框架给TFUMS项目增加了全套的标签模块的增、删、改、查功能,标签的删除功能福哥使用的是状态删除方式而不是物理删除方式,为的就是那些误删除的标签可以通过恢复功能找回来,今天福哥要带着大家来实现这个恢复功能。
标签模块的恢复功能和删除功能相对的,删除功能是把标签状态改为T_STATE_LOCKED,恢复功能是把标签状态改回T_STATE_NORMAL。
为了实现标签模块的恢复功能,福哥建立了一个标签模块的回收站,里面可以查到已经删除掉的标签信息。
结构
模型
WEB-APP/Model/tag.inc.php
控制器
WEB-APP/Controller/admin/tag/recycle.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/recycle.html
js/pages/admin/tag/recycle.js
删除(Delete)
错误码
1012031 - 错误请求 1012032 - 标签不存在 1012033 - 保存失败 1012034 - 恢复失败
模型
WEB-APP/Model/tag.inc.php
public function restore(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_NORMAL, '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 doRestore(){ $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, 1012031, "错误请求"); } // delete $ret = $tag->restore($this->login->getLoginStatus()->mId, $tagId); switch ($ret){ case 1: $this->tfphp->getResponse()->responseJSON_CM(200, 1012032, "标签不存在"); break; case 2: $this->tfphp->getResponse()->responseJSON_CM(200, 1012033, "保存失败"); break; } } catch(\Exception $e){ TFLog::getDefault($this->tfphp)->error($e->getMessage()); $this->tfphp->getResponse()->responseJSON_CM(200, 1012034, "恢复失败"); } // output $this->tfphp->getResponse()->responseJSON_CM(200, 0, "OK", array( 'tagid'=>$tagId, )); }
视图
HTML
<!-- restore form --> <div class="dlg-box dlg-restore-form"> <form class="form restore-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
_startRestoreForm: function(id) { var ex=this; var formOpts; formOpts = { url: this.baseUri + "api/admin/tag/" + id + "/_restore", method: "post", dataUrl: this.baseUri + "api/resource/tag/" + id + "/_detail", dataMethod: "post", onSuccess: function (d) { if(d.errcode == 0){ ex._dlg_restore_form.close(); ex._list.refresh(null, true); } else{ $('form.restore-form').tips({ text:d.errmsg }); } }, onError: function (d) { $('form.restore-form').tips({ text:"服务器响应错误" }); }, onDataSuccess: function (d) { $('form.restore-form').find('[name="title"]').text(d.cName); }, onValidationError: function (form, name, msg) { $('form.restore-form').tips({ text:msg }); $('form.restore-form').find('[name="'+ name +'"]').focus(); } }; this._mod_form = $('form.restore-form').form(formOpts); },
查询(Retreive)
模型
WEB-APP/Model/tag.inc.php
public function loadDeletedTags(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_LOCKED); $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 doListDeleted(){ $req = $this->tfphp->getRequest(); $tag = new tag($this->tfphp); $keyword = $req->post->get("keyword"); $datas = $tag->loadDeletedTags(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> </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_deleted?pn={pn}", dataMethod: "post", dataRenderType: "classic", pn: _pn, attachRowEvent: function (obj, id) { var item = obj.find('tr[dataid="' + id + '"]'), dataid = id; item.find('.btn-restore').click(function () { // restore ex._openRestoreForm(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-restore">恢复</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); },
效果
列表
表单
总结
今天福哥带着童鞋们给TFUMS项目的标签模块增加了恢复功能,通过恢复功能可以实现已删除标签的找回功能!大家可以看到标签的删除功能和恢复功能都是执行的update操作,这就是模块功能的状态删除的实现技巧!