{{wikiTitle}}
核心依赖库crmeb目录说明
目录:
核心依赖库crmeb目录说明
概述
crmeb 目录是CRMEB多店系统的核心依赖库,包含了系统运行所需的基础类、服务封装、工具函数、接口定义等核心代码。这些代码与业务逻辑解耦,提供了可复用的底层功能支持。
目录结构
crmeb/
├── basic/ # 基础类目录
│ ├── BaseAuth.php # 认证基类
│ ├── BaseController.php # 控制器基类
│ ├── BaseDelivery.php # 配送基类
│ ├── BaseErp.php # ERP基类
│ ├── BaseExpress.php # 快递基类
│ ├── BaseJobs.php # 队列任务基类
│ ├── BaseManager.php # 管理器基类
│ ├── BaseMessage.php # 消息基类
│ ├── BaseModel.php # 模型基类
│ ├── BasePay.php # 支付基类
│ ├── BasePrinter.php # 打印机基类
│ ├── BaseProduct.php # 商品基类
│ ├── BaseSms.php # 短信基类
│ ├── BaseSmss.php # 短信服务基类
│ ├── BaseStorage.php # 存储基类
│ └── BaseUpload.php # 上传基类
├── command/ # 命令行工具
│ └── ...
├── exceptions/ # 异常类目录
│ ├── AdminException.php # 后台异常
│ ├── ApiException.php # API异常
│ ├── AuthException.php # 认证异常
│ ├── PayException.php # 支付异常
│ ├── SmsException.php # 短信异常
│ ├── UploadException.php # 上传异常
│ └── ...
├── form/ # 表单构建器
│ ├── BaseComponent.php # 组件基类
│ ├── Build.php # 表单构建类
│ ├── CommonRule.php # 通用规则
│ ├── components/ # 表单组件
│ └── validate/ # 表单验证
├── interfaces/ # 接口定义
│ ├── HandlerInterface.php # 处理器接口
│ ├── JobInterface.php # 队列任务接口
│ ├── ListenerInterface.php # 监听器接口
│ ├── MiddlewareInterface.php # 中间件接口
│ └── ProviderInterface.php # 服务提供者接口
├── listeners/ # 系统监听器
│ └── ...
├── services/ # 服务类目录
│ ├── AccessTokenServeService.php # Token服务
│ ├── AliPayService.php # 支付宝服务
│ ├── CacheService.php # 缓存服务
│ ├── DownloadImageService.php # 图片下载服务
│ ├── FileService.php # 文件服务
│ ├── HttpService.php # HTTP请求服务
│ ├── LockService.php # 锁服务
│ ├── MysqlBackupService.php # 数据库备份服务
│ ├── QrcodeService.php # 二维码服务
│ ├── SpreadsheetExcelService.php # Excel服务
│ ├── SystemConfigService.php # 系统配置服务
│ ├── UploadService.php # 上传服务
│ ├── delivery/ # 配送服务
│ ├── express/ # 快递服务
│ ├── printer/ # 打印服务
│ ├── sms/ # 短信服务
│ ├── upload/ # 上传驱动
│ └── wechat/ # 微信服务
├── traits/ # Trait特性
│ ├── ErrorTrait.php # 错误处理特性
│ ├── JwtAuthModelTrait.php # JWT模型特性
│ ├── ModelTrait.php # 模型特性
│ ├── QueueTrait.php # 队列特性
│ ├── SearchDaoTrait.php # 搜索Dao特性
│ ├── ServicesTrait.php # 服务特性
│ └── ...
└── utils/ # 工具类目录
├── ApiErrorCode.php # API错误码
├── Arr.php # 数组工具
├── Canvas.php # 画布工具
├── Captcha.php # 验证码
├── Cron.php # 定时任务
├── Hook.php # 钩子
├── Json.php # JSON工具
├── JwtAuth.php # JWT认证
├── QRcode.php # 二维码生成
├── Queue.php # 队列工具
├── Start.php # 启动工具
└── Tag.php # 标签工具
一、基础类 (basic/)
1.1 BaseController - 控制器基类
所有控制器的基类,提供通用功能。
<?php
namespace crmeb\basic;
use think\App;
abstract class BaseController
{
/**
* 应用实例
* @var App
*/
protected $app;
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 构造方法
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
$this->initialize();
}
/**
* 初始化
*/
protected function initialize()
{
}
}
1.2 BaseJobs - 队列任务基类
所有队列任务的基类:
<?php
namespace crmeb\basic;
use crmeb\interfaces\JobInterface;
use think\queue\Job;
/**
* 消息队列基类
*/
class BaseJobs implements JobInterface
{
/**
* 运行消息队列
* @param Job $job
* @param array $data
*/
public function fire(Job $job, $data): void
{
try {
$action = $data['do'] ?? 'doJob'; // 任务名
$infoData = $data['data'] ?? []; // 执行数据
$errorCount = $data['errorCount'] ?? 0; // 最大错误次数
$this->runJob($action, $job, $infoData, $errorCount);
} catch (\Throwable $e) {
$job->delete();
}
}
/**
* 执行队列
*/
protected function runJob(string $action, Job $job, array $infoData, int $errorCount = 3)
{
$action = method_exists($this, $action) ? $action : 'handle';
if (!method_exists($this, $action)) {
$job->delete();
return;
}
if ($this->{$action}(...$infoData)) {
// 执行成功,删除任务
$job->delete();
} else {
if ($job->attempts() >= $errorCount && $errorCount) {
// 超过重试次数,删除任务
$job->delete();
} else {
// 重新放入队列
$job->release();
}
}
}
}
创建队列任务示例
<?php
namespace app\jobs\order;
use crmeb\basic\BaseJobs;
/**
* 订单处理队列任务
*/
class OrderJob extends BaseJobs
{
/**
* 处理订单
* @param int $orderId
* @return bool
*/
public function doJob(int $orderId): bool
{
try {
// 处理订单逻辑
$orderService = app()->make(\app\services\order\StoreOrderServices::class);
$orderService->processOrder($orderId);
return true;
} catch (\Exception $e) {
\think\facade\Log::error('订单处理失败:' . $e->getMessage());
return false;
}
}
/**
* 发送订单通知
*/
public function sendNotify(int $orderId, int $uid): bool
{
// 发送通知逻辑
return true;
}
}
1.3 BaseUpload - 上传基类
文件上传的基础类:
<?php
namespace crmeb\basic;
abstract class BaseUpload
{
/**
* 上传文件
* @param string $file 文件路径
* @param bool $isStream 是否为流
* @param string|null $fileContent 文件内容
* @return array
*/
abstract public function move(string $file, bool $isStream = false, ?string $fileContent = null): array;
/**
* 删除文件
* @param string $filePath 文件路径
* @return bool
*/
abstract public function delete(string $filePath): bool;
/**
* 获取上传信息
* @return array
*/
abstract public function getUploadInfo(): array;
}
二、服务类 (services/)
2.1 CacheService - 缓存服务
统一的缓存操作服务:
<?php
namespace crmeb\services;
use think\facade\Cache as CacheStatic;
/**
* 缓存服务类
* @mixin \Redis
*/
class CacheService
{
protected static $globalCacheName = '_cached_1515146130';
/**
* 判断缓存是否存在
*/
public static function has(string $name): bool
{
return CacheStatic::has($name);
}
/**
* 写入缓存
* @param string $name 缓存名称
* @param mixed $value 缓存值
* @param int $expire 过期时间(秒)
*/
public static function set(string $name, $value, int $expire = null): bool
{
return self::handler()->set($name, $value, $expire);
}
/**
* 读取缓存,不存在则执行回调并缓存
*/
public static function get(string $name, $default = false, int $expire = null)
{
return self::handler()->remember($name, $default, $expire);
}
/**
* 删除缓存
*/
public static function delete(string $name)
{
return CacheStatic::delete($name);
}
/**
* 清空缓存池
*/
public static function clear()
{
return self::handler()->clear();
}
/**
* Redis句柄
*/
public static function redisHandler(string $type = null)
{
if ($type) {
return CacheStatic::store('redis')->tag($type);
}
return CacheStatic::store('redis');
}
/**
* 设置库存队列(Redis)
*/
public static function setStock(string $unique, int $number, int $type = 1, bool $isPush = true)
{
// 使用Redis List实现库存队列
// ...
}
/**
* 弹出库存
*/
public static function popStock(string $unique, int $number, int $type = 1)
{
// 从Redis List弹出库存
// ...
}
/**
* 分布式锁
*/
public static function setMutex(string $key, int $timeout = 10)
{
$curTime = time();
$readMutexKey = "redis:mutex:{$key}";
$mutexRes = self::redisHandler()->handler()->setnx($readMutexKey, $curTime + $timeout);
if ($mutexRes) {
return true;
}
// 检查锁是否过期
$time = self::redisHandler()->handler()->get($readMutexKey);
if ($curTime > $time) {
self::redisHandler()->handler()->del($readMutexKey);
return self::redisHandler()->handler()->setnx($readMutexKey, $curTime + $timeout);
}
return false;
}
/**
* 释放锁
*/
public static function delMutex(string $key)
{
$readMutexKey = "redis:mutex:{$key}";
self::redisHandler()->handler()->del($readMutexKey);
}
}
使用示例
// 基本缓存操作
CacheService::set('user_info_1', $userData, 3600);
$userData = CacheService::get('user_info_1');
CacheService::delete('user_info_1');
// 使用回调获取缓存
$config = CacheService::get('site_config', function() {
return SystemConfigService::more(['site_name', 'site_logo']);
}, 86400);
// 使用分布式锁
if (CacheService::setMutex('order_pay_' . $orderId, 30)) {
try {
// 处理订单支付
$this->processPayment($orderId);
} finally {
CacheService::delMutex('order_pay_' . $orderId);
}
}
// 库存操作(秒杀场景)
CacheService::setStock($productUnique, 100, 1); // 设置100个库存
if (CacheService::checkStock($productUnique, 1, 1)) {
CacheService::popStock($productUnique, 1, 1); // 扣减1个库存
}
2.2 SystemConfigService - 系统配置服务
读取系统配置:
<?php
namespace crmeb\services;
class SystemConfigService
{
/**
* 获取单个配置
* @param string $key 配置键名
* @param mixed $default 默认值
* @param bool $isCaChe 是否使用缓存
*/
public static function get(string $key, $default = '', bool $isCaChe = false)
{
// 实现逻辑
}
/**
* 获取多个配置
* @param array $keys 配置键名数组
*/
public static function more(array $keys, int $storeId = 0)
{
// 实现逻辑
}
}
使用示例
// 获取单个配置
$siteName = SystemConfigService::get('site_name', 'CRMEB');
// 获取多个配置
$config = SystemConfigService::more(['site_name', 'site_logo', 'site_url']);
// 获取门店配置
$storeConfig = SystemConfigService::more(['store_name'], $storeId);
2.3 微信服务 (services/wechat/)
Payment - 微信支付服务
<?php
namespace crmeb\services\wechat;
class Payment extends BaseApplication
{
/**
* 创建订单
* @param string $orderId 订单号
* @param string $totalFee 金额
* @param string $body 商品描述
* @param string $notifyUrl 回调地址
* @param string $tradeType 交易类型
*/
public function create(string $orderId, string $totalFee, string $body, string $notifyUrl, string $tradeType = 'JSAPI')
{
// 创建微信支付订单
}
/**
* 退款
*/
public function refund(string $orderId, string $refundNo, float $totalFee, float $refundFee)
{
// 处理退款
}
/**
* 查询订单
*/
public function query(string $orderId)
{
// 查询订单状态
}
}
OfficialAccount - 公众号服务
<?php
namespace crmeb\services\wechat;
class OfficialAccount extends BaseApplication
{
/**
* 获取JSSDK配置
*/
public function jssdk(array $apis = [])
{
// 返回JSSDK配置
}
/**
* 发送模板消息
*/
public function sendTemplate(string $openid, string $templateId, array $data, string $url = '')
{
// 发送模板消息
}
/**
* 获取用户信息
*/
public function getUserInfo(string $openid)
{
// 获取用户信息
}
/**
* 创建二维码
*/
public function qrcode(string $scene, int $expireSeconds = 604800)
{
// 创建带参数二维码
}
}
使用示例
use crmeb\services\wechat\Payment;
use crmeb\services\wechat\OfficialAccount;
// 微信支付
$payment = app()->make(Payment::class);
$result = $payment->create($orderId, $amount, '商品购买', $notifyUrl, 'JSAPI');
// 公众号服务
$official = app()->make(OfficialAccount::class);
// 发送模板消息
$official->sendTemplate($openid, $templateId, [
'first' => ['value' => '订单支付成功'],
'keyword1' => ['value' => $orderNo],
'keyword2' => ['value' => $amount],
'remark' => ['value' => '感谢您的购买']
], $detailUrl);
// 获取JSSDK配置
$jssdkConfig = $official->jssdk(['chooseWXPay', 'scanQRCode']);
2.4 UploadService - 上传服务
<?php
namespace crmeb\services;
class UploadService
{
/**
* 获取上传实例
* @param int $type 上传类型 1=本地 2=七牛 3=OSS 4=COS
*/
public static function init(int $type = null)
{
// 返回对应的上传驱动实例
}
}
使用示例
// 使用系统配置的上传方式
$upload = UploadService::init();
$result = $upload->move('image.jpg');
// 指定本地上传
$localUpload = UploadService::init(1);
// 指定七牛云上传
$qiniuUpload = UploadService::init(2);
// 指定阿里OSS上传
$ossUpload = UploadService::init(3);
// 指定腾讯COS上传
$cosUpload = UploadService::init(4);
2.5 HttpService - HTTP请求服务
<?php
namespace crmeb\services;
class HttpService
{
/**
* GET请求
*/
public static function getRequest(string $url, array $data = [], array $header = [])
{
// 发送GET请求
}
/**
* POST请求
*/
public static function postRequest(string $url, $data = [], array $header = [])
{
// 发送POST请求
}
/**
* CURL请求
*/
public static function request(string $url, string $method = 'GET', $data = null, array $header = [], int $timeout = 30)
{
// 通用CURL请求
}
}
三、工具类 (utils/)
3.1 JwtAuth - JWT认证工具
<?php
namespace crmeb\utils;
use Firebase\JWT\JWT;
class JwtAuth
{
/**
* 生成Token
* @param int $id 用户ID
* @param string $type 用户类型
* @param array $params 额外参数
*/
public function getToken(int $id, string $type, array $params = []): array
{
$host = app()->request->host();
$time = time();
$exp_time = strtotime('+ 7day');
// APP端延长有效期
if (app()->request->isApp()) {
$exp_time = strtotime('+ 30day');
}
$params += [
'iss' => $host, // 签发者
'aud' => $host, // 接收者
'iat' => $time, // 签发时间
'nbf' => $time, // 生效时间
'exp' => $exp_time, // 过期时间
];
$params['jti'] = compact('id', 'type');
$token = JWT::encode($params, env('app.app_key'));
return compact('token', 'params');
}
/**
* 解析Token
*/
public function parseToken(string $jwt): array
{
[$headb64, $bodyb64, $cryptob64] = explode('.', $jwt);
$payload = JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64));
return [$payload->jti->id, $payload->jti->type, $payload->auth ?? ''];
}
/**
* 验证Token
*/
public function verifyToken()
{
JWT::$leeway = 60;
JWT::decode($this->token, env('app.app_key'), ['HS256']);
}
/**
* 创建Token并存入令牌桶
*/
public function createToken(int $id, string $type, array $params = [])
{
$tokenInfo = $this->getToken($id, $type, $params);
$exp = $tokenInfo['params']['exp'] - $tokenInfo['params']['iat'] + 60;
CacheService::setTokenBucket(
md5($tokenInfo['token']),
['uid' => $id, 'type' => $type, 'token' => $tokenInfo['token'], 'exp' => $exp],
(int)$exp,
$type
);
return $tokenInfo;
}
}
使用示例
$jwtAuth = app()->make(JwtAuth::class);
// 生成Token
$tokenInfo = $jwtAuth->createToken($userId, 'api');
$token = $tokenInfo['token'];
// 解析Token
[$id, $type, $auth] = $jwtAuth->parseToken($token);
// 验证Token
try {
$jwtAuth->verifyToken();
} catch (\Exception $e) {
// Token无效或已过期
}
3.2 Queue - 队列工具
<?php
namespace crmeb\utils;
/**
* 队列工具类
* @method $this do(string $do) 设置任务执行方法
* @method $this job(string $job) 设置任务执行类名
* @method $this errorCount(int $errorCount) 执行失败次数
* @method $this data(...$data) 执行数据
* @method $this secs(int $secs) 延迟执行秒数
*/
class Queue
{
/**
* 放入消息队列
*/
public function push(?array $data = null)
{
// 将任务放入队列
}
}
使用示例
use crmeb\utils\Queue;
use app\jobs\order\OrderJob;
// 基本用法 - 立即执行
Queue::instance()
->job(OrderJob::class)
->data($orderId)
->push();
// 指定执行方法
Queue::instance()
->job(OrderJob::class)
->do('sendNotify')
->data($orderId, $uid)
->push();
// 延迟执行(5分钟后)
Queue::instance()
->job(OrderJob::class)
->secs(300)
->data($orderId)
->push();
// 设置重试次数
Queue::instance()
->job(OrderJob::class)
->errorCount(5)
->data($orderId)
->push();
3.3 ApiErrorCode - API错误码
<?php
namespace crmeb\utils;
class ApiErrorCode
{
// 成功
const SUCCESS = [200, 'SUCCESS'];
// 通用错误
const ERR_EXCEPTION = [400, '系统错误'];
const ERR_PARAM = [400100, '参数错误'];
const ERR_NOT_FOUND = [404, '资源不存在'];
// 认证错误
const ERR_LOGIN = [410000, '请登录'];
const ERR_LOGIN_INVALID = [410001, '登录已过期,请重新登录'];
const ERR_LOGIN_STATUS = [410002, '登录状态有误,请重新登录'];
const ERR_SITE_UPGRADE = [410010, '站点升级中,请稍候访问'];
const ERR_BAN_LOGIN = [410020, '您已被禁止登录,请联系管理员'];
// 权限错误
const ERR_AUTH = [403, '没有权限'];
// Token错误
const ERR_SAVE_TOKEN = [400200, 'token保存失败'];
}
3.4 Captcha - 验证码
<?php
namespace crmeb\utils;
class Captcha
{
/**
* 生成验证码
*/
public function create($id = '')
{
// 生成图形验证码
}
/**
* 验证验证码
*/
public function check(string $code, $id = ''): bool
{
// 验证图形验证码
}
}
四、接口定义 (interfaces/)
4.1 JobInterface - 队列任务接口
<?php
namespace crmeb\interfaces;
use think\queue\Job;
interface JobInterface
{
/**
* 执行队列任务
* @param Job $job
* @param mixed $data
*/
public function fire(Job $job, $data): void;
}
4.2 MiddlewareInterface - 中间件接口
<?php
namespace crmeb\interfaces;
interface MiddlewareInterface
{
/**
* 处理请求
* @param \think\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, \Closure $next);
}
4.3 ListenerInterface - 监听器接口
<?php
namespace crmeb\interfaces;
interface ListenerInterface
{
/**
* 处理事件
* @param mixed $event
*/
public function handle($event);
}
五、异常类 (exceptions/)
5.1 使用异常类
use crmeb\exceptions\AdminException;
use crmeb\exceptions\ApiException;
use crmeb\exceptions\AuthException;
use crmeb\exceptions\PayException;
// 后台异常
throw new AdminException('操作失败', 400);
// API异常
throw new ApiException('参数错误');
// 认证异常
throw new AuthException('请先登录', 410000);
// 支付异常
throw new PayException('支付失败');
六、Trait特性 (traits/)
6.1 ErrorTrait - 错误处理
<?php
namespace crmeb\traits;
trait ErrorTrait
{
protected $error = '';
/**
* 设置错误信息
*/
protected function setError(string $error)
{
$this->error = $error;
return false;
}
/**
* 获取错误信息
*/
public function getError(): string
{
return $this->error;
}
}
6.2 ServicesTrait - 服务特性
<?php
namespace crmeb\traits;
trait ServicesTrait
{
/**
* 事务处理
*/
public function transaction(callable $callback)
{
return \think\facade\Db::transaction($callback);
}
}
七、表单构建器 (form/)
7.1 使用表单构建器
use crmeb\services\FormBuilder;
// 创建表单
$form = FormBuilder::createForm('admin/user/save', [
FormBuilder::input('username', '用户名')->required(),
FormBuilder::input('password', '密码')->type('password'),
FormBuilder::select('status', '状态', 1)->options([
['value' => 1, 'label' => '启用'],
['value' => 0, 'label' => '禁用']
]),
FormBuilder::frameImage('avatar', '头像', '/admin/widget.images'),
FormBuilder::dateTime('birthday', '生日'),
FormBuilder::radio('gender', '性别', 1)->options([
['value' => 1, 'label' => '男'],
['value' => 2, 'label' => '女']
])
]);
return $form->setMethod('post')->setTitle('添加用户');
八、最佳实践
8.1 扩展基础类
<?php
namespace app\services\order;
use crmeb\basic\BaseJobs;
class MyOrderJob extends BaseJobs
{
public function doJob(int $orderId): bool
{
// 自定义处理逻辑
return true;
}
}
8.2 使用缓存服务
// 带锁的操作
CacheService::lock('order_' . $orderId, function() use ($orderId) {
// 原子操作
return $this->processOrder($orderId);
});
// 使用Remember模式
$data = CacheService::remember('key', function() {
return $this->expensiveOperation();
}, 3600);
8.3 队列任务设计
// 推荐:任务参数简洁
Queue::instance()
->job(OrderJob::class)
->data($orderId) // 只传ID
->push();
// 在任务中查询完整数据
public function doJob(int $orderId): bool
{
$order = $this->orderService->get($orderId);
// 处理逻辑
}
常见问题
Q1: 如何自定义上传驱动?
继承 BaseUpload 类并实现抽象方法。
Q2: 如何扩展缓存功能?
使用 CacheService::redisHandler() 获取Redis实例,直接调用Redis命令。
Q3: JWT Token过期时间如何调整?
修改 JwtAuth::getToken() 方法中的 $exp_time 计算逻辑。
Q4: 如何添加新的异常类型?
继承 \Exception 类,放置在 crmeb/exceptions/ 目录。
评论({{cateWiki.comment_num}})
{{commentWhere.order ? '评论从旧到新':'评论从新到旧'}}
{{cateWiki.page_view_num}}人看过该文档
评论(0)
{{commentWhere.order ? '评论从旧到新':'评论从新到旧'}}
8人看过该文档
{{item.user ? item.user.nickname : ''}}
(自评)
{{item.content}}
{{item.create_time}}
删除
搜索结果
为您找到{{wikiCount}}条结果
{{item.page_view_num}}
{{item.like ? item.like.like_num : 0}}
{{item.comment ? item.comment.comment_num : 0}}
位置:
{{path.name}}
{{(i+1) == item.catalogue.path_data.length ? '':'/'}}