Gitee项目地址:https://gitee.com/MoSheng2020/wxbill
一、搭建环境:
1、Mac安装brew,安装brew参考另一篇文章:点我跳转
2、安装Nginx
brew install nginx
Nginx对laravel9的配置参考
server {
listen 80;
listen [::]:80;
server_name example.com;
root /srv/example.com/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
3、安装mysql
brew install muysql
4、安装composer
brew install composer
5、安装php
brew install php@8.0
//添加PHP的软链
brew link php@8.0
//按照提示设置php
echo 'export PATH="/usr/local/opt/php@8.0/bin:$PATH"' >> ~/.zshrc
echo 'export PATH="/usr/local/opt/php@8.0/sbin:$PATH"' >> ~/.zshrc
export LDFLAGS="-L/usr/local/opt/php@8.0/lib"
export CPPFLAGS="-I/usr/local/opt/php@8.0/include"
laravel9php配置要求
Laravel 框架对系统有一些要求,请确保你的 Web 服务器至少满足以下 PHP 版本及扩展需求。
- PHP >= 8.0
- BCMath PHP 扩展
- Ctype PHP 扩展
- DOM PHP 扩展
- Fileinfo PHP 扩展
- JSON PHP 扩展
- Mbstring PHP 扩展
- OpenSSL PHP 扩展
- PCRE PHP 扩展
- PDO PHP 扩展
- Tokenizer PHP 扩展
- XML PHP 扩展
6、安装一个laravel项目
在web目录新建一个目录,比如/usr/local/var/www/wxbill
务必保证目录是空的,否则会提示安装失败
使用命令进入这个目录,compose+php来安装laravel
cd /usr/local/var/www/wxbill
composer create-project laravel/laravel ./
安装完毕后,使用php artisan serve命令快速启动laravel项目,完毕会提示laravel访问地址,如:http://localhost:8000,你也可以使用Nginx配置网址访问/usr/local/var/www/wxbill/public
二、功能模块
- 用户模块:添加用户、用户注册、用户登录
- 信息模块:
- 商品类:
- 待发商品
- 已发商品
- 添加商品
- 在线选品
- 设置类:
- 设置发单群
- 设置采集群
- 全局设置:推广ID、推送时间、推送开关、新人欢迎语、新人欢迎间隔时间、商品间隔时间、图片间隔时间
- 推送模块:E语言客户端,启动微信,并拉取服务端数据推送到微信
三、用户模块
用户登录,新建路由
Route::get('/user/login',function(){
return view('user.login');
});
Route::post('/user/login',[UserController::class,'login'])->name('login');
在.env文件中配置好mysql登录账号密码
新建数据库daka_goods
新建表
创建控制器
php atrtisan make:controller UserLogin
创建模型关联数据表
php artisan make:model LoginUser
在app/Models/LoginUser.php文件中,填入
class LoginUser extends Model
{
use HasFactory;
protected $table = 'a_user';
protected $primaryKey = 'id';
public $guarded=[];
public $timestamps = false;
}
打开地址:http://localhost:83/user/login
登录页在resources/views/user/login.blade.php中,登录的post写法
$.post('/user/login',
{'_token':'{{csrf_token()}}','L_username':L_username,'L_pass':L_pass},
function(data){
// console.log(data);
if(data.status == 0){
layer.msg(data.msg,{icon:6},function(){
// location.reload();
self.location.href="/user/index";
});
}else{
layer.msg(data.msg,{icon:5});
}
})
接下里是写/user/login的登录api接口
使用php命令创建一个数据库模型
php atrisan make:model LoginUser
模型路径:app/Http/Models/LoginUser.php
在UserController控制器中引入这个模型
use App\Models\LoginUser;
控制器login方法:
//登录
public function login(Request $request){
$L_username = $request -> input('L_username');
$L_pass = $request -> input('L_pass');
$users = LoginUser::where('username',$L_username)->get()->first();
if($users){
if($users['password'] == $L_pass){
$data = array('status' => 0, 'msg' => '登录成功!');
}else{
$data = array('status' => 1, 'msg' => '密码错误!');
}
}else{
$data = array('status' => 1, 'msg' => '不存在这个用户!');
}
$request->session()->put('user', $users);
return response()->json($data);
}
到此为止登录页就写完了,为了安全起见,又写了一个中间还能来判断用户是否登录。
// 首页
Route::get('/user/index',[UserController::class,'index'])->middleware('isLogin');
这个是登录后的首页,然后我们在路由中添加middleware中间件
中间件流程:
1、申明中间件 -> php artisan
2、写中间件逻辑 -> app/Http/Middleware/IsLogin.php
3、注册中间件 -> app/Http/Kernel.php
4、使用中间件 -> 路由中使用
申明中间件:
php artisan make:middleware IsLogin;
生成的中间件在:app/Http/Middleware/IsLogin.php
注册中间件:
在文件app/Http/Kernel.php中添加isLogin
然后路由中可直接使用中间件了
四、信息模块
首页,待发商品列表
路由:
// 首页
Route::get('/user/index',[UserController::class,'index'])->middleware('isLogin');
控制器
//待发送商品页
public function index(Request $request){
return view('user.list');
}
list.blade.php页面使用layui的table模块
html代码
<table id="demo" class="layui-table" lay-filter="test" lay-data="{height: 'full-200'}"></table>
js代码
<script type="text/javascript">
layui.use('table', function(){
var table = layui.table,form = layui.form;
//table数据模板
table.render({
elem: '#demo',
cellMinWidth: 80, //全局定义常规单元格的最小宽度,layui 2.2.1 新增
//height:'full',
height:1000,
url: '/user/get_list?status=0', //数据接口
page: true ,//开启分页
//toolbar: '#toolbarDemo', //开启头部工具栏,并为其绑定左侧模板
cols: [[ //表头
{field: 'ID', title: 'ID', width:50, align: 'center'},
{
field: 'goodsImage',
title: '推广图',
width:120,
align: 'center',
templet: function(d){
return '<div><img id="'+d.ID+'tgimg" src="'+d.goodsImage+'" alt="" class="layui-upload-img" onclick="previewImg(this)"></div>';
}
},{
field: 'sucai1',
title: '素材1',
width:120,
align: 'center',
templet: function(d){
if(d.sucai1 !== null && d.sucai1 !== ""){
if(d.sucai1.indexOf("mp4") != -1){
return '<div><video controls="controls" id="'+d.ID+'tgimg" src="'+d.sucai1+'" alt="" class="layui-upload-img" onclick="previewImg(this)"></div>';
}else if(d.sucai1.indexOf("jpg") != -1 || d.sucai1.indexOf("jpeg") != -1 || d.sucai1.indexOf("png") != -1){
return '<div><img id="'+d.ID+'tgimg" src="'+d.sucai1+'" alt="" class="layui-upload-img" onclick="previewImg(this)"></div>';
}else{
return '<div>无</div>';
}
}else{
return '<div>无</div>';
}
}
},{
field: 'sucai2',
title: '素材2',
width:120,
align: 'center',
templet: function(d){
if(d.sucai2 !== null && d.sucai2 !== ""){
if(d.sucai2.indexOf("mp4") != -1){
return '<div><video controls="controls" id="'+d.ID+'tgimg" src="'+d.sucai1+'" alt="" class="layui-upload-img" onclick="previewImg(this)"></div>';
}else if(d.sucai2.indexOf("jpg") != -1 || d.sucai2.indexOf("jpeg") != -1 || d.sucai2.indexOf("png") != -1){
return '<div><img id="'+d.ID+'tgimg" src="'+d.sucai2+'" alt="" class="layui-upload-img" onclick="previewImg(this)"></div>';
}else{
return '<div>无</div>';
}
}else{
return '<div>无</div>';
}
}
},{
field: 'sucai3',
title: '素材3',
width:120,
align: 'center',
templet: function(d){
if(d.sucai3 !== null && d.sucai3 !== ""){
if(d.sucai3.indexOf("mp4") != -1){
return '<div><video controls="controls" id="'+d.ID+'tgimg" src="'+d.sucai1+'" alt="" class="layui-upload-img" onclick="previewImg(this)"></div>';
}else if(d.sucai3.indexOf("jpg") != -1 || d.sucai3.indexOf("jpeg") != -1 || d.sucai3.indexOf("png") != -1){
return '<div><img id="'+d.ID+'tgimg" src="'+d.sucai3+'" alt="" class="layui-upload-img" onclick="previewImg(this)"></div>';
}else{
return '<div>无</div>';
}
}else{
return '<div>无</div>';
}
}
},
{
field: 'docment',
title: '文案',
width: 280,
align: 'center',
templet: function(d){
d.docment = Base64.decode(d.docment);
return '<textarea id="' + d.ID + 'checkinfo" placeholder="商品文案" class="layui-textarea">' + d.docment + '</textarea>';
//return '<div>' + d.docment + '</div>';
}
},{
field: 'upcment',
title: '补刀',
width: 280,
align: 'center',
templet: function(d){
if(d.upcment != null && d.upcment != ""){
d.upcment = Base64.decode(d.upcment);
}else{
d.upcment = "";
}
return '<textarea id="' + d.ID + 'checkinfo" placeholder="补刀段子" class="layui-textarea">' + d.upcment + '</textarea>';
}
},
{fixed: 'right', title:'操作', toolbar: '#barDemo', width:400, align: 'center'}
]]
});
});
});
</script>
其中get_list是获取列表接口
路由
//数据接口
Route::get('/user/get_list',[UserController::class,'get_list'])->middleware('isLogin');
控制器,记得先创建SoftGoods的数据表模板然后在控制器中引用
//list接口
public function get_list(Request $request){
$status = $request->input('status');
$username = $request->session()->get('user');
$username = $username['username'];
$soft = SoftGoods::where('username',$username)->where('status',0)->get();//数组array
$softs = array();
$softs['data'] = $soft;
$softs['code'] = 0;
return json_encode($softs);
}
user/index待发商品列表页