介绍
介绍
上一课福哥带着大家使用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操作,这就是模块功能的状态删除的实现技巧!