This commit is contained in:
Alone
2024-09-14 15:10:43 +08:00
parent 6c64bbd82a
commit 610dee88cd
4241 changed files with 0 additions and 622695 deletions
-22
View File
@@ -1,22 +0,0 @@
<?php
declare (strict_types = 1);
namespace app;
use think\Service;
/**
* 应用服务类
*/
class AppService extends Service
{
public function register()
{
// 服务注册
}
public function boot()
{
// 服务启动
}
}
-58
View File
@@ -1,58 +0,0 @@
<?php
namespace app;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\Response;
use Throwable;
/**
* 应用异常处理类
*/
class ExceptionHandle extends Handle
{
/**
* 不需要记录信息(日志)的异常类列表
* @var array
*/
protected $ignoreReport = [
HttpException::class,
HttpResponseException::class,
ModelNotFoundException::class,
DataNotFoundException::class,
ValidateException::class,
];
/**
* 记录异常信息(包括日志或者其它方式记录)
*
* @access public
* @param Throwable $exception
* @return void
*/
public function report(Throwable $exception): void
{
// 使用内置的方式记录异常日志
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @access public
* @param \think\Request $request
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
{
// 添加自定义异常处理机制
// 其他错误交给系统处理
return parent::render($request, $e);
}
}
-8
View File
@@ -1,8 +0,0 @@
<?php
namespace app;
// 应用请求对象类
class Request extends \think\Request
{
}
-679
View File
@@ -1,679 +0,0 @@
<?php
declare(strict_types=1);
namespace app\admin;
use think\App;
use think\facade\View;
use app\model\Admin as AdminModel;
use app\model\Access as AccessModel;
use app\model\Auth as AuthModel;
use app\model\Node as NodeModel;
use app\model\Group as GroupModel;
use app\model\Conf as ConfModel;
/**
* 控制器基础类
*/
abstract class QfShop
{
protected $model = null;
//搜索字段
protected $selectList = '*';
protected $selectDetail = '*';
//筛选字段
protected $searchFilter = [];
//更新字段
protected $updateFields = [];
//更新时的必须字段
protected $updateRequire = [];
//添加字段
protected $insertFields = [];
//添加时的必须字段
protected $insertRequire = [];
//excel查询字段 用来查询
protected $excelField = [
"join_id" => "编号",
];
//excel 表头
protected $excelTitle = "数据导出表";
//EXCEL 单元格字母
protected $excelCells = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'AA', 'AB', 'AC', 'AD'];
//主键key
protected $pk = '';
//表名称
protected $table = '';
//主键value
protected $pk_value = 0;
//模型
protected $adminModel;
protected $accessModel;
protected $authModel;
protected $nodeModel;
protected $groupModel;
protected $confModel;
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
protected $plat = 'all';
protected $version = 0;
protected $module;
protected $controller;
protected $action;
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 控制器初始化
$this->initialize();
}
//TODO !!!如有特殊需求请重写下面的方法到子类,请勿修改此处!!! BEGIN.........//
/**
* 添加接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function add()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
//校验Insert字段是否填写
$error = $this->validateInsertFields();
if ($error) {
return $error;
}
//从请求中获取Insert数据
$data = $this->getInsertDataFromRequest();
//添加这行数据
$this->insertRow($data);
return jok('添加成功');
}
/**
* 修改接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function update()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "参数必须填写", 400);
}
//根据主键获取一行数据
$item = $this->getRowByPk();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
//校验Update字段是否填写
$error = $this->validateUpdateFields();
if ($error) {
return $error;
}
//从请求中获取Update数据
$data = $this->getUpdateDataFromRequest();
//根据主键更新这条数据
$this->updateByPk($data);
return jok('修改成功');
}
/**
* 禁用接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function disable()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "参数必须填写", 400);
}
if (isInteger($this->pk_value)) {
//根据主键获取一行数据
$item = $this->getRowByPk();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
//单个操作
$this->disableBySingle();
} else {
//批量操作
$this->disableByMultiple();
}
return jok("禁用成功");
}
/**
* 启用接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function enable()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "参数必须填写", 400);
}
if (isInteger($this->pk_value)) {
//根据主键获取一行数据
$item = $this->getRowByPk();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
//单个操作
$this->enableBySingle();
} else {
//批量操作
$this->enableByMultiple();
}
return jok("启用成功");
}
/**
* 删除接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function delete()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "必须填写", 400);
}
if (isInteger($this->pk_value)) {
//根据主键获取一行数据
$item = $this->getRowByPk();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
//单个操作
$this->deleteBySingle();
} else {
//批量操作
$this->deleteByMultiple();
}
return jok('删除成功');
}
/**
* 获取列表接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function getList()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
//从请求中获取筛选数据的数组
$map = $this->getDataFilterFromRequest();
//从请求中获取排序方式
$order = $this->getorderfromRequest();
//设置Model中的 per_page
$this->setGetListPerPage();
//查询数据
$dataList = $this->model->getListByPage($map, $order, $this->selectList);
return jok('数据获取成功', $dataList);
}
/**
* 获取详情基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function detail()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "必须填写", 400);
}
//根据主键获取一行数据
$item = $this->getRowByPk();
if (empty($item)) {
return jerr("没有查询到数据", 404);
}
return jok('数据加载成功', $item);
}
/**
* 导出Excel基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function excel()
{
$error = $this->access();
if ($error) {
return $error;
}
$this->exportExcelData();
}
// !!!如有特殊需求请重写下面的方法到子类,请勿修改此处!!! END.........//
// 初始化
protected function initialize()
{
$this->module = "api";
$this->controller = $this->request->controller() ? $this->request->controller() : "Index";
$this->action = strtolower($this->request->action()) ? strtolower($this->request->action()) : "index";
View::assign('controller', strtolower($this->controller));
View::assign('action', strtolower($this->action));
$this->table = strtolower($this->controller);
$this->pk = $this->table . "_id";
$this->pk_value = input($this->pk);
$this->adminModel = new AdminModel();
$this->accessModel = new AccessModel();
$this->authModel = new AuthModel();
$this->nodeModel = new NodeModel();
$this->groupModel = new GroupModel();
$this->confModel = new ConfModel();
$configs = $this->confModel->select()->toArray();
$c = [];
foreach ($configs as $config) {
$c[$config['conf_key']] = $config['conf_value'];
}
config($c, 'qfshop');
}
/**
* 检测授权
*
* @return void
*/
protected function access()
{
if (!input("plat")) {
return jerr("plat参数为必须", 400);
}
$this->plat = input('plat');
if (!input("version")) {
return jerr("version参数为必须", 400);
}
$this->version = input('version');
if (!input("access_token")) {
return jerr("AccessToken为必要参数", 400);
}
$access_token = input("access_token");
$this->admin = $this->adminModel->getAdminByAccessToken($access_token);
if (!$this->admin) {
return jerr("登录过期,请重新登录", 401);
}
if ($this->admin['admin_status'] == 1) {
return jerr("你的账户被禁用,登录失败", 401);
}
}
/**
* 从请求中获取Request数据
*
* @return void
*/
protected function getInsertDataFromRequest()
{
$data = [];
foreach (input('post.') as $k => $v) {
if (in_array($k, $this->insertFields)) {
$data[$k] = $v;
}
}
return $data;
}
/**
* 校验Insert的字段
*
* @return void
*/
protected function validateInsertFields()
{
foreach ($this->insertRequire as $k => $v) {
if (!input($k)) {
return jerr($v, 400);
}
}
return null;
}
/**
* 从请求中获取Update数据
*
* @return void
*/
protected function getUpdateDataFromRequest()
{
$data = [];
foreach (input('post.') as $k => $v) {
if (in_array($k, $this->updateFields)) {
$data[$k] = $v;
}
}
return $data;
}
/**
* 校验Update的字段
*
* @return void
*/
protected function validateUpdateFields()
{
foreach ($this->updateRequire as $k => $v) {
if (!input($k)) {
return jerr($v, 400);
}
}
return null;
}
/**
* 按主键集合批量禁用 1,2,3,4
*
* @return void
*/
protected function disableByMultiple()
{
$list = explode(',', $this->pk_value);
$this->model->where($this->pk, 'in', $list)->update([
$this->table . "_status" => 1,
$this->table . "_updatetime" => time(),
]);
}
/**
* 单个禁用 可传入自定义$map
* 默认按主键ID禁用
*
* @param array $map
* @return void
*/
protected function disableBySingle($map = null)
{
if ($map == null) {
$map = [$this->pk => $this->pk_value];
}
$this->model->where($map)->update([
$this->table . "_status" => 1,
$this->table . "_updatetime" => time(),
]);
}
/**
* 按主键集合批量启用 1,2,3,4
*
* @return void
*/
protected function enableByMultiple()
{
$list = explode(',', $this->pk_value);
$this->model->where($this->pk, 'in', $list)->update([
$this->table . "_status" => 0,
$this->table . "_updatetime" => time(),
]);
}
/**
* 单个启用 可传入自定义$map
* 默认按主键ID启用
*
* @param array $map
* @return void
*/
protected function enableBySingle($map = null)
{
if ($map == null) {
$map = [$this->pk => $this->pk_value];
}
$this->model->where($map)->update([
$this->table . "_status" => 0,
$this->table . "_updatetime" => time(),
]);
}
/**
* 按主键集合批量删除1,2,3,4
*
* @return void
*/
protected function deleteByMultiple()
{
$list = explode(',', $this->pk_value);
$this->model->where($this->pk, 'in', $list)->delete();
}
/**
* 单个删除 默认主键ID
*
* @param array $map
* @return void
*/
protected function deleteBySingle($map = null)
{
if ($map == null) {
$map = [$this->pk => $this->pk_value];
}
$this->model->where($map)->delete();
}
/**
* 根据主键ID获取一行数据
*
* @param int|null 主键ID
* @return array|null
*/
protected function getRowByPk($pk_value = null)
{
if (!$pk_value) {
$pk_value = $this->pk_value;
}
$item = $this->model->where($this->pk, $pk_value)->field($this->selectDetail)->find();
return $item ? $item->toArray() : null;
}
/**
* 根据主键ID更新数据
*
* @param array 需要更新的KV数组
* @param int|null 主键ID 默认$this->pk_value
* @param bool 是否更新_updatetime字段 默认TRUE
* @return void
*/
protected function updateByPk($data, $pk_value = null, $auto_updatetime = true)
{
if (!$pk_value) {
$pk_value = $this->pk_value;
}
if ($auto_updatetime) {
$data[$this->table . "_updatetime"] = time();
}
$this->model->where($this->pk, $this->pk_value)->update($data);
}
/**
* 添加一行数据
*
* @param array 需要添加的KV数组
* @param bool 是否自动记录_createtime和_updatetime字段 默认true
* @return int 添加返回的主键ID
*/
protected function insertRow($data, $auto_inserttime = true)
{
if ($auto_inserttime) {
$data[$this->table . "_updatetime"] = time();
$data[$this->table . "_createtime"] = time();
} else {
$data[$this->table . "_updatetime"] = 0;
$data[$this->table . "_createtime"] = 0;
}
$id = $this->model->insertGetId($data);
return $id;
}
/**
* 从请求中获取查询排序(默认主键DESC)
*
* @return void
*/
protected function getOrderFromRequest()
{
if (input('order')) {
$order = urldecode(input('order'));
} else {
$order = strtolower($this->controller) . "_id desc";
}
return $order;
}
/**
* 设置分页查询每页数量
*
* @param int|null 每页数量
* @return void
*/
protected function setGetListPerPage($per_page = null)
{
if ($per_page) {
$this->model->per_page = intval($per_page);
} else if (input('per_page')) {
$this->model->per_page = input('per_page');
} else {
$this->model->per_page = 10;
}
}
/**
* 获取查询列表的Where参数
*
* @return array
*/
protected function getDataFilterFromRequest()
{
$map = [];
$filter = input('post.');
foreach ($filter as $k => $v) {
if ($k == 'filter') {
$k = input('filter');
$v = input('keyword');
}
if ($v === '' || $v === null) {
continue;
}
if (array_key_exists($k, $this->searchFilter)) {
switch ($this->searchFilter[$k]) {
case "like":
array_push($map, [$k, 'like', "%" . $v . "%"]);
break;
case "=":
array_push($map, [$k, '=', $v]);
break;
default:
}
}
}
return $map;
}
protected function getExcelFields()
{
$excelField = [];
foreach ($this->excelField as $k => $v) {
if ($k == "*") {
continue;
} else {
array_push($excelField, [
$k, $v
]);
}
}
return $excelField;
}
/**
* 导出Excel
*
* @return string 下载文件名
*/
protected function exportExcelData($data)
{
$datalist = $data ? $data->toArray() : [];
$excelField = $this->getExcelFields();
$PHPExcel = new \PHPExcel(); //实例化
$PHPExcel
->getProperties() //获得文件属性对象,给下文提供设置资源
->setCreator("qfshop") //设置文件的创建者
->setLastModifiedBy("qfshop") //设置最后修改者
->setDescription("Export by qfshop"); //设置备注
$PHPSheet = $PHPExcel->getActiveSheet();
if (count($excelField) > count($this->excelCells)) {
echo 'Error and you need check Excel Cells Keys...';
die;
}
$PHPSheet->getRowDimension(1)->setRowHeight(30);
for ($column = 0; $column < count($excelField); $column++) {
$PHPSheet->setCellValue($this->excelCells[$column] . "1", $excelField[$column][1]);
$PHPSheet->getStyle($this->excelCells[$column])->getNumberFormat()
->setFormatCode(\PHPExcel_Style_NumberFormat::FORMAT_TEXT);
for ($line = 0; $line < count($datalist); $line++) {
$string = $datalist[$line][$excelField[$column][0]];
$PHPSheet->getColumnDimension($this->excelCells[$column])->setWidth(20);
$PHPSheet->setCellValueExplicit($this->excelCells[$column] . ($line + 2), $string, \PHPExcel_Cell_DataType::TYPE_STRING);
}
}
//***********************画出单元格边框*****************************
$styleArray = array(
);
$PHPSheet->getStyle('A2:' . $this->excelCells[count($excelField) - 1] . (count(
$datalist
) + 2))->applyFromArray($styleArray);
//***********************画出单元格边框结束*****************************
//设置全部居中对齐
$PHPSheet->getStyle('A1:' . $this->excelCells[count($excelField) - 1] . (count(
$datalist
) + 2))->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_CENTER)->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER)->setVertical(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
//设置全部字体
$PHPSheet->getStyle('A1:' . $this->excelCells[count($excelField) - 1] . (count(
$datalist
) + 2))->getFont()->setName('微软雅黑');
$PHPWriter = \PHPExcel_IOFactory::createWriter($PHPExcel, "Excel2007"); //创建生成的格式
header('Content-Disposition: attachment;filename="' . $this->excelTitle . "_" . date('Y-m-d_H:i:s') . '.xlsx"'); //下载下来的表格名
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
$PHPWriter->save("php://output"); //表示在$path路径下面生成demo.xlsx文件
exit;
return $this->excelTitle . "_" . date('Y-m-d_H:i:s') . '.xlsx"';
}
public function __call($method, $args)
{
return jerr("访问异常", 404);
}
}
-480
View File
@@ -1,480 +0,0 @@
<?php
namespace app\admin\controller;
use think\App;
use app\admin\QfShop;
use app\model\Admin as model;
use app\model\Sms as SmsModel;
use app\model\Validate as ValidateModel;
class Admin extends QfShop
{
public function __construct(App $app)
{
parent::__construct($app);
//查询字段
$this->selectList = "*";
$this->selectDetail = "*";
//筛选字段
$this->searchFilter = [
"admin_id" => "=",
"admin_account" => "like",
"admin_name" => "like",
"admin_truename" => "like",
"admin_status" => "=",
];
$this->insertFields = [
"admin_account", "admin_password", "admin_name", "admin_idcard", "admin_email", "admin_group", "admin_truename"
];
$this->updateFields = [
"admin_account", "admin_password", "admin_name", "admin_idcard", "admin_email", "admin_group", "admin_truename"
];
$this->insertRequire = [
'admin_name' => "用户昵称必须填写",
'admin_account' => "用户帐号必须填写",
'admin_password' => "密码必须填写",
'admin_group' => "用户组必须填写",
];
$this->updateRequire = [
'admin_name' => "用户昵称必须填写",
'admin_account' => "用户帐号必须填写",
'admin_group' => "用户组必须填写",
];
$this->excelField = [
"id" => "编号",
"account" => "帐号",
"name" => "昵称",
"idcard" => "身份证",
"email" => "邮箱",
"createtime" => "创建时间",
"updatetime" => "修改时间"
];
$this->model = new model();
}
public function add()
{
$error = $this->access();
if ($error) {
return $error;
}
$error = $this->validateInsertFields();
if ($error) {
return $error;
}
$data = $this->getInsertDataFromRequest();
$data['admin_ipreg'] = "127.0.0.1";
$admin = $this->model->getAdminByAccount($data["admin_account"]);
if ($admin) {
return jerr("帐号已存在,请重新输入");
}
$salt = getRandString(4);
$password = $data["admin_password"];
$password = encodePassword($password, $salt);
$data["admin_salt"] = $salt;
$data["admin_password"] = $password;
$this->insertRow($data);
return jok('用户添加成功');
}
public function update()
{
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "必须填写", 400);
}
if (!isInteger($this->pk_value)) {
return jerr("修改失败,参数错误", 400);
}
$item = $this->model->where($this->pk, $this->pk_value)->find();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
if (intval($this->pk_value) == 1) {
return jerr("无法修改超管用户信息");
}
foreach ($this->updateRequire as $k => $v) {
if (!input($k)) {
return jerr($v);
}
}
$data = [];
foreach (input('post.') as $k => $v) {
if (in_array($k, $this->updateFields)) {
$data[$k] = $v;
}
}
$admin = $this->model->getAdminByAccount($data["admin_account"]);
if ($admin && $admin[$this->pk] != $item[$this->pk]) {
return jerr("帐号已存在,请重新输入");
}
if (input('new_password')) {
//设置密码
$salt = getRandString(4);
$password = input('new_password');
$password = encodePassword($password, $salt);
$data["admin_salt"] = $salt;
$data["admin_password"] = $password;
}
if ($this->admin['admin_group'] != 1) {
//除超级管理员组外 其他任何组不允许修改用户组
unset($data['admin_group']);
}
$data[$this->table . "_updatetime"] = time();
$this->model->where($this->pk, $this->pk_value)->update($data);
return jok('用户信息更新成功');
}
/**
* 禁用用户
*
* @return void
*/
public function disable()
{
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "参数必须填写", 400);
}
if (isInteger($this->pk_value)) {
$map = [$this->pk => $this->pk_value];
$item = $this->model->where($map)->find();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
if ($item["admin_group"] == 1) {
return jerr("超级管理员不允许操作!");
}
$this->model->where($map)->update([
$this->table . "_status" => 1,
$this->table . "_updatetime" => time(),
]);
} else {
$list = explode(',', $this->pk_value);
$this->model->where($this->pk, 'in', $list)->where("admin_group > 1")->update([
$this->table . "_status" => 1,
$this->table . "_updatetime" => time(),
]);
}
return jok("禁用用户成功");
}
/**
* 启用用户
*
* @return void
*/
public function enable()
{
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "参数必须填写", 400);
}
if (isInteger($this->pk_value)) {
$map = [$this->pk => $this->pk_value];
$item = $this->model->where($map)->find();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
if ($item["admin_group"] == 1) {
return jerr("超级管理员不允许操作!");
}
$this->model->where($map)->update([
$this->table . "_status" => 0,
$this->table . "_updatetime" => time(),
]);
} else {
$list = explode(',', $this->pk_value);
$this->model->where($this->pk, 'in', $list)->where("admin_group > 1")->update([
$this->table . "_status" => 0,
$this->table . "_updatetime" => time(),
]);
}
return jok("启用用户成功");
}
/**
* 删除用户
*
* @return void
*/
public function delete()
{
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "必须填写", 400);
}
if (isInteger($this->pk_value)) {
$map = [$this->pk => $this->pk_value];
$item = $this->model->where($map)->find();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
//
if ($item["admin_group"] == 1) {
return jerr("超级管理员不允许操作!");
}
$this->model->where($map)->delete();
} else {
$list = explode(',', $this->pk_value);
//批量删除只允许删除用户组不为1的用户
$this->model->where($this->pk, 'in', $list)->where("admin_group > 1")->delete();
}
return jok('删除用户成功');
}
public function detail()
{
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "必须填写", 400);
}
$item = $this->model->field($this->selectDetail)->where($this->pk, $this->pk_value)->find();
if (empty($item)) {
return jerr("没有查询到数据", 404);
}
return jok('数据加载成功', $item);
}
public function getList()
{
$error = $this->access();
if ($error) {
return $error;
}
$map = [];
$filter = input('post.');
foreach ($filter as $k => $v) {
if ($k == 'filter') {
$k = input('filter');
$v = input('keyword');
}
if ($v === '' || $v === null) {
continue;
}
if (array_key_exists($k, $this->searchFilter)) {
switch ($this->searchFilter[$k]) {
case "like":
array_push($map, [$k, 'like', "%" . $v . "%"]);
break;
case "=":
array_push($map, [$k, '=', $v]);
break;
default:
}
}
}
$order = strtolower($this->controller) . "_id desc";
if (input('order')) {
$order = urldecode(input('order'));
}
if (input('per_page')) {
$this->model->per_page = intval(input('per_page'));
}
$dataList = $this->model->getListByPage($map, $order, $this->selectList);
return jok('用户列表获取成功', $dataList);
}
public function login()
{
if (!input("admin_account")) {
return jerr('请确认帐号是否正确填写', 400);
}
if (!input("admin_password")) {
return jerr('请确认密码是否正确填写', 400);
}
if (!input("admin_code")) {
return jerr('请确认图形验证码是否填写', 400);
}
$plat = input("plat");
$admin_account = input("admin_account");
$admin_password = input("admin_password");
//验证图形验证码
$validateModel = new ValidateModel();
$error = $validateModel->validateImgCode(input('token'), input('admin_code'));
if ($error) {
return jerr('验证码错误', 400);
}
//登录获取用户信息
$admin = $this->model->login($admin_account, $admin_password);
if ($admin) {
//创建一个新的授权
$access = $this->accessModel->createAccess($admin['admin_id'], $plat);
if ($access) {
setCookie('access_token', $access['access_token'], time() + 3600, '/');
return jok('登录成功', ['access_token' => $access['access_token']]);
} else {
return jerr('登录系统异常');
}
} else {
return jerr('帐号或密码错误');
}
}
/**
* 退出登录
*
* @return void
*/
public function logout()
{
$access_token = input("access_token");
cookie('access_token', null);
$this->accessModel->where('access_token', $access_token)->update(["access_status" => 1]);
return jok('已退出登录');
}
/**
* 用户注册接口
*
* @return void
*/
public function reg()
{
if (!input("phone")) {
return jerr("手机号不能为空!", 400);
}
$phone = input("phone");
if (!input("code")) {
return jerr("短信验证码不能为空!", 400);
}
$code = input("code");
if (!input("password")) {
return jerr("密码不能为空!", 400);
}
$password = input("password");
$name = $phone;
if (input("name")) {
$name = input("name");
}
$smsModel = new SmsModel();
if ($smsModel->validSmsCode($phone, $code)) {
$admin = $this->model->where([
"admin_account" => $phone
])->find();
if ($admin) {
return jerr("该手机号已经注册!");
}
$result = $this->model->reg($phone, $password, $name);
if ($result) {
return jok("用户注册成功");
} else {
return jerr("注册失败,请重试!");
}
} else {
return jerr("短信验证码已过期,请重新获取");
}
}
public function motifyPassword()
{
$error = $this->access();
if ($error) {
return $error;
}
if (!input("oldPassword")) {
return jerr("你必须要输入你的原密码!", 400);
}
if (!input("newPassword")) {
return jerr("你必须输入一个新的密码!", 400);
}
$old_password = input("oldPassword");
$new_password = input("newPassword");
if (strlen($new_password) < 6 || strlen($new_password) > 16) {
return jerr("新密码因为6-16位!");
}
if ($this->admin['admin_password'] != encodePassword($old_password, $this->admin['admin_salt'])) {
return jerr("原密码输入不正确,请重试!");
}
$result = $this->model->motifyPassword($this->admin['admin_id'], $new_password);
if ($result) {
return jok("密码已重置,请使用新密码登录");
} else {
return jerr("注册失败,请重试!");
}
}
/**
* 重置密码
*
* @return void
*/
public function resetPassword()
{
if (!input("phone")) {
return jerr("手机号不能为空!", 400);
}
if (!input("code")) {
return jerr("短信验证码不能为空!", 400);
}
if (!input("password")) {
return jerr("密码不能为空!", 400);
}
$phone = input("phone");
$code = input("code");
$password = input("password");
$smsModel = new SmsModel();
if ($smsModel->validSmsCode($phone, $code)) {
$admin = $this->model->where([
"admin_account" => $phone
])->find();
if (!$admin) {
return jerr("该手机号尚未注册!", 404);
}
$result = $this->model->motifyPassword($admin['admin_id'], $password);
if ($result) {
return jok("密码已重置,请使用新密码登录");
} else {
return jerr("注册失败,请重试!");
}
} else {
return jerr("短信验证码已过期,请重新获取");
}
}
/**
* 获取我的信息
*
* @return void
*/
public function getMyInfo()
{
$error = $this->access();
if ($error) {
return $error;
}
$myInfo = $this->admin;
foreach (['admin_password', 'admin_salt', 'admin_accesstoken', 'admin_tokentime', 'admin_status'] as $key) {
unset($myInfo[$key]);
}
return jok('数据获取成功', $myInfo);
}
public function updateMyInfo()
{
$error = $this->access();
if ($error) {
return $error;
}
if (!input("admin_name")) {
return jerr("你确定飘到连名字都可以不要了吗?", 400);
}
$data = [
"admin_name" => input("admin_name"),
"admin_truename" => input("admin_truename"),
"admin_email" => input("admin_email"),
"admin_idcard" => input("admin_idcard"),
];
$this->model->where("admin_id", $this->admin['admin_id'])->update($data);
return jok("资料更新成功");
}
}
-221
View File
@@ -1,221 +0,0 @@
<?php
namespace app\admin\controller;
use think\App;
use think\facade\Filesystem;
use think\exception\ValidateException;
use app\admin\QfShop;
use app\model\Attach as AttachModel;
class Attach extends QfShop
{
public function __construct(App $app)
{
parent::__construct($app);
//筛选字段
$this->searchFilter = [
"attach_id" => "=", //相同筛选
"attach_key" => "like", //相似筛选
"attach_value" => "like", //相似筛选
"attach_desc" => "like", //相似筛选
"attach_readonly" => "=", //相似筛选
];
$this->model = new AttachModel();
}
/**
* 上传图片
*
* @return void
*/
public function uploadImage()
{
$error = $this->access();
if ($error) {
return $error;
}
try {
$file = request()->file('file');
try {
validate(['file' => 'filesize:' . config("qfshop.upload_max_image") . '|fileExt:' . config("qfshop.upload_image_type")])
->check(['file' => $file]);
$saveName = Filesystem::putFile('image', $file);
$attach_data = array(
'attach_path' => "/uploads/".$saveName,
'attach_name' => $file->getOriginalName(),
'attach_type' => $file->extension(),
'attach_size' => $file->getSize(),
'attach_admin' => $this->admin['admin_id']
);
$attach_id = $this->insertRow($attach_data);
$attach_data = $this->getRowByPk($attach_id);
if (input("?extend")) {
$attach_data['extend'] = input("extend");
}
return jok('上传成功!', $attach_data);
} catch (ValidateException $e) {
return jerr($e->getMessage());
}
} catch (\Exception $error) {
return jerr('上传文件失败,请检查你的文件!');
}
}
/**
* 删除图片
*
* @return void
*/
public function delete()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "必须填写", 400);
}
if (isInteger($this->pk_value)) {
//根据主键获取一行数据
$item = $this->getRowByPk();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
//单个操作
$map = [$this->pk => $this->pk_value];
$res = $this->model->where($map)->delete();
if($res){
try {
unlink("./uploads/".$item['attach_path']);
} catch (\Throwable $th) {
//throw $th;
}
}
} else {
//批量操作
$list = explode(',', $this->pk_value);
foreach ($list as $key => $value) {
$item = $this->model->where("attach_id",$value)->find();
if($item){
try {
unlink("./uploads/".$item['attach_path']);
} catch (\Throwable $th) {
//throw $th;
}
}
}
$this->model->where($this->pk, 'in', $list)->delete();
}
return jok('删除成功');
}
/**
* 上传文件
*
* @return void
*/
public function uploadFile()
{
$error = $this->access();
if ($error) {
return $error;
}
try {
$file = request()->file('file');
try {
validate(['file' => 'filesize:' . config("qfshop.upload_max_file") . '|fileExt:' . config("qfshop.upload_file_type")])
->check(['file' => $file]);
$saveName = Filesystem::putFile('normal', $file);
$attach_data = array(
'attach_path' => $saveName,
'attach_type' => $file->extension(),
'attach_size' => $file->getSize(),
'attach_admin' => $this->admin['admin_id']
);
$attach_id = $this->insertRow($attach_data);
$attach_data = $this->getRowByPk($attach_id);
if (input("?extend")) {
$attach_data['extend'] = input("extend");
}
return jok('上传成功!', $attach_data);
} catch (ValidateException $e) {
return jerr($e);
}
} catch (\Exception $error) {
return jerr('上传文件失败,请检查你的文件!');
}
}
/**
* 富文本上传图片
*
* @return void
*/
public function uploads()
{
header("Content-Type: text/html; charset=utf-8");
$error = $this->access();
if ($error) {
return $error;
}
$CONFIG = json_decode(preg_replace("/\/\*[\s\S]+?\*\//", "", file_get_contents("./static/admin/UEditor/config.json")), true);
$action = $_GET['action'];
switch ($action) {
case 'config':
$result = json_encode($CONFIG);
break;
/* 上传图片 */
case 'uploadimage':
/* 上传涂鸦 */
case 'uploadscrawl':
/* 上传视频 */
case 'uploadvideo':
/* 上传文件 */
case 'uploadfile':
try {
$file = request()->file('upfile');
try {
validate(['file' => 'filesize:' . config("qfshop.upload_max_image") . '|fileExt:' . config("qfshop.upload_image_type")])
->check(['file' => $file]);
$saveName = Filesystem::putFile('normal', $file);
$result = json_encode(array(
'original'=> $file->getOriginalName(),
'state'=> "SUCCESS",
'title'=> $file->getOriginalName(),
'url'=> "/uploads/".$saveName,
'type'=> $file->extension(),
));
} catch (ValidateException $e) {
$result = json_encode(array(
'state'=> $e->getMessage()
));
}
} catch (\Exception $error) {
$result = json_encode(array(
'state'=> '上传文件失败,请检查你的文件!'
));
}
break;
default:
$result = json_encode(array(
'state'=> '请求地址出错'
));
break;
}
/* 输出结果 */
if (isset($_GET["callback"])) {
if (preg_match("/^[\w_]+$/", $_GET["callback"])) {
echo htmlspecialchars($_GET["callback"]) . '(' . $result . ')';
} else {
echo json_encode(array(
'state'=> 'callback参数不合法'
));
}
} else {
echo $result;
}
die;
}
}
-35
View File
@@ -1,35 +0,0 @@
<?php
namespace app\admin\controller;
use think\App;
use app\admin\QfShop;
use app\model\Auth as AuthModel;
class Auth extends QfShop
{
public function __construct(App $app)
{
parent::__construct($app);
//筛选字段
$this->searchFilter = [
"auth_id" => "=", //相同筛选
];
$this->model = new AuthModel();
}
/**
* 清除访问日志
*
* @return void
*/
public function clean()
{
$error = $this->access();
if ($error) {
return $error;
}
$this->model->cleanAuth();
return jok('授权信息清理成功');
}
}
-205
View File
@@ -1,205 +0,0 @@
<?php
namespace app\admin\controller;
use think\App;
use app\admin\QfShop;
use app\model\Conf as ConfModel;
class Conf extends QfShop
{
public function __construct(App $app)
{
parent::__construct($app);
//筛选字段
$this->searchFilter = [
"conf_id" => "=", //相同筛选
"conf_key" => "like", //相似筛选
"conf_value" => "like", //相似筛选
"conf_title" => "like", //相似筛选
"conf_status" => "=", //相同筛选
"conf_type" => "=", //相同筛选
];
$this->insertFields = [
"conf_key", "conf_value", "conf_title", "conf_desc", "conf_status", "conf_type", "conf_spec", "conf_content", "conf_sort", "conf_system"
];
$this->updateFields = [
"conf_key", "conf_value", "conf_title", "conf_desc", "conf_status", "conf_type", "conf_spec", "conf_content", "conf_sort", "conf_system"
];
$this->insertRequire = [
'conf_title' => "参数名称必须填写",
'conf_key' => "参数字段必须填写",
];
$this->updateRequire = [
'conf_title' => "参数名称必须填写",
'conf_key' => "参数字段必须填写",
];
$this->model = new ConfModel();
}
/**
* 获取列表接口基类
*
* @return void
*/
public function getList()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
//从请求中获取筛选数据的数组
$map = $this->getDataFilterFromRequest();
//从请求中获取排序方式
$order = "conf_sort desc, conf_id asc";
//设置Model中的 per_page
$this->setGetListPerPage();
//查询数据
$dataList = $this->model->getListByPage($map, $order, $this->selectList);
return jok('数据获取成功', $dataList);
}
/**
* 读取基本配置
*
* @return void
*/
public function getBaseConfig()
{
$error = $this->access();
if ($error) {
return $error;
}
$datalist = $this->model->where('conf_status', 1)->order("conf_sort desc ".$this->pk . " asc")->select();
foreach ($datalist as $key => $value) {
if($value['conf_content']){
$value['conf_content'] = explode("\n",$value['conf_content']);
}
}
return jok('', $datalist);
}
/**
* 更新基础配置
*
* @return void
*/
public function updateBaseConfig()
{
$error = $this->access();
if ($error) {
return $error;
}
foreach (input("post.") as $k => $v) {
$map["conf_key"] = $k;
$item = $this->model->where($map)->find();
if (empty($item)) {
continue;
}
if(is_array($v)){
$v = implode(",",$v);
}
$this->model->where("conf_key", $k)->update(["conf_value" => $v]);
}
return jok("配置修改成功");
}
/**
* 添加接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function add()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
//校验Insert字段是否填写
$error = $this->validateInsertFields();
if ($error) {
return $error;
}
//从请求中获取Insert数据
$data = $this->getInsertDataFromRequest();
$res = $this->model->where('conf_key',$data['conf_key'])->find();
if ($res) {
return jerr("参数字段已存在");
}
//添加这行数据
$data['conf_value'] = '';
$this->insertRow($data);
return jok('添加成功');
}
/**
* 修改接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function update()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "参数必须填写", 400);
}
//根据主键获取一行数据
$item = $this->getRowByPk();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
//校验Update字段是否填写
$error = $this->validateUpdateFields();
if ($error) {
return $error;
}
//从请求中获取Update数据
$data = $this->getUpdateDataFromRequest();
$res = $this->model->where('conf_key',$data['conf_key'])->find();
if ($res['conf_id']!= input("conf_id") && $res) {
return jerr("参数字段已存在");
}
//根据主键更新这条数据
$this->updateByPk($data);
return jok('修改成功');
}
/**
* 删除接口基类
*
* @return void
*/
public function delete()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "必须填写", 400);
}
if (isInteger($this->pk_value)) {
//根据主键获取一行数据
$item = $this->getRowByPk();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
if($item['conf_system']==1){
return jerr("系统参数,禁止删除", 404);
}
//单个操作
$this->deleteBySingle();
} else {
//批量操作
return jerr("暂不支持批量删除", 400);
}
return jok('删除成功');
}
}
-13
View File
@@ -1,13 +0,0 @@
<?php
namespace app\admin\controller;
use app\admin\QfShop;
class Error extends QfShop
{
public function index()
{
return jerr("admin not found", 404);
}
}
-46
View File
@@ -1,46 +0,0 @@
<?php
namespace app\admin\controller;
use think\App;
use think\facade\Filesystem;
use app\admin\QfShop;
use app\model\Feedback as FeedbackModel;
class Feedback extends QfShop
{
public function __construct(App $app)
{
parent::__construct($app);
//查询列表时允许的字段
$this->selectList = "*";
//查询详情时允许的字段
$this->selectDetail = "*";
$this->model = new FeedbackModel();
}
/**
* 获取列表接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function getList()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
//从请求中获取筛选数据的数组
$map = $this->getDataFilterFromRequest();
//从请求中获取排序方式
$order = $this->getorderfromRequest();
//设置Model中的 per_page
$this->setGetListPerPage();
//查询数据
$dataList = $this->model->getListByPage($map, $order, $this->selectList);
return jok('数据获取成功', $dataList);
}
}
-264
View File
@@ -1,264 +0,0 @@
<?php
namespace app\admin\controller;
use think\App;
use app\admin\QfShop;
use app\model\Group as GroupModel;
class Group extends QfShop
{
public function __construct(App $app)
{
parent::__construct($app);
//筛选字段
$this->searchFilter = [
"group_id" => "=", //相同筛选
"group_name" => "like", //相似筛选
];
$this->insertFields = [
"group_name", "group_desc"
];
$this->updateFields = [
"group_name", "group_desc"
];
$this->insertRequire = [
'group_name' => "组名称必须填写"
];
$this->updateRequire = [
'group_name' => "组名称必须填写"
];
$this->model = new GroupModel();
}
/**
* 修改用户组
*
* @return void
*/
public function update()
{
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "必须填写", 400);
}
if (!isInteger($this->pk_value)) {
return jerr("修改失败,参数错误", 400);
}
$item = $this->model->where($this->pk, $this->pk_value)->find();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
if ($item[$this->pk] == 1) {
return jerr("无法操作超级管理员组信息");
}
foreach ($this->updateRequire as $k => $v) {
if (!input($k)) {
return jerr($v);
}
}
$data = [];
foreach (input('post.') as $k => $v) {
if (in_array($k, $this->updateFields)) {
$data[$k] = $v;
}
}
if (!input($this->table . "_name")) {
return jerr("组名称必须填写", 400);
}
$data[$this->table . "_updatetime"] = time();
$this->model->where($this->pk, $this->pk_value)->update($data);
return jok('用户组信息更新成功');
}
/**
* 禁用用户组
*
* @return void
*/
public function disable()
{
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "参数必须填写", 400);
}
if (isInteger($this->pk_value)) {
$map = [$this->pk => $this->pk_value];
$item = $this->model->where($map)->find();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
if ($item[$this->pk] == 1) {
return jerr("无法操作超级管理员组信息");
}
$this->model->where($map)->update([
$this->table . "_status" => 1,
$this->table . "_updatetime" => time(),
]);
} else {
$list = explode(',', $this->pk_value);
$this->model->where($this->pk, 'in', $list)->where("group_id > 1")->update([
$this->table . "_status" => 1,
$this->table . "_updatetime" => time(),
]);
}
return jok("禁用用户组成功");
}
/**
* 启用用户组
*
* @return void
*/
public function enable()
{
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "参数必须填写", 400);
}
if (isInteger($this->pk_value)) {
$map = [$this->pk => $this->pk_value];
$item = $this->model->where($map)->find();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
if ($item[$this->pk] == 1) {
return jerr("无法操作超级管理员组信息");
}
$this->model->where($map)->update([
$this->table . "_status" => 0,
$this->table . "_updatetime" => time(),
]);
} else {
$list = explode(',', $this->pk_value);
$this->model->where($this->pk, 'in', $list)->where("group_id > 1")->update([
$this->table . "_updatetime" => time(),
]);
}
return jok("启用用户组成功");
}
/**
* 删除用户组
*
* @return void
*/
public function delete()
{
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "必须填写", 400);
}
if (isInteger($this->pk_value)) {
$item = $this->getRowByPk();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
if ($item[$this->pk] == 1) {
return jerr("无法删除超级管理员组");
}
$this->deleteBySingle();
//删除对应ID的授权记录
$this->authModel->where([
"auth_group" => $this->pk_value
])->delete();
} else {
$list = explode(',', $this->pk_value);
$this->model->where($this->pk, 'in', $list)->where("group_id > 1")->delete();
//删除对应ID的授权记录
$this->authModel->where("auth_group", "in", $list)->delete();
}
return jok('删除用户组成功');
}
/**
* 为用户组授权节点
*
* @return void
*/
public function authorize()
{
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "必须填写", 400);
}
if (!isInteger($this->pk_value)) {
return jerr("修改失败,参数错误", 400);
}
$item = $this->getRowByPk();
if (empty($item)) {
return jerr("用户组信息查询失败,授权失败", 404);
}
$this->authModel->where([
"auth_group" => $this->pk_value
])->delete();
if ($item[$this->pk] == 1) {
return jerr("超级管理组无需授权!");
}
$node_ids = explode(",", input("node_ids"));
foreach ($node_ids as $node_id) {
if (intval($node_id) == 0) {
continue;
}
$this->authModel->insert([
"auth_group" => $this->pk_value,
"auth_node" => $node_id,
"auth_createtime" => time(),
"auth_updatetime" => time()
]);
}
return jok('用户组授权成功');
}
/**
* 获取用户组拥有的权限
*
* @return void
*/
public function getAuthorize()
{
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "必须填写", 400);
}
if (!isInteger($this->pk_value)) {
return jerr("修改失败,参数错误", 400);
}
$item = $this->getRowByPk();
if (empty($item)) {
return jerr("用户组信息查询失败,授权失败", 404);
}
$myAuthorizeList = $this->authModel->where("auth_group", $this->pk_value)->select();
return jok('ok', $myAuthorizeList);
}
/**
* 获取所有用户组
*
* @return void
*/
public function getList()
{
$error = $this->access();
if ($error) {
return $error;
}
$dataList = $this->model->select();
return jok('用户组列表获取成功', $dataList);
}
}
-14
View File
@@ -1,14 +0,0 @@
<?php
namespace app\admin\controller;
use app\admin\QfShop;
use think\facade\Config;
use think\facade\Cache;
use think\facade\Db;
use util\Time;
class Index extends QfShop
{
}
-213
View File
@@ -1,213 +0,0 @@
<?php
namespace app\admin\controller;
use think\App;
use app\admin\QfShop;
use app\model\Node as NodeModel;
class Node extends QfShop
{
public function __construct(App $app)
{
parent::__construct($app);
//筛选字段
$this->searchFilter = [
"node_id" => "=", //相同筛选
"node_show" => "=", //相同筛选
"node_title" => "like", //相似筛选
"node_desc" => "like", //相似筛选
"node_module" => "like", //相似筛选
"node_controller" => "like", //相似筛选
"node_action" => "like", //相似筛选
];
$this->insertFields = [
"node_title", "node_desc", "node_module", "node_action", "node_controller", "node_icon", "node_show", "node_pid", "node_order", "node_login", "node_access"
];
$this->updateFields = [
"node_title", "node_desc", "node_module", "node_action", "node_controller", "node_icon", "node_show", "node_pid", "node_order", "node_login", "node_access"
];
$this->insertRequire = [
'node_title' => "节点名称必须填写",
'node_module' => "节点模块必须填写",
];
$this->updateRequire = [
'node_title' => "节点名称必须填写",
'node_module' => "节点模块必须填写",
];
$this->model = new NodeModel();
}
/**
* 添加节点
*
* @return void
*/
public function add()
{
$error = $this->access();
if ($error) {
return $error;
}
$error = $this->validateInsertFields();
if ($error) {
return $error;
}
$data = $this->getInsertDataFromRequest();
$data['node_module'] = strtolower($data['node_module']);
$data['node_controller'] = input("node_controller") ? strtolower($data['node_controller']) : "";
$data['node_action'] = input("node_action") ? strtolower($data['node_action']) : "";
$this->insertRow($data);
return jok('用户添加成功');
}
/**
* 更新节点
*
* @return void
*/
public function update()
{
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "必须填写", 400);
}
if (!isInteger($this->pk_value)) {
return jerr("修改失败,参数错误", 400);
}
$item = $this->getRowByPk();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
$error = $this->validateUpdateFields();
if ($error) {
return $error;
}
$data = $this->getUpdateDataFromRequest();
if($item['node_id'] == $data['node_pid']){
return jerr("不能选择自己为上级菜单", 404);
}
$data['node_module'] = strtolower($data['node_module']);
$data['node_controller'] = input("node_controller") ? strtolower($data['node_controller']) : "";
$data['node_action'] = input("node_action") ? strtolower($data['node_action']) : "";
$this->updateByPk($data);
return jok('节点信息更新成功');
}
/**
* 删除节点
*
* @return void
*/
public function delete()
{
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "必须填写");
}
if (isInteger($this->pk_value)) {
$map = [$this->pk => $this->pk_value];
$item = $this->model->where($map)->find();
if (empty($item)) {
return jerr("数据查询失败");
}
$this->deleteBySingle();
//删除对应ID的授权记录
$this->authModel->where("auth_node", $this->pk_value)->delete();
} else {
$this->deleteByMultiple();
//删除对应ID的授权记录
$list = explode(',', $this->pk_value);
$this->authModel->where("auth_node", 'in', $list)->delete();
}
return jok('删除节点成功');
}
/**
* 获取所有节点
*
* @return void
*/
public function getList()
{
$error = $this->access();
if ($error) {
return $error;
}
$order = $this->table . "_order desc," . $this->pk . " asc";
$map = [
"node_pid" => 0
];
$datalist = $this->model->where($map)->order($order)->select();
$subMap = $this->getDataFilterFromRequest();
for ($i = 0; $i < count($datalist); $i++) {
$subDatalist = $this->model->field($this->selectList)->where($subMap)->where($this->table . "_pid", $datalist[$i][$this->pk])->order($order)->select();
$datalist[$i]['sub'] = $subDatalist;
for ($j = 0; $j < count($datalist[$i]['sub']); $j++) {
$subDatalist2 = $this->model->field($this->selectList)->where($subMap)->where($this->table . "_pid", $datalist[$i]['sub'][$j][$this->pk])->order($order)->select();
$datalist[$i]['sub'][$j]['sub'] = $subDatalist2;
}
}
return jok('success', [
'data' => $datalist,
'map' => $map
]);
}
/**
* 显示到菜单中
*
* @return void
*/
public function show_menu()
{
$error = $this->access();
if ($error) {
return $error;
}
if (isInteger($this->pk_value)) {
$this->model->where($this->pk, $this->pk_value)->update([
$this->table . "_show" => 1,
$this->table . "_updatetime" => time(),
]);
} else {
$list = explode(',', $this->pk_value);
$this->model->where($this->pk, 'in', $list)->update([
$this->table . "_show" => 1,
$this->table . "_updatetime" => time(),
]);
}
return jok("显示成功");
}
/**
* 从菜单中隐藏
*
* @return void
*/
public function hide_menu()
{
$error = $this->access();
if ($error) {
return $error;
}
if (isInteger($this->pk_value)) {
$this->model->where($this->pk, $this->pk_value)->update([
$this->table . "_show" => 0,
$this->table . "_updatetime" => time(),
]);
} else {
$list = explode(',', $this->pk_value);
$this->model->where($this->pk, 'in', $list)->update([
$this->table . "_show" => 0,
$this->table . "_updatetime" => time(),
]);
}
return jok("隐藏成功");
}
}
-49
View File
@@ -1,49 +0,0 @@
<?php
namespace app\admin\controller;
use think\App;
use app\admin\QfShop;
use app\model\Sms as SmsModel;
use app\model\Validate as ValidateModel;
class Sms extends QfShop
{
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new SmsModel();
}
/**
* 发送短信验证码
*
* @return void
*/
public function send()
{
//验证图形验证码
$validateModel = new ValidateModel();
$error = $validateModel->validateImgCode(input('token'), input('code'));
if ($error) {
return $error;
}
if (input("phone")) {
$phone = input('phone');
$code = cache("SMS_" . $phone);
if ($code) {
return jerr('发送短信太频繁,请稍候再试');
}
$code = rand(100000, 999999);
$error = $this->model->sendSms($phone, $code);
if ($error) {
return $error;
}
cache('SMS_' . $phone, $code, 300);
return jok('短信验证码已经发送至你的手机');
} else {
return jerr("手机号为必填信息,请填写后提交");
}
}
}
-486
View File
@@ -1,486 +0,0 @@
<?php
namespace app\admin\controller;
use think\App;
use think\facade\Filesystem;
use app\admin\QfShop;
use app\model\Source as SourceModel;
use app\model\SourceLog as SourceLogModel;
class Source extends QfShop
{
public function __construct(App $app)
{
parent::__construct($app);
//第三方转存接口地址
$this->url = "https://pan.xinyuedh.com";
//查询列表时允许的字段
$this->selectList = "*";
//查询详情时允许的字段
$this->selectDetail = "*";
//筛选字段
$this->searchFilter = [
"source_id" => "=",
"title"=>"like",
];
$this->insertFields = [
//允许添加的字段列表
"source_category_id","title","url","status","is_delete","sort","is_top"
];
$this->updateFields = [
//允许更新的字段列表
"source_category_id","title","url","status","is_delete","sort","is_top"
];
$this->insertRequire = [
//添加时必须填写的字段
// "字段名称"=>"该字段不能为空"
"title"=>"资源名称必须填写",
"url"=>"资源地址必须填写",
];
$this->updateRequire = [
//修改时必须填写的字段
// "字段名称"=>"该字段不能为空"
"source_id"=>"资源ID必须填写",
"title"=>"资源名称必须填写",
"url"=>"资源地址必须填写",
];
$this->model = new SourceModel();
$this->SourceLogModel = new SourceLogModel();
}
/**
* 获取列表接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function getList()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
//从请求中获取筛选数据的数组
$map = $this->getDataFilterFromRequest();
$map[] = ['is_delete','=',0];
if(!empty(input('source_category_id'))){
$map[] = ['source_category_id','=',input('source_category_id')];
}
//从请求中获取排序方式
$order = ['is_top' => 'desc','sort' => 'desc','source_id' => 'desc'];
//设置Model中的 per_page
$this->setGetListPerPage();
//查询数据
$dataList = $this->model->getListByPage($map, $order, $this->selectList);
return jok('数据获取成功', $dataList);
}
/**
* 添加接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function add()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
//校验Insert字段是否填写
$error = $this->validateInsertFields();
if ($error) {
return $error;
}
//从请求中获取Insert数据
$data = $this->getInsertDataFromRequest();
//添加这行数据
$data["update_time"] = time();
$data["create_time"] = time();
$this->model->insertGetId($data);
return jok('添加成功');
}
/**
* 修改接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function update()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "参数必须填写", 400);
}
//根据主键获取一行数据
$item = $this->getRowByPk();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
//校验Update字段是否填写
$error = $this->validateUpdateFields();
if ($error) {
return $error;
}
//从请求中获取Update数据
$data = $this->getUpdateDataFromRequest();
//根据主键更新这条数据
$data["update_time"] = time();
$this->model->where($this->pk, $this->pk_value)->update($data);
return jok('修改成功');
}
/**
* 删除接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function delete()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
if (!$this->pk_value) {
return jerr($this->pk . "必须填写", 400);
}
//根据主键获取一行数据
$item = $this->getRowByPk();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
$this->model->where($this->pk, $this->pk_value)->delete();
return jok('删除成功');
}
// 判断文件编码
function detectFileEncoding($filename) {
$handle = fopen($filename, 'r');
$firstLine = fread($handle, 1024); // 读取文件的开头一部分内容
fclose($handle);
// 尝试使用不同的编码进行解码,并检查是否成功
if (mb_check_encoding($firstLine, 'UTF-8')) {
return 'UTF-8';
} elseif (mb_check_encoding($firstLine, 'GBK')) {
return 'GBK';
} else {
// 如果无法确定编码,则返回默认编码
return 'UTF-8'; // 或者根据需要返回其他默认编码
}
}
/**
* Excel导入
*
* @return void
*/
public function imports()
{
$error = $this->access();
if ($error) {
return $error;
}
// try {
$file = request()->file('file');
try {
validate(['file' => 'filesize:' . config("qfshop.upload_max_file") . '|fileExt:' . config("qfshop.upload_file_type")])
->check(['file' => $file]);
$saveName = Filesystem::putFile('excel', $file, 'excel.csv');
ini_set("memory_limit",-1);
$file_name = app()->getRootPath()."public/uploads/".$saveName;
$extension = pathinfo($file_name, PATHINFO_EXTENSION);
if ($extension == 'csv') {
$PHPReader = new \PHPExcel_Reader_CSV();
$encoding = $this->detectFileEncoding($file_name);
$PHPReader->setInputEncoding($encoding);
$PHPReader->setDelimiter(',');
} elseif ($extension == 'xlsx') {
$PHPReader = new \PHPExcel_Reader_Excel2007();
} elseif ($extension == 'xls') {
$PHPReader = new \PHPExcel_Reader_Excel5();
} else {
return jerr('不支持的文件类型');
}
//载入文件
$objExcel = $PHPReader->load($file_name);
$excel_array = $objExcel ->getSheet(0)->toArray();
array_shift($excel_array); //删除第一个数组(标题);
$data = [];
$i = 0;
$j = 0;
//删除这个文件
unlink("./uploads/".$saveName);
// 生成二维码
foreach ($excel_array as $k => $v) {
$patterns = '/^\d+\.|\d+\-/';
$title = '';
if (!empty($v[2]) && preg_match('/http[^ ]+/', $v[2], $matches)) {
$title = preg_replace($patterns, '', $v[1]);
$url = $matches[0];
} else {
if (!empty($v[3]) && preg_match('/http[^ ]+/', $v[3], $matches)) {
$title = preg_replace($patterns, '', $v[2]);
$url = $matches[0];
} else {
$url = '';
}
}
$map = [];
$map[] = ['title', '=',$title];
$res = $this->model->where($map)->find();
if (empty($res) && $url) {
$data[$k]['title'] = $title;
$data[$k]['url'] = $url;
$data[$k]['source_category_id'] = input('source_category_id')??0;
$data[$k]['update_time'] = time();
$data[$k]['create_time'] = time();
$i++;
}else if($url){
$this->model->where($map)->update(['url' => $url, 'update_time' => time()]);
$j++;
}
}
$this->model->insertAll($data);
if($i == 0 && $j == 0){
return jok('无可导入的资源,请检查表格格式');
}
return jok('导入成功'.$i.'个资源,更新成功'.$j.'个资源');
} catch (ValidateException $e) {
return jerr($e->getMessage());
}
// } catch (\Exception $error) {
// return jerr('上传文件失败,请检查你的文件!');
// }
}
/**
* 一键转存并分享夸克资源
*
* @return void
*/
public function transfer()
{
$error = $this->access();
if ($error) {
return $error;
}
$url = input("url");
$substring = strstr($url, 's/');
if ($substring !== false) {
$pwd_id = substr($substring, 2); // 去除 's/' 部分
} else {
return jerr("资源地址格式有误");
}
$logId = $this->SourceLogModel->addLog('一键转存他人链接',1);
$urlData = array(
'cookie' => Config('qfshop.quark_cookie'),
'url' => $url,
);
$res = curlHelper($this->url."/api/open/transfer", "POST", $urlData)['body'];
$res = json_decode($res, true);
if($res['code'] !== 200){
$this->SourceLogModel->editLog($logId,1,'fail_num',$res['message'],1);
return jerr($res['message']);
}
$patterns = '/^\d+\./';
$title = preg_replace($patterns, '', $res['data']['title']);
//添加资源到系统中
$data["title"] = $title;
$data["url"] = $res['data']['share_url'];
$data["update_time"] = time();
$data["create_time"] = time();
$this->model->insertGetId($data);
$this->SourceLogModel->editLog($logId,1,'new_num','',1);
return jok('已提交任务,稍后查看结果',$data);
}
/**
* 全部转存
* 转存心悦搜剧资源
* @return void
*/
public function transferAll()
{
$error = $this->access();
if ($error) {
return $error;
}
@set_time_limit(999999);
//分页转存
$page_no = 1;
$dataList = '';
$logId = '';
while ($dataList=='' || !empty($dataList['items'])) {
$searchData = array(
'page_no' => $page_no,
'page_size' => 100,
'type' => 2,
);
$res = curlHelper($this->url."/api/search", "POST", $searchData)['body'];
$res = json_decode($res, true);
if($res['code'] !== 200){
return jerr($res['message']);
}
$dataList = $res['data'];
$page_no++;
if($logId == ''){
$logId = $this->SourceLogModel->addLog('全部转存',$dataList['total_result']);
}
foreach ($dataList['items'] as $key => $value) {
//如已有此资源 跳过
$detail = $this->model->where('title', $value['title'])->find();
if(!empty($detail)){
$this->SourceLogModel->editLog($logId,$dataList['total_result'],'skip_num','重复跳过转存');
continue;
}
$url = $value['url'];
$substring = strstr($url, 's/');
if ($substring !== false) {
$pwd_id = substr($substring, 2); // 去除 's/' 部分
} else {
$this->SourceLogModel->editLog($logId,$dataList['total_result'],'fail_num','资源地址格式有误');
continue;
}
$urlData = array(
'cookie' => Config('qfshop.quark_cookie'),
'url' => $url,
);
$res = curlHelper($this->url."/api/open/transfer", "POST", $urlData)['body'];
$res = json_decode($res, true);
if($res['code'] !== 200){
if($res['message'] == 'capacity limit[{0}]'){
$this->SourceLogModel->editLog($logId,$dataList['total_result'],'fail_num',$res['message']);
break;
}else{
$this->SourceLogModel->editLog($logId,$dataList['total_result'],'fail_num',$res['message']);
continue;
}
}
//添加资源到系统中
$data["title"] = $value['title'];
$data["url"] = $res['data']['share_url'];
$data["update_time"] = time();
$data["create_time"] = time();
$this->model->insertGetId($data);
$this->SourceLogModel->editLog($logId,$dataList['total_result'],'new_num','');
}
// 可以添加一个最大重试次数的限制,防止无限循环
if ($page_no > 1000) {
break;
}
}
$this->SourceLogModel->editLog($logId,$dataList['total_result'],'','',3);
return jok('已提交任务,稍后查看结果',$dataList);
}
/**
* 获取夸克网盘文件夹
*
* @return void
*/
public function getFiles()
{
$error = $this->access();
if ($error) {
return $error;
}
$urlData = array(
'cookie' => Config('qfshop.quark_cookie'),
);
$res = curlHelper($this->url."/api/open/getFiles", "POST", $urlData)['body'];
$res = json_decode($res, true);
if($res['code'] !== 200){
return jerr($res['message']);
}
return jok('获取成功',$res['data']);
}
/**
* 导出
*
* @return void
*/
public function excel()
{
$error = $this->access();
if ($error) {
return $error;
}
//查询数据
$map = [];
$filter = input('');
foreach ($filter as $k => $v) {
if ($k == 'filter') {
$k = input('filter');
$v = input('keyword');
}
if ($v === '' || $v === null) {
continue;
}
if (array_key_exists($k, $this->searchFilter)) {
switch ($this->searchFilter[$k]) {
case "like":
array_push($map, [$k, 'like', "%" . $v . "%"]);
break;
case "=":
array_push($map, [$k, '=', $v]);
break;
default:
}
}
}
$field = 'title,url';
$dataList = $this->model->field($field)->where($map)->select();
$excelField = [
"title" => "资源名称",
"url" => "资源地址",
];
$data = $dataList->toArray();
$this->excelField = $excelField;
$this->exportExcelData($dataList);
print_r(12);
}
}
-258
View File
@@ -1,258 +0,0 @@
<?php
namespace app\admin\controller;
use think\App;
use app\admin\QfShop;
use app\model\SourceCategory as SourceCategoryModel;
class SourceCategory extends QfShop
{
public function __construct(App $app)
{
parent::__construct($app);
//查询列表时允许的字段
$this->selectList = "*";
//查询详情时允许的字段
$this->selectDetail = "*";
//筛选字段
$this->searchFilter = [
"source_category_id" => "=",
"name"=>"like"
];
$this->insertFields = [
//允许添加的字段列表
"name","sort","status"
];
$this->updateFields = [
//允许更新的字段列表
"name","sort","status"
];
$this->insertRequire = [
//添加时必须填写的字段
// "字段名称"=>"该字段不能为空"
"name"=>"分类名称必须填写",
];
$this->updateRequire = [
//修改时必须填写的字段
// "字段名称"=>"该字段不能为空"
"name"=>"分类名称必须填写",
];
$this->model = new SourceCategoryModel();
}
/**
* 获取列表接口
*
* @return void
*/
public function getList()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
//查询数据
$dataList = $this->model->order('sort', 'desc')->select();
return jok('数据获取成功', $dataList);
}
/**
* 获取详情基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function detail()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
$source_category_id = input("source_category_id");
if (!$source_category_id) {
return jerr("ID参数必须填写", 400);
}
//根据主键获取一行数据
$item = $this->model->where("source_category_id", $source_category_id)->field($this->selectDetail)->find();
if (empty($item)) {
return jerr("没有查询到数据", 404);
}
return jok('数据加载成功', $item);
}
/**
* 添加接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function add()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
//校验Insert字段是否填写
$error = $this->validateInsertFields();
if ($error) {
return $error;
}
//从请求中获取Insert数据
$data = $this->getInsertDataFromRequest();
//添加这行数据
$data['create_time'] = time();
$data['update_time'] = time();
$this->model->insertGetId($data);
return jok('添加成功');
}
/**
* 修改接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function update()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
$source_category_id = input("source_category_id");
if (!$source_category_id) {
return jerr("ID参数必须填写", 400);
}
//根据主键获取一行数据
$item = $this->model->where("source_category_id", $source_category_id)->field($this->selectDetail)->find();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
//校验Update字段是否填写
$error = $this->validateUpdateFields();
if ($error) {
return $error;
}
//从请求中获取Update数据
$data = $this->getUpdateDataFromRequest();
//根据主键更新这条数据
$data['update_time'] = time();
$this->model->where("source_category_id", $source_category_id)->update($data);
return jok('修改成功');
}
/**
* 删除接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function delete()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
$source_category_id = input("source_category_id");
if (!$source_category_id) {
return jerr("ID参数必须填写", 400);
}
if (isInteger($source_category_id)) {
//根据主键获取一行数据
$item = $this->model->where("source_category_id", $source_category_id)->field($this->selectDetail)->find();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
//单个操作
$map = ["source_category_id" => $source_category_id];
$this->model->where($map)->delete();
} else {
//批量操作
$list = explode(',', $source_category_id);
$this->model->where("source_category_id", 'in', $list)->delete();
}
return jok('删除成功');
}
/**
* 禁用接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function disable()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
$source_category_id = input("source_category_id");
if (!$source_category_id) {
return jerr("ID参数必须填写", 400);
}
if (isInteger($source_category_id)) {
//根据主键获取一行数据
$item = $this->model->where("source_category_id", $source_category_id)->field($this->selectDetail)->find();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
//单个操作
$map = ["source_category_id" => $source_category_id];
$this->model->where($map)->update([
"status" => 1,
"update_time" => time(),
]);
} else {
//批量操作
$list = explode(',', $source_category_id);
$this->model->where("source_category_id", 'in', $list)->update([
"status" => 1,
"update_time" => time(),
]);
}
return jok("禁用成功");
}
/**
* 启用接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function enable()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
$source_category_id = input("source_category_id");
if (!$source_category_id) {
return jerr("ID参数必须填写", 400);
}
if (isInteger($source_category_id)) {
//根据主键获取一行数据
$item = $this->model->where("source_category_id", $source_category_id)->field($this->selectDetail)->find();
if (empty($item)) {
return jerr("数据查询失败", 404);
}
//单个操作
$map = ["source_category_id" => $source_category_id];
$this->model->where($map)->update([
"status" => 0,
"update_time" => time(),
]);
} else {
//批量操作
$list = explode(',', $source_category_id);
$this->model->where("source_category_id", 'in', $list)->update([
"status" => 0,
"update_time" => time(),
]);
}
return jok("启用成功");
}
}
-46
View File
@@ -1,46 +0,0 @@
<?php
namespace app\admin\controller;
use think\App;
use think\facade\Filesystem;
use app\admin\QfShop;
use app\model\SourceLog as SourceLogModel;
class SourceLog extends QfShop
{
public function __construct(App $app)
{
parent::__construct($app);
//查询列表时允许的字段
$this->selectList = "*";
//查询详情时允许的字段
$this->selectDetail = "*";
$this->model = new SourceLogModel();
}
/**
* 获取列表接口基类 子类自动继承 如有特殊需求 可重写到子类 请勿修改父类方法
*
* @return void
*/
public function getList()
{
//校验Access与RBAC
$error = $this->access();
if ($error) {
return $error;
}
//从请求中获取筛选数据的数组
$map = $this->getDataFilterFromRequest();
//从请求中获取排序方式
$order = $this->getorderfromRequest();
//设置Model中的 per_page
$this->setGetListPerPage();
//查询数据
$dataList = $this->model->getListByPage($map, $order, $this->selectList);
return jok('数据获取成功', $dataList);
}
}
-77
View File
@@ -1,77 +0,0 @@
<?php
namespace app\admin\controller;
use think\App;
use think\facade\Db;
use think\facade\Cache;
use app\admin\QfShop;
use app\model\Validate as ValidateModel;
class System extends QfShop
{
public function __construct(App $app)
{
parent::__construct($app);
}
/**
* 获取图形验证码
*
* @return void
*/
public function getCaptcha()
{
// $error = $this->access();
// if ($error) {
// return $error;
// }
$validateModel = new ValidateModel();
$imgData = $validateModel->getImg();
$code = strtoupper($validateModel->getCode());
$token = sha1($code . time()) . rand(100000, 999999);
cache($token, $code, 60);
return jok('验证码生成成功', [
'img' => $imgData,
'token' => $token
]);
}
/**
* 清除缓存
*
* @return void
*/
public function clean()
{
$error = $this->access();
if ($error) {
return $error;
}
Cache::clear();
if($this->del_dir("../runtime/")){
return jok('缓存已清空');
}else{
return jerr('缓存清除失败');
}
}
function del_dir($dir) {
$dh=opendir($dir);
while ($file=readdir($dh)) {
if($file!="." && $file!="..") {
$fullpath=$dir."/".$file;
if(!is_dir($fullpath)) {
@unlink($fullpath);
} else {
$this->del_dir($fullpath);
}
}
}
closedir($dh);
if(rmdir($dir)) {
return true;
} else {
return false;
}
}
}
-92
View File
@@ -1,92 +0,0 @@
<?php
declare(strict_types=1);
namespace app\api;
use think\App;
use think\facade\View;
use app\model\Conf as ConfModel;
use app\model\Token as TokenModel;
/**
* 控制器基础类
*/
abstract class QfShop
{
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 控制器初始化
$this->initialize();
}
// 初始化
protected function initialize()
{
//访问XMLHttpRequest已被CORS政策阻止
header('Access-Control-Allow-Origin: *');
$this->confModel = new ConfModel();
$configs = $this->confModel->select()->toArray();
$c = [];
foreach ($configs as $config) {
$c[$config['conf_key']] = $config['conf_value'];
}
config($c, 'qfshop');
}
public function __call($method, $args)
{
return jerr("API接口方法不存在", 404);
}
/**
* 检测授权 获取当前用户登录信息
* @param $type false不提示登录失败状态
* @param user_id 顾客时为用户id
* @param action 操作者 顾客端为手机号,管理端为登录账号
* @param client_type 0=顾客 1=管理组 -1=游客
*/
protected function getLoginUser($type = true)
{
$is_login = true;
// 获取请求中的token
$access_token = request()->header('X-CSRF-TOKEN');
if (!$access_token) {
if($type){
return jerr("用户未登录", 401);
}else{
$is_login = false;
}
}
$Token = new TokenModel();
$user = $Token->getToken($access_token);
if (!$user) {
if($type){
return jerr("登录过期,请重新登录", 401);
}else{
$is_login = false;
}
}
if($is_login){
$user['action'] = $user['mobile'];
$user['client_type'] = 0;
unset($user['mobile']);
unset($user['status']);
return $user;
}else{
$user['client_type'] = -1;
return $user;
}
}
}
-13
View File
@@ -1,13 +0,0 @@
<?php
namespace app\api\controller;
use app\api\QfShop;
class Error extends QfShop
{
public function index()
{
return jerr("Error", 404);
}
}
-16
View File
@@ -1,16 +0,0 @@
<?php
namespace app\api\controller;
use app\api\QfShop;
class Index extends QfShop
{
public function index()
{
return jok("Hello World!");
}
public function search() {
return jok("Hello World!");
}
}
-127
View File
@@ -1,127 +0,0 @@
<?php
namespace app\api\controller;
use think\App;
use app\api\QfShop;
use app\model\Source as SourceModel;
class Other extends QfShop
{
public function __construct(App $app)
{
parent::__construct($app);
//第三方转存接口地址
$this->url = "https://pan.xinyuedh.com";
$this->model = new SourceModel();
}
/**
* 全网搜索 该接口仅用于微信自动回复
*
* @return void
*/
public function search()
{
$param = input('');
if (empty($param['title'])) {
return jerr("请输入要看的内容");
}
$searchData = array(
'cookie' => Config('qfshop.quark_cookie'),
'title' => $param['title'],
);
$res = curlHelper($this->url."/api/open/network_search", "POST", $searchData)['body'];
$res = json_decode($res, true);
if($res['code'] !== 200){
return jerr($res['message']);
}
$urls = $res['data'];
$datas = [];
foreach ($urls as $url) {
$substring = strstr($url, 's/');
if ($substring !== false) {
$pwd_id = substr($substring, 2); // 去除 's/' 部分
} else {
continue;
}
$urlData = array(
'cookie' => Config('qfshop.quark_cookie'),
'url' => $url,
);
$res = curlHelper($this->url."/api/open/transfer", "POST", $urlData)['body'];
$res = json_decode($res, true);
if($res['code'] !== 200){
continue;
}
$patterns = '/^\d+\./';
$title = preg_replace($patterns, '', $res['data']['title']);
//添加资源到系统中
$data["title"] = $title.'('.$param['title'].')';
$data["url"] = $res['data']['share_url'];
$data["fid"] = $res['data']['first_file']['fid'];
$data["is_time"] = 1;
$data["update_time"] = time();
$data["create_time"] = time();
$this->model->insertGetId($data);
$datas[] = $data;
}
return jok('临时资源获取成功',$datas);
}
/**
* 十分钟后清除临时资源
*
* @return void
*/
public function delete_search()
{
// 搜索条件
$map[] = ['is_time', '=', 1];
$map[] = ['create_time', '<=', time() - (10 * 60)];
$this->model->where($map)->chunk(100, function ($order) {
foreach ($order as $value) {
$deles = $value->toArray();
$filelist = [];
$filelist[] = $deles['fid'];
$urlData = '{ "action_type": 2, "exclude_fids": [], "filelist": '.json_encode($filelist).' }';
$urlHeader = array(
'Accept: application/json, text/plain, */*',
'Accept-Language: zh-CN,zh;q=0.9',
'content-type: application/json;charset=UTF-8',
'sec-ch-ua: "Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"',
'sec-ch-ua-mobile: ?0',
'sec-ch-ua-platform: "Windows"',
'sec-fetch-dest: empty',
'sec-fetch-mode: cors',
'sec-fetch-site: same-site',
'Referer: https://pan.quark.cn/',
'Referrer-Policy: strict-origin-when-cross-origin',
'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'cookie: '.Config('qfshop.quark_cookie'),
);
$res = curlHelper("https://drive-pc.quark.cn/1/clouddrive/file/delete?pr=ucpro&fr=pc&uc_param_str=", "POST", $urlData, $urlHeader)['body'];
$res = json_decode($res, true);
if($res['status'] == 200){
$this->model->where('fid', $deles['fid'])->delete();
}
}
});
return jok('临时资源删除成功');
}
}
-45
View File
@@ -1,45 +0,0 @@
<?php
namespace app\api\controller;
use app\api\QfShop;
use app\model\Source as SourceModel;
use app\model\SourceCategory as SourceCategoryModel;
class Search extends QfShop
{
public function index()
{
$SourceModel = new SourceModel();
$data = $SourceModel->getList(input(''));
return jok('获取成功',$data);
}
public function getDetail()
{
$SourceModel = new SourceModel();
$data = $SourceModel->getDetail(input(''));
return jok('获取成功',$data);
}
public function getNew()
{
$SourceModel = new SourceModel();
$data = $SourceModel->getNew(input(''));
return jok('获取成功',$data);
}
public function getHot()
{
$SourceModel = new SourceModel();
$data = $SourceModel->getHot(input(''));
return jok('获取成功',$data);
}
public function getCategory()
{
$SourceCategoryModel = new SourceCategoryModel();
$data = $SourceCategoryModel->getList(input(''));
return jok('获取成功',$data);
}
}
-118
View File
@@ -1,118 +0,0 @@
<?php
namespace app\api\controller;
use think\App;
use app\api\QfShop;
use think\facade\Cache;
use Carbon\Carbon;
use app\model\Source as SourceModel;
use app\model\SourceLog as SourceLogModel;
class Source extends QfShop
{
public function __construct(App $app)
{
parent::__construct($app);
//第三方转存接口地址
$this->url = "https://pan.xinyuedh.com";
$this->model = new SourceModel();
$this->SourceLogModel = new SourceLogModel();
}
public function day()
{
// 当前日期
$currentDate = Carbon::today()->toDateString();
// 缓存键名
$cacheKey = 'api_alone_date_' . $currentDate;
// 检查缓存中是否存在该键
if (Cache::has($cacheKey)) {
return jerr("请勿频繁调用,一个小时后再试!");
}
Cache::set($cacheKey, time(), 3600);
ini_set('max_execution_time', -1);
//分页转存
$page_no = 1;
$dataList = '';
$logId = '';
while ($dataList=='' || !empty($dataList['items'])) {
$searchData = array(
'page_no' => $page_no,
'page_size' => 100,
'type' => 2,
'day' => 2,
);
$res = curlHelper($this->url."/api/search", "POST", $searchData)['body'];
$res = json_decode($res, true);
if($res['code'] !== 200){
ini_set('max_execution_time', 300);
return jerr($res['message']);
}
$dataList = $res['data'];
$page_no++;
if($logId == ''){
$logId = $this->SourceLogModel->addLog('每日更新',$dataList['total_result']);
}
foreach ($dataList['items'] as $key => $value) {
//如已有此资源 跳过
$detail = $this->model->where('title', $value['title'])->find();
if(!empty($detail)){
$this->SourceLogModel->editLog($logId,$dataList['total_result'],'skip_num','重复跳过转存');
continue;
}
$url = $value['url'];
$substring = strstr($url, 's/');
if ($substring !== false) {
$pwd_id = substr($substring, 2); // 去除 's/' 部分
} else {
$this->SourceLogModel->editLog($logId,$dataList['total_result'],'fail_num','资源地址格式有误');
continue;
}
$urlData = array(
'cookie' => Config('qfshop.quark_cookie'),
'url' => $url,
);
$res = curlHelper($this->url."/api/open/transfer", "POST", $urlData)['body'];
$res = json_decode($res, true);
if($res['code'] !== 200){
if($res['message'] == 'capacity limit[{0}]'){
$this->SourceLogModel->editLog($logId,$dataList['total_result'],'fail_num',$res['message']);
break;
}else{
$this->SourceLogModel->editLog($logId,$dataList['total_result'],'fail_num',$res['message']);
continue;
}
}
//添加资源到系统中
$data["title"] = $value['title'];
$data["url"] = $res['data']['share_url'];
$data["update_time"] = time();
$data["create_time"] = time();
$this->model->insertGetId($data);
$this->SourceLogModel->editLog($logId,$dataList['total_result'],'new_num','');
}
// 可以添加一个最大重试次数的限制,防止无限循环
if ($page_no > 1000) {
break;
}
}
$this->SourceLogModel->editLog($logId,$dataList['total_result'],'','',3);
ini_set('max_execution_time', 300);
return jok('已提交任务,稍后查看结果',$dataList);
}
}
-75
View File
@@ -1,75 +0,0 @@
<?php
namespace app\api\controller;
use think\App;
use app\api\QfShop;
use app\model\User as Usermodel;
use app\model\Ads as Adsmodel;
use app\model\Feedback as FeedbackModel;
class Tool extends QfShop
{
/**
* 系统配置参数
*
* @return void
*/
public function getConfig()
{
$data = [
'app_name' => Config('qfshop.app_name'),
'qcode' => getimgurl(Config('qfshop.qcode')),
'logo' => getimgurl(Config('qfshop.logo')),
'app_description' => Config('qfshop.app_description'),
];
return jok('获取成功',$data);
}
/**
* 上传图片
*
* @return void
*/
public function Upload()
{
// 获取当前登录的用户信息
$userInfo = $this->getLoginUser();
try {
$file = request()->file('file');
} catch (\Exception $error) {
return jerr('上传文件失败,请检查你的文件!');
}
$Usermodel = new Usermodel();
$data = $Usermodel->Upload($file, $userInfo);
return jok('上传成功',$data);
}
/**
* 根据广告位关键词获取广告图片列表
*
* @return void
*/
public function getAdsCode()
{
$Adsmodel = new Adsmodel();
$data = $Adsmodel->getAdsCode(input(''));
return jok('获取成功',$data);
}
/**
* 用户反馈
*
* @return void
*/
public function feedback()
{
$data = input('');
if (empty($data['content'])) {
return jerr("请输入要看的内容");
}
$FeedbackModel = new FeedbackModel();
$FeedbackModel->save(['content' => $data['content']]);
return jok('已反馈');
}
}
-700
View File
@@ -1,700 +0,0 @@
<?php
/**
* 输出正常JSON
*
* @param string 提示信息
* @param array 输出数据
* @return json
*/
function jok($message = 'success', $data = null)
{
header("content-type:application/json;chartset=uft-8");
if ($data) {
echo json_encode(["code" => 200, "message" => $message, 'data' => $data]);
} else {
echo json_encode(["code" => 200, "message" => $message, 'data' => $data??'']);
}
die;
}
/**
* 输出错误JSON
*
* @param string 错误信息
* @param int 错误代码
* @return json
*/
function jerr($message = 'error', $code = 500)
{
header("content-type:application/json;chartset=uft-8");
echo json_encode(["code" => $code, "message" => $message]);
die;
}
/**
* 密码+盐 加密
*
* @param string 明文密码
* @param string 盐
* @return string
*/
function encodePassword($password, $salt)
{
return sha1($password . $salt . $password . $salt);
}
/**
* 密码校验 6-16
*
* @param string 明文密码
* @return boolean 是否校验通过
*/
function isValidPassword($password)
{
return preg_match('/(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*\s).{6,}/', $password);
}
/**
* 获取随机字符
*
* @param int $len
* @return void
*/
function getRandString($len)
{
$string = '';
$randString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for ($i = 0; $i < $len; $i++) {
$string .= $randString[rand(0, strlen($randString) - 1)];
}
return $string;
}
/**
* 生成唯一会议编码
* @param string $prefix 头部
* @return string
*/
function get_order_no($prefix = 'QF')
{
$order_no = $prefix;
$order_no .= mb_strtoupper(dechex(date('m')), 'utf-8');
$order_no .= date('d') . mb_substr(time(), -5, null, 'utf-8');
$order_no .= mb_substr(microtime(), 2, 5, 'utf-8');
return $order_no;
}
/**
* 获取随机字母
*
* @param int 长度
* @return string
*/
function getRandChar($len)
{
$string = '';
$randString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for ($i = 0; $i < $len; $i++) {
$string .= $randString[rand(0, strlen($randString) - 1)];
}
return $string;
}
/**
* 驼峰转下划线
* @param $camelCaps
* @param string $separator
* @return string
*/
function uncamelize($camelCaps, $separator = '_')
{
return strtolower(preg_replace('/([a-z])([A-Z])/', "$1" . $separator . "$2", $camelCaps));
}
/**
* 遍历类的方法
*
* @param string 指定的类名称
* @return array
*/
function getClassMethods($class)
{
$array_result = [];
$array_all = get_class_methods($class);
if ($parent_class = get_parent_class($class)) {
$array_parent = get_class_methods($parent_class);
$array_result = array_diff($array_all, $array_parent);
} else {
$array_result = $array_all;
}
return $array_result;
}
/**
* 获取包含协议和端口的域名
*
* @return string
*/
function getFullDomain()
{
// return ($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? $_SERVER['REQUEST_SCHEME']) . "://" . $_SERVER['HTTP_HOST'];
return "http://" . $_SERVER['HTTP_HOST'];
}
/**
* 图片地址转绝对路径
*
* @return string
*/
function getimgurl($img)
{
$result = '';
if($img){
// $url = ($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? $_SERVER['REQUEST_SCHEME']) . "://" . $_SERVER['HTTP_HOST'];
$url = "http://" . $_SERVER['HTTP_HOST'];
if(is_array($img)){
$result = [];
foreach ($img as $key => $value) {
if(!preg_match("/^http(s)?:\\/\\/.+/", $value)){
$result[] = $url.$value;
}else{
$result[] = $value;
}
}
}else{
if(!preg_match("/^http(s)?:\\/\\/.+/", $img)){
$result = $url.$img;
}else{
$result = $img;
}
}
}
return $result;
}
/**
* 替换编辑器内容中的文件地址
* @param string $content 编辑器内容
* @return string
*/
function app_replace_content_file_url($content)
{
\phpQuery::newDocumentHTML($content);
$pq = pq(null);
$domain = request()->host();
$images = $pq->find("img");
if ($images->length) {
foreach ($images as $img) {
$img = pq($img);
$imgSrc = $img->attr("src");
if(!preg_match("/^http(s)?:\\/\\/.+/", $imgSrc)){
$img->attr("src", getimgurl($imgSrc));
}
}
}
$links = $pq->find("a");
if ($links->length) {
foreach ($links as $link) {
$link = pq($link);
$href = $link->attr("href");
if(!preg_match("/^http(s)?:\\/\\/.+/", $href)){
$img->attr("href", getimgurl($imgSrc));
}
}
}
$content = $pq->htmlOuter();
\phpQuery::$documents = null;
return $content;
}
/**
* 获取客户端IP
*
* @return string
*/
function getClientIp()
{
foreach (array(
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED',
'HTTP_X_CLUSTER_CLIENT_IP',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED',
'REMOTE_ADDR'
) as $key) {
if (array_key_exists($key, $_SERVER)) {
foreach (explode(',', $_SERVER[$key]) as $ip) {
$ip = trim($ip);
if ((bool) filter_var(
$ip,
FILTER_VALIDATE_IP,
FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6
// FILTER_FLAG_NO_PRIV_RANGE |
// FILTER_FLAG_NO_RES_RANGE
)) {
return $ip;
}
}
}
}
return null;
}
/**
* 取文本中间
*
* @param string 原始字符串
* @param string 左边字符串
* @param string 右边字符串
* @return string
*/
function getSubstr($str, $leftStr, $rightStr)
{
$left = strpos($str, $leftStr);
$right = strpos($str, $rightStr, $left);
if ($left < 0 or $right < $left) return '';
return substr($str, $left + strlen($leftStr), $right - $left - strlen($leftStr));
}
/**
* 获取操作系统
*
* @return string
*/
function getOs()
{
if (empty($_SERVER['HTTP_USER_AGENT'])) {
return 'Other';
}
$agent = strtolower($_SERVER['HTTP_USER_AGENT']);
if (strpos($agent, 'windows nt')) {
$platform = 'Windows';
} elseif (strpos($agent, 'macintosh')) {
$platform = 'MacOS';
} elseif (strpos($agent, 'ipod')) {
$platform = 'iPod';
} elseif (strpos($agent, 'ipad')) {
$platform = 'iPad';
} elseif (strpos($agent, 'iphone')) {
$platform = 'iPhone';
} elseif (strpos($agent, 'android')) {
$platform = 'Android';
} elseif (strpos($agent, 'unix')) {
$platform = 'Unix';
} elseif (strpos($agent, 'linux')) {
$platform = 'Linux';
} else {
$platform = 'Other';
}
return $platform;
}
/**
* 获取浏览器
*
* @return void
*/
function getBrowser()
{
if (empty($_SERVER['HTTP_USER_AGENT'])) {
return 'Unknown';
}
$agent = $_SERVER["HTTP_USER_AGENT"];
if (strpos($agent, 'MSIE') !== false || strpos($agent, 'rv:11.0')) //ie11判断
{
return "IE";
} else if (strpos($agent, 'Firefox') !== false) {
return "Firefox";
} else if (strpos($agent, 'Chrome') !== false) {
return "Chrome";
} else if (strpos($agent, 'Opera') !== false) {
return 'Opera';
} else if ((strpos($agent, 'Chrome') == false) && strpos($agent, 'Safari') !== false) {
return 'Safari';
} else {
return 'Unknown';
}
}
/**
* 是否手机请求
*
* @return boolean
*/
function isMobileRequest()
{
$_SERVER['ALL_HTTP'] = isset($_SERVER['ALL_HTTP']) ? $_SERVER['ALL_HTTP'] : '';
$mobile_browser = '0';
if (preg_match('/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|phone|iphone|uc|qq|wechat|micro|messenger|ipad|ipod|android|xoom)/i', strtolower($_SERVER['HTTP_USER_AGENT'])))
$mobile_browser++;
if ((isset($_SERVER['HTTP_ACCEPT'])) and (strpos(strtolower($_SERVER['HTTP_ACCEPT']), 'application/vnd.wap.xhtml+xml') !== false))
$mobile_browser++;
if (isset($_SERVER['HTTP_X_WAP_PROFILE']))
$mobile_browser++;
if (isset($_SERVER['HTTP_PROFILE']))
$mobile_browser++;
$mobile_ua = strtolower(substr($_SERVER['HTTP_USER_AGENT'], 0, 4));
$mobile_agents = array(
'w3c ', 'acs-', 'alav', 'alca', 'amoi', 'audi', 'avan', 'benq', 'bird', 'blac',
'blaz', 'brew', 'cell', 'cldc', 'cmd-', 'dang', 'doco', 'eric', 'hipt', 'inno',
'ipaq', 'java', 'jigs', 'kddi', 'keji', 'leno', 'lg-c', 'lg-d', 'lg-g', 'lge-',
'maui', 'maxo', 'midp', 'mits', 'mmef', 'mobi', 'mot-', 'moto', 'mwbp', 'nec-',
'newt', 'noki', 'oper', 'palm', 'pana', 'pant', 'phil', 'play', 'port', 'prox',
'qwap', 'sage', 'sams', 'sany', 'sch-', 'sec-', 'send', 'seri', 'sgh-', 'shar',
'sie-', 'siem', 'smal', 'smar', 'sony', 'sph-', 'symb', 't-mo', 'teli', 'tim-',
'tosh', 'tsm-', 'upg1', 'upsi', 'vk-v', 'voda', 'wap-', 'wapa', 'wapi', 'wapp',
'wapr', 'webc', 'winw', 'winw', 'xda', 'xda-'
);
if (in_array($mobile_ua, $mobile_agents))
$mobile_browser++;
if (strpos(strtolower($_SERVER['ALL_HTTP']), 'operamini') !== false)
$mobile_browser++;
// Pre-final check to reset everything if the user is on Windows
if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'windows') !== false)
$mobile_browser = 0;
// But WP7 is also Windows, with a slightly different characteristic
if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'windows phone') !== false)
$mobile_browser++;
if ($mobile_browser > 0)
return true;
else
return false;
}
/**
* 身份证号验证
* @param $id
* @return bool
*/
function isIDCard($id)
{
$id = strtoupper($id);
$regx = "/(^\d{15}$)|(^\d{17}([0-9]|X)$)/";
$arr_split = array();
if (!preg_match($regx, $id)) {
return FALSE;
}
if (15 == strlen($id)) //检查15位
{
$regx = "/^(\d{6})+(\d{2})+(\d{2})+(\d{2})+(\d{3})$/";
@preg_match($regx, $id, $arr_split);
//检查生日日期是否正确
$dtm_birth = "19" . $arr_split[2] . '/' . $arr_split[3] . '/' . $arr_split[4];
if (!strtotime($dtm_birth)) {
return FALSE;
} else {
return TRUE;
}
} else { //检查18位
$regx = "/^(\d{6})+(\d{4})+(\d{2})+(\d{2})+(\d{3})([0-9]|X)$/";
@preg_match($regx, $id, $arr_split);
$dtm_birth = $arr_split[2] . '/' . $arr_split[3] . '/' . $arr_split[4];
if (!strtotime($dtm_birth)) //检查生日日期是否正确
{
return FALSE;
} else {
//检验18位身份证的校验码是否正确。
//校验位按照ISO 7064:1983.MOD 11-2的规定生成,X可以认为是数字10。
$arr_int = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
$arr_ch = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
$sign = 0;
for ($i = 0; $i < 17; $i++) {
$b = (int) $id[$i];
$w = $arr_int[$i];
$sign += $b * $w;
}
$n = $sign % 11;
$val_num = $arr_ch[$n];
if ($val_num != substr($id, 17, 1)) {
return FALSE;
} else {
return TRUE;
}
}
}
}
/**
* 是否是整数
*
* @param string 输入内容
* @return boolean
*/
function isInteger($input)
{
return (ctype_digit(strval($input)));
}
/**
* 获取一个key摘要
*
* @param string 原始key
* @return string
*/
function getTicket($key)
{
return sha1($key . (env('SYSTEM_SALT') ?? 'qfshop') . $key);
}
/**
* CURL请求
*
* @param string URL地址
* @param mixed 请求方法,支持GET/POST/PUT/DELETE/PATCH/TRACE/OPTION/HEAD 默认GET
* @param mixed 请求数据包体
* @param mixed 请求头 数组
* @param mixed 请求COOKIES字符串
* @return void
*/
function curlHelper($url, $method = 'GET', $data = null, $header = [], $queryParams = [], $cookies = "")
{
// 构建查询参数
if (!empty($queryParams)) {
$queryString = http_build_query($queryParams);
$url .= '?' . $queryString;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_COOKIE, $cookies);
switch ($method) {
case "GET":
curl_setopt($ch, CURLOPT_HTTPGET, true);
break;
case "POST":
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
break;
case "PUT":
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
break;
case "DELETE":
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
break;
case "PATCH":
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
break;
case "TRACE":
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "TRACE");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
break;
case "OPTIONS":
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "OPTIONS");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
break;
case "HEAD":
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "HEAD");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
break;
default:
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
$response = curl_exec($ch);
$output = [];
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
// 根据头大小去获取头信息内容
$output['header'] = substr($response, 0, $headerSize);
$output['body'] = substr($response, $headerSize, strlen($response) - $headerSize);
$output['detail'] = curl_getinfo($ch);
curl_close($ch);
return $output;
}
/**
* 模拟表单上传文件请求
* @param $$url 提交地址
* @param $data 提交数据
* @param $cookies 如设置了Content-Type将被自动覆写为formdata
* ex.
* $data = ['file'=>new \CURLFile(realpath($file_dir)),appid"=>"1234"];
* $result = curl_form($url,$data);
* @return mixed
*/
function curlForm($url, $data = null, $header = [], $cookies = "")
{
$header[] = 'Content-Type: multipart/form-data';
return curlHelper($url, "POST", $data, $header, $cookies);
}
/**
* 多维数组合并(支持多数组)
* @param arraylist arrayMergeMulti(['1'=>'1','2'=>'2','3'=>'3'],['4'=>'4','5'=>'5','6'=>'6'])
* @return array
*/
function arrayMergeMulti()
{
//获取当前方法捕获到的所有参数数组
$args = func_get_args();
$array = [];
foreach ($args as $arg) {
if (is_array($arg)) {
foreach ($arg as $k => $v) {
if (is_array($v)) {
$array[$k] = isset($array[$k]) ? $array[$k] : [];
$array[$k] = arrayMergeMulti($array[$k], $v);
} else {
$array[$k] = $v;
}
}
}
}
return $array;
}
/**
* 对查询结果集进行排序
* @access public
* @param array $list 查询结果
* @param string $field 排序的字段名
* @param array $sortBy 排序类型
* asc正向排序 desc逆向排序 nat自然排序
* @return array|bool
*/
function listSortBy($list, $field, $sortBy = 'asc')
{
if (is_array($list)) {
$refer = $resultSet = [];
foreach ($list as $i => $data) {
$refer[$i] = &$data[$field];
}
switch ($sortBy) {
case 'asc': // 正向排序
asort($refer);
break;
case 'desc': // 逆向排序
arsort($refer);
break;
case 'nat': // 自然排序
natcasesort($refer);
break;
}
foreach ($refer as $key => $val) {
$resultSet[] = &$list[$key];
}
return $resultSet;
}
return false;
}
/**
* 格式化字节大小
* @param number $size 字节数
* @param int $float 小数保留位数
* @param string $delimiter 数字和单位分隔符
* @return string 格式化后的带单位的大小
*/
function formatBytes($size, $float = 2, $delimiter = '')
{
$units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
for ($i = 0; $size >= 1024 && $i < 5; $i++) $size /= 1024;
return round($size, $float) . $delimiter . $units[$i];
}
/**
* 生成标准UUID
*
* @return string
*/
function getUuid()
{
mt_srand((float) microtime() * 10000);
$uuid = sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535));
return $uuid;
}
/**
* 判断是否为空参数
* @param mixed $parm
* @return bool
*/
function is_empty_parm(&$parm)
{
return !(isset($parm) && '' !== $parm);
}
/**
* 返回当前账号openid
* $openid wxapp_openid wechat_openid
* @return string
*/
function get_client_openid($user_id, $openid)
{
return \think\facade\Db::name('user')->where('user_id', $user_id)->value($openid);
}
/**
* 产生数字与字母混合随机字符串
* @param int $len 数值长度,默认6位
* @return string
*/
function get_randstr($len = 6)
{
$chars = [
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2',
'3', '4', '5', '6', '7', '8', '9',
];
$charsLen = count($chars) - 1;
shuffle($chars);
$output = '';
for ($i = 0; $i < $len; $i++) {
$output .= $chars[mt_rand(0, $charsLen)];
}
return $output;
}
/**
* 产生随机数值
* @param int $len 数值长度,默认8位
* @return string
*/
function rand_number($len = 8)
{
$chars = str_repeat('123456789', 3);
if ($len > 10) {
$chars = str_repeat($chars, $len);
}
$chars = str_shuffle($chars);
return mb_substr($chars, 0, $len, 'utf-8');
}
/**
* 智能字符串模糊化
* @param string $str 被模糊的字符串
* @param int $len 模糊的长度
* @return string
*/
function auto_hid_substr(string $str, $len = 3)
{
if (empty($str)) {
return null;
}
$sub_str = mb_substr($str, 0, 1, 'utf-8');
for ($i = 0; $i < $len; $i++) {
$sub_str .= '*';
}
if (mb_strlen($str, 'utf-8') <= 2) {
$str = $sub_str;
}
$sub_str .= mb_substr($str, -1, 1, 'utf-8');
return $sub_str;
}
/**
* 多维数组,根据某个特定字段过滤重复值
* @return array
*/
function assoc_unique($arr, $key) {
$tmp_arr = array();
foreach ($arr as $k => $v) {
if (in_array($v[$key], $tmp_arr)) {//搜索$v[$key]是否在$tmp_arr数组中存在,若存在返回true
unset($arr[$k]);
} else {
$tmp_arr[] = $v[$key];
}
}
sort($arr); //sort函数对数组进行排序
return $arr;
}
-17
View File
@@ -1,17 +0,0 @@
<?php
// 事件定义文件
return [
'bind' => [
],
'listen' => [
'AppInit' => [],
'HttpRun' => [],
'HttpEnd' => [],
'LogLevel' => [],
'LogWrite' => [],
],
'subscribe' => [
],
];
-171
View File
@@ -1,171 +0,0 @@
<?php
declare(strict_types=1);
namespace app\index;
use think\App;
use EasyWeChat\Factory;
use app\model\Conf as ConfModel;
use app\model\User as UserModel;
/**
* 控制器基础类
*/
abstract class QfShop
{
protected $confModel;
protected $UserModel;
protected $access_token;
protected $wechat_appid;
protected $wechat_appkey;
protected $easyWeChat;
//微信用户数据数组
protected $user;
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
protected $module;
protected $controller;
protected $action;
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 控制器初始化
// $this->initialize();
}
// 初始化
protected function initialize()
{
$this->module = "index";
$this->controller = "index";
$this->action = strtolower($this->request->action()) ? strtolower($this->request->action()) : "index";
$this->confModel = new ConfModel();
$this->UserModel = new UserModel();
$configs = $this->confModel->select()->toArray();
$c = [];
foreach ($configs as $config) {
$c[$config['conf_key']] = $config['conf_value'];
}
config($c, 'qfshop');
$this->initWechatConfig();
}
/**
* 微信服务登录 $this->user将为用户数据
*
* @param mixed $openid
* @return void
*/
protected function updateWechatUserInfo($openid)
{
$user = $this->easyWeChat->user->get($openid);
if (array_key_exists("errcode", $user)) {
return false;
} else {
$nickname = $user['nickname']??"";
$sex = $user['sex']??"";
$headimgurl = empty($user['headimgurl'])?'' : str_replace("http://", 'https://', $user['headimgurl']);
$this->user = $this->UserModel->where('openid', $openid)->find();
if (!$this->user) {
//注册
$data = ["openid" => $openid, "nickname" => $nickname, "head_pic" => $headimgurl, "sex" => $sex, "create_time" => time(), "update_time" => time()];
$this->UserModel->insert($data);
} else {
//更新
$this->UserModel->where('openid', $openid)->update(["nickname" => $nickname, "head_pic" => $headimgurl, "sex" => $sex,"update_time" => time()]);
}
$this->user = $this->UserModel->where('openid', $openid)->find();
return $this->user;
}
}
protected function initWechatConfig()
{
$this->wechat_appid = config("qfshop.mp_appid");
$this->wechat_appkey = config("qfshop.mp_appsecret");
if (!$this->wechat_appid || !$this->wechat_appkey) {
die('Input wechat appid and appkey first!');
}
$this->wechat_config = [
'app_id' => $this->wechat_appid,
'secret' => $this->wechat_appkey,
'token' => 'qfshop',
'aes_key' => 'qfshop',
//必须添加部分
'http' => [ // 配置
'verify' => false,
'timeout' => 4.0,
],
];
$this->easyWeChat = Factory::officialAccount($this->wechat_config);
$user_id = cookie('user_id');
$user_ticket = cookie('user_ticket');
if ($user_ticket == getTicket($user_id)) {
$this->user = $this->UserModel->where('user_id', $user_id)->find();
if ($this->user) {
$this->user = $this->user->toArray();
}
}
}
/**
* 调用微信授权
*
* @return void
*/
protected function authorize()
{
if ($this->user) {
return null;
}
//生成授权所需要的回调地址 并重定向到Authorize控制器进行微信授权
$callback = '/';
if ($this->module != "index") {
$callback .= strtolower($this->module) . '/';
} else {
if ($this->controller != "Index" && $this->action != "index") {
$callback .= strtolower($this->module) . '/';
}
}
if ($this->controller != "Index") {
$callback .= strtolower($this->controller) . '/';
} else {
if ($this->action != "index") {
$callback .= strtolower($this->controller) . '/';
}
}
if ($this->action != "index") {
$callback .= strtolower($this->action) . '/';
}
$i = 0;
foreach (input('get.') as $k => $v) {
if ($i == 0) {
$callback .= "?";
} else {
$callback .= "&";
}
if (!in_array($k, ['code', 'state', 'from', 'isappinstalled'])) {
$callback .= $k . "=" . $v;
}
$i++;
}
return redirect('/index/authorize?callback=' . urlencode($callback));
}
}
-43
View File
@@ -1,43 +0,0 @@
<?php
namespace app\index\controller;
use app\index\QfShop;
class Authorize extends QfShop
{
public function index()
{
$callback = '';
if (input('callback')) {
$callback = urldecode(input('callback'));
}
$callbackWechat = urlencode(getFullDomain() . "/index/authorize/callback/");
return redirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $this->wechat_appid . "&redirect_uri=" . $callbackWechat . "&response_type=code&scope=snsapi_base&state=" . urlencode($callback) . "#wechat_redirect");
}
public function callback()
{
$callback = '/index';
if (input('state')) {
$callback = urldecode(input('state'));
}
if (!input('code')) {
return redirect($callback);
}
$code = input('code');
$retStr = curlHelper("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" . $this->wechat_appid . "&secret=" . $this->wechat_appkey . "&code={$code}&grant_type=authorization_code")['body'];
$retObj = json_decode($retStr);
if (isset($retObj->errcode)) {
return redirect($callback);
} else {
$access_token = $retObj->access_token;
$openid = $retObj->openid;
if (!$this->updateWechatUserInfo($openid)) {
return redirect($callback);
}
cookie('user_id', $this->user['user_id'], 3600000);
cookie('user_ticket', getTicket($this->user['user_id']), 3600000);
return redirect($callback);
}
}
}
-32
View File
@@ -1,32 +0,0 @@
<?php
namespace app\index\controller;
use app\index\QfShop;
use think\facade\View;
class Error extends QfShop
{
public function __call($method, $args)
{
$error = $this->authorize();
if ($error) {
return $error;
}
View::assign('wechat', $this->wechat);
if (file_exists(app_path() . "/view/" . strtolower($this->request->controller()) . "/" . $method . ".html")) {
if (key_exists('callback', $args)) {
View::assign('callback', $args['callback']);
} else {
View::assign('callback', '/admin');
}
return View::fetch();
} else {
return 404;
}
}
public static function show($msg = null)
{
View::assign('msg', $msg);
return View::fetch("/error");
}
}
-29
View File
@@ -1,29 +0,0 @@
<?php
namespace app\index\controller;
use think\App;
use think\facade\View;
use think\facade\Request;
use think\facade\Cache;
use app\index\QfShop;
class Index extends QfShop
{
public function __construct(App $app)
{
parent::__construct($app);
}
/**
* @description: 报名页面
* @param {*}
* @return {*}
*/
public function index()
{
return View::fetch();
}
}
-24
View File
@@ -1,24 +0,0 @@
<?php
namespace app\index\controller;
use app\index\QfShop;
class Jssdk extends QfShop
{
protected $ServiceToken = 'QfShop';
protected $wechat;
public function index()
{
$this->easyWeChat->jssdk->setUrl(input('url'));
$ret = $this->easyWeChat->jssdk->buildConfig([
'scanQRCode',
'closeWindow',
'showMenuItems',
'hideAllNonBaseMenuItem',
'updateAppMessageShareData',
'updateTimelineShareData'
], false, false, false);
return $ret;
}
}
-310
View File
@@ -1,310 +0,0 @@
<!DOCTYPE html>
<html dir="ltr" lang="zh">
<head>
<meta charset="utf-8">
<meta name="theme-color" content="#fff">
<meta name="viewport" content="initial-scale=1, minimum-scale=1, width=device-width">
<title>提示</title>
<style>
a {
color: var(--link-color);
}
body {
--background-color: #fff;
--error-code-color: var(--google-gray-700);
--google-blue-100: rgb(210, 227, 252);
--google-blue-300: rgb(138, 180, 248);
--google-blue-600: rgb(26, 115, 232);
--google-blue-700: rgb(25, 103, 210);
--google-gray-100: rgb(241, 243, 244);
--google-gray-300: rgb(218, 220, 224);
--google-gray-500: rgb(154, 160, 166);
--google-gray-50: rgb(248, 249, 250);
--google-gray-600: rgb(128, 134, 139);
--google-gray-700: rgb(95, 99, 104);
--google-gray-800: rgb(60, 64, 67);
--google-gray-900: rgb(32, 33, 36);
--heading-color: var(--google-gray-900);
--primary-button-fill-color-active: var(--google-blue-700);
--primary-button-fill-color: var(--google-blue-600);
--primary-button-text-color: #fff;
--text-color: var(--google-gray-700);
background: var(--background-color);
color: var(--text-color);
word-wrap: break-word;
}
html {
-webkit-text-size-adjust: 100%;
font-size: 125%;
}
.icon {
background-repeat: no-repeat;
background-size: 100%;
}
@media (prefers-color-scheme: dark) {
body.captive-portal,
body.dark-mode-available,
body.neterror,
body.supervised-user-block,
.offline body {
--background-color: var(--google-gray-900);
--error-code-color: var(--google-gray-500);
--heading-color: var(--google-gray-500);
--link-color: var(--google-blue-300);
--primary-button-fill-color-active: rgb(129, 162, 208);
--primary-button-fill-color: var(--google-blue-300);
--primary-button-text-color: var(--google-gray-900);
--text-color: var(--google-gray-500);
}
}
</style>
<style>
button {
border: 0;
border-radius: 4px;
box-sizing: border-box;
color: var(--primary-button-text-color);
cursor: pointer;
float: right;
font-size: .875em;
margin: 0;
padding: 8px 16px;
transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1);
user-select: none;
}
[dir='rtl'] button {
float: left;
}
.ssl button {
background: var(--primary-button-fill-color);
}
button:active {
background: var(--primary-button-fill-color-active);
outline: 0;
}
h1 {
color: var(--heading-color);
font-size: 1.6em;
font-weight: normal;
line-height: 1.25em;
margin-bottom: 16px;
}
h2 {
font-size: 1.2em;
font-weight: normal;
}
.icon {
height: 72px;
margin: 0 0 40px;
width: 72px;
}
.interstitial-wrapper {
box-sizing: border-box;
font-size: 1em;
line-height: 1.6em;
margin: 14vh auto 0;
max-width: 600px;
width: 100%;
}
#main-message>p {
display: inline;
}
.nav-wrapper {
margin-top: 51px;
}
.nav-wrapper::after {
clear: both;
content: '';
display: table;
width: 100%;
}
@media (max-width: 700px) {
.interstitial-wrapper {
padding: 0 10%;
}
}
@media (max-width: 420px) {
button,
[dir='rtl'] button {
float: none;
font-size: .825em;
font-weight: 500;
margin: 0;
width: 100%;
}
button {
padding: 16px 24px;
}
.interstitial-wrapper {
padding: 0 5%;
}
.nav-wrapper {
margin-top: 30px;
}
}
@media (min-width: 240px) and (max-width: 420px) and (min-height: 401px),
(min-width: 421px) and (min-height: 240px) and (max-height: 560px) {
body .nav-wrapper {
background: var(--background-color);
bottom: 0;
box-shadow: 0 -22px 40px var(--background-color);
left: 0;
margin: 0 auto;
max-width: 736px;
padding-left: 24px;
padding-right: 24px;
position: fixed;
right: 0;
width: 100%;
z-index: 2;
}
.interstitial-wrapper {
max-width: 736px;
}
}
@media (max-width: 420px) and (orientation: portrait),
(max-height: 560px) {
body {
margin: 0 auto;
}
button,
[dir='rtl'] button,
button.small-link {
font-family: Roboto-Regular, Helvetica;
font-size: .933em;
margin: 6px 0;
transform: translatez(0);
}
.nav-wrapper {
box-sizing: border-box;
padding-bottom: 8px;
width: 100%;
}
h1 {
font-size: 1.5em;
margin-bottom: 8px;
}
.icon {
margin-bottom: 5.69vh;
}
.interstitial-wrapper {
box-sizing: border-box;
margin: 7vh auto 12px;
padding: 0 24px;
position: relative;
}
.interstitial-wrapper p {
font-size: .95em;
line-height: 1.61em;
margin-top: 8px;
}
}
@media (min-width: 421px) and (min-height: 500px) and (max-height: 560px) {
.interstitial-wrapper {
margin-top: 10vh;
}
}
@media (min-height: 400px) and (orientation:portrait) {
.interstitial-wrapper {
margin-bottom: 145px;
}
}
@media (min-height: 299px) {
.nav-wrapper {
padding-bottom: 16px;
}
}
@media (min-height: 500px) and (max-height: 650px) and (max-width: 414px) and (orientation: portrait) {
.interstitial-wrapper {
margin-top: 7vh;
}
}
@media (min-height: 650px) and (max-width: 414px) and (orientation: portrait) {
.interstitial-wrapper {
margin-top: 10vh;
}
}
.ssl .icon {
background-image: -webkit-image-set(url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAMAAABiM0N1AAABAlBMVEUAAADcRTfcRDfdRET/gIDcRjr/ZmbjVTncRDfcRTfcRDfdRDzgSTncRDjeSDvcRTjbRDfbRDjeRzvcRjfbRjjcRTjcRTjcRTfdRTfcRDjdRTjcRTjbRDjbRTjbRTjbRTfcRjjdRDrcRjfbRTjZQzfcRDjZRDfZRzbWQzXXRDXXQzbXQzbWQjXYSDvWQjbbRDfOQDPSQTTUQjXCPDDNPzPJPjLGPTHVQjXMPzPRQTTWQjXLPzPDPDHYQzbAOzDTQTXHPTLIPjK8Oi++Oy/FPTHEPTHPQDTQQDTUQTXBPDDKPjK/OzC9Oi/////PQDPRQDS3OS66OS7TQTTEPDHXQjbMPjMBhLaWAAAAL3RSTlMA4tgPAhYFCcL98B4x9ie1+s49WICbqXNKZY3pjuqcgVdLZnL2qKg9zmXpjfontV8LANsAAAJrSURBVHhe7ZTnduIwFAY3ARIgBAg9vW1v173ROylby/u/yso2Fx3MNaxs9h/zAHM+Sfa8+M/s2LFjx+3tdjwH+/sHWxHVAerb8KSyANnUFkRXwLiK78llgJHJxRalwSMd11OGOeV4nsM9FO0dxhJdw4LrOJ6jYy46PoohqgEHatE9JViiFNWTPIElTpIRRXcQ4C6aJ3EJAS4TkUQXsMJFFE++CCsU8xFEBSAoiHsaQNIQ7yuQCFe3DiHUhftKIlzdKoRSFe0r8sXDAkSoumkIigYaIOkIfeWi56EESFm8r1w0fFIl4epWgBA9qOMpmirCfeWijtoa9WSx6taAELFBRl/vilS3BJRIbRk9/VFTsLrifUXRuNfXLU0y/7m6p0CKxqN+v6lJU/k3eJxu7Os5LWKDHi1tYstKG1zON1X3DGiRMR80Mx3fdCbc1+bQe3o2SJrYXcV0fFMxL9xXiz0987BBtux65qaCeF8lHCR3FabBTQ3xvk4M1yN5B/Mw2+urew8hTP1BM38Qnu5evK8gMw+7IcfH9E3ZlEBfMSO//Kf35+Cm6ua+rhbSYDeEa9CUyW3qK1HIjj5DBz8dWd0bWCd6Ult/uMPEr+BmbV/JHrVG/a9MsEybV5fsK50R3frmBFXtCtVXmt73H4PhQ4t9k9rkJ55tYXwZrO4rCEUfPHfUEcuaZC/umw97TfaVpslu2tCb2lRWnBlKFtf+huwrjaa6Pxv7RfgW7nubJPtKI/X0puQO4k/Pfe/ovtLY7KbxVwve0/sE3VeaLosIbkEDvt8Hoq/hKGwQYvoq5OMnoq/hLAbgc/FVn33PX7pAfE5QHR6fAAAAAElFTkSuQmCC) 1x,
url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJAAAACQCAMAAADQmBKKAAABTVBMVEUAAADcRDf/ZmbcRjrjVTn/gIDdRETdRDzZQzbXQzXWQzbXQjbWQzXZRDbbRDnWQjXWQzXYSDvbRTjcRTjbRTfcRjfcRTjcRTjdRjncRTfdRTndRTfdRDrbRTjcRDnbRDfbRDjbRjfcRjfbRTjcRTjdRTjbRjjcRTjcRDjcRjncRTncRTndRDnbRTjcRDfZQzbcRTfgSTncRDfcRjjZQzjcRTfVRDbcRDjcRDjWQzXeRzvbRDjXRDXXQzbXQzbbRDfeSDvWQjbVQjXIPjLOQDPXQjbCPDDNPzPUQTXRQTS5OS7QQDTUQjW3OS7SQTTPQDTFPDHJPjK2OC26OS7HPjHOPzPLPjLMPjPRQDTGPDHTQTTEPTHLPzPGPTG7Oi/HPTLKPjLTQTXYQza9Oi/MPzPFPTHDPDHBPDC/OzC+Oy+8Oi/AOzDWQjX////bRDd3undHAAAAQnRSTlMA2AUWCQIPHj39wvbO8DH64ifqqYFmtrVMc1lKS5x0nY6PWKqbjYDpZXWCZ1py8Jv9McJXV+KA9qioPc5l6Y36J7VmcHe8AAAFWUlEQVR4XuzWS4rCQBSG0euz56ISgiaEjHwgGhAhDnRF3/6HDY1Ia5WPjP4a3LOKY28555xzzjnnnHPOuSyzpPR7vb6lZAUrS8hgB7uBpaMEKC0Zhz3A/mCpaPjTWCK23GwtCcMjN8ehpWDN3doS8HPi7vRjejX/1CbX8qA1sdGZB+eRaW14sjGp8YQnk7EpVQQqE7peCFyupjMnYm4yGVGZ7q1EyTZbEEche2uUbLMlL5W6t4Zkm22Ikm02561c89aQbLNTPpgq3hqSbbbmo1r41rhW8NaAaLMzvjITvDUg2WzFlyrBWwOCzc6Jkm12QQcL3Vtlmy3opFC9VbbZJR0tNW+Vbbahs0b41rhc8FbVZqdEyTb724t5/bYNA3G4e+80NYI0gGFkvaR779KKZUWuFKe7nlIsT5X//2M5VMZiZB9DQj74xW8ffrwjP90Mb/07Vf5CbXYJg0BtO4toKS9vhYHGY1vDZg28FQY6tBZls8tYBehwNLTyt1nhrTDQaDQcWAux2SJWAxpOBpWMWSvm4q0w0Gg4nFQqFTd/m72HlYBYQJV+w83bZu9jRaDJYEB4osjJ02aFt8JASUBRq+PlarMrWBGI8lQajVanXA5kopUcvBUEGrCAWhSoXs3PZtewKhA/MMbTbcpEa7l4KwwURZSHANnVnGz2CVYGmg6oZ1u1XGy2hNWBCA8BogE1m7Zl+ShNVMrdW2Wg/v+Amr2eRYCcGLBZU2+FgcSBESDfdZxdwGbNvBUGihKgnk1OjPAEwS5gsybeCgNNdTQLyAtqtRCwWQNvhYH4ndjtNnlAnlet1uIQsFl9b4WBpgNyaUCEJ45DwGa1vRUGanU6nMcmB+ZSnlosES3nvm/tUpGm1tFPd5DDAyKFBJGpzRaxSjW5J0o8/MAQ4ZEyKua/b+0Np175blMERDuaECFBZGqzBaxY9iAjIMbDK01U0OVZxcplE6BIjLzFRixgQDwflCJaXcC+1ToKyOYHFvCOljPiNmvurTBRI+oQoGTk2Z1YQyIeiWhlEftWnx8Yf8RcyiMCEkyhic2u4xOWSw9MBBQENTQFI83a+iL2rdgpJ1rms45mByYzhbDNwt6qTtTlQC7r6FT/CLRQ02ZLWKc8OmK+LzooCykhKpl4q7p+7B/d0SjNggRbqGOzm1gPqL3PX3niZakOQsenf1PDWzWAxr+JBtEDQxnnJTISNmvurfBK75t45bORBNGSobcqb9DqBCjdQOl5E370xthbYaDRiIjRDxKQwJk9a+o2u431gYZERBo/kcBIfvJ/TrSt6K1b+kDUHMkra2V3j5zRlprNbmADILbQ65S/z2ggyY82zL0VXsdQnnLdhSOKQzWbLWADIMpDgOrd3q958QiigrG3wusYzmNbXmY4sh+tangrVJ2Dgy97X9v0CmILzzIHcj3ZPTL+h6DN7mhYR5nxHI4mtKNbLCAmaX9QDDKFO6C36hDttcdJQFGLeTWRIupocGOj62cBb9WqesLTFwfm000MQgqz9lDLW+Hve35HM9Fnqw9HetBkNsF6+Yaet8Jf0+xbka0XbYspSMIg+5D8/8psnqdYv3qso1vsS9Hy6SaGQ6AYHP9ngLdqllVpiIB8RygRQjGEdOsc4K26RGzk6YTxjhbDDdzXcfwC8Fbd8glPnR4Y62gBAM/a1WybfYVNyyUBiZFPXYCAH70GvFW7nFRHH7EgyI8uAd6qXZ7NAqoilG6ZKuBH184D3qpdAQlIWp0p9dE7wFv1q8Y6+njLoPl+9P4C4K0GRKSjgTyywvoAeKtBxVWU6YhorovcvA14q0HtouwU0Fw/+jzN8w/cQ/zg6ug2/QAAAABJRU5ErkJggg==) 2x);
}
</style>
</head>
<body id="body" class="ssl extended-reporting-has-checkbox">
<div class="interstitial-wrapper">
<div id="main-content">
<div class="icon" id="icon"></div>
<div id="main-message">
<h1>提示</h1>
<p>{$msg}</p>
</div>
</div>
<div class="nav-wrapper">
<a href="javascript:history.go(-1);"><button id="primary-button">好的,我知道了</button></a>
</div>
</div>
<style>
html {
direction: ltr;
}
body {
font-family: system-ui, PingFang SC, STHeiti, sans-serif;
font-size: 75%;
}
button {
font-family: system-ui, PingFang SC, STHeiti, sans-serif;
}
</style>
</body>
</html>
-27
View File
@@ -1,27 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="/assets/uni.4906e6f8.css">
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title>心悦搜剧-短剧搜索</title>
<link rel="icon" href="/assets/logo-DQLPqAxx.png" />
<script src="./static/config.js"></script>
<script charset="UTF-8" id="LA_COLLECT" src="//sdk.51.la/js-sdk-pro.min.js"></script>
<script>LA.init({id:"3HsdT1GaTQzE091Y",ck:"3HsdT1GaTQzE091Y",hashMode:true})</script>
<!--preload-links-->
<!--app-context-->
<script type="module" crossorigin src="/assets/index-bFszJRU6.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BLVVqZ0m.css">
</head>
<body>
<div id="app"><!--app-html--></div>
</body>
</html>
-63
View File
@@ -1,63 +0,0 @@
<?php
namespace app\job;
use think\queue\Job;
use app\model\Source as SourceModel;
use app\model\SourceLog as SourceLogModel;
class InsertDataJob
{
// 处理具体的插入操作
public function fire(Job $job, $value)
{
try {
$this->model = new SourceModel();
$this->SourceLogModel = new SourceLogModel();
$logId = $value['logId'];
$detail = $this->model->where('title', $value['title'])->find();
if(empty($detail)){
$url = $value['url'];
$substring = strstr($url, 's/');
if ($substring !== false) {
$pwd_id = substr($substring, 2); // 去除 's/' 部分
$urlData = array(
'cookie' => Config('qfshop.quark_cookie'),
'url' => $url,
);
$res = curlHelper($value['urls']."/api/open/transfer", "POST", $urlData)['body'];
$res = json_decode($res, true);
if($res['code'] !== 200){
$this->SourceLogModel->editLog($logId,'fail_num',$res['message']);
return;
}
//添加资源到系统中
$data["title"] = $value['title'];
$data["url"] = $res['data']['share_url'];
$data["update_time"] = time();
$data["create_time"] = time();
$this->model->insertGetId($data);
$this->SourceLogModel->editLog($logId,'new_num','');
} else {
$this->SourceLogModel->editLog($logId,'fail_num','资源地址格式有误');
}
}else{
//如已有此资源 跳过
$this->SourceLogModel->editLog($logId,'skip_num','重复跳过转存');
}
// 处理完成后可以删除任务,避免重复执行
$job->delete();
} catch (\Exception $e) {
// 处理异常情况,例如记录日志等
\think\facade\Log::error('数据插入失败:' . $e->getMessage());
// 记录日志后可以选择重新放回队列,等待下次重试
// $job->release(60); // 重新放回队列,延迟 60 秒后重试
}
}
}
-12
View File
@@ -1,12 +0,0 @@
<?php
// 全局中间件定义文件
return [
// 跨域请求支持
\think\middleware\AllowCrossDomain::class,
// 全局请求缓存
// \think\middleware\CheckRequestCache::class,
// 多语言加载
// \think\middleware\LoadLangPack::class,
// Session初始化
\think\middleware\SessionInit::class
];
-36
View File
@@ -1,36 +0,0 @@
<?php
namespace app\model;
use app\model\QfShop;
class Access extends QfShop
{
/**
* 创建一个新的授权
*
* @param [int] AdminID
* @param [plat] 授权平台
* @return 授权信息|false
*/
public function createAccess($access_admin, $access_plat)
{
//将该平台下所有授权记录标记为失效
// $this->where([
// "access_admin" => $access_admin,
// "access_plat" => $access_plat
// ])->update(['access_status' => 1]);
//生成一个新的Access_token
$access_token = sha1(time()) . rand(100000, 99999) . sha1(time());
$access_id = $this->insertGetId([
"access_admin" => $access_admin,
"access_plat" => $access_plat,
"access_token" => $access_token,
"access_ip" => request()->ip(),
"access_createtime" => time(),
"access_updatetime" => time()
]);
$access = $this->where("access_id", $access_id)->find();
return $access ?? false;
}
}
-130
View File
@@ -1,130 +0,0 @@
<?php
namespace app\model;
use app\model\QfShop;
class Admin extends QfShop
{
/**
* 用户登录
*
* @param string 帐号
* @param string 密码
* @return void
*/
public function login($admin_account, $admin_password)
{
$admin = $this->where([
"admin_account" => $admin_account,
])->find();
if ($admin) {
//判断密码是否正确
$salt = $admin['admin_salt'];
$password = $admin['admin_password'];
if ($password != encodePassword($admin_password, $salt)) {
return false;
}
return $admin->toArray() ?? false;
} else {
return false;
}
}
public function getListByPage($maps, $order = null, $field = "*")
{
$resource = $this->view('admin', $field)->view('group', '*', 'group.group_id = admin.admin_group', 'left');
foreach ($maps as $map) {
switch (count($map)) {
case 1:
$resource = $resource->where($map[0]);
break;
case 2:
$resource = $resource->where($map[0], $map[1]);
break;
case 3:
$resource = $resource->where($map[0], $map[1], $map[2]);
break;
default:
}
}
if ($order) {
$resource = $resource->order($order);
}
return $resource->paginate($this->per_page);
}
/**
* 重置密码
*
* @param string UID
* @param string 密码
* @return void
*/
public function motifyPassword($admin_id, $password)
{
$access = new Access();
//将所有授权记录标记为失效
$access->where('access_admin', $admin_id)->update(['access_status' => 1]);
$salt = getRandString(4);
$password = encodePassword($password, $salt);
return $this->where([
"admin_id" => $admin_id
])->update([
"admin_password" => $password,
"admin_salt" => $salt,
]);
}
/**
* 通过帐号获取用户信息
*
* @param string 帐号/手机号
* @return void
*/
public function getAdminByAccount($admin_account)
{
$admin = $this->where([
"admin_account" => $admin_account
])->find();
if ($admin) {
return $admin->toArray() ?? false;
} else {
return false;
}
}
/**
* AccessToken获取用户信息
*
* @param string access_token
* @return void
*/
public function getAdminByAccessToken($access_token)
{
$Access = new Access();
$access = $Access->where([
"access_token" => $access_token,
"access_status" => 0,
])->find();
if ($access) {
if (time() > $access['access_updatetime'] + 7200) {
return false;
}
if ($access['access_updatetime'] - $access['access_createtime'] > 86400) {
return false;
}
$Access->where([
"access_id" => $access['access_id'],
])->update([
'access_updatetime' => time()
]);
$this->where("admin_id", $access['access_admin'])->update([
'admin_updatetime' => time()
]);
$admin = $this->where("admin_id", $access['access_admin'])->find();
return $admin->toArray() ?? false;
} else {
return false;
}
}
}
-9
View File
@@ -1,9 +0,0 @@
<?php
namespace app\model;
use app\model\QfShop;
class App extends QfShop
{
}
-9
View File
@@ -1,9 +0,0 @@
<?php
namespace app\model;
use app\model\QfShop;
class Attach extends QfShop
{
}
-191
View File
@@ -1,191 +0,0 @@
<?php
namespace app\model;
use think\facade\Db;
use app\model\QfShop;
class Auth extends QfShop
{
/**
* 判断用户组是否获得某节点的授权
*
* @param int 用户组ID
* @param int 节点ID
* @return void
*/
public function auth($auth_group, $auth_node)
{
$auth = $this->where([
"auth_group" => $auth_group,
"auth_node" => $auth_node
])->find();
return $auth ? true : false;
}
/**
* 根据用户组 获取管理后台菜单
*
* @param int 用户组ID
* @return void
*/
public function getAdminMenuListByAdminId($group_id)
{
if ($group_id == 1) {
//超级管理员组
$list = Node::where([
"node_pid" => 0,
"node_show" => 1,
])
->order("node_order desc,node_id asc")
->select();
for ($i = 0; $i < count($list); $i++) {
$list[$i]['subList'] = $this->getSubAdminListByPid($list[$i]['node_id'], $group_id);
for ($j = 0; $j < count($list[$i]['subList']); $j++) {
$list[$i]['subList'][$j]['subList'] = $this->getSubAdminListByPid($list[$i]['subList'][$j]['node_id'], $group_id);
}
}
return $list;
} else {
//其他组
$list = Node::where([
"node_pid" => 0,
"node_show" => 1,
])
->order("node_order desc,node_id asc")
->select();
for ($i = 0; $i < count($list); $i++) {
$list[$i]['subList'] = $this->getSubAdminListByPid($list[$i]['node_id'], 1);
for ($j = 0; $j < count($list[$i]['subList']); $j++) {
$list[$i]['subList'][$j]['subList'] = $this->getSubAdminListByPid($list[$i]['subList'][$j]['node_id'], 1);
}
}
if($list){
$list = $list->toArray();
}
$list2 = Node::alias("node")
->view('node', '*')
->view('auth', '*', 'node.node_id=auth.auth_node', 'left')
->where([
"node_module" => "qfadmin",
"node_show" => 1,
"auth_group" => $group_id
])
->order("node_order desc,node_id asc")
->select()->toArray();
foreach ($list2 as $k => $v) {
//一级
foreach ($list as $key => $value) {
if($v['node_id'] == $value['node_id']){
$list[$key]['select'] = 1;
}
//2级
foreach ($value['subList'] as $key2 => $value2) {
if($v['node_id'] == $value2['node_id']){
$list[$key]['subList'][$key2]['select'] = 1;
}
//3级
foreach ($value2['subList'] as $key3 => $value3) {
if($v['node_id'] == $value3['node_id']){
$list[$key]['subList'][$key2]['subList'][$key3]['select'] = 1;
}
}
}
}
}
foreach ($list as $key => $value) {
//一级
if(empty($value['select'])){
if(!empty($value['subList'])){
foreach ($value['subList'] as $key2 => $value2) {
//2级
if(empty($value2['select'])){
if(!empty($value2['subList'])){
foreach ($value2['subList'] as $key3 => $value3) {
//3级
if(empty($value3['select'])){
if(empty($value3['subList'])){
unset($list[$key]['subList'][$key2]['subList'][$key3]);
if(empty($list[$key]['subList'][$key2]['subList'])){
unset($list[$key]['subList'][$key2]);
}
}
}
}
}else{
unset($list[$key]['subList'][$key2]);
if(empty($list[$key]['subList'])){
unset($list[$key]);
}
}
}
}
}else{
unset($list[$key]);
}
}
}
$list = array_values($list);
foreach ($list as $key => $value) {
if(!empty($value['subList'])){
$list[$key]['subList'] = array_values($list[$key]['subList']);
foreach ($value['subList'] as $key2 => $value2) {
if(!empty($value2['subList'])){
try {
$list[$key]['subList'][$key2]['subList'] = array_values($list[$key]['subList'][$key2]['subList']);
} catch (\Throwable $th) {
//throw $th;
}
}
}
}
}
return $list;
}
}
/**
* 根据节点ID 获取用户组的子菜单
*
* @param int 节点ID
* @param int 用户组ID
* @return void
*/
public function getSubAdminListByPid($node_id, $group_id = 1)
{
if ($group_id == 1) {
//超级管理员组
return Node::where([
"node_pid" => $node_id,
"node_show" => 1
])
->order("node_order desc,node_id asc")
->select();
} else {
//其他组
return Node::alias("node")
->view('node', '*')
->view('auth', '*', 'node.node_id=auth.auth_node', 'left')
->where([
"node_pid" => $node_id,
"node_show" => 1,
"auth_group" => $group_id
])
->order("node_order desc,node_id asc")
->select();
}
}
/**
* 删除授权记录
*
* @return void
*/
public function cleanAuth()
{
//清空auth表
Db::execute("truncate table " . config('database.connections.mysql.prefix') . "auth");
return true;
}
}
-30
View File
@@ -1,30 +0,0 @@
<?php
namespace app\model;
use app\model\QfShop;
class Conf extends QfShop
{
/**
* 更新配置
*
* @param string 配置key
* @param string 配置值
* @param int 整形配置
* @param string 配置描述
* @return void
*/
public function updateConf($key, $value, $int = 0, $desc = null)
{
$data = [];
if ($desc) {
$data['conf_desc'] = $desc;
}
$data['conf_value'] = $value;
$this->where([
"conf_key" => $key,
"conf_readonly" => 0,
])->update($data);
}
}
-36
View File
@@ -1,36 +0,0 @@
<?php
namespace app\model;
use app\model\QfShop;
class Feedback extends QfShop
{
/**
* 主键
* @var string
*/
protected $pk = 'id';
/**
* 是否需要自动写入时间戳
* @var bool
*/
protected $autoWriteTimestamp = true;
/**
* 只读属性
* @var array
*/
protected $readonly = [
'id',
];
/**
* 字段类型或者格式转换
* @var array
*/
protected $type = [
'id' => 'integer',
];
}
-9
View File
@@ -1,9 +0,0 @@
<?php
namespace app\model;
use app\model\QfShop;
class Group extends QfShop
{
}
-9
View File
@@ -1,9 +0,0 @@
<?php
namespace app\model;
use app\model\QfShop;
class Node extends QfShop
{
}
-226
View File
@@ -1,226 +0,0 @@
<?php
namespace app\model;
use think\Model;
use think\helper\Str;
use app\model\Token as TokenModel;
/**
* QfShop 数据模型基类
*/
class QfShop extends Model
{
/**
* 默认分页获取条数
*
* @var int 默认分页获取条数
*/
public $page_size = 40;
public $per_page = 10;
/**
* 翻页搜索器
* @access public
* @param object $query
* @param mixed $value
* @param mixed $data
*/
public function searchPageAttr($query, $value, $data)
{
$pageNo = isset($data['page_no']) ? $data['page_no'] : 1;
$pageSize = isset($data['page_size']) ? $data['page_size'] : $this->page_size;
$query->page($pageNo, $pageSize);
}
/**
* 排序搜索器
* @access public
* @param object $query
* @param mixed $value
* @param mixed $data
*/
public function searchOrderAttr($query, $value, $data)
{
$order = [];
if (!empty($data['order_field']) || !empty($data['order_type'])) {
$order[$data['order_field']] = $data['order_type'];
} else {
$order = $this->defaultOrder;
}
if (!empty($this->fixedOrder)) {
// 固定排序必须在前,否则将导致自定义排序无法覆盖
$order = array_merge($this->fixedOrder, $order);
if (!empty($data['order_field']) && $this->isReverse) {
$order = array_reverse($order);
}
}
if (!empty($order)) {
$query->order($order);
}
}
/**
* 设置默认排序
* @access public
* @param array $order 默认排序
* @param array $fixed 固定排序
* @param bool $reverse 是否调整顺序
* @return $this
*/
public function setDefaultOrder(array $order, $fixed = [], $reverse = false)
{
$this->defaultOrder = $order;
$this->fixedOrder = $fixed;
$this->isReverse = $reverse;
return $this;
}
/**
* 模型验证器
* @access public
* @param array|object $data 验证数据
* @param string|null $scene 场景名
* @param bool $clean 是否清理规则键值不存在的$data
* @param string $validate 验证器规则或类
* @return bool
*/
public function validateData(array &$data, $scene = null, $clean = false, $validate = '')
{
try {
// 确定规则来源
if (empty($validate)) {
$class = '\\app\\validate\\' . $this->getName();
if ($scene) {
$v = new $class();
$v->extractScene($data, $scene, $clean, $this->getPk());
} else {
$v = validate($class);
}
} else {
$v = validate($validate);
if ($scene) {
$v->extractScene($data, $scene, $clean, $this->getPk());
}
}
if ($clean) {
$keys = $v->getRuleKey();
foreach ($data as $key => $value) {
if (!in_array($key, $keys, true)) {
unset($data[$key]);
}
}
unset($key, $value);
}
$v->failException(true)->check($data);
} catch (ValidateException $e) {
return $this->setError($e->getMessage());
}
return true;
}
/**
* 检测是否存在相同值
* @access public
* @param array $map 查询条件
* @return bool false:不存在
*/
public static function checkUnique(array $map)
{
if (empty($map)) {
return true;
}
$count = self::where($map)->count();
if (is_numeric($count) && $count <= 0) {
return false;
}
return true;
}
/**
* 后台使用分页获取数据
*
* @param array 筛选数组
* @param string 排序方式
* @param string 搜索字段
* @return void
*/
public function getListByPage($maps, $order = null, $field = "*")
{
$resource = $this->field($field);
foreach ($maps as $map) {
switch (count($map)) {
case 1:
$resource = $resource->where($map[0]);
break;
case 2:
$resource = $resource->where($map[0], $map[1]);
break;
case 3:
$resource = $resource->where($map[0], $map[1], $map[2]);
break;
default:
}
}
if ($order) {
$resource = $resource->order($order);
}
return $resource->paginate($this->per_page);
}
/**
* 替换数组中的驼峰键名为下划线
* @access public
* @param array $name 需要修改的键名
* @param array &$data 源数据
*/
public static function keyToSnake(array $name, array &$data)
{
if (!is_array($name)) {
return;
}
foreach ($name as $value) {
foreach ($data as &$item) {
if (!array_key_exists($value, $item)) {
continue;
}
$temp = $item[$value];
unset($item[$value]);
$item[Str::snake($value)] = $temp;
}
}
}
/**
* 将数组键名驼峰转下划线
* @access public
* @param array $data 数据
* @return array
*/
public static function snake(array $data)
{
if (empty($data)) {
return [];
}
foreach ($data as $itemKey => $item) {
foreach ($item as $valueKey => $value) {
$data[$itemKey][Str::snake($valueKey)] = $value;
unset($data[$itemKey][$valueKey]);
}
}
return $data;
}
}
-133
View File
@@ -1,133 +0,0 @@
<?php
namespace app\model;
class Sms
{
/**
* 发送通知短信
*
* @param string 手机号码
* @param string 内容
* @param string 签到二维码链接
* @return void
*/
public function sendSmsNotice($smsData)
{
//短连接生成
$baidu_token = config('qfshop.baidu_token');
if (!$baidu_token) {
jerr('请先在后台系统设置短链接相关参数!');
}
$urlData = [
[
'LongUrl' => $smsData['qrcodeUrl'],
'TermOfValidity' => "1-year",
]
];
$urlHeader = array(
'Content-Type: application/json; charset=UTF-8',
'Dwz-Token: '.$baidu_token,
);
$res = curlHelper("https://dwz.cn/api/v3/short-urls", "POST", json_encode($urlData,256), $urlHeader)['body'];
$res = json_decode($res, true);
if($res['Code'] != 0){
return false;
}
$smsData['qrcodeurl'] = $res['ShortUrls'][0]['ShortUrl'];
$result = $this->sendSms($smsData);
if($result){
return true;
}else{
return false;
}
}
/**
* 发送短信(百度)
*
* @param string 手机号码
* @param string 内容
* @return void
*/
private function sendSms($smsData)
{
//初始化短信相关配置
$sms_sign = config('qfshop.sms_sign');
$sms_tmpl = config('qfshop.sms_tmpl_1');
$error = null;
if (!($sms_sign && $sms_tmpl)) {
$error = jerr('请先在后台系统设置短信相关参数!');
}
require_once __DIR__ . "/../../extend/baidu/baidusmsv3.php";
$config = array(
'endPoint' => 'smsv3.bj.baidubce.com',
'accessKey' => 'b71eab07ebcc4f09b3f770e43a9d126d',
'secretAccessKey' => '3c6c8b3d85274baab4c38481996919ec',
);
$smsClient = new \Baidusmsv3($config);
$message = array(
'template' => $sms_tmpl, //短信模板ID
'signatureId' => $sms_sign, //短信签名ID
'mobile' => $smsData['mobile'],
"contentVar" => array(
'param1' => '“'.$smsData['title'].'“',
'param2' => $smsData['time'],
'param3' => $smsData['address'],
'param4' => '青峰网络',
'param5' => $smsData['qrcodeurl'],
),
);
$result = $smsClient->sendMessage($message);
if($result['code'] == 1000){
return true;
}else{
return false;
}
}
/**
* 发送短信验证码
*
* @param string 手机号码
* @return void
*/
public function sendSmsCode($mobile,$code)
{
//初始化短信相关配置
$sms_sign = config('qfshop.sms_sign');
$sms_tmpl = config('qfshop.sms_tmpl_2');
$error = null;
if (!($sms_sign && $sms_tmpl)) {
$error = jerr('请先在后台系统设置短信相关参数!');
}
require_once __DIR__ . "/../../extend/baidu/baidusmsv3.php";
$config = array(
'endPoint' => 'smsv3.bj.baidubce.com',
'accessKey' => 'b71eab07ebcc4f09b3f770e43a9d126d',
'secretAccessKey' => '3c6c8b3d85274baab4c38481996919ec',
);
$smsClient = new \Baidusmsv3($config);
$message = array(
'template' => $sms_tmpl, //短信模板ID
'signatureId' => $sms_sign, //短信签名ID
'mobile' => $mobile,
"contentVar" => array(
'code' => ''.$code,
'time' => '5',
),
);
$result = $smsClient->sendMessage($message);
if($result['code'] == 1000){
return true;
}else{
return false;
}
}
}
-203
View File
@@ -1,203 +0,0 @@
<?php
namespace app\model;
use app\model\QfShop;
class Source extends QfShop
{
/**
* 主键
* @var string
*/
protected $pk = 'source_id';
/**
* 是否需要自动写入时间戳
* @var bool
*/
protected $autoWriteTimestamp = true;
/**
* 只读属性
* @var array
*/
protected $readonly = [
'source_id',
];
/**
* 字段类型或者格式转换
* @var array
*/
protected $type = [
'source_id' => 'integer',
'is_delete' => 'integer',
'status' => 'integer',
'time' => 'timestamp',
];
/**
* hasOne qf_source_category
* @access public
* @return mixed
*/
public function category()
{
return $this
->hasOne(SourceCategory::class, 'source_category_id', 'source_category_id')
->joinType('left')
->field('source_category_id,name');
}
/**
* @description: 获取一个信息
* @param {*} $code
* @return {*}
*/
public function getDetail(array $data)
{
$map[] = ['status', '=', 1];
$map[] = ['is_delete', '=', 0];
$map[] = ['source_id', '=', $data['id']];
$field = 'source_id as id,source_category_id,title,url,update_time as time';
$result = $this->with('category')->where($map)->field($field)->find();
if(!is_null($result)){
$result->inc('page_views')->update();
}
$result['times'] = substr($result['time'], 0, 10);
unset($result['time']);
return $result;
}
/**
* 获取列表
* @access public
* @param array $data 外部数据
* @return array|false
* @throws
*/
public function getList(array $data)
{
// 搜索条件
$map = [];
empty($data['title']) ?: $map[] = ['title', 'like', '%' . $data['title'] . '%'];
$map[] = ['status', '=', 1];
$map[] = ['is_time', '=', 0];
if(!empty($data['day']) && $data['day']==2){
// 获取今天的时间戳范围
$todayStart = strtotime(date('Y-m-d'));
$todayEnd = $todayStart + 86400; // 86400 秒 = 24 小时
// 获取昨天的时间戳范围
$yesterdayStart = $todayStart - 86400;
$yesterdayEnd = $todayStart;
// 添加日期范围条件
$map[] = ['create_time', 'between', [$yesterdayStart, $todayEnd]];
}
if(!empty($data['is_time']) && $data['is_time']==1){
unset($map[array_search(['is_time', '=', 0], $map)]);
}
if(!empty($data['category_id'])){
$map[] = ['source_category_id', '=', $data['category_id']];
}
$result['total_result'] = $this->where($map)->count();
if ($result['total_result'] <= 0) {
return $result;
}
$order = ['source_id' => 'desc'];
if(!empty($data['type']) && $data['type']==2){
$order = ['source_id' => 'asc'];
}
$result['items'] = $this->setDefaultOrder($order)
->field('source_id as id,source_category_id,title,url,update_time as time,is_time')
->with('category')
->where($map)
->withSearch(['page', 'order'], $data)
->select()->each(function($item,$key){
$item['times'] = substr($item['time'], 0, 10);
unset($item['time']);
return $item;
})
->toArray();
return $result;
}
/**
* 获取最新
* @access public
* @param array $data 外部数据
* @return array|false
* @throws
*/
public function getNew(array $data)
{
// 搜索条件
$map = [];
$map[] = ['status', '=', 1];
$map[] = ['is_time', '=', 0];
$result['total_result'] = $this->where($map)->count();
if ($result['total_result'] <= 0) {
return $result;
}
$result['items'] = $this->setDefaultOrder(['update_time' => 'desc'])
->field('title,update_time as time')
->where($map)
->withSearch(['page', 'order'], $data)
->select()->each(function($item,$key){
$item['times'] = substr($item['time'], 5, 5);
unset($item['time']);
return $item;
})
->toArray();
return $result;
}
/**
* 获取最热
* @access public
* @param array $data 外部数据
* @return array|false
* @throws
*/
public function getHot(array $data)
{
// 搜索条件
$map = [];
$map[] = ['status', '=', 1];
$map[] = ['is_time', '=', 0];
$result['total_result'] = $this->where($map)->count();
if ($result['total_result'] <= 0) {
return $result;
}
$result['items'] = $this->setDefaultOrder(['page_views' => 'desc'])
->field('title,update_time as time')
->where($map)
->withSearch(['page', 'order'], $data)
->select()->each(function($item,$key){
$item['times'] = substr($item['time'], 5, 5);
unset($item['time']);
return $item;
})
->toArray();
return $result;
}
}
-25
View File
@@ -1,25 +0,0 @@
<?php
namespace app\model;
use app\model\QfShop;
class SourceCategory extends QfShop
{
/**
* 获取列表
* @access public
* @param array $data 外部数据
* @return array|false
* @throws
*/
public function getList(array $data)
{
// 搜索条件
$map = [];
$map[] = ['status', '=', 0];
$result = $this->where($map)->order('sort', 'desc')->select();
return $result;
}
}
-79
View File
@@ -1,79 +0,0 @@
<?php
namespace app\model;
use app\model\QfShop;
class SourceLog extends QfShop
{
/**
* 主键
* @var string
*/
protected $pk = 'source_log_id';
/**
* 是否需要自动写入时间戳
* @var bool
*/
protected $autoWriteTimestamp = true;
/**
* 只读属性
* @var array
*/
protected $readonly = [
'source_log_id',
];
/**
* 字段类型或者格式转换
* @var array
*/
protected $type = [
'source_log_id' => 'integer',
'end_time' => 'timestamp',
];
public function addLog($name="任务名称",$total_num=0)
{
try {
$Log = [
'name' => $name,
'total_num' => $total_num,
'create_time' => time(),
'update_time' => time(),
];
$logId = $this->insertGetId($Log);
return $logId;
} catch (\Throwable $th) {
//throw $th;
}
}
public function editLog($source_log_id,$total_num,$edit_name,$fail_dec='',$type=0)
{
try {
$data = [];
$data['total_num'] = $total_num;
if(!empty($fail_dec)){
$data['fail_dec'] = $fail_dec;
}
$data['update_time'] = time();
if($type==3){
$this->where('source_log_id', $source_log_id)
->update(['end_time' => time()]);
}else{
if($type==1){
$data['end_time'] = time();
}
$this->where('source_log_id', $source_log_id)
->inc($edit_name)
->update($data);
}
} catch (\Throwable $th) {
//throw $th;
}
}
}
-83
View File
@@ -1,83 +0,0 @@
<?php
namespace app\model;
use app\model\QfShop;
class Token extends QfShop
{
/**
* 创建更新一个新的授权
*
* @param [int] 用户ID
* @param [plat] 授权平台
* @return 授权信息|false
*/
public function createAccess($user_id, $platform)
{
$token = $this->where([
"user_id" => $user_id,
"platform" => $platform
])->find();
//生成一个新的Access_token
$access_token = sha1(time()) . rand(100000, 99999) . sha1(time());
$expires = time() + (30 * 24 * 60 * 60); // 30天
if($token){
//如果已有token 执行更新
$token_id = $token['token_id'];
$this->where('token_id',$token_id)->update([
"token" => $access_token,
"ip" => request()->ip(),
"token_expires" => $expires,
"create_time" => time(),
]);
}else{
//如果没有token 执行新增
$token_id = $this->insertGetId([
"user_id" => $user_id,
"platform" => $platform,
"token" => $access_token,
"ip" => request()->ip(),
"token_expires" => $expires,
"create_time" => time(),
]);
}
$access = $this->where("token_id", $token_id)->find();
return $access ?? false;
}
/**
* 授权校验
*
* @param string token
* @return void
* 校验成功 更新授权码过期时间
*/
public function getToken($access_token)
{
$token = $this->where([
"token" => $access_token
])->find();
if ($token) {
if (time() > $token['token_expires']) {
return false;
}
$expires = time() + (30 * 24 * 60 * 60); // 30天
$this->where([
"token_id" => $token['token_id'],
])->update([
'token_expires' => $expires
]);
$user = User::field("user_id,status,mobile")->where(["user_id" => $token['user_id'],"is_delete" => 0])->find();
if(!$user){
return jerr("账号不存在");
}
if ($user['status'] == 0) {
return jerr("你的账户被禁用");
}
return $user;
} else {
return false;
}
}
}
-9
View File
@@ -1,9 +0,0 @@
<?php
namespace app\model;
use app\model\QfShop;
class User extends QfShop
{
}
-108
View File
@@ -1,108 +0,0 @@
<?php
namespace app\model;
//验证码类
class Validate
{
private $charset = 'abcdefghkmnprstuvwxyzABCDEFGHKMNPRSTUVWXYZ23456789'; //随机因子
private $code; //验证码
private $codelen = 4; //验证码长度
private $width = 130; //宽度
private $height = 50; //高度
private $img; //图形资源句柄
private $font; //指定的字体
private $fontsize = 20; //指定字体大小
private $fontcolor; //指定字体颜色
//构造方法初始化
public function __construct()
{
$this->font = $_SERVER['DOCUMENT_ROOT'] . '/static/admin/css/fonts/code.ttc';
}
//生成随机码
private function createCode()
{
$_len = strlen($this->charset) - 1;
for ($i = 0; $i < $this->codelen; $i++) {
$this->code .= $this->charset[mt_rand(0, $_len)];
}
}
//生成背景
private function createBg()
{
$this->img = imagecreatetruecolor($this->width, $this->height);
$color = imagecolorallocate($this->img, mt_rand(157, 255), mt_rand(157, 255), mt_rand(157, 255));
imagefilledrectangle($this->img, 0, $this->height, $this->width, 0, $color);
}
//生成文字
private function createFont()
{
$_x = $this->width / $this->codelen;
for ($i = 0; $i < $this->codelen; $i++) {
$this->fontcolor = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
imagettftext($this->img, $this->fontsize, mt_rand(-30, 30), $_x * $i + mt_rand(1, 5), $this->height / 1.4, $this->fontcolor, $this->font, $this->code[$i]);
}
}
//生成线条、雪花
private function createLine()
{
for ($i = 0; $i < 6; $i++) {
$color = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
imageline($this->img, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $color);
}
for ($i = 0; $i < 100; $i++) {
$color = imagecolorallocate($this->img, mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255));
imagestring($this->img, mt_rand(1, 5), mt_rand(0, $this->width), mt_rand(0, $this->height), '*', $color);
}
}
//对外生成
public function getImg()
{
$this->createBg();
$this->createCode();
$this->createLine();
$this->createFont();
imagepng($this->img);
$image_data = ob_get_contents();
ob_end_clean();
imagedestroy($this->img);
return "data:image/png;base64," . base64_encode($image_data);
}
//获取验证码
public function getCode()
{
return strtolower($this->code);
}
/**
* 验证图形验证码
*
* @return void
*/
public function validateImgCode($token, $code)
{
if (!$token) {
return jerr("TOKEN参数丢失");
}
if (!$code) {
return jerr("请输入验证码");
}
$code = strtoupper($code);
$token = $token;
$_code = cache($token);
if (!$_code) {
return jerr("验证码已过期");
}
if ($code != $_code) {
return jerr('验证码错误');
}
// 删除设置的缓存
cache($token, null);
return null;
}
}
-310
View File
@@ -1,310 +0,0 @@
<!DOCTYPE html>
<html dir="ltr" lang="zh">
<head>
<meta charset="utf-8">
<meta name="theme-color" content="#fff">
<meta name="viewport" content="initial-scale=1, minimum-scale=1, width=device-width">
<title>系统错误</title>
<style>
a {
color: var(--link-color);
}
body {
--background-color: #fff;
--error-code-color: var(--google-gray-700);
--google-blue-100: rgb(210, 227, 252);
--google-blue-300: rgb(138, 180, 248);
--google-blue-600: rgb(26, 115, 232);
--google-blue-700: rgb(25, 103, 210);
--google-gray-100: rgb(241, 243, 244);
--google-gray-300: rgb(218, 220, 224);
--google-gray-500: rgb(154, 160, 166);
--google-gray-50: rgb(248, 249, 250);
--google-gray-600: rgb(128, 134, 139);
--google-gray-700: rgb(95, 99, 104);
--google-gray-800: rgb(60, 64, 67);
--google-gray-900: rgb(32, 33, 36);
--heading-color: var(--google-gray-900);
--primary-button-fill-color-active: var(--google-blue-700);
--primary-button-fill-color: var(--google-blue-600);
--primary-button-text-color: #fff;
--text-color: var(--google-gray-700);
background: var(--background-color);
color: var(--text-color);
word-wrap: break-word;
}
html {
-webkit-text-size-adjust: 100%;
font-size: 125%;
}
.icon {
background-repeat: no-repeat;
background-size: 100%;
}
@media (prefers-color-scheme: dark) {
body.captive-portal,
body.dark-mode-available,
body.neterror,
body.supervised-user-block,
.offline body {
--background-color: var(--google-gray-900);
--error-code-color: var(--google-gray-500);
--heading-color: var(--google-gray-500);
--link-color: var(--google-blue-300);
--primary-button-fill-color-active: rgb(129, 162, 208);
--primary-button-fill-color: var(--google-blue-300);
--primary-button-text-color: var(--google-gray-900);
--text-color: var(--google-gray-500);
}
}
</style>
<style>
button {
border: 0;
border-radius: 4px;
box-sizing: border-box;
color: var(--primary-button-text-color);
cursor: pointer;
float: right;
font-size: .875em;
margin: 0;
padding: 8px 16px;
transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1);
user-select: none;
}
[dir='rtl'] button {
float: left;
}
.ssl button {
background: var(--primary-button-fill-color);
}
button:active {
background: var(--primary-button-fill-color-active);
outline: 0;
}
h1 {
color: var(--heading-color);
font-size: 1.6em;
font-weight: normal;
line-height: 1.25em;
margin-bottom: 16px;
}
h2 {
font-size: 1.2em;
font-weight: normal;
}
.icon {
height: 72px;
margin: 0 0 40px;
width: 72px;
}
.interstitial-wrapper {
box-sizing: border-box;
font-size: 1em;
line-height: 1.6em;
margin: 14vh auto 0;
max-width: 600px;
width: 100%;
}
#main-message>p {
display: inline;
}
.nav-wrapper {
margin-top: 51px;
}
.nav-wrapper::after {
clear: both;
content: '';
display: table;
width: 100%;
}
@media (max-width: 700px) {
.interstitial-wrapper {
padding: 0 10%;
}
}
@media (max-width: 420px) {
button,
[dir='rtl'] button{
float: none;
font-size: .825em;
font-weight: 500;
margin: 0;
width: 100%;
}
button {
padding: 16px 24px;
}
.interstitial-wrapper {
padding: 0 5%;
}
.nav-wrapper {
margin-top: 30px;
}
}
@media (min-width: 240px) and (max-width: 420px) and (min-height: 401px),
(min-width: 421px) and (min-height: 240px) and (max-height: 560px) {
body .nav-wrapper {
background: var(--background-color);
bottom: 0;
box-shadow: 0 -22px 40px var(--background-color);
left: 0;
margin: 0 auto;
max-width: 736px;
padding-left: 24px;
padding-right: 24px;
position: fixed;
right: 0;
width: 100%;
z-index: 2;
}
.interstitial-wrapper {
max-width: 736px;
}
}
@media (max-width: 420px) and (orientation: portrait),
(max-height: 560px) {
body {
margin: 0 auto;
}
button,
[dir='rtl'] button,
button.small-link {
font-family: Roboto-Regular, Helvetica;
font-size: .933em;
margin: 6px 0;
transform: translatez(0);
}
.nav-wrapper {
box-sizing: border-box;
padding-bottom: 8px;
width: 100%;
}
h1 {
font-size: 1.5em;
margin-bottom: 8px;
}
.icon {
margin-bottom: 5.69vh;
}
.interstitial-wrapper {
box-sizing: border-box;
margin: 7vh auto 12px;
padding: 0 24px;
position: relative;
}
.interstitial-wrapper p {
font-size: .95em;
line-height: 1.61em;
margin-top: 8px;
}
}
@media (min-width: 421px) and (min-height: 500px) and (max-height: 560px) {
.interstitial-wrapper {
margin-top: 10vh;
}
}
@media (min-height: 400px) and (orientation:portrait) {
.interstitial-wrapper {
margin-bottom: 145px;
}
}
@media (min-height: 299px) {
.nav-wrapper {
padding-bottom: 16px;
}
}
@media (min-height: 500px) and (max-height: 650px) and (max-width: 414px) and (orientation: portrait) {
.interstitial-wrapper {
margin-top: 7vh;
}
}
@media (min-height: 650px) and (max-width: 414px) and (orientation: portrait) {
.interstitial-wrapper {
margin-top: 10vh;
}
}
.ssl .icon {
background-image: -webkit-image-set(url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAMAAABiM0N1AAABAlBMVEUAAADcRTfcRDfdRET/gIDcRjr/ZmbjVTncRDfcRTfcRDfdRDzgSTncRDjeSDvcRTjbRDfbRDjeRzvcRjfbRjjcRTjcRTjcRTfdRTfcRDjdRTjcRTjbRDjbRTjbRTjbRTfcRjjdRDrcRjfbRTjZQzfcRDjZRDfZRzbWQzXXRDXXQzbXQzbWQjXYSDvWQjbbRDfOQDPSQTTUQjXCPDDNPzPJPjLGPTHVQjXMPzPRQTTWQjXLPzPDPDHYQzbAOzDTQTXHPTLIPjK8Oi++Oy/FPTHEPTHPQDTQQDTUQTXBPDDKPjK/OzC9Oi/////PQDPRQDS3OS66OS7TQTTEPDHXQjbMPjMBhLaWAAAAL3RSTlMA4tgPAhYFCcL98B4x9ie1+s49WICbqXNKZY3pjuqcgVdLZnL2qKg9zmXpjfontV8LANsAAAJrSURBVHhe7ZTnduIwFAY3ARIgBAg9vW1v173ROylby/u/yso2Fx3MNaxs9h/zAHM+Sfa8+M/s2LFjx+3tdjwH+/sHWxHVAerb8KSyANnUFkRXwLiK78llgJHJxRalwSMd11OGOeV4nsM9FO0dxhJdw4LrOJ6jYy46PoohqgEHatE9JViiFNWTPIElTpIRRXcQ4C6aJ3EJAS4TkUQXsMJFFE++CCsU8xFEBSAoiHsaQNIQ7yuQCFe3DiHUhftKIlzdKoRSFe0r8sXDAkSoumkIigYaIOkIfeWi56EESFm8r1w0fFIl4epWgBA9qOMpmirCfeWijtoa9WSx6taAELFBRl/vilS3BJRIbRk9/VFTsLrifUXRuNfXLU0y/7m6p0CKxqN+v6lJU/k3eJxu7Os5LWKDHi1tYstKG1zON1X3DGiRMR80Mx3fdCbc1+bQe3o2SJrYXcV0fFMxL9xXiz0987BBtux65qaCeF8lHCR3FabBTQ3xvk4M1yN5B/Mw2+urew8hTP1BM38Qnu5evK8gMw+7IcfH9E3ZlEBfMSO//Kf35+Cm6ua+rhbSYDeEa9CUyW3qK1HIjj5DBz8dWd0bWCd6Ult/uMPEr+BmbV/JHrVG/a9MsEybV5fsK50R3frmBFXtCtVXmt73H4PhQ4t9k9rkJ55tYXwZrO4rCEUfPHfUEcuaZC/umw97TfaVpslu2tCb2lRWnBlKFtf+huwrjaa6Pxv7RfgW7nubJPtKI/X0puQO4k/Pfe/ovtLY7KbxVwve0/sE3VeaLosIbkEDvt8Hoq/hKGwQYvoq5OMnoq/hLAbgc/FVn33PX7pAfE5QHR6fAAAAAElFTkSuQmCC) 1x,
url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJAAAACQCAMAAADQmBKKAAABTVBMVEUAAADcRDf/ZmbcRjrjVTn/gIDdRETdRDzZQzbXQzXWQzbXQjbWQzXZRDbbRDnWQjXWQzXYSDvbRTjcRTjbRTfcRjfcRTjcRTjdRjncRTfdRTndRTfdRDrbRTjcRDnbRDfbRDjbRjfcRjfbRTjcRTjdRTjbRjjcRTjcRDjcRjncRTncRTndRDnbRTjcRDfZQzbcRTfgSTncRDfcRjjZQzjcRTfVRDbcRDjcRDjWQzXeRzvbRDjXRDXXQzbXQzbbRDfeSDvWQjbVQjXIPjLOQDPXQjbCPDDNPzPUQTXRQTS5OS7QQDTUQjW3OS7SQTTPQDTFPDHJPjK2OC26OS7HPjHOPzPLPjLMPjPRQDTGPDHTQTTEPTHLPzPGPTG7Oi/HPTLKPjLTQTXYQza9Oi/MPzPFPTHDPDHBPDC/OzC+Oy+8Oi/AOzDWQjX////bRDd3undHAAAAQnRSTlMA2AUWCQIPHj39wvbO8DH64ifqqYFmtrVMc1lKS5x0nY6PWKqbjYDpZXWCZ1py8Jv9McJXV+KA9qioPc5l6Y36J7VmcHe8AAAFWUlEQVR4XuzWS4rCQBSG0euz56ISgiaEjHwgGhAhDnRF3/6HDY1Ia5WPjP4a3LOKY28555xzzjnnnHPOuSyzpPR7vb6lZAUrS8hgB7uBpaMEKC0Zhz3A/mCpaPjTWCK23GwtCcMjN8ehpWDN3doS8HPi7vRjejX/1CbX8qA1sdGZB+eRaW14sjGp8YQnk7EpVQQqE7peCFyupjMnYm4yGVGZ7q1EyTZbEEche2uUbLMlL5W6t4Zkm22Ikm02561c89aQbLNTPpgq3hqSbbbmo1r41rhW8NaAaLMzvjITvDUg2WzFlyrBWwOCzc6Jkm12QQcL3Vtlmy3opFC9VbbZJR0tNW+Vbbahs0b41rhc8FbVZqdEyTb724t5/bYNA3G4e+80NYI0gGFkvaR779KKZUWuFKe7nlIsT5X//2M5VMZiZB9DQj74xW8ffrwjP90Mb/07Vf5CbXYJg0BtO4toKS9vhYHGY1vDZg28FQY6tBZls8tYBehwNLTyt1nhrTDQaDQcWAux2SJWAxpOBpWMWSvm4q0w0Gg4nFQqFTd/m72HlYBYQJV+w83bZu9jRaDJYEB4osjJ02aFt8JASUBRq+PlarMrWBGI8lQajVanXA5kopUcvBUEGrCAWhSoXs3PZtewKhA/MMbTbcpEa7l4KwwURZSHANnVnGz2CVYGmg6oZ1u1XGy2hNWBCA8BogE1m7Zl+ShNVMrdW2Wg/v+Amr2eRYCcGLBZU2+FgcSBESDfdZxdwGbNvBUGihKgnk1OjPAEwS5gsybeCgNNdTQLyAtqtRCwWQNvhYH4ndjtNnlAnlet1uIQsFl9b4WBpgNyaUCEJ45DwGa1vRUGanU6nMcmB+ZSnlosES3nvm/tUpGm1tFPd5DDAyKFBJGpzRaxSjW5J0o8/MAQ4ZEyKua/b+0Np175blMERDuaECFBZGqzBaxY9iAjIMbDK01U0OVZxcplE6BIjLzFRixgQDwflCJaXcC+1ToKyOYHFvCOljPiNmvurTBRI+oQoGTk2Z1YQyIeiWhlEftWnx8Yf8RcyiMCEkyhic2u4xOWSw9MBBQENTQFI83a+iL2rdgpJ1rms45mByYzhbDNwt6qTtTlQC7r6FT/CLRQ02ZLWKc8OmK+LzooCykhKpl4q7p+7B/d0SjNggRbqGOzm1gPqL3PX3niZakOQsenf1PDWzWAxr+JBtEDQxnnJTISNmvurfBK75t45bORBNGSobcqb9DqBCjdQOl5E370xthbYaDRiIjRDxKQwJk9a+o2u431gYZERBo/kcBIfvJ/TrSt6K1b+kDUHMkra2V3j5zRlprNbmADILbQ65S/z2ggyY82zL0VXsdQnnLdhSOKQzWbLWADIMpDgOrd3q958QiigrG3wusYzmNbXmY4sh+tangrVJ2Dgy97X9v0CmILzzIHcj3ZPTL+h6DN7mhYR5nxHI4mtKNbLCAmaX9QDDKFO6C36hDttcdJQFGLeTWRIupocGOj62cBb9WqesLTFwfm000MQgqz9lDLW+Hve35HM9Fnqw9HetBkNsF6+Yaet8Jf0+xbka0XbYspSMIg+5D8/8psnqdYv3qso1vsS9Hy6SaGQ6AYHP9ngLdqllVpiIB8RygRQjGEdOsc4K26RGzk6YTxjhbDDdzXcfwC8Fbd8glPnR4Y62gBAM/a1WybfYVNyyUBiZFPXYCAH70GvFW7nFRHH7EgyI8uAd6qXZ7NAqoilG6ZKuBH184D3qpdAQlIWp0p9dE7wFv1q8Y6+njLoPl+9P4C4K0GRKSjgTyywvoAeKtBxVWU6YhorovcvA14q0HtouwU0Fw/+jzN8w/cQ/zg6ug2/QAAAABJRU5ErkJggg==) 2x);
}
</style>
</head>
<body id="body" class="ssl extended-reporting-has-checkbox">
<div class="interstitial-wrapper">
<div id="main-content">
<div class="icon" id="icon"></div>
<div id="main-message">
<h1>系统发生错误:</h1>
<p>虽然不知道错在哪,但是确实出了点小问题...</p>
</div>
</div>
<div class="nav-wrapper">
<a href="javascript:history.go(-1);"><button id="primary-button">好的,我知道了</button></a>
</div>
</div>
<style>
html {
direction: ltr;
}
body {
font-family: system-ui, PingFang SC, STHeiti, sans-serif;
font-size: 75%;
}
button {
font-family: system-ui, PingFang SC, STHeiti, sans-serif;
}
</style>
</body>
</html>
-585
View File
@@ -1,585 +0,0 @@
<?php
/** @var array $traces */
if (!function_exists('parse_padding')) {
function parse_padding($source)
{
$length = strlen(strval(count($source['source']) + $source['first']));
return 40 + ($length - 1) * 8;
}
}
if (!function_exists('parse_class')) {
function parse_class($name)
{
$names = explode('\\', $name);
return '<abbr title="' . $name . '">' . end($names) . '</abbr>';
}
}
if (!function_exists('parse_file')) {
function parse_file($file, $line)
{
return '<a class="toggle" title="' . "{$file} line {$line}" . '">' . basename($file) . " line {$line}" . '</a>';
}
}
if (!function_exists('parse_args')) {
function parse_args($args)
{
$result = [];
foreach ($args as $key => $item) {
switch (true) {
case is_object($item):
$value = sprintf('<em>object</em>(%s)', parse_class(get_class($item)));
break;
case is_array($item):
if (count($item) > 3) {
$value = sprintf('[%s, ...]', parse_args(array_slice($item, 0, 3)));
} else {
$value = sprintf('[%s]', parse_args($item));
}
break;
case is_string($item):
if (strlen($item) > 20) {
$value = sprintf(
'\'<a class="toggle" title="%s">%s...</a>\'',
htmlentities($item),
htmlentities(substr($item, 0, 20))
);
} else {
$value = sprintf("'%s'", htmlentities($item));
}
break;
case is_int($item):
case is_float($item):
$value = $item;
break;
case is_null($item):
$value = '<em>null</em>';
break;
case is_bool($item):
$value = '<em>' . ($item ? 'true' : 'false') . '</em>';
break;
case is_resource($item):
$value = '<em>resource</em>';
break;
default:
$value = htmlentities(str_replace("\n", '', var_export(strval($item), true)));
break;
}
$result[] = is_int($key) ? $value : "'{$key}' => {$value}";
}
return implode(', ', $result);
}
}
if (!function_exists('echo_value')) {
function echo_value($val)
{
if (is_array($val) || is_object($val)) {
echo htmlentities(json_encode($val, JSON_PRETTY_PRINT));
} elseif (is_bool($val)) {
echo $val ? 'true' : 'false';
} elseif (is_scalar($val)) {
echo htmlentities($val);
} else {
echo 'Resource';
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>系统发生错误</title>
<meta name="robots" content="noindex,nofollow" />
<style>
/* Base */
body {
color: #333;
font: 16px Verdana, "Helvetica Neue", helvetica, Arial, 'Microsoft YaHei', sans-serif;
margin: 0;
padding: 0 20px 20px;
}
h1 {
margin: 10px 0 0;
font-size: 28px;
font-weight: 500;
line-height: 32px;
}
h2 {
color: #4288ce;
font-weight: 400;
padding: 6px 0;
margin: 6px 0 0;
font-size: 18px;
border-bottom: 1px solid #eee;
}
h3 {
margin: 12px;
font-size: 16px;
font-weight: bold;
}
abbr {
cursor: help;
text-decoration: underline;
text-decoration-style: dotted;
}
a {
color: #868686;
cursor: pointer;
}
a:hover {
text-decoration: underline;
}
.line-error {
background: #f8cbcb;
}
.echo table {
width: 100%;
}
.echo pre {
padding: 16px;
overflow: auto;
font-size: 85%;
line-height: 1.45;
background-color: #f7f7f7;
border: 0;
border-radius: 3px;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
}
.echo pre>pre {
padding: 0;
margin: 0;
}
/* Exception Info */
.exception {
margin-top: 20px;
}
.exception .message {
padding: 12px;
border: 1px solid #ddd;
border-bottom: 0 none;
line-height: 18px;
font-size: 16px;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
font-family: Consolas, "Liberation Mono", Courier, Verdana, "微软雅黑", serif;
}
.exception .code {
float: left;
text-align: center;
color: #fff;
margin-right: 12px;
padding: 16px;
border-radius: 4px;
background: #999;
}
.exception .source-code {
padding: 6px;
border: 1px solid #ddd;
background: #f9f9f9;
overflow-x: auto;
}
.exception .source-code pre {
margin: 0;
}
.exception .source-code pre ol {
margin: 0;
color: #4288ce;
display: inline-block;
min-width: 100%;
box-sizing: border-box;
font-size: 14px;
font-family: "Century Gothic", Consolas, "Liberation Mono", Courier, Verdana, serif;
padding-left: <?php echo (isset($source) && !empty($source)) ? parse_padding($source) : 40; ?>px;
}
.exception .source-code pre li {
border-left: 1px solid #ddd;
height: 18px;
line-height: 18px;
}
.exception .source-code pre code {
color: #333;
height: 100%;
display: inline-block;
border-left: 1px solid #fff;
font-size: 14px;
font-family: Consolas, "Liberation Mono", Courier, Verdana, "微软雅黑", serif;
}
.exception .trace {
padding: 6px;
border: 1px solid #ddd;
border-top: 0 none;
line-height: 16px;
font-size: 14px;
font-family: Consolas, "Liberation Mono", Courier, Verdana, "微软雅黑", serif;
}
.exception .trace h2:hover {
text-decoration: underline;
cursor: pointer;
}
.exception .trace ol {
margin: 12px;
}
.exception .trace ol li {
padding: 2px 4px;
}
.exception div:last-child {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
/* Exception Variables */
.exception-var table {
width: 100%;
margin: 12px 0;
box-sizing: border-box;
table-layout: fixed;
word-wrap: break-word;
}
.exception-var table caption {
text-align: left;
font-size: 16px;
font-weight: bold;
padding: 6px 0;
}
.exception-var table caption small {
font-weight: 300;
display: inline-block;
margin-left: 10px;
color: #ccc;
}
.exception-var table tbody {
font-size: 13px;
font-family: Consolas, "Liberation Mono", Courier, "微软雅黑", serif;
}
.exception-var table td {
padding: 0 6px;
vertical-align: top;
word-break: break-all;
}
.exception-var table td:first-child {
width: 28%;
font-weight: bold;
white-space: nowrap;
}
.exception-var table td pre {
margin: 0;
}
/* Copyright Info */
.copyright {
margin-top: 24px;
padding: 12px 0;
border-top: 1px solid #eee;
}
/* SPAN elements with the classes below are added by prettyprint. */
pre.prettyprint .pln {
color: #000
}
/* plain text */
pre.prettyprint .str {
color: #080
}
/* string content */
pre.prettyprint .kwd {
color: #008
}
/* a keyword */
pre.prettyprint .com {
color: #800
}
/* a comment */
pre.prettyprint .typ {
color: #606
}
/* a type name */
pre.prettyprint .lit {
color: #066
}
/* a literal value */
/* punctuation, lisp open bracket, lisp close bracket */
pre.prettyprint .pun,
pre.prettyprint .opn,
pre.prettyprint .clo {
color: #660
}
pre.prettyprint .tag {
color: #008
}
/* a markup tag name */
pre.prettyprint .atn {
color: #606
}
/* a markup attribute name */
pre.prettyprint .atv {
color: #080
}
/* a markup attribute value */
pre.prettyprint .dec,
pre.prettyprint .var {
color: #606
}
/* a declaration; a variable name */
pre.prettyprint .fun {
color: red
}
/* a function name */
</style>
</head>
<body>
<?php if (\think\facade\App::isDebug()) { ?>
<?php foreach ($traces as $index => $trace) { ?>
<div class="exception">
<div class="message">
<div class="info">
<div>
<h2><?php echo "#{$index} [{$trace['code']}]" . sprintf('%s in %s', parse_class($trace['name']), parse_file($trace['file'], $trace['line'])); ?></h2>
</div>
<div>
<h1><?php echo nl2br(htmlentities($trace['message'])); ?></h1>
</div>
</div>
</div>
<?php if (!empty($trace['source'])) { ?>
<div class="source-code">
<pre class="prettyprint lang-php"><ol start="<?php echo $trace['source']['first']; ?>"><?php foreach ((array) $trace['source']['source'] as $key => $value) { ?><li class="line-<?php echo "{$index}-";
echo $key + $trace['source']['first'];
echo $trace['line'] === $key + $trace['source']['first'] ? ' line-error' : ''; ?>"><code><?php echo htmlentities($value); ?></code></li><?php } ?></ol></pre>
</div>
<?php } ?>
<div class="trace">
<h2 data-expand="<?php echo 0 === $index ? '1' : '0'; ?>">Call Stack</h2>
<ol>
<li><?php echo sprintf('in %s', parse_file($trace['file'], $trace['line'])); ?></li>
<?php foreach ((array) $trace['trace'] as $value) { ?>
<li>
<?php
// Show Function
if ($value['function']) {
echo sprintf(
'at %s%s%s(%s)',
isset($value['class']) ? parse_class($value['class']) : '',
isset($value['type']) ? $value['type'] : '',
$value['function'],
isset($value['args']) ? parse_args($value['args']) : ''
);
}
// Show line
if (isset($value['file']) && isset($value['line'])) {
echo sprintf(' in %s', parse_file($value['file'], $value['line']));
}
?>
</li>
<?php } ?>
</ol>
</div>
</div>
<?php } ?>
<?php } else { ?>
<div class="exception">
<div class="info">
<h1><?php echo htmlentities($message); ?></h1>
</div>
</div>
<?php } ?>
<?php if (!empty($datas)) { ?>
<div class="exception-var">
<h2>Exception Datas</h2>
<?php foreach ((array) $datas as $label => $value) { ?>
<table>
<?php if (empty($value)) { ?>
<caption><?php echo $label; ?><small>empty</small></caption>
<?php } else { ?>
<caption><?php echo $label; ?></caption>
<tbody>
<?php foreach ((array) $value as $key => $val) { ?>
<tr>
<td><?php echo htmlentities($key); ?></td>
<td><?php echo_value($val); ?></td>
</tr>
<?php } ?>
</tbody>
<?php } ?>
</table>
<?php } ?>
</div>
<?php } ?>
<?php if (!empty($tables)) { ?>
<div class="exception-var">
<h2>Environment Variables</h2>
<?php foreach ((array) $tables as $label => $value) { ?>
<table>
<?php if (empty($value)) { ?>
<caption><?php echo $label; ?><small>empty</small></caption>
<?php } else { ?>
<caption><?php echo $label; ?></caption>
<tbody>
<?php foreach ((array) $value as $key => $val) { ?>
<tr>
<td><?php echo htmlentities($key); ?></td>
<td><?php echo_value($val); ?></td>
</tr>
<?php } ?>
</tbody>
<?php } ?>
</table>
<?php } ?>
</div>
<?php } ?>
<?php if (\think\facade\App::isDebug()) { ?>
<script>
function $(selector, node) {
var elements;
node = node || document;
if (document.querySelectorAll) {
elements = node.querySelectorAll(selector);
} else {
switch (selector.substr(0, 1)) {
case '#':
elements = [node.getElementById(selector.substr(1))];
break;
case '.':
if (document.getElementsByClassName) {
elements = node.getElementsByClassName(selector.substr(1));
} else {
elements = get_elements_by_class(selector.substr(1), node);
}
break;
default:
elements = node.getElementsByTagName();
}
}
return elements;
function get_elements_by_class(search_class, node, tag) {
var elements = [],
eles,
pattern = new RegExp('(^|\\s)' + search_class + '(\\s|$)');
node = node || document;
tag = tag || '*';
eles = node.getElementsByTagName(tag);
for (var i = 0; i < eles.length; i++) {
if (pattern.test(eles[i].className)) {
elements.push(eles[i])
}
}
return elements;
}
}
$.getScript = function(src, func) {
var script = document.createElement('script');
script.async = 'async';
script.src = src;
script.onload = func || function() {};
$('head')[0].appendChild(script);
}
;
(function() {
var files = $('.toggle');
var ol = $('ol', $('.prettyprint')[0]);
var li = $('li', ol[0]);
// 短路径和长路径变换
for (var i = 0; i < files.length; i++) {
files[i].ondblclick = function() {
var title = this.title;
this.title = this.innerHTML;
this.innerHTML = title;
}
}
(function() {
var expand = function(dom, expand) {
var ol = $('ol', dom.parentNode)[0];
expand = undefined === expand ? dom.attributes['data-expand'].value === '0' : undefined;
if (expand) {
dom.attributes['data-expand'].value = '1';
ol.style.display = 'none';
dom.innerText = 'Call Stack (展开)';
} else {
dom.attributes['data-expand'].value = '0';
ol.style.display = 'block';
dom.innerText = 'Call Stack (折叠)';
}
};
var traces = $('.trace');
for (var i = 0; i < traces.length; i++) {
var h2 = $('h2', traces[i])[0];
expand(h2);
h2.onclick = function() {
expand(this);
};
}
})();
$.getScript('//cdn.bootcss.com/prettify/r298/prettify.min.js', function() {
prettyPrint();
});
})();
</script>
<?php } ?>
</body>
</html>
-309
View File
@@ -1,309 +0,0 @@
<!DOCTYPE html>
<html dir="ltr" lang="zh">
<head>
<meta charset="utf-8">
<meta name="theme-color" content="#fff">
<meta name="viewport" content="initial-scale=1, minimum-scale=1, width=device-width">
<title>系统操作成功</title>
<style>
a {
color: var(--link-color);
}
body {
--background-color: #fff;
--error-code-color: var(--google-gray-700);
--google-blue-100: rgb(210, 227, 252);
--google-blue-300: rgb(138, 180, 248);
--google-blue-600: rgb(26, 115, 232);
--google-blue-700: rgb(25, 103, 210);
--google-gray-100: rgb(241, 243, 244);
--google-gray-300: rgb(218, 220, 224);
--google-gray-500: rgb(154, 160, 166);
--google-gray-50: rgb(248, 249, 250);
--google-gray-600: rgb(128, 134, 139);
--google-gray-700: rgb(95, 99, 104);
--google-gray-800: rgb(60, 64, 67);
--google-gray-900: rgb(32, 33, 36);
--heading-color: var(--google-gray-900);
--primary-button-fill-color-active: var(--google-blue-700);
--primary-button-fill-color: var(--google-blue-600);
--primary-button-text-color: #fff;
--text-color: var(--google-gray-700);
background: var(--background-color);
color: var(--text-color);
word-wrap: break-word;
}
html {
-webkit-text-size-adjust: 100%;
font-size: 125%;
}
.icon {
background-repeat: no-repeat;
background-size: 100%;
}
@media (prefers-color-scheme: dark) {
body.captive-portal,
body.dark-mode-available,
body.neterror,
body.supervised-user-block,
.offline body {
--background-color: var(--google-gray-900);
--error-code-color: var(--google-gray-500);
--heading-color: var(--google-gray-500);
--link-color: var(--google-blue-300);
--primary-button-fill-color-active: rgb(129, 162, 208);
--primary-button-fill-color: var(--google-blue-300);
--primary-button-text-color: var(--google-gray-900);
--text-color: var(--google-gray-500);
}
}
</style>
<style>
button {
border: 0;
border-radius: 4px;
box-sizing: border-box;
color: var(--primary-button-text-color);
cursor: pointer;
float: right;
font-size: .875em;
margin: 0;
padding: 8px 16px;
transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1);
user-select: none;
}
[dir='rtl'] button {
float: left;
}
.ssl button {
background: var(--primary-button-fill-color);
}
button:active {
background: var(--primary-button-fill-color-active);
outline: 0;
}
h1 {
color: var(--heading-color);
font-size: 1.6em;
font-weight: normal;
line-height: 1.25em;
margin-bottom: 16px;
}
h2 {
font-size: 1.2em;
font-weight: normal;
}
.icon {
height: 72px;
margin: 0 0 40px;
width: 72px;
}
.interstitial-wrapper {
box-sizing: border-box;
font-size: 1em;
line-height: 1.6em;
margin: 14vh auto 0;
max-width: 600px;
width: 100%;
}
#main-message>p {
display: inline;
}
.nav-wrapper {
margin-top: 51px;
}
.nav-wrapper::after {
clear: both;
content: '';
display: table;
width: 100%;
}
@media (max-width: 700px) {
.interstitial-wrapper {
padding: 0 10%;
}
}
@media (max-width: 420px) {
button,
[dir='rtl'] button{
float: none;
font-size: .825em;
font-weight: 500;
margin: 0;
width: 100%;
}
button {
padding: 16px 24px;
}
.interstitial-wrapper {
padding: 0 5%;
}
.nav-wrapper {
margin-top: 30px;
}
}
@media (min-width: 240px) and (max-width: 420px) and (min-height: 401px),
(min-width: 421px) and (min-height: 240px) and (max-height: 560px) {
body .nav-wrapper {
background: var(--background-color);
bottom: 0;
box-shadow: 0 -22px 40px var(--background-color);
left: 0;
margin: 0 auto;
max-width: 736px;
padding-left: 24px;
padding-right: 24px;
position: fixed;
right: 0;
width: 100%;
z-index: 2;
}
.interstitial-wrapper {
max-width: 736px;
}
}
@media (max-width: 420px) and (orientation: portrait),
(max-height: 560px) {
body {
margin: 0 auto;
}
button,
[dir='rtl'] button,
button.small-link {
font-family: Roboto-Regular, Helvetica;
font-size: .933em;
margin: 6px 0;
transform: translatez(0);
}
.nav-wrapper {
box-sizing: border-box;
padding-bottom: 8px;
width: 100%;
}
h1 {
font-size: 1.5em;
margin-bottom: 8px;
}
.icon {
margin-bottom: 5.69vh;
}
.interstitial-wrapper {
box-sizing: border-box;
margin: 7vh auto 12px;
padding: 0 24px;
position: relative;
}
.interstitial-wrapper p {
font-size: .95em;
line-height: 1.61em;
margin-top: 8px;
}
}
@media (min-width: 421px) and (min-height: 500px) and (max-height: 560px) {
.interstitial-wrapper {
margin-top: 10vh;
}
}
@media (min-height: 400px) and (orientation:portrait) {
.interstitial-wrapper {
margin-bottom: 145px;
}
}
@media (min-height: 299px) {
.nav-wrapper {
padding-bottom: 16px;
}
}
@media (min-height: 500px) and (max-height: 650px) and (max-width: 414px) and (orientation: portrait) {
.interstitial-wrapper {
margin-top: 7vh;
}
}
@media (min-height: 650px) and (max-width: 414px) and (orientation: portrait) {
.interstitial-wrapper {
margin-top: 10vh;
}
}
.ssl .icon {
background-image: -webkit-image-set(url(data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20%20style%3d%22fill%3agreen%3bstroke%3awhite%3b%22%20d%3D%22M12%2022C6.477%2022%202%2017.523%202%2012S6.477%202%2012%202s10%204.477%2010%2010-4.477%2010-10%2010zm-1.177-7.86l-2.765-2.767L7%2012.431l3.119%203.121a1%201%200%20001.414%200l5.952-5.95-1.062-1.062-5.6%205.6z%22%2F%3E%3C%2Fsvg%3E) 2x);
}
</style>
</head>
<body id="body" class="ssl extended-reporting-has-checkbox">
<div class="interstitial-wrapper">
<div id="main-content">
<div class="icon" id="icon"></div>
<div id="main-message">
<h1>系统操作成功:</h1>
<p><?php echo $message ? $message : '虽然不知道你干啥了,但是确实操作成功了...'; ?></p>
</div>
</div>
<div class="nav-wrapper">
<a href="<?php echo $url;?>"><button id="primary-button">好的,我知道了</button></a>
</div>
</div>
<style>
html {
direction: ltr;
}
body {
font-family: system-ui, PingFang SC, STHeiti, sans-serif;
font-size: 75%;
}
button {
font-family: system-ui, PingFang SC, STHeiti, sans-serif;
}
</style>
</body>
</html>
-9
View File
@@ -1,9 +0,0 @@
<?php
use app\ExceptionHandle;
use app\Request;
// 容器Provider定义文件
return [
'think\Request' => Request::class,
'think\exception\Handle' => ExceptionHandle::class,
];
-162
View File
@@ -1,162 +0,0 @@
<?php
declare(strict_types=1);
namespace app\qfadmin;
use think\App;
use think\facade\View;
use app\model\Admin as AdminModel;
use app\model\Access as AccessModel;
use app\model\Auth as AuthModel;
use app\model\Node as NodeModel;
use app\model\Group as GroupModel;
use app\model\Conf as ConfModel;
/**
* 控制器基础类
*/
abstract class QfShop
{
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
protected $module;
protected $controller;
protected $action;
//模型
protected $AdminModel;
protected $accessModel;
protected $authModel;
protected $nodeModel;
protected $groupModel;
protected $confModel;
//主键key
protected $pk = '';
//表名称
protected $table = '';
//主键value
protected $pk_value = '';
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 控制器初始化
$this->initialize();
}
// 初始化
protected function initialize()
{
$this->module = "qfadmin";
$this->controller = $this->request->controller() ? $this->request->controller() : "Index";
$this->action = strtolower($this->request->action()) ? strtolower($this->request->action()) : "index";
View::assign('controller', strtolower($this->controller));
View::assign('action', strtolower($this->action));
$this->table = strtolower($this->controller);
$this->pk = $this->table . "_id";
$this->pk_value = input($this->pk);
$this->adminModel = new AdminModel();
$this->accessModel = new AccessModel();
$this->authModel = new AuthModel();
$this->nodeModel = new NodeModel();
$this->groupModel = new GroupModel();
$this->confModel = new ConfModel();
$configs = $this->confModel->select()->toArray();
$c = [];
foreach ($configs as $config) {
$c[$config['conf_key']] = $config['conf_value'];
}
config($c, 'yadmin');
}
/**
* 后台简单的身份判断
*
* @return void
*/
protected function access()
{
$callback = "/qfadmin";
if (strtolower($this->controller) != "index") {
$callback .= "/" . strtolower($this->controller);
}
if ($this->action != "index") {
$callback .= "/" . $this->action;
}
$access_token = cookie('access_token');
if (!$access_token) {
return redirect('/qfadmin/admin/login/?callback=' . urlencode($callback));
}
View::assign("access_token", $access_token);
$this->admin = $this->adminModel->getAdminByAccessToken($access_token);
if (!$this->admin) {
return redirect('/qfadmin/admin/login/?callback=' . urlencode($callback));
}
if ($this->admin['admin_status'] > 0) {
return $this->error("抱歉,你的帐号已被禁用,暂时无法登录系统!");
}
cookie("access_token", $access_token);
View::assign('adminInfo', $this->admin);
$this->group = $this->groupModel->where('group_id', $this->admin['admin_group'])->find();
if ($this->group) {
if ($this->group['group_id'] != 1 && $this->group['group_status'] == 1) {
return $this->error("抱歉,你所在的用户组已被禁用,暂时无法登录系统");
} else {
$menuList = $this->authModel->getAdminMenuListByAdminId($this->group['group_id']);
View::assign('menuList', $menuList);
$node = $this->nodeModel->where(['node_module' => $this->module, 'node_controller' => strtolower($this->controller), 'node_action' => $this->action])->find();
View::assign('node', $node);
if($node['node_pid']==0){
View::assign('menu', 0);
}else{
$res = $this->nodeModel->where('node_id',$node['node_pid'])->find();
View::assign('menu', $res['node_pid']);
}
$menuLists = [];
foreach ($menuList as $key => $value) {
if($value['node_id'] == $node['node_pid']){
$menuLists = $value['subList'];
}else{
foreach ($value['subList'] as $k => $v) {
if($v['node_id'] == $node['node_pid']){
$menuLists = $value['subList'];
}
}
}
}
View::assign('menuLists', $menuLists);
View::assign('action', $this->request->action());
}
} else {
return $this->error("抱歉,没有查到你的用户组信息,暂时无法登录系统");
}
}
protected function error($message)
{
echo $message;
die;
}
}
-33
View File
@@ -1,33 +0,0 @@
<?php
namespace app\qfadmin\controller;
use app\qfadmin\QfShop;
use think\facade\View;
class Error extends QfShop
{
/**
* 监听所有请求 渲染对应控制器下方法的页面
*/
public function __call($method, $args)
{
// 判断是否是登录/注册/找回密码
// 否则进行accesss授权验证 如错误 直接返回
if (!(strtolower($this->controller) == "admin" && in_array(strtolower($this->action), ['login', 'resetpassword', 'reg']))) {
$error = $this->access();
if ($error) {
return $error;
}
}else{
cookie('access_token', null);
}
if (key_exists('callback', $args)) {
View::assign('callback', $args['callback']);
} else {
View::assign('callback', '/qfadmin');
}
View::assign('datas', $args);
return View::fetch();
}
}
-449
View File
@@ -1,449 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-form :inline="true">
<el-form-item>
<el-button icon="el-icon-plus" size="small" @click="clickAdd" plain>添加</el-button>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-delete" size="small" @click="postMultDelete" plain>批量删除</el-button>
</el-form-item>
<div style="float:right">
<el-form-item>
<el-select placeholder="请选择状态" size="small" v-model="search.admin_status">
<el-option value="" label="全部用户">
</el-option>
<el-option value="0" label="正常用户">
</el-option>
<el-option value="1" label="禁用用户">
</el-option>
</el-select>
</el-form-item>
<el-form-item style="width:120px;">
<el-select placeholder="筛选类别" size="small" v-model="search.filter">
<el-option value="admin_id" label="用户ID">
</el-option>
<el-option value="admin_name" label="用户昵称">
</el-option>
<el-option value="admin_account" label="用户帐号">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-input placeholder="输入关键词搜索" size="small" v-model="search.keyword"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="small" @click="getList_search" plain>搜索</el-button>
</el-form-item>
</div>
</el-form>
<el-table :data="dataList.data" @selection-change="changeSelection" v-loading="loading">
<el-table-column type="selection" width="50">
</el-table-column>
<el-table-column prop="admin_id" label="ID" width="100">
</el-table-column>
<el-table-column prop="admin_account" label="帐号">
</el-table-column>
<el-table-column prop="admin_name" label="昵称">
</el-table-column>
<el-table-column prop="group_name" label="用户组">
</el-table-column>
<el-table-column prop="admin_ipreg" label="注册IP" width="150">
</el-table-column>
<el-table-column label="最后活跃" width="120">
<template slot-scope="scope">
{{time2string(scope.row.admin_updatetime)}}
</template>
</el-table-column>
<el-table-column label="注册时间" width="120">
<template slot-scope="scope">
{{time2string(scope.row.admin_createtime)}}
</template>
</el-table-column>
<el-table-column label="禁用" width="80">
<template slot-scope="scope">
<el-switch v-model="scope.row.admin_status==1?true:false" active-color="#ff4949"
@change="clickStatus(scope.row)">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" width="180">
<template slot-scope="scope">
<el-link type="primary" @click="clickEdit(scope.row)" :underline="false">编辑</el-link>&nbsp;
<el-link type="danger" @click="clickDelete(scope.row)" :underline="false">删除</el-link>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination @size-change="handleSizeChange" :page-sizes="[10, 20, 50, 100,200,500]" :page-size="10"
layout="total, sizes, prev, pager, next, jumper" background @current-change="changeCurrentPage"
:current-page="dataList.current_page" :page-count="dataList.last_page" :total="dataList.total">
</el-pagination>
</div>
<!-- 添加框 -->
<el-dialog title="添加用户" :visible.sync="dialogFormAdd" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formAdd" status-icon :rules="rules" ref="formAdd">
<el-form-item label="帐号" :label-width="formLabelWidth" prop="admin_account">
<el-input size="medium" autocomplete="off" v-model="formAdd.admin_account"></el-input>
</el-form-item>
<el-form-item label="密码" :label-width="formLabelWidth" prop="admin_password">
<el-input size="medium" show-password="true" autocomplete="off" v-model="formAdd.admin_password">
</el-input>
</el-form-item>
<el-form-item label="昵称" :label-width="formLabelWidth" prop="admin_name">
<el-input size="medium" autocomplete="off" v-model="formAdd.admin_name"></el-input>
</el-form-item>
<el-form-item label="邮箱" :label-width="formLabelWidth" prop="admin_email">
<el-input size="medium" autocomplete="off" v-model="formAdd.admin_email"></el-input>
</el-form-item>
<el-form-item label="身份证" :label-width="formLabelWidth" prop="admin_idcard">
<el-input size="medium" autocomplete="off" v-model="formAdd.admin_idcard"></el-input>
</el-form-item>
<el-form-item label="真实姓名" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formAdd.admin_truename"></el-input>
</el-form-item>
<el-form-item label="用户组" :label-width="formLabelWidth">
<el-select size="medium" placeholder="请选择用户组" v-model="formAdd.admin_group">
<el-option v-for="group_add in groupList" :value="group_add.group_id" :label="group_add.group_name">
</el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postAdd">确认添加</el-button>
</div>
</el-dialog>
<!-- 修改框 -->
<el-dialog title="修改用户" :visible.sync="dialogFormEdit" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formEdit" status-icon :rules="rules" ref="formEdit">
<el-form-item label="帐号" :label-width="formLabelWidth" prop="admin_account">
<el-input size="medium" autocomplete="off" v-model="formEdit.admin_account"></el-input>
</el-form-item>
<el-form-item label="密码" :label-width="formLabelWidth" prop="new_password">
<el-input size="medium" show-password="true" autocomplete="off" v-model="formEdit.new_password"
placeholder="不修改请留空">
</el-input>
</el-form-item>
<el-form-item label="昵称" :label-width="formLabelWidth" prop="admin_name">
<el-input size="medium" autocomplete="off" v-model="formEdit.admin_name"></el-input>
</el-form-item>
<el-form-item label="邮箱" :label-width="formLabelWidth" prop="admin_email">
<el-input size="medium" autocomplete="off" v-model="formEdit.admin_email"></el-input>
</el-form-item>
<el-form-item label="身份证" :label-width="formLabelWidth" prop="admin_idcard">
<el-input size="medium" autocomplete="off" v-model="formEdit.admin_idcard"></el-input>
</el-form-item>
<el-form-item label="真实姓名" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formEdit.admin_truename"></el-input>
</el-form-item>
<el-form-item label="用户组" :label-width="formLabelWidth">
<el-select size="medium" placeholder="请选择用户组" v-model="formEdit.admin_group">
<el-option v-for="group_edit in groupList" :value="group_edit.group_id"
:label="group_edit.group_name"></el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postEdit">确认修改</el-button>
</div>
</el-dialog>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
this.getList();
return {
search: {
admin_status: "",
keyword: "",
filter: "admin_id"
},
formLabelWidth: '80px',
dialogFormAdd: false,
dialogFormEdit: false,
loading: true,
dataList: [],
groupList: [],
selectList: [],
form: {
page: 1,
per_page: 10
},
formAdd: {
admin_group: 1
},
formEdit: {
admin_group: 1
},
rules: {
admin_account: [
{ required: true, message: '帐号必须填写', trigger: 'blur' },
],
admin_name: [
{ required: true, message: '昵称必须填写', trigger: 'blur' },
],
admin_password: [
{ required: true, message: '密码必须填写', trigger: 'blur' },
// { required: true, pattern: /^(?=.*[a-z])(?=.*\d).{6,16}$/, message: '密码必须包含字母和数字(6-16位)', trigger: 'blur' },
],
new_password: [
{ required: true, message: '密码必须填写', trigger: 'blur' },
// { pattern: /^(?=.*[a-z])(?=.*\d).{6,16}$/, message: '密码必须包含字母和数字(6-16位)', trigger: 'blur' },
],
admin_email: [
{ pattern: /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/, message: '邮箱格式不正确', trigger: 'blur' },
],
admin_idcard: [
{ pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/, message: '身份证格式不正确', trigger: 'blur' },
],
}
}
},
methods: {
getList_search() {
this.form.page = 1;
this.getList();
},
time2string(timestamps) {
var now = new Date(timestamps * 1000),
y = now.getFullYear(),
m = now.getMonth() + 1,
d = now.getDate();
// return y + "-" + (m < 10 ? "0" + m : m) + "-" + (d < 10 ? "0" + d : d) + " " + now.toTimeString().substr(0, 8);
return (m < 10 ? "0" + m : m) + "-" + (d < 10 ? "0" + d : d) + " " + now.toTimeString().substr(0, 5);
},
handleSizeChange(per_page) {
this.form.per_page = per_page;
this.getList();
},
postMultDelete() {
var that = this;
if (that.selectList.length == 0) {
that.$message.error('未选择任何用户!');
return;
}
this.$confirm('即将删除选中的用户, 是否确认?', '批量删除', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/admin/delete', Object.assign({}, PostBase, {
admin_id: that.selectList.join(",")
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
changeSelection(list) {
var that = this;
that.selectList = [];
for (var index in list) {
that.selectList.push(list[index].admin_id);
}
},
postEdit() {
var that = this;
that.$refs['formEdit'].validate((valid) => {
if (!valid) {
that.$message.error('仔细检查检查,是不是有个地方写得不对?');
return;
}
axios.post('/admin/admin/update', Object.assign({}, PostBase, that.formEdit))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormEdit = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
});
},
postAdd() {
var that = this;
that.$refs['formAdd'].validate((valid) => {
if (!valid) {
that.$message.error('仔细检查检查,是不是有个地方写得不对?');
return;
}
axios.post('/admin/admin/add', Object.assign({}, PostBase, that.formAdd))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormAdd = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
});
},
clickAdd() {
var that = this;
that.formAdd = {
admin_group: 1
};
axios.post('/admin/group/getList', Object.assign({}, PostBase))
.then(function (response) {
that.groupList = response.data.data;
if (response.data.code == CODE_SUCCESS) {
that.dialogFormAdd = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickDelete(row) {
var that = this;
this.$confirm('即将删除这个用户, 是否确认?', '删除提醒', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/admin/delete', Object.assign({}, PostBase, {
admin_id: row.admin_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
clickStatus(row) {
var that = this;
axios.post(row.admin_status ? '/admin/admin/enable' : '/admin/admin/disable', Object.assign({}, PostBase, {
admin_id: row.admin_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickEdit(row) {
var that = this;
that.formEdit = row;
axios.post('/admin/group/getList', Object.assign({}, PostBase))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.groupList = response.data.data;
axios.post('/admin/admin/detail', Object.assign({}, PostBase, {
admin_id: row.admin_id
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.formEdit = response.data.data;
that.dialogFormEdit = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/admin/getList', Object.assign({}, PostBase, that.form, that.search))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
console.log(error);
});
},
}
})
</script>
</html>
-263
View File
@@ -1,263 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>后台管理系统</title>
<meta charset="UTF-8">
<!-- import CSS -->
<link rel="stylesheet" href="/static/admin/css/element.css">
<link rel="stylesheet" href="/static/admin/css/YAdmin.css">
<style>
.login-container {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
align-items: center;
justify-content: space-around;
min-width: 1280px;
min-height: 800px;
background: url(/static/admin/images/login_bg.jpg) no-repeat;
background-size: 100% 100%;
background-color: #ffffff;
}
.login-container:before{
content: " ";
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: url(/static/admin/images/login_bg_bottom.png) no-repeat;
background-size: 100% 100%;
height: 170px;
}
.login-box img{
width: 720px;
}
.login-border {
display: flex;
justify-content: center;
flex-direction: column;
position: relative;
top: -30px;
right: 100px;
}
.login-main{
background-color: #ffffff;
padding: 35px 45px 15px 45px;
border-radius: 6px;
}
.login-main .vadmin{
font-size: 16px;
font-weight: bold;
color: #6881ec;
line-height: 20px;
padding-bottom: 6px;
}
.login-logo {
margin: 0 0 20px;
}
.login-logo p {
color: #ffffff;
font-size: 25px;
font-weight: bold;
}
.login-submit {
margin-top: 10px;
width: 100%;
}
.login-form {
margin: 10px 0;
}
.login-form .el-form-item__content {
width: 270px;
}
.login-form .el-form-item {
margin-bottom: 26px;
}
.login-form .el-input input {
text-indent: 5px;
border-color: #DCDCDC;
border-radius: 3px;
border: none;
border-bottom: 1px solid #eee;
}
.login-form .el-input .el-input__prefix i {
padding: 0 5px;
font-size: 16px !important;
}
.login-code {
display: flex;
align-items: center;
justify-content: space-around;
margin-left: 10px;
cursor: pointer;
}
.login-code-img {
margin-top: 1px;
width: 100px;
height: 38px;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<div id="app" v-cloak>
<div class="login-container">
<div class="login-box">
<img src="/static/admin/images/login_bg_box.png">
</div>
<div class="login-border">
<div class="login-logo">
<p>后台登录</p>
</div>
<div class="login-main">
<p class="vadmin">管理员登录</p>
<el-form class="login-form" status-icon :rules="loginRules" ref="loginForm" :model="loginForm"
label-width="0" size="default">
<el-form-item prop="admin_account">
<el-input @keyup.enter.native="handleLogin()" v-model="loginForm.admin_account"
auto-complete="off" placeholder="请输入账号">
<i slot="prefix" class="el-icon-user"></i>
</el-input>
</el-form-item>
<el-form-item prop="admin_password">
<el-input @keyup.enter.native="handleLogin()" v-model="loginForm.admin_password" show-password
auto-complete="off" placeholder="请输入密码">
<i slot="prefix" class="el-icon-key"></i>
</el-input>
</el-form-item>
<el-form-item v-if="codeUrl" prop="admin_code">
<el-row :span="34">
<el-col :span="14">
<el-input @keyup.enter.native="handleLogin()" v-model="loginForm.admin_code"
auto-complete="off" placeholder="请输入验证码">
<i slot="prefix" class="el-icon-mobile"></i>
</el-input>
</el-col>
<el-col :span="10">
<div class="login-code">
<img :src="codeUrl" class="login-code-img" @click="getCaptcha" alt="" />
</div>
</el-col>
</el-row>
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="loading" @click.native.prevent="handleLogin"
class="login-submit">登 录
</el-button>
</el-form-item>
</el-form>
</div>
</div>
</div>
</div>
</div>
</body>
<script src="/static/admin/js/vue-2.6.10.min.js"></script>
<script src="/static/admin/js/axios.min.js"></script>
<script src="/static/admin/js/element.js"></script>
<script src="/static/admin/js/YAdmin.js"></script>
<script>
new Vue({
el: '#app',
data() {
return {
codeUrl: '',
codeToken: '',
loading: false,
loginForm: {
admin_account: '',
admin_password: '',
admin_code: '',
},
loginRules: {
admin_account: [
{ required: true, message: '请输入账号', trigger: 'blur' }
],
admin_password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, message: '密码长度最少为6位', trigger: 'blur' }
],
admin_code: [
{ required: true, message: '请输入验证码', trigger: 'blur' },
{ min: 4, max: 4, message: '验证码长度为4位', trigger: 'blur' }
]
}
}
},
created() {
this.getCaptcha();
},
methods: {
/**
* @description 正式登录
*/
handleLogin() {
var that = this;
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
this.loginForm.token = this.codeToken
axios.post('/admin/admin/login', Object.assign({}, PostBase, this.loginForm))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: '登录成功,正在跳转中',
type: 'success'
});
setTimeout(function () {
location.replace('/qfadmin');
}, 1000)
} else {
that.$message.error(response.data.message);
that.loading = false
that.getCaptcha();
}
})
.catch(function (error) {
that.$message.error('登录失败,服务器内部错误');
that.loading = false
});
}
})
},
onSubmit() {
var that = this;
axios.post('/admin/admin/login', Object.assign({}, PostBase, this.form))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: '登录成功,正在跳转中',
type: 'success'
});
setTimeout(function () {
location.replace('{$callback}');
}, 1000)
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('登录失败,服务器内部错误');
});
},
getCaptcha() {
var that = this;
axios.post('/admin/system/getCaptcha', Object.assign({}, PostBase))
.then(function (res) {
that.codeUrl = res.data.data.img
that.codeToken = res.data.data.token
})
.catch(function (error) {
that.$message.error('获取失败');
});
},
}
})
</script>
</html>
@@ -1,94 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<span>修改我的密码</span>
</div>
<div class="text item">
<el-form :model="form" status-icon :rules="rules" ref="form" label-width="80px">
<el-form-item label="原密码" prop="oldPassword">
<el-input show-password v-model="form.oldPassword" placeholder="请输入原密码"></el-input>
</el-form-item>
<el-form-item label="新密码" prop="newPassword">
<el-input show-password password="password" v-model="form.newPassword" placeholder="请输入新密码">
</el-input>
</el-form-item>
<el-form-item label="新密码" prop="checkPassword">
<el-input show-password v-model="form.checkPassword" placeholder="请确认新密码"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">修改密码</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
return {
form: {
oldPassword: "",
newPassword: "",
checkPassword: "",
},
rules: {
oldPassword: [
{ required: true, message: '原密码必须输入', trigger: 'blur' },
],
newPassword: [
{ required: true, pattern: /^(?=.*[a-z])(?=.*\d).{6,16}$/, message: '密码必须包含大小写字母和数字(6-16位)', trigger: 'blur' },
],
checkPassword: [
{ required: true, pattern: /^(?=.*[a-z])(?=.*\d).{6,16}$/, message: '密码必须包含大小写字母和数字(6-16位)', trigger: 'blur' },
],
}
}
},
methods: {
onSubmit() {
var that = this;
that.$refs['form'].validate((valid) => {
if (!valid) {
that.$message.error('仔细检查检查,是不是有个地方写得不对?');
return;
}
if (that.form.newPassword != that.form.checkPassword) {
that.$message.error('两次密码输入不一致,请确认');
return;
}
axios.post('/admin/admin/motifypassword', Object.assign({}, PostBase, {
oldPassword: that.form.oldPassword,
newPassword: that.form.newPassword,
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
setTimeout(function () {
location.href = "/qfadmin";
}, 2000);
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
});
},
}
});
</script>
</html>
-103
View File
@@ -1,103 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<span>修改我的资料</span>
</div>
<div class="text item">
<el-form :model="form" status-icon :rules="rules" ref="form" label-width="80px">
<el-form-item label="昵称" prop="admin_name">
<el-input v-model="form.admin_name" placeholder="请输入你的昵称"></el-input>
</el-form-item>
<el-form-item label="姓名" prop="admin_truename">
<el-input v-model="form.admin_truename" placeholder="请输入你的真实姓名"></el-input>
</el-form-item>
<el-form-item label="邮箱" prop="admin_email">
<el-input v-model="form.admin_email" placeholder="请输入你的邮箱"></el-input>
</el-form-item>
<el-form-item label="身份证" prop="admin_idcard">
<el-input v-model="form.admin_idcard" placeholder="请输入你的身份证"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">更新资料</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
this.getData();
return {
form: {
},
rules: {
admin_name: [
{ required: true, message: '昵称必须填写', trigger: 'blur' },
],
admin_email: [
{ pattern: /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/, message: '邮箱格式不正确', trigger: 'blur' },
],
admin_idcard: [
{ pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/, message: '身份证格式不正确', trigger: 'blur' },
],
}
}
},
methods: {
getData() {
var that = this;
axios.post('/admin/admin/getmyinfo', Object.assign({}, PostBase))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.form = response.data.data;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
onSubmit() {
var that = this;
that.$refs['form'].validate((valid) => {
if (!valid) {
that.$message.error('仔细检查检查,是不是有个地方写得不对?');
return;
}
if (that.form.newPassword != that.form.checkPassword) {
that.$message.error('两次密码输入不一致,请确认');
return;
}
axios.post('/admin/admin/updateMyInfo', Object.assign({}, PostBase, that.form))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
});
},
}
});
</script>
</html>
-214
View File
@@ -1,214 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-form :inline="true">
<el-form-item>
<el-upload class="upload-demo" action="/admin/attach/uploadImage" :on-success="handleUploadSuccess"
:file-list="fileList" :show-file-list="false" :before-upload="beforeUpload" :data="postData"
v-loading.fullscreen.lock="fullscreenLoading">
<el-button size="small" type="primary">上传图片</el-button>
</el-upload>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-delete" size="small" @click="postMultDelete" plain>批量删除</el-button>
</el-form-item>
</el-form>
<el-table :data="dataList.data" @selection-change="changeSelection" v-loading="loading">
<el-table-column type="selection" width="50">
</el-table-column>
<el-table-column prop="attach_id" label="ID" width="60">
</el-table-column>
<el-table-column label="文件预览" width="120">
<template slot-scope="scope">
<div style="display: flex;align-items: center;">
<el-link :href="scope.row.attach_path" :underline="false" target="_blank">
<el-image style="width: 80px; height: 80px;flex:none;margin-right: 10px;background-color: #f8f8f9;border-radius: 6px;"
fit="contain" :src="scope.row.attach_path">
</el-image>
</el-link>
</div>
</template>
</el-table-column>
<el-table-column prop="attach_name" label="文件名称">
</el-table-column>
<el-table-column prop="attach_size" label="附件大小" width="100">
</el-table-column>
<el-table-column label="附件类型" width="100">
<template slot-scope="scope">
<el-tag size="medium" type="warning">{{scope.row.attach_type.toUpperCase()}}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="100">
<template slot-scope="scope">
<el-link type="danger" @click="clickDelete(scope.row)" :underline="false">删除</el-link>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination @size-change="handleSizeChange" :page-sizes="[10, 20, 50, 100,200,500]" :page-size="10"
layout="total, sizes, prev, pager, next, jumper" background @current-change="changeCurrentPage"
:current-page="dataList.current_page" :page-count="dataList.last_page" :total="dataList.total">
</el-pagination>
</div>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
this.getList();
return {
fullscreenLoading: false,
search: {
keyword: "",
filter: "attach_phone"
},
loading: true,
dataList: [],
selectList: [],
fileList: [],
form: {
page: 1,
per_page: 10,
},
postData: PostBase,
}
},
methods: {
handleUploadSuccess(res, file) {
this.fullscreenLoading = false;
if (res.code == CODE_SUCCESS) {
this.$message({
message: res.message,
type: 'success'
});
this.getList();
} else {
this.$message.error(res.message);
}
},
beforeUpload(file) {
const isImage = file.type === 'image/jpeg' || file.type === 'image/png';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isImage) {
this.$message.error('上传图片只能是 JPG/PNG 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
}
this.fullscreenLoading = true;
return isImage && isLt2M;
},
handleSizeChange(per_page) {
this.form.per_page = per_page;
this.getList();
},
time2string(timestamps, formatStr = 'MM-dd hh:mm') {
var now = new Date(timestamps * 1000),
y = now.getFullYear(),
m = now.getMonth() + 1,
d = now.getDate();
return y + "-" + (m < 10 ? "0" + m : m) + "-" + (d < 10 ? "0" + d : d) + " " + now.toTimeString().substr(0, 8);
},
postMultDelete() {
var that = this;
if (that.selectList.length == 0) {
that.$message.error('未选择任何附件!');
return;
}
this.$confirm('即将删除选中的附件, 是否确认?', '批量删除', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/attach/delete', Object.assign({}, PostBase, {
attach_id: that.selectList.join(",")
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => { });
},
changeSelection(list) {
var that = this;
that.selectList = [];
for (var index in list) {
that.selectList.push(list[index].attach_id);
}
},
clickAdd() {
var that = this;
that.formAdd = {};
that.dialogFormAdd = true;
},
clickDelete(row) {
var that = this;
this.$confirm('即将删除这个附件, 是否确认?', '删除提醒', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/attach/delete', Object.assign({}, PostBase, {
attach_id: row.attach_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => { });
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/attach/getList', Object.assign({}, PostBase, that.form, that.search))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
console.log(error);
});
}
}
})
</script>
</html>
-19
View File
@@ -1,19 +0,0 @@
</el-main>
</el-container>
</el-container>
<Uploads ref="upload"></Uploads>
<Goodslists ref="goodslist"></Goodslists>
</div>
</body>
{include file="component/view"/}
<script src="/static/admin/js/vue-2.6.10.min.js"></script>
<script src="/static/admin/js/axios.min.js"></script>
<script src="/static/admin/js/element.js"></script>
<script src="/static/admin/js/YAdmin.js"></script>
<script src="/static/admin/js/SkuForm.umd.js"></script>
<script src="/static/admin/UEditor/vue-ueditor-wrap.min.js"></script>
<script src="/static/admin/UEditor/ueditor.config.js"></script>
<script src="/static/admin/UEditor/ueditor.all.js"></script>
<script src="/static/admin/js/component.js"></script>
<script src="/static/admin/js/Sortable.min.js"></script>
<script src="/static/admin/js/vuedraggable.umd.min.js"></script>
-67
View File
@@ -1,67 +0,0 @@
<meta charset="UTF-8">
<!-- import CSS -->
<link rel="stylesheet" href="/static/admin/css/element.css">
<link rel="stylesheet" href="/static/admin/css/YAdmin.css">
</head>
<body>
<div id="app" v-cloak>
<el-container>
<el-header>
<el-col style="width: auto;">
<el-menu class="el-menu-vertical" text-color="#333333" :default-active="'{if condition="$node.node_pid"}{$node.node_pid}{else}{$node.node_id}{/if}'" unique-opened
style="border:none;" mode="horizontal" active-text-color="#333333">
{volist name="menuList" id="item"}
{if condition="count($item.subList)>0"}
{if condition="count($item.subList[0]['subList'])>0"}
<el-menu-item index="{$item.node_id}"
onclick="location.href='/{$item['subList'][0]['subList'][0]['node_module']}/{$item['subList'][0]['subList'][0]['node_controller']}/{$item['subList'][0]['subList'][0]['node_action']}';"
{if
condition="$menu==$item.node_id"
}class="is-active" {/if}>
<i class="{$item.node_icon}"></i> {$item.node_title}
</el-menu-item>
{else}
<el-menu-item index="{$item.node_id}"
onclick="location.href='/{$item['subList'][0]['node_module']}/{$item['subList'][0]['node_controller']}/{$item['subList'][0]['node_action']}';" {if
condition="$menu==$item.node_id"
}class="is-active" {/if}>
<i class="{$item.node_icon}"></i> {$item.node_title}
</el-menu-item>
{/if}
{else}
{if condition="count($item.subList)>0 || $item.node_controller=='index'"}
<el-menu-item index="{$item.node_id}"
onclick="location.href='/{$item.node_module}/{$item.node_controller}/{$item.node_action}';" {if
condition="$menu==$item.node_id"
}class="is-active" {/if}>
<i class="{$item.node_icon}"></i> {$item.node_title}
</el-menu-item>
{/if}
{/if}
{/volist}
</el-menu>
</el-col>
<el-col style="width: 240px;float: right;">
<span class="topArea">
<el-link :underline="false" class="el-icon-full-screen menuicon" onclick="requestFullScreen()"></el-link>
<!-- <el-link :underline="false" class="el-icon-brush menuicon"></el-link> -->
<el-dropdown>
<el-link :underline="false">&nbsp;{$adminInfo['admin_name']}<i class="el-icon-arrow-down"></i></el-link>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item onclick="location.href='/qfadmin/admin/updatemyinfo';">修改资料
</el-dropdown-item>
<el-dropdown-item onclick="location.href='/qfadmin/admin/motifypassword';">修改密码
</el-dropdown-item>
<el-dropdown-item onclick="location.href='/qfadmin/system/clean';">清除缓存
</el-dropdown-item>
<el-dropdown-item onclick="logout()">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</span>
</el-col>
</el-header>
<el-container class="body">
{include file="common/menu"/}
<el-main>
@@ -1,47 +0,0 @@
<meta charset="UTF-8">
<!-- import CSS -->
<link rel="stylesheet" href="/static/admin/css/element.css">
<link rel="stylesheet" href="/static/admin/css/YAdmin.css">
</head>
<body>
<div id="app" v-cloak>
<el-container>
<el-header>
<el-col style="width: auto;">
<el-menu class="el-menu-vertical" text-color="#333333" unique-opened
style="border:none;" mode="horizontal" active-text-color="#333333">
<el-menu-item onclick="location.href='./index.html?meeting_id={$datas.meeting_id??''}'" {if
condition="$action=='index'"
}class="is-active" {/if}>
<i class="el-icon-user-solid"></i> 客户管理
</el-menu-item>
<el-menu-item onclick="location.href='./team.html?meeting_id={$datas.meeting_id??''}'" {if
condition="$action=='team'"
}class="is-active" {/if}>
<i class="el-icon-s-custom"></i> 团队管理
</el-menu-item>
<el-menu-item onclick="location.href='./valetor.html?meeting_id={$datas.meeting_id??''}'" {if
condition="$action=='valetor'"
}class="is-active" {/if}>
<i class="el-icon-s-help"></i> 会务人员管理
</el-menu-item>
</el-menu>
</el-col>
<el-col style="width: 240px;float: right;">
<span class="topArea">
<el-link :underline="false" class="el-icon-full-screen menuicon" onclick="requestFullScreen()"></el-link>
<!-- <el-link :underline="false" class="el-icon-brush menuicon"></el-link> -->
<el-dropdown>
<el-link :underline="false">&nbsp;{$adminInfo['admin_name']}<i class="el-icon-arrow-down"></i></el-link>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item onclick="logout()">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</span>
</el-col>
</el-header>
<el-container class="body">
{include file="common/menu"/}
<el-main>
-44
View File
@@ -1,44 +0,0 @@
{if condition="$menuLists"}
<el-aside width="160px">
<a class="titlehome" href="/qfadmin" style="display: block;height: 62px;line-height: 62px;text-align: center;"><img src="/static/admin/images/logo.png" width="40px" style="vertical-align: middle;" /></a>
<el-menu class="el-menu-vertical-demo" text-color="#333333" default-active="'{$node.node_pid}-{$node.node_id}'" :collapse="false" :default-openeds="['{$node.node_pid}']">
{volist name="menuLists" id="item"}
{if condition="count($item.subList)>0"}
<el-submenu index="{$item.node_id}">
<template slot="title">
<i {if condition='$item.node_icon'}class="{$item.node_icon}"{else}class="el-icon-menu"{/if}></i> {$item.node_title}
</template>
{volist name="$item.subList" id="subItem"}
<el-menu-item onclick="location.href='/{$subItem.node_module}/{$subItem.node_controller}/{$subItem.node_action}';"
index="{$item.node_id}-{$subItem.node_id}" {if
condition="$subItem.node_controller==strtolower($controller) && $subItem.node_action==strtolower($action)"
}class="is-active" {/if}>{$subItem.node_title}</el-menu-item>
{/volist}
</el-submenu>
{else}
{if condition="$item.node_controller=='' && $item.node_action==''"}
<el-menu-item index="{$item.node_id}" onclick="testalert('暂无该功能')">
<i {if condition='$item.node_icon' }class="{$item.node_icon}" {else}class="el-icon-menu" {/if}></i>
{$item.node_title}
</el-menu-item>
{else}
<el-menu-item index="{$item.node_id}"
onclick="location.href='/{$item.node_module}/{$item.node_controller}/{$item.node_action}';" {if
condition="$item.node_controller==strtolower($controller) && $item.node_action==strtolower($action)"
}class="is-active" {/if}>
<i {if condition='$item.node_icon' }class="{$item.node_icon}" {else}class="el-icon-menu" {/if}></i>
{$item.node_title}
</el-menu-item>
{/if}
{/if}
{/volist}
<div style="height: 120px;"></div>
</el-menu>
<div class="version">资源管理系统<br> Version 1.0.0</div>
</el-aside>
{else}
<div style="position: absolute;top: -72px;left: 0;width: 160px;background-color: #ffffff;box-shadow: 0 0 12px 0 rgb(47 75 168 / 6%);border-radius: 12px;">
<a class="title" href="/admin" style="display: block;height: 62px;line-height: 62px;text-align: center;"><img
src="/static/admin/images/logo.png" width="40px" style="vertical-align: middle;" /></a>
</div>
{/if}
-152
View File
@@ -1,152 +0,0 @@
<template id="Upload">
<el-dialog title="图片库" :visible.sync="visible" :modal-append-to-body='false' append-to-body :close-on-click-modal="false"
width="725px">
<div class="upload-boxs">
<el-upload class="upload-right" action="/admin/attach/uploadImage" :on-success="handleUploadSuccess"
:file-list="fileList" :show-file-list="false" :before-upload="beforeUpload" :data="postData"
v-loading.fullscreen.lock="fullscreenLoading">
<el-button size="small" type="primary" icon="el-icon-upload">上传图片</el-button>
</el-upload>
</div>
<ul class="storage-list">
<li :class="item.select?'active':''" v-for="(item, index) in dataList.data" :key="index" @click="select(index)">
<el-image fit="contain" :src="item.attach_path"></el-image>
<p>{{item.attach_name}}</p>
</li>
</ul>
<p v-if="dataList.data&&dataList.data.length==0" style="text-align: center;">暂无资源</p>
<el-pagination @current-change="changeCurrentPage" layout="prev, pager, next" :current-page="dataList.current_page"
:page-count="dataList.last_page" hide-on-single-page background>
</el-pagination>
<div slot="footer" class="dialog-footer">
<div style="float: left; font-size: 13px;">
<span v-if="multiple">
当前已选 <span style="color: #F56C6C;">{{selectList.length+selected_num}}</span> 个,最多允许选择 <span
style="color: #F56C6C;">{{total_num}}</span> 个资源
</span>
<span v-else>当前已选 <span style="color: #F56C6C;">{{selectList.length}}</span> 个资源</span>
</div>
<el-button @click="visible = false" size="small">取消</el-button>
<el-button type="primary" @click="save" size="small">确定</el-button>
</div>
</el-dialog>
</template>
<template id="Single">
<div class="slectimg" v-if="multiple">
<block v-if="value.length>0">
<draggable v-model="value" chosenClass="chosen" forceFallback="true" animation="600" @start="onStart"
@end="onEnd">
<transition-group>
<div class="imgs" v-for="(v, s) in value" :key="s" style="cursor: all-scroll;">
<el-image fit="contain" :src="v" :preview-src-list="value" :z-index="s"></el-image>
<!-- <el-image fit="contain" :src="v" ></el-image> -->
<i class="close el-icon-error" @click="deles(s)"></i>
</div>
</transition-group>
</draggable>
</block>
<div class="noimg" @click="selectimg()">
<i class="el-icon-plus"></i>
</div>
</div>
<div class="slectimg" v-else>
<div class="imgs" v-if="value.length>0">
<el-image fit="contain" :src="value" :preview-src-list="[value]"></el-image>
<i class="close el-icon-error" @click="deles()"></i>
</div>
<div class="noimg" v-else @click="selectimg()">
<i class="el-icon-plus"></i>
</div>
</div>
</template>
<template id="Ueditor">
<Ueditors v-model="value" ref="Ueditor" :config="config"></Ueditors>
</template>
<template id="skuforms">
<div>
<div style="padding-bottom: 10px;">
<el-input style="width: 120px;" v-if="inputVisible" v-model="inputValue" ref="saveTagInput" size="small"
@keyup.enter.native="handleInputConfirm" placeholder="回车确定">
</el-input>
<el-button v-else class="button-new-tag" size="small" @click="showInput" style="width: 120px;">+添加规格组</el-button>
</div>
<sku-form :source-attribute="sourceAttribute" :attribute.sync="attribute" :structure="structure" :sku.sync="sku"
ref="skuForm"></sku-form>
</div>
</template>
<template id="Goodslist">
<el-dialog title="商品库" :before-close="handleClose" :visible.sync="visible" :modal-append-to-body='false' append-to-body
:close-on-click-modal="false" width="900px">
<el-form :inline="true">
<div style="float:right">
<el-form-item style="width:100px; margin-bottom: 0;">
<el-cascader v-model="search.classify" placeholder="商品分类" :options="categoryList" :props="cascaderProps"
style="width: 100%;" filterable clearable size="small" :show-all-levels="false">
</el-cascader>
</el-form-item>
<el-form-item style="margin-bottom: 0;">
<el-input placeholder="输入商品名称搜索" size="small" v-model="search.keyword" @keyup.enter.native="getList_search"
clearable @clear="getList_search"></el-input>
</el-form-item>
<el-form-item style="margin-bottom: 0;">
<el-button type="primary" icon="el-icon-search" size="small" @click="getList_search" plain>搜索
</el-button>
<el-button icon="el-icon-refresh-left" size="small" @click="getList_search(0)" plain>重置</el-button>
</el-form-item>
</div>
</el-form>
<el-table :data="dataList.data" ref="multipleTable" @selection-change="changeSelection" row-key="goods_id" reserve-selection="true" style="min-height: 425px;" v-loading="loading">
<el-table-column align="center" type="selection" reserve-selection="true" width="55"></el-table-column>
<el-table-column label="商品" prop="goods_id" min-width="380">
<template slot-scope="scope">
<el-image class="goods-image" style="width: 50px;height: 50px;" :src="scope.row.picture[0]" :preview-src-list="[scope.row.picture[0]]"
fit="contain" lazy></el-image>
<div class="goods-info cs-ml">
<p class="action" style="overflow:hidden;text-overflow:ellipsis;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 2;">
<span :title="scope.row.goods_name" class="link">{{scope.row.goods_name}}</span>
</p>
</div>
</template>
</el-table-column>
<el-table-column label="本店价" prop="goods_price">
<template slot-scope="scope">
<div class="action">
<span class="goods-shop-price">{{scope.row.goods_price}}</span>
</div>
</template>
</el-table-column>
<el-table-column label="库存" prop="stock_total">
<template slot-scope="scope">
<div class="action">
<span>{{scope.row.stock_total}}</span>
</div>
</template>
</el-table-column>
</el-table>
<div slot="footer" class="dialog-footer">
<p style="padding-bottom: 10px;">
<el-pagination hide-on-single-page="true" layout="prev, pager, next" background :current-page="form.page" @current-change="changeCurrentPage" :page-size="5" :total="dataList.total">
</el-pagination>
</p>
<p>
<el-button @click="cancels" size="small">取消</el-button>
<el-button type="primary" @click="save" size="small">确定</el-button>
</p>
</div>
</el-dialog>
</template>
-186
View File
@@ -1,186 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-card class="box-card" shadow="never">
<el-tabs v-model="activeName">
<el-tab-pane :label="item.name" :name="item.val" v-for="(item, index) in tabname" :key="index" v-if="item.show">
<div class="base_form" style="padding-right: 220px;">
<el-form ref="form" label-width="220px">
<block v-for="(items, indexs) in form" :key="indexs">
<el-form-item :label="items.conf_title?items.conf_title:items.conf_key" v-if="items.conf_type==item.val">
<block v-if="items.conf_spec==1">
<el-input type="textarea" :rows="4" v-model="items.conf_value"></el-input>
</block>
<block v-else-if="items.conf_spec==2">
<el-radio v-model="items.conf_value" v-for="(val, key) in items.conf_content" :key="key" :label="val.value">{{val.name}}</el-radio>
</block>
<block v-else-if="items.conf_spec==3">
<el-checkbox-group v-model="items.conf_value">
<el-checkbox v-for="(val, key) in items.conf_content" :key="key" :label="val.value">{{val.name}}</el-checkbox>
</el-checkbox-group>
</block>
<block v-else-if="items.conf_spec==4">
<Single v-model="items.conf_value"/>
</block>
<block v-else-if="items.conf_spec==5">
<Single v-model="items.conf_value" multiple="true" :selected_num="items.conf_value.length"/>
</block>
<block v-else-if="items.conf_spec==6">
<Ueditor v-model="items.conf_value"></Ueditor>
</block>
<block v-else>
<el-input v-model="items.conf_value"></el-input>
</block>
<span class="f_tips" v-html="items.conf_desc"><span v-if="items.conf_spec==5"> 最多上传10张</span></span>
</el-form-item>
</block>
<el-form-item>
<el-button type="primary" @click="onSubmit(item.val)">保存配置</el-button>
</el-form-item>
</el-form>
</div>
</el-tab-pane>
</el-tabs>
</el-card>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
this.getData();
return {
form: [],
activeName: "0",
tabname: [
{
name: '基础设置',
val: '0',
show: false,
},
{
name: '微信设置',
val: '8',
show: false,
},
{
name: '交易设置',
val: '10',
show: false,
},
{
name: '售后设置',
val: '11',
show: false,
},
{
name: '上传配置',
val: '2',
show: false,
},
{
name: '短信配置',
val: '3',
show: false,
},
{
name: '物流配置',
val: '9',
show: false,
},
{
name: '其他配置',
val: '4',
show: false,
},
],
}
},
methods: {
getData() {
var that = this;
axios.post('/admin/conf/getBaseConfig', Object.assign({}, PostBase))
.then(function (res) {
if (res.data.code == 200) {
for (let item of res.data.data) {
if (item.conf_spec == 2) {
for (let i = 0; i < item.conf_content.length; i++) {
let d = item.conf_content[i].split("=>");
item.conf_content[i] = {
name: d[0].toString(),
value: d[1].toString()
}
}
}else if(item.conf_spec==3){
for (let i = 0; i < item.conf_content.length; i++) {
let d = item.conf_content[i].split("=>");
item.conf_content[i] = {
name: d[0].toString(),
value: d[1].toString()
}
}
if(item.conf_value){
item.conf_value = item.conf_value.split(",");
}else{
item.conf_value = []
}
}else if (item.conf_spec == 5) {
if(item.conf_value){
item.conf_value = item.conf_value.split(",");
for (let i = 0; i < item.conf_value.length; i++) {
if (!item.conf_value[i]) {
item.conf_value.splice(i, 1);
}
}
} else {
item.conf_value = []
}
}
for (let i = 0; i < that.tabname.length; i++) {
if(that.tabname[i].val == item.conf_type){
that.tabname[i].show = true
}
}
}
that.form = res.data.data;
} else {
that.$message.error(res.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
onSubmit(index) {
var that = this;
var postData = {};
for (var i = 0; i < that.form.length; i++) {
if(that.form[i].conf_type == index){
postData[that.form[i].conf_key] = that.form[i].conf_value;
}
}
axios.post('/admin/conf/updateBaseConfig', Object.assign({}, PostBase, postData))
.then(function (res) {
if (res.data.code == 200) {
that.$message({
message: res.data.message,
type: 'success'
});
} else {
that.$message.error(res.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
}
})
</script>
</html>
-467
View File
@@ -1,467 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-form :inline="true">
<el-form-item>
<el-button icon="el-icon-plus" size="small" @click="clickAdd" plain>添加</el-button>
</el-form-item>
<div style="float:right">
<el-form-item style="width:120px;">
<el-select placeholder="筛选类别" size="small" v-model="search.filter">
<el-option value="conf_id" label="参数ID">
</el-option>
<el-option value="conf_title" label="参数名称">
</el-option>
<el-option value="conf_key" label="参数字段">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-input placeholder="输入关键词搜索" size="small" v-model="search.keyword"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="small" @click="getList_search" plain>搜索</el-button>
</el-form-item>
</div>
</el-form>
<el-table :data="dataList.data" @selection-change="changeSelection" v-loading="loading">
<el-table-column prop="conf_id" label="ID" width="60">
</el-table-column>
<el-table-column prop="conf_type" label="所属分类" width="150">
<template slot-scope="scope">
<el-tag size="small" type="success" v-if="scope.row.conf_type==1">店铺设置</el-tag>
<el-tag size="small" type="warning" v-else-if="scope.row.conf_type==2">上传配置</el-tag>
<el-tag size="small" type="info" v-else-if="scope.row.conf_type==3">短信配置</el-tag>
<el-tag size="small" type="danger" v-else-if="scope.row.conf_type==4">其他配置</el-tag>
<el-tag size="small" type="success" v-else-if="scope.row.conf_type==5">微信支付配置</el-tag>
<el-tag size="small" type="warning" v-else-if="scope.row.conf_type==6">支付宝支付配置</el-tag>
<el-tag size="small" type="success" v-else-if="scope.row.conf_type==7">微信小程序配置</el-tag>
<el-tag size="small" type="danger" v-else-if="scope.row.conf_type==8">微信公众号配置</el-tag>
<el-tag size="small" type="danger" v-else-if="scope.row.conf_type==9">物流配置</el-tag>
<el-tag size="small" type="danger" v-else-if="scope.row.conf_type==10">交易设置</el-tag>
<el-tag size="small" type="danger" v-else-if="scope.row.conf_type==11">售后设置</el-tag>
<el-tag size="small" v-else>基础设置</el-tag>
</template>
</el-table-column>
<el-table-column prop="conf_title" label="参数名称">
</el-table-column>
<el-table-column prop="conf_desc" label="参数描述">
</el-table-column>
<el-table-column prop="conf_key" label="参数字段">
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" :content="scope.row.conf_title" placement="top">
<el-link>{{scope.row.conf_key}}</el-link>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="conf_sort" label="排序" width="90">
</el-table-column>
<el-table-column label="操作" width="180">
<template slot-scope="scope">
<el-link type="primary" @click="clickEdit(scope.row)" :underline="false">编辑</el-link>&nbsp;
<el-link type="danger" @click="clickDelete(scope.row)" :underline="false" v-if="scope.row.conf_system==0">删除</el-link>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination @size-change="handleSizeChange" :page-sizes="[10, 20, 50, 100,200,500]" :page-size="10"
layout="total, sizes, prev, pager, next, jumper" background @current-change="changeCurrentPage"
:current-page="dataList.current_page" :page-count="dataList.last_page" :total="dataList.total">
</el-pagination>
</div>
<!-- 添加框 -->
<el-dialog title="添加配置" :visible.sync="dialogFormAdd" width="800px" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formAdd" status-icon :rules="rules" ref="formAdd">
<el-form-item label="所属分类" :label-width="formLabelWidth" prop="conf_type">
<el-select v-model="formAdd.conf_type" placeholder="请选择所属分类" size="medium">
<el-option label="基础设置" value="0"></el-option>
<el-option label="店铺设置" value="1"></el-option>
<el-option label="上传配置" value="2"></el-option>
<el-option label="短信配置" value="3"></el-option>
<el-option label="其他配置" value="4"></el-option>
<el-option label="微信支付配置" value="5"></el-option>
<el-option label="支付宝支付配置" value="6"></el-option>
<el-option label="微信小程序配置" value="7"></el-option>
<el-option label="微信公众号配置" value="8"></el-option>
<el-option label="物流配置" value="9"></el-option>
<el-option label="交易设置" value="10"></el-option>
<el-option label="售后设置" value="11"></el-option>
</el-select>
</el-form-item>
<el-form-item label="参数名称" :label-width="formLabelWidth" prop="conf_title">
<el-input size="medium" autocomplete="off" v-model="formAdd.conf_title"></el-input>
<span style="color: #999;">参数名称,如:网站LOGO</span>
</el-form-item>
<el-form-item label="参数字段" :label-width="formLabelWidth" prop="conf_key">
<el-input size="medium" autocomplete="off" v-model="formAdd.conf_key"></el-input>
<span style="color: #999;">参数字段,如:logo</span>
</el-form-item>
<el-form-item label="参数描述" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formAdd.conf_desc"></el-input>
<span style="color: #999;">参数描述,如:建议尺寸: 300*300</span>
</el-form-item>
<el-form-item label="字段类型" :label-width="formLabelWidth">
<el-radio-group v-model="formAdd.conf_spec" size="small">
<el-radio-button label="0">文本框</el-radio-button>
<el-radio-button label="1">多行文本框</el-radio-button>
<el-radio-button label="2">单选框</el-radio-button>
<el-radio-button label="3">多选框</el-radio-button>
<el-radio-button label="4">单图</el-radio-button>
<el-radio-button label="5">多图</el-radio-button>
<el-radio-button label="6">富文本</el-radio-button>
</el-radio-group>
<el-input v-if="formAdd.conf_spec==2 || formAdd.conf_spec==3" type="textarea" v-model="formAdd.conf_content"
:rows="4" placeholder="参数方式例如:&#10;开启=>1&#10;关闭=>0" style="margin-top: 10px;"></el-input>
</el-form-item>
<el-form-item label="显示隐藏" :label-width="formLabelWidth">
<el-switch size="medium" v-model="formAdd.conf_status"></el-switch>
</el-form-item>
<el-form-item label="排序" :label-width="formLabelWidth">
<el-input-number v-model="formAdd.conf_sort" :min="0" :max="999" size="medium" style="width: 120px;" controls-position="right" />
</el-form-item>
<el-form-item label="系统参数" :label-width="formLabelWidth">
<el-switch size="medium" v-model="formAdd.conf_system"></el-switch>
<div style="color: #999;">开启后,添加的参数将无法删除</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postAdd">确认添加</el-button>
</div>
</el-dialog>
<!-- 修改框 -->
<el-dialog title="修改配置" :visible.sync="dialogFormEdit" width="800px" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formEdit" status-icon :rules="rules" ref="formEdit">
<el-form-item label="所属分类" :label-width="formLabelWidth" prop="conf_type">
<el-select v-model="formEdit.conf_type" placeholder="请选择所属分类" size="medium">
<el-option label="基础设置" value="0"></el-option>
<el-option label="店铺设置" value="1"></el-option>
<el-option label="上传配置" value="2"></el-option>
<el-option label="短信配置" value="3"></el-option>
<el-option label="其他配置" value="4"></el-option>
<el-option label="微信支付配置" value="5"></el-option>
<el-option label="支付宝支付配置" value="6"></el-option>
<el-option label="微信小程序配置" value="7"></el-option>
<el-option label="微信公众号配置" value="8"></el-option>
<el-option label="物流配置" value="9"></el-option>
<el-option label="交易设置" value="10"></el-option>
<el-option label="售后设置" value="11"></el-option>
</el-select>
</el-form-item>
<el-form-item label="参数名称" :label-width="formLabelWidth" prop="conf_title">
<el-input size="medium" autocomplete="off" v-model="formEdit.conf_title"></el-input>
<span style="color: #999;">参数名称,如:网站LOGO</span>
</el-form-item>
<el-form-item label="参数字段" :label-width="formLabelWidth" prop="conf_key">
<el-input size="medium" autocomplete="off" v-model="formEdit.conf_key"></el-input>
<span style="color: #6881ec;">参数字段,切勿随意修改</span>
</el-form-item>
<el-form-item label="参数描述" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formEdit.conf_desc"></el-input>
<span style="color: #999;">参数描述,如:建议尺寸: 300*300</span>
</el-form-item>
<el-form-item label="字段类型" :label-width="formLabelWidth">
<el-radio-group v-model="formEdit.conf_spec" size="small">
<el-radio-button label="0">文本框</el-radio-button>
<el-radio-button label="1">多行文本框</el-radio-button>
<el-radio-button label="2">单选框</el-radio-button>
<el-radio-button label="3">多选框</el-radio-button>
<el-radio-button label="4">单图</el-radio-button>
<el-radio-button label="5">多图</el-radio-button>
<el-radio-button label="6">富文本</el-radio-button>
</el-radio-group>
<el-input v-if="formEdit.conf_spec==2 || formEdit.conf_spec==3" type="textarea" v-model="formEdit.conf_content" :rows="4" placeholder="参数方式例如:&#10;开启=>1&#10;关闭=>0" style="margin-top: 10px;"></el-input>
</el-form-item>
<el-form-item label="显示隐藏" :label-width="formLabelWidth">
<el-switch size="medium" v-model="formEdit.conf_status"></el-switch>
</el-form-item>
<el-form-item label="排序" :label-width="formLabelWidth">
<el-input-number v-model="formEdit.conf_sort" :min="0" :max="999" size="medium" style="width: 120px;"
controls-position="right" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postEdit">确认修改</el-button>
</div>
</el-dialog>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
this.getList();
return {
search: {
keyword: "",
filter: "conf_id"
},
formLabelWidth: '80px',
dialogFormAdd: false,
dialogFormEdit: false,
loading: true,
dataList: [],
selectList: [],
form: {
page: 1,
per_page: 10
},
formAdd: {
conf_status: true,
conf_spec: 0,
conf_sort: 0,
},
formEdit: {},
rules: {
conf_title: [
{ required: true, message: '参数名称必须填写', trigger: 'blur' },
],
conf_key: [
{ required: true, message: '参数字段必须填写', trigger: 'blur' },
],
conf_type: [
{ required: true, message: '所属分类必须填写', trigger: 'blur' },
],
}
}
},
methods: {
getList_search() {
this.form.page = 1;
this.getList();
},
handleSizeChange(per_page) {
this.form.per_page = per_page;
this.getList();
},
postMultDelete() {
var that = this;
if (that.selectList.length == 0) {
that.$message.error('未选择任何配置!');
return;
}
this.$confirm('即将删除选中的配置, 是否确认?', '批量删除', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/conf/delete', Object.assign({}, PostBase, {
conf_id: that.selectList.join(",")
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
changeSelection(list) {
var that = this;
that.selectList = [];
for (var index in list) {
that.selectList.push(list[index].conf_id);
}
},
postEdit() {
var that = this;
that.$refs['formEdit'].validate((valid) => {
if (!valid) {
that.$message.error('仔细检查检查,是不是有个地方写得不对?');
return;
}
axios.post('/admin/conf/update', Object.assign({}, PostBase, that.formEdit))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormEdit = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
});
},
postAdd() {
var that = this;
that.$refs['formAdd'].validate((valid) => {
if (!valid) {
that.$message.error('仔细检查检查,是不是有个地方写得不对?');
return;
}
axios.post('/admin/conf/add', Object.assign({}, PostBase, that.formAdd))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormAdd = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
});
},
clickAdd() {
var that = this;
that.formAdd = {
conf_status: true,
conf_spec: 0,
conf_sort: 0,
};
axios.post('/admin/conf/getList', Object.assign({}, PostBase))
.then(function (response) {
that.groupList = response.data.data;
if (response.data.code == CODE_SUCCESS) {
that.dialogFormAdd = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickDelete(row) {
var that = this;
this.$confirm('即将删除这个配置, 是否确认?', '删除提醒', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/conf/delete', Object.assign({}, PostBase, {
conf_id: row.conf_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
clickStatus(row) {
var that = this;
axios.post(row.conf_status ? '/admin/conf/enable' : '/admin/conf/disable', Object.assign({}, PostBase, {
conf_id: row.conf_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickEdit(row) {
var that = this;
that.formEdit = row;
axios.post('/admin/conf/getList', Object.assign({}, PostBase))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.groupList = response.data.data;
axios.post('/admin/conf/detail', Object.assign({}, PostBase, {
conf_id: row.conf_id
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
response.data.data.conf_status = response.data.data.conf_status?true:false;
response.data.data.conf_type = response.data.data.conf_type.toString();
that.formEdit = response.data.data;
that.dialogFormEdit = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/conf/getList', Object.assign({}, PostBase, that.form, that.search))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
console.log(error);
});
}
}
})
</script>
</html>
-408
View File
@@ -1,408 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-form :inline="true">
<el-form-item>
<el-button icon="el-icon-plus" size="small" @click="clickAdd" plain>添加</el-button>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-delete" size="small" @click="postMultDelete" plain>批量删除</el-button>
</el-form-item>
</el-form>
<el-table :data="dataList" @selection-change="changeSelection" v-loading="loading">
<el-table-column type="selection" width="50">
</el-table-column>
<el-table-column prop="group_id" label="组ID" width="100">
</el-table-column>
<el-table-column prop="group_name" label="组名称" width="200">
</el-table-column>
<el-table-column prop="group_desc" label="组描述">
</el-table-column>
</el-table-column>
<el-table-column label="禁用" width="80">
<template slot-scope="scope">
<el-switch v-model="scope.row.group_status==1?true:false" active-color="#ff4949"
@change="clickStatus(scope.row)">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<el-link type="primary" @click="clickEdit(scope.row)" :underline="false">编辑</el-link>&nbsp;
<el-link type="primary" @click="clickAuth(scope.row)" :underline="false">授权</el-link>&nbsp;
<el-link type="danger" @click="clickDelete(scope.row)" :underline="false">删除</el-link>
</template>
</el-table-column>
</el-table>
<!-- 添加框 -->
<el-dialog title="添加用户组" :visible.sync="dialogFormAdd" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formAdd" status-icon :rules="rules" ref="formAdd">
<el-form-item label="组名称" :label-width="formLabelWidth" prop="group_name">
<el-input size="medium" autocomplete="off" v-model="formAdd.group_name"></el-input>
</el-form-item>
<el-form-item label="组描述" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formAdd.group_desc"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postAdd">确认添加</el-button>
</div>
</el-dialog>
<!-- 修改框 -->
<el-dialog title="修改用户组" :visible.sync="dialogFormEdit" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formEdit" status-icon :rules="rules" ref="formEdit">
<el-form-item label="组名称" :label-width="formLabelWidth" prop="group_name">
<el-input size="medium" autocomplete="off" v-model="formEdit.group_name"></el-input>
</el-form-item>
<el-form-item label="组描述" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formEdit.group_desc"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postEdit">确认修改</el-button>
</div>
</el-dialog>
<!-- 授权框 -->
<el-dialog class="pub_dialog" title="用户组授权" :visible.sync="dialogFormAuth" :modal-append-to-body='false' append-to-body
width="60%" :close-on-click-modal='false'>
<div style="padding: 10px 30px;">
<el-tree :data="nodeList" @check="currentChecked" show-checkbox node-key="node_id" :props="defaultProps" :default-checked-keys="defaultkeys"></el-tree>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postAuth">确认授权</el-button>
</div>
</el-dialog>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
this.getList();
return {
checkAll: false,
search: {
group_status: "",
keyword: "",
filter: "group_id"
},
formLabelWidth: '80px',
dialogFormAdd: false,
dialogFormEdit: false,
dialogFormAuth: false,
loading: true,
dataList: [],
groupList: [],
selectList: [],
selectNodeList: [],
selectedGroupId: 0,
nodeList: [],
defaultProps: {
children: 'sub',
label: 'node_title'
},
defaultkeys: [],
form: {
page: 1
},
formAdd: {},
formEdit: {},
rules: {
group_name: [
{ required: true, message: '组名称必须填写', trigger: 'blur' },
],
}
}
},
methods: {
postMultDelete() {
var that = this;
if (that.selectList.length == 0) {
that.$message.error('未选择任何用户!');
return;
}
this.$confirm('即将删除选中的用户, 是否确认?', '批量删除', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/group/delete', Object.assign({}, PostBase, {
group_id: that.selectList.join(",")
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
changeSelection(list) {
var that = this;
that.selectList = [];
for (var index in list) {
that.selectList.push(list[index].group_id);
}
},
postAuth() {
var that = this;
axios.post('/admin/group/authorize', Object.assign({}, PostBase, {
node_ids: that.selectNodeList.join(','),
group_id: that.selectedGroupId
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormAuth = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
postEdit() {
var that = this;
that.$refs['formEdit'].validate((valid) => {
if (!valid) {
that.$message.error('仔细检查检查,是不是有个地方写得不对?');
return;
}
axios.post('/admin/group/update', Object.assign({}, PostBase, that.formEdit))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormEdit = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
});
},
postAdd() {
var that = this;
that.$refs['formAdd'].validate((valid) => {
if (!valid) {
that.$message.error('仔细检查检查,是不是有个地方写得不对?');
return;
}
axios.post('/admin/group/add', Object.assign({}, PostBase, that.formAdd))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormAdd = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
});
},
clickAdd() {
var that = this;
that.formAdd = {};
axios.post('/admin/group/getList', Object.assign({}, PostBase))
.then(function (response) {
that.groupList = response.data.data;
if (response.data.code == CODE_SUCCESS) {
that.dialogFormAdd = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickDelete(row) {
var that = this;
this.$confirm('即将删除这个用户, 是否确认?', '删除提醒', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/group/delete', Object.assign({}, PostBase, {
group_id: row.group_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
clickStatus(row) {
var that = this;
axios.post(row.group_status ? '/admin/group/enable' : '/admin/group/disable', Object.assign({}, PostBase, {
group_id: row.group_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickAuth(row) {
var that = this;
that.selectNodeList = [];
that.selectedGroupId = row.group_id;
axios.post('/admin/node/getList', Object.assign({}, PostBase))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.nodeList = response.data.data.data;
that.dialogFormAuth = true;
that.getAuthList(row);
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
getAuthList(row) {
var that = this;
that.defaultkeys = [];
axios.post('/admin/group/getAuthorize', Object.assign({}, PostBase, {
group_id: row.group_id
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.defaultkeys = [];
for (var i in response.data.data) {
that.defaultkeys.push(response.data.data[i].auth_node);
}
that.dialogFormAuth = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('设置选中状态失败');
});
},
currentChecked(nodeObj, SelectedObj) {
this.selectNodeList = SelectedObj.checkedKeys
},
clickEdit(row) {
var that = this;
that.formEdit = row;
axios.post('/admin/group/getList', Object.assign({}, PostBase))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.groupList = response.data.data;
axios.post('/admin/group/detail', Object.assign({}, PostBase, {
group_id: row.group_id
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.formEdit = response.data.data;
that.dialogFormEdit = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/group/getList', Object.assign({}, PostBase, that.form, that.search))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
console.log(error);
});
}
}
})
</script>
</html>
-28
View File
@@ -1,28 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>后台管理系统</title>
{include file="common/header"/}
<div class="homecontainer" style="height: 100%;display: flex;align-items: center;justify-content: center;">
<div>
<img src="/static/admin/images/logo@2x.png" alt="">
<p style="color: #999999;">@资源管理系统</p>
</div>
</div>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
return {
data: {}
}
},
methods: {
}
});
</script>
</html>
-462
View File
@@ -1,462 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-form :inline="true">
<el-form-item>
<el-button icon="el-icon-plus" size="small" @click="clickAdd" plain>添加</el-button>
</el-form-item>
<div style="float:right">
<el-form-item style="width:120px;">
<el-select placeholder="显示状态" size="small" v-model="search.node_show">
<el-option value="" label="全部状态">
</el-option>
<el-option v-for="show in showList" :value="show.show_id" :label="show.show_title">
</el-option>
</el-select>
</el-form-item>
<el-form-item style="width:120px;">
<el-select placeholder="筛选类别" size="small" v-model="search.filter">
<el-option value="node_id" label="节点ID">
</el-option>
<el-option value="node_title" label="节点名称">
</el-option>
<el-option value="node_desc" label="节点描述">
</el-option>
<el-option value="node_module" label="模块">
</el-option>
<el-option value="node_controller" label="控制器">
</el-option>
<el-option value="node_action" label="方法">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-input placeholder="输入关键词搜索" size="small" v-model="search.keyword"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="small" @click="getList_search" plain>搜索</el-button>
</el-form-item>
</div>
</el-form>
<el-table :data="dataList" default-expand-all @selection-change="changeSelection" v-loading="loading" row-key="node_id" :tree-props="{children: 'sub', hasChildren: 'hasChildren'}">
<el-table-column prop="node_id" label="ID" width="120">
</el-table-column>
<el-table-column prop="node_title" label="节点名称">
<template slot-scope="scope">
<i :class="scope.row.node_icon" style="font-size: 16px;"></i>&nbsp;{{scope.row.node_title}}
</template>
</el-table-column>
<el-table-column label="节点地址">
<template slot-scope="scope">
{{scope.row.node_module+"/"+scope.row.node_controller+"/"+scope.row.node_action}}
</template>
</el-table-column>
<el-table-column prop="node_order" label="排序" width="">
</el-table-column>
<el-table-column label="隐藏" width="80">
<template slot-scope="scope">
<el-switch v-model="scope.row.node_show==0?true:false" active-color="#ff4949"
@change="clickShow(scope.row)">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" width="180">
<template slot-scope="scope">
<el-link type="primary" @click="clickEdit(scope.row)" :underline="false">编辑</el-link>&nbsp;
<el-link type="danger" @click="clickDelete(scope.row)" :underline="false">删除</el-link>
</template>
</el-table-column>
</el-table>
<!-- 添加框 -->
<el-dialog title="添加节点" :visible.sync="dialogFormAdd" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formAdd" status-icon :rules="rules" ref="formAdd">
<el-form-item label="节点名称" :label-width="formLabelWidth" prop="node_title">
<el-input size="medium" autocomplete="off" v-model="formAdd.node_title"></el-input>
</el-form-item>
<el-form-item label="节点描述" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formAdd.node_desc"></el-input>
</el-form-item>
<el-form-item label="节点图标" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formAdd.node_icon"></el-input>
</el-form-item>
<el-form-item label="所属模块" :label-width="formLabelWidth" prop="node_module">
<el-input size="medium" autocomplete="off" v-model="formAdd.node_module"></el-input>
</el-form-item>
<el-form-item label="控制器" :label-width="formLabelWidth" prop="node_controller">
<el-input size="medium" autocomplete="off" v-model="formAdd.node_controller"></el-input>
</el-form-item>
<el-form-item label="方法" :label-width="formLabelWidth" prop="node_action">
<el-input size="medium" autocomplete="off" v-model="formAdd.node_action"></el-input>
</el-form-item>
<el-form-item label="是否显示" :label-width="formLabelWidth">
<el-select placeholder="请选择是否显示到菜单" size="small" v-model="formAdd.node_show">
<el-option v-for="show in showList" :value="show.show_id" :label="show.show_title">
</el-option>
</el-select>
</el-form-item>
<!-- <el-form-item label="父级菜单" :label-width="formLabelWidth">
<el-select placeholder="请选择菜单" size="small" v-model="formAdd.node_pid">
<el-option v-for="parent in parentList" :value="parent.node_id" :label="parent.node_title">
</el-option>
</el-select>
</el-form-item> -->
<el-form-item label="父级菜单" :label-width="formLabelWidth">
<el-cascader :options="parentList" v-model="formAdd.node_pid" :props="props" :show-all-levels="false">
</el-cascader>
</el-form-item>
<el-form-item label="显示顺序" :label-width="formLabelWidth" prop="node_order">
<el-input size="medium" autocomplete="off" v-model="formAdd.node_order"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postAdd">确认添加</el-button>
</div>
</el-dialog>
<!-- 修改框 -->
<el-dialog title="修改节点" :visible.sync="dialogFormEdit" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formEdit" status-icon :rules="rules" ref="formEdit">
<el-form-item label="节点名称" :label-width="formLabelWidth" prop="node_title">
<el-input size="medium" autocomplete="off" v-model="formEdit.node_title"></el-input>
</el-form-item>
<el-form-item label="节点描述" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formEdit.node_desc"></el-input>
</el-form-item>
<el-form-item label="节点图标" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formEdit.node_icon"></el-input>
</el-form-item>
<el-form-item label="所属模块" :label-width="formLabelWidth" prop="node_module">
<el-input size="medium" autocomplete="off" v-model="formEdit.node_module"></el-input>
</el-form-item>
<el-form-item label="控制器" :label-width="formLabelWidth" prop="node_controller">
<el-input size="medium" autocomplete="off" v-model="formEdit.node_controller"></el-input>
</el-form-item>
<el-form-item label="方法" :label-width="formLabelWidth" prop="node_action">
<el-input size="medium" autocomplete="off" v-model="formEdit.node_action"></el-input>
</el-form-item>
<el-form-item label="是否显示" :label-width="formLabelWidth">
<el-select placeholder="请选择是否显示到菜单" size="small" v-model="formEdit.node_show">
<el-option v-for="show in showList" :value="show.show_id" :label="show.show_title">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="父级菜单" :label-width="formLabelWidth">
<el-cascader :options="parentList" v-model="formEdit.node_pid" :props="props" :show-all-levels="false"></el-cascader>
</el-form-item>
<el-form-item label="显示顺序" :label-width="formLabelWidth" prop="node_order">
<el-input size="medium" autocomplete="off" v-model="formEdit.node_order"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postEdit">确认修改</el-button>
</div>
</el-dialog>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
this.getList();
return {
search: {
node_show: "",
keyword: "",
filter: "node_id"
},
formLabelWidth: '80px',
dialogFormAdd: false,
dialogFormEdit: false,
loading: true,
dataList: [],
parentList: [],
props: {
checkStrictly: true,
emitPath: false,
value: 'node_id',
label: 'node_title',
children: 'sub',
},
showList: [
{
show_id: 0,
show_title: "隐藏"
},
{
show_id: 1,
show_title: "显示"
}
],
selectList: [],
formAdd: {
node_readonly: 0,
node_pid: 0,
node_order: 1,
node_show: 1,
},
formEdit: {
node_readonly: 0,
node_pid: 0,
},
rules: {
node_title: [
{ required: true, message: '节点名称必须填写', trigger: 'blur' },
],
node_controller: [
// { required: true, pattern: /^[a-z]+$/, message: '控制器为有效小写字母', trigger: 'blur' },
],
node_module: [
{ required: true, pattern: /^[a-z]+$/, message: '模块名为有效小写字母', trigger: 'blur' },
],
node_action: [
{ required: true, pattern: /^[a-z]+$/, message: '方法名为有效小写字母', trigger: 'blur' },
],
node_order: [
{ required: true, pattern: /^\d$/, message: '顺序为有效自然数', trigger: 'blur' },
],
}
}
},
methods: {
getList_search() {
this.form.page = 1;
this.getList();
},
postMultDelete() {
var that = this;
if (that.selectList.length == 0) {
that.$message.error('未选择任何节点!');
return;
}
this.$confirm('即将删除选中的节点, 是否确认?', '批量删除', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/node/delete', Object.assign({}, PostBase, {
node_id: that.selectList.join(",")
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
changeSelection(list) {
var that = this;
that.selectList = [];
for (var index in list) {
that.selectList.push(list[index].node_id);
}
},
postEdit() {
var that = this;
axios.post('/admin/node/update', Object.assign({}, PostBase, that.formEdit))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormEdit = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
postAdd() {
var that = this;
axios.post('/admin/node/add', Object.assign({}, PostBase, that.formAdd))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormAdd = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickAdd() {
var that = this;
that.formAdd = {
node_readonly: 0,
node_pid: 0,
node_order: 1,
node_show: 1,
};
axios.post('/admin/node/getList', Object.assign({}, PostBase))
.then(function (response) {
that.groupList = response.data.data;
if (response.data.code == CODE_SUCCESS) {
that.dialogFormAdd = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickDelete(row) {
var that = this;
this.$confirm('即将删除这个节点, 是否确认?', '删除提醒', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/node/delete', Object.assign({}, PostBase, {
node_id: row.node_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
clickShow(row) {
var that = this;
axios.post(row.node_show ? '/admin/node/hide_menu' : '/admin/node/show_menu', Object.assign({}, PostBase, {
node_id: row.node_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickEdit(row) {
var that = this;
that.formEdit = row;
axios.post('/admin/node/getList', Object.assign({}, PostBase))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.groupList = response.data.data;
axios.post('/admin/node/detail', Object.assign({}, PostBase, {
node_id: row.node_id
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
response.data.data.node_pid = response.data.data.node_pid==0?'0':response.data.data.node_pid
that.formEdit = response.data.data;
that.dialogFormEdit = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/node/getList', Object.assign({}, PostBase, that.form, that.search))
.then(function (res) {
that.loading = false;
if (res.data.code == 200) {
that.dataList = JSON.parse(JSON.stringify(res.data.data.data));
that.parentList = [];
that.parentList.push({
node_id: "0",
node_title: "顶级菜单",
sub: [],
});
for (var i in res.data.data.data) {
res.data.data.data[i].node_id = res.data.data.data[i].node_id
that.parentList.push(res.data.data.data[i]);
}
for (let item of that.parentList) {
if(item.sub.length>0){
for (let items of item.sub) {
items.sub = undefined
}
}else{
item.sub = undefined
}
}
} else {
that.$message.error(res.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
console.log(error);
});
}
}
})
</script>
</html>
-279
View File
@@ -1,279 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>资源分类</title>
{include file="common/header"/}
<el-form :inline="true">
<el-form-item>
<el-button icon="el-icon-plus" size="small" @click="clickAdd" plain>添加</el-button>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-delete" size="small" @click="postMultDelete" plain>批量删除</el-button>
</el-form-item>
</el-form>
<el-table :data="dataList" @selection-change="changeSelection" v-loading="loading">
<el-table-column type="selection" width="50">
</el-table-column>
<el-table-column prop="source_category_id" label="ID" width="60">
</el-table-column>
<el-table-column prop="name" label="分类名称">
</el-table-column>
<el-table-column label="状态" width="80">
<template slot-scope="scope">
<el-switch v-model="scope.row.status==1?true:false" active-color="#ff4949"
@change="clickStatus(scope.row)">
</el-switch>
</template>
</el-table-column>
<el-table-column prop="sort" label="排序" width="80">
</el-table-column>
<el-table-column label="操作" width="180">
<template slot-scope="scope">
<el-link type="primary" @click="clickEdit(scope.row)" :underline="false">编辑</el-link>&nbsp;
<el-link type="danger" @click="clickDelete(scope.row)" :underline="false">删除</el-link>
</template>
</el-table-column>
</el-table>
<!-- 添加框 -->
<el-dialog title="添加资源分类名称" :visible.sync="dialogFormAdd" width="500px" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formAdd" :rules="rules" ref="formAdd">
<el-form-item prop="name" label="分类名称" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formAdd.name"></el-input>
</el-form-item>
<el-form-item prop="sort" label="排序" :label-width="formLabelWidth">
<el-input-number v-model="formAdd.sort" :min="0" :max="999" size="medium" style="width: 120px;"
controls-position="right" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postAdd()">确认添加</el-button>
</div>
</el-dialog>
<!-- 修改框 -->
<el-dialog title="修改资源分类信息" :visible.sync="dialogFormEdit" width="500px" :modal-append-to-body='false' append-to-body :close-on-click-modal='false'>
<el-form :model="formEdit" :rules="rules" ref="formEdit">
<el-form-item prop="name" label="分类名称" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" v-model="formEdit.name"></el-input>
</el-form-item>
<el-form-item prop="sort" label="排序" :label-width="formLabelWidth">
<el-input-number v-model="formEdit.sort" :min="0" :max="999" size="medium" style="width: 120px;"
controls-position="right" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postEdit()">确认修改</el-button>
</div>
</el-dialog>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
this.getList();
return {
formLabelWidth: '80px',
dialogFormAdd: false,
dialogFormEdit: false,
loading: true,
dataList: [],
selectList: [],
formAdd: {
sort: 0
},
formEdit: {
},
rules: {
name: [ { required: true, message: '请输入分类名称', trigger: 'blur' }],
}
}
},
methods: {
postMultDelete() {
var that = this;
if (that.selectList.length == 0) {
that.$message.error('未选择任何分类!');
return;
}
this.$confirm('即将删除选中的分类, 是否确认?', '批量删除', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/source_category/delete', Object.assign({}, PostBase, {
source_category_id: that.selectList.join(",")
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
});
}).catch(() => {
});
},
changeSelection(list) {
var that = this;
that.selectList = [];
for (var index in list) {
that.selectList.push(list[index].source_category_id);
}
},
postEdit() {
var that = this;
that.$refs["formEdit"].validate((valid) => {
if (valid) {
axios.post('/admin/source_category/update', Object.assign({}, PostBase, that.formEdit))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormEdit = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}
});
},
postAdd() {
var that = this;
that.$refs['formAdd'].validate((valid) => {
if (valid) {
axios.post('/admin/source_category/add', Object.assign({}, PostBase, that.formAdd))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormAdd = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}
});
},
clickAdd() {
var that = this;
that.formAdd = { sort: 0 };
that.dialogFormAdd = true;
},
clickDelete(row) {
var that = this;
this.$confirm('即将删除这个分类, 是否确认?', '删除提醒', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/source_category/delete', Object.assign({}, PostBase, {
source_category_id: row.source_category_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
clickStatus(row) {
var that = this;
axios.post(row.status ? '/admin/source_category/enable' : '/admin/source_category/disable', Object.assign({}, PostBase, {
source_category_id: row.source_category_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
clickEdit(row) {
var that = this;
that.formEdit = row;
axios.post('/admin/source_category/detail', Object.assign({}, PostBase, {
source_category_id: row.source_category_id
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.formEdit = response.data.data;
that.dialogFormEdit = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/source_category/getList', Object.assign({}, PostBase))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
console.log(error);
});
}
}
})
</script>
</html>
-212
View File
@@ -1,212 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<span>目前仅支持夸克</span>
</div>
<div class="text item">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>设置夸克cookie</span>
</div>
<div style="font-size:14px;color:#666;">
<el-form :model="form">
<el-form-item>
<el-input style="width: 100%;" v-model="form.cookie" placeholder="夸克云盘网页版的cookie"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">保存</el-button>
</el-form-item>
</el-form>
<p>Tips:夸克云盘网页版的cookie,不懂如何获取请百度;填写并保存后才能使用下面功能</p>
</div>
</el-card>
<br>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>一键转存他人链接</span>
</div>
<div style="margin-bottom: 20px;font-size:14px;color:#666;">
<font color=orangered>简单理解就是将别人的资源分享转成自己的并添加该资源到系统中</font>
<p>功能说明:</p>
<p>1、转存短剧资源到自己的网盘</p>
<p>2、生成自己的分享链接</p>
<p>3、将分享链接添加到该系统资源管理中</p>
<p>Tips:该功能仅支持单条操作;资源标题重复的会跳过;复制他人分享的网盘链接,如:https://pan.quark.cn/s/fb8402aed9c4</p>
</div>
<el-button type="danger" @click="s1Btn">立即转存</el-button>
</el-card>
<br>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>每日自动更新</span>
</div>
<div style="margin-bottom: 20px;font-size:14px;color:#666;">
<p>自动更新:<font color=orangered>转存当日及昨天的资源数据;</font></p>
<font color=orangered>将此接口添加到计划任务中,计划任务每2个小时执行一次即可;接口地址:https://你的域名/api/source/day</font>
<p>Tips:添加计划任务后方可生效;名称重复的资源会跳过转存;</p>
</div>
</el-card>
<br>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>转存心悦搜剧资源</span>
</div>
<div style="margin-bottom: 20px;font-size:14px;color:#666;">
<p>全部转存:<font color=orangered>一键转存心悦搜剧所有资源到自己的网盘及系统中</font></p>
<font color=orangered>全部转存速度比较慢,提交后请耐心等待;名称重复的资源会跳过转存;</font>
<p>Tips:心悦搜剧:https://pan.xinyuedh.com</p>
</div>
<el-button type="danger" @click="s2Btn">全部转存</el-button>
</el-card>
<!-- <el-card class="box-card">
<div slot="header" class="clearfix">
<span>清除缓存</span>
</div>
<div style="margin-bottom: 20px;font-size:14px;color:#666;">
清除缓存
<font color=orangered>不可逆操作</font>
</div>
<el-button type="danger" @click="">清除缓存</el-button>
</el-card> -->
</div>
</el-card>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
return {
form: {
cookie: '',
},
file: '',
files: [],
};
},
created() {
this.getData();
this.getFile()
},
methods: {
getData(){
let that = this
axios.post('/admin/conf/getBaseConfig', Object.assign({}, PostBase))
.then(function (response) {
if (response.data.code == 200) {
for (let item of response.data.data) {
if(item.conf_key === 'quark_cookie'){
that.form.cookie = item.conf_value
}
if(item.conf_key === 'quark_file'){
that.file = item.conf_value
}
}
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
});
},
onSubmit(){
let that = this
axios.post('/admin/conf/updateBaseConfig', Object.assign({}, PostBase, {
quark_cookie: that.form.cookie
}))
.then(function (response) {
if (response.data.code == 200) {
that.$message({
message: response.data.message,
type: 'success'
});
that.getFile()
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
s1Btn(){
let that = this
this.$prompt('请输入夸克资源分享地址', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputPattern: /.+/,
inputErrorMessage: '不能为空'
}).then(({ value }) => {
axios.post('/admin/source/transfer', Object.assign({}, PostBase, {
url: value
}))
.then(function (res) {
if (res.data.code == 200) {
that.$message({
message: res.data.message,
type: 'success'
});
} else {
that.$message.error(res.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {});
},
s2Btn(){
let that = this
this.$confirm('全部转存速度比较慢,提交后请耐心等待, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/source/transferAll', Object.assign({}, PostBase))
.then(function (res) {
if (res.data.code == 200) {
} else {
that.$message.error(res.data.message);
}
})
.catch(function (error) {
});
that.$message({
message: "已提交任务,稍后查看结果",
type: 'success'
});
}).catch(() => {});
},
getFile(){
let that = this
axios.post('/admin/source/getFiles', Object.assign({}, PostBase))
.then(function (res) {
if (res.data.code == 200) {
that.files = res.data || []
} else {
that.$message.error(res.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
},
}
})
</script>
</html>
-74
View File
@@ -1,74 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-table :data="dataList.data" v-loading="loading">
<el-table-column prop="id" label="ID" align="center" width="100">
</el-table-column>
<el-table-column prop="content" label="用户想要的资源描述">
</el-table-column>
<el-table-column prop="create_time" label="提交时间" align="center" width="200">
</el-table-column>
</el-table>
<div class="page">
<el-pagination @size-change="handleSizeChange" :page-sizes="[10, 20, 50, 100,200,500]" :page-size="10"
layout="total, sizes, prev, pager, next, jumper" background @current-change="changeCurrentPage"
:current-page="dataList.current_page" :page-count="dataList.last_page" :total="dataList.total">
</el-pagination>
</div>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
return {
loading: true,
dataList: [],
form: {
page: 1,
per_page: 10,
order: 'id desc'
},
}
},
created() {
this.getList();
},
methods: {
handleSizeChange(per_page) {
this.form.per_page = per_page;
this.getList();
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/feedback/getList', Object.assign({}, PostBase, that.form))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
});
},
}
})
</script>
</html>
-417
View File
@@ -1,417 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-form :inline="true" @submit.native.prevent>
<el-form-item>
<el-button icon="el-icon-plus" size="small" @click="clickAdd" plain>添加资源</el-button>
<el-button icon="el-icon-plus" size="small" @click="ImportShow" plain>导入资源</el-button>
<el-button icon="el-icon-document-copy" size="small" @click="getExport" plain>导出资源</el-button>
</el-form-item>
<div style="float:right">
<el-form-item style="width:120px;">
<el-select size="small" v-model="search.source_category_id" placeholder="筛选分类">
<el-option v-for="item in category" :key="item.source_category_id" :label="item.name" :value="item.source_category_id">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-input placeholder="输入关键词搜索" size="small" v-model="search.keyword" @keyup.enter.native="getList_search"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="small" @click="getList_search" plain>搜索
</el-button>
<el-button icon="el-icon-refresh-left" size="small" @click="getList_search(0)" plain>重置</el-button>
</el-form-item>
</div>
</el-form>
<el-table :data="dataList.data" v-loading="loading">
<el-table-column prop="source_id" label="ID" width="60">
</el-table-column>
<el-table-column prop="title" label="资源名称">
</el-table-column>
<el-table-column prop="source_category_id_name" label="资源分类">
</el-table-column>
<el-table-column prop="url" label="资源地址" align="center">
</el-table-column>
<el-table-column prop="is_top" label="置顶" width="90" align="center">
<template slot-scope="scope">
<p v-if="scope.row.is_top">
<el-tag size="mini">置顶</el-tag>
</p>
</template>
</el-table-column>
<el-table-column prop="sort" label="排序" width="90" align="center">
</el-table-column>
<el-table-column prop="create_time" label="入库时间" align="center" width="160">
</el-table-column>
<el-table-column prop="update_time" label="更新时间" align="center" width="160">
</el-table-column>
<el-table-column label="操作" width="180" align="center">
<template slot-scope="scope">
<div class="order-text">
<p>
<el-link type="success" @click="clickEdit(scope.row)" :underline="false">编辑</el-link>
</p>
<p>
<el-link type="danger" @click="clickDelete(scope.row)" :underline="false">删除</el-link>
</p>
</div>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination @size-change="handleSizeChange" :page-sizes="[10, 20, 50, 100,200,500]" :page-size="10"
layout="total, sizes, prev, pager, next, jumper" background @current-change="changeCurrentPage"
:current-page="dataList.current_page" :page-count="dataList.last_page" :total="dataList.total">
</el-pagination>
</div>
<!-- 添加框 -->
<el-dialog title="添加资源" :visible.sync="dialogFormAdd" :modal-append-to-body='false' append-to-body
:close-on-click-modal='false' width="680px">
<el-form :model="formAdd" :rules="rules" ref="formAdd">
<el-form-item prop="source_category_id" label="资源分类" :label-width="formLabelWidth">
<el-select size="medium" v-model="formAdd.source_category_id" placeholder="请选择分类">
<el-option v-for="item in category" :key="item.source_category_id" :label="item.name" :value="item.source_category_id">
</el-option>
</el-select>
</el-form-item>
<el-form-item prop="title" label="资源名称" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" placeholder="请输入资源名称" v-model="formAdd.title"></el-input>
</el-form-item>
<el-form-item prop="url" label="资源地址" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" placeholder="请输入资源地址" v-model="formAdd.url"></el-input>
</el-form-item>
<el-form-item prop="sort" label="排序" :label-width="formLabelWidth">
<el-input-number v-model="formAdd.sort" :min="0" :max="999" size="medium" style="width: 120px;"
controls-position="right" />
</el-form-item>
<el-form-item prop="is_top" label="置顶" :label-width="formLabelWidth">
<el-switch v-model="formAdd.is_top"></el-switch>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postAdd()">确认添加</el-button>
</div>
</el-dialog>
<!-- 修改框 -->
<el-dialog title="修改资源" :visible.sync="dialogFormEdit" :modal-append-to-body='false' append-to-body
:close-on-click-modal='false' width="680px">
<el-form :model="formEdit" :rules="rules" ref="formEdit">
<el-form-item prop="source_category_id" label="资源分类" :label-width="formLabelWidth">
<el-select size="medium" v-model="formEdit.source_category_id" placeholder="请选择分类">
<el-option v-for="item in category" :key="item.source_category_id" :label="item.name"
:value="item.source_category_id">
</el-option>
</el-select>
</el-form-item>
<el-form-item prop="title" label="资源名称" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" placeholder="请输入资源名称" v-model="formEdit.title"></el-input>
</el-form-item>
<el-form-item prop="url" label="资源地址" :label-width="formLabelWidth">
<el-input size="medium" autocomplete="off" placeholder="请输入资源地址" v-model="formEdit.url"></el-input>
</el-form-item>
<el-form-item prop="sort" label="排序" :label-width="formLabelWidth">
<el-input-number v-model="formEdit.sort" :min="0" :max="999" size="medium" style="width: 120px;"
controls-position="right" />
</el-form-item>
<el-form-item prop="is_top" label="置顶" :label-width="formLabelWidth">
<el-switch v-model="formEdit.is_top"></el-switch>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="postEdit()">确认修改</el-button>
</div>
</el-dialog>
<!-- 导入数据 -->
<el-dialog title="导入资源" :visible.sync="dialogImport" :modal-append-to-body='false' append-to-body
:close-on-click-modal='false' width="600px">
<el-form :model="Importform">
<el-form-item prop="source_category_id" label="资源分类" :label-width="formLabelWidth">
<el-select size="medium" v-model="Importform.source_category_id" placeholder="请选择分类">
<el-option v-for="item in category" :key="item.source_category_id" :label="item.name"
:value="item.source_category_id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="" :label-width="formLabelWidth">
<el-upload class="upload-demo" :data="Importform" name="file"
ref="ImportUpload"
drag
:auto-upload="false"
limit="1"
:on-exceed="handleExceed"
:on-success="handleAvatarSuccess"
action="/admin/source/imports"
accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
</el-upload>
<span style="color: #999;">请导入夸克官方导出的csv文件</span>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="ImportPost()">提交</el-button>
</div>
</el-dialog>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
return {
search: {
keyword: "",
filter: "title",
source_category_id: ''
},
formLabelWidth: '120px',
dialogFormAdd: false,
dialogFormEdit: false,
loading: true,
dataList: [],
form: {
page: 1,
per_page: 10,
order: 'source_id desc'
},
formAdd: {
},
formEdit: {
},
rules: {
title: [{ required: true, message: '请输入资源名称', trigger: 'blur' }],
url: [{ required: true, message: '请输入资源地址', trigger: 'blur' }],
},
dialogImport: false,
Importform: {
},
category: [],
}
},
created() {
this.getcategory();
},
methods: {
getList_search(val) {
if (val == 0) {
this.search = {
keyword: "",
filter: "title",
source_category_id: ''
}
}
this.form.page = 1;
this.getList();
},
handleSizeChange(per_page) {
this.form.per_page = per_page;
this.getList();
},
postEdit() {
var that = this;
that.$refs["formEdit"].validate((valid) => {
if (valid) {
axios.post('/admin/source/update', Object.assign({}, PostBase, that.formEdit))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormEdit = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}
});
},
postAdd() {
var that = this;
that.$refs['formAdd'].validate((valid) => {
if (valid) {
axios.post('/admin/source/add', Object.assign({}, PostBase, that.formAdd))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
that.dialogFormAdd = false;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
});
}
});
},
clickAdd() {
var that = this;
that.formAdd = { status: 1, share_image: '' };
that.dialogFormAdd = true;
},
clickDelete(row) {
var that = this;
this.$confirm('删除后,资源将无法查看,是否继续删除?', '删除提醒', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/source/delete', Object.assign({}, PostBase, {
source_id: row.source_id
}))
.then(function (response) {
that.getList();
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
});
}).catch(() => {
});
},
clickEdit(row) {
var that = this;
that.formEdit = row;
axios.post('/admin/source/detail', Object.assign({}, PostBase, {
source_id: row.source_id
}))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
response.data.data.source_category_id = response.data.data.source_category_id || undefined
response.data.data.is_top = response.data.data.is_top?true:false
that.formEdit = response.data.data;
that.dialogFormEdit = true;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
});
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getcategory(){
var that = this;
axios.post('/admin/source_category/getList', Object.assign({}, PostBase))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.category = response.data.data;
that.getList();
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
console.log(error);
});
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/source/getList', Object.assign({}, PostBase, that.form, that.search))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
that.setcategory()
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
});
},
setcategory(){
for (let item of this.dataList.data) {
for (let items of this.category) {
if(item.source_category_id == items.source_category_id){
item.source_category_id_name = items.name
}
}
}
},
//导入数据
ImportShow() {
this.Importform = {
}
this.dialogImport = true
},
handleExceed(files, fileList) {
this.$message.warning(`只能选择一个文件`);
},
handleAvatarSuccess(res, file) {
if (res.code == 200) {
this.getList();
this.$message({
message: res.message,
type: 'success'
});
this.dialogImport = false;
} else {
this.$message.error(res.message);
}
this.$refs.ImportUpload.clearFiles();
},
ImportPost(){
this.Importform = Object.assign(this.Importform, PostBase)
this.$nextTick(() => {
this.$refs.ImportUpload.submit();
})
},
//数据导出
getExport(){
var that = this;
var filters = Object.assign({}, PostBase, that.search);
var url = '/admin/source/excel?';
for (let key in filters) {
url += key + "=" + filters[key] + "&";
}
window.open(url);
that.$message.success('数据导出成功');
},
}
})
</script>
</html>
-90
View File
@@ -1,90 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-table :data="dataList.data" v-loading="loading">
<el-table-column prop="name" label="转存任务名称">
</el-table-column>
<el-table-column prop="total_num" label="转存总数" align="center">
</el-table-column>
<el-table-column prop="new_num" label="新增数" align="center">
</el-table-column>
<el-table-column prop="skip_num" label="重复跳过" align="center">
</el-table-column>
<el-table-column prop="fail_num" label="失败数" align="center">
</el-table-column>
<el-table-column label="状态" align="center">
<template slot-scope="scope">
<el-tag v-if="scope.row.end_time">已完成</el-tag>
<el-tag type="danger" v-else>转存中</el-tag>
</template>
</el-table-column>
<el-table-column prop="create_time" label="时间" align="center" width="240">
<template slot-scope="scope">
<p>任务开始:{{scope.row.create_time}}</p>
<p v-if="scope.row.end_time">任务结束:{{scope.row.end_time}}</p>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination @size-change="handleSizeChange" :page-sizes="[10, 20, 50, 100,200,500]" :page-size="10"
layout="total, sizes, prev, pager, next, jumper" background @current-change="changeCurrentPage"
:current-page="dataList.current_page" :page-count="dataList.last_page" :total="dataList.total">
</el-pagination>
</div>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
return {
loading: true,
dataList: [],
form: {
page: 1,
per_page: 10,
order: 'source_log_id desc'
},
}
},
created() {
this.getList();
},
methods: {
handleSizeChange(per_page) {
this.form.per_page = per_page;
this.getList();
},
changeCurrentPage(page) {
this.form.page = page;
this.getList();
},
getList() {
var that = this;
that.loading = true;
axios.post('/admin/source_log/getList', Object.assign({}, PostBase, that.form))
.then(function (response) {
that.loading = false;
if (response.data.code == CODE_SUCCESS) {
that.dataList = response.data.data;
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.loading = false;
that.$message.error('服务器内部错误');
});
},
}
})
</script>
</html>
-100
View File
@@ -1,100 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>{$node.node_title}</title>
{include file="common/header"/}
<el-card class="box-card" shadow="never">
<div slot="header" class="clearfix">
<span>系统数据清理</span>
</div>
<div class="text item">
<!-- <el-card class="box-card">
<div slot="header" class="clearfix">
<span>清理授权记录</span>
</div>
<div style="margin-bottom: 20px;font-size:14px;color:#666;">
用户组授权信息清理为
<font color=orangered>不可逆操作</font>,请谨慎操作!<br> 清理完毕后,除超级管理用户组外,其他任何用户组将无法访问系统任何功能!
<br> 建议仅在用户组权限混乱或出现其他账号安全问题时进行清理操作。
<br> 清理成功后可重新对用户组进行权限授权,即可恢复正常使用。
</div>
<el-button type="danger" @click="clearAuth">清理授权</el-button>
</el-card>
<br> -->
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>清除缓存</span>
</div>
<div style="margin-bottom: 20px;font-size:14px;color:#666;">
清除缓存
<font color=orangered>不可逆操作</font>
</div>
<el-button type="danger" @click="clearLog">清除缓存</el-button>
</el-card>
</div>
</el-card>
{include file="common/footer"/}
<script>
var app = new Vue({
el: '#app',
data() {
return {};
},
methods: {
clearLog() {
var that = this;
this.$confirm('即将清除缓存, 是否确认?', '删除日志', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios.post('/admin/system/clean', Object.assign({}, PostBase))
.then(function (response) {
if (response.data.code == CODE_SUCCESS) {
that.$message({
message: response.data.message,
type: 'success'
});
} else {
that.$message.error(response.data.message);
}
})
.catch(function (error) {
that.$message.error('服务器内部错误');
console.log(error);
});
}).catch(() => {
});
},
// clearAuth() {
// var that = this;
// this.$confirm('即将删除授权信息, 是否确认?', '清空授权', {
// confirmButtonText: '删除',
// cancelButtonText: '取消',
// type: 'warning'
// }).then(() => {
// axios.post('/admin/auth/clean', Object.assign({}, PostBase))
// .then(function (response) {
// if (response.data.code == CODE_SUCCESS) {
// that.$message({
// message: response.data.message,
// type: 'success'
// });
// } else {
// that.$message.error(response.data.message);
// }
// })
// .catch(function (error) {
// that.$message.error('服务器内部错误');
// console.log(error);
// });
// }).catch(() => {
// });
// },
}
})
</script>
</html>
-9
View File
@@ -1,9 +0,0 @@
<?php
use app\AppService;
// 系统服务定义文件
// 服务在完成全局初始化之后执行
return [
AppService::class,
];
-194
View File
@@ -1,194 +0,0 @@
<?php
/**
* QfShop 公共验证基类
*
* @author Qf
* @date 2020/7/21
*/
namespace app\validate;
use think\Validate;
class QfShop extends Validate
{
/**
* 获取某个字段的描述
* @access public
* @param string $field 参数
* @return bool
*/
public function getField(string $field)
{
return isset($this->field[$field]) ? $this->field[$field] : $field;
}
/**
* 获取规则全部键名
* @access public
* @return array
*/
public function getRuleKey()
{
return array_keys($this->rule);
}
/**
* 提取场景字段载入到规则
* @access public
* @param array $data 验证数据
* @param string $name 场景名
* @param bool $clean 当需要清理$data时场景过滤启用
* @param string $pk 模型主键
* @throws \Exception
*/
public function extractScene(array $data, string $name, bool $clean, string $pk)
{
// 为了兼容数组格式的场景验证,不对函数式场景做检测
if (!isset($this->scene[$name])) {
throw new \Exception('验证规则场景 ' . $name . ' 不存在');
}
$rule = [];
$scene = $this->scene[$name];
foreach ($scene as $key => $value) {
$sceneKey = is_numeric($key) ? $value : $key;
if ($clean && $sceneKey != $pk) {
if (!array_key_exists($sceneKey, $data)) {
continue;
}
}
if (is_numeric($key)) {
$rule[$value] = $this->rule[$value];
} else {
$rule[$key] = $value;
}
}
$this->rule = $rule;
}
/**
* 日期是否在合理范围内
* @access public
* @param array $args 参数
* @return bool
*/
public function betweenTime(...$args)
{
if (strtotime($args[0]) >= 0 && strtotime($args[0]) <= 2147483647) {
return true;
}
return $args[4] . '不在合理日期范围内';
}
/**
* 某个字段的值是否小于某个字段(日期)
* @access public
* @param array $args 参数
* @return bool
*/
public function beforeTime(...$args)
{
if (!isset($args[2][$args[1]])) {
return $this->getField($args[1]) . '不能为空';
}
if (strtotime($args[0]) <= strtotime($args[2][$args[1]])) {
return true;
}
return $args[4] . '不能大于 ' . $this->getField($args[1]);
}
/**
* 某个字段的值是否大于某个字段(日期)
* @access public
* @param array $args 参数
* @return bool
*/
public function afterTime(...$args)
{
if (!isset($args[2][$args[1]])) {
return $this->getField($args[1]) . '不能为空';
}
if (strtotime($args[0]) >= strtotime($args[2][$args[1]])) {
return true;
}
return $args[4] . '不能小于 ' . $this->getField($args[1]);
}
/**
* 检测数组内所有键值是否都为int
* @access public
* @param array $args 参数
* @return bool
*/
public function arrayHasOnlyInts(...$args)
{
if (!is_array($args[0])) {
return $args[4] . '必须是数组';
}
$isZero = 'zero' == $args[1]; // 允许存在小于等于0的整数
if ($args[0] === array_filter($args[0], function ($value) use ($isZero) {
if ($this->filter($value, FILTER_VALIDATE_INT)) {
if (false == $isZero && $value <= 0) {
return false;
}
return true;
}
return false;
})
) {
return true;
}
return $args[4] . ($isZero ? '内的键值必须是合法的整数' : '内的键值必须是大于零的整数');
}
/**
* 检测数组内所有键值是否都为string
* @access public
* @param array $args 参数
* @return bool
*/
public function arrayHasOnlyStrings(...$args)
{
if (!is_array($args[0])) {
return $args[4] . '必须是数组';
}
if ($args[0] === array_filter($args[0], function ($value) {
return is_string($value);
})
) {
return true;
}
return $args[4] . '内的键值必须是字符串';
}
/**
* 验证模块是否在指定范围内
* @access public
* @param array $args 参数
* @return bool
*/
public function checkModule(...$args)
{
$moduleList = config('extra.module_group');
if (!isset($moduleList[$args[0]])) {
return sprintf('%s必须在 %s 范围内', $args[4], implode(',', array_keys($moduleList)));
}
return true;
}
}