一、引入项目及后台模板
下载phpstudy集成环境 , 修改PHP运行环境PHP >= 7.1.0,安装 Composer,建立网站www.xxx.com,解析域名在 C:\Windows\System32\drivers\etc 目录下,打开 hosts文件,输入 127.0.0.1 www.xxx.com。
下载Thinkphp6命令,更新Thinkphp6核心
composer create-project topthink/think tp
composer update topthink/framework
安装多应用模式扩展:建立前台,后台模块,修改模块命名空间 index(admin)
composer require topthink/think-multi-app
安装think-view 模板引擎驱动: 引入门面类 use think\facade\View 渲染页面 return View::fetch()
备注:类名对应view下面的目录名 ,方法名对应view下面的目录里的静态文件名
composer require topthink/think-view
修改文件名后缀,引入后台模板, 模板输出字符串替换 ,替换样式,行为,图片资源位置
'tpl_replace_string' => [ '{__ADMIN__}' => '/static/admin' ]
建立common文件夹,拆分头部和左侧公共文件,引入文件
{include file="common/top(left)"}
二、完善左侧菜单
商品管理 =>商品列表 添加商品 商品品牌 商品分类 商品类型 商品回收站
推荐位管理 =>推荐位列表 添加推荐位
栏目关联 =>推荐词关联 品牌关联 左图关联
促销管理 =>团购活动 积分商城 优惠券
订单管理 =>订单列表 订单查询
会员管理 =>会员列表 会员级别 会员留言
数据库管理 =>数据备份 数据表优化
短信管理 =>发送短信 短信签名
文章模块 =>文章分类 文章管理
导航管理 =>导航列表 添加导航
图片管理 =>图片列表 轮播图列表
系统设置 =>配置项 配置管理 支付方式设置
友情链接 =>链接列表
<!-- Sidebar Menu -->
<ul class="nav sidebar-menu">
<!--Dashboard-->
<li>
<a href="#" class="menu-dropdown">
<i class="menu-icon fa fa-shopping-cart"></i>
<span class="menu-text">商品管理</span>
<i class="menu-expand"></i>
</a>
<ul class="submenu">
<li>
<a href="{:url('Goods/lst')}">
<span class="menu-text">商品列表</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="{:url('Goods/add')}">
<span class="menu-text">添加商品</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="{:url('Brand/lst')}">
<span class="menu-text">商品品牌</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="{:url('Category/lst')}">
<span class="menu-text">商品分类</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="{:url('Type/add')}">
<span class="menu-text">商品类型</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="#">
<span class="menu-text">商品回收站</span>
<i class="menu-expand"></i>
</a>
</li>
</ul>
</li>
<li>
<a href="#" class="menu-dropdown">
<i class="menu-icon fa fa-thumbs-up"></i>
<span class="menu-text">推荐位管理</span>
<i class="menu-expand"></i>
</a>
<ul class="submenu">
<li>
<a href="{:url('Recpos/lst')}">
<span class="menu-text">推荐位列表</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="{:url('Recpos/add')}">
<span class="menu-text">添加推荐位</span>
<i class="menu-expand"></i>
</a>
</li>
</ul>
</li>
<li>
<a href="#" class="menu-dropdown">
<i class="menu-icon fa fa-random"></i>
<span class="menu-text">栏目关联</span>
<i class="menu-expand"></i>
</a>
<ul class="submenu">
<li>
<a href="{:url('CategoryWords/lst')}">
<span class="menu-text">推荐词关联</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="{:url('CategoryBrands/lst')}">
<span class="menu-text">品牌关联</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="{:url('CategoryAd/lst')}">
<span class="menu-text">左图关联</span>
<i class="menu-expand"></i>
</a>
</li>
</ul>
</li>
<li>
<a href="#" class="menu-dropdown">
<i class="menu-icon fa fa-money"></i>
<span class="menu-text">促销管理</span>
<i class="menu-expand"></i>
</a>
<ul class="submenu">
<li>
<a href="#">
<span class="menu-text">团购活动</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="#">
<span class="menu-text">积分商城</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="{:url('Coupons/add')}">
<span class="menu-text">优惠券</span>
<i class="menu-expand"></i>
</a>
</li>
</ul>
</li>
<li>
<a href="#" class="menu-dropdown">
<i class="menu-icon fa fa-legal"></i>
<span class="menu-text">订单管理</span>
<i class="menu-expand"></i>
</a>
<ul class="submenu">
<li>
<a href="{:url('Order/lst')}">
<span class="menu-text">订单列表</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="{:url('Order/orderSelect')}">
<span class="menu-text">订单查询</span>
<i class="menu-expand"></i>
</a>
</li>
</ul>
</li>
<li>
<a href="#" class="menu-dropdown">
<i class="menu-icon fa fa-users"></i>
<span class="menu-text">会员管理</span>
<i class="menu-expand"></i>
</a>
<ul class="submenu">
<li>
<a href="{:url('User/lst')}">
<span class="menu-text">会员列表</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="{:url('MemberLevel/add')}">
<span class="menu-text">会员级别</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="#">
<span class="menu-text">会员留言</span>
<i class="menu-expand"></i>
</a>
</li>
</ul>
</li>
<li>
<a href="#" class="menu-dropdown">
<i class="menu-icon fa fa-sitemap"></i>
<span class="menu-text">数据库管理</span>
<i class="menu-expand"></i>
</a>
<ul class="submenu">
<li>
<a href="#">
<span class="menu-text">数据备份</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="#">
<span class="menu-text">数据表优化</span>
<i class="menu-expand"></i>
</a>
</li>
</ul>
</li>
<li>
<a href="#" class="menu-dropdown">
<i class="menu-icon fa fa-envelope"></i>
<span class="menu-text">短信管理</span>
<i class="menu-expand"></i>
</a>
<ul class="submenu">
<li>
<a href="#">
<span class="menu-text">发送短信</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="#">
<span class="menu-text">短信签名</span>
<i class="menu-expand"></i>
</a>
</li>
</ul>
</li>
<li>
<a href="#" class="menu-dropdown">
<i class="menu-icon fa fa-file-text"></i>
<span class="menu-text">文章模块</span>
<i class="menu-expand"></i>
</a>
<ul class="submenu">
<li>
<a href="{:url('Cate/lst')}">
<span class="menu-text">文章分类</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="{:url('Article/lst')}">
<span class="menu-text">文章管理</span>
<i class="menu-expand"></i>
</a>
</li>
</ul>
</li>
<li>
<a href="#" class="menu-dropdown">
<i class="menu-icon fa fa-location-arrow"></i>
<span class="menu-text">导航管理</span>
<i class="menu-expand"></i>
</a>
<ul class="submenu">
<li>
<a href="{:url('Nav/lst')}">
<span class="menu-text">导航列表</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="{:url('Nav/add')}">
<span class="menu-text">添加导航</span>
<i class="menu-expand"></i>
</a>
</li>
</ul>
</li>
<li>
<a href="#" class="menu-dropdown">
<i class="menu-icon fa fa-picture-o"></i>
<span class="menu-text">图片管理</span>
<i class="menu-expand"></i>
</a>
<ul class="submenu">
<li>
<a href="{:url('Article/imglist')}">
<span class="menu-text">图片列表</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="{:url('AlternateImg/lst')}">
<span class="menu-text">轮播图列表</span>
<i class="menu-expand"></i>
</a>
</li>
</ul>
</li>
<li>
<a href="#" class="menu-dropdown">
<i class="menu-icon fa fa-gear"></i>
<span class="menu-text">系统设置</span>
<i class="menu-expand"></i>
</a>
<ul class="submenu">
<li>
<a href="{:url('Conf/conflist')}">
<span class="menu-text">配置项</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="{:url('Conf/lst')}">
<span class="menu-text">配置管理</span>
<i class="menu-expand"></i>
</a>
</li>
<li>
<a href="#">
<span class="menu-text">支付方式设置</span>
<i class="menu-expand"></i>
</a>
</li>
</ul>
</li>
<li>
<a href="#" class="menu-dropdown">
<i class="menu-icon fa fa-link"></i>
<span class="menu-text">友情链接</span>
<i class="menu-expand"></i>
</a>
<ul class="submenu">
<li>
<a href="{:url('Link/lst')}">
<span class="menu-text">链接列表</span>
<i class="menu-expand"></i>
</a>
</li>
</ul>
</li>
</ul>
<!-- /Sidebar Menu -->
三、创建品牌表及处理品牌添加界面
品牌表
CREATE TABLE `tp_brand` (
`id` mediumint(8) PRIMARY KEY AUTO_INCREMENT COMMENT '品牌id',
`brand_name` varchar(60) NOT NULL COMMENT '品牌名称',
`brand_url` varchar(60) NOT NULL COMMENT '品牌地址',
`brand_img` varchar(100) NOT NULL COMMENT '品牌logo',
`brand_description` varchar(255) NOT NULL COMMENT '品牌描述',
`sort` smallint(6) NOT NULL DEFAULT '50' COMMENT '品牌排序',
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1:显示 0:隐藏'
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
品牌添加页面
<div class="page-body">
<div class="row">
<div class="col-lg-12 col-sm-12 col-xs-12">
<div class="widget">
<div class="widget-header bordered-bottom bordered-blue">
<span class="widget-caption">新增品牌</span>
</div>
<div class="widget-body">
<div id="horizontal-form">
<form class="form-horizontal" role="form" action="" method="post"
enctype="multipart/form-data">
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">品牌名称</label>
<div class="col-sm-6">
<input class="form-control" placeholder="" name="brand_name"
required="" type="text">
</div>
<p class="help-block col-sm-4 red">* 必填</p>
</div>
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">品牌网址</label>
<div class="col-sm-6">
<input class="form-control" placeholder="" name="brand_url"
type="text">
</div>
</div>
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">品牌logo</label>
<div class="col-sm-6">
<input placeholder="" name="brand_img" type="file">
</div>
</div>
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">品牌描述</label>
<div class="col-sm-6">
<textarea class="form-control" name="brand_description"></textarea>
</div>
</div>
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">品牌状态</label>
<div class="col-sm-6">
<div class="radio" style="float:left; padding-right:10px;">
<label>
<input name="status" value="1" class="colored-blue"
checked="checked" type="radio">
<span class="text">显示</span>
</label>
</div>
<div class="radio" style="float:left;">
<label>
<input name="status" value="0" class="colored-blue"
type="radio">
<span class="text">隐藏</span>
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">保存信息</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
四、品牌数据的添加
品牌添加
public function add()
{
if(request()->isPost()){
$data=input('post.');
// $data['brand_url']; http://
if($data['brand_url'] && stripos($data['brand_url'],'http://') === false){
$data['brand_url']='http://'.$data['brand_url'];
}
if($_FILES['brand_img']['tmp_name']){
$file = request()->file('brand_img');
// 上传到本地服务器
$data['brand_img'] = \think\facade\Filesystem::putFile( 'topic', $file);
}
//上传图片函数封装,$data['brand_img']=$this->upload() 调用失败
//验证
$validate = validate('Brand');
if(!$validate->check($data)){
$this->error($validate->getError());
}
$add = Db::table('tp_brand')->insert($data);
if($add){
$this->success('添加品牌成功!','lst');
}else{
$this->error('添加品牌失败!');
}
}
return view();
}
// 磁盘列表
'disks' => [
'local' => [
'type' => 'local',
'root' => app()->getRuntimePath() . '../public/static/admin/uploads',
]
]
TP6 SUCCESS、ERROR、REDIRECT、RESULT 问题解决:BaseController.php 尾部引入use \liliuwei\think\jump
composer require liliuwei/thinkphp-jump
五、品牌的列表和删除
品牌列表页面
<div class="page-body">
<button type="button" tooltip="添加品牌" class="btn btn-sm btn-azure btn-addon"
onClick="javascript:window.location.href = 'add.html'"> <i class="fa fa-plus"></i>
Add
</button>
<div class="row">
<div class="col-lg-12 col-sm-12 col-xs-12">
<div class="widget">
<div class="widget-body">
<div class="flip-scroll">
<table class="table table-bordered table-hover">
<thead class="">
<tr>
<th class="text-center" width="8%">ID</th>
<th class="text-center">品牌名称</th>
<th>品牌地址</th>
<th class="text-center">品牌logo</th>
<th>品牌描述</th>
<th class="text-center" width="8%">品牌状态</th>
<th class="text-center" width="14%">操作</th>
</tr>
</thead>
<tbody>
{volist name="brandRes" id="brand"}
<tr>
<td align="center">{$brand.id}</td>
<td align="center">{$brand.brand_name}</td>
<td><a href="{$brand.brand_url}"
target="_blank">{$brand.brand_url}</a></td>
<td align="center">
{if condition="$brand['brand_img'] neq ''"}
<img src="{__UPLOAD_IMG__}/{$brand.brand_img}" height="30">
{else /}
暂无图片
{/if}
</td>
<td>{$brand.brand_description|cut_str=###,6}</td>
<td align="center">
{if condition="$brand['status'] eq 1"}
<img src="{__ADMIN__}/images/right.png" height="30">
{else /}
<img src="{__ADMIN__}/images/wrong.png" height="25">
{/if}
</td>
<td align="center">
<a href="{:url('edit',array('id'=>$brand['id']))}"
class="btn btn-primary btn-sm shiny">
<i class="fa fa-edit"></i> 编辑
</a>
<a href="{:url('del',array('id'=>$brand['id']))}"
onClick="warning('确实要删除吗')"
class="btn btn-danger btn-sm shiny">
<i class="fa fa-trash-o"></i> 删除
</a>
</td>
</tr>
{/volist}
</tbody>
</table>
</div>
<div style="padding-top:10px; text-align:right;">
//分页展示{$brandRes|raw}
</div>
<div>
</div>
</div>
</div>
</div>
</div>
</div>
字符串截取
function cut_str($sourcestr,$cutlength)
{
$returnstr='';
$i=0;
$n=0;
$str_length=strlen($sourcestr);//字符串的字节数
while (($n<$cutlength) and ($i<=$str_length))
{
$temp_str=substr($sourcestr,$i,1);
$ascnum=Ord($temp_str);//得到字符串中第$i位字符的ascii码
if ($ascnum>=224) //如果ASCII位高与224,
{
$returnstr=$returnstr.substr($sourcestr,$i,3); //根据UTF-8编码规范,将3个连续的字符计为单个字符
$i=$i+3; //实际Byte计为3
$n++; //字串长度计1
}
elseif ($ascnum>=192) //如果ASCII位高与192,
{
$returnstr=$returnstr.substr($sourcestr,$i,2); //根据UTF-8编码规范,将2个连续的字符计为单个字符
$i=$i+2; //实际Byte计为2
$n++; //字串长度计1
}
elseif ($ascnum>=65 && $ascnum<=90) //如果是大写字母,
{
$returnstr=$returnstr.substr($sourcestr,$i,1);
$i=$i+1; //实际的Byte数仍计1个
$n++; //但考虑整体美观,大写字母计成一个高位字符
}
else //其他情况下,包括小写字母和半角标点符号,
{
$returnstr=$returnstr.substr($sourcestr,$i,1);
$i=$i+1; //实际的Byte数计1个
$n=$n+0.5; //小写字母和半角标点等与半个高位字符宽...
}
}
if ($str_length>$i){
$returnstr = $returnstr . "...";//超过长度时在尾处加上省略号
}
return $returnstr;
}
模板输出字符串替换
'tpl_replace_string' => [
'{__UPLOAD_IMG__}' => '/static/admin/uploads',
]
品牌列表
public function lst()
{
$brandRes=Db::table("tp_brand")->order('id DESC')->paginate(2);
View::assign([
'brandRes'=>$brandRes,
]);
return view('list');
}
品牌删除
public function del($id)
{
$Brands=Db::table('tp_brand')->field('brand_img')->find($id);
$BrandImg=IMG_UPLOADS.$Brands['brand_img'];
if(file_exists($BrandImg)){
@unlink($BrandImg);
}
$del=Db::table('tp_brand')->delete($id);
if( $del){
$this->success('删除品牌成功!','lst');
}else{
$this->error('删除品牌失败!');
}
return view();
}
六、品牌的修改及其他
品牌修改页面
<div class="page-body">
<div class="row">
<div class="col-lg-12 col-sm-12 col-xs-12">
<div class="widget">
<div class="widget-header bordered-bottom bordered-blue">
<span class="widget-caption">修改品牌</span>
</div>
<div class="widget-body">
<div id="horizontal-form">
<form class="form-horizontal" role="form" action="" method="post"
enctype="multipart/form-data">
<input type="hidden" name="id" value="{$brands.id}">
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">品牌名称</label>
<div class="col-sm-6">
<input class="form-control" placeholder="" name="brand_name"
required="" value="{$brands.brand_name}" type="text">
</div>
<p class="help-block col-sm-4 red">* 必填</p>
</div>
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">品牌网址</label>
<div class="col-sm-6">
<input class="form-control" placeholder="" name="brand_url"
value="{$brands.brand_url}" type="text">
</div>
</div>
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">品牌logo</label>
<div class="col-sm-6">
<input placeholder="" name="brand_img" type="file">
{if condition="$brands['brand_img'] neq ''"}
<img src="{__UPLOAD_IMG__}/{$brands.brand_img}" height="1000">
{else/}
暂无图片
{/if}
</div>
</div>
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">品牌描述</label>
<div class="col-sm-6">
<textarea class="form-control"
name="brand_description">{$brands.brand_description}</textarea>
</div>
</div>
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">品牌状态</label>
<div class="col-sm-6">
<div class="radio" style="float:left; padding-right:10px;">
<label>
<input name="status" value="1" class="colored-blue" {if
condition="$brands['status'] eq 1" } checked="checked"
{/if} type="radio">
<span class="text">显示</span>
</label>
</div>
<div class="radio" style="float:left;">
<label>
<input name="status" value="0" {if
condition="$brands['status'] eq 0" } checked="checked"
{/if} class="colored-blue" type="radio">
<span class="text">隐藏</span>
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">保存信息</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
品牌修改
public function edit()
{
if(request()->isPost()){
$data=input('post.');
// $data['brand_url']; http://
if($data['brand_url'] && stripos($data['brand_url'],'http://') === false){
$data['brand_url']='http://'.$data['brand_url'];
}
//处理图片上传
if($_FILES['brand_img']['tmp_name']){
$oldBrands=Db::table('tp_brand')->field('brand_img')->find($data['id']);
$oldBrandImg=IMG_UPLOADS.$oldBrands['brand_img'];
// dump($oldBrandImg);die;
if(file_exists($oldBrandImg)){
@unlink($oldBrandImg);
}
$file = request()->file('brand_img');
// 上传到本地服务器
$data['brand_img'] = \think\facade\Filesystem::putFile( 'topic', $file);
}
//验证
$validate = validate('Brand');
if(!$validate->check($data)){
$this->error($validate->getError());
}
$save=Db::table('tp_brand')->update($data);
if($save !== false){
$this->success('修改品牌成功!','lst');
}else{
$this->error('修改品牌失败!');
}
return;
}
$id=input('id');
$brands=DB::table('tp_brand')->find($id);
View::assign([
'brands'=>$brands,
]);
return view();
}
七、品牌数据验证
<?php
namespace app\admin\validate;
use think\Validate;
class Brand extends Validate
{
protected $rule = [
'brand_name' => 'require|unique:brand',
'brand_url' => 'url',
'brand_description' => 'min:6',
];
protected $message = [
'brand_name.require' => '品牌名称必须',
'brand_name.unique' => '品牌名称不能重复',
'brand_url.url' => 'url格式不正确',
'brand_description.min' => '描述最少6个字符',
];
}
八、处理文章分类添加界面
分类表
CREATE TABLE `tp_cate` (
`id` smallint(6) PRIMARY KEY AUTO_INCREMENT COMMENT '栏目id',
`cate_name` varchar(20) NOT NULL COMMENT '栏目名称',
`cate_type` tinyint(1) NOT NULL DEFAULT '5' COMMENT '栏目类型 cate_type 1:系统分类 2:帮助分类 3:网店帮助 4:网店信息 5:普通分类',
`keywords` varchar(100) NOT NULL COMMENT '关键词',
`description` varchar(150) NOT NULL COMMENT '描述',
`show_nav` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否显示到导航栏 1:显示到导航栏 0:不显示到导航栏',
`allow_son` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1:是 0:否 是否允许添加子分类',
`sort` smallint(6) NOT NULL DEFAULT '50' COMMENT '排序',
`pid` smallint(6) NOT NULL DEFAULT '0' COMMENT '上级栏目id'
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
分类添加页面
<div class="page-body">
<div class="row">
<div class="col-lg-12 col-sm-12 col-xs-12">
<div class="widget">
<div class="widget-header bordered-bottom bordered-blue">
<span class="widget-caption">新增文章</span>
</div>
<div class="widget-body">
<div id="horizontal-form">
<form class="form-horizontal" role="form" action="" method="post">
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">上级文章</label>
<div class="col-sm-6">
<select name="pid">
<option value="0">顶级分类</option>
{volist name="cateRes" id="cate"}
<option {if condition="$cate['allow_son'] eq 0" }
disabled="disabled" {/if} value="{$cate.id}">
<?php echo str_repeat('-', $cate['level']*8)?>{$cate.cate_name}
</option>
{/volist}
</select>
</div>
<p class="help-block col-sm-4 red">* 必填</p>
</div>
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">文章名称</label>
<div class="col-sm-6">
<input class="form-control" placeholder="" name="cate_name"
required="" type="text">
</div>
<p class="help-block col-sm-4 red">* 必填</p>
</div>
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">显示到导航</label>
<div class="col-sm-6">
<div class="radio" style="float:left; padding-right:10px;">
<label>
<input name="show_nav" value="1" class="colored-blue"
type="radio">
<span class="text">是</span>
</label>
</div>
<div class="radio" style="float:left;">
<label>
<input name="show_nav" value="0" checked="checked"
class="colored-blue" type="radio">
<span class="text">否</span>
</label>
</div>
</div>
</div>
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">关键词</label>
<div class="col-sm-6">
<textarea class="form-control" name="keywords"></textarea>
</div>
</div>
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">描述</label>
<div class="col-sm-6">
<textarea class="form-control" name="description"></textarea>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">保存信息</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
九、文章分类添加和列表
文章添加
public function add()
{
if(request()->isPost()){
$data=input('post.');
$add = Db::table('tp_cate')->insert($data);
if($add){
$this->success('添加文章成功!','lst');
}else{
$this->error('添加文章失败!');
}
}
$cateRes = Db::table('tp_cate')->select();
View::assign([
'cateRes'=>$cateRes,
]);
return view();
}
文章分类列表页面
<div class="page-body">
<button type="button" tooltip="添加文章" class="btn btn-sm btn-azure btn-addon"
onClick="javascript:window.location.href = 'add.html'"> <i class="fa fa-plus"></i> Add
</button>
<div class="row">
<div class="col-lg-12 col-sm-12 col-xs-12">
<div class="widget">
<div class="widget-body">
<div class="flip-scroll">
<form action="" method="post">
<table class="table table-bordered table-hover">
<thead class="">
<tr>
<th class="text-center" width="8%">ID</th>
<th class="text-center">文章名称</th>
<th class="text-center" width="10%">类型</th>
<th width="8%">显示到导航栏</th>
<th class="text-center" width="8%">排序</th>
<th class="text-center" width="14%">操作</th>
</tr>
</thead>
<tbody>
{volist name="cateRes" id="cate"}
<tr>
<td align="center">{$cate.id}</td>
<td>{$cate.cate_name}</td>
<td align="center">
{if condition="$cate['cate_type'] eq 1"}
系统分类
{elseif condition="$cate['cate_type'] eq 2" /}
帮助分类
{elseif condition="$cate['cate_type'] eq 3" /}
网店帮助
{elseif condition="$cate['cate_type'] eq 4" /}
网店信息
{else /}
普通分类
{/if}
</td>
<td align="center">
{if condition="$cate['show_nav'] eq 1"}
<img src="{__ADMIN__}/images/right.png" height="30">
{else /}
<img src="{__ADMIN__}/images/wrong.png" height="25">
{/if}
</td>
<td align="center">
<input type="text" style="width:60px; text-align:center;"
name="sort[{$cate.id}]" value="{$cate.sort}" />
</td>
<td align="center">
<a href="{:url('Cate/edit',array('id'=>$cate['id']))}"
class="btn btn-primary btn-sm shiny">
<i class="fa fa-edit"></i> 编辑
</a>
{notin name="$cate['id']" value="1,2,3"}
<a href="{:url('Cate/del',array('id'=>$cate['id']))}"
onClick="warning('确实要删除吗')"
class="btn btn-danger btn-sm shiny">
<i class="fa fa-trash-o"></i> 删除
</a>
{else /}
<a href="#" disabled="disabled"
class="btn btn-danger btn-sm shiny">
<i class="fa fa-trash-o"></i> 删除
</a>
{/notin}
</td>
</tr>
{/volist}
<tr>
<td colspan="6" align="right" style="padding-right:16.5%;">
<input class="btn btn-primary btn-sm shiny" type="submit"
value="提交" /></td>
</tr>
</tbody>
</table>
</form>
</div>
<div style="padding-top:10px; text-align:right;">
<!-- 分页 -->
</div>
<div>
</div>
</div>
</div>
</div>
</div>
</div>
文章分类列表
public function lst()
{
$cateRes=Db::table("tp_cate")->order('id DESC')->paginate( );
View::assign([
'cateRes'=>$cateRes,
]);
return view('list');
}
十、用扩展类的方法解决无限级分类
<?php
namespace catetree;
class Catetree {
public function catetree($cateRes){
return $this->sort($cateRes);
}
public function sort($cateRes,$pid=0,$level=0){
static $arr=array();
foreach ($cateRes as $k => $v) {
if($v['pid']==$pid){
$v['level']=$level;
$arr[]=$v;
$this->sort($cateRes,$v['id'],$level+1);
}
}
return $arr;
}
//获取子栏目id
public function childrenids($cateid,$obj){
$data=$obj->field('id,pid')->select();
return $this->_childrenids($data,$cateid,TRUE);
}
private function _childrenids($data,$cateid,$clear=FALSE){
static $arr=array();
if($clear){
$arr=array();
}
foreach ($data as $k => $v) {
if($v['pid']==$cateid){
$arr[]=$v['id'];
$this->_childrenids($data,$v['id']);
}
}
return $arr;
}
//处理栏目排序
public function cateSort($data,$obj){
foreach ($data as $k => $v) {
(clone $obj)->where(['id'=>$k])->update(['sort'=>$v]);
}
}
//处理批量删除
public function pdel($cateids){
foreach ($cateids as $k => $v) {
$childrenidsarr[]=$this->childrenids($v);
$childrenidsarr[]=(int)$v;
}
$_childrenidsarr=array();
foreach ($childrenidsarr as $k => $v) {
if(is_array($v)){
foreach ($v as $k1 => $v1) {
$_childrenidsarr[]=$v1;
}
}else{
$_childrenidsarr[]=$v;
}
}
$_childrenidsarr=array_unique($_childrenidsarr);
$this::destroy($_childrenidsarr);
}
}
无限级列表
public function lst()
{
$cate=new Catetree();
$cateDb=Db::table("tp_cate")->select();
$cate=new Catetree();
$cateRes=$cate->catetree($cateDb);
View::assign([
'cateRes'=>$cateRes,
]);
return view('list');
}
列表页面展示
<td><?php echo str_repeat('-', $cate['level']*8)?>{$cate.cate_name}</td>
十一、处理分类的类型问题
栏目类型 cate_type 1:系统分类 2:帮助分类 3:网店帮助 4:网店信息 5:普通分类
public function add()
{
$cate=new Catetree();
if(request()->isPost()){
$data=input('post.');
//判断是否可以添加子分类
if(in_array($data['pid'], ['3'])){
$this->error('系统分类不能作为上级分类!');
}
//
if($data['pid']==2){
$data['cate_type']=3;
}
//
$cateId=Db::table("tp_cate")->field('pid')->find($data['pid']);
$cateId=$cateId['pid'];
if($cateId==2){
$this->error('此分类不能作为上级分类!');
}
//验证
$validate = validate('Cate');
if(!$validate->check($data)){
$this->error($validate->getError());
}
$add = Db::table('tp_cate')->insert($data);
if($add){
$this->success('添加文章成功!','lst');
}else{
$this->error('添加文章失败!');
}
return;
}
$cateRes = Db::table('tp_cate')->select();
$cateRes=$cate->catetree($cateRes);
View::assign([
'cateRes'=>$cateRes,
]);
return view();
}
十二、文章分类的删除详解
public function del($id)
{
$cate=Db::table('tp_cate');
$cateTree=new Catetree();
$sonids=$cateTree->childrenids($id,$cate);
$sonids[]=intval($id);
$arrSys=[1,2,3];
$arrRes=array_intersect($arrSys,$sonids);
if($arrRes){
$this->error('系统内置文章分类不允许删除!');
}
$del=Db::table('tp_cate')->delete($sonids);
if( $del){
$this->success('删除品牌成功!','lst');
}else{
$this->error('删除品牌失败!');
}
return view();
}
十三、栏目的排序处理
public function lst()
{
$cate=new Catetree();
$cateObj=DB::table('tp_cate');
if(request()->isPost()){
$data=input('post.');
$cate->cateSort($data['sort'],$cateObj);
$this->success('排序成功!',url('lst'));
}
$cateRes=$cateObj->order('sort DESC')->select();
$cateRes=$cate->catetree($cateRes);
View::assign([
'cateRes'=>$cateRes,
]);
return view('list');
}
十四、栏目的修改
修改页面
<div class="page-body">
<div class="row">
<div class="col-lg-12 col-sm-12 col-xs-12">
<div class="widget">
<div class="widget-header bordered-bottom bordered-blue">
<span class="widget-caption">修改文章</span>
</div>
<div class="widget-body">
<div id="horizontal-form">
<form class="form-horizontal" role="form" action="" method="post">
<input type="hidden" name="id" value="{$cates.id}">
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">上级文章</label>
<div class="col-sm-6">
<select name="pid">
<option value="0">顶级文章</option>
{volist name="cateRes" id="cate"}
<option {if
condition="($cates['cate_type'] == 1) OR ($cates['cate_type'] == 2) OR ($cates['cate_type'] == 3) OR ($cates['cate_type'] == 4)"
} disabled="disabled" {/if} {if
condition="$cate['cate_type'] neq 5" } disabled="disabled"
{/if} {if condition="$cates['id'] eq $cate['id']" }
disabled="disabled" {/if} {if
condition="$cate['id'] eq $cates['pid']" }
selected="selected" {/if} value="{$cate.id}">
<?php echo str_repeat('-', $cate['level']*8)?>{$cate.cate_name}
</option>
{/volist}
</select>
</div>
<p class="help-block col-sm-4 red">* 必填</p>
</div>
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">文章名称</label>
<div class="col-sm-6">
<input class="form-control" placeholder=""
value="{$cates.cate_name}" name="cate_name" required=""
type="text">
</div>
<p class="help-block col-sm-4 red">* 必填</p>
</div>
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">显示到导航</label>
<div class="col-sm-6">
<div class="radio" style="float:left; padding-right:10px;">
<label>
<input name="show_nav" {if
condition="$cates['show_nav'] eq 1" } checked="checked"
{/if} value="1" class="colored-blue" type="radio">
<span class="text">是</span>
</label>
</div>
<div class="radio" style="float:left;">
<label>
<input name="show_nav" value="0" {if
condition="$cates['show_nav'] eq 0" } checked="checked"
{/if} class="colored-blue" type="radio">
<span class="text">否</span>
</label>
</div>
</div>
</div>
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">关键词</label>
<div class="col-sm-6">
<textarea class="form-control"
name="keywords">{$cates.keywords}</textarea>
</div>
</div>
<div class="form-group">
<label for="username"
class="col-sm-2 control-label no-padding-right">描述</label>
<div class="col-sm-6">
<textarea class="form-control"
name="description">{$cates.description}</textarea>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">保存信息</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
栏目编辑
public function edit()
{
$cate=new Catetree();
$cateObj=db('cate');
if(request()->isPost()){
$data=input('post.');
//验证
$validate = validate('Cate');
if(!$validate->check($data)){
$this->error($validate->getError());
}
$save=$cateObj->update($data);
if($save !== false){
$this->success('修改分类成功!','lst');
}else{
$this->error('修改分类失败!');
}
return;
}
$cates=$cateObj->find(input('id'));
$cateRes=$cateObj->order('sort DESC')->select();
$cateRes=$cate->catetree($cateRes);
$this->assign([
'cateRes'=>$cateRes,
'cates'=>$cates
]);
return view();
}
十五、分类数据验证
<?php
namespace app\admin\validate;
use think\Validate;
class Cate extends Validate
{
protected $rule = [
'cate_name' => 'require|unique:cate|min:6',
];
protected $message = [
'cate_name.require' => '分类名称必须',
'cate_name.unique' => '分类名称不能重复',
'cate_name.min' => '分类名称过短',
];
}