JetibenRong

JetibenRong

我想有那么一段时光,可以在面朝大海的房车里煮上一杯咖啡,看看曾写过的代码

Jtbc5 做一个简单的会员功能

本文发布于:2024-02-02

一、概要

利用现有的用户模块

适用于会员不是太多的场景

二、具体步骤

1、\Public\console\account\common\diplomat\manage.php,中的 getRoleList  方法里添加  $result[] = ['id' => -2, 'title' => '注册会员'];  这是为了和后台手动添加的角色区分开。

代码片段:

...

  private function getRoleList()
  {
    $result = [];
    $roleModel = new RoleModel();
    $roleModel -> orderBy('order', 'desc');
    $roleModel -> orderBy('id', 'asc');
    $roleRsa = $roleModel -> getAll(['id', 'title']);
    $result[] = ['id' => 0, 'title' => Jtbc::take('::communal.please-select', 'lng')];
    if ($this -> guard -> role -> isSuper)
    {
      $result[] = ['id' => -1, 'title' => Jtbc::take('::communal.role-super', 'lng')];
      $result[] = ['id' => -2, 'title' => '注册会员'];
    }
    foreach ($roleRsa as $roleRs)
    {
      $result[] = ['id' => intval($roleRs -> id), 'title' => $roleRs -> title];
    }
    return $result;
  }

...

2、\App\Common\Ambassador.php  中添加  

use App\Console\Common\Ambassador\Guard;

$this -> guard = new Guard($this -> di);  // 这里和后台的公用一套用户系统,通过此实例 guard ,可以获取用户信息,判断是否登录。

代码片段

...

use Jtbc\Diplomatist;
use App\Common\Hook\ForeStageHookLoader;
use App\Console\Common\Ambassador\Guard;

class Ambassador extends Diplomatist
...


...

  public function __construct()
  {
    parent::__construct();
    $this -> setParam('assets_path', 'common/assets');
    $this -> setParam('root_assets_path', Path::getActualRoute('common/assets'));
    $this -> addParam('meta_title', Jtbc::take('global.communal.title', 'lng'));
    $this -> setParam('meta_keywords', Jtbc::take('global.communal.keywords', 'lng'));
    $this -> setParam('meta_description', Jtbc::take('global.communal.description', 'lng'));
    $this -> addParam('stylesheets', ['url' => $this -> getParam('root_assets_path') . '/frame.css']);
    $this -> guard = new Guard($this -> di);
    $this -> foreStageHookLoader = new ForeStageHookLoader();
    $this -> foreStageHookLoader -> load($this -> di -> hook);
    $this -> di -> hook -> forestageAfterConstruct -> trigger($this, $this -> middleware);
  }

...

3、如何应用,这里用一个不太合适的例子,只要登陆的用户 就可以看到未发布的文章。

以文章模块为例 news\common\diplomat\index.php  中 list 方法中添加  if (!$this -> guard -> checkLogin()) $model -> where -> published = 1;

代码片段

...

 public function list(Request $req, Response $res)
  {
    $pagesize = 12;
    $page = intval($req -> get('page'));
    $category = intval($req -> get('category') ?? -1);
    $lang = intval($this -> getParam('lang'));
    $model = new TinyModel();
    $model -> pageNum = $page;
    $model -> pageSize = $pagesize;
    if (!$this -> guard -> checkLogin()) $model -> where -> published = 1;
    $model -> where -> lang = $lang;
    if ($category != -1)
    {
...

 

三、加一个用户中心

1、后台 -> 开发维护 -> 模块管理:创建一个父模块,模块标题为“用户中心”,目录名为 “my”。 如图

 

2、然后在新建的模块下添加如下图所示的文件和文件夹。

 

具体代码如下 

diplomat\index.php

<?php
namespace Jtbc;
use App\Common\Ambassador;
use App\Common\Widgets\Breadcrumb\BreadcrumbBuilder;

class Diplomat extends Ambassador {
  private $breadcrumbBuilder;

  public function __start()
  {
    $this -> addParam('meta_title', Jtbc::take('index.title', 'lng'));
    $this -> breadcrumbBuilder = new BreadcrumbBuilder($this -> getParam('genre'));
    $this -> setParam('breadcrumb', $this -> breadcrumbBuilder -> build());
  }

  public function index()
  {
    return Jtbc::take('index.index');
  }
}

language\index.jtbc

<?xml version="1.0" encoding="utf-8"?>
<xml mode="jtbc" author="jetiben">
  <configure>
    <node>item</node>
    <field>name,zh-cn</field>
    <base>item_list</base>
  </configure>
  <item_list>
    <item>
      <name><![CDATA[title]]></name>
      <zh-cn><![CDATA[用户中心]]></zh-cn>
    </item>
  </item_list>
</xml>

template\index.jtbc // 具体的用户信息模板,

<?xml version="1.0" encoding="utf-8"?>
<xml mode="jtbc" author="jetiben">
  <configure>
    <node>item</node>
    <field>name,default</field>
    <base>item_list</base>
  </configure>
  <item_list>
    <item>
      <name><![CDATA[index]]></name>
      <default><![CDATA[{$=$take('global.communal.header')}
<navigation>
  <box><jtbc-breadcrumb data="{$=$htmlEncode($breadcrumb)}"></jtbc-breadcrumb></box>
</navigation>
<container>
  <box>
    <main>
      <div style="width: 300px; margin: 30px auto; font-size: 16px; padding-top: 50px">
          <p>用户名 :{$=$userInfo['username']}</p>
          <p style="margin: 15px 0">E-mail :{$=$userInfo['email']}</p>
          <p style="margin: 15px 0">手机 :{$=$userInfo['mobile']}</p>
          <p>注册日期 :{$=$formatDate($userInfo['time'], 1)}</p>
      </div>

	</main>
  </box>
</container>
{$=$take('global.communal.footer')}]]></default>
    </item>
  </item_list>
</xml>

 

3、在\App\My 目录下添加一个拦截器 Gateway.php  // 这是一个中间件,这里用来拦截 my 模块下的请求,只用登录才可以放行,否则显示 403,也可以处理为跳转登录,这里为了简洁显示 403。

<?php
namespace App\My;


class Gateway
{
  public static function handle(callable $handler, $diplomat)
  {
    $result = function() use ($handler, $diplomat)
    {
      $code = 0;
      $passed = false;
      $guard = $diplomat -> guard;
      var_dump($diplomat -> getParam('genre'));
      if ($guard -> checkLogin() || $diplomat -> getParam('genre') != 'my')
      {
        $passed = true;
      }
      if ($passed == false)
      {
        $diplomat -> di -> response -> setStatusCode(403);
        return null;
      }
      else
      {
        return call_user_func($handler);
      }
    };
    return $result;
  }
}

4、在 App\Common\Ambassador.php  中添加  中间件 Gateway.php

    use App\My\Gateway;     

              $this -> addParam('userName', $this -> guard -> checkLogin() ? $this -> guard -> account : null);
              $this -> middleware -> add([Gateway::class, 'handle'], $this);
 
             如图
 
 
 

至此就结束了,前台访问 http://xxx.com/my/, 如果没有登录会显示 403,登录后会显示登录的用户信息。注意这里没有提供具体的登录页面,是和后台登录共用的,也没有注册。

四、总结

相当的简陋,但是重点不在具体的细节,而是一个实现的思路,希望对你能有所帮助。

来源:http://blog.dafengge.net/blog/detail-2.html

 

JetibenRong

JetibenRong

我想有那么一段时光,可以在面朝大海的房车里煮上一杯咖啡,看看曾写过的代码

联络

标签

链接