first commit

This commit is contained in:
编码猿
2024-09-27 01:32:49 +08:00
commit 28ebe05a64
7399 changed files with 1174529 additions and 0 deletions

View File

@@ -0,0 +1 @@
1869b3c6-ad2e-4621-aeea-d2243390b75f

View File

@@ -0,0 +1,70 @@
<?php
/**
* 访问权限控制
* Class AuthService
* @package app\admin\service
*/
namespace app\admin\service;
class AuthService {
/**
* 判断是否有权限访问该节点
* @param $node 节点
* @return bool (true:有权限,false:无权限)
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public static function checkNode($node = '') {
//如果没有传参,默认获取当前位置 模块/控制器/方法 (小写)
if (empty($node)) $node = self::getNode();
//判断当前登录是否为超级管理员
if (session('user.id') == 1) return true;
//判断是否加入RABC控制
$is_auth = model('SysNode')->where(['node' => $node, 'is_auth' => 1])->find();
if (empty($is_auth)) return true;
//获取当前用户角色组信息 ,拆表
$user = new \app\admin\model\User;
$auth_id_list = json_decode($user->where(['id' => session('user.id'), 'status' => 1, 'is_deleted' => 0])->value('auth_id'), true);
//去除失效的角色组信息
foreach ($auth_id_list as $k => $val) {
if (empty(model('SysAuth')->where(['id' => $val, 'status' => 1])->find())) unset($auth_id_list[$k]);
}
//判断是否有权限访问
foreach ($auth_id_list as $vo) {
if ($vo == 0) return true; //超级管理员组权限
$is_auth_node = model('SysAuthNode')->where(['auth' => $vo, 'node' => $is_auth['id']])->find();
if (!empty($is_auth_node)) return true;
}
return false;
}
/**
* 获取当前节点
* @return string 节点信息
*/
public static function getNode() {
$node = app('request')->module() . '/' . app('request')->controller() . '/' . app('request')->action();
return self::parseNodeStr($node);
}
/**
* 驼峰转下划线规则
* @param string $node
* @return string
*/
public static function parseNodeStr($node) {
$tmp = [];
foreach (explode('/', $node) as $name) {
$tmp[] = strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
}
return str_replace('._', '.', trim(join('/', $tmp), '/'));
}
}

View File

