分类
编程

Mac wxbill开发记录(使用laravel9+易语言)

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

laravel安装成功页面
laravel启动welcome页面

二、功能模块

  • 用户模块:添加用户、用户注册、用户登录
  • 信息模块:
    • 商品类:
    • 待发商品
    • 已发商品
    • 添加商品
    • 在线选品
    • 设置类:
    • 设置发单群
    • 设置采集群
    • 全局设置:推广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

table:表名,primaryke:索引字段名,guarded=[]允许操作所有字段

在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待发商品列表页