ThinkPHP6企业级知识库系统开发:从权限控制到全文检索全流程实战 | PHP开发进阶

2025-08-18 0 452

发布日期:2024年8月20日

一、系统架构设计

本教程将构建一个完整的企业知识库系统,包含以下核心模块:

  • 权限系统RBAC权限控制模型
  • 知识管理:Markdown编辑器与版本控制
  • 全文检索Elasticsearch集成
  • API接口:JWT认证与Swagger文档
  • 数据统计:知识图谱可视化

技术栈:ThinkPHP6 + MySQL + Elasticsearch + Vue3(管理后台)

二、项目初始化与配置

1. 环境准备

# 安装ThinkPHP6
composer create-project topthink/think knowledge-base
cd knowledge-base

# 安装扩展包
composer require elasticsearch/elasticsearch
composer require firebase/php-jwt
composer require league/flysystem-aws-s3-v3

2. 目录结构规划

app/
├── controller/       # 控制器
│   ├── admin/        # 后台控制器
│   └── api/          # API控制器
├── model/            # 数据模型
│   ├── enums/        # 枚举类
│   └── traits/       # 模型特性
├── service/          # 业务服务
│   ├── auth/         # 认证服务
│   └── search/       # 搜索服务
├── middleware/       # 中间件
├── common.php        # 公共函数
config/
├── elasticsearch.php # ES配置
├── jwt.php           # JWT配置
database/
├── migrations/       # 迁移文件
└── seeds/            # 数据填充

三、RBAC权限系统实现

1. 数据库设计

// 用户表迁移
Schema::create('admin_users', function (Blueprint $table) {
    $table->id();
    $table->string('username', 50)->unique();
    $table->string('password');
    $table->string('realname')->nullable();
    $table->tinyInteger('status')->default(1);
    $table->timestamps();
});

// 角色表迁移
Schema::create('admin_roles', function (Blueprint $table) {
    $table->id();
    $table->string('name', 50);
    $table->string('description')->nullable();
    $table->timestamps();
});

// 权限表迁移
Schema::create('admin_permissions', function (Blueprint $table) {
    $table->id();
    $table->string('name', 50);
    $table->string('path')->nullable();
    $table->string('method')->nullable();
    $table->timestamps();
});

2. 权限中间件

// app/middleware/PermissionCheck.php
namespace appmiddleware;

use thinkfacadeSession;

class PermissionCheck
{
    public function handle($request, Closure $next)
    {
        $user = Session::get('admin_user');
        $path = $request->pathinfo();
        $method = $request->method();
        
        if (!$this->checkPermission($user, $path, $method)) {
            return $request->isAjax() 
                ? json(['code' => 403, 'msg' => '无权访问']) 
                : redirect('/admin/error/403');
        }
        
        return $next($request);
    }
    
    protected function checkPermission($user, $path, $method)
    {
        // 超级管理员拥有所有权限
        if ($user['is_super']) {
            return true;
        }
        
        // 检查用户角色权限
        $permissions = $user->roles()
            ->with('permissions')
            ->select()
            ->column('permissions.*');
            
        foreach ($permissions as $perm) {
            if ($this->matchPath($perm->path, $path) {
                return in_array($method, explode(',', $perm->method));
            }
        }
        
        return false;
    }
}

四、Markdown知识管理

1. 编辑器集成

// 前端编辑器组件
<template>
  <div class="editor-container">
    <textarea ref="editor"></textarea>
    <div class="preview" v-html="compiledMarkdown"></div>
  </div>
</template>

<script>
import marked from 'marked';
import hljs from 'highlight.js';

export default {
  data() {
    return {
      content: ''
    }
  },
  computed: {
    compiledMarkdown() {
      return marked(this.content, {
        highlight: code => hljs.highlightAuto(code).value
      });
    }
  },
  mounted() {
    this.initEditor();
  },
  methods: {
    initEditor() {
      // 初始化SimpleMDE编辑器
      this.editor = new SimpleMDE({
        element: this.$refs.editor,
        autoDownloadFontAwesome: false,
        spellChecker: false,
        toolbar: ['bold', 'italic', 'heading', '|', 'quote', 'code', '|', 'link', 'image', '|', 'preview']
      });
      
      this.editor.codemirror.on('change', () => {
        this.content = this.editor.value();
      });
    }
  }
}
</script>

2. 版本控制实现

// app/model/Knowledge.php
namespace appmodel;

use thinkModel;

class Knowledge extends Model
{
    // 关联版本
    public function versions()
    {
        return $this->hasMany(KnowledgeVersion::class);
    }
    
