no message

This commit is contained in:
hajimi
2026-06-11 12:15:29 +08:00
parent 10ebe39c30
commit 96efa1d905
5859 changed files with 815501 additions and 5 deletions
+80
View File
@@ -0,0 +1,80 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\cache;
/**
* //后台账号安全机制,连续输错后锁定,防止账号密码暴力破解
* Class AdminAccountSafeCache
* @package app\common\cache
*/
class AdminAccountSafeCache extends BaseCache
{
private $key;//缓存次数名称
public $minute = 15;//缓存设置为15分钟,即密码错误次数达到,锁定15分钟
public $count = 15; //设置连续输错次数,即15分钟内连续输错误15次后,锁定
public function __construct()
{
parent::__construct();
$ip = \request()->ip();
$this->key = $this->tagName . $ip;
}
/**
* @notes 记录登录错误次数
* @author 令狐冲
* @date 2021/6/30 01:51
*/
public function record()
{
if ($this->get($this->key)) {
//缓存存在,记录错误次数
$this->inc($this->key, 1);
} else {
//缓存不存在,第一次设置缓存
$this->set($this->key, 1, $this->minute * 60);
}
}
/**
* @notes 判断是否安全
* @return bool
* @author 令狐冲
* @date 2021/6/30 01:53
*/
public function isSafe()
{
$count = $this->get($this->key);
if ($count >= $this->count) {
return false;
}
return true;
}
/**
* @notes 删除该ip记录错误次数
* @author 令狐冲
* @date 2021/6/30 01:55
*/
public function relieve()
{
$this->delete($this->key);
}
}
+122
View File
@@ -0,0 +1,122 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\cache;
use app\adminapi\logic\auth\AuthLogic;
/**
* 管理员权限缓存
* Class AdminAuthCache
* @package app\common\cache
*/
class AdminAuthCache extends BaseCache
{
private $prefix = 'admin_auth_';
private $authConfigList = [];
private $cacheMd5Key = ''; //权限文件MD5的key
private $cacheAllKey = ''; //全部权限的key
private $cacheUrlKey = ''; //管理员的url缓存key
private $authMd5 = ''; //权限文件MD5的值
private $adminId = '';
public function __construct($adminId = '')
{
parent::__construct();
$this->adminId = $adminId;
// 全部权限
$this->authConfigList = AuthLogic::getAllAuth();
// 当前权限配置文件的md5
$this->authMd5 = md5(json_encode($this->authConfigList));
$this->cacheMd5Key = $this->prefix . 'md5';
$this->cacheAllKey = $this->prefix . 'all';
$this->cacheUrlKey = $this->prefix . 'url_' . $this->adminId;
$cacheAuthMd5 = $this->get($this->cacheMd5Key);
$cacheAuth = $this->get($this->cacheAllKey);
//权限配置和缓存权限对比,不一样说明权限配置文件已修改,清理缓存
if ($this->authMd5 !== $cacheAuthMd5 || empty($cacheAuth)) {
$this->deleteTag();
}
}
/**
* @notes 获取管理权限uri
* @param $adminId
* @return array|mixed
* @author 令狐冲
* @date 2021/8/19 15:27
*/
public function getAdminUri()
{
//从缓存获取,直接返回
$urisAuth = $this->get($this->cacheUrlKey);
if ($urisAuth) {
return $urisAuth;
}
//获取角色关联的菜单id(菜单或权限)
$urisAuth = AuthLogic::getAuthByAdminId($this->adminId);
if (empty($urisAuth)) {
return [];
}
$this->set($this->cacheUrlKey, $urisAuth, 3600);
//保存到缓存并读取返回
return $urisAuth;
}
/**
* @notes 获取全部权限uri
* @return array|mixed
* @author cjhao
* @date 2021/9/13 11:41
*/
public function getAllUri()
{
$cacheAuth = $this->get($this->cacheAllKey);
if ($cacheAuth) {
return $cacheAuth;
}
// 获取全部权限
$authList = AuthLogic::getAllAuth();
//保存到缓存并读取返回
$this->set($this->cacheMd5Key, $this->authMd5);
$this->set($this->cacheAllKey, $authList);
return $authList;
}
/**
* @notes 清理管理员缓存
* @return bool
* @author cjhao
* @date 2021/10/13 18:47
*/
public function clearAuthCache()
{
$this->tag($this->cacheUrlKey)->clear();
return true;
}
}
+119
View File
@@ -0,0 +1,119 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\cache;
use app\common\model\auth\Admin;
use app\common\model\auth\AdminSession;
use app\common\model\auth\SystemRole;
/**
* 管理员token缓存
* Class AdminTokenCache
* @package app\common\cache
*/
class AdminTokenCache extends BaseCache
{
private $prefix = 'token_admin_';
/**
* @notes 通过token获取缓存管理员信息
* @param $token
* @return false|mixed
* @author 令狐冲
* @date 2021/6/30 16:57
*/
public function getAdminInfo($token)
{
//直接从缓存获取
$adminInfo = $this->get($this->prefix . $token);
if ($adminInfo) {
return $adminInfo;
}
//从数据获取信息被设置缓存(可能后台清除缓存)
$adminInfo = $this->setAdminInfo($token);
if ($adminInfo) {
return $adminInfo;
}
return false;
}
/**
* @notes 通过有效token设置管理信息缓存
* @param $token
* @return array|false|mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 令狐冲
* @date 2021/7/5 12:12
*/
public function setAdminInfo($token)
{
$adminSession = AdminSession::where([['token', '=', $token], ['expire_time', '>', time()]])
->find();
if (empty($adminSession)) {
return [];
}
$admin = Admin::where('id', '=', $adminSession->admin_id)
->append(['role_id'])
->find();
$roleName = '';
$roleLists = SystemRole::column('name', 'id');
if ($admin['root'] == 1) {
$roleName = '系统管理员';
} else {
foreach ($admin['role_id'] as $roleId) {
$roleName .= $roleLists[$roleId] ?? '';
$roleName .= '/';
}
$roleName = trim($roleName, '/');
}
$adminInfo = [
'admin_id' => $admin->id,
'root' => $admin->root,
'name' => $admin->name,
'account' => $admin->account,
'role_name' => $roleName,
'role_id' => $admin->role_id,
'token' => $token,
'terminal' => $adminSession->terminal,
'expire_time' => $adminSession->expire_time,
'login_ip' => request()->ip(),
];
$this->set($this->prefix . $token, $adminInfo, new \DateTime(Date('Y-m-d H:i:s', $adminSession->expire_time)));
return $this->getAdminInfo($token);
}
/**
* @notes 删除缓存
* @param $token
* @return bool
* @author 令狐冲
* @date 2021/7/3 16:57
*/
public function deleteAdminInfo($token)
{
return $this->delete($this->prefix . $token);
}
}
+68
View File
@@ -0,0 +1,68 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace app\common\cache;
use think\App;
use think\Cache;
/**
* 缓存基础类,用于管理缓存
* Class BaseCache
* @package app\common\cache
*/
abstract class BaseCache extends Cache
{
/**
* 缓存标签
* @var string
*/
protected $tagName;
public function __construct()
{
parent::__construct(app());
$this->tagName = get_class($this);
}
/**
* @notes 重写父类set,自动打上标签
* @param string $key
* @param mixed $value
* @param null $ttl
* @return bool
* @author 段誉
* @date 2021/12/27 14:16
*/
public function set($key, $value, $ttl = null): bool
{
return $this->store()->tag($this->tagName)->set($key, $value, $ttl);
}
/**
* @notes 清除缓存类所有缓存
* @return bool
* @author 段誉
* @date 2021/12/27 14:16
*/
public function deleteTag(): bool
{
return $this->tag($this->tagName)->clear();
}
}
+70
View File
@@ -0,0 +1,70 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\cache;
class ExportCache extends BaseCache
{
protected $uniqid = '';
public function __construct()
{
parent::__construct();
//以微秒计的当前时间,生成一个唯一的 ID,以tagname为前缀
$this->uniqid = md5(uniqid($this->tagName,true).mt_rand());
}
/**
* @notes 获取excel缓存目录
* @return string
* @author 令狐冲
* @date 2021/7/28 17:36
*/
public function getSrc()
{
return app()->getRootPath() . 'runtime/file/export/'.date('Y-m').'/'.$this->uniqid.'/';
}
/**
* @notes 设置文件路径缓存地址
* @param $fileName
* @return string
* @author 令狐冲
* @date 2021/7/28 17:36
*/
public function setFile($fileName)
{
$src = $this->getSrc();
$key = md5($src . $fileName) . time();
$this->set($key, ['src' => $src, 'name' => $fileName], 300);
return $key;
}
/**
* @notes 获取文件缓存的路径
* @param $key
* @return mixed
* @author 令狐冲
* @date 2021/7/26 18:36
*/
public function getFile($key)
{
return $this->get($key);
}
}
+80
View File
@@ -0,0 +1,80 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\cache;
/**
* //后台账号安全机制,连续输错后锁定,防止账号密码暴力破解
* Class AdminAccountSafeCache
* @package app\common\cache
*/
class UserAccountSafeCache extends BaseCache
{
private $key;//缓存次数名称
public $minute = 15;//缓存设置为15分钟,即密码错误次数达到,锁定15分钟
public $count = 5; //设置连续输错次数,即15分钟内连续输错误5次后,锁定
public function __construct(string $account = '')
{
parent::__construct();
$ip = \request()->ip();
$this->key = $this->tagName . $ip . ':' . $account;
}
/**
* @notes 记录登录错误次数
* @author 令狐冲
* @date 2021/6/30 01:51
*/
public function record()
{
if ($this->get($this->key)) {
//缓存存在,记录错误次数
$this->inc($this->key, 1);
} else {
//缓存不存在,第一次设置缓存
$this->set($this->key, 1, $this->minute * 60);
}
}
/**
* @notes 判断是否安全
* @return bool
* @author 令狐冲
* @date 2021/6/30 01:53
*/
public function isSafe()
{
$count = $this->get($this->key);
if ($count >= $this->count) {
return false;
}
return true;
}
/**
* @notes 删除该ip记录错误次数
* @author 令狐冲
* @date 2021/6/30 01:55
*/
public function relieve()
{
$this->delete($this->key);
}
}
+105
View File
@@ -0,0 +1,105 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\cache;
use app\common\model\user\User;
use app\common\model\user\UserSession;
class UserTokenCache extends BaseCache
{
private $prefix = 'token_user_';
/**
* @notes 通过token获取缓存用户信息
* @param $token
* @return array|false|mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 段誉
* @date 2022/9/16 10:11
*/
public function getUserInfo($token)
{
//直接从缓存获取
$userInfo = $this->get($this->prefix . $token);
if ($userInfo) {
return $userInfo;
}
//从数据获取信息被设置缓存(可能后台清除缓存)
$userInfo = $this->setUserInfo($token);
if ($userInfo) {
return $userInfo;
}
return false;
}
/**
* @notes 通过有效token设置用户信息缓存
* @param $token
* @return array|false|mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 段誉
* @date 2022/9/16 10:11
*/
public function setUserInfo($token)
{
$userSession = UserSession::where([['token', '=', $token], ['expire_time', '>', time()]])->find();
if (empty($userSession)) {
return [];
}
$user = User::where('id', '=', $userSession->user_id)
->find();
$userInfo = [
'user_id' => $user->id,
'nickname' => $user->nickname,
'token' => $token,
'sn' => $user->sn,
'mobile' => $user->mobile,
'avatar' => $user->avatar,
'terminal' => $userSession->terminal,
'expire_time' => $userSession->expire_time,
];
$ttl = new \DateTime(Date('Y-m-d H:i:s', $userSession->expire_time));
$this->set($this->prefix . $token, $userInfo, $ttl);
return $this->getUserInfo($token);
}
/**
* @notes 删除缓存
* @param $token
* @return bool
* @author 段誉
* @date 2022/9/16 10:13
*/
public function deleteUserInfo($token)
{
return $this->delete($this->prefix . $token);
}
}
+65
View File
@@ -0,0 +1,65 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\cache;
class WebScanLoginCache extends BaseCache
{
private $prefix = 'web_scan_';
/**
* @notes 获取扫码登录状态标记
* @param $state
* @return false|mixed
* @author 段誉
* @date 2022/10/20 18:39
*/
public function getScanLoginState($state)
{
return $this->get($this->prefix . $state);
}
/**
* @notes 设置扫码登录状态
* @param $state
* @return false|mixed
* @author 段誉
* @date 2022/10/20 18:31
*/
public function setScanLoginState($state)
{
$this->set($this->prefix . $state, $state, 600);
return $this->getScanLoginState($state);
}
/**
* @notes 删除缓存
* @param $token
* @return bool
* @author 段誉
* @date 2022/9/16 10:13
*/
public function deleteLoginState($state)
{
return $this->delete($this->prefix . $state);
}
}
@@ -0,0 +1,31 @@
<?php
namespace app\common\command;
use app\common\service\article\ArticleAiCommentService;
use think\console\Command;
use think\console\Input;
use think\console\Output;
class ArticleAiComment extends Command
{
protected function configure()
{
$this->setName('article_ai_comment')
->setDescription('资讯AI评论定时任务');
}
protected function execute(Input $input, Output $output)
{
$summary = ArticleAiCommentService::tick();
$output->writeln(sprintf(
'[ArticleAiComment] 虚拟账号 %d 个,新增任务 %d 个,已执行 %d 个',
$summary['virtual_user_count'] ?? 0,
$summary['seeded']['created'] ?? 0,
$summary['processed']['done'] ?? 0
));
return 0;
}
}
@@ -0,0 +1,93 @@
<?php
namespace app\common\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\console\input\Argument;
class CrawlerCommand extends Command
{
protected function configure()
{
$this->setName('crawler')
->addArgument('action', Argument::REQUIRED, '执行动作: standings/schedule/all/menu')
->setDescription('懂球帝数据爬虫');
}
protected function execute(Input $input, Output $output)
{
$action = $input->getArgument('action');
$allowed = [
'standings',
'schedule',
'all',
'menu',
'news',
'league_news',
'article_content',
'live',
'lottery',
'lottery_draw',
'lottery_draw_force',
'match_data',
'init-db',
'test',
'csl_match',
'nba_match',
'cba_match',
'epl_match',
'bundesliga_match',
'laliga_match',
'seriea_match',
'ligue1_match',
'ucl_match',
'uel_match',
'tennis_match',
'esports_match',
'sports_match',
'truth_social',
'crypto_news',
'lottery_news',
'taiwan_lottery_news',
'hkjc_lottery_news',
'lottery_community',
'nba_news',
'cba_news',
'article_content_fetch',
'fifa_worldcup_news',
'dqd_worldcup',
'match_finish',
'live_detail',
];
if (!in_array($action, $allowed)) {
$output->writeln("<error>不支持的动作: {$action}, 可选: " . implode('/', $allowed) . "</error>");
return;
}
// 文件锁防止同一动作并发执行
$lockFile = runtime_path() . "crawler_{$action}.lock";
$fp = fopen($lockFile, 'w');
if (!flock($fp, LOCK_EX | LOCK_NB)) {
$output->writeln("<comment>[Crawler] {$action} 正在执行中,跳过本次</comment>");
fclose($fp);
return;
}
try {
$crawlerDir = app()->getRootPath() . 'public/dongqiudi-crawler';
$venvPython = $crawlerDir . '/venv/bin/python3';
$python = file_exists($venvPython) ? $venvPython : 'python3';
$cmd = "cd {$crawlerDir} && {$python} main.py {$action} 2>&1";
$output->writeln("<info>[Crawler] 执行: {$cmd}</info>");
$result = shell_exec($cmd);
$output->writeln($result ?: '(无输出)');
} finally {
flock($fp, LOCK_UN);
fclose($fp);
@unlink($lockFile);
}
}
}
+236
View File
@@ -0,0 +1,236 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\command;
use app\common\enum\CrontabEnum;
use app\common\model\CrontabLog;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use Cron\CronExpression;
use think\facade\Console;
use app\common\model\Crontab as CrontabModel;
use app\common\service\crontab\CrontabAlertService;
/**
* 定时任务
* Class Crontab
* @package app\command
*/
class Crontab extends Command
{
protected const CRAWLER_DEFAULT_TIMEOUT = 600;
protected const CRAWLER_ACTION_TIMEOUTS = [
'csl_match' => 180,
'nba_match' => 180,
'cba_match' => 180,
'epl_match' => 180,
'bundesliga_match' => 180,
'laliga_match' => 180,
'seriea_match' => 180,
'ligue1_match' => 180,
'ucl_match' => 180,
'uel_match' => 180,
'tennis_match' => 180,
'esports_match' => 180,
'sports_match' => 180,
'live_detail' => 180,
'match_finish' => 180,
'lottery_draw' => 180,
'lottery_draw_force' => 180,
'article_content' => 600,
'article_content_fetch' => 900,
'league_news' => 900,
'fifa_worldcup_news' => 600,
'dqd_worldcup' => 600,
];
protected function configure()
{
$this->setName('crontab')
->setDescription('定时任务');
}
protected function execute(Input $input, Output $output)
{
$lists = CrontabModel::where('status', CrontabEnum::START)->select()->toArray();
if (empty($lists)) {
return false;
}
$time = time();
foreach ($lists as $item) {
if (empty($item['last_time'])) {
$lastTime = (new CronExpression($item['expression']))
->getNextRunDate()
->getTimestamp();
CrontabModel::where('id', $item['id'])->update([
'last_time' => $lastTime,
]);
continue;
}
$nextTime = (new CronExpression($item['expression']))
->getNextRunDate($item['last_time'])
->getTimestamp();
if ($nextTime > $time) {
// 未到时间,不执行
continue;
}
// 开始执行
self::start($item);
}
}
public static function start($item)
{
if ($item['command'] === 'crawler') {
self::startCrawler($item);
return;
}
$startTime = microtime(true);
$error = '';
$outputStr = '';
try {
ob_start();
$params = explode(' ', $item['params']);
if (is_array($params) && !empty($item['params'])) {
Console::call($item['command'], $params);
} else {
Console::call($item['command']);
}
$outputStr = ob_get_clean() ?: '';
CrontabModel::where('id', $item['id'])->update(['error' => '']);
} catch (\Exception $e) {
$outputStr = ob_get_clean() ?: '';
$error = $e->getMessage();
CrontabModel::where('id', $item['id'])->update([
'error' => $error,
'status' => CrontabEnum::ERROR
]);
} finally {
$endTime = microtime(true);
$useTime = round(($endTime - $startTime), 2);
$maxTime = max($useTime, $item['max_time']);
$logId = 0;
CrontabModel::where('id', $item['id'])->update([
'last_time' => time(),
'time' => $useTime,
'max_time' => $maxTime
]);
try {
$log = CrontabLog::create([
'crontab_id' => $item['id'],
'name' => $item['name'],
'command' => $item['command'],
'params' => $item['params'],
'status' => $error ? 2 : 1,
'output' => $error ?: mb_substr($outputStr ?: '执行完成', 0, 5000),
'elapsed' => $useTime,
'trigger_type' => 1,
]);
$logId = (int) $log->id;
} catch (\Exception $logEx) {
}
try {
if ($error) {
CrontabAlertService::upsertCommandException($item, $error ?: $outputStr, $logId);
} else {
CrontabAlertService::resolveByCrontabId((int) $item['id']);
}
} catch (\Exception $alertEx) {
}
}
}
protected static function startCrawler($item)
{
$crawlerDir = app()->getRootPath() . 'public/dongqiudi-crawler';
$python = is_file($crawlerDir . '/venv/bin/python3') ? $crawlerDir . '/venv/bin/python3' : 'python3';
$action = $item['params'] ?: 'all';
$timeout = self::getCrawlerActionTimeout($action);
$now = time();
self::markStaleCrawlerLogs($item, $timeout, $now);
$running = CrontabLog::where('crontab_id', $item['id'])
->where('status', 0)
->where('create_time', '>', $now - $timeout)
->order('id', 'desc')
->findOrEmpty();
if (!$running->isEmpty()) {
CrontabModel::where('id', $item['id'])->update([
'last_time' => $now,
'error' => '上一次任务仍在执行,已跳过本次',
]);
return;
}
$log = CrontabLog::create([
'crontab_id' => $item['id'],
'name' => $item['name'],
'command' => $item['command'],
'params' => $item['params'],
'status' => 0,
'output' => '',
'elapsed' => 0,
'trigger_type' => 1,
]);
$logId = $log->id;
$crontabId = $item['id'];
$cmd = "cd {$crawlerDir} && nohup {$python} main.py {$action} --log-id={$logId} --crontab-id={$crontabId} > /dev/null 2>&1 &";
\shell_exec($cmd);
CrontabModel::where('id', $item['id'])->update([
'last_time' => time(),
'error' => '',
]);
}
protected static function getCrawlerActionTimeout(string $action): int
{
return self::CRAWLER_ACTION_TIMEOUTS[$action] ?? self::CRAWLER_DEFAULT_TIMEOUT;
}
protected static function markStaleCrawlerLogs(array $item, int $timeout, int $now): void
{
$staleIds = CrontabLog::where('crontab_id', $item['id'])
->where('status', 0)
->where('create_time', '<=', $now - $timeout)
->column('id');
if (empty($staleIds)) {
return;
}
$message = sprintf('执行超过 %d 秒未结束,已由调度器标记超时', $timeout);
CrontabLog::whereIn('id', $staleIds)->update([
'status' => 2,
'output' => $message,
'elapsed' => $timeout,
]);
CrontabModel::where('id', $item['id'])->update([
'error' => $message,
]);
try {
CrontabAlertService::upsertCommandException($item, $message, (int) end($staleIds));
} catch (\Exception $e) {
}
}
}
+76
View File
@@ -0,0 +1,76 @@
<?php
namespace app\common\command;
use app\common\model\ai\AiKbSyncJob;
use app\common\service\ai\KbService;
use app\common\service\ai\KbSyncService;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\console\input\Option;
class KbConsume extends Command
{
protected function configure()
{
$this->setName('kb:consume')
->setDescription('消费AI知识库同步任务')
->addOption('batch', null, Option::VALUE_OPTIONAL, '批量处理数量', 100);
}
protected function execute(Input $input, Output $output)
{
$batch = max(1, (int) $input->getOption('batch'));
KbSyncService::markLotteryBackfillJobs($batch);
KbSyncService::markMatchBackfillJobs($batch);
$jobs = AiKbSyncJob::where('status', AiKbSyncJob::STATUS_PENDING)
->where('scheduled_at', '<=', time())
->order('priority', 'asc')
->order('id', 'asc')
->limit($batch)
->select();
$success = 0;
$failed = 0;
foreach ($jobs as $job) {
$job->status = AiKbSyncJob::STATUS_PROCESSING;
$job->update_time = time();
$job->save();
try {
if ($job->action === AiKbSyncJob::ACTION_DELETE) {
KbService::deleteDocument($job->domain, $job->subtype, (int) $job->source_id);
$result = ['success' => true];
} else {
$result = KbService::upsertDocument($job->domain, $job->subtype, (int) $job->source_id);
}
if (!empty($result['success'])) {
$job->status = AiKbSyncJob::STATUS_SUCCESS;
$job->processed_at = time();
$job->error_msg = '';
$success++;
} else {
$job->status = AiKbSyncJob::STATUS_FAILED;
$job->retry_count = (int) $job->retry_count + 1;
$job->error_msg = $result['error'] ?? 'unknown';
$failed++;
}
} catch (\Throwable $e) {
$job->status = AiKbSyncJob::STATUS_FAILED;
$job->retry_count = (int) $job->retry_count + 1;
$job->error_msg = $e->getMessage();
$failed++;
}
$job->update_time = time();
$job->save();
}
$output->writeln(sprintf('[kb:consume] success=%d failed=%d jobs=%d', $success, $failed, count($jobs)));
return 0;
}
}
+97
View File
@@ -0,0 +1,97 @@
<?php
namespace app\common\command;
use app\common\service\ai\KbService;
use app\common\service\ai\KbSyncService;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\console\input\Option;
use think\facade\Db;
class KbRebuild extends Command
{
protected function configure()
{
$this->setName('kb:rebuild')
->setDescription('重建AI知识库文档')
->addOption('domain', null, Option::VALUE_OPTIONAL, 'article|post|lottery|match|all', 'all');
}
protected function execute(Input $input, Output $output)
{
$domain = (string) $input->getOption('domain');
$targets = $domain === 'all' ? ['article', 'post', 'lottery', 'match'] : [$domain];
$summary = ['success' => 0, 'failed' => 0];
foreach ($targets as $target) {
foreach ($this->yieldRows($target) as $row) {
$result = KbService::upsertDocument($row['domain'], $row['subtype'], (int) $row['source_id']);
if (!empty($result['success'])) {
$summary['success']++;
} else {
$summary['failed']++;
$output->writeln(sprintf(
'[failed] %s/%s/%d %s',
$row['domain'],
$row['subtype'],
$row['source_id'],
$result['error'] ?? 'unknown'
));
}
}
}
KbSyncService::markLotteryBackfillJobs();
$output->writeln(sprintf('[kb:rebuild] success=%d failed=%d', $summary['success'], $summary['failed']));
return 0;
}
private function yieldRows(string $domain): \Generator
{
if ($domain === 'article') {
yield from $this->yieldTableRows('article', 'article', 'article');
return;
}
if ($domain === 'post') {
yield from $this->yieldTableRows('community_post', 'post', 'post');
return;
}
if ($domain === 'lottery') {
yield from $this->yieldTableRows('lottery_draw_result', 'lottery', 'draw_result');
yield from $this->yieldTableRows('lottery_ai_analysis', 'lottery', 'ai_history');
return;
}
if ($domain === 'match') {
yield from $this->yieldTableRows('match', 'match', 'event');
}
}
private function yieldTableRows(string $table, string $domain, string $subtype): \Generator
{
$lastId = 0;
$chunkSize = 5000;
while (true) {
$ids = Db::name($table)
->where('id', '>', $lastId)
->order('id', 'asc')
->limit($chunkSize)
->column('id');
if (empty($ids)) {
break;
}
foreach ($ids as $id) {
$lastId = (int) $id;
yield [
'domain' => $domain,
'subtype' => $subtype,
'source_id' => $lastId,
];
}
}
}
}
+202
View File
@@ -0,0 +1,202 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\command;
use app\common\enum\PayEnum;
use app\common\enum\RefundEnum;
use app\common\model\recharge\RechargeOrder;
use app\common\model\refund\RefundLog;
use app\common\model\refund\RefundRecord;
use app\common\service\pay\WeChatPayService;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Log;
class QueryRefund extends Command
{
protected function configure()
{
$this->setName('query_refund')
->setDescription('订单退款状态处理');
}
protected function execute(Input $input, Output $output)
{
try {
// 查找退款中的退款记录(微信,支付宝支付)
$refundRecords = (new RefundLog())->alias('l')
->join('refund_record r', 'r.id = l.record_id')
->field([
'l.id' => 'log_id', 'l.sn' => 'log_sn',
'r.id' => 'record_id', 'r.order_id', 'r.sn' => 'record_sn', 'r.order_type'
])
->where(['l.refund_status' => RefundEnum::REFUND_ING])
->select()->toArray();
if (empty($refundRecords)) {
return false;
}
// 分别处理各个类型订单
$rechargeRecords = array_filter($refundRecords, function ($item) {
return $item['order_type'] == RefundEnum::ORDER_TYPE_RECHARGE;
});
if (!empty($rechargeRecords)) {
$this->handleRechargeOrder($rechargeRecords);
}
return true;
} catch (\Exception $e) {
Log::write('订单退款状态查询失败,失败原因:' . $e->getMessage());
return false;
}
}
/**
* @notes 处理充值订单
* @param $refundRecords
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
* @author 段誉
* @date 2023/3/1 15:55
*/
public function handleRechargeOrder($refundRecords)
{
$orderIds = array_unique(array_column($refundRecords, 'order_id'));
$Orders = RechargeOrder::whereIn('id', $orderIds)->column('*', 'id');
foreach ($refundRecords as $record) {
if (!isset($Orders[$record['order_id']])) {
continue;
}
$order = $Orders[$record['order_id']];
if (!in_array($order['pay_way'], [PayEnum::WECHAT_PAY, PayEnum::ALI_PAY])) {
continue;
}
$this->checkReFundStatus([
'record_id' => $record['record_id'],
'log_id' => $record['log_id'],
'log_sn' => $record['log_sn'],
'pay_way' => $order['pay_way'],
'order_terminal' => $order['order_terminal'],
]);
}
}
/**
* @notes 校验退款状态
* @param $refundData
* @return bool
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
* @author 段誉
* @date 2023/3/1 15:54
*/
public function checkReFundStatus($refundData)
{
$result = null;
switch ($refundData['pay_way']) {
case PayEnum::WECHAT_PAY:
$result = self::checkWechatRefund($refundData['order_terminal'], $refundData['log_sn']);
break;
}
if (is_null($result)) {
return false;
}
if (true === $result) {
$this->updateRefundSuccess($refundData['log_id'], $refundData['record_id']);
} else {
$this->updateRefundMsg($refundData['log_id'], $result);
}
return true;
}
/**
* @notes 查询微信支付退款状态
* @param $orderTerminal
* @param $refundLogSn
* @return bool|string|null
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
* @author 段誉
* @date 2023/3/1 15:47
*/
public function checkWechatRefund($orderTerminal, $refundLogSn)
{
// 根据商户退款单号查询退款
$result = (new WeChatPayService($orderTerminal))->queryRefund($refundLogSn);
if (!empty($result['status']) && $result['status'] == 'SUCCESS') {
return true;
}
if (!empty($result['code']) || !empty($result['message'])) {
return '微信:' . $result['code'] . '-' . $result['message'];
}
return null;
}
/**
* @notes 更新记录为成功
* @param $logId
* @param $recordId
* @author 段誉
* @date 2023/3/1 15:38
*/
public function updateRefundSuccess($logId, $recordId)
{
// 更新日志
RefundLog::update([
'id' => $logId,
'refund_status' => RefundEnum::REFUND_SUCCESS,
]);
// 更新记录
RefundRecord::update([
'id' => $recordId,
'refund_status' => RefundEnum::REFUND_SUCCESS,
]);
}
/**
* @notes 更新退款信息
* @param $logId
* @param $msg
* @author 段誉
* @date 2023/3/1 15:47
*/
public function updateRefundMsg($logId, $msg)
{
// 更新日志
RefundLog::update([
'id' => $logId,
'refund_msg' => $msg,
]);
}
}
@@ -0,0 +1,65 @@
<?php
namespace app\common\command;
use app\common\model\user\User;
use app\common\model\SmsLog;
use think\console\Command;
use think\console\Input;
use think\console\Output;
/**
* 短信验证定时任务
* 轮询有手机号但未验证(is_bind_mobile=0)的用户,
* 从 la_sms_upload 反向校验是否有该手机号的任意上传记录,
* 若匹配则标记 is_bind_mobile=1
*/
class SmsVerifyCommand extends Command
{
protected function configure()
{
$this->setName('sms_verify')
->setDescription('轮询未验证手机号用户,从上传记录反向校验并更新绑定状态');
}
protected function execute(Input $input, Output $output)
{
$users = User::where('mobile', '<>', '')
->where('is_bind_mobile', 0)
->field('id, mobile')
->select();
if ($users->isEmpty()) {
$output->writeln('<info>[SmsVerify] 无待验证用户</info>');
return;
}
$output->writeln('<info>[SmsVerify] 待验证用户: ' . $users->count() . '</info>');
$updated = 0;
foreach ($users as $user) {
$mobile = $user->mobile;
// 查询 la_sms_upload 是否有该手机号的任意上传记录(兼容+86前缀)
$record = SmsLog::where(function ($query) use ($mobile) {
$query->where('phone', $mobile)
->whereOr('phone', '+86' . $mobile)
->whereOr('phone', '86' . $mobile);
})
->order('sms_time', 'desc')
->findOrEmpty();
if (!$record->isEmpty()) {
if ((int)$record->status === 0) {
$record->status = 1;
$record->save();
}
User::where('id', $user->id)->update(['is_bind_mobile' => 1]);
$updated++;
$output->writeln("<info> ✓ 用户 {$user->id} ({$mobile}) 已验证</info>");
}
}
$output->writeln("<info>[SmsVerify] 完成,更新 {$updated} 个用户</info>");
}
}
@@ -0,0 +1,129 @@
<?php
namespace app\common\command;
use app\api\logic\ArticleLogic;
use app\common\enum\YesNoEnum;
use app\common\model\article\Article;
use think\console\Command;
use think\console\Input;
use think\console\Output;
class WorldcupArticleTranslate extends Command
{
protected function configure()
{
$this->setName('worldcup_article_translate')
->setDescription('预热世界杯英文资讯翻译缓存');
}
protected function execute(Input $input, Output $output)
{
$articles = Article::field('id,cid,title,desc,content,ext,is_show,delete_time')
->where('cid', 22)
->where('is_show', YesNoEnum::YES)
// 与前台世界杯资讯列表保持一致,只预热用户最先看到的 50 条。
->order('published_at', 'desc')
->order('id', 'desc')
->limit(50)
->select()
->toArray();
if (empty($articles)) {
$output->writeln('<comment>[WorldcupTranslate] 没有找到可处理的世界杯文章</comment>');
return 0;
}
$translated = 0;
$skippedExist = 0;
$skippedNonEnglish = 0;
$failed = 0;
foreach ($articles as $article) {
$ext = $this->decodeExt($article['ext'] ?? []);
if (!empty($ext['translated_content'])) {
$skippedExist++;
continue;
}
if (!$this->isProbablyEnglish($article)) {
$skippedNonEnglish++;
continue;
}
try {
$result = ArticleLogic::autoTranslateArticle($article);
if ($result !== '') {
$translated++;
$output->writeln(sprintf('[WorldcupTranslate] 已翻译文章 #%d %s', $article['id'], $article['title'] ?? ''));
} else {
$failed++;
$output->writeln(sprintf('<comment>[WorldcupTranslate] 翻译失败或无结果 #%d %s</comment>', $article['id'], $article['title'] ?? ''));
}
} catch (\Throwable $e) {
$failed++;
$output->writeln(sprintf('<error>[WorldcupTranslate] 异常 #%d %s - %s</error>', $article['id'], $article['title'] ?? '', $e->getMessage()));
}
}
$output->writeln(sprintf(
'[WorldcupTranslate] 完成,翻译 %d 条,已存在 %d 条,跳过非英文 %d 条,失败 %d 条',
$translated,
$skippedExist,
$skippedNonEnglish,
$failed
));
return 0;
}
private function isProbablyEnglish(array $article): bool
{
$text = trim(implode(' ', [
(string) ($article['title'] ?? ''),
(string) ($article['desc'] ?? ''),
$this->normalizeText((string) ($article['content'] ?? '')),
]));
if ($text === '') {
return false;
}
if (preg_match('/[\x{4e00}-\x{9fff}]/u', $text)) {
return false;
}
$letterCount = preg_match_all('/[A-Za-z]/', $text);
$wordCount = preg_match_all('/\b[A-Za-z]{2,}\b/', $text);
// 世界杯资讯里不少正文并不长,阈值过高会误杀正常英文稿件。
return $letterCount >= 30 && $wordCount >= 5;
}
private function normalizeText(string $content): string
{
if ($content === '') {
return '';
}
$content = strip_tags($content);
$content = html_entity_decode($content, ENT_QUOTES | ENT_HTML5, 'UTF-8');
$content = preg_replace('/\s+/u', ' ', $content);
return trim($content);
}
private function decodeExt($ext): array
{
if (is_array($ext)) {
return $ext;
}
if (is_string($ext) && $ext !== '') {
$data = json_decode($ext, true);
return is_array($data) ? $data : [];
}
return [];
}
}
@@ -0,0 +1,121 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace app\common\controller;
use app\BaseController;
use app\common\lists\BaseDataLists;
use app\common\service\JsonService;
use think\facade\App;
/**
* 控制器基类
* Class BaseLikeAdminController
* @package app\common\controller
*/
class BaseLikeAdminController extends BaseController
{
public array $notNeedLogin = [];
/**
* @notes 操作成功
* @param string $msg
* @param array $data
* @param int $code
* @param int $show
* @return \think\response\Json
* @author 段誉
* @date 2021/12/27 14:21
*/
protected function success(string $msg = 'success', array $data = [], int $code = 1, int $show = 0)
{
return JsonService::success($msg, $data, $code, $show);
}
/**
* @notes 数据返回
* @param $data
* @return \think\response\Json
* @author 段誉
* @date 2021/12/27 14:21\
*/
protected function data($data)
{
return JsonService::data($data);
}
/**
* @notes 列表数据返回
* @param \app\common\lists\BaseDataLists|null $lists
* @return \think\response\Json
* @author 令狐冲
* @date 2021/7/8 00:40
*/
protected function dataLists(BaseDataLists $lists = null)
{
//列表类和控制器一一对应,"app/应用/controller/控制器的方法" =》"app\应用\lists\"目录下
//(例如:"app/adminapi/controller/auth/AdminController.php的lists()方法" =》 "app/adminapi/lists/auth/AminLists.php")
//当对象为空时,自动创建列表对象
if (is_null($lists)) {
$listName = str_replace('.', '\\', App::getNamespace() . '\\lists\\' . $this->request->controller() . ucwords($this->request->action()));
$lists = invoke($listName);
}
return JsonService::dataLists($lists);
}
/**
* @notes 操作失败
* @param string $msg
* @param array $data
* @param int $code
* @param int $show
* @return \think\response\Json
* @author 段誉
* @date 2021/12/27 14:21
*/
protected function fail(string $msg = 'fail', array $data = [], int $code = 0, int $show = 1)
{
return JsonService::fail($msg, $data, $code, $show);
}
/**
* @notes 是否免登录验证
* @return bool
* @author 段誉
* @date 2021/12/27 14:21
*/
public function isNotNeedLogin(): bool
{
$notNeedLogin = $this->notNeedLogin;
if (empty($notNeedLogin)) {
return false;
}
$action = $this->request->action();
if (!in_array(trim($action), $notNeedLogin)) {
return false;
}
return true;
}
}
@@ -0,0 +1,28 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\enum;
/**
* 管理后台登录终端
* Class terminalEnum
* @package app\common\enum
*/
class AdminTerminalEnum
{
const PC = 1;
const MOBILE = 2;
}
+37
View File
@@ -0,0 +1,37 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\enum;
/**
* 定时任务枚举
* Class CrontabEnum
* @package app\common\enum
*/
class CrontabEnum
{
/**
* 类型
* CRONTAB 定时任务
*/
const CRONTAB = 1;
const DAEMON = 2;
/**
* 定时任务状态
*/
const START = 1;
const STOP = 2;
const ERROR = 3;
}
+134
View File
@@ -0,0 +1,134 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\enum;
class DefaultEnum
{
//默认排序
const SORT = 50;
//显示隐藏
const HIDE = 0;//隐藏
const SHOW = 1;//显示
//性别
const UNKNOWN = 0;//未知
const MAN = 1;//男
const WOMAN = 2;//女
//属性
const SYSTEM = 1;//系统默认
const CUSTOM = 2;//自定义
/**
* @notes 获取显示状态
* @param bool $value
* @return string|string[]
* @author ljj
* @date 2022/2/8 3:56 下午
*/
public static function getShowDesc($value = true)
{
$data = [
self::HIDE => '隐藏',
self::SHOW => '显示'
];
if ($value === true) {
return $data;
}
return $data[$value];
}
/**
* @notes 启用状态
* @param bool $value
* @return string|string[]
* @author ljj
* @date 2022/2/14 4:02 下午
*/
public static function getEnableDesc($value = true)
{
$data = [
self::HIDE => '停用',
self::SHOW => '启用'
];
if ($value === true) {
return $data;
}
return $data[$value];
}
/**
* @notes 性别
* @param bool $value
* @return string|string[]
* @author ljj
* @date 2022/2/10 11:40 上午
*/
public static function getSexDesc($value = true)
{
$data = [
self::UNKNOWN => '未知',
self::MAN => '男',
self::WOMAN => '女'
];
if ($value === true) {
return $data;
}
return $data[$value];
}
/**
* @notes 属性
* @param bool $value
* @return string|string[]
* @author ljj
* @date 2022/2/14 4:41 下午
*/
public static function getAttrDesc($value = true)
{
$data = [
self::SYSTEM => '系统默认',
self::CUSTOM => '自定义'
];
if ($value === true) {
return $data;
}
return $data[$value];
}
/**
* @notes 是否推荐
* @param bool $value
* @return string|string[]
* @author ljj
* @date 2022/2/23 3:30 下午
*/
public static function getRecommendDesc($value = true)
{
$data = [
self::HIDE => '不推荐',
self::SHOW => '推荐'
];
if ($value === true) {
return $data;
}
return $data[$value];
}
}
+14
View File
@@ -0,0 +1,14 @@
<?php
namespace app\common\enum;
class ExportEnum
{
//获取导出信息
const INFO = 1;
//导出excel
const EXPORT = 2;
}
+31
View File
@@ -0,0 +1,31 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\enum;
class FileEnum
{
// 图片类型
const IMAGE_TYPE = 10; // 图片类型
const VIDEO_TYPE = 20; // 视频类型
const FILE_TYPE = 30; // 文件类型
// 图片来源
const SOURCE_ADMIN = 0; // 后台
const SOURCE_USER = 1; // 用户
}
+63
View File
@@ -0,0 +1,63 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\enum;
class GeneratorEnum
{
// 模板类型
const TEMPLATE_TYPE_SINGLE = 0;// 单表
const TEMPLATE_TYPE_TREE = 1; // 树表
// 生成方式
const GENERATE_TYPE_ZIP = 0; // 压缩包下载
const GENERATE_TYPE_MODULE = 1; // 生成到模块
// 删除方式
const DELETE_TRUE = 0; // 真实删除
const DELETE_SOFT = 1; // 软删除
// 删除字段名 (默认名称)
const DELETE_NAME = 'delete_time';
// 菜单创建类型
const GEN_SELF = 0; // 手动添加
const GEN_AUTO = 1; // 自动添加
// 关联模型类型relations
const RELATION_HAS_ONE = 'has_one';
const RELATION_HAS_MANY = 'has_many';
/**
* @notes 获取模板类型描述
* @param bool $value
* @return string|string[]
* @author 段誉
* @date 2022/6/14 11:24
*/
public static function getTemplateTypeDesc($value = true)
{
$data = [
self::TEMPLATE_TYPE_SINGLE => '单表(增删改查)',
self::TEMPLATE_TYPE_TREE => '树表(增删改查)',
];
if ($value === true) {
return $data;
}
return $data[$value] ?? '';
}
}
+32
View File
@@ -0,0 +1,32 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\enum;
/**
* 登录枚举
* Class LoginEnum
* @package app\common\enum
*/
class LoginEnum
{
/**
* 支持的登录方式
* ACCOUNT_PASSWORD 账号/手机号密码登录
* MOBILE_CAPTCHA 手机验证码登录
* THIRD_LOGIN 第三方登录
*/
const ACCOUNT_PASSWORD = 1;
const MOBILE_CAPTCHA = 2;
const THIRD_LOGIN = 3;
}
+60
View File
@@ -0,0 +1,60 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\enum;
class MenuEnum
{
//商城页面
const SHOP_PAGE = [
[
'index' => 1,
'name' => '首页',
'path' => '/pages/index/index',
'params' => [],
'type' => 'shop',
],
];
//菜单类型
const NAVIGATION_HOME = 1;//首页导航
const NAVIGATION_PERSONAL = 2;//个人中心
//链接类型
const LINK_SHOP = 1;//商城页面
const LINK_CATEGORY = 2;//分类页面
const LINK_CUSTOM = 3;//自定义链接
/**
* @notes 链接类型
* @param bool $value
* @return string|string[]
* @author ljj
* @date 2022/2/14 12:14 下午
*/
public static function getLinkDesc($value = true)
{
$data = [
self::LINK_SHOP => '商城页面',
self::LINK_CATEGORY => '分类页面',
self::LINK_CUSTOM => '自定义链接'
];
if ($value === true) {
return $data;
}
return $data[$value];
}
}
@@ -0,0 +1,94 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\enum;
/**
* 微信公众号枚举
* Class OfficialAccountEnum
* @package app\common\enum
*/
class OfficialAccountEnum
{
/**
* 菜单类型
* click - 关键字
* view - 跳转网页链接
* miniprogram - 小程序
*/
const MENU_TYPE = ['click', 'view', 'miniprogram'];
/**
* 关注回复
*/
const REPLY_TYPE_FOLLOW = 1;
/**
* 关键字回复
*/
const REPLY_TYPE_KEYWORD = 2;
/**
* 默认回复
*/
const REPLY_TYPE_DEFAULT= 3;
/**
* 回复类型
* follow - 关注回复
* keyword - 关键字回复
* default - 默认回复
*/
const REPLY_TYPE = [
self::REPLY_TYPE_FOLLOW => 'follow',
self::REPLY_TYPE_KEYWORD => 'keyword',
self::REPLY_TYPE_DEFAULT => 'default'
];
/**
* 匹配类型 - 全匹配
*/
const MATCHING_TYPE_FULL = 1;
/**
* 匹配类型 - 模糊匹配
*/
const MATCHING_TYPE_FUZZY = 2;
/**
* 消息类型 - 事件
*/
const MSG_TYPE_EVENT = 'event';
/**
* 消息类型 - 文本
*/
const MSG_TYPE_TEXT = 'text';
/**
* 事件类型 - 关注
*/
const EVENT_SUBSCRIBE = 'subscribe';
/**
* @notes 获取类型英文名称
* @param $type
* @return string
* @author Tab
* @date 2021/7/29 16:32
*/
public static function getReplyType($type)
{
return self::REPLY_TYPE[$type] ?? '';
}
}
+112
View File
@@ -0,0 +1,112 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\enum;
/**
* 支付
* Class PayrEnum
* @package app\common\enum
*/
class PayEnum
{
//支付类型
const BALANCE_PAY = 1; //余额支付
const WECHAT_PAY = 2; //微信支付
const ALI_PAY = 3; //支付宝支付
//支付状态
const UNPAID = 0; //未支付
const ISPAID = 1; //已支付
//支付场景
const SCENE_H5 = 1;//H5
const SCENE_OA = 2;//微信公众号
const SCENE_MNP = 3;//微信小程序
const SCENE_APP = 4;//APP
const SCENE_PC = 5;//PC商城
/**
* @notes 获取支付类型
* @param bool $value
* @return string|string[]
* @author 段誉
* @date 2023/2/23 15:36
*/
public static function getPayDesc($value = true)
{
$data = [
self::BALANCE_PAY => '余额支付',
self::WECHAT_PAY => '微信支付',
self::ALI_PAY => '支付宝支付',
];
if ($value === true) {
return $data;
}
return $data[$value] ?? '';
}
/**
* @notes 支付状态
* @param bool $value
* @return string|string[]
* @author 段誉
* @date 2023/2/23 15:36
*/
public static function getPayStatusDesc($value = true)
{
$data = [
self::UNPAID => '未支付',
self::ISPAID => '已支付',
];
if ($value === true) {
return $data;
}
return $data[$value] ?? '';
}
/**
* @notes 支付场景
* @param bool $value
* @return string|string[]
* @author 段誉
* @date 2023/2/23 15:36
*/
public static function getPaySceneDesc($value = true)
{
$data = [
self::SCENE_H5 => 'H5',
self::SCENE_OA => '微信公众号',
self::SCENE_MNP => '微信小程序',
self::SCENE_APP => 'APP',
self::SCENE_PC => 'PC',
];
if ($value === true) {
return $data;
}
return $data[$value] ?? '';
}
}
+116
View File
@@ -0,0 +1,116 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\enum;
class RefundEnum
{
// 退款类型
const TYPE_ADMIN = 1; // 后台退款
// 退款状态
const REFUND_ING = 0;//退款中
const REFUND_SUCCESS = 1;//退款成功
const REFUND_ERROR = 2;//退款失败
// 退款方式
const REFUND_ONLINE = 1; // 线上退款
const REFUND_OFFLINE = 2; // 线下退款
// 退款订单类型
const ORDER_TYPE_ORDER = 'order'; // 普通订单
const ORDER_TYPE_RECHARGE = 'recharge'; // 充值订单
/**
* @notes 退款类型描述
* @param bool $value
* @return string|string[]
* @author 段誉
* @date 2022/12/1 10:40
*/
public static function getTypeDesc($value = true)
{
$data = [
self::TYPE_ADMIN => '后台退款',
];
if ($value === true) {
return $data;
}
return $data[$value];
}
/**
* @notes 退款状态
* @param bool $value
* @return string|string[]
* @author 段誉
* @date 2022/12/1 10:43
*/
public static function getStatusDesc($value = true)
{
$data = [
self::REFUND_ING => '退款中',
self::REFUND_SUCCESS => '退款成功',
self::REFUND_ERROR => '退款失败',
];
if ($value === true) {
return $data;
}
return $data[$value];
}
/**
* @notes 退款方式
* @param bool $value
* @return string|string[]
* @author 段誉
* @date 2022/12/1 10:43
*/
public static function getWayDesc($value = true)
{
$data = [
self::REFUND_ONLINE => '线上退款',
self::REFUND_OFFLINE => '线下退款',
];
if ($value === true) {
return $data;
}
return $data[$value];
}
/**
* @notes 通过支付方式获取退款方式
* @param $payWay
* @return int
* @author 段誉
* @date 2022/12/6 10:31
*/
public static function getRefundWayByPayWay($payWay)
{
if (in_array($payWay, [PayEnum::ALI_PAY, PayEnum::WECHAT_PAY])) {
return self::REFUND_ONLINE;
}
return self::REFUND_OFFLINE;
}
}
+46
View File
@@ -0,0 +1,46 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\enum;
/**
* 通过枚举类,枚举只有两个值的时候使用
* Class YesNoEnum
* @package app\common\enum
*/
class YesNoEnum
{
const YES = 1;
const NO = 0;
/**
* @notes 获取禁用状态
* @param bool $value
* @return string|string[]
* @author 令狐冲
* @date 2021/7/8 19:02
*/
public static function getDisableDesc($value = true)
{
$data = [
self::YES => '禁用',
self::NO => '正常'
];
if ($value === true) {
return $data;
}
return $data[$value];
}
}
@@ -0,0 +1,272 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\enum\notice;
/**
* 通知枚举
* Class NoticeEnum
* @package app\common\enum
*/
class NoticeEnum
{
/**
* 通知类型
*/
const SYSTEM = 1;
const SMS = 2;
const OA = 3;
const MNP = 4;
/**
* 短信验证码场景
*/
const LOGIN_CAPTCHA = 101;
const BIND_MOBILE_CAPTCHA = 102;
const CHANGE_MOBILE_CAPTCHA = 103;
const FIND_LOGIN_PASSWORD_CAPTCHA = 104;
/**
* 验证码场景
*/
const SMS_SCENE = [
self::LOGIN_CAPTCHA,
self::BIND_MOBILE_CAPTCHA,
self::CHANGE_MOBILE_CAPTCHA,
self::FIND_LOGIN_PASSWORD_CAPTCHA,
];
//通知类型
const BUSINESS_NOTIFICATION = 1;//业务通知
const VERIFICATION_CODE = 2;//验证码
/**
* @notes 通知类型
* @param bool $value
* @return string|string[]
* @author ljj
* @date 2022/2/17 2:49 下午
*/
public static function getTypeDesc($value = true)
{
$data = [
self::BUSINESS_NOTIFICATION => '业务通知',
self::VERIFICATION_CODE => '验证码'
];
if ($value === true) {
return $data;
}
return $data[$value];
}
/**
* @notes 获取场景描述
* @param $sceneId
* @param false $flag
* @return string|string[]
* @author 段誉
* @date 2022/3/29 11:33
*/
public static function getSceneDesc($sceneId, $flag = false)
{
$desc = [
self::LOGIN_CAPTCHA => '登录验证码',
self::BIND_MOBILE_CAPTCHA => '绑定手机验证码',
self::CHANGE_MOBILE_CAPTCHA => '变更手机验证码',
self::FIND_LOGIN_PASSWORD_CAPTCHA => '找回登录密码验证码',
];
if ($flag) {
return $desc;
}
return $desc[$sceneId] ?? '';
}
/**
* @notes 更具标记获取场景
* @param $tag
* @return int|string
* @author 段誉
* @date 2022/9/15 15:08
*/
public static function getSceneByTag($tag)
{
$scene = [
// 手机验证码登录
'YZMDL' => self::LOGIN_CAPTCHA,
// 绑定手机号验证码
'BDSJHM' => self::BIND_MOBILE_CAPTCHA,
// 变更手机号验证码
'BGSJHM' => self::CHANGE_MOBILE_CAPTCHA,
// 找回登录密码
'ZHDLMM' => self::FIND_LOGIN_PASSWORD_CAPTCHA,
];
return $scene[$tag] ?? '';
}
/**
* @notes 获取场景变量
* @param $sceneId
* @param false $flag
* @return array|string[]
* @author 段誉
* @date 2022/3/29 11:33
*/
public static function getVars($sceneId, $flag = false)
{
$desc = [
self::LOGIN_CAPTCHA => '验证码:code',
self::BIND_MOBILE_CAPTCHA => '验证码:code',
self::CHANGE_MOBILE_CAPTCHA => '验证码:code',
self::FIND_LOGIN_PASSWORD_CAPTCHA => '验证码:code',
];
if ($flag) {
return $desc;
}
return isset($desc[$sceneId]) ? ['可选变量 ' . $desc[$sceneId]] : [];
}
/**
* @notes 获取系统通知示例
* @param $sceneId
* @param false $flag
* @return array|string[]
* @author 段誉
* @date 2022/3/29 11:33
*/
public static function getSystemExample($sceneId, $flag = false)
{
$desc = [];
if ($flag) {
return $desc;
}
return isset($desc[$sceneId]) ? [$desc[$sceneId]] : [];
}
/**
* @notes 获取短信通知示例
* @param $sceneId
* @param false $flag
* @return array|string[]
* @author 段誉
* @date 2022/3/29 11:33
*/
public static function getSmsExample($sceneId, $flag = false)
{
$desc = [
self::LOGIN_CAPTCHA => '您正在登录,验证码${code},切勿将验证码泄露于他人,本条验证码有效期5分钟。',
self::BIND_MOBILE_CAPTCHA => '您正在绑定手机号,验证码${code},切勿将验证码泄露于他人,本条验证码有效期5分钟。',
self::CHANGE_MOBILE_CAPTCHA => '您正在变更手机号,验证码${code},切勿将验证码泄露于他人,本条验证码有效期5分钟。',
self::FIND_LOGIN_PASSWORD_CAPTCHA => '您正在找回登录密码,验证码${code},切勿将验证码泄露于他人,本条验证码有效期5分钟。',
];
if ($flag) {
return $desc;
}
return isset($desc[$sceneId]) ? ['示例:' . $desc[$sceneId]] : [];
}
/**
* @notes 获取公众号模板消息示例
* @param $sceneId
* @param false $flag
* @return array|string[]|\string[][]
* @author 段誉
* @date 2022/3/29 11:33
*/
public static function getOaExample($sceneId, $flag = false)
{
$desc = [];
if ($flag) {
return $desc;
}
return $desc[$sceneId] ?? [];
}
/**
* @notes 获取小程序订阅消息示例
* @param $sceneId
* @param false $flag
* @return array|mixed
* @author 段誉
* @date 2022/3/29 11:33
*/
public static function getMnpExample($sceneId, $flag = false)
{
$desc = [];
if ($flag) {
return $desc;
}
return $desc[$sceneId] ?? [];
}
/**
* @notes 提示
* @param $type
* @param $sceneId
* @return array|string|string[]|\string[][]
* @author 段誉
* @date 2022/3/29 11:33
*/
public static function getOperationTips($type, $sceneId)
{
// 场景变量
$vars = self::getVars($sceneId);
// 其他提示
$other = [];
// 示例
switch ($type) {
case self::SYSTEM:
$example = self::getSystemExample($sceneId);
break;
case self::SMS:
$other[] = '生效条件:1、管理后台完成短信设置。 2、第三方短信平台申请模板。';
$example = self::getSmsExample($sceneId);
break;
case self::OA:
$other[] = '配置路径:公众号后台 > 广告与服务 > 模板消息';
$other[] = '推荐行业:主营行业:IT科技/互联网|电子商务 副营行业:消费品/消费品';
$example = self::getOaExample($sceneId);
break;
case self::MNP:
$other[] = '配置路径:小程序后台 > 功能 > 订阅消息';
$example = self::getMnpExample($sceneId);
break;
}
$tips = array_merge($vars, $example, $other);
return $tips;
}
}
+53
View File
@@ -0,0 +1,53 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\enum\notice;
/**
* 短信枚举
* Class SmsEnum
* @package app\common\enum
*/
class SmsEnum
{
/**
* 发送状态
*/
const SEND_ING = 0;
const SEND_SUCCESS = 1;
const SEND_FAIL = 2;
/**
* 短信平台
*/
const ALI = 1;
const TENCENT = 2;
/**
* @notes 获取短信平台名称
* @param $value
* @return string
* @author 段誉
* @date 2022/8/5 11:10
*/
public static function getNameDesc($value)
{
$desc = [
'ALI' => '阿里云短信',
'TENCENT' => '腾讯云短信',
];
return $desc[$value] ?? '';
}
}
@@ -0,0 +1,244 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\enum\user;
/**
* 用户账户流水变动表枚举
* Class AccountLogEnum
* @package app\common\enum
*/
class AccountLogEnum
{
/**
* 变动类型命名规则:对象_动作_简洁描述
* 动作 DEC-减少 INC-增加
* 对象 UM-用户余额
*/
/**
* 变动对象
* UM 用户余额(user_money)
*/
const UM = 1;
const UP = 2; // 用户积分(user_points)
/**
* 动作
* INC 增加
* DEC 减少
*/
const INC = 1;
const DEC = 2;
/**
* 用户余额减少类型
*/
const UM_DEC_ADMIN = 100;
const UM_DEC_RECHARGE_REFUND = 101;
const UM_DEC_BUY_POINTS = 102;
const UM_DEC_BUY_VIP = 103;
/**
* 用户积分减少类型
*/
const UP_DEC_ADMIN = 300;
const UP_DEC_PURCHASE_POST = 301;
const UP_DEC_TRANSLATE_POST = 302;
/**
* 用户余额增加类型
*/
const UM_INC_ADMIN = 200;
const UM_INC_RECHARGE = 201;
/**
* 用户积分增加类型
*/
const UP_INC_ADMIN = 400;
const UP_INC_POST_SOLD = 401;
const UP_INC_BUY_POINTS = 402;
/**
* 用户余额(减少类型汇总)
*/
const UM_DEC = [
self::UM_DEC_ADMIN,
self::UM_DEC_RECHARGE_REFUND,
self::UM_DEC_BUY_POINTS,
self::UM_DEC_BUY_VIP,
];
/**
* 用户余额(增加类型汇总)
*/
const UM_INC = [
self::UM_INC_ADMIN,
self::UM_INC_RECHARGE,
];
/**
* 用户积分(减少类型汇总)
*/
const UP_DEC = [
self::UP_DEC_ADMIN,
self::UP_DEC_PURCHASE_POST,
self::UP_DEC_TRANSLATE_POST,
];
/**
* 用户积分(增加类型汇总)
*/
const UP_INC = [
self::UP_INC_ADMIN,
self::UP_INC_POST_SOLD,
self::UP_INC_BUY_POINTS,
];
/**
* @notes 动作描述
* @param $action
* @param false $flag
* @return string|string[]
* @author 段誉
* @date 2023/2/23 10:07
*/
public static function getActionDesc($action, $flag = false)
{
$desc = [
self::DEC => '减少',
self::INC => '增加',
];
if ($flag) {
return $desc;
}
return $desc[$action] ?? '';
}
/**
* @notes 变动类型描述
* @param $changeType
* @param false $flag
* @return string|string[]
* @author 段誉
* @date 2023/2/23 10:07
*/
public static function getChangeTypeDesc($changeType, $flag = false)
{
$desc = [
self::UM_DEC_ADMIN => '平台减少余额',
self::UM_INC_ADMIN => '平台增加余额',
self::UM_INC_RECHARGE => '充值增加余额',
self::UM_DEC_RECHARGE_REFUND => '充值订单退款减少余额',
self::UM_DEC_BUY_POINTS => '余额购买积分',
self::UM_DEC_BUY_VIP => '余额购买VIP',
self::UP_DEC_ADMIN => '平台减少积分',
self::UP_DEC_PURCHASE_POST => '购买帖子消费积分',
self::UP_DEC_TRANSLATE_POST => 'AI翻译帖子消费积分',
self::UP_INC_ADMIN => '平台增加积分',
self::UP_INC_POST_SOLD => '帖子被购买获得积分',
self::UP_INC_BUY_POINTS => '购买积分到账',
];
if ($flag) {
return $desc;
}
return $desc[$changeType] ?? '';
}
/**
* @notes 获取用户余额类型描述
* @return string|string[]
* @author 段誉
* @date 2023/2/23 10:08
*/
public static function getUserMoneyChangeTypeDesc()
{
$UMChangeType = self::getUserMoneyChangeType();
$changeTypeDesc = self::getChangeTypeDesc('', true);
return array_filter($changeTypeDesc, function ($key) use ($UMChangeType) {
return in_array($key, $UMChangeType);
}, ARRAY_FILTER_USE_KEY);
}
/**
* @notes 获取用户余额变动类型
* @return int[]
* @author 段誉
* @date 2023/2/23 10:08
*/
public static function getUserMoneyChangeType(): array
{
return array_merge(self::UM_DEC, self::UM_INC);
}
/**
* @notes 获取用户积分变动类型
* @return int[]
* @author 段誉
* @date 2023/2/23 10:08
*/
public static function getUserPointsChangeType(): array
{
return array_merge(self::UP_DEC, self::UP_INC);
}
/**
* @notes 获取用户积分类型描述
* @return string|string[]
* @author 段誉
* @date 2023/2/23 10:08
*/
public static function getUserPointsChangeTypeDesc()
{
$UPChangeType = self::getUserPointsChangeType();
$changeTypeDesc = self::getChangeTypeDesc('', true);
return array_filter($changeTypeDesc, function ($key) use ($UPChangeType) {
return in_array($key, $UPChangeType);
}, ARRAY_FILTER_USE_KEY);
}
/**
* @notes 获取变动对象
* @param $changeType
* @return false
* @author 段誉
* @date 2023/2/23 10:10
*/
public static function getChangeObject($changeType)
{
// 用户余额
$um = self::getUserMoneyChangeType();
if (in_array($changeType, $um)) {
return self::UM;
}
// 用户积分
$up = self::getUserPointsChangeType();
if (in_array($changeType, $up)) {
return self::UP;
}
return false;
}
}
+55
View File
@@ -0,0 +1,55 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\enum\user;
/**
* 管理后台登录终端
* Class terminalEnum
* @package app\common\enum
*/
class UserEnum
{
/**
* 性别
* SEX_OTHER = 未知
* SEX_MEN = 男
* SEX_WOMAN = 女
*/
const SEX_OTHER = 0;
const SEX_MEN = 1;
const SEX_WOMAN = 2;
/**
* @notes 性别描述
* @param bool $from
* @return string|string[]
* @author 段誉
* @date 2022/9/7 15:05
*/
public static function getSexDesc($from = true)
{
$desc = [
self::SEX_OTHER => '未知',
self::SEX_MEN => '男',
self::SEX_WOMAN => '女',
];
if (true === $from) {
return $desc;
}
return $desc[$from] ?? '';
}
}
@@ -0,0 +1,64 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\enum\user;
/**
* 管理后台登录终端
* Class terminalEnum
* @package app\common\enum
*/
class UserTerminalEnum
{
//const OTHER = 0; //其他来源
const WECHAT_MMP = 1; //微信小程序
const WECHAT_OA = 2; //微信公众号
const H5 = 3;//手机H5登录
const PC = 4;//电脑PC
const IOS = 5;//苹果app
const ANDROID = 6;//安卓app
const ALL_TERMINAL = [
self::WECHAT_MMP,
self::WECHAT_OA,
self::H5,
self::PC,
self::IOS,
self::ANDROID,
];
/**
* @notes 获取终端
* @param bool $from
* @return array|mixed|string
* @author cjhao
* @date 2021/7/30 18:09
*/
public static function getTermInalDesc($from = true)
{
$desc = [
self::WECHAT_MMP => '微信小程序',
self::WECHAT_OA => '微信公众号',
self::H5 => '手机H5',
self::PC => '电脑PC',
self::IOS => '苹果APP',
self::ANDROID => '安卓APP',
];
if(true === $from){
return $desc;
}
return $desc[$from] ?? '';
}
}
@@ -0,0 +1,40 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\exception;
use think\Exception;
/**
* 控制器继承异常
* Class ControllerExtendException
* @package app\common\exception
*/
class ControllerExtendException extends Exception
{
/**
* 构造方法
* @access public
* @param string $message
* @param string $model
* @param array $config
*/
public function __construct(string $message, string $model = '', array $config = [])
{
$this->message = '控制器需要继承模块的基础控制器:' . $message;
$this->model = $model;
}
}
@@ -0,0 +1,30 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\http\middleware;
/**
* 基础中间件
* Class LikeShopMiddleware
* @package app\common\http\middleware
*/
class BaseMiddleware
{
public function handle($request, \Closure $next)
{
return $next($request);
}
}
@@ -0,0 +1,87 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\http\middleware;
use app\common\service\JsonService;
use Closure;
/**
* 自定义跨域中间件
* Class LikeAdminAllowMiddleware
* @package app\common\http\middleware
*/
class LikeAdminAllowMiddleware
{
/**
* 允许的请求头常量
*/
private const ALLOWED_HEADERS = [
'Authorization', 'Sec-Fetch-Mode', 'DNT', 'X-Mx-ReqToken', 'Keep-Alive', 'User-Agent',
'If-Match', 'If-None-Match', 'If-Unmodified-Since', 'X-Requested-With', 'If-Modified-Since',
'Cache-Control', 'Content-Type', 'Accept-Language', 'Origin', 'Accept-Encoding', 'Access-Token',
'token', 'version'
];
/**
* @notes 跨域处理
* @param $request
* @param \Closure $next
* @param array|null $header
* @return mixed|\think\Response
* @author 令狐冲
* @date 2021/7/26 11:51
*/
public function handle($request, Closure $next, ?array $header = []): mixed
{
// 设置跨域头
$this->setCorsHeaders();
// 如果是OPTIONS请求,直接返回响应
if (strtoupper($request->method()) === 'OPTIONS') {
return response();
}
// 安装检测
$install = file_exists(root_path() . '/config/install.lock');
if (!$install) {
return JsonService::fail('程序未安装', [], -2);
}
return $next($request);
}
/**
* @notes 设置跨域头信息
* @return void
* @author JXDN
* @date 2024/09/24 16:35
*/
private function setCorsHeaders(): void
{
$headers = [
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Headers' => implode(', ', self::ALLOWED_HEADERS),
'Access-Control-Allow-Methods' => 'GET, POST, PATCH, PUT, DELETE, post',
'Access-Control-Max-Age' => '1728000',
'Access-Control-Allow-Credentials' => 'true'
];
foreach ($headers as $key => $value) {
header("$key: $value");
}
}
}
@@ -0,0 +1,43 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\listener;
use app\common\logic\NoticeLogic;
use think\facade\Log;
/**
* 通知事件监听
* Class NoticeListener
* @package app\listener
*/
class NoticeListener
{
public function handle($params)
{
try {
if (empty($params['scene_id'])) {
throw new \Exception('场景ID不能为空');
}
// 根据不同的场景发送通知
$result = NoticeLogic::noticeByScene($params);
if (false === $result) {
throw new \Exception(NoticeLogic::getError());
}
return true;
} catch (\Exception $e) {
Log::write('通知发送失败:'.$e->getMessage());
return $e->getMessage();
}
}
}
+218
View File
@@ -0,0 +1,218 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\lists;
use app\common\enum\ExportEnum;
use app\common\service\JsonService;
use app\common\validate\ListsValidate;
use app\Request;
use think\facade\Config;
/**
* 数据列表基类
* Class BaseDataLists
* @package app\common\lists
*/
abstract class BaseDataLists implements ListsInterface
{
use ListsSearchTrait;
use ListsSortTrait;
use ListsExcelTrait;
public Request $request; //请求对象
public int $pageNo; //页码
public int $pageSize; //每页数量
public int $limitOffset; //limit查询offset值
public int $limitLength; //limit查询数量
public int $pageSizeMax;
public int $pageType = 0; //默认类型:0-一般分页;1-不分页,获取最大所有数据
protected string $orderBy;
protected string $field;
protected $startTime;
protected $endTime;
protected $start;
protected $end;
protected array $params;
protected $sortOrder = [];
public string $export;
public function __construct()
{
//参数验证
(new ListsValidate())->get()->goCheck();
//请求参数设置
$this->request = request();
$this->params = $this->request->param();
//分页初始化
$this->initPage();
//搜索初始化
$this->initSearch();
//排序初始化
$this->initSort();
//导出初始化
$this->initExport();
}
/**
* @notes 分页参数初始化
* @author 令狐冲
* @date 2021/7/30 23:55
*/
private function initPage()
{
$this->pageSizeMax = Config::get('project.lists.page_size_max');
$this->pageSize = Config::get('project.lists.page_size');
$this->pageType = $this->request->get('page_type', 1);
if ($this->pageType == 1) {
//分页
$this->pageNo = $this->request->get('page_no', 1) ?: 1;
$this->pageSize = $this->request->get('page_size', $this->pageSize) ?: $this->pageSize;
} else {
//不分页
$this->pageNo = 1;//强制到第一页
$this->pageSize = $this->pageSizeMax;// 直接取最大记录数
}
//limit查询参数设置
$this->limitOffset = ($this->pageNo - 1) * $this->pageSize;
$this->limitLength = $this->pageSize;
}
/**
* @notes 初始化搜索
* @return array
* @author 令狐冲
* @date 2021/7/31 00:00
*/
private function initSearch()
{
if (!($this instanceof ListsSearchInterface)) {
return [];
}
$startTime = $this->request->get('start_time');
if ($startTime) {
$this->startTime = strtotime($startTime);
}
$endTime = $this->request->get('end_time');
if ($endTime) {
$this->endTime = strtotime($endTime);
}
$this->start = $this->request->get('start');
$this->end = $this->request->get('end');
return $this->searchWhere = $this->createWhere($this->setSearch());
}
/**
* @notes 初始化排序
* @return array|string[]
* @author 令狐冲
* @date 2021/7/31 00:03
*/
private function initSort()
{
if (!($this instanceof ListsSortInterface)) {
return [];
}
$this->field = $this->request->get('field', '');
$this->orderBy = $this->request->get('order_by', '');
return $this->sortOrder = $this->createOrder($this->setSortFields(), $this->setDefaultOrder());
}
/**
* @notes 导出初始化
* @return false|\think\response\Json
* @author 令狐冲
* @date 2021/7/31 01:15
*/
private function initExport()
{
$this->export = $this->request->get('export', '');
//不做导出操作
if ($this->export != ExportEnum::INFO && $this->export != ExportEnum::EXPORT) {
return false;
}
//导出操作,但是没有实现导出接口
if (!($this instanceof ListsExcelInterface)) {
return JsonService::throw('该列表不支持导出');
}
$this->fileName = $this->request->get('file_name', '') ?: $this->setFileName();
//不导出文件,不初始化一下参数
if ($this->export != ExportEnum::EXPORT) {
return false;
}
//导出文件名设置
$this->fileName .= '-' . date('Y-m-d-His') . '.xlsx';
//导出文件准备
//指定导出范围(例:第2页到,第5页的数据)
if ($this->pageType == 1) {
$this->pageStart = $this->request->get('page_start', $this->pageStart);
$this->pageEnd = $this->request->get('page_end', $this->pageEnd);
//改变查询数量参数(例:第2页到,第5页的数据,查询->page(2,(5-2+1)*25)
$this->limitOffset = ($this->pageStart - 1) * $this->pageSize;
$this->limitLength = ($this->pageEnd - $this->pageStart + 1) * $this->pageSize;
}
$count = $this->count();
//判断导出范围是否有数据
if ($count == 0 || ceil($count / $this->pageSize) < $this->pageStart) {
$msg = $this->pageType ? '第' . $this->pageStart . '页到第' . $this->pageEnd . '页没有数据,无法导出' : '没有数据,无法导出';
return JsonService::throw($msg);
}
}
/**
* @notes 不需要分页,可以调用此方法,无需查询第二次
* @return int
* @author 令狐冲
* @date 2021/7/6 00:34
*/
public function defaultCount(): int
{
return count($this->lists());
}
}
@@ -0,0 +1,39 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\lists;
interface ListsExcelInterface
{
/**
* @notes 设置导出字段
* @return array
* @author 令狐冲
* @date 2021/7/21 16:04
*/
public function setExcelFields(): array;
/**
* @notes 设置导出文件名
* @return string
* @author 令狐冲
* @date 2021/7/26 17:47
*/
public function setFileName():string;
}
+136
View File
@@ -0,0 +1,136 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\lists;
use app\common\cache\ExportCache;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
trait ListsExcelTrait
{
public int $pageStart = 1; //导出开始页码
public int $pageEnd = 200; //导出介绍页码
public string $fileName = ''; //文件名称
/**
* @notes 创建excel
* @param $excelFields
* @param $lists
* @return string
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
* @author 令狐冲
* @date 2021/7/21 16:04
*/
public function createExcel($excelFields, $lists)
{
$title = array_values($excelFields);
$data = [];
foreach ($lists as $row) {
$temp = [];
foreach ($excelFields as $key => $excelField) {
$fieldData = $row[$key];
if (is_numeric($fieldData) && strlen($fieldData) >= 12) {
$fieldData .= "\t";
}
$temp[$key] = $fieldData;
}
$data[] = $temp;
}
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
//设置单元格内容
foreach ($title as $key => $value) {
// 单元格内容写入
$sheet->setCellValueByColumnAndRow($key + 1, 1, $value);
}
$row = 2; //从第二行开始
foreach ($data as $item) {
$column = 1;
foreach ($item as $value) {
//单元格内容写入
$sheet->setCellValueByColumnAndRow($column, $row, $value);
$column++;
}
$row++;
}
$getHighestRowAndColumn = $sheet->getHighestRowAndColumn();
$HighestRow = $getHighestRowAndColumn['row'];
$column = $getHighestRowAndColumn['column'];
$titleScope = 'A1:' . $column . '1';//第一(标题)范围(例:A1:D1)
$sheet->getStyle($titleScope)
->getFill()
->setFillType(Fill::FILL_SOLID) // 设置填充样式
->getStartColor()
->setARGB('00B0F0');
// 设置文字颜色为白色
$sheet->getStyle($titleScope)->getFont()->getColor()
->setARGB('FFFFFF');
// $sheet->getStyle('B2')->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_DATE_YYYYMMDD);
$spreadsheet->getActiveSheet()->getColumnDimension('B')->setAutoSize(true);
$allCope = 'A1:' . $column . $HighestRow;//整个表格范围(例:A1:D5
$sheet->getStyle($allCope)->getBorders()->getAllBorders()->setBorderStyle(Border::BORDER_THIN);
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
//创建excel文件
$exportCache = new ExportCache();
$src = $exportCache->getSrc();
if (!file_exists($src)) {
mkdir($src, 0775, true);
}
$writer->save($src . $this->fileName);
//设置本地excel缓存并返回下载地址
$vars = ['file' => $exportCache->setFile($this->fileName)];
return (string)(url('adminapi/download/export', $vars, true, true));
}
/**
* @notes 获取导出信息
* @return array
* @author 令狐冲
* @date 2021/7/29 16:08
*/
public function excelInfo()
{
$count = $this->count();
$sum_page = max(ceil($count / $this->pageSize), 1);
return [
'count' => $count, //所有数据记录数
'page_size' => $this->pageSize,//每页记录数
'sum_page' => $sum_page,//一共多少页
'max_page' => floor($this->pageSizeMax / $this->pageSize),//最多导出多少页
'all_max_size' => $this->pageSizeMax,//最多导出记录数
'page_start' => $this->pageStart,//导出范围页码开始值
'page_end' => min($sum_page, $this->pageEnd),//导出范围页码结束值
'file_name' => $this->fileName,//默认文件名
];
}
}
@@ -0,0 +1,30 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\lists;
interface ListsExtendInterface
{
/**
* @notes 扩展字段
* @return mixed
* @author 令狐冲
* @date 2021/7/21 17:45
*/
public function extend();
}
@@ -0,0 +1,37 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\lists;
interface ListsInterface
{
/**
* @notes 实现数据列表
* @return array
* @author 令狐冲
* @date 2021/7/6 00:33
*/
public function lists(): array;
/**
* @notes 实现数据列表记录数
* @return int
* @author 令狐冲
* @date 2021/7/6 00:34
*/
public function count(): int;
}
@@ -0,0 +1,29 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\lists;
interface ListsSearchInterface
{
/**
* @notes 设置搜索条件
* @return array
* @author 令狐冲
* @date 2021/7/7 19:44
*/
public function setSearch(): array;
}
@@ -0,0 +1,108 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\lists;
trait ListsSearchTrait
{
protected array $params;
protected $searchWhere = [];
/**
* @notes 搜索条件生成
* @param $search
* @return array
* @author 令狐冲
* @date 2021/7/7 19:36
*/
private function createWhere($search)
{
if (empty($search)) {
return [];
}
$where = [];
foreach ($search as $whereType => $whereFields) {
switch ($whereType) {
case '=':
case '<>':
case '>':
case '>=':
case '<':
case '<=':
case 'in':
foreach ($whereFields as $whereField) {
$paramsName = substr_symbol_behind($whereField);
if (!isset($this->params[$paramsName]) || $this->params[$paramsName] == '') {
continue;
}
$where[] = [$whereField, $whereType, $this->params[$paramsName]];
}
break;
case '%like%':
foreach ($whereFields as $whereField) {
$paramsName = substr_symbol_behind($whereField);
if (!isset($this->params[$paramsName]) || empty($this->params[$paramsName])) {
continue;
}
$where[] = [$whereField, 'like', '%' . $this->params[$paramsName] . '%'];
}
break;
case '%like':
foreach ($whereFields as $whereField) {
$paramsName = substr_symbol_behind($whereField);
if (!isset($this->params[$paramsName]) || empty($this->params[$paramsName])) {
continue;
}
$where[] = [$whereField, 'like', '%' . $this->params[$paramsName]];
}
break;
case 'like%':
foreach ($whereFields as $whereField) {
$paramsName = substr_symbol_behind($whereField);
if (!isset($this->params[$paramsName]) || empty($this->params[$paramsName])) {
continue;
}
$where[] = [$whereField, 'like', $this->params[$paramsName] . '%'];
}
break;
case 'between_time':
if (!is_numeric($this->startTime) || !is_numeric($this->endTime)) {
break;
}
$where[] = [$whereFields, 'between', [$this->startTime, $this->endTime]];
break;
case 'between':
if (empty($this->start) || empty($this->end)) {
break;
}
$where[] = [$whereFields, 'between', [$this->start, $this->end]];
break;
case 'find_in_set': // find_in_set查询
foreach ($whereFields as $whereField) {
$paramsName = substr_symbol_behind($whereField);
if (!isset($this->params[$paramsName]) || $this->params[$paramsName] == '') {
continue;
}
$where[] = [$whereField, 'find in set', $this->params[$paramsName]];
}
break;
}
}
return $where;
}
}
@@ -0,0 +1,38 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\lists;
interface ListsSortInterface
{
/**
* @notes 设置支持排序字段
* @return array
* @author 令狐冲
* @date 2021/7/7 19:44
*/
public function setSortFields(): array;
/**
* @notes 设置默认排序条件
* @return array
* @author 令狐冲
* @date 2021/7/16 00:01
*/
public function setDefaultOrder():array;
}
@@ -0,0 +1,53 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\lists;
trait ListsSortTrait
{
protected string $orderBy;
protected string $field;
/**
* @notes 生成排序条件
* @param $sortField
* @param $defaultOrder
* @return array|string[]
* @author 令狐冲
* @date 2021/7/16 00:06
*/
private function createOrder($sortField, $defaultOrder)
{
if (empty($sortField) || empty($this->orderBy) || empty($this->field) || !in_array($this->field, array_keys($sortField))) {
return $defaultOrder;
}
if (isset($sortField[$this->field])) {
$field = $sortField[$this->field];
} else {
return $defaultOrder;
}
if ($this->orderBy == 'desc') {
return [$field => 'desc'];
}
if ($this->orderBy == 'asc') {
return [$field => 'asc'];
}
return $defaultOrder;
}
}
@@ -0,0 +1,80 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\logic;
use app\common\enum\user\AccountLogEnum;
use app\common\model\user\UserAccountLog;
use app\common\model\user\User;
/**
* 账户流水记录逻辑层
* Class AccountLogLogic
* @package app\common\logic
*/
class AccountLogLogic extends BaseLogic
{
/**
* @notes 账户流水记录
* @param $userId
* @param $changeType
* @param $action
* @param $changeAmount
* @param string $sourceSn
* @param string $remark
* @param array $extra
* @return UserAccountLog|false|\think\Model
* @author 段誉
* @date 2023/2/23 12:03
*/
public static function add($userId, $changeType, $action, $changeAmount, string $sourceSn = '', string $remark = '', array $extra = [], int $relationId = 0)
{
$user = User::findOrEmpty($userId);
if ($user->isEmpty()) {
return false;
}
$changeObject = AccountLogEnum::getChangeObject($changeType);
if (!$changeObject) {
return false;
}
switch ($changeObject) {
// 用户余额
case AccountLogEnum::UM:
$left_amount = $user->user_money;
break;
// 用户积分
case AccountLogEnum::UP:
$left_amount = $user->user_points;
break;
}
$data = [
'sn' => generate_sn(UserAccountLog::class, 'sn', 20),
'user_id' => $userId,
'change_object' => $changeObject,
'change_type' => $changeType,
'action' => $action,
'left_amount' => $left_amount,
'change_amount' => $changeAmount,
'source_sn' => $sourceSn,
'remark' => $remark,
'extra' => $extra ? json_encode($extra, JSON_UNESCAPED_UNICODE) : '',
'relation_id' => $relationId,
];
return UserAccountLog::create($data);
}
}
+114
View File
@@ -0,0 +1,114 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\logic;
/**
* 逻辑基类
* Class BaseLogic
* @package app\common\logic
*/
class BaseLogic
{
/**
* 错误信息
* @var string
*/
protected static $error;
/**
* 返回状态码
* @var int
*/
protected static $returnCode = 0;
protected static $returnData;
/**
* @notes 获取错误信息
* @return string
* @author 段誉
* @date 2021/7/21 18:23
*/
public static function getError() : string
{
if (false === self::hasError()) {
return '系统错误';
}
return self::$error;
}
/**
* @notes 设置错误信息
* @param $error
* @author 段誉
* @date 2021/7/21 18:20
*/
public static function setError($error) : void
{
!empty($error) && self::$error = $error;
}
/**
* @notes 是否存在错误
* @return bool
* @author 段誉
* @date 2021/7/21 18:32
*/
public static function hasError() : bool
{
return !empty(self::$error);
}
/**
* @notes 设置状态码
* @param $code
* @author 段誉
* @date 2021/7/28 17:05
*/
public static function setReturnCode($code) : void
{
self::$returnCode = $code;
}
/**
* @notes 特殊场景返回指定状态码,默认为0
* @return int
* @author 段誉
* @date 2021/7/28 15:14
*/
public static function getReturnCode() : int
{
return self::$returnCode;
}
/**
* @notes 获取内容
* @return mixed
* @author cjhao
* @date 2021/9/11 17:29
*/
public static function getReturnData()
{
return self::$returnData;
}
}
+184
View File
@@ -0,0 +1,184 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\logic;
use app\common\enum\notice\NoticeEnum;
use app\common\enum\YesNoEnum;
use app\common\model\notice\NoticeRecord;
use app\common\model\notice\NoticeSetting;
use app\common\model\user\User;
use app\common\service\sms\SmsMessageService;
/**
* 通知逻辑层
* Class NoticeLogic
* @package app\common\logic
*/
class NoticeLogic extends BaseLogic
{
/**
* @notes 根据场景发送短信
* @param $params
* @return bool
* @author 段誉
* @date 2022/9/15 15:28
*/
public static function noticeByScene($params)
{
try {
$noticeSetting = NoticeSetting::where('scene_id', $params['scene_id'])->findOrEmpty()->toArray();
if (empty($noticeSetting)) {
throw new \Exception('找不到对应场景的配置');
}
// 合并额外参数
$params = self::mergeParams($params);
$res = false;
self::setError('发送通知失败');
// 短信通知
if (isset($noticeSetting['sms_notice']['status']) && $noticeSetting['sms_notice']['status'] == YesNoEnum::YES) {
$res = (new SmsMessageService())->send($params);
}
return $res;
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* @notes 整理参数
* @param $params
* @return array
* @author 段誉
* @date 2022/9/15 15:28
*/
public static function mergeParams($params)
{
// 用户相关
if (!empty($params['params']['user_id'])) {
$user = User::findOrEmpty($params['params']['user_id'])->toArray();
$params['params']['nickname'] = $user['nickname'];
$params['params']['user_name'] = $user['nickname'];
$params['params']['user_sn'] = $user['sn'];
$params['params']['mobile'] = $params['params']['mobile'] ?? $user['mobile'];
}
// 跳转路径
$jumpPath = self::getPathByScene($params['scene_id'], $params['params']['order_id'] ?? 0);
$params['url'] = $jumpPath['url'];
$params['page'] = $jumpPath['page'];
return $params;
}
/**
* @notes 根据场景获取跳转链接
* @param $sceneId
* @param $extraId
* @return string[]
* @author 段誉
* @date 2022/9/15 15:29
*/
public static function getPathByScene($sceneId, $extraId)
{
// 小程序主页路径
$page = '/pages/index/index';
// 公众号主页路径
$url = '/mobile/pages/index/index';
return [
'url' => $url,
'page' => $page,
];
}
/**
* @notes 替换消息内容中的变量占位符
* @param $content
* @param $params
* @return array|mixed|string|string[]
* @author 段誉
* @date 2022/9/15 15:29
*/
public static function contentFormat($content, $params)
{
foreach ($params['params'] as $k => $v) {
$search = '{' . $k . '}';
$content = str_replace($search, $v, $content);
}
return $content;
}
/**
* @notes 添加通知记录
* @param $params
* @param $noticeSetting
* @param $sendType
* @param $content
* @param string $extra
* @return NoticeRecord|\think\Model
* @author 段誉
* @date 2022/9/15 15:29
*/
public static function addNotice($params, $noticeSetting, $sendType, $content, $extra = '')
{
return NoticeRecord::create([
'user_id' => $params['params']['user_id'] ?? 0,
'title' => self::getTitleByScene($sendType, $noticeSetting),
'content' => $content,
'scene_id' => $noticeSetting['scene_id'],
'read' => YesNoEnum::NO,
'recipient' => $noticeSetting['recipient'],
'send_type' => $sendType,
'notice_type' => $noticeSetting['type'],
'extra' => $extra,
]);
}
/**
* @notes 通知记录标题
* @param $sendType
* @param $noticeSetting
* @return string
* @author 段誉
* @date 2022/9/15 15:30
*/
public static function getTitleByScene($sendType, $noticeSetting)
{
switch ($sendType) {
case NoticeEnum::SMS:
$title = '';
break;
case NoticeEnum::OA:
$title = $noticeSetting['oa_notice']['name'] ?? '';
break;
case NoticeEnum::MNP:
$title = $noticeSetting['mnp_notice']['name'] ?? '';
break;
default:
$title = '';
}
return $title;
}
}
+144
View File
@@ -0,0 +1,144 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\logic;
use app\common\enum\PayEnum;
use app\common\enum\user\AccountLogEnum;
use app\common\model\points\PointsOrder;
use app\common\model\recharge\RechargeOrder;
use app\common\model\user\User;
use app\common\model\vip\VipLevel;
use app\common\model\vip\VipOrder;
use think\facade\Db;
use think\facade\Log;
/**
* 支付成功后处理订单状态
* Class PayNotifyLogic
* @package app\api\logic
*/
class PayNotifyLogic extends BaseLogic
{
public static function handle($action, $orderSn, $extra = [])
{
Db::startTrans();
try {
self::$action($orderSn, $extra);
Db::commit();
return true;
} catch (\Exception $e) {
Db::rollback();
Log::write(implode('-', [
__CLASS__,
__FUNCTION__,
$e->getFile(),
$e->getLine(),
$e->getMessage()
]));
self::setError($e->getMessage());
return $e->getMessage();
}
}
/**
* @notes 充值回调
* @param $orderSn
* @param array $extra
* @author 段誉
* @date 2023/2/27 15:28
*/
public static function recharge($orderSn, array $extra = [])
{
$order = RechargeOrder::where('sn', $orderSn)->findOrEmpty();
// 增加用户累计充值金额及用户余额
$user = User::findOrEmpty($order->user_id);
$user->total_recharge_amount += $order->order_amount;
$user->user_money += $order->order_amount;
$user->save();
// 记录账户流水
AccountLogLogic::add(
$order->user_id,
AccountLogEnum::UM_INC_RECHARGE,
AccountLogEnum::INC,
$order->order_amount,
$order->sn,
'用户充值'
);
// 更新充值订单状态
$order->transaction_id = $extra['transaction_id'] ?? '';
$order->pay_status = PayEnum::ISPAID;
$order->pay_time = time();
$order->save();
}
public static function points_order($orderSn, array $extra = [])
{
$order = PointsOrder::where('sn', $orderSn)->findOrEmpty();
$user = User::findOrEmpty($order->user_id);
$user->user_points = ($user->user_points ?? 0) + $order->points;
$user->save();
$logExtra = [
'product_id' => $order->product_id ?? 0,
'product_name' => $order->product_name ?? '',
'points' => $order->points ?? 0,
'order_amount' => $order->order_amount ?? 0,
];
AccountLogLogic::add(
$order->user_id,
AccountLogEnum::UP_INC_BUY_POINTS,
AccountLogEnum::INC,
$order->points,
$order->sn,
'购买积分到账',
$logExtra
);
$order->transaction_id = $extra['transaction_id'] ?? '';
$order->pay_status = PayEnum::ISPAID;
$order->pay_time = time();
$order->save();
}
public static function vip_order($orderSn, array $extra = [])
{
$order = VipOrder::where('sn', $orderSn)->findOrEmpty();
if ($order->isEmpty() || $order->pay_status == PayEnum::ISPAID) {
return;
}
$user = User::findOrEmpty($order->user_id);
$vipLevel = VipLevel::where('id', $order->level_id)->findOrEmpty();
$level = $vipLevel->isEmpty() ? 0 : (int) $vipLevel->level;
$now = time();
$currentExpire = ($user->is_vip == 1 && $user->vip_expire_time > $now) ? $user->vip_expire_time : $now;
$user->is_vip = 1;
$user->vip_level = $level;
$user->vip_expire_time = $currentExpire + ($order->duration * 86400);
$user->save();
$order->transaction_id = $extra['transaction_id'] ?? '';
$order->pay_status = PayEnum::ISPAID;
$order->pay_time = time();
$order->save();
}
}
+345
View File
@@ -0,0 +1,345 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\logic;
use app\common\enum\PayEnum;
use app\common\enum\user\AccountLogEnum;
use app\common\enum\YesNoEnum;
use app\common\model\pay\PayWay;
use app\common\model\points\PointsOrder;
use app\common\model\recharge\RechargeOrder;
use app\common\model\vip\VipOrder;
use app\common\model\user\User;
use app\common\service\pay\AliPayService;
use app\common\service\pay\WeChatPayService;
/**
* 支付逻辑
* Class PaymentLogic
* @package app\common\logic
*/
class PaymentLogic extends BaseLogic
{
/**
* @notes 支付方式
* @param $userId
* @param $terminal
* @param $params
* @return array|false
* @author 段誉
* @date 2023/2/24 17:53
*/
public static function getPayWay($userId, $terminal, $params)
{
try {
if ($params['from'] == 'recharge') {
// 充值
$order = RechargeOrder::findOrEmpty($params['order_id'])->toArray();
}
if ($params['from'] == 'points_order') {
$model = PointsOrder::findOrEmpty($params['order_id']);
if (!$model->isEmpty()) {
$order = $model->toArray();
}
}
if ($params['from'] == 'vip_order') {
$model = VipOrder::findOrEmpty($params['order_id']);
if (!$model->isEmpty()) {
$order = $model->toArray();
}
}
if (empty($order)) {
throw new \Exception('待支付订单不存在, from=' . ($params['from'] ?? '') . ', order_id=' . ($params['order_id'] ?? ''));
}
//获取支付场景
$pay_way = PayWay::alias('pw')
->join('dev_pay_config dp', 'pw.pay_config_id = dp.id')
->where(['pw.scene' => $terminal, 'pw.status' => YesNoEnum::YES])
->field('dp.id,dp.name,dp.pay_way,dp.icon,dp.sort,dp.remark,pw.is_default')
->order('pw.is_default desc,dp.sort desc,id asc')
->select()
->toArray();
foreach ($pay_way as $k => &$item) {
if ($item['pay_way'] == PayEnum::WECHAT_PAY) {
$item['extra'] = '微信快捷支付';
}
if ($item['pay_way'] == PayEnum::ALI_PAY) {
$item['extra'] = '支付宝快捷支付';
}
if ($item['pay_way'] == PayEnum::BALANCE_PAY) {
$user_money = User::where(['id' => $userId])->value('user_money');
$item['extra'] = '可用余额:' . $user_money;
}
// 充值时去除余额支付
if (in_array($params['from'], ['recharge']) && $item['pay_way'] == PayEnum::BALANCE_PAY) {
unset($pay_way[$k]);
}
}
return [
'lists' => array_values($pay_way),
'order_amount' => $order['order_amount'],
];
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* @notes 获取支付状态
* @param $params
* @return array|false
* @author 段誉
* @date 2023/3/1 16:23
*/
public static function getPayStatus($params)
{
try {
$order = [];
$orderInfo = [];
switch ($params['from']) {
case 'recharge':
$order = RechargeOrder::where(['user_id' => $params['user_id'], 'id' => $params['order_id']])
->findOrEmpty();
$payTime = empty($order['pay_time']) ? '' : date('Y-m-d H:i:s', $order['pay_time']);
$orderInfo = [
'order_id' => $order['id'],
'order_sn' => $order['sn'],
'order_amount' => $order['order_amount'],
'pay_way' => PayEnum::getPayDesc($order['pay_way']),
'pay_status' => PayEnum::getPayStatusDesc($order['pay_status']),
'pay_time' => $payTime,
];
break;
case 'points_order':
$order = PointsOrder::where(['user_id' => $params['user_id'], 'id' => $params['order_id']])
->findOrEmpty();
$payTime = empty($order['pay_time']) ? '' : date('Y-m-d H:i:s', $order['pay_time']);
$orderInfo = [
'order_id' => $order['id'],
'order_sn' => $order['sn'],
'order_amount' => $order['order_amount'],
'pay_way' => PayEnum::getPayDesc($order['pay_way']),
'pay_status' => PayEnum::getPayStatusDesc($order['pay_status']),
'pay_time' => $payTime,
];
break;
case 'vip_order':
$order = VipOrder::where(['user_id' => $params['user_id'], 'id' => $params['order_id']])
->findOrEmpty();
$payTime = empty($order['pay_time']) ? '' : date('Y-m-d H:i:s', $order['pay_time']);
$orderInfo = [
'order_id' => $order['id'],
'order_sn' => $order['sn'],
'order_amount' => $order['order_amount'],
'pay_way' => PayEnum::getPayDesc($order['pay_way']),
'pay_status' => PayEnum::getPayStatusDesc($order['pay_status']),
'pay_time' => $payTime,
];
break;
}
if (empty($order)) {
throw new \Exception('订单不存在');
}
return [
'pay_status' => $order['pay_status'],
'pay_way' => $order['pay_way'],
'order' => $orderInfo
];
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* @notes 获取预支付订单信息
* @param $params
* @return RechargeOrder|array|false|\think\Model
* @author 段誉
* @date 2023/2/27 15:19
*/
public static function getPayOrderInfo($params)
{
try {
switch ($params['from']) {
case 'recharge':
$order = RechargeOrder::findOrEmpty($params['order_id']);
if ($order->isEmpty()) {
throw new \Exception('充值订单不存在');
}
break;
case 'points_order':
$order = PointsOrder::findOrEmpty($params['order_id']);
if ($order->isEmpty()) {
throw new \Exception('积分订单不存在');
}
break;
case 'vip_order':
$order = VipOrder::findOrEmpty($params['order_id']);
if ($order->isEmpty()) {
throw new \Exception('VIP订单不存在');
}
break;
}
if ($order['pay_status'] == PayEnum::ISPAID) {
throw new \Exception('订单已支付');
}
return $order;
} catch (\Exception $e) {
self::$error = $e->getMessage();
return false;
}
}
/**
* @notes 支付
* @param $payWay
* @param $from
* @param $order
* @param $terminal
* @param $redirectUrl
* @return array|false|mixed|string|string[]
* @throws \Exception
* @author mjf
* @date 2024/3/18 16:49
*/
public static function pay($payWay, $from, $order, $terminal, $redirectUrl)
{
// 支付编号-仅为微信支付预置(同一商户号下不同客户端支付需使用唯一订单号)
$paySn = $order['sn'];
if ($payWay == PayEnum::WECHAT_PAY) {
$paySn = self::formatOrderSn($order['sn'], $terminal);
}
//更新支付方式
switch ($from) {
case 'recharge':
RechargeOrder::update(['pay_way' => $payWay, 'pay_sn' => $paySn], ['id' => $order['id']]);
break;
case 'points_order':
PointsOrder::update(['pay_way' => $payWay, 'pay_sn' => $paySn], ['id' => $order['id']]);
break;
case 'vip_order':
VipOrder::update(['pay_way' => $payWay, 'pay_sn' => $paySn], ['id' => $order['id']]);
break;
}
if ($order['order_amount'] == 0) {
PayNotifyLogic::handle($from, $order['sn']);
return ['pay_way' => PayEnum::BALANCE_PAY];
}
$payService = null;
switch ($payWay) {
case PayEnum::BALANCE_PAY:
$user = User::find($order['user_id']);
if ($user->user_money < $order['order_amount']) {
self::$error = '余额不足';
$result = false;
break;
}
$user->user_money -= $order['order_amount'];
$user->save();
if ($from == 'vip_order') {
$logExtra = [
'level_id' => $order['level_id'] ?? 0,
'level_name' => $order['level_name'] ?? '',
'duration' => $order['duration'] ?? 0,
'order_amount' => $order['order_amount'],
];
AccountLogLogic::add(
$order['user_id'],
AccountLogEnum::UM_DEC_BUY_VIP,
AccountLogEnum::DEC,
$order['order_amount'],
$order['sn'],
'余额支付购买VIP',
$logExtra
);
} else {
$extra = [
'product_id' => $order['product_id'] ?? 0,
'product_name' => $order['product_name'] ?? '',
'points' => $order['points'] ?? 0,
'order_amount' => $order['order_amount'],
];
AccountLogLogic::add(
$order['user_id'],
AccountLogEnum::UM_DEC_BUY_POINTS,
AccountLogEnum::DEC,
$order['order_amount'],
$order['sn'],
'余额支付购买积分',
$extra
);
}
PayNotifyLogic::handle($from, $order['sn']);
$result = ['pay_way' => PayEnum::BALANCE_PAY];
break;
case PayEnum::WECHAT_PAY:
$payService = (new WeChatPayService($terminal, $order['user_id'] ?? null));
$order['pay_sn'] = $paySn;
$order['redirect_url'] = $redirectUrl;
$result = $payService->pay($from, $order);
break;
case PayEnum::ALI_PAY:
$payService = (new AliPayService($terminal));
$order['redirect_url'] = $redirectUrl;
$result = $payService->pay($from, $order);
break;
default:
self::$error = '订单异常';
$result = false;
}
if (false === $result && !self::hasError()) {
self::setError($payService->getError());
}
return $result;
}
/**
* @notes 设置订单号 支付回调时截取前面的单号 18个
* @param $orderSn
* @param $terminal
* @return string
* @author 段誉
* @date 2023/3/1 16:31
* @remark 回调时使用了不同的回调地址,导致跨客户端支付时(例如小程序,公众号)可能出现201,商户订单号重复错误
*/
public static function formatOrderSn($orderSn, $terminal)
{
$suffix = mb_substr(time(), -4);
return $orderSn . $terminal . $suffix;
}
}
+209
View File
@@ -0,0 +1,209 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\logic;
use app\common\enum\PayEnum;
use app\common\enum\RefundEnum;
use app\common\model\recharge\RechargeOrder;
use app\common\model\refund\RefundLog;
use app\common\model\refund\RefundRecord;
use app\common\service\pay\AliPayService;
use app\common\service\pay\WeChatPayService;
/**
* 订单退款逻辑
* Class OrderRefundLogic
* @package app\common\logic
*/
class RefundLogic extends BaseLogic
{
protected static $refundLog;
/**
* @notes 发起退款
* @param $order
* @param $refundRecordId
* @param $refundAmount
* @param $handleId
* @return bool
* @throws \Exception
* @author 段誉
* @date 2023/2/28 17:24
*/
public static function refund($order, $refundRecordId, $refundAmount, $handleId)
{
// 退款前校验
self::refundBeforeCheck($refundAmount);
// 添加退款日志
self::log($order, $refundRecordId, $refundAmount, $handleId);
// 根据不同支付方式退款
try {
switch ($order['pay_way']) {
//微信退款
case PayEnum::WECHAT_PAY:
self::wechatPayRefund($order, $refundAmount);
break;
// 支付宝退款
case PayEnum::ALI_PAY:
self::aliPayRefund($refundRecordId, $refundAmount);
break;
default:
throw new \Exception('支付方式异常');
}
// 此处true并不表示退款成功,仅表示退款请求成功,具体成功与否由定时任务查询或通过退款回调得知
return true;
} catch (\Exception $e) {
// 退款请求失败,标记退款记录及日志为失败.在退款记录处重新退款
self::$error = $e->getMessage();
self::refundFailHandle($refundRecordId, $e->getMessage());
return false;
}
}
/**
* @notes 退款前校验
* @param $refundAmount
* @throws \Exception
* @author 段誉
* @date 2023/2/28 16:27
*/
public static function refundBeforeCheck($refundAmount)
{
if ($refundAmount <= 0) {
throw new \Exception('订单金额异常');
}
}
/**
* @notes 微信支付退款
* @param $order
* @param $refundAmount
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
* @author 段誉
* @date 2023/2/28 17:19
*/
public static function wechatPayRefund($order, $refundAmount)
{
// 发起退款。 若发起退款请求返回明确错误,退款日志和记录标记状态为退款失败
// 退款日志及记录的成功状态目前统一由定时任务查询退款结果为退款成功后才标记成功
// 也可通过设置退款回调,在退款回调时处理退款记录状态为成功
(new WeChatPayService($order['order_terminal']))->refund([
'transaction_id' => $order['transaction_id'],
'refund_sn' => self::$refundLog['sn'],
'refund_amount' => $refundAmount,// 退款金额
'total_amount' => $order['order_amount'],// 订单金额
]);
}
/**
* @notes 支付宝退款
* @param $refundRecordId
* @param $refundAmount
* @throws \Exception
* @author mjf
* @date 2024/3/18 18:54
*/
public static function aliPayRefund($refundRecordId, $refundAmount)
{
$refundRecord = RefundRecord::where('id', $refundRecordId)->findOrEmpty()->toArray();
$result = (new AliPayService())->refund($refundRecord['order_sn'], $refundAmount, self::$refundLog['sn']);
$result = (array)$result;
if ($result['code'] == '10000' && $result['msg'] == 'Success' && $result['fundChange'] == 'Y') {
// 更新日志
RefundLog::update([
'refund_status' => RefundEnum::REFUND_SUCCESS,
'refund_msg' => json_encode($result, JSON_UNESCAPED_UNICODE),
], ['id'=>self::$refundLog['id']]);
// 更新记录
RefundRecord::update([
'refund_status' => RefundEnum::REFUND_SUCCESS,
], ['id'=>$refundRecordId]);
// 更新订单信息
if ($refundRecord['order_type'] == 'recharge') {
RechargeOrder::update([
'id' => $refundRecord['order_id'],
'refund_transaction_id' => $result['tradeNo'] ?? '',
]);
}
}
}
/**
* @notes 退款请求失败处理
* @param $refundRecordId
* @author 段誉
* @date 2023/2/28 16:00
* @remark 【微信,支付宝】退款接口请求失败时,更新退款记录及日志为失败,在退款记录重新发起
*/
public static function refundFailHandle($refundRecordId, $msg)
{
// 更新退款日志记录
RefundLog::update([
'id' => self::$refundLog['id'],
'refund_status' => RefundEnum::REFUND_ERROR,
'refund_msg' => $msg,
]);
// 更新退款记录状态为退款失败
RefundRecord::update([
'id' => $refundRecordId,
'refund_status' => RefundEnum::REFUND_ERROR,
'refund_msg' => $msg,
]);
}
/**
* @notes 退款日志
* @param $order
* @param $refundRecordId
* @param $refundAmount
* @param $handleId
* @param int $refundStatus
* @author 段誉
* @date 2023/2/28 15:29
*/
public static function log($order, $refundRecordId, $refundAmount, $handleId, $refundStatus = RefundEnum::REFUND_ING)
{
$sn = generate_sn(RefundLog::class, 'sn');
self::$refundLog = RefundLog::create([
'sn' => $sn,
'record_id' => $refundRecordId,
'user_id' => $order['user_id'],
'handle_id' => $handleId,
'order_amount' => $order['order_amount'],
'refund_amount' => $refundAmount,
'refund_status' => $refundStatus
]);
}
}
+50
View File
@@ -0,0 +1,50 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model;
use app\common\service\FileService;
use think\Model;
/**
* 基础模型
* Class BaseModel
* @package app\common\model
*/
class BaseModel extends Model
{
/**
* @notes 公共处理图片,补全路径
* @param $value
* @return string
* @author 张无忌
* @date 2021/9/10 11:02
*/
public function getImageAttr($value)
{
return trim($value) ? FileService::getFileUrl($value) : '';
}
/**
* @notes 公共图片处理,去除图片域名
* @param $value
* @return mixed|string
* @author 张无忌
* @date 2021/9/10 11:04
*/
public function setImageAttr($value)
{
return trim($value) ? FileService::setFileUrl($value) : '';
}
}
+19
View File
@@ -0,0 +1,19 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model;
class Config extends BaseModel
{
}
+12
View File
@@ -0,0 +1,12 @@
<?php
namespace app\common\model;
use think\Model;
class CrawlErrorLog extends Model
{
protected $name = 'crawl_error_log';
protected $autoWriteTimestamp = false;
}
+80
View File
@@ -0,0 +1,80 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model;
use app\common\enum\CrontabEnum;
use think\model\concern\SoftDelete;
/**
* 定时任务模型
* Class Crontab
* @package app\common\model
*/
class Crontab extends BaseModel
{
use SoftDelete;
protected $deleteTime = 'delete_time';
protected $name = 'dev_crontab';
/**
* @notes 类型获取器
* @param $value
* @return string
* @author 段誉
* @date 2022/3/29 12:05
*/
public function getTypeDescAttr($value)
{
$desc = [
CrontabEnum::CRONTAB => '定时任务',
CrontabEnum::DAEMON => '守护进程',
];
return $desc[$value] ?? '';
}
/**
* @notes 状态获取器
* @param $value
* @return string
* @author 段誉
* @date 2022/3/29 12:06
*/
public function getStatusDescAttr($value)
{
$desc = [
CrontabEnum::START => '运行',
CrontabEnum::STOP => '停止',
CrontabEnum::ERROR => '错误',
];
return $desc[$value] ?? '';
}
/**
* @notes 最后执行时间获取器
* @param $value
* @return string
* @author 段誉
* @date 2022/3/29 12:06
*/
public function getLastTimeAttr($value)
{
return empty($value) ? '' : date('Y-m-d H:i:s', $value);
}
}
+12
View File
@@ -0,0 +1,12 @@
<?php
namespace app\common\model;
class CrontabLog extends BaseModel
{
protected $name = 'dev_crontab_log';
protected $autoWriteTimestamp = 'int';
protected $createTime = 'create_time';
protected $updateTime = false;
}
+20
View File
@@ -0,0 +1,20 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model;
class HotSearch extends BaseModel
{
}
+9
View File
@@ -0,0 +1,9 @@
<?php
namespace app\common\model;
class OperationLog extends BaseModel
{
}
+24
View File
@@ -0,0 +1,24 @@
<?php
namespace app\common\model;
class ShortLink extends BaseModel
{
protected $name = 'short_link';
/**
* @notes 生成唯一随机码
*/
public static function generateCode(int $length = 8): string
{
$chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789';
do {
$code = '';
for ($i = 0; $i < $length; $i++) {
$code .= $chars[random_int(0, strlen($chars) - 1)];
}
} while (self::where('code', $code)->findOrEmpty()->isExists());
return $code;
}
}
+29
View File
@@ -0,0 +1,29 @@
<?php
namespace app\common\model;
class ShortLinkLog extends BaseModel
{
protected $name = 'short_link_log';
/**
* @notes 从UA解析平台
*/
public static function parsePlatform(string $ua): string
{
$ua = strtolower($ua);
if (str_contains($ua, 'micromessenger'))
return 'wechat';
if (str_contains($ua, 'alipay'))
return 'alipay';
if (str_contains($ua, 'iphone') || str_contains($ua, 'ipad'))
return 'ios';
if (str_contains($ua, 'android'))
return 'android';
if (str_contains($ua, 'windows'))
return 'windows';
if (str_contains($ua, 'macintosh'))
return 'mac';
return 'other';
}
}
+13
View File
@@ -0,0 +1,13 @@
<?php
namespace app\common\model;
/**
* 短信上传记录模型
* Class SmsLog
* @package app\common\model
*/
class SmsLog extends BaseModel
{
protected $name = 'sms_upload';
}
+40
View File
@@ -0,0 +1,40 @@
<?php
namespace app\common\model\ai;
use app\common\model\BaseModel;
class AiAnalysis extends BaseModel
{
// 分析类型
const TYPE_MATCH_PREDICT = 1;
const TYPE_ARTICLE_ANALYSIS = 2;
const TYPE_USER_CREDIBILITY = 3;
const TYPE_LOTTERY_ANALYSIS = 4;
const TYPE_POST_ANALYSIS = 5;
const TYPE_KB_RETRIEVAL = 6;
const TYPE_ASSISTANT_CHAT = 7;
// 状态
const STATUS_SUCCESS = 1;
const STATUS_FAILED = 2;
const STATUS_PROCESSING = 3;
/**
* 获取有效缓存
*/
public static function getCache(int $type, int $refId): ?array
{
$row = self::where('type', $type)
->where('ref_id', $refId)
->where('status', self::STATUS_SUCCESS)
->where('expire_time', '>', time())
->order('id', 'desc')
->findOrEmpty();
if ($row->isEmpty()) {
return null;
}
return $row->toArray();
}
}
@@ -0,0 +1,16 @@
<?php
namespace app\common\model\ai;
use app\common\model\BaseModel;
class AiChatMessage extends BaseModel
{
protected $name = 'ai_chat_message';
public const ROLE_USER = 'user';
public const ROLE_ASSISTANT = 'assistant';
public const STATUS_SUCCESS = 1;
public const STATUS_FAILED = 2;
}
@@ -0,0 +1,10 @@
<?php
namespace app\common\model\ai;
use app\common\model\BaseModel;
class AiChatSession extends BaseModel
{
protected $name = 'ai_chat_session';
}
+25
View File
@@ -0,0 +1,25 @@
<?php
namespace app\common\model\ai;
use app\common\model\BaseModel;
class AiConfig extends BaseModel
{
public static function getVal(string $name, string $default = ''): string
{
$val = AiConfig::where('name', $name)->value('value');
return $val !== null ? $val : $default;
}
public static function setVal(string $name, string $value): void
{
$row = AiConfig::where('name', $name)->findOrEmpty();
if ($row->isEmpty()) {
AiConfig::create(['name' => $name, 'value' => $value]);
} else {
$row->value = $value;
$row->save();
}
}
}
+14
View File
@@ -0,0 +1,14 @@
<?php
namespace app\common\model\ai;
use app\common\model\BaseModel;
class AiKbChunk extends BaseModel
{
protected $name = 'ai_kb_chunk';
protected $json = ['embedding_json'];
protected $jsonAssoc = true;
}
@@ -0,0 +1,14 @@
<?php
namespace app\common\model\ai;
use app\common\model\BaseModel;
class AiKbDocument extends BaseModel
{
protected $name = 'ai_kb_document';
protected $json = ['metadata_json'];
protected $jsonAssoc = true;
}
@@ -0,0 +1,17 @@
<?php
namespace app\common\model\ai;
use app\common\model\BaseModel;
class AiKbQueryLog extends BaseModel
{
protected $name = 'ai_kb_query_log';
protected $json = ['filters_json', 'hit_docs_json'];
protected $jsonAssoc = true;
public const STATUS_SUCCESS = 1;
public const STATUS_FAILED = 2;
}
@@ -0,0 +1,19 @@
<?php
namespace app\common\model\ai;
use app\common\model\BaseModel;
class AiKbSyncJob extends BaseModel
{
protected $name = 'ai_kb_sync_job';
public const STATUS_PENDING = 0;
public const STATUS_PROCESSING = 1;
public const STATUS_SUCCESS = 2;
public const STATUS_FAILED = 3;
public const ACTION_UPSERT = 'upsert';
public const ACTION_DELETE = 'delete';
public const ACTION_REBUILD = 'rebuild';
}
+9
View File
@@ -0,0 +1,9 @@
<?php
namespace app\common\model\ai;
use app\common\model\BaseModel;
class AiLog extends BaseModel
{
}
+87
View File
@@ -0,0 +1,87 @@
<?php
namespace app\common\model\ai;
use app\common\model\BaseModel;
use app\common\model\user\User;
class AiUnlock extends BaseModel
{
/**
* 检查用户是否已解锁某场比赛
*/
public static function isUnlocked(int $userId, int $matchId): bool
{
return self::where('user_id', $userId)->where('match_id', $matchId)->count() > 0;
}
/**
* 解锁比赛(扣次数 + 写记录)
* @return array ['ok' => bool, 'msg' => string]
*/
public static function unlock(int $userId, int $matchId): array
{
// 已解锁则直接返回
if (self::isUnlocked($userId, $matchId)) {
return ['ok' => true, 'msg' => '已解锁'];
}
// 检查今日剩余次数
$user = User::findOrEmpty($userId);
if ($user->isEmpty()) {
return ['ok' => false, 'msg' => '用户不存在'];
}
// VIP用户不限次数
if ($user->is_vip && $user->vip_expire_time > time()) {
self::create([
'user_id' => $userId,
'match_id' => $matchId,
]);
return ['ok' => true, 'msg' => 'VIP解锁'];
}
// 重置每日次数(跨天时)
$today = date('Y-m-d');
if ($user->ai_free_date !== $today) {
$user->ai_free_count = 3;
$user->ai_free_date = $today;
$user->save();
}
if ($user->ai_free_count <= 0) {
return ['ok' => false, 'msg' => '今日免费次数已用完,升级VIP可无限使用'];
}
// 扣次数 + 写解锁记录
$user->ai_free_count = $user->ai_free_count - 1;
$user->save();
self::create([
'user_id' => $userId,
'match_id' => $matchId,
]);
return ['ok' => true, 'msg' => '解锁成功', 'remain' => $user->ai_free_count];
}
/**
* 获取用户今日剩余次数
*/
public static function getRemainCount(int $userId): int
{
$user = User::findOrEmpty($userId);
if ($user->isEmpty()) {
return 0;
}
// VIP不限
if ($user->is_vip && $user->vip_expire_time > time()) {
return 999;
}
$today = date('Y-m-d');
if ($user->ai_free_date !== $today) {
return 3;
}
return max(0, (int)$user->ai_free_count);
}
}
@@ -0,0 +1,62 @@
<?php
namespace app\common\model\app;
use app\common\model\BaseModel;
use app\common\service\FileService;
use think\model\concern\SoftDelete;
/**
* APP 版本管理模型
* Class AppVersion
* @package app\common\model\app
*/
class AppVersion extends BaseModel
{
use SoftDelete;
protected $name = 'app_version';
protected $deleteTime = 'delete_time';
/**
* 平台名称
*/
public function getPlatformTextAttr($value, $data): string
{
$map = [1 => 'Android', 2 => 'iOS'];
return $map[$data['platform']] ?? '';
}
/**
* 包类型名称
*/
public function getPackageTypeTextAttr($value, $data): string
{
$map = [1 => 'wgt热更', 2 => 'apk整包', 3 => 'ipa/AppStore'];
return $map[$data['package_type']] ?? '';
}
/**
* 升级类型名称
*/
public function getUpdateTypeTextAttr($value, $data): string
{
$map = [1 => '普通升级', 2 => '强制升级', 3 => '静默升级'];
return $map[$data['update_type']] ?? '';
}
/**
* 完整下载链接
*/
public function getDownloadUrlAttr($value): string
{
if (empty($value)) {
return '';
}
// 已是完整 URLhttp/https)直接返回
if (preg_match('/^https?:\/\//i', $value)) {
return $value;
}
return FileService::getFileUrl($value);
}
}
+138
View File
@@ -0,0 +1,138 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model\article;
use app\common\enum\YesNoEnum;
use app\common\model\BaseModel;
use app\common\model\article\ArticleComment;
use think\model\concern\SoftDelete;
/**
* 资讯管理模型
* Class Article
* @package app\common\model\article;
*/
class Article extends BaseModel
{
use SoftDelete;
protected $deleteTime = 'delete_time';
public static function hasPublishableContent(?string $content): bool
{
$raw = trim((string) $content);
if ($raw === '') {
return false;
}
$plain = trim(strip_tags($raw));
if (mb_strlen($plain) < 50) {
return false;
}
if (preg_match('/<(p|div|article|section|img|video|h1|h2|h3|h4|blockquote|li)\b/i', $raw)) {
return true;
}
return mb_strlen($plain) >= 200;
}
public function comments()
{
return $this->hasMany(ArticleComment::class, 'article_id', 'id');
}
/**
* @notes 获取分类名称
* @param $value
* @param $data
* @return string
* @author heshihu
* @date 2022/2/22 9:53
*/
public function getCateNameAttr($value, $data)
{
return ArticleCate::where('id', $data['cid'])->value('name');
}
/**
* @notes 浏览量
* @param $value
* @param $data
* @return mixed
* @author 段誉
* @date 2022/9/15 11:33
*/
public function getClickAttr($value, $data)
{
return $data['click_actual'] + $data['click_virtual'];
}
/**
* @notes 设置图片域名
* @param $value
* @param $data
* @return array|string|string[]|null
* @author 段誉
* @date 2022/9/28 10:17
*/
public function getContentAttr($value, $data)
{
return get_file_domain($value);
}
/**
* @notes 清除图片域名
* @param $value
* @param $data
* @return array|string|string[]
* @author 段誉
* @date 2022/9/28 10:17
*/
public function setContentAttr($value, $data)
{
return clear_file_domain($value);
}
/**
* @notes 获取文章详情
* @param $id
* @return array
* @author 段誉
* @date 2022/10/20 15:23
*/
public static function getArticleDetailArr(int $id)
{
$article = Article::withCount(['comments' => 'comment_count'])
->where(['id' => $id, 'is_show' => YesNoEnum::YES])
->findOrEmpty();
if ($article->isEmpty()) {
return [];
}
// 增加点击量
$article->click_actual += 1;
$article->save();
return $article->append(['click'])
->hidden(['click_virtual', 'click_actual'])
->toArray();
}
}
@@ -0,0 +1,14 @@
<?php
namespace app\common\model\article;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
class ArticleAiCommentTask extends BaseModel
{
use SoftDelete;
protected $name = 'article_ai_comment_task';
protected $deleteTime = 'delete_time';
}
@@ -0,0 +1,74 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model\article;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
/**
* 资讯分类管理模型
* Class ArticleCate
* @package app\common\model\article;
*/
class ArticleCate extends BaseModel
{
use SoftDelete;
protected $deleteTime = 'delete_time';
/**
* @notes 关联文章
* @return \think\model\relation\HasMany
* @author 段誉
* @date 2022/10/19 16:59
*/
public function article()
{
return $this->hasMany(Article::class, 'cid', 'id');
}
/**
* @notes 状态描述
* @param $value
* @param $data
* @return string
* @author 段誉
* @date 2022/9/15 11:25
*/
public function getIsShowDescAttr($value, $data)
{
return $data['is_show'] ? '启用' : '停用';
}
/**
* @notes 文章数量
* @param $value
* @param $data
* @return int
* @author 段誉
* @date 2022/9/15 11:32
*/
public function getArticleCountAttr($value, $data)
{
return Article::where(['cid' => $data['id']])->count('id');
}
}
@@ -0,0 +1,52 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model\article;
use app\common\enum\YesNoEnum;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
/**
* 资讯收藏
* Class ArticleCollect
* @package app\common\model\article
*/
class ArticleCollect extends BaseModel
{
use SoftDelete;
protected $deleteTime = 'delete_time';
/**
* @notes 是否已收藏文章
* @param $userId
* @param $articleId
* @return bool (true=已收藏, false=未收藏)
* @author 段誉
* @date 2022/10/20 15:13
*/
public static function isCollectArticle($userId, $articleId)
{
$collect = ArticleCollect::where([
'user_id' => $userId,
'article_id' => $articleId,
'status' => YesNoEnum::YES
])->findOrEmpty();
return !$collect->isEmpty();
}
}
@@ -0,0 +1,18 @@
<?php
namespace app\common\model\article;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
/**
* 文章评论模型
* Class ArticleComment
* @package app\common\model\article
*/
class ArticleComment extends BaseModel
{
use SoftDelete;
protected $deleteTime = 'delete_time';
}
@@ -0,0 +1,18 @@
<?php
namespace app\common\model\article;
use app\common\model\BaseModel;
/**
* 文章投票模型(点赞/踩)
* Class ArticleVote
* @package app\common\model\article
*/
class ArticleVote extends BaseModel
{
// 点赞
const VOTE_LIKE = 1;
// 踩
const VOTE_DISLIKE = 2;
}
+116
View File
@@ -0,0 +1,116 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model\auth;
use app\common\enum\YesNoEnum;
use app\common\model\BaseModel;
use app\common\model\dept\Dept;
use think\model\concern\SoftDelete;
use app\common\service\FileService;
class Admin extends BaseModel
{
use SoftDelete;
protected $deleteTime = 'delete_time';
protected $append = [
'role_id',
'dept_id',
'jobs_id',
];
/**
* @notes 关联角色id
* @param $value
* @param $data
* @return array
* @author 段誉
* @date 2022/11/25 15:00
*/
public function getRoleIdAttr($value, $data)
{
return AdminRole::where('admin_id', $data['id'])->column('role_id');
}
/**
* @notes 关联部门id
* @param $value
* @param $data
* @return array
* @author 段誉
* @date 2022/11/25 15:00
*/
public function getDeptIdAttr($value, $data)
{
return AdminDept::where('admin_id', $data['id'])->column('dept_id');
}
/**
* @notes 关联岗位id
* @param $value
* @param $data
* @return array
* @author 段誉
* @date 2022/11/25 15:01\
*/
public function getJobsIdAttr($value, $data)
{
return AdminJobs::where('admin_id', $data['id'])->column('jobs_id');
}
/**
* @notes 获取禁用状态
* @param $value
* @param $data
* @return string|string[]
* @author 令狐冲
* @date 2021/7/7 01:25
*/
public function getDisableDescAttr($value, $data)
{
return YesNoEnum::getDisableDesc($data['disable']);
}
/**
* @notes 最后登录时间获取器 - 格式化:年-月-日 时:分:秒
* @param $value
* @return string
* @author Tab
* @date 2021/7/13 11:35
*/
public function getLoginTimeAttr($value)
{
return empty($value) ? '' : date('Y-m-d H:i:s', $value);
}
/**
* @notes 头像获取器 - 头像路径添加域名
* @param $value
* @return string
* @author Tab
* @date 2021/7/13 11:35
*/
public function getAvatarAttr($value)
{
return empty($value) ? FileService::getFileUrl(config('project.default_image.admin_avatar')) : FileService::getFileUrl(trim($value, '/'));
}
}
@@ -0,0 +1,32 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model\auth;
use app\common\model\BaseModel;
class AdminDept extends BaseModel
{
/**
* @notes 删除用户关联部门
* @param $adminId
* @return bool
* @author 段誉
* @date 2022/11/25 14:14
*/
public static function delByUserId($adminId)
{
return self::where(['admin_id' => $adminId])->delete();
}
}
@@ -0,0 +1,32 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model\auth;
use app\common\model\BaseModel;
class AdminJobs extends BaseModel
{
/**
* @notes 删除用户关联岗位
* @param $adminId
* @return bool
* @author 段誉
* @date 2022/11/25 14:14
*/
public static function delByUserId($adminId)
{
return self::where(['admin_id' => $adminId])->delete();
}
}
@@ -0,0 +1,34 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model\auth;
use app\common\model\BaseModel;
class AdminRole extends BaseModel
{
/**
* @notes 删除用户关联角色
* @param $adminId
* @return bool
* @author 段誉
* @date 2022/11/25 14:14
*/
public static function delByUserId($adminId)
{
return self::where(['admin_id' => $adminId])->delete();
}
}
@@ -0,0 +1,32 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model\auth;
use app\common\model\BaseModel;
class AdminSession extends BaseModel
{
/**
* @notes 关联管理员表
* @return \think\model\relation\HasOne
* @author 令狐冲
* @date 2021/7/5 14:39
*/
public function admin()
{
return $this->hasOne(Admin::class, 'id', 'admin_id')
->field('id,multipoint_login');
}
}
@@ -0,0 +1,31 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model\auth;
use app\common\model\BaseModel;
/**
* 系统菜单
* Class SystemMenu
* @package app\common\model\auth
*/
class SystemMenu extends BaseModel
{
}
@@ -0,0 +1,43 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model\auth;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
/**
* 角色模型
* Class Role
* @package app\common\model
*/
class SystemRole extends BaseModel
{
use SoftDelete;
protected $deleteTime = 'delete_time';
protected $name = 'system_role';
/**
* @notes 角色与菜单关联关系
* @return \think\model\relation\HasMany
* @author 段誉
* @date 2022/7/6 11:16
*/
public function roleMenuIndex()
{
return $this->hasMany(SystemRoleMenu::class, 'role_id');
}
}
@@ -0,0 +1,30 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model\auth;
use app\common\model\BaseModel;
/**
* 角色与菜单权限关系
* Class SystemRoleMenu
* @package app\common\model\auth
*/
class SystemRoleMenu extends BaseModel
{
}
@@ -0,0 +1,28 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model\channel;
use app\common\model\BaseModel;
/**
* 微信公众号回复
* Class OfficialAccountReply
* @package app\common\model\channel
*/
class OfficialAccountReply extends BaseModel
{
}
@@ -0,0 +1,13 @@
<?php
namespace app\common\model\chat;
use app\common\model\BaseModel;
class PrivateChatMessage extends BaseModel
{
protected $name = 'private_chat_message';
public const TYPE_TEXT = 'text';
public const TYPE_IMAGE = 'image';
}
@@ -0,0 +1,10 @@
<?php
namespace app\common\model\chat;
use app\common\model\BaseModel;
class PrivateChatSession extends BaseModel
{
protected $name = 'private_chat_session';
}
@@ -0,0 +1,14 @@
<?php
namespace app\common\model\community;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
class CommunityComment extends BaseModel
{
use SoftDelete;
protected $name = 'community_comment';
protected $deleteTime = 'delete_time';
}
@@ -0,0 +1,10 @@
<?php
namespace app\common\model\community;
use app\common\model\BaseModel;
class CommunityFollow extends BaseModel
{
protected $name = 'community_follow';
}
@@ -0,0 +1,10 @@
<?php
namespace app\common\model\community;
use app\common\model\BaseModel;
class CommunityLike extends BaseModel
{
protected $name = 'community_like';
}
@@ -0,0 +1,29 @@
<?php
namespace app\common\model\community;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
class CommunityPost extends BaseModel
{
use SoftDelete;
protected $name = 'community_post';
protected $deleteTime = 'delete_time';
public function getImagesAttr($value)
{
return $value ? json_decode($value, true) : [];
}
public function setImagesAttr($value)
{
return $value ? json_encode($value, JSON_UNESCAPED_UNICODE) : '[]';
}
public function tags()
{
return $this->belongsToMany(CommunityTag::class, 'la_community_post_tag', 'tag_id', 'post_id');
}
}
@@ -0,0 +1,10 @@
<?php
namespace app\common\model\community;
use app\common\model\BaseModel;
class CommunityTag extends BaseModel
{
protected $name = 'community_tag';
}
@@ -0,0 +1,28 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model\decorate;
use app\common\model\BaseModel;
/**
* 装修配置-页面
* Class DecorateTabbar
* @package app\common\model\decorate
*/
class DecoratePage extends BaseModel
{
}
@@ -0,0 +1,63 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model\decorate;
use app\common\model\BaseModel;
use app\common\service\FileService;
/**
* 装修配置-底部导航
* Class DecorateTabbar
* @package app\common\model\decorate
*/
class DecorateTabbar extends BaseModel
{
// 设置json类型字段
protected $json = ['link'];
// 设置JSON数据返回数组
protected $jsonAssoc = true;
/**
* @notes 获取底部导航列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @author 段誉
* @date 2022/9/23 12:07
*/
public static function getTabbarLists()
{
$tabbar = self::select()->toArray();
if (empty($tabbar)) {
return $tabbar;
}
foreach ($tabbar as &$item) {
if (!empty($item['selected'])) {
$item['selected'] = FileService::getFileUrl($item['selected']);
}
if (!empty($item['unselected'])) {
$item['unselected'] = FileService::getFileUrl($item['unselected']);
}
}
return $tabbar;
}
}
+46
View File
@@ -0,0 +1,46 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model\dept;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
/**
* 部门模型
* Class Dept
* @package app\common\model\article
*/
class Dept extends BaseModel
{
use SoftDelete;
protected $deleteTime = 'delete_time';
/**
* @notes 状态描述
* @param $value
* @param $data
* @return string
* @author 段誉
* @date 2022/5/25 18:03
*/
public function getStatusDescAttr($value, $data)
{
return $data['status'] ? '正常' : '停用';
}
}
+44
View File
@@ -0,0 +1,44 @@
<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\common\model\dept;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
/**
* 岗位模型
* Class Jobs
* @package app\common\model\dept
*/
class Jobs extends BaseModel
{
use SoftDelete;
protected $deleteTime = 'delete_time';
/**
* @notes 状态描述
* @param $value
* @param $data
* @return string
* @author 段誉
* @date 2022/5/25 18:03
*/
public function getStatusDescAttr($value, $data)
{
return $data['status'] ? '正常' : '停用';
}
}

Some files were not shown because too many files have changed in this diff Show More