首页 > 知识库 > 生活常识 >

fastadmin+xunsearch题库系统搭建教程(fastadmin+微信小程序开发:todolist开发准备)

生活常识 2022-12-12 18:26:35
fastadmin+xunsearch题库系统搭建教程 前言一、开始整活二、开始搭建1.fastadmin配置2.xun...更多fastadmin+xunsearch题库系统搭建教程的内容,欢迎关注我们的专题频道。

fastadmin+微信小程序开发:todolist开发准备

fastadmin+xunsearch题库系统搭建教程

fastadmin+xunsearch题库系统搭建教程(fastadmin+微信小程序开发:todolist开发准备)

fastadmin+xunsearch题库系统搭建教程 前言一、开始整活二、开始搭建1.fastadmin配置2.xunsearch服务端安装(一).openssl的版本与libevent版本不对应解决方案 2.安装完成后配置3.数据库搭建4.fastadmin生成与代码修改(一).fastadmin数据表、控制器、菜单创建与生成(二).fastadmin控制器修改,调用api添加索引数据库(三).接口搭建(四).接口测试1.插入题目2.查询题目 总结
前言

因为前段时间需要搭建一套题库系统,但是网上并没有很好的开源题库 机缘巧合之下,看到fastadmin整合的xunsearch插件(提供了很好的搜索引擎) 由此我决定尝试使用fastadmin来搭建一套题库系统,而且fastadmin便捷的api给了搜题系统很大的接口支持。可以很简单的写出需要的接口,还不用担心鉴权的问题(接口收费、接口鉴权等各种功能都很好写,都有对应的插件,简化接口搭建时间)

本文利用fastadmin后台框架 + xunsearch插件,快速搭建题库系统

一、开始整活

服务器使用的是腾讯云的99一年的服务器 本文搭建基于CentOS8.0(xunsearch服务器端必须使用linux系统,官网也是强烈推荐) 服务器环境使用宝塔搭建


提示:xunsearch服务端可以和题库系统分开部署在不同服务器上(作者并未尝试),有需求可以自己探究,本文仅展示fastadmin框架与xunsearch插件同时部署在一台服务器上。

二、开始搭建

宝塔与fastadmin的搭建就不再介绍了,这两个搭建很简单,网上都有教程。 fastadmin关于xunsearch文档的文档(你也可以根据此文档完成配置)

1.fastadmin配置

我们要将fastadmin插件市场中xunsearch插件安装进我们的框架

2.xunsearch服务端安装

离线安装:讯搜官网 在线安装(Linux系统下):

curl -O http://www.xunsearch.com/download/xunsearch-full-latest.tar.bz2tar -xvf xunsearch-full-latest.tar.bz2

安装 1.4.15版本

cd xunsearch-full-1.4.15sh setup.sh

接下来就是等待安装完成 安装出现的问题:

(一).openssl的版本与libevent版本不对应

在centos8中升级了openssl,导致xunseach内libevent版本对应不上导致报错

解决方案

手动替换libevent文件 下载libevent文件2.1.12版本(我替换了这个版本解决了这个问题,其他版本尚未确认)

wget https://github.com/libevent/libevent/releases/download/release-2.1.12-stable/libevent-2.1.12-stable.tar.gz

将下载的文件打包

tar -zxvf libevent-2.1.12-stable.tar.gz

复制一份到xunsearch的packages文件夹内(删除旧版本的libevent)

cp libevent-2.1.12-stable.tar.bz2 packages/

替换后 这样重新安装就不会出现版本不一致导致libevent出现问题

2.安装完成后配置

启动服务 当安装完成Xunsearch后,我们可以通过以下命令进行启动服务

cd xunsearch-full-1.4.15cd bin./xs-ctl.sh start

启动完成后就可以和我们的fastadmin进行交互了(使用fastadmin默认配置即可) 接下来我们进入fastadmin添加一个项目 字段配置 必须要添加(id/title/body)这三个类型,不创建将导致配置生成失败 接下来我们生成一下配置

这时我们的题库已经搭建完成了,我们点击前台即可进入搜索页面. 但是这个时候我们的题库并没有数据,别着急请接着完成下面数据库的搭建!

3.数据库搭建

我们进入宝塔管理面板,去创建一个新的数据库 数据表创建与字段设置(请与上方fastadmin里xunsearch项目字段保持一致) 这时候请不要把题库导入该数据库

4.fastadmin生成与代码修改 (一).fastadmin数据表、控制器、菜单创建与生成

