# 开发新模块
## 操作,开发流程
```
php think make:controller admin/Wemedia --plain
php think make:validate
php think make:model
```
## validate
```
<?php
namespace app\common\validate;
use think\Validate;
class Wemedia extends Validate
{
protected $rule = [
'id' => 'require|number',
'title' => 'require|max:40|unique:wemedia',
'url' => 'require|max:60|url',
'username' => 'require|max:20',
'password' => 'require|length:6,20',
'email' => 'require|max:30|email',
'telphone' => 'require|mobile',
'description' => 'require|max:200',
'order' => 'require|integer',
'status' => 'require|in:0,1,2',
];
protected $message = [
'id.require' => 'id 为必填项',
'title.require' => 'title 为必填项',
'title.max' => 'title 最长为40个字符',
'title.unique' => 'title 不能重复添加',
'url.require' => 'url 为必填项',
'url.max' => 'url 最长为60个字符',
'url.url' => 'url 地址不合法',
'username.require' => 'username 为必填项',
'username.max' => 'username 最长为20个字符',
'password.require' => 'password 为必填项',
'password.length' => 'password 长度必须为6到20个字符',
'email.require' => 'email 为必填项',
'email.max' => 'email 最长为30个字符',
'email.email' => 'email 格式不正确',
'telphone.require' => 'telphone 为必填项',
'telphone.mobile' => 'telphone 格式不正确',
'description.require' => 'description 为必填项',
'description.max' => 'description 不能多于200个字符',
'status.require' => 'status 为必填项',
'order.require' => 'order 为必填项',
'order.integer' => 'order 必须为整数',
];
public function sceneAdd()
{
return $this->remove('id', 'require');
}
public function sceneOrder()
{
return $this->only(['order', 'id']);
}
}
```
## 控制器
*application\admin\controller\Wemedia.php*
```
<?php
namespace app\admin\controller;
use think\facade\Request;
use app\common\model\Wemedia as WemediaModel;
use app\common\model\WemediaCatalog;
use app\common\model\WemediaLinks;
class Wemedia extends Base
{
public function index()
{
$title = Request::param('title');
$where = [];
$limit = 10;
if ($title) {
$where[] = ['title', 'like', "%" . $title . "%"];
}
$where[] = ['status', 'in', [0, 1]];
$list = WemediaModel::where($where)->order("order", "asc")->order("id", "desc")->paginate($limit);
$count = WemediaModel::where($where)->count();
return view('index', compact('list', 'count'));
}
public function addWemedia()
{
$data = Request::param();
if (Request::isPost()) {
$args = [];
$args['id'] = isset($data['id']) ? (integer)$data['id'] : null;
$args['title'] = $data['title'];
$args['email'] = $data['email'];
$args['url'] = $data['url'];
$args['username'] = $data['username'];
$args['password'] = $data['password'];
$args['telphone'] = $data['telphone'];
$args['description'] = $data['description'];
$args['order'] = (integer)$data['order'];
$args['status'] = (integer)$data['status'];
$validate = validate('Wemedia');
if (isset($data['id']) && $data['id']) {
// 编辑
if (!$validate->batch()->check($args)) {
return json(['status' => 0, 'data' => $args, 'msg' => implode("; ", $validate->getError())]);
}
$model = new WemediaModel();
if ($model->save($args, ['id' => $args['id']])) {
return json(['data' => $args, 'status' => 1, 'msg' => '编辑成功']);
} else {
return json(['data' => $args, 'status' => 0, 'msg' => '编辑失败']);
}
} else {
// 添加
if (!$validate->scene('add')->batch()->check($args)) {
return json(['status' => 0, 'data' => $args, 'msg' => implode("; ", $validate->getError())]);
}
$model = new WemediaModel($args);
if ($model->save()) {
return json(['data' => $args, 'status' => 1, 'msg' => '添加成功']);
} else {
return json(['data' => $args, 'status' => 0, 'msg' => '添加失败']);
}
}
}
if (isset($data['id']) && $data['id']) {
$data = WemediaModel::get($data['id']);
return view("add_wemedia", compact('data'));
}
return view("add_wemedia");
}
public function delAll()
{
$data = Request::param();
$model = Request::param('model');
if (!isset($data['ids'])) {
return json(['data' => $data, 'status' => 0, 'msg' => '选中不能为空']);
}
//强制删除
if ($model == "WemediaModel") {
if (WemediaModel::destroy($data['ids'])) {
return json(['data' => $data, 'status' => 1, 'msg' => '操作成功']);
}
} elseif ($model == "WemediaCatalog") {
if (WemediaCatalog::destroy($data['ids'])) {
return json(['data' => $data, 'status' => 1, 'msg' => '操作成功']);
}
}
return json(['data' => $data, 'status' => 0, 'msg' => '删除失败']);
}
}
```
## 视图
*application\admin\view\wemedia\index.html*
```
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>列表页面</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<link rel="stylesheet" href="/static/admin/css/font.css">
<link rel="stylesheet" href="/static/admin/css/xadmin.css">
<script type="text/javascript" src="/static/jquery/3.2.1/jquery.min.js"></script>
<script src="/static/admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/static/admin/js/xadmin.js"></script>
<script type="text/javascript" src="/static/admin/js/cookie.js"></script>
<!-- 让IE8/9支持媒体查询,从而兼容栅格 -->
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="x-nav">
<span class="layui-breadcrumb">
<a href="{:url('index/index')}">首页</a>
<a href="{:url('wemedia/index')}"><cite>自媒体号列表</cite></a>
</span>
<a class="layui-btn layui-btn-small" style="line-height:1.6em;margin-top:3px;float:right;"
href="javascript:location.replace(location.href);" title="刷新"><i class="layui-icon layui-icon-refresh" style="line-height:30px"></i></a>
<a class="layui-btn" href="{:url('wemedia/index')}" target="_blank" style="line-height:1.6em;margin-top:3px;float:right; margin-right: 10px;"><i class="layui-icon layui-icon-senior" style="line-height:30px"></i>新窗口</a>
</div>
<div class="x-body">
<div class="layui-row">
<form class="layui-form layui-col-md12 x-so">
<input class="layui-input" autocomplete="off" placeholder="开始日" name="start" id="start">
<input class="layui-input" autocomplete="off" placeholder="截止日" name="end" id="end">
<input type="text" name="title" placeholder="请输入名称" autocomplete="off" class="layui-input">
<button class="layui-btn" lay-submit="" lay-filter="sreach"><i class="layui-icon"></i></button>
</form>
</div>
<xblock>
<button class="layui-btn layui-btn-danger" onclick="delAll()"><i class="layui-icon"></i>批量删除</button>
<?php $add_url = url("wemedia/addWemedia"); ?>
<button class="layui-btn" onclick="x_admin_show('添加新媒体','{$add_url}',1200,650)"><i class="layui-icon"></i>添加</button>
<span class="x-right" style="line-height:40px">共有数据:{$count} 条</span>
</xblock>
<form id="update">
<table class="layui-table x-admin">
<thead>
<tr>
<th width="20">
<div class="layui-unselect header layui-form-checkbox" lay-skin="primary"><i class="layui-icon"></i></div>
</th>
<th width="25">ID</th>
<th>标题</th>
<th width="25">排序</th>
<th width="40">状态</th>
<th width="50">操作</th></tr>
</thead>
<tbody>
{volist name="list" id="vo"}
<tr>
<td>
<div class="layui-unselect layui-form-checkbox" lay-skin="primary" data-id='{$vo->id}'><i class="layui-icon"></i></div>
</td>
<td>{$vo->id}</td>
<td>{$vo->title}</td>
<td width="40"><input type="text" name="list[{$vo->id}]" value="{$vo->order}" class="layui-input layui-input-inline" /></td>
<td class="td-status" style="text-align: center;">
{if $vo->status == 1}
<span onclick="member_update(this,'{$vo->id}',0)" class="layui-icon layui-icon-ok" style="color: #009688; font-weight: bold;"></span>
{else /}
<span onclick="member_update(this,'{$vo->id}',1)" class="layui-icon layui-icon-close" style="color: #FF5722; font-weight: bold;"></span>
{/if}
</td>
<td class="td-manage">
<?php $editUrl = url('wemedia/addWemedia', ['id' => $vo->id]) ?>
<a title="编辑" onclick="x_admin_show('编辑','{$editUrl}', 1200, 500)" href="javascript:;"><i class="layui-icon"></i></a>
<a title="删除" onclick="member_del(this,'{$vo->id}')" href="javascript:;"><i class="layui-icon"></i></a>
</td>
</tr>
{/volist}
</tbody>
</table>
<input type="hidden" value="Wemedia" name="model" />
</form>
<div class="page">
{$list|raw}
</div>
<div class="layui-row">
<div class="layui-col-md12">
<button class="layui-btn" style="float: right" onclick="order_update(this)">
<i class="layui-icon layui-icon-list"></i> 更新排序
</button>
</div>
</div>
</div>
<script>
/*删除*/
function member_del(obj,id){
layer.confirm('确认要删除吗?',function(index){
//发异步删除数据
$.post(
"{:url('base/status')}",
{'id': id, 'model': 'Wemedia', 'type' : 2},
function (res) {
if (res.status == 1) {
$(obj).parents("tr").remove();
layer.msg('已删除!',{icon:1,time:1000});
} else {
layer.msg(res.msg);
}
},
"JSON"
);
});
}
/*修改状态*/
function member_update(obj, id, status) {
$.post(
"{:url('base/status')}",
{'id': id, 'model': 'Wemedia', 'type' : 1, 'status': status},
function (res) {
if (res.status == 1) {
location.replace(location.href);
} else {
layer.msg(res.msg);
}
},
"JSON"
);
}
/*全选删除*/
function delAll () {
var data = tableCheck.getData();
console.log(data);
if (data.length == 0) {
layer.msg("选中商品不能为空");
return false;
}
layer.confirm('确认要删除吗,该操作无法恢复,建议先备份数据库?' + data, function (index) {
//捉到所有被选中的,发异步进行删除
$.post(
"{:url('wemedia/delAll')}",
{"ids": data, model: $("input[name='model']").val()},
function (res) {
if (res.status == 1) {
layer.msg('删除成功', {icon: 1});
$(".layui-form-checked").not('.header').parents('tr').remove();
return false;
} else {
layer.msg(res.msg);
}
},
"JSON"
);
return false;
});
}
/*更新排序*/
function order_update(obj) {
var postData = $('form#update').serializeArray();
var url = '{:url("base/Order")}';
$.post(url, postData, function (res) {
if (res.status == 1) {
layer.msg("更新成功");
setTimeout(function () {
location.replace(location.href);
}, 1 * 1000);
return false;
} else {
layer.msg(res.msg);
return false;
}
});
}
</script>
</body>
</html>
```
*****
*application\admin\view\wemedia\add_wemedia.html*
```
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
<meta charset="UTF-8">
<title>{:isset($data)?'编辑新媒体':'添加新媒体'}</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<link rel="stylesheet" href="/static/admin/css/font.css">
<link rel="stylesheet" href="/static/admin/css/xadmin.css">
<script type="text/javascript" src="/static/jquery/3.2.1/jquery.min.js"></script>
<script src="/static/admin/lib/layui/layui.js" charset="utf-8"></script>
<script type="text/javascript" src="/static/admin/js/xadmin.js"></script>
<script type="text/javascript" src="/static/admin/js/cookie.js"></script>
<!-- 让IE8/9支持媒体查询,从而兼容栅格 -->
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="x-body">
<div class="layui-container">
<div class="layui-row">
<fieldset class="layui-elem-field layui-field-title">
<legend>{:isset($data)?'编辑新媒体':'添加新媒体'}</legend>
</fieldset>
<form class="layui-form" method="post">
<div class="layui-form-item">
<label class="layui-form-label">名称</label>
<div class="layui-input-inline">
<input type="text" name="title" value="{:isset($data->title)?$data->title:''}" autocomplete="off" placeholder="请输入名称" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">分类</label>
<div class="layui-input-inline">
<select name="cate_id">
<option value=""></option>
{volist name="catalog" id="vo"}
<option value="{$vo->id}" <?php echo (isset($data->cate_id) && $vo->id==$data->cate_id)?'selected':''; ?>>{$vo->name}</option>
{/volist}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">头像</label>
<div class="layui-input-block">
<button type="button" class="layui-btn" id="head_img">
<i class="layui-icon"></i>上传图片
</button>
{if isset($data->pic)}
<div style="display: block" id="head_img_block">
<img src="{:isset($data->pic)?$data->pic:''}" alt="" width="200" style="border: 1px solid #cccccc; margin-top: 10px;"/>
<input type="hidden" name="pic" id="head_pic" value="{:isset($data->pic)?$data->pic:''}">
</div>
{else/}
<div style="display: none" id="head_img_block">
<img src="" alt="" width="200" style="border: 1px solid #cccccc; margin-top: 10px;"/>
<input type="hidden" name="pic" id="head_pic" value="{:isset($data->pic)?$data->pic:''}">
</div>
{/if}
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">URL</label>
<div class="layui-input-inline" style="width: 300px">
<input type="text" name="url" value="{:isset($data->url)?$data->url:''}" autocomplete="off" placeholder="请输入URL" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">出生日期</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" id="birthday" name="birthday">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">用户名</label>
<div class="layui-input-inline">
<input type="text" name="username" value="{:isset($data->username)?$data->username:''}" autocomplete="off" placeholder="请输入用户名" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">密码</label>
<div class="layui-input-inline">
<input type="text" name="password" value="{:isset($data->password)?$data->password:''}" autocomplete="off" placeholder="请输入密码" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">邮箱</label>
<div class="layui-input-inline">
<input type="text" name="email" value="{:isset($data->email)?$data->email:''}" autocomplete="off" placeholder="请输入邮箱" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">手机号</label>
<div class="layui-input-inline">
<input type="text" name="telphone" value="{:isset($data->telphone)?$data->telphone:''}" autocomplete="off" placeholder="请输入手机号" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">备注</label>
<div class="layui-input-block">
<textarea placeholder="请输入备注" class="layui-textarea" name="description">{:isset($data->description)?$data->description:''}</textarea>
<div class="layui-form-mid layui-word-aux">200字限制</div>
</div>
</div>
<input type="hidden" name="status" value="1">
<input type="hidden" name="order" value="1">
<input type="hidden" name="id" value="{:isset($data)?$data->id:''}">
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div style="margin-left: 20px;">
<button class="layui-btn" lay-submit="add" lay-filter="add" type="submit">立即提交</button>
</div>
</div>
</form>
</div>
</div>
</div>
<script>
layui.use(['form', 'layer', 'layedit', 'upload', 'laydate'], function () {
//上传图片
var upload = layui.upload;
//执行实例
var uploadInst = upload.render({
elem: '#head_img',
url: '{:url("base/upload", ["type"=>"wemedia"])}',
method: 'post',
done: function (res) {
//上传完毕回调
if (res.code == 0) {
$("input[name='head_pic']").val(res.data.src);
$("#head_img_block").show();
$("#head_img_block>img").attr("src", res.data.src);
} else {
layer.msg(res.msg);
}
},
error: function () {
//请求异常回调
layer.msg("上传失败");
}
});
var laydate = layui.laydate;
//日期控件
laydate.render({
elem: '#birthday'
,isInitValue: false
,format: 'yyyy-MM-dd'
,value: '{$time}'
,ready: function(date){
console.log(date);
}
,done: function(value, date, endDate){
console.log(value, date, endDate);
}
});
//监听提交
var form = layui.form, layer = layui.layer;
form.on('submit(add)', function (data) {
var url = '{:url("wemedia/addWemedia")}';
var postData = data.field;
console.log(postData);
$.post(url, postData, function (res) {
if (res.status == 1) {
var time = 2; // 定义窗口刷新秒数
layer.msg(res.msg + '<br>' + time + '秒后页面自动刷新');
setTimeout(function () {
x_admin_father_reload();
}, time * 1000);
} else {
layer.msg(res.msg);
}
}, 'json');
return false;
});
});
</script>
</body>
</html>
```