省市区三级城市管理功能、广告中图片上传功能。
一、城市管理功能
这里同之前的功能是一样的,主要说一下流程,然后把该功能独有的特点说一下。
建立省级列表,有添加编辑删除功能,在省级列表中添加按钮,点击跳转到该省下的市级列表,也有添加编辑删除功能,然后以此类推,有该市下面的区的列表。这样就形成了三级城市管理。
有几点需要注意:
1、分别建立3级城市列表的前端展示页,然后共用add save delete功能。实现思路是:在后端add方法中通过get分别得到id fid level,当然如果是省级列表那么fid是没有的只有通过前端列表的add方法get到id和level,市级是通过add方法get到上面3个值;有了这三个值(主要用在新增,因为新增form表单中没有上面这三个值,)需要通过隐藏域post到后端save方法执行数据库操作。
2、在区级城市列表前端页面中,上面的省级列表、市级列表a链接导航,需要注意,市级列表导航需要id参数,这个参数传递给后端two_index方法,从发放中看到需要市级的fid,所以,在three_index方法中需要查询出当前市级城市记录,然后在前端引用该记录的fid值
<?php
/**
* Created by PhpStorm.
* User: apple
* Date: 2020/2/21
* Time: 10:26 PM
*/
namespace app\admins\controller;
use think\Controller;
//省市区管理
class City extends BaseAdmin
{
//省列表
public function one_index() {
//查询出省列表发送给前端
$list = $this->db->table('shop_city')->where(array('level'=>1))->lists();
$this->assign('list', $list);
return $this->fetch();
}
//省添加、编辑
public function one_add() {
//接收传过来的id level fid 编辑省的时候fid没有那么就传过来0
// 市的时候 把省的id通过点击市列表是,get传过来然后赋给给fid给到前端
// 前端点击add市把 level fid id都传给 one_add
$id = (int)input('get.id');
$level = (int)input('get.level');
$fid = (int)input('get.fid');
//查询出该id的省的信息
$data = $this->db->table('shop_city')->where(array('id'=>$id))->item();
//把data level给前端
$this->assign('data', $data);
$this->assign('level', $level);
$this->assign('fid', $fid);
return $this->fetch();
}
//省保存
public function one_save() {
//将传过来的数据整理在一起
$id = (int)input('post.id');
$data['name'] = trim(input('post.name'));
$data['initials'] = trim(input('post.initials'));
$data['sort'] = (int)input('post.sort');
$data['status'] = (int)input('post.status');
//判断 如果id存在那么就是修改执行更新操作
if ($id) {
$res = $this->db->table('shop_city')->where(array('id'=>$id))->update($data);
} else {
//如果id不存在 那么就是新增需要把level fid 和data插入
$data['level'] = (int)input('post.level');
$data['fid'] = (int)input('post.fid');
$res = $this->db->table('shop_city')->insert($data);
}
if ($res) {
exit(json_encode(array('code'=>0, 'msg'=>'保存成功')));
} else {
exit(json_encode(array('code'=>1, 'msg'=>'保存失败')));
}
}
//省删除
public function one_del() {
$id = (int)input('post.id');
//16 执行删除操作
$res = $this->db->table('shop_city')->where(array('id'=>$id))->delete();
if (!$res) {
exit(json_encode(array('code'=>1, 'msg'=>'删除失败')));
}
exit(json_encode(array('code'=>0, 'msg'=>'删除成功')));
}
//市列表
public function two_index() {
$fid = (int)input('get.id');
//查找fid下的所有市级城市记录
$list = $this->db->table('shop_city')->where(array('fid'=>$fid))->lists();
$this->assign('list', $list);
$this->assign('fid', $fid);
return $this->fetch();
}
//区列表
public function three_index() {
$fid = (int)input('get.id');
//找到fid的时机城市记录
$two_city = $this->db->table('shop_city')->where(array('id'=>$fid))->item();
//查找fid下的所有市级城市记录
$list = $this->db->table('shop_city')->where(array('fid'=>$fid))->lists();
$this->assign('list', $list);
$this->assign('two_city', $two_city);
$this->assign('fid', $fid);
return $this->fetch();
}
}
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="/static/plugins/layui/css/layui.css">
<script type="text/javascript" src="/static/plugins/layui/layui.js"></script>
<style type="text/css">
.header span{background: #009688;margin-left: 30px;padding: 10px;color:#ffffff;}
.header div{border-bottom: solid 2px #009688;margin-top: 8px;}
.header button{float: right;margin-top: -5px;}
</style>
</head>
<body style="padding: 10px;">
<div class="header">
<span>省列表</span>
<button class="layui-btn layui-btn-sm" onclick="add()">添加</button>
<div></div>
</div>
<table class="layui-table">
<thead>
<tr>
<th>ID</th>
<th>名称</th>
<th>首字母</th>
<th>状态</th>
<th>市列表</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- 循环出所有省记录 -->
{volist name="list" id="vo"}
<tr>
<td>{$vo.id}</td>
<td>{$vo.name}</td>
<td>{$vo.initials}</td>
<td>{if condition="$vo.status == 1"}<span style="color: green;">开启</span>{else/}<span style="color: red;">关闭</span>{/if}</td>
<td>
<button class="layui-btn layui-btn-xs" onclick="url({$vo.id})">此省——城市列表</button>
</td>
<td>
<button class="layui-btn layui-btn-xs" onclick="add({$vo.id})">编辑</button>
<button class="layui-btn layui-btn-danger layui-btn-xs" onclick="del({$vo.id})">删除</button>
</td>
</tr>
{/volist}
</tbody>
</table>
<script type="text/javascript">
layui.use(['layer'],function(){
layer = layui.layer;
$ = layui.jquery;
});
// 添加编辑
function add(id) {
layer.open({
type: 2,
title: id>0 ? '编辑省' : '添加省',
shade: 0.3,
area: ['480px', '420px'],
content: '/index.php/admins/City/one_add?id='+id+'&level=1'
});
}
//分类下的广告列表
function url(id) {
window.location.href = "/index.php/admins/City/two_index?id="+id;
}
// 删除
function del(id) {
layer.confirm('确定要删除吗?', {
icon: 3,
btn: ['确定', '取消']
}, function () {
$.post('/index.php/admins/City/one_del', {'id':id}, function (res) {
if (res.code > 0) {
layer.alert(res.msg, {icon:2});
} else {
layer.msg(res.msg);
setTimeout(function () {
window.location.reload();
}, 1000)
}
}, 'json');
});
}
</script>
</body>
</html>
``````html
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="/static/plugins/layui/css/layui.css">
<script type="text/javascript" src="/static/plugins/layui/layui.js"></script>
</head>
<body style="padding: 10px;">
<form class="layui-form">
<!-- hidden 是把input框隐藏,它的作用是把一些隐藏信息传值到接口中 -->
<input type="hidden" name="id" value="{$data.id}">
<input type="hidden" name="level" value="{$level}">
<input type="hidden" name="fid" value="{$fid}">
<div class="layui-form-item">
<label class="layui-form-label">名称</label>
<div class="layui-input-inline">
<!-- value 是默认值 -->
<!-- 当添加时,传值是0,默认值是空 -->
<!-- readonly 是input里的一个参数,可以禁用input框,只有在修改用户时,才使用 -->
<input type="text" class="layui-input" name="name" value="{$data.name}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">首字母</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" name="initials" value="{$data.initials}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">排序</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" name="sort" value="{$data.sort}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-input-inline">
<input type="checkbox" name="status" lay-skin="primary" title="开启" value="1" {$data.status==1 || !$data ?'checked':''}>
</div>
</div>
</form>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" onclick="save()">保存</button>
</div>
</div>
<script type="text/javascript">
layui.use(['layer','form'],function(){
form = layui.form;
layer = layui.layer;
$ = layui.jquery;
});
// 保存管理员
function save(){
// 用js 获取省名称 首字母
var name = $.trim($('input[name="name"]').val());
var initials = $.trim($('input[name="initials"]').val());
if(name==''){
layer.alert('请输入省名称',{icon:2});
return;
}
if(initials==''){
layer.alert('请输入首字母',{icon:2});
return;
}
// 请求保存接口,把数据传值到接口中。
$.post('/index.php/admins/City/one_save',$('form').serialize(),function(res){
if(res.code>0){
layer.alert(res.msg,{icon:2});
}else{
layer.msg(res.msg);
setTimeout(function(){parent.window.location.reload();},1000);
}
},'json');
}
</script>
</body>
</html>
``````html
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="/static/plugins/layui/css/layui.css">
<script type="text/javascript" src="/static/plugins/layui/layui.js"></script>
<style type="text/css">
.header span{background: #009688;margin-left: 30px;padding: 10px;color:#ffffff;}
.header div{border-bottom: solid 2px #009688;margin-top: 8px;}
.header button{float: right;margin-top: -5px;}
</style>
</head>
<body style="padding: 10px;">
<div class="header">
<span style="background-color:#999;"><a href="/index.php/admins/City/one_index" style="color:#fff;">省列表</a></span>
<span>市列表</span>
<button class="layui-btn layui-btn-sm" onclick="add()">添加</button>
<div></div>
</div>
<table class="layui-table">
<thead>
<tr>
<th>ID</th>
<th>名称</th>
<th>首字母</th>
<th>状态</th>
<th>区列表</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- 循环出所有省记录 -->
{volist name="list" id="vo"}
<tr>
<td>{$vo.id}</td>
<td>{$vo.name}</td>
<td>{$vo.initials}</td>
<td>{if condition="$vo.status == 1"}<span style="color: green;">开启</span>{else/}<span style="color: red;">关闭</span>{/if}</td>
<td>
<button class="layui-btn layui-btn-xs" onclick="url({$vo.id})">此市——区列表</button>
</td>
<td>
<button class="layui-btn layui-btn-xs" onclick="add({$vo.id})">编辑</button>
<button class="layui-btn layui-btn-danger layui-btn-xs" onclick="del({$vo.id})">删除</button>
</td>
</tr>
{/volist}
</tbody>
</table>
<script type="text/javascript">
layui.use(['layer'],function(){
layer = layui.layer;
$ = layui.jquery;
});
var fid = {$fid};
// 添加编辑
function add(id) {
layer.open({
type: 2,
title: id>0 ? '编辑市' : '添加市',
shade: 0.3,
area: ['480px', '420px'],
content: '/index.php/admins/City/one_add?id='+id+'&level=2&fid='+fid
});
}
//分类下的广告列表
function url(id) {
window.location.href = "/index.php/admins/City/three_index?id="+id;
}
// 删除
function del(id) {
layer.confirm('确定要删除吗?', {
icon: 3,
btn: ['确定', '取消']
}, function () {
$.post('/index.php/admins/City/one_del', {'id':id}, function (res) {
if (res.code > 0) {
layer.alert(res.msg, {icon:2});
} else {
layer.msg(res.msg);
setTimeout(function () {
window.location.reload();
}, 1000)
}
}, 'json');
});
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="/static/plugins/layui/css/layui.css">
<script type="text/javascript" src="/static/plugins/layui/layui.js"></script>
<style type="text/css">
.header span{background: #009688;margin-left: 30px;padding: 10px;color:#ffffff;}
.header div{border-bottom: solid 2px #009688;margin-top: 8px;}
.header button{float: right;margin-top: -5px;}
</style>
</head>
<body style="padding: 10px;">
<div class="header">
<span style="background-color:#999;"><a href="/index.php/admins/City/one_index" style="color:#fff;">省列表</a></span>
<span style="background-color:#999;"><a href="/index.php/admins/City/two_index?id={$two_city['fid']}" style="color:#fff;">市列表</a></span>
<span>区列表</span>
<button class="layui-btn layui-btn-sm" onclick="add()">添加</button>
<div></div>
</div>
<table class="layui-table">
<thead>
<tr>
<th>ID</th>
<th>名称</th>
<th>首字母</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- 循环出所有省记录 -->
{volist name="list" id="vo"}
<tr>
<td>{$vo.id}</td>
<td>{$vo.name}</td>
<td>{$vo.initials}</td>
<td>{if condition="$vo.status == 1"}<span style="color: green;">开启</span>{else/}<span style="color: red;">关闭</span>{/if}</td>
<td>
<button class="layui-btn layui-btn-xs" onclick="add({$vo.id})">编辑</button>
<button class="layui-btn layui-btn-danger layui-btn-xs" onclick="del({$vo.id})">删除</button>
</td>
</tr>
{/volist}
</tbody>
</table>
<script type="text/javascript">
layui.use(['layer'],function(){
layer = layui.layer;
$ = layui.jquery;
});
var fid = {$fid};
// 添加编辑
function add(id) {
layer.open({
type: 2,
title: id>0 ? '编辑市' : '添加市',
shade: 0.3,
area: ['480px', '420px'],
content: '/index.php/admins/City/one_add?id='+id+'&level=3&fid='+fid
});
}
// 删除
function del(id) {
layer.confirm('确定要删除吗?', {
icon: 3,
btn: ['确定', '取消']
}, function () {
$.post('/index.php/admins/City/one_del', {'id':id}, function (res) {
if (res.code > 0) {
layer.alert(res.msg, {icon:2});
} else {
layer.msg(res.msg);
setTimeout(function () {
window.location.reload();
}, 1000)
}
}, 'json');
});
}
</script>
</body>
</html>
二、图片上传功能
需要在广告列表list前端上添加图片的标签,然后调用到数据库的数据
<thead>
<tr>
<th>ID</th>
<th>广告标题</th>
<th>图片</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!-- 循环出所有广告 -->
{volist name="list" id="vo"}
<tr>
<td>{$vo.id}</td>
<td><a href="{$vo.cat_url}" target="_blank">{$vo.cat_title}</a></td>
<td><img src="{$vo.cat_img}" alt="" style="width: 30px;height: 30px;"></td>
<td>{if condition="$vo.status == 1"}<span style="color: green;">开启</span>{else/}<span style="color: red;">关闭</span>{/if}</td>
<td>
<button class="layui-btn layui-btn-xs" onclick="add({$vo.id})">编辑</button>
<button class="layui-btn layui-btn-danger layui-btn-xs" onclick="del({$vo.id})">删除</button>
</td>
</tr>
{/volist}
在新增广告团出框页面,需要利用layui的上传组件和js代码,(需要隐藏域name=’cat_img’方便post传表单数据是把图片链接赋给cat_img传给后端)
//隐藏域
<input type="hidden" name="cat_img" value="">
//上传组建
<div class="layui-form-item">
<label class="layui-form-label">图片上传</label>
<div class="layui-upload">
<button type="button" class="layui-btn" id="test1">上传图片</button>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">图片预览</label>
<div class="layui-upload-list">
<img class="layui-upload-img" id="demo1" name="cat_img" style="width: 200px;">
<p id="demoText"></p>
</div>
</div>
组册upload组件,然后引用实例upload.render,可以实现预处理before,上传后处理done,失败后处理error。url是将照片数据较给该路径下的方法处理
layui.use(['layer','form', 'upload'],function(){
form = layui.form;
layer = layui.layer;
$ = layui.jquery;
upload = layui.upload;
var uploadInst = upload.render({
elem: '#test1'
,url: '/index.php/admins/Home/up_img'
,before: function(obj){
//预读本地文件示例,不支持ie8
obj.preview(function(index, file, result){
$('#demo1').attr('src', result); //图片链接(base64)
});
}
,done: function(res){
//如果上传失败
if(res.code > 0){
return layer.msg('上传失败');
}else{
$('#demo1').attr('src', res.data); //图片链接(base64)
$('input[name="cat_img"]').val(res.data); //图片链接(base64)
}
//上传成功
}
,error: function(){
//演示失败状态,并实现重传
var demoText = $('#demoText');
demoText.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs demo-reload">重试</a>');
demoText.find('.demo-reload').on('click', function(){
uploadInst.upload();
});
}
});
在Home下新建up_img方法处理图片数据,将图片保存为图片流数据,然后判断是否上传,然后将临时图片保存在指定位置,得到上传文件后缀名,对图片格式加以约束,然后将图片的路径整合好,将路径 code msg以json形式传给前端js方法处理
//图片上传
public function up_img() {
//获取上传的图片信息流
$file = request()->file('file');
//判断没有上传
if (!$file) {
exit(json_encode(array('code'=>1, 'msg'=>'上传失败')));
}
//把上传的临时文件移动到指定文件夹,tp会自动创建当前日期的文件夹
$up = $file->move('../public/uploads');
$img = $up->getExtension();
if( $img!='jpg' AND $img!='png' ){
exit(json_encode(array('code'=>1,'msg'=>'图片格式不对,请重新上传!')));
}
$img_url = '/uploads/'.$up->getSaveName();
// /uploads/20190410\3ca658d42c5e241347254e006949a0c7.jpg
exit(json_encode(array('code'=>0,'msg'=>'上传成功','data'=>$img_url)));
}