这时我们来到最后一步 用fastadmin中的在线命令管理(这个也是个插件,需要在插件市场安装后使用),生成该数据表的控制器 菜单创建 我们就可以看到菜单出现(如果没有多出一个菜单请刷新缓存) 我这个是修改过菜单名称的,初始名称并不是这样,不过这个并不重要 搭建到这个步骤可以看到使用这个菜单可以往数据库中加入数据,但是这样并不会往搜索引擎中加入索引数据

(二).fastadmin控制器修改,调用api添加索引数据库

以下内容使用到fastadmin的xunsearch文档中关于api的调用

我们打开宝塔,进入网站根目录,用默认的宝塔文件管理打开 目录为:/www/wwwroot/shouti/application/admin/controller/sou/Tiku.php 如果你一键生成的控制器不和我相同,那么最后文件目录也会有差异,这一步需要根据自己配置来找 打开后修改内容

默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改

我们可以在该文件中看到这个提示,根据提示,我们从[application/admin/library/traits/Backend.php]中找到添加、编辑、删除的代码

public function add() { if ($this->request->isPost()) { $params = $this->request->post("row/a"); if ($params) { $params = $this->preExcludeFields($params); if ($this->dataLimit && $this->dataLimitFieldAutoFill) { $params[$this->dataLimitField] = $this->auth->id; } $result = false; Db::startTrans(); try { //是否采用模型验证 if ($this->modelValidate) { $name = str_replace("model", "validate", get_class($this->model)); $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate; $this->model->validateFailException(true)->validate($validate); } $result = $this->model->allowField(true)->save($params); Db::commit(); } catch (ValidateException $e) { Db::rollback(); $this->error($e->getMessage()); } catch (PDOException $e) { Db::rollback(); $this->error($e->getMessage()); } catch (Exception $e) { Db::rollback(); $this->error($e->getMessage()); } if ($result !== false) { $this->success(); } else { $this->error(__('No rows were inserted')); } } $this->error(__('Parameter %s can not be empty', '')); } return $this->view->fetch(); } public function edit($ids = null) { $row = $this->model->get($ids); if (!$row) { $this->error(__('No Results were found')); } $adminIds = $this->getDataLimitAdminIds(); if (is_array($adminIds)) { if (!in_array($row[$this->dataLimitField], $adminIds)) { $this->error(__('You have no permission')); } } if ($this->request->isPost()) { $params = $this->request->post("row/a"); if ($params) { $params = $this->preExcludeFields($params); $result = false; Db::startTrans(); try { //是否采用模型验证 if ($this->modelValidate) { $name = str_replace("model", "validate", get_class($this->model)); $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate; $row->validateFailException(true)->validate($validate); } $result = $row->allowField(true)->save($params); Db::commit(); } catch (ValidateException $e) { Db::rollback(); $this->error($e->getMessage()); } catch (PDOException $e) { Db::rollback(); $this->error($e->getMessage()); } catch (Exception $e) { Db::rollback(); $this->error($e->getMessage()); } if ($result !== false) { $this->success(); } else { $this->error(__('No rows were updated')); } } $this->error(__('Parameter %s can not be empty', '')); } $this->view->assign("row", $row); return $this->view->fetch(); } public function del($ids = "") { if (!$this->request->isPost()) { $this->error(__("Invalid parameters")); } $ids = $ids ? $ids : $this->request->post("ids"); if ($ids) { $pk = $this->model->getPk(); $adminIds = $this->getDataLimitAdminIds(); if (is_array($adminIds)) { $this->model->where($this->dataLimitField, 'in', $adminIds); } $list = $this->model->where($pk, 'in', $ids)->select(); $count = 0; Db::startTrans(); try { foreach ($list as $k => $v) { $count += $v->delete(); } Db::commit(); } catch (PDOException $e) { Db::rollback(); $this->error($e->getMessage()); } catch (Exception $e) { Db::rollback(); $this->error($e->getMessage()); } if ($count) { $this->success(); } else { $this->error(__('No rows were deleted')); } } $this->error(__('Parameter %s can not be empty', 'ids')); }

我们将这段代码复制进刚刚打开的文件中 同时将这些方法根据fastadmin提供的api进行修改,达到添加xunsearch数据库索引的效果 添加修改后代码

public function add() { $search = addonsxunsearchlibraryXunsearch::instance("souti"); if ($this->request->isPost()) { $params = $this->request->post("row/a"); if ($params) { $params = $this->preExcludeFields($params); if ($this->dataLimit && $this->dataLimitFieldAutoFill) { $params[$this->dataLimitField] = $this->auth->id; } $result = false; Db::startTrans(); try { //是否采用模型验证 if ($this->modelValidate) { $name = str_replace("model", "validate", get_class($this->model)); $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate; $this->model->validateFailException(true)->validate($validate); } $result = $this->model->allowField(true)->save($params); Db::commit(); $lastid = Db::table('sou_tiku')->where('id>0')->max('id'); $data = [ 'id'=>$lastid, 'title'=>"[ID".$lastid."]:".$params['title'], 'body'=>$params['body'], 'ans'=> $params['ans'] ]; $search->add($data); } catch (ValidateException $e) { Db::rollback(); $this->error($e->getMessage()); } catch (PDOException $e) { Db::rollback(); $this->error($e->getMessage()); } catch (Exception $e) { Db::rollback(); $this->error($e->getMessage()); } if ($result !== false) { $this->success(); } else { $this->error(__('No rows were inserted')); } } $this->error(__('Parameter %s can not be empty', '')); } return $this->view->fetch(); }

添加部分解析 我首先获取到最后一位id(添加进索引数据库必须拥有一个自己的id,通过id才可以修改此条题目状态),这个id我放到题目上,如果用户投诉答案出错,可以向开发者提供此题目id,开发者可以根据id快速定位该题目 然后接下来就是根据fastadmin写好的,获取每一条数据,根据fastadmin提供的api导入进索引数据库

$lastid = Db::table('sou_tiku')->where('id>0')->max('id'); $data = [ 'id'=>$lastid, 'title'=>"[ID".$lastid."]:".$params['title'], 'body'=>$params['body'], 'ans'=> $params['ans'] ]; $search->add($data);

编辑修改后代码

public function edit($ids = null) { $search = addonsxunsearchlibraryXunsearch::instance("souti"); $row = $this->model->get($ids); if (!$row) { $this->error(__('No Results were found')); } $adminIds = $this->getDataLimitAdminIds(); if (is_array($adminIds)) { if (!in_array($row[$this->dataLimitField], $adminIds)) { $this->error(__('You have no permission')); } } if ($this->request->isPost()) { $params = $this->request->post("row/a"); if ($params) { $params = $this->preExcludeFields($params); $result = false; Db::startTrans(); try { //是否采用模型验证 if ($this->modelValidate) { $name = str_replace("model", "validate", get_class($this->model)); $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate; $row->validateFailException(true)->validate($validate); } $result = $row->allowField(true)->save($params); Db::commit(); $data = [ 'id'=>$ids, 'title'=>"[ID".$ids."]:".$params['title'], 'body'=>$params['body'], 'ans'=>$params['ans'] ]; $search->update($data); } catch (ValidateException $e) { Db::rollback(); $this->error($e->getMessage()); } catch (PDOException $e) { Db::rollback(); $this->error($e->getMessage()); } catch (Exception $e) { Db::rollback(); $this->error($e->getMessage()); } if ($result !== false) { $this->success(); } else { $this->error(__('No rows were updated')); } } $this->error(__('Parameter %s can not be empty', '')); } $this->view->assign("row", $row); return $this->view->fetch(); }

编辑部分解析 编辑该数据的同时,我们将此次编辑也通过api进行修改到索引数据库

$data = [ 'id'=>$ids, 'title'=>"[ID".$ids."]:".$params['title'], 'body'=>$params['body'], 'ans'=>$params['ans'] ]; $search->update($data);

删除修改后代码

public function del($ids = "") { $search = addonsxunsearchlibraryXunsearch::instance("souti"); if (!$this->request->isPost()) { $this->error(__("Invalid parameters")); } $ids = $ids ? $ids : $this->request->post("ids"); if ($ids) { $pk = $this->model->getPk(); $adminIds = $this->getDataLimitAdminIds(); if (is_array($adminIds)) { $this->model->where($this->dataLimitField, 'in', $adminIds); } $list = $this->model->where($pk, 'in', $ids)->select(); $count = 0; Db::startTrans(); try { foreach ($list as $k => $v) { $count += $v->delete(); } Db::commit(); $search->del($ids); } catch (PDOException $e) { Db::rollback(); $this->error($e->getMessage()); } catch (Exception $e) { Db::rollback(); $this->error($e->getMessage()); } if ($count) { $this->success(); } else { $this->error(__('No rows were deleted')); } } $this->error(__('Parameter %s can not be empty', 'ids')); }

删除部分解析 这里是当数据表中数据删除的时候,我们也应该删除索引数据库里面的数据

$search->del($ids);

至此从fastadmin中添加/编辑/删除的操作,全部会同步到题库系统中. 重要提示:在fastadmin控制台只能一条一条的插入题库,因为导入的代码并未修改,所以导入进去的数据是无法查询的 这里id不一致是因为添加的时候id没有+1,上面代码未修改此问题,请自行修改[添加]部分代码.

(三).接口搭建

因为一个一个导入真的是太慢了. 我这边解决方案就是搭建一个接口,通过接口上传题目 我这边创建了一个新的接口,如果是小白,可以把接口搭建在demo中 同时将接口鉴权关闭 加入题目函数

public function insertans() { $search = addonsxunsearchlibraryXunsearch::instance("souti"); $title = $this->request->request('title'); $body = $this->request->request('body'); $ans = $this->request->request('ans'); $lastid = Db::table('sou_tiku')->where('id>0')->max('id'); $data = ['title' => $title, 'body' => $body , 'ans' => $ans]; Db::startTrans(); try { Db::table('sou_tiku')->insert($data); Db::commit(); $sdata = [ 'id'=>$lastid, 'title'=>"[ID".$lastid."]:".$title, 'body'=>$body, 'ans'=> $ans ]; $search->add($sdata); } catch (ValidateException $e) { Db::rollback(); $this->error($e->getMessage()); } catch (PDOException $e) { Db::rollback(); $this->error($e->getMessage()); } catch (Exception $e) { Db::rollback(); $this->error($e->getMessage()); } $this->success('返回成功',$res); //Db::table('sou_tiku')->insert($data); }

搜索题目返回函数

public function searchans() { $que = $this->request->request('q'); $search = addonsxunsearchlibraryXunsearch::instance("souti"); $res = $search->search($que,1,10); $this->success('返回成功',$res); }

如果你实在不会写,请在该目录下创建sou.php 并加入以下代码

<?phpnamespace appapicontroller;use appcommoncontrollerApi;use thinkDb;class Sou extends Api{ //如果$noNeedLogin为空表示所有接口都需要登录才能请求 //如果$noNeedRight为空表示所有接口都需要验证权限才能请求 //如果接口已经设置无需登录,那也就无需鉴权了 // // 无需登录的接口,*表示全部 protected $noNeedLogin = ['searchans','insertans']; // 无需鉴权的接口,*表示全部 protected $noNeedRight = []; public function insertans() { $search = addonsxunsearchlibraryXunsearch::instance("souti"); $title = $this->request->request('title'); $body = $this->request->request('body'); $ans = $this->request->request('ans'); $lastid = Db::table('sou_tiku')->where('id>0')->max('id'); $data = ['title' => $title, 'body' => $body , 'ans' => $ans]; Db::startTrans(); try { Db::table('sou_tiku')->insert($data); Db::commit(); $sdata = [ 'id'=>$lastid, 'title'=>"[ID".$lastid."]:".$title, 'body'=>$body, 'ans'=> $ans ]; $search->add($sdata); } catch (ValidateException $e) { Db::rollback(); $this->error($e->getMessage()); } catch (PDOException $e) { Db::rollback(); $this->error($e->getMessage()); } catch (Exception $e) { Db::rollback(); $this->error($e->getMessage()); } $this->success('返回成功',$res); //Db::table('sou_tiku')->insert($data); } public function searchans() { $que = $this->request->request('q'); $search = addonsxunsearchlibraryXunsearch::instance("souti"); $res = $search->search($que,1,10); $this->success('返回成功',$res); }}

具体代码含义,请自行查询thinkphp

(四).接口测试 1.插入题目

调用网址:https://你的网站/api/sou/insertans?title=&body=&ans= 中文必须进行url编码,可以使用get或者post进行提交,title为题目,body为选项,ans为答案 具体字段可以自行修改

2.查询题目

调用网址:http://你的网站/api/sou/searchans?q="zg" 返回的是一段json代码,可以根据需求自己解析使用

总结

搭建比较繁琐,新手建议先看fastadmin官方给的教程,bilibili上也有的 小白请先看上面教程,不然会安装到你崩溃 看完前几集其实就差不多了,可以对比此教程看视频,学会控制器修改,api接口即可搭建 在thinkphp方面作者也是个小白,教程中一些地方写的并不是很标准,目的只是搭建能够查询的题库,更安全更标准的搭建方式,请自行探索


fastadmin+xunsearch题库系统搭建教程拓展阅读

fastadmin+xunsearch题库系统搭建教程(fastadmin+微信小程序开发:todolist开发准备)

fastadmin+xunsearch题库系统搭建教程 前言一、开始整活二、开始搭建1.fastadmin配置2.xunsearch服务端安装(一).opens....
以上就是关于fastadmin+xunsearch题库系统搭建教程(fastadmin+微信小程序开发:todolist开发准备)的所有内容,希望对你学习有所帮助。

标签: fastadmin+xunsearch题库系统搭建教程

【免责声明】本站所有文章(含图片和视频)由网站用户自行上传发布,平台仅提供信息存储服务,并不代表本站立场和观点,若有侵犯你的权利,请及时联系我们删除。
Copyright © 2016-2020 shuguohai.com All Rights Reserved. 皖ICP备2022016496号-4