@@ -0,0 +1,17 @@
<?php
/**
* 验证码服务类
* Class CodeService
* @package app\admin\service
*/
namespace app\admin\service;
class CodeService {
public static function validate() {
}
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* 日志服务
* Class LogService
* @package app\admin\service
*/
namespace app\admin\service;
use think\Db;
class LogService {
/**
* 登录日志
* @param $user_id 系统用户编号
* @param $type 登录类型 (0:退出,1:登录)
* @param bool $status 状态(0:失败,1:成功)
* @param string $remark
*/
public static function loginLog($user_id, $type = 1, $status = 1, $remark = '') {
$location_info = get_location();
$insert = [
'type' => $type,
'user_id' => $user_id,
'ip' => get_ip(),
'country' => $location_info['country'],
'region' => $location_info['region'],
'city' => $location_info['city'],
'isp' => $location_info['isp'],
'location' => $location_info['country'] . $location_info['region'] . $location_info['city'] . $location_info['isp'],
'remark' => $remark,
'status' => $status,
];
Db::name('SystemLoginRecord')->insert($insert);
}
}

View File

@@ -0,0 +1,77 @@
<?php
/*
* 邮件服务类
* */
namespace app\admin\service;
use app\admin\model\User;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use think\Db;
/**
* 邮箱服务类
* Class MailService
* @package app\admin\service
*/
class MailService {
/**
* @var 邮箱服务类对象
*/
public static $mail;
/**
* 初始化服务类
* MailService constructor.
*/
public static function __init() {
$mailInfo = Db::name('SystemConfig')->where('group', 'mail')->column('name,value');//获取邮箱配置信息
self::$mail = new PHPMailer();
self::$mail->isSMTP();// 使用SMTP服务
self::$mail->CharSet = "utf8";// 编码格式为utf8,不设置编码的话,中文会出现乱码
self::$mail->Host = $mailInfo['MailHost'];// 发送方的SMTP服务器地址
self::$mail->SMTPAuth = true;// 是否使用身份验证
self::$mail->Username = $mailInfo['MailUsername'];// 发送方的QQ邮箱用户名,就是自己的邮箱名
self::$mail->Password = $mailInfo['MailPassword'];// 发送方的邮箱密码,不是登录密码,是qq的第三方授权登录码,要自己去开启,在邮箱的设置->账户->POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务 里面
self::$mail->setFrom($mailInfo['MailUsername'], $mailInfo['MailNickname']);// 设置发件人信息,如邮件格式说明中的发件人,
self::$mail->addReplyTo($mailInfo['MailReplyTo'], $mailInfo['MailNickname']);// 设置回复人信息,指的是收件人收到邮件后,如果要回复,回复邮件将发送到的邮箱地址
self::$mail->SMTPSecure = "ssl";// 使用ssl协议方式,
self::$mail->Port = 465;// QQ邮箱的ssl协议方式端口号是465/587
}
/**
* 发送邮箱信息
* @param $toemail 邮箱 (可以为单个:1111@qq.com 可以为数组:[1111@qq.com, 2222@qq.com])
* @param $title 标题
* @param $info 内容
* @return array
*/
public static function send($toemail, $title, $info) {
self::__init();
self::$mail->Subject = $title;
self::$mail->Body = $info;
// self::$mail->addCC("xxx@163.com");// 设置邮件抄送人,可以只写地址,上述的设置也可以只写地址(这个人也能收到邮件)
// self::$mail->addBCC("xxx@163.com");// 设置秘密抄送人(这个人也能收到邮件)
// self::$mail->addAttachment("bug0.jpg");// 添加附件
// self::$mail->AltBody = "纯文本";// 这个是设置纯文本方式显示的正文内容,如果不支持Html方式,就会用到这个,基本无用
//判断是否为群发信息
if (is_array($toemail)) {
foreach ($toemail as $vo) {
self::$mail->addAddress($vo, 'send');
!self::$mail->send() ? $msg[] = ['mail' => $vo, 'msg' => self::$mail->ErrorInfo] : $msg[] = ['mail' => $vo, 'msg' => '邮箱发送成功!'];
}
return ['code' => 1, 'msg' => $msg];
} else {
self::$mail->addAddress($toemail, 'send');
if (!self::$mail->send()) {
return ['code' => 1, 'msg' => self::$mail->ErrorInfo];
} else {
return ['code' => 0, 'msg' => '邮箱发送成功!'];
}
}
}
}

View File

@@ -0,0 +1,95 @@
<?php
/**
* 模型基础数据服务
* Class ModelService
* @package service
*/
namespace app\admin\service;
use think\Model;
class ModelService extends Model {
/**
* 主键定义
* @var string
*/
protected $pk = 'id';
/**
* 格式化分页
* @param array $query 分页参数 ['word' => $word]
*/
public function formatQuery($query = []) {
$format_query = [
'query' => [],
];
foreach ($query as $k => $val) {
$format_query['query'] = [$k, $val];
}
return $format_query;
}
/**
* 修改字段值
* @param $update
* @return \think\response\Json
*/
public static function editField($update) {
$data = self::where('id', $update['id'])->update([$update['field'] => $update['value']]);
if ($data == 1) {
return __success('修改成功!');
} else {
return __error('数据没有修改!');
}
}
/**
* 新增
* @param $post
* @return \think\response\Json
* @throws \think\exception\PDOException
*/
public static function addData($post) {
try {
self::insert($post);
} catch (\Exception $e) {
return __error($e->getMessage());
}
return __success('添加成功');
}
/**
* 修改
* @param $post
* @return \think\response\Json
*/
public static function editData($post) {
try {
self::where('id', $post['id'])->update($post);
} catch (\Exception $e) {
return __error($e->getMessage());
}
return __success('修改成功');
}
/**
* 软删除操作
* @param $id 列ID
* @param bool $type 删除类型 (false:软删除,true:真实删除)
* @return bool|ModelService
* @throws \Exception
*/
public function delData($id, $type = false) {
is_array($id) ? $model = self::whereIn('id', $id) : $model = self::where('id', $id);
$del = $model->delete();
if ($del >= 1) return __success('删除成功');
return __error('删除失败,请检查!');
}
}

View File

@@ -0,0 +1,187 @@
<?php
/**
* 系统节点服务类
* Class NodeService
* @package app\admin\service
*/
namespace app\admin\service;
use app\common\model\SysNode;
use think\Env;
use think\Db;
class NodeService {
/**
* 获取指定模块的所有节点,默认获取所有模块的所有节点(树形形状)
* @param array $module $module['admin','index'] 不传默认为所有模块
* @return array
*/
public static function getNodeTree($module = []) {
empty($module) && $module = self::getFolders();
$node_list = [];
foreach ($module as &$vo_m) {
$controller = self::getControllers('../application/' . $vo_m . '/controller');
foreach ($controller as &$vo_c) {
if ($vo_c != 'Login') {
$action = self::getActions('app\\' . $vo_m . '\\controller\\' . $vo_c);
foreach ($action as &$vo_a) $vo_a = AuthService::parseNodeStr($vo_m . '/' . $vo_c . '/' . $vo_a);
!empty($action) && $node_list[AuthService::parseNodeStr($vo_m)][AuthService::parseNodeStr($vo_m . '/' . $vo_c)] = $action;
}
}
}
return $node_list;
}
/**
* 获取指定目录下的所有文件夹名称
* @param $dir
* @return array
*/
public static function getFolders($dir) {
$pathList = glob($dir . '/*');
$folder_list = [];
foreach ($pathList as $vo) {
if (is_dir($vo)) {
$folder_list[] = str_replace($dir . '/', '', $vo);
}
}
return $folder_list;
}
/**
* 获取指定模块中的控制器
* @param $dir
* @return array|mixed
*/
public static function getControllers($dir) {
list($folders, $pathList, $controllerList) = [self::getFolders($dir), glob($dir . '/*.php'), []];
foreach ($folders as $folder) {
$pathFolders = glob("{$dir}/{$folder}/*.php");
foreach ($pathFolders as $pathFolder) {
$pathList[] = $pathFolder;
}
}
foreach ($pathList as $vo) {
$className = explode("/controller/", $vo);
$className = str_replace('.php', '', end($className));
$className = str_replace('/', '.', $className);
$controllerList[] = $className;
}
return $controllerList;
}
/**
* 获取控制器中的方法
* @param $className
* @return array|mixed
*/
public static function getActions($className) {
list($actions, $actionList) = [get_class_methods($className), []];
if (!empty($actions)) {
foreach ($actions as $action) {
if (strpos($action, '_') !== 0 && $action !== 'initialize') {
$actionList[] = $action;
}
}
}
return $actionList;
}
/**
* 获取系统节点
* @param array $modules 模块名
* @return array|mixed 节点列表
*/
public static function getNodeList($modules = []) {
list($nodeList, $appPath, $appNamespace) = [[], '../application', env('app_namespace')];
empty($modules) && $modules = self::getFolders($appPath);
foreach ($modules as $module) {
$nodeList[] = AuthService::parseNodeStr($module);
$modulePath = "{$appPath}/{$module}/controller";
$controllers = self::getControllers($modulePath);
foreach ($controllers as $controller) {
$nodeList[] = AuthService::parseNodeStr("{$module}/{$controller}");
$controller_replace = str_replace('.', '\\', $controller);
$controllerPath = "{$appNamespace}\\{$module}\\controller\\{$controller_replace}";
$actions = self::getActions($controllerPath);
foreach ($actions as $action) {
$nodeList[] = AuthService::parseNodeStr("{$module}/{$controller}/{$action}");
}
}
}
return $nodeList;
}
/**
* 刷新系统节点
* @param array $modules
*/
public static function refreshNode($modules = []) {
empty($modules) && $modules = self::getFolders(env('app_path'));
list($nodeList, $insertNode) = [self::getNodeList($modules), []];
foreach ($nodeList as $vo) {
$nodeInfo = Db::name('SystemNode')->where(['node' => $vo])->find();
if (empty($nodeInfo)) {
list($nodeCount, $nodeType) = [substr_count($vo, '/'), 0];
switch ($nodeCount) {
case 0:
$nodeType = 1;
break;
case 1:
$nodeType = 2;
break;
case 2:
$nodeType = 3;
break;
}
$insertNode[] = ['type' => $nodeType, 'node' => $vo];
}
}
if (!empty($insertNode)) {
Db::startTrans();
try {
Db::name('SystemNode')->insertAll($insertNode);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
return ['code' => 1, 'msg' => $e->getMessage()];
}
return ['code' => 0, 'msg' => '节点刷新成功!'];
} else {
return ['code' => 1, 'msg' => '节点数据暂无变化!'];
}
}
/**
* 清除失效节点
* @param array $modules
*/
public static function cleanNode($modules = []) {
empty($modules) && $modules = self::getFolders(env('app_path'));
$nodeList = Db::name('SystemNode')->where(['is_auto' => 0])->select();
$autoNodeList = self::getNodeList($modules);
foreach ($nodeList as $voNode) {
$is_exist = false;
foreach ($autoNodeList as $voAutoNode) {
$voNode['node'] == $voAutoNode && $is_exist = true;
}
$is_exist == false && $delete[] = $voNode['id'];
}
if (!empty($delete)) {
Db::startTrans();
try {
Db::name('SystemNode')->delete($delete);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
return ['code' => 1, 'msg' => $e->getMessage()];
}
return ['code' => 0, 'msg' => '清除失效节点成功!'];
} else {
return ['code' => 1, 'msg' => '无失效节点!'];
}
}
}

View File

@@ -0,0 +1,81 @@
<?php
/*
* 七牛云cdn服务类
* */
namespace app\admin\service;
use think\Db;
use think\facade\Config;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
class QiniuService {
/**
* 上传至七牛云
* @param string $filePath 要上传文件的本地路径
* @param string $key 上传到七牛后保存的文件名
* @return mixed
* @throws \Exception
*/
public static function upload($filePath = '') {
// 需要填写你的 Access Key 和 Secret Key
$accessKey = Config::get('qiniu.AccessKey');
$secretKey = Config::get('qiniu.SecretKey');
$bucket = Config::get('qiniu.Bucket');
// 构建鉴权对象
$auth = new Auth($accessKey, $secretKey);
// 生成上传 Token
$token = $auth->uploadToken($bucket);
// 初始化 UploadManager 对象并进行文件的上传。
$uploadMgr = new UploadManager();
// 要上传文件的本地路径
$filePath = ".{$filePath}";
// 上传到七牛后保存的文件名
$key = md5($filePath) . ToolService::getSuffix($filePath);
// 初始化 UploadManager 对象并进行文件的上传。
$uploadMgr = new UploadManager();
// 调用 UploadManager 的 putFile 方法进行文件的上传。
list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath);
if ($err !== null) {
return $err;
} else {
$url = Config::get('qiniu.url') . '/' . $ret['key'];
return $url;
}
}
public static function base64($base64, $key) {
$accessKey = Config::get('qiniu.AccessKey');
$secretKey = Config::get('qiniu.SecretKey');
$bucket = Config::get('qiniu.Bucket');
$auth = new Auth($accessKey, $secretKey);
$token = $auth->uploadToken($bucket);
$uploadMgr = new UploadManager();
// 上传字符串到七牛
list($ret, $err) = $uploadMgr->put($token, $key, $base64);
if ($err !== null) {
return $err;
} else {
return $ret;
}
}
/**
* 获取七牛云上传token
* @return string
*/
public static function getToken() {
// 需要填写你的 Access Key 和 Secret Key
$accessKey = Config::get('qiniu.AccessKey');
$secretKey = Config::get('qiniu.SecretKey');
$bucket = Config::get('qiniu.Bucket');
// 构建鉴权对象
$auth = new Auth($accessKey, $secretKey);
// 生成上传 Token
$token = $auth->uploadToken($bucket);
return $token;
}
}

