first commit

This commit is contained in:
Your Name
2026-09-08 11:40:15 +08:00
commit a5353f7eb5
9568 changed files with 1646214 additions and 0 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);
}
}
+123
View File
@@ -0,0 +1,123 @@
<?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()
{
// BaseCache::set() 使用类名作为标签,并没有使用 cacheUrlKey 作为标签;
// 这里必须直接删除单账号缓存键,否则角色变更后旧权限会继续保留一小时。
return $this->delete($this->cacheUrlKey);
}
}
+120
View File
@@ -0,0 +1,120 @@
<?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(),
'work_wechat_userid' => $admin->work_wechat_userid ?? '',
];
$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 = 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);
}
}
+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);
}
}
+101
View File
@@ -0,0 +1,101 @@
<?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 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;
/**
* 定时任务
* Class Crontab
* @package app\command
*/
class Crontab extends Command
{
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)
{
// 开始执行
$startTime = microtime(true);
try {
$params = explode(' ', $item['params']);
if (is_array($params) && !empty($item['params'])) {
Console::call($item['command'], $params);
} else {
Console::call($item['command']);
}
// 清除错误信息
CrontabModel::where('id', $item['id'])->update(['error' => '']);
} catch (\Exception $e) {
// 记录错误信息
CrontabModel::where('id', $item['id'])->update([
'error' => $e->getMessage(),
'status' => CrontabEnum::ERROR
]);
} finally {
$endTime = microtime(true);
// 本次执行时间
$useTime = round(($endTime - $startTime), 2);
// 最大执行时间
$maxTime = max($useTime, $item['max_time']);
// 更新最后执行时间
CrontabModel::where('id', $item['id'])->update([
'last_time' => time(),
'time' => $useTime,
'max_time' => $maxTime
]);
}
}
}
@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace app\common\command;
use think\console\Input;
use think\console\Output;
/**
* 定时:补全订单 creator_id(逻辑在 SyncWechatWorkBills::fillOrderCreatorsFromPayee
*/
class FillOrderCreatorFromPayee extends SyncWechatWorkBills
{
protected function configure()
{
$this->setName('fill_order_creator_from_payee')
->setDescription('补全订单创建人:creator_id 为空时按 payee_userid 匹配 zyt_admin.work_wechat_userid');
}
protected function execute(Input $input, Output $output)
{
$fixed = $this->fillOrderCreatorsFromPayee();
$output->writeln("补全创建人完成,共更新 {$fixed} 条订单");
}
}
+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,51 @@
<?php
declare(strict_types=1);
namespace app\common\command;
use app\adminapi\logic\tcm\DiagnosisLogic;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\facade\Log;
/**
* 从腾讯云 IM 拉取诊单单聊漫游消息并写入本地归档表(建议 cron 每几小时执行)
*/
class SyncImChatArchive extends Command
{
protected function configure()
{
$this->setName('sync_im_chat_archive')
->setDescription('同步诊单腾讯云 IM 聊天记录到数据库归档')
->addOption('since-days', null, Option::VALUE_OPTIONAL, '仅处理最近 N 天内更新过的诊单;0 表示不限制', '7')
->addOption('limit', 'l', Option::VALUE_OPTIONAL, '本轮最多处理的诊单数量(1-500)', '50')
->addOption('diagnosis-id', null, Option::VALUE_OPTIONAL, '只同步指定诊单 ID,设置后忽略 since-days', '0');
}
protected function execute(Input $input, Output $output)
{
$sinceDays = (int)$input->getOption('since-days');
$sinceDays = max(0, $sinceDays);
$limit = (int)$input->getOption('limit');
$onlyId = (int)$input->getOption('diagnosis-id');
$only = $onlyId > 0 ? $onlyId : null;
if ($only !== null) {
$output->writeln("同步诊单 ID={$only} ...");
} else {
$output->writeln('同步 IM 归档:since-days=' . ($sinceDays > 0 ? $sinceDays : '不限制') . ", limit={$limit}");
}
$stats = DiagnosisLogic::syncImChatArchiveBatch($sinceDays, $limit, $only);
$output->writeln("处理诊单数: {$stats['diagnoses']},新插入行数(INSERT IGNORE 成功数): {$stats['inserted']}");
if (!empty($stats['errors'])) {
foreach ($stats['errors'] as $e) {
$output->writeln("<error>{$e}</error>");
Log::error('sync_im_chat_archive: ' . $e);
}
}
}
}
@@ -0,0 +1,98 @@
<?php
declare(strict_types=1);
namespace app\common\command;
use app\common\model\doctor\Medicine;
use app\common\service\doctor\MedicineNameAbbrService;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
/**
* 批量回填药材库 name_pinyin_abbr(拼音首字母,供检索)
*
* 用法:
* php think sync_medicine_pinyin_abbr # 仅更新 abbr 为空的记录
* php think sync_medicine_pinyin_abbr --all # 全部按当前名称重算
* php think sync_medicine_pinyin_abbr --dry # 只打印将更新多少条,不写库
*/
class SyncMedicinePinyinAbbr extends Command
{
protected function configure()
{
$this->setName('sync_medicine_pinyin_abbr')
->setDescription('回填/刷新药材表 name_pinyin_abbr(需已执行迁移并 composer 安装 overtrue/pinyin')
->addOption('all', null, Option::VALUE_NONE, '重算全部记录(默认只处理 abbr 为空的)')
->addOption('dry', null, Option::VALUE_NONE, '仅统计/预览,不写入数据库');
}
protected function execute(Input $input, Output $output)
{
if (!class_exists(\Overtrue\Pinyin\Pinyin::class)) {
$output->writeln('<error>未检测到 overtrue/pinyin,请在 server 目录执行: composer update</error>');
return 1;
}
$all = (bool) $input->getOption('all');
$dry = (bool) $input->getOption('dry');
$makeQuery = function () use ($all) {
$q = Medicine::order('id', 'asc');
if (!$all) {
$q->where('name_pinyin_abbr', '');
}
return $q;
};
$total = $makeQuery()->count();
if ($total === 0) {
$output->writeln('没有需要处理的记录。');
return 0;
}
$output->writeln(($all ? '模式: 全部重算' : '模式: 仅空 abbr') . ",待处理 {$total}" . ($dry ? 'dry-run' : ''));
$updated = 0;
$skipped = 0;
$makeQuery()->chunk(200, function ($rows) use (&$updated, &$skipped, $dry) {
foreach ($rows as $row) {
$data = $row instanceof \think\Model ? $row->toArray() : (array) $row;
$id = (int) ($data['id'] ?? 0);
$name = trim((string) ($data['name'] ?? ''));
if ($id <= 0 || $name === '') {
++$skipped;
continue;
}
$abbr = MedicineNameAbbrService::build($name);
if ($abbr === '') {
++$skipped;
continue;
}
if ($dry) {
++$updated;
continue;
}
Medicine::where('id', $id)->update([
'name_pinyin_abbr' => $abbr,
'update_time' => time(),
]);
++$updated;
}
});
if ($dry) {
$output->writeln("[预览] 将写入/覆盖拼音首字母: {$updated} 条,跳过(空名或无法生成): {$skipped}");
} else {
$output->writeln("完成: 已更新 {$updated} 条,跳过 {$skipped} 条。");
}
return 0;
}
}
@@ -0,0 +1,113 @@
<?php
declare(strict_types=1);
namespace app\common\command;
use app\adminapi\logic\order\OrderLogic;
use app\common\model\auth\Admin;
use app\common\model\Order;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\facade\Log;
/**
* 同步企业微信对外收款到订单
* 按天拉取,避免接口时间范围限制
*/
class SyncWechatWorkBills extends Command
{
protected function configure()
{
$this->setName('sync_wechat_work_bills')
->setDescription('同步企业微信对外收款到订单(按天拉取)')
->addOption('date', 'd', Option::VALUE_OPTIONAL, '指定日期 Y-m-d,默认今天', '')
->addOption('days', null, Option::VALUE_OPTIONAL, '拉取最近N天,每天单独请求', '1')
->addOption(
'fill-order-creators-only',
null,
Option::VALUE_NONE,
'仅补全订单创建人:creator_id 为空时用 payee_userid 匹配 admin.work_wechat_userid(可单独做定时任务)'
);
}
protected function execute(Input $input, Output $output)
{
if ($input->getOption('fill-order-creators-only')) {
$fixed = $this->fillOrderCreatorsFromPayee();
$output->writeln("补全创建人完成,共更新 {$fixed} 条订单");
return;
}
$dateStr = $input->getOption('date');
$days = (int)$input->getOption('days');
$days = $days > 0 ? min($days, 31) : 1;
$totalCreated = 0;
$totalUpdated = 0;
$totalSkipped = 0;
$errors = [];
if ($dateStr) {
$dates = [$dateStr];
} else {
$dates = [];
for ($i = 0; $i < $days; $i++) {
$dates[] = date('Y-m-d', strtotime("-{$i} days"));
}
}
foreach ($dates as $d) {
$beginTime = strtotime($d . ' 00:00:00');
$endTime = strtotime($d . ' 23:59:59');
$output->writeln("同步 {$d} ...");
$result = OrderLogic::syncFromWechatWorkBills($beginTime, $endTime);
$totalCreated += $result['created'];
$totalUpdated += $result['updated'];
$totalSkipped += $result['skipped'];
if (!empty($result['errors'])) {
$errors = array_merge($errors, $result['errors']);
}
$output->writeln(" -> 新增 {$result['created']} 更新 {$result['updated']} 跳过 {$result['skipped']}");
}
$output->writeln("完成: 共新增 {$totalCreated} 更新 {$totalUpdated} 跳过 {$totalSkipped}");
if (!empty($errors)) {
foreach ($errors as $e) {
$output->writeln("<error>{$e}</error>");
Log::error('sync_wechat_work_bills: ' . $e);
}
}
}
/**
* creator_id 为空的订单,用 payee_userid 匹配管理员 work_wechat_userid 写入 creator_id
*/
protected function fillOrderCreatorsFromPayee(): int
{
$fixed = 0;
Order::whereRaw('(creator_id IS NULL OR creator_id = 0)')
->whereNotNull('payee_userid')
->where('payee_userid', '<>', '')
->chunk(200, function ($orders) use (&$fixed) {
foreach ($orders as $order) {
$payee = trim((string) $order->getAttr('payee_userid'));
if ($payee === '') {
continue;
}
$admin = Admin::where('work_wechat_userid', $payee)->whereNull('delete_time')->find();
if (!$admin) {
continue;
}
$order->creator_id = (int) $admin->getAttr('id');
$order->save();
$fixed++;
}
});
return $fixed;
}
}
@@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
namespace app\common\command;
use app\common\model\doctor\Appointment;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\facade\Db;
use think\facade\Log;
/**
* 挂号单状态自动更新
* - 已预约(status=1) 且预约时间已过超过 35 分钟 → status=4(已过号)
* - 已过号(status=4) 且预约时间已过超过 8 小时 → status=2(已取消)
* - 不处理:status=3(已完成)、未到预约时间、距预约未满 35 分钟的单子
*/
class UpdateAppointmentStatus extends Command
{
protected function configure()
{
$this->setName('update_appointment_status')
->setDescription('挂号单:已预约过号35分钟→已过号;已过号超8小时→已取消')
->addOption('dry', null, Option::VALUE_NONE, '仅预览不执行');
}
protected function execute(Input $input, Output $output)
{
$dryRun = $input->getOption('dry');
$now = time();
$table = (new Appointment())->getTable();
$dtExpr = "CONCAT(appointment_date, ' ', IFNULL(appointment_time, '00:00:00'))";
// 1. 已预约 → 已过号:预约时间早于「当前 − 35 分钟」
$missedWhere = "status = 1 AND {$dtExpr} < DATE_SUB(NOW(), INTERVAL 35 MINUTE)";
$missedSql = "UPDATE {$table} SET status = 4, update_time = ? WHERE {$missedWhere}";
// 2. 已过号 → 已取消:预约时间早于或等于「当前 − 8 小时」
$cancelWhere = "status = 4 AND {$dtExpr} <= DATE_SUB(NOW(), INTERVAL 8 HOUR)";
$cancelSql = "UPDATE {$table} SET status = 2, update_time = ? WHERE {$cancelWhere}";
if ($dryRun) {
$missedPreview = Db::query("SELECT id FROM {$table} WHERE {$missedWhere}");
$cancelPreview = Db::query("SELECT id FROM {$table} WHERE {$cancelWhere}");
$output->writeln('[预览] 将改为已过号(1→4): ' . count($missedPreview) . ' 条');
$output->writeln('[预览] 将改为已取消(4→2,过号超8小时): ' . count($cancelPreview) . ' 条');
$output->writeln('[说明] 真实执行时先执行 1→4,再执行 4→2;同一次内刚由 1 变 4 且已超 8 小时的会再被改为 2。');
return;
}
$missedCount = Db::execute($missedSql, [$now]);
$cancelCount = Db::execute($cancelSql, [$now]);
$output->writeln("已过号(1→4): {$missedCount}");
$output->writeln("已取消(4→2,过号超8小时): {$cancelCount}");
Log::info("update_appointment_status: 已过号 {$missedCount}, 已取消 {$cancelCount}");
}
}
@@ -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,167 @@
<?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;
/**
* 动作
* INC 增加
* DEC 减少
*/
const INC = 1;
const DEC = 2;
/**
* 用户余额减少类型
*/
const UM_DEC_ADMIN = 100;
const UM_DEC_RECHARGE_REFUND = 101;
/**
* 用户余额增加类型
*/
const UM_INC_ADMIN = 200;
const UM_INC_RECHARGE = 201;
/**
* 用户余额(减少类型汇总)
*/
const UM_DEC = [
self::UM_DEC_ADMIN,
self::UM_DEC_RECHARGE_REFUND,
];
/**
* 用户余额(增加类型汇总)
*/
const UM_INC = [
self::UM_INC_ADMIN,
self::UM_INC_RECHARGE,
];
/**
* @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 => '充值订单退款减少余额',
];
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 获取变动对象
* @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;
}
// 其他...
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,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
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\exception;
use think\Exception;
/**
* 控制器继承异常
* Class ControllerExtendException
* @package app\common\exception
*/
class ControllerExtendException extends Exception
{
/** PHP 8.2 不再允许通过赋值隐式创建动态属性。 */
protected string $model = '';
/**
* 构造方法
* @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();
}
}
}
+226
View File
@@ -0,0 +1,226 @@
<?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;
/**
* 管理端列表:在 request 就绪后写入 adminId/adminInfo(见 BaseAdminDataLists
*/
protected function initAdminIdentity(): void
{
}
public function __construct()
{
//参数验证
(new ListsValidate())->get()->goCheck();
//请求参数设置
$this->request = request();
// admin 列表子类在 initExport 中可能触发 count/lists,须先于 initPage/initExport 写入身份
$this->initAdminIdentity();
$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,117 @@
<?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])) {
continue;
}
$paramVal = $this->params[$paramsName];
// 勿用 == ''PHP 中 0 == '' 为 true,会误跳过 prescription_audit_status=0 等合法筛选
if ($paramVal === '' || $paramVal === null) {
continue;
}
$where[] = [$whereField, $whereType, $paramVal];
}
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])) {
continue;
}
$paramVal = $this->params[$paramsName];
if ($paramVal === '' || $paramVal === null) {
continue;
}
$where[] = [$whereField, 'find in set', $paramVal];
}
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,122 @@
<?php
declare(strict_types=1);
namespace app\common\lists\Traits;
use app\common\service\DataScope\DataScopeService;
use think\db\Query;
/**
* 列表按「数据范围」过滤。
*
* 使用前置条件:宿主类须通过 BaseAdminDataLists 获得 $this->adminId 与 $this->adminInfo。
*
* 三种用法:
* - applyDataScopeByOwner($q, 'creator_id') 直接按某列 IN
* - applyDataScopeByOwnerColumns($q, ['creator_id', 'doctor_id']) 多列 OR
* - applyDataScopeByExists($q, $sqlTemplate, 'owner_expr') 通过 exists 子查询(跨表)
*/
trait HasDataScopeFilter
{
/**
* 单列过滤。null 表示豁免(ALL)。
*/
protected function applyDataScopeByOwner($query, string $ownerField): bool
{
if (!$this->dataScopeShouldApply()) {
return false;
}
$ids = $this->getDataScopeVisibleAdminIds();
if ($ids === null) {
return false;
}
if ($ids === []) {
$query->whereRaw('0 = 1');
return true;
}
$query->whereIn($ownerField, $ids);
return true;
}
/**
* 多列 OR 过滤(任意属主列命中即可)。
*
* @param string[] $ownerFields
*/
protected function applyDataScopeByOwnerColumns($query, array $ownerFields): bool
{
if (!$this->dataScopeShouldApply()) {
return false;
}
$ids = $this->getDataScopeVisibleAdminIds();
if ($ids === null) {
return false;
}
if ($ids === []) {
$query->whereRaw('0 = 1');
return true;
}
$query->where(function ($q) use ($ownerFields, $ids) {
$first = true;
foreach ($ownerFields as $f) {
if ($first) {
$q->whereIn($f, $ids);
$first = false;
} else {
$q->whereOr(function ($qq) use ($f, $ids) {
$qq->whereIn($f, $ids);
});
}
}
});
return true;
}
/**
* exists 子查询方式。
* $subSqlTemplate 内部可使用占位符 `__OWNER_IDS__`,将被替换成逗号分隔的整数列表。
*/
protected function applyDataScopeByExistsSql($query, string $subSqlTemplate): bool
{
if (!$this->dataScopeShouldApply()) {
return false;
}
$ids = $this->getDataScopeVisibleAdminIds();
if ($ids === null) {
return false;
}
if ($ids === []) {
$query->whereRaw('0 = 1');
return true;
}
$inList = implode(',', $ids);
$sql = str_replace('__OWNER_IDS__', $inList, $subSqlTemplate);
$query->whereExists($sql);
return true;
}
/**
* 可见 admin idnull = 全部。
*
* @return array<int>|null
*/
protected function getDataScopeVisibleAdminIds(): ?array
{
$adminId = property_exists($this, 'adminId') ? (int) $this->adminId : 0;
$adminInfo = property_exists($this, 'adminInfo') && is_array($this->adminInfo) ? $this->adminInfo : [];
return DataScopeService::getVisibleAdminIds($adminId, $adminInfo);
}
protected function dataScopeShouldApply(): bool
{
return DataScopeService::isEnabled();
}
}
@@ -0,0 +1,76 @@
<?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 = [])
{
$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;
// 其他
}
$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) : '',
];
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;
}
}
+106
View File
@@ -0,0 +1,106 @@
<?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\recharge\RechargeOrder;
use app\common\model\user\User;
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();
}
/**
* @notes 订单支付回调
* @param $orderSn
* @param array $extra
*/
public static function order($orderSn, array $extra = [])
{
$order = \app\common\model\Order::where('order_no', $orderSn)->findOrEmpty();
if ($order->isEmpty()) {
throw new \Exception('订单不存在: ' . $orderSn);
}
if ($order->status == 2) {
return;
}
$order->status = 2;
$order->pay_time = date('Y-m-d H:i:s');
$order->transaction_id = $extra['transaction_id'] ?? '';
$order->save();
}
}
+274
View File
@@ -0,0 +1,274 @@
<?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\YesNoEnum;
use app\common\model\pay\PayWay;
use app\common\model\recharge\RechargeOrder;
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();
} elseif ($params['from'] == 'order') {
$orderModel = \app\common\model\Order::findOrEmpty($params['order_id']);
if (!$orderModel->isEmpty()) {
$order = $orderModel->toArray();
$order['order_amount'] = $order['amount'];
$order['sn'] = $order['order_no'];
}
}
if (empty($order)) {
throw new \Exception('待支付订单不存在');
}
//获取支付场景
$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 ($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 'order':
$order = \app\common\model\Order::where(['id' => $params['order_id']])
->findOrEmpty();
$statusMap = [1 => 0, 2 => 1, 3 => 0, 4 => 0];
$order['pay_status'] = $statusMap[$order['status']] ?? 0;
$order['pay_way'] = $order['pay_way'] ?? 0;
$orderInfo = [
'order_id' => $order['id'],
'order_sn' => $order['order_no'],
'order_amount' => $order['amount'],
'pay_way' => PayEnum::getPayDesc($order['pay_way']),
'pay_status' => $order['status'] == 2 ? '已支付' : '未支付',
'pay_time' => $order['pay_time'] ?? '',
];
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 'order':
$order = \app\common\model\Order::findOrEmpty($params['order_id']);
if ($order->isEmpty()) {
throw new \Exception('订单不存在');
}
if ($order['status'] == 2) {
throw new \Exception('订单已支付');
}
$order['order_amount'] = $order['amount'];
$order['sn'] = $order['order_no'];
$order['pay_status'] = PayEnum::UNPAID;
return $order;
}
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 'order':
\app\common\model\Order::update(['pay_way' => $payWay], ['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::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
]);
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace app\common\model;
use app\common\service\FileService;
class AssetResource extends BaseModel
{
protected $name = 'asset_resource';
protected $autoWriteTimestamp = true;
public function getFileUrlAttr($value)
{
return trim($value) ? FileService::getFileUrl($value) : '';
}
public function setFileUrlAttr($value)
{
return trim($value) ? FileService::setFileUrl($value) : '';
}
public function getCoverUrlAttr($value)
{
return trim($value) ? FileService::getFileUrl($value) : '';
}
public function setCoverUrlAttr($value)
{
return trim($value) ? FileService::setFileUrl($value) : '';
}
// Relation to users via asset_user_resource
public function users()
{
return $this->belongsToMany(AssetUser::class, AssetUserResource::class, 'user_id', 'resource_id');
}
}
+13
View File
@@ -0,0 +1,13 @@
<?php
namespace app\common\model;
use think\model\concern\SoftDelete;
class AssetUser extends BaseModel
{
protected $name = 'asset_user';
protected $autoWriteTimestamp = true;
// Optional: Hide password when returning array/json
protected $hidden = ['password'];
}
@@ -0,0 +1,10 @@
<?php
namespace app\common\model;
use think\model\Pivot;
class AssetUserResource extends Pivot
{
protected $name = 'asset_user_resource';
protected $autoWriteTimestamp = 'create_time';
protected $updateTime = false;
}
+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
{
}
+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);
}
}
@@ -0,0 +1,50 @@
<?php
namespace app\common\model;
use app\common\model\user\User;
use app\common\model\tcm\Diagnosis;
use think\model\concern\SoftDelete;
/**
* 诊单查看记录模型
*/
class DiagnosisViewRecord extends BaseModel
{
use SoftDelete;
protected $name = 'diagnosis_view_records';
protected $deleteTime = 'delete_time';
/**
* @notes 关联用户
*/
public function user()
{
return $this->hasOne(User::class, 'id', 'user_id');
}
/**
* @notes 关联诊单
*/
public function diagnosis()
{
return $this->hasOne(Diagnosis::class, 'id', 'diagnosis_id');
}
/**
* @notes 关联患者
*/
public function patient()
{
return $this->hasOne(User::class, 'id', 'patient_id');
}
/**
* @notes 关联分享用户
*/
public function shareUser()
{
return $this->hasOne(User::class, 'id', 'share_user_id');
}
}
@@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace app\common\model;
/**
* 物流查询日志模型
*/
class ExpressQueryLog extends BaseModel
{
protected $name = 'express_query_log';
// 表只有 create_time、无 update_timeconfig/database.php 全局 auto_timestamp=true,需显式关闭避免 Unknown column 'update_time'
protected $autoWriteTimestamp = false;
}
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace app\common\model;
/**
* 物流状态变更记录模型
*/
class ExpressStateLog extends BaseModel
{
protected $name = 'express_state_log';
// 表只有 create_time、无 update_timeconfig/database.php 全局 auto_timestamp=true,需显式关闭避免 Unknown column 'update_time'
protected $autoWriteTimestamp = false;
/**
* 关联主表
*/
public function tracking()
{
return $this->belongsTo(ExpressTracking::class, 'tracking_id', 'id');
}
}
+24
View File
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace app\common\model;
/**
* 物流轨迹明细模型
*/
class ExpressTrace extends BaseModel
{
protected $name = 'express_trace';
// 表只有 create_time、无 update_timeconfig/database.php 全局 auto_timestamp=true,需显式关闭避免 Unknown column 'update_time'
protected $autoWriteTimestamp = false;
/**
* 关联主表
*/
public function tracking()
{
return $this->belongsTo(ExpressTracking::class, 'tracking_id', 'id');
}
}
+101
View File
@@ -0,0 +1,101 @@
<?php
declare(strict_types=1);
namespace app\common\model;
use think\model\concern\SoftDelete;
/**
* 物流追踪模型
*/
class ExpressTracking extends BaseModel
{
use SoftDelete;
protected $name = 'express_tracking';
protected $deleteTime = 'delete_time';
// 物流状态常量
public const STATE_IN_TRANSIT = '0'; // 在途
public const STATE_COLLECTED = '1'; // 揽收
public const STATE_PROBLEM = '2'; // 疑难
public const STATE_SIGNED = '3'; // 签收
public const STATE_RETURN_SIGNED = '4'; // 退签
public const STATE_DELIVERING = '5'; // 派件
public const STATE_RETURNING = '6'; // 退回
public const STATE_FORWARDING = '7'; // 转投
public const STATE_CUSTOMS = '8'; // 清关
public const STATE_WAIT_CUSTOMS = '10'; // 待清关
public const STATE_IN_CUSTOMS = '11'; // 清关中
public const STATE_CUSTOMS_DONE = '12'; // 已清关
public const STATE_CUSTOMS_ERROR = '13'; // 清关异常
public const STATE_REJECTED = '14'; // 拒签
/**
* 获取状态文本
*/
public static function getStateText(string $state): string
{
$map = [
self::STATE_IN_TRANSIT => '在途',
self::STATE_COLLECTED => '揽收',
self::STATE_PROBLEM => '疑难',
self::STATE_SIGNED => '已签收',
self::STATE_RETURN_SIGNED => '退签',
self::STATE_DELIVERING => '派件中',
self::STATE_RETURNING => '退回',
self::STATE_FORWARDING => '转投',
self::STATE_CUSTOMS => '清关',
self::STATE_WAIT_CUSTOMS => '待清关',
self::STATE_IN_CUSTOMS => '清关中',
self::STATE_CUSTOMS_DONE => '已清关',
self::STATE_CUSTOMS_ERROR => '清关异常',
self::STATE_REJECTED => '拒签',
];
return $map[$state] ?? '未知';
}
/**
* 是否为终态(不再需要更新)
*/
public static function isFinalState(string $state): bool
{
return in_array($state, [
self::STATE_SIGNED,
self::STATE_RETURN_SIGNED,
self::STATE_REJECTED,
], true);
}
/**
* 是否为异常状态
*/
public static function isProblemState(string $state): bool
{
return in_array($state, [
self::STATE_PROBLEM,
self::STATE_CUSTOMS_ERROR,
self::STATE_REJECTED,
], true);
}
/**
* 关联轨迹明细
*/
public function traces()
{
return $this->hasMany(ExpressTrace::class, 'tracking_id', 'id')
->order('trace_time_stamp', 'desc');
}
/**
* 关联状态变更记录
*/
public function stateLogs()
{
return $this->hasMany(ExpressStateLog::class, 'tracking_id', 'id')
->order('change_time', 'desc');
}
}
+35
View File
@@ -0,0 +1,35 @@
<?php
namespace app\common\model;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
class Fan extends BaseModel
{
use SoftDelete;
protected $name = 'fan';
protected $autoWriteTimestamp = true;
protected $createTime = 'create_time';
protected $updateTime = 'update_time';
protected $deleteTime = 'delete_time';
protected $dateFormat = false;
public function getGenderDescAttr($value, $data)
{
$gender = [0 => '未知', 1 => '男', 2 => '女'];
return $gender[$data['gender']] ?? '未知';
}
public function getStatusDescAttr($value, $data)
{
$status = [0 => '禁用', 1 => '启用'];
return $status[$data['status']] ?? '未知';
}
public function visitRecords()
{
return $this->hasMany(FanVisitRecord::class, 'fan_id', 'id');
}
}
@@ -0,0 +1,29 @@
<?php
namespace app\common\model;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
class FanVisitRecord extends BaseModel
{
use SoftDelete;
protected $name = 'fan_visit_record';
protected $autoWriteTimestamp = true;
protected $createTime = 'create_time';
protected $updateTime = 'update_time';
protected $deleteTime = 'delete_time';
protected $dateFormat = false;
public function getVisitTypeDescAttr($value, $data)
{
$types = [1 => '电话', 2 => '微信', 3 => '短信', 4 => '上门', 5 => '其他'];
return $types[$data['visit_type']] ?? '未知';
}
public function fan()
{
return $this->belongsTo(Fan::class, 'fan_id', 'id');
}
}
+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
{
}
+175
View File
@@ -0,0 +1,175 @@
<?php
declare(strict_types=1);
namespace app\common\model;
use think\model\concern\SoftDelete;
/**
* 订单模型
* Class Order
* @package app\common\model
*/
class Order extends BaseModel
{
use SoftDelete;
protected $deleteTime = 'delete_time';
protected $name = 'order';
/**
* @notes 关联订单详情
* @return \think\model\relation\HasMany
*/
public function details()
{
return $this->hasMany(OrderDetail::class, 'order_id', 'id');
}
/**
* @notes 关联患者(从诊单表)
* @return \think\model\relation\BelongsTo
*/
public function patient()
{
return $this->belongsTo('app\common\model\tcm\Diagnosis', 'patient_id', 'id');
}
/**
* @notes 关联创建人
* @return \think\model\relation\BelongsTo
*/
public function creator()
{
return $this->belongsTo('app\common\model\auth\Admin', 'creator_id', 'id');
}
/**
* @notes 搜索器-订单号
*/
public function searchOrderNoAttr($query, $value, $data)
{
if ($value) {
$query->where('order_no', 'like', '%' . $value . '%');
}
}
/**
* @notes 搜索器-患者关键词
*/
public function searchPatientKeywordAttr($query, $value, $data)
{
if ($value) {
$query->whereHas('patient', function ($q) use ($value) {
$q->where('patient_name|patient_phone', 'like', '%' . $value . '%');
});
}
}
/**
* @notes 搜索器-订单类型
*/
public function searchOrderTypeAttr($query, $value, $data)
{
if ($value) {
$query->where('order_type', '=', $value);
}
}
/**
* @notes 搜索器-订单状态
*/
public function searchStatusAttr($query, $value, $data)
{
if ($value) {
$query->where('status', '=', $value);
}
}
/**
* @notes 搜索器-创建时间开始
*/
public function searchCreateTimeStartAttr($query, $value, $data)
{
if ($value) {
$query->where('create_time', '>=', $value . ' 00:00:00');
}
}
/**
* @notes 搜索器-创建时间结束
*/
public function searchCreateTimeEndAttr($query, $value, $data)
{
if ($value) {
$query->where('create_time', '<=', $value . ' 23:59:59');
}
}
/**
* @notes 获取器-订单类型描述
*/
public function getOrderTypeDescAttr($value, $data)
{
$typeMap = [1 => '挂号费', 2 => '问诊费', 3 => '药品费用'];
return $typeMap[$data['order_type']] ?? '未知';
}
/**
* @notes 获取器-订单状态描述
*/
public function getStatusDescAttr($value, $data)
{
$statusMap = [1 => '待支付', 2 => '已支付', 3 => '已取消', 4 => '已退款', 5 => '待审核'];
return $statusMap[$data['status']] ?? '未知';
}
/**
* @notes 获取器-患者名称
*/
public function getPatientNameAttr($value, $data)
{
if ($value) {
return $value;
}
try {
$patient = $this->patient()->find();
return $patient ? $patient->patient_name : '';
} catch (\Exception $e) {
return '';
}
}
/**
* @notes 获取器-患者电话
*/
public function getPatientPhoneAttr($value, $data)
{
if ($value) {
return $value;
}
try {
$patient = $this->patient()->find();
return $patient ? $patient->patient_phone : '';
} catch (\Exception $e) {
return '';
}
}
/**
* @notes 获取器-创建人名称
*/
public function getCreatorNameAttr($value, $data)
{
if ($value) {
return $value;
}
try {
$creator = $this->creator()->find();
return $creator ? $creator->name : '';
} catch (\Exception $e) {
return '';
}
}
}
@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace app\common\model;
/**
* 支付单(zyt_order)后台操作日志
*/
class OrderActionLog extends BaseModel
{
protected $name = 'order_action_log';
protected $autoWriteTimestamp = false;
}
+33
View File
@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace app\common\model;
/**
* 订单详情模型
* Class OrderDetail
* @package app\common\model
*/
class OrderDetail extends BaseModel
{
protected $table = 'la_order_detail';
/**
* @notes 关联订单
* @return \think\model\relation\BelongsTo
*/
public function order()
{
return $this->belongsTo(Order::class, 'order_id', 'id');
}
/**
* @notes 获取器-关联类型描述
*/
public function getRelatedTypeDescAttr($value, $data)
{
$typeMap = ['appointment' => '挂号', 'diagnosis' => '问诊', 'medicine' => '药品'];
return $typeMap[$data['related_type']] ?? '未知';
}
}
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace app\common\model;
use think\model\concern\SoftDelete;
/**
* 企业微信外部联系人模型
*/
class QywxExternalContact extends BaseModel
{
use SoftDelete;
protected $name = 'qywx_external_contact';
protected $deleteTime = 'delete_time';
/**
* 未删除行在库中为 delete_time = NULL(建表与同步 upsert 均如此)。
* 若设为 0Think 会生成 delete_time = 0,与数据不一致导致列表永远为空。
*/
protected $defaultSoftDelete = null;
}
@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace app\common\model;
/**
* 企业微信「客户联系」事件流水模型
*
* - 每收到一次 `change_external_contact` 回调就落一行;
* - (change_type, user_id, external_userid, event_time) 唯一键做幂等,企微自动重试不会重复计数;
* - 用作"今天进来多少人 = 今日 change_type=add_external_contact 的行数"等零误差统计;
* - 与 `qywx_external_contact` 解耦:后者会软删/覆盖,这张表只追加、不改写。
*/
class QywxExternalContactEvent extends BaseModel
{
protected $name = 'qywx_external_contact_event';
}
@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace app\common\model;
class QywxMediaChannel extends BaseModel
{
protected $name = 'qywx_media_channel';
protected $autoWriteTimestamp = true;
protected $createTime = 'create_time';
protected $updateTime = 'update_time';
protected $dateFormat = false;
}
@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
namespace app\common\model;
/**
* 企业微信会话存档消息
*
* 数据来源为「会话内容存档」SDK 拉取后解密落库,msgid 官方唯一。
* 消息体字段根据 msgtype 有不同含义,统一用 content(摘要/文本)+ raw(原始 JSON)组合存储,
* 具体渲染放到业务层(前端或 Logic)再按需展开。
*/
class QywxMsgArchive extends BaseModel
{
protected $name = 'qywx_msg_archive';
protected $autoWriteTimestamp = 'int';
protected $type = [
'send_time' => 'integer',
'seq' => 'integer',
'file_size' => 'integer',
'play_length' => 'integer',
];
/** JSON 反序列化 to_list 访问器,便于业务层直接拿数组 */
public function getToListAttr($value): array
{
if ($value === null || $value === '') {
return [];
}
if (is_array($value)) {
return $value;
}
$decoded = json_decode((string) $value, true);
return is_array($decoded) ? $decoded : [];
}
public function setToListAttr($value): string
{
if (is_string($value)) {
return $value;
}
return json_encode($value ?? [], JSON_UNESCAPED_UNICODE);
}
}
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace app\common\model;
class QywxMsgArchiveCursor extends BaseModel
{
protected $name = 'qywx_msg_archive_cursor';
protected $autoWriteTimestamp = 'int';
public const DEFAULT_KEY = 'global';
}
@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace app\common\model;
class QywxMsgArchiveMedia extends BaseModel
{
protected $name = 'qywx_msg_archive_media';
protected $autoWriteTimestamp = 'int';
public const STATUS_PENDING = 0;
public const STATUS_SUCCESS = 1;
public const STATUS_FAILED = 2;
}
@@ -0,0 +1,78 @@
<?php
declare(strict_types=1);
namespace app\common\model;
/**
* 员工代发消息(企业群发)任务
*
* 企业群发 add_msg_template 的特性:
* - 必须以「员工身份」为 sender 代发,客户端显示为员工本人
* - 员工手机端会弹一次"发送确认",员工点确认后才真正送达客户;admin 后台无法强制送达
* - 返回的 msgid 可通过 get_group_msg_send_result 查询确认 / 送达结果
*
* 状态:
* 0=待提交、1=已提交等待员工确认、2=员工已确认发送、3=失败
*/
class QywxMsgSendTask extends BaseModel
{
protected $name = 'qywx_msg_send_task';
protected $autoWriteTimestamp = 'int';
public const STATUS_PENDING = 0;
public const STATUS_SUBMITTED = 1;
public const STATUS_SENT = 2;
public const STATUS_FAILED = 3;
public function getExternalUseridsAttr($value): array
{
if ($value === null || $value === '') {
return [];
}
$decoded = json_decode((string) $value, true);
return is_array($decoded) ? $decoded : [];
}
public function setExternalUseridsAttr($value): string
{
if (is_string($value)) {
return $value;
}
return json_encode($value ?? [], JSON_UNESCAPED_UNICODE);
}
public function getMsgPayloadAttr($value)
{
if ($value === null || $value === '') {
return [];
}
$decoded = json_decode((string) $value, true);
return is_array($decoded) ? $decoded : [];
}
public function setMsgPayloadAttr($value): string
{
if (is_string($value)) {
return $value;
}
return json_encode($value ?? [], JSON_UNESCAPED_UNICODE);
}
public function getFailListAttr($value)
{
if ($value === null || $value === '') {
return [];
}
$decoded = json_decode((string) $value, true);
return is_array($decoded) ? $decoded : [];
}
public function setFailListAttr($value): string
{
if (is_string($value)) {
return $value;
}
return json_encode($value ?? [], JSON_UNESCAPED_UNICODE);
}
}
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace app\common\model;
/**
* 企业微信 员工×客户 会话索引(用于 admin 聊天页左侧会话列表)
*/
class QywxMsgSession extends BaseModel
{
protected $name = 'qywx_msg_session';
protected $autoWriteTimestamp = 'int';
}
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace app\common\model;
/**
* 企业微信同步设置模型
*/
class QywxSyncSettings extends BaseModel
{
protected $name = 'qywx_sync_settings';
}
@@ -0,0 +1,14 @@
<?php
namespace app\common\model;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
class WechatChatRecord extends BaseModel
{
use SoftDelete;
protected $name = 'wechat_chat_record';
protected $deleteTime = 'delete_time';
}
+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\model\article;
use app\common\enum\YesNoEnum;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
/**
* 资讯管理模型
* Class Article
* @package app\common\model\article;
*/
class Article extends BaseModel
{
use SoftDelete;
protected $deleteTime = 'delete_time';
/**
* @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::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,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();
}
}
+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,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'] ? '正常' : '停用';
}
}
+47
View File
@@ -0,0 +1,47 @@
<?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\dict;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
/**
* 字典数据模型
* Class DictData
* @package app\common\model\dict
*/
class DictData extends BaseModel
{
use SoftDelete;
protected $deleteTime = 'delete_time';
/**
* @notes 状态描述
* @param $value
* @param $data
* @return string
* @author 段誉
* @date 2022/6/20 16:31
*/
public function getStatusDescAttr($value, $data)
{
return $data['status'] ? '正常' : '停用';
}
}
+47
View File
@@ -0,0 +1,47 @@
<?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\dict;
use app\common\model\BaseModel;
use think\model\concern\SoftDelete;
/**
* 字典类型模型
* Class DictType
* @package app\common\model\dict
*/
class DictType extends BaseModel
{
use SoftDelete;
protected $deleteTime = 'delete_time';
/**
* @notes 状态描述
* @param $value
* @param $data
* @return string
* @author 段誉
* @date 2022/6/20 15:54
*/
public function getStatusDescAttr($value, $data)
{
return $data['status'] ? '正常' : '停用';
}
}
@@ -0,0 +1,103 @@
<?php
namespace app\common\model\doctor;
use app\common\model\BaseModel;
/**
* 医生预约模型
* Class Appointment
* @package app\common\model\doctor
*/
class Appointment extends BaseModel
{
protected $name = 'doctor_appointment';
// 自动时间戳类型设置为整型
protected $autoWriteTimestamp = true;
protected $createTime = 'create_time';
protected $updateTime = 'update_time';
protected $deleteTime = false;
// 时间字段取出后的默认时间格式(设置为false表示保持整型)
protected $dateFormat = false;
/**
* @notes 状态描述
* @param $value
* @param $data
* @return string
*/
public function getStatusDescAttr($value, $data)
{
$statusMap = [
1 => '已预约',
2 => '已取消',
3 => '已完成',
4 => '已过号',
];
return $statusMap[$data['status']] ?? '未知';
}
/**
* @notes 时段描述
* @param $value
* @param $data
* @return string
*/
public function getPeriodDescAttr($value, $data)
{
return $data['period'] == 'morning' ? '上午' : '下午';
}
/**
* @notes 预约类型描述
* @param $value
* @param $data
* @return string
*/
public function getAppointmentTypeDescAttr($value, $data)
{
$typeMap = [
'video' => '视频问诊',
'text' => '图文问诊',
'phone' => '电话问诊',
];
return $typeMap[$data['appointment_type']] ?? '未知';
}
/**
* @notes 预约日期格式化
* @param $value
* @param $data
* @return string
*/
public function getAppointmentDateTextAttr($value, $data)
{
return $data['appointment_date'] ?? '';
}
/**
* @notes 关联患者
* @return \think\model\relation\HasOne
*/
public function patient()
{
return $this->hasOne('app\common\model\user\User', 'id', 'patient_id')
->bind(['patient_name' => 'nickname', 'patient_phone' => 'mobile']);
}
/**
* @notes 关联医生
* @return \think\model\relation\HasOne
*/
public function doctor()
{
return $this->hasOne('app\adminapi\logic\auth\AdminLogic', 'id', 'doctor_id')
->bind(['doctor_name' => 'name']);
}
public function diagnosis(){
return $this->belongsTo('app\common\model\tcm\Diagnosis', 'patient_id', 'id');
}
}

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