    // 创建新版本
    public function createVersion($content, $userId)
    {
        return $this->versions()->save([
            'content' => $content,
            'user_id' => $userId,
            'version' => $this->versions()->count() + 1
        ]);
    }
    
    // 恢复版本
    public function restoreVersion($versionId)
    {
        $version = $this->versions()
            ->where('id', $versionId)
            ->find();
            
        if ($version) {
            $this->save([
                'content' => $version->content
            ]);
        }
        
        return $this;
    }
}

五、Elasticsearch集成

1. 搜索服务封装

// app/service/SearchService.php
namespace appservice;

use ElasticsearchClientBuilder;

class SearchService
{
    protected $client;
    
    public function __construct()
    {
        $this->client = ClientBuilder::create()
            ->setHosts(config('elasticsearch.hosts'))
            ->build();
    }
    
    // 创建索引
    public function createIndex($index)
    {
        $params = [
            'index' => $index,
            'body' => [
                'settings' => [
                    'number_of_shards' => 1,
                    'number_of_replicas' => 0
                ],
                'mappings' => [
                    'properties' => [
                        'title' => ['type' => 'text', 'analyzer' => 'ik_max_word'],
                        'content' => ['type' => 'text', 'analyzer' => 'ik_max_word'],
                        'tags' => ['type' => 'keyword']
                    ]
                ]
            ]
        ];
        
        return $this->client->indices()->create($params);
    }
    
    // 索引文档
    public function indexDocument($index, $id, $document)
    {
        $params = [
            'index' => $index,
            'id' => $id,
            'body' => $document
        ];
        
        return $this->client->index($params);
    }
}

2. 全文检索实现

// app/controller/api/Search.php
namespace appcontrollerapi;

use appBaseController;
use appserviceSearchService;

class Search extends BaseController
{
    public function index()
    {
        $keyword = $this->request->param('keyword');
        $page = $this->request->param('page', 1);
        $size = $this->request->param('size', 10);
        
        $params = [
            'index' => 'knowledge',
            'body' => [
                'query' => [
                    'multi_match' => [
                        'query' => $keyword,
                        'fields' => ['title^3', 'content', 'tags']
                    ]
                ],
                'from' => ($page - 1) * $size,
                'size' => $size,
                'highlight' => [
                    'fields' => [
                        'title' => new stdClass(),
                        'content' => new stdClass()
                    ]
                ]
            ]
        ];
        
        $results = app(SearchService::class)->search($params);
        
        return json([
            'code' => 200,
            'data' => $this->formatResults($results)
        ]);
    }
}

六、JWT认证接口

1. JWT服务封装

// app/service/JwtService.php
namespace appservice;

use FirebaseJWTJWT;
use FirebaseJWTKey;

class JwtService
{
    protected $key;
    protected $algorithm;
    
    public function __construct()
    {
        $this->key = config('jwt.key');
        $this->algorithm = config('jwt.algorithm');
    }
    
    public function generateToken($userId)
    {
        $payload = [
            'iss' => config('app.app_host'),
            'iat' => time(),
            'exp' => time() + 3600, // 1小时过期
            'sub' => $userId
        ];
        
        return JWT::encode($payload, $this->key, $this->algorithm);
    }
    