View File

@@ -0,0 +1,75 @@
<?php
/*
* 工具服务类
* */
namespace app\admin\service;
class ToolService {
/**
* 获取文件后缀名
* @param $filename
* @return string
*/
public static function getSuffix($filename) {
return strrchr($filename, '.');
}
/**
* 加密
* @param $data 加密内容
* @param $key 秘钥
* @return string
*/
public static function encrypt($data, $key) {
$key = md5($key);
$x = 0;
$len = strlen($data);
$l = strlen($key);
list($char, $str) = ['', ''];
for ($i = 0; $i < $len; $i++) {
if ($x == $l) {
$x = 0;
}
$char .= $key{$x};
$x++;
}
for ($i = 0; $i < $len; $i++) {
$str .= chr(ord($data{$i}) + (ord($char{$i})) % 256);
}
return base64_encode($str);
}
/**
* 解密
* @param $data 解密内容
* @param $key 秘钥
* @return string
*/
public static function decrypt($data, $key) {
$key = md5($key);
$x = 0;
$data = base64_decode($data);
$len = strlen($data);
$l = strlen($key);
list($char, $str) = ['', ''];
for ($i = 0; $i < $len; $i++) {
if ($x == $l) {
$x = 0;
}
$char .= substr($key, $x, 1);
$x++;
}
for ($i = 0; $i < $len; $i++) {
if (ord(substr($data, $i, 1)) < ord(substr($char, $i, 1))) {
$str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
} else {
$str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
}
}
return $str;
}
}