    public function validateToken($token)
    {
        try {
            $decoded = JWT::decode($token, new Key($this->key, $this->algorithm));
            return (array)$decoded;
        } catch (Exception $e) {
            return false;
        }
    }
}

2. API认证中间件

// app/middleware/JwtAuth.php
namespace appmiddleware;

use appserviceJwtService;

class JwtAuth
{
    public function handle($request, Closure $next)
    {
        $token = $request->header('Authorization');
        
        if (!$token) {
            return json(['code' => 401, 'msg' => 'Token缺失']);
        }
        
        $payload = app(JwtService::class)->validateToken($token);
        
        if (!$payload) {
            return json(['code' => 401, 'msg' => 'Token无效']);
        }
        
        // 将用户ID存入请求
        $request->userId = $payload['sub'];
        
        return $next($request);
    }
}

七、知识图谱可视化

1. 数据关系分析

// app/service/KnowledgeGraph.php
namespace appservice;

use appmodelKnowledge;
use appmodelKnowledgeTag;

class KnowledgeGraph
{
    public function generateGraphData($knowledgeId)
    {
        $knowledge = Knowledge::with('tags')
            ->find($knowledgeId);
            
        $nodes = [];
        $links = [];
        
        // 添加当前知识节点
        $nodes[] = [
            'id' => 'knowledge_' . $knowledge->id,
            'name' => $knowledge->title,
            'category' => 0
        ];
        
        // 添加标签节点
        foreach ($knowledge->tags as $tag) {
            $nodes[] = [
                'id' => 'tag_' . $tag->id,
                'name' => $tag->name,
                'category' => 1
            ];
            
            $links[] = [
                'source' => 'knowledge_' . $knowledge->id,
                'target' => 'tag_' . $tag->id
            ];
        }
        
        // 添加相关知识点
        $related = $this->findRelatedKnowledge($knowledge);
        foreach ($related as $item) {
            $nodes[] = [
                'id' => 'knowledge_' . $item->id,
                'name' => $item->title,
                'category' => 2
            ];
            
            $links[] = [
                'source' => 'knowledge_' . $knowledge->id,
                'target' => 'knowledge_' . $item->id
            ];
        }
        
        return compact('nodes', 'links');
    }
}

2. ECharts可视化

// 前端可视化组件
<template>
  <div ref="chart" style="width: 100%; height: 600px;"></div>
</template>

<script>
import * as echarts from 'echarts';

export default {
  props: ['knowledgeId'],
  data() {
    return {
      chart: null
    }
  },
  mounted() {
    this.initChart();
    this.loadData();
  },
  methods: {
    initChart() {
      this.chart = echarts.init(this.$refs.chart);
      
      const option = {
        tooltip: {},
        legend: {
          data: ['知识点', '标签', '相关知识点']
        },
        series: [{
          type: 'graph',
          layout: 'force',
          data: [],
          links: [],
          categories: [
            { name: '知识点' },
            { name: '标签' },
            { name: '相关知识点' }
          ],
          roam: true,
          label: {
            show: true,
            position: 'right'
          },
          force: {
            repulsion: 100,
            edgeLength: [100, 300]
          }
        }]
      };
      
      this.chart.setOption(option);
    },
    
    async loadData() {
      const res = await this.$api.getKnowledgeGraph(this.knowledgeId);
      
      const option = {
        series: [{
          data: res.nodes,
          links: res.links
        }]
      };
      
      this.chart.setOption(option);
    }
  }
}
</script>

八、总结与扩展

通过本教程,您已经掌握了:

  1. RBAC权限系统设计
  2. Markdown知识管理实现
  3. Elasticsearch全文检索
  4. JWT认证接口开发
  5. 知识图谱可视化技术

扩展学习方向:

  • 微服务架构改造
  • 自动化测试体系
  • 多语言支持方案
  • Serverless部署
ThinkPHP6企业级知识库系统开发:从权限控制到全文检索全流程实战 | PHP开发进阶
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

淘吗网 thinkphp ThinkPHP6企业级知识库系统开发:从权限控制到全文检索全流程实战 | PHP开发进阶 https://www.taomawang.com/server/thinkphp/894.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务