chore: 添加静态资源文件和版本配置文件

添加大量图片、字体、音频等静态资源文件,包括用户界面图片、模板文件和安装界面素材
添加系统版本配置文件(.version)和常量定义文件(.constant)
更新供应商依赖文件,包括Symfony VarDumper组件和相关许可证文件
添加验证码配置文件(captcha.php)和.gitignore规则
This commit is contained in:
2026-03-06 20:14:23 +08:00
commit c9a98f342c
4485 changed files with 490986 additions and 0 deletions

157
app/jobs/BatchHandleJob.php Normal file
View File

@@ -0,0 +1,157 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs;
use app\jobs\user\UserJob;
use app\services\other\queue\QueueServices;
use app\services\product\product\StoreProductServices;
use app\services\product\sku\StoreProductAttrServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 批量任务队列
* Class BatchHandleJob
* @package app\jobs
*/
class BatchHandleJob extends BaseJobs
{
use QueueTrait;
/**
* @return mixed
*/
public static function queueName()
{
$default = config('queue.default');
return config('queue.connections.' . $default . '.batch_queue');
}
/**
* 批量任务队列
* @param false $data
* @param $type
* @param array $other
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function doJob($data = false, $type = 1, array $other = [])
{
/** @var QueueServices $queueServices */
$queueServices = app()->make(QueueServices::class);
$re = true;
try {
switch ($type) {
case 1://批量发放优惠券
if (!$data) {
return true;
}
$re = $queueServices->sendCoupon($data, $type);
break;
case 2://批量设置用户分组
if (!$data) {
return true;
}
$re = $queueServices->setUserGroup($data, $type);
break;
case 3://批量设置用户标签
if (!$data) {
return true;
}
$re = $queueServices->setUserLabel($data, $type, $other);
break;
case 4://批量上下架商品
$re = $queueServices->setProductShow($data, $type);
break;
case 5://批量删除商品规格
$re = $queueServices->delProductRule($type);
break;
case 6://批量删除用户已删除订单
$re = $queueServices->delOrder($type);
break;
case 7://批量手动发货
case 8://批量电子面单发货
case 9://批量配送
case 10://批量虚拟发货
$re = $queueServices->orderDelivery($data, $other);
break;
case 11://批量回收站
$re = $queueServices->productRecycle($type);
break;
case 12://回收站批量删除
$re = $queueServices->productDeleteBatch($type);
break;
default:
$re = false;
break;
}
} catch (\Throwable $e) {
$queueName = $queueServices->queue_type_name[$type] ?? '';
Log::error($queueName . '失败,原因' . $e->getMessage());
$re = false;
}
if ($re === false) $queueServices->delWrongQueue(0, $type, false);
//清除缓存
/** @var StoreProductServices $productService */
$productService = app()->make(StoreProductServices::class);
/** @var StoreProductAttrServices $productAttrService */
$productAttrService = app()->make(StoreProductAttrServices::class);
$productService->cacheTag()->clear();
$productAttrService->cacheTag()->clear();
return true;
}
/**
* 用户批量队列
* @param $type
* @param $uids
* @param $data
* @return bool
*/
public function userBatch($type, $uids, $data)
{
if (!$type || !$uids || !$data) {
return true;
}
//拆分大数组 分批加入二级队列
$uidsArr = array_chunk($uids, 100);
foreach ($uidsArr as $ids) {
//加入分批队列
self::dispatchDo('chunkUserBatch', [$type, $ids, $data]);
}
return true;
}
/**
* 拆分分批队列
* @param $type
* @param $uids
* @param $data
* @return bool
*/
public function chunkUserBatch($type, $uids, $data)
{
if (!$type || !$uids || !$data) {
return true;
}
foreach ($uids as $id) {
UserJob::dispatchDo('runUserBatch', [$type, $id, $data]);
}
return true;
}
}

View File

@@ -0,0 +1,198 @@
<?php
declare(strict_types=1);
namespace app\jobs;
use app\services\activity\holiday\HolidayGiftPushServices;
use app\services\activity\holiday\HolidayGiftServices;
use app\services\message\sms\SmsSendServices;
use app\services\wechat\WechatServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 节日有礼推送任务
* Class HolidayGiftPushJob
* @package app\jobs
*/
class HolidayGiftPushJob extends BaseJobs
{
use QueueTrait;
/**
* 执行推送任务
* @param int $pushId 推送记录ID
* @return bool
*/
public function doJob(int $pushId): bool
{
try {
/** @var HolidayGiftPushServices $pushServices */
$pushServices = app()->make(HolidayGiftPushServices::class);
/** @var HolidayGiftServices $giftServices */
$giftServices = app()->make(HolidayGiftServices::class);
// 获取推送记录
$pushInfo = $pushServices->get($pushId);
if (!$pushInfo || $pushInfo->status != 0) {
return true;
}
// 获取活动信息
$activity = $giftServices->get($pushInfo->holiday_gift_id);
if (!$activity || $activity->status != 1) {
// 更新推送状态为失败
$pushServices->update($pushId, ['status' => 2, 'push_time' => time()]);
return true;
}
// 根据推送类型执行不同的推送
$result = false;
switch ($pushInfo->push_type) {
case 1: // 短信
$result = $this->sendSms($pushInfo->uid, $activity->toArray());
break;
case 2: // 公众号
$result = $this->sendWechat($pushInfo->uid, $activity->toArray());
break;
case 3: // 弹框广告
$result = $this->sendPopup($pushInfo->uid, $activity->toArray());
break;
}
// 更新推送状态
$pushServices->update($pushId, [
'status' => $result ? 1 : 2,
'push_time' => time()
]);
return true;
} catch (\Throwable $e) {
Log::error('节日有礼推送任务执行失败:' . $e->getMessage());
return false;
}
}
/**
* 发送短信
* @param int $uid 用户ID
* @param array $activity 活动信息
* @return bool
*/
protected function sendSms(int $uid, array $activity): bool
{
try {
/** @var SmsSendServices $smsServices */
$smsServices = app()->make(SmsSendServices::class);
// 获取用户手机号
$userInfo = app()->make(\app\services\user\UserServices::class)->getUserInfo($uid);
if (!$userInfo || !$userInfo['phone']) {
return false;
}
// 短信模板变量
$data = [
'activity_name' => $activity['name'],
'gift_type' => $this->getGiftTypeName($activity['gift_type']),
'date' => date('Y-m-d')
];
// 发送短信
return $smsServices->send($userInfo['phone'], $data, 'HOLIDAY_GIFT_NOTICE');
} catch (\Throwable $e) {
Log::error('节日有礼短信推送失败:' . $e->getMessage());
return false;
}
}
/**
* 发送公众号消息
* @param int $uid 用户ID
* @param array $activity 活动信息
* @return bool
*/
protected function sendWechat(int $uid, array $activity): bool
{
try {
/** @var WechatServices $wechatServices */
$wechatServices = app()->make(WechatServices::class);
// 获取用户openid
$userInfo = app()->make(\app\services\user\UserServices::class)->getUserInfo($uid);
if (!$userInfo || !$userInfo['openid']) {
return false;
}
// 消息内容
$title = '节日有礼通知';
$description = "亲爱的用户,您有一个节日礼物待领取\n\n活动名称:{$activity['name']}\n礼物类型:{$this->getGiftTypeName($activity['gift_type'])}\n有效期至:" . date('Y-m-d', $activity['end_time']);
$url = sys_config('site_url') . '/pages/activity/holiday_gift/detail?id=' . $activity['id'];
$image = $activity['wechat_image'] ?: sys_config('site_logo');
// 发送图文消息
return $wechatServices->sendTemplate($userInfo['openid'], $title, $description, $url, $image);
} catch (\Throwable $e) {
Log::error('节日有礼公众号推送失败:' . $e->getMessage());
return false;
}
}
/**
* 发送弹框广告
* @param int $uid 用户ID
* @param array $activity 活动信息
* @return bool
*/
protected function sendPopup(int $uid, array $activity): bool
{
try {
// 创建弹框广告记录
$popupData = [
'uid' => $uid,
'title' => '节日有礼',
'image' => $activity['popup_image'] ?: '',
'type' => 'holiday_gift',
'link' => '/pages/activity/holiday_gift/detail?id=' . $activity['id'],
'status' => 1,
'add_time' => time(),
'is_show' => 1,
'sort' => 0
];
// 保存弹框广告记录
return (bool)app()->make(\app\services\user\UserPopupServices::class)->save($popupData);
} catch (\Throwable $e) {
Log::error('节日有礼弹框广告推送失败:' . $e->getMessage());
return false;
}
}
/**
* 获取礼物类型名称
* @param string $giftType
* @return string
*/
protected function getGiftTypeName(string $giftType): string
{
$types = [
'1' => '优惠券',
'2' => '积分',
'3' => '多倍积分',
'4' => '余额',
'5' => '全场包邮'
];
$names = [];
$giftTypes = explode(',', $giftType);
foreach ($giftTypes as $type) {
if (isset($types[$type])) {
$names[] = $types[$type];
}
}
return implode('、', $names) ?: '礼品';
}
}

32
app/jobs/TestJob.php Normal file
View File

@@ -0,0 +1,32 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 测试队列
* Class BatchHandleJob
* @package app\jobs
*/
class TestJob extends BaseJobs
{
use QueueTrait;
public function doJob()
{
\think\facade\Log::error('队列执行了');
return true;
}
}

View File

@@ -0,0 +1,64 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\activity;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
use app\services\activity\live\LiveGoodsServices;
use app\services\activity\live\LiveRoomServices;
/**
* 自动更新直播间状态和直播间产品状态
* Class AutoUpdateLiveJob
* @package app\jobs\live
*/
class AutoUpdateLiveJob extends BaseJobs
{
use QueueTrait;
/**
* @return string
*/
protected static function queueName()
{
return 'CRMEB_PRO_TASK';
}
public function doJob()
{
//更新直播商品状态
try {
/** @var LiveGoodsServices $liveGoods */
$liveGoods = app()->make(LiveGoodsServices::class);
$liveGoods->syncGoodStatus();
} catch (\Throwable $e) {
response_log_write([
'message' => '更新直播商品状态失败,失败原因:[' . class_basename($this) . ']' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
//更新直播间状态
try {
/** @var LiveRoomServices $liveRoom */
$liveRoom = app()->make(LiveRoomServices::class);
$liveRoom->syncRoomStatus();
} catch (\Throwable $e) {
response_log_write([
'message' => '更新直播间状态失败,失败原因:[' . class_basename($this) . ']' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,74 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\activity;
use app\services\activity\holiday\HolidayGiftPushServices;
use app\services\activity\holiday\HolidayGiftRecordServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 节日有礼用户权益处理队列
* Class HolidayGiftJob
* @package app\jobs\activity
*/
class HolidayGiftJob extends BaseJobs
{
use QueueTrait;
/**
* 处理单个用户的节日有礼权益
* @param int $uid 用户ID
* @param array $giftInfo 活动信息
* @return bool
*/
public function doJob(int $uid, array $giftInfo)
{
try {
/** @var HolidayGiftPushServices $holidayGiftPushServices */
$holidayGiftPushServices = app()->make(HolidayGiftPushServices::class);
$holidayGiftRecordServices = app()->make(HolidayGiftRecordServices::class);
//检查是否需要提前推送或当天推送
if (!$holidayGiftPushServices->checkAdvancePush($giftInfo, true, $uid)) {
return true;
}
// 检查用户是否符合活动条件
if (!$holidayGiftPushServices->checkUserCondition($uid, $giftInfo)) {
return true;
}
// 检查是否可以推送(频次限制)
if ($holidayGiftRecordServices->checkUserCanPush($uid, $giftInfo['id'])) {
return true;
}
// 执行赠送权益
$grantResults = $holidayGiftPushServices->grantUserBenefits($uid, $giftInfo);
// 记录推送记录(无论成功失败都要记录)
$holidayGiftPushServices->recordPushLog($uid, $giftInfo);
if ($grantResults) {
Log::info("用户{$uid}节日有礼处理成功,活动ID:{$giftInfo['id']}");
} else {
Log::warning("用户{$uid}节日有礼权益赠送失败,活动ID:{$giftInfo['id']},详情:" . json_encode($grantResults['details']));
}
return true;
} catch (\Exception $e) {
Log::error("用户{$uid}节日有礼处理失败: " . $e->getMessage());
return false;
}
}
}

View File

@@ -0,0 +1,61 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\activity;
use app\services\activity\lottery\LuckLotteryRecordServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 营销:抽奖活动
* Class LuckLotteryJob
* @package app\jobs\activity
*/
class LuckLotteryJob extends BaseJobs
{
use QueueTrait;
/**
* @param $oid
* @param $orderInfo
* @return bool|void
*/
public function updateLotteryRecord($oid, $orderInfo)
{
if (!$oid) {
return true;
}
try {
/** @var LuckLotteryRecordServices $lotteryRecordServices */
$lotteryRecordServices = app()->make(LuckLotteryRecordServices::class);
$data['oid'] = $orderInfo['id'];
$data['is_receive'] = 1;
$data['receive_time'] = time();
$receive_info['name'] = $orderInfo['real_name'];
$receive_info['phone'] = $orderInfo['user_phone'];
if ($orderInfo['shipping_type'] == 2) {
$receive_info['address'] = '';
} else {
$receive_info['address'] = $orderInfo['user_address'];
}
$data['receive_info'] = $receive_info;
$lotteryRecordServices->update($orderInfo['activity_id'], $data, 'id');
} catch (\Throwable $e) {
Log::error('抽奖订单处理中奖记录失败,失败原因:' . $e->getMessage());
}
return true;
}
}

View File

@@ -0,0 +1,72 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\activity;
use app\services\activity\bargain\StoreBargainServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 营销:砍价
* Class StoreBargainJob
* @package app\jobs\activity
*/
class StoreBargainJob extends BaseJobs
{
use QueueTrait;
/**
* 增加砍价统计(查看、分享)
* @param $bargainId
* @param string $field
* @return bool
*/
public function setBargainCount($bargainId, string $field = 'look')
{
try {
/** @var StoreBargainServices $bargainServices */
$bargainServices = app()->make(StoreBargainServices::class);
$bargainServices->addBargain((int)$bargainId, $field);
} catch (\Throwable $e) {
response_log_write([
'message' => '增加砍价统计(查看、分享)失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 下单成功修改砍价状态
* @param int $uid
* @param int $bargainId
* @return bool
*/
public function setBargainUserStatus(int $uid, int $bargainId)
{
try {
/** @var StoreBargainServices $bargainServices */
$bargainServices = app()->make(StoreBargainServices::class);
$bargainServices->setBargainUserStatus($bargainId, $uid);
} catch (\Throwable $e) {
response_log_write([
'message' => '下单成功修改砍价状态失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,92 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\activity;
use app\services\activity\coupon\StoreCouponIssueServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 营销:优惠券
* Class StoreCouponJob
* @package app\jobs\user
*/
class StoreCouponJob extends BaseJobs
{
use QueueTrait;
/**
* 新人礼赠送优惠券
* @param $uid
* @return bool
*/
public function newcomerGiveCoupon($uid)
{
try {
/**@var StoreCouponIssueServices $storeCoupon */
$storeCoupon = app()->make(StoreCouponIssueServices::class);
$storeCoupon->newcomerGiveCoupon((int)$uid);
} catch (\Throwable $e) {
response_log_write([
'message' => '赠送新人礼优惠券失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 会员卡激活赠送优惠券
* @param $uid
* @return bool
*/
public function levelGiveCoupon($uid)
{
try {
/**@var StoreCouponIssueServices $storeCoupon */
$storeCoupon = app()->make(StoreCouponIssueServices::class);
$storeCoupon->levelGiveCoupon((int)$uid);
} catch (\Throwable $e) {
response_log_write([
'message' => '会员卡激活赠送优惠券,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 增加新人券
* @param $uid
* @return bool
*/
public function newUserGiveCoupon($uid)
{
try {
/**@var StoreCouponIssueServices $storeCoupon */
$storeCoupon = app()->make(StoreCouponIssueServices::class);
$storeCoupon->userFirstSubGiveCoupon((int)$uid);
} catch (\Throwable $e) {
response_log_write([
'message' => '赠送新人券失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,189 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\activity;
use app\services\user\UserServices;
use app\services\user\UserBillServices;
use app\services\user\label\UserLabelRelationServices;
use app\services\activity\coupon\StoreCouponIssueServices;
use app\services\activity\promotions\StorePromotionsAuxiliaryServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 营销:优惠活动
* Class StorePromotionsJob
* @package app\jobs\activity
*/
class StorePromotionsJob extends BaseJobs
{
use QueueTrait;
/**
* 赠送
* @param $orderInfo
* @return bool
*/
public function give($orderInfo)
{
$uid = (int)$orderInfo['uid'];
$promotions_give = [];
if (isset($orderInfo['promotions_give']) && $orderInfo['promotions_give']) {
$promotions_give = is_string($orderInfo['promotions_give']) ? json_decode($promotions_give, true) : $orderInfo['promotions_give'];
}
$give_integral = $promotions_give['give_integral'] ?? 0;
if ($give_integral) {
try {
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$userInfo = $userServices->getUserInfo($uid);
/** @var UserBillServices $userBillServices */
$userBillServices = app()->make(UserBillServices::class);
$balance = bcadd((string)$userInfo['integral'], (string)$give_integral, 0);
$userServices->update(['uid' => $userInfo['uid']], ['integral' => $balance]);
$userBillServices->income('order_promotions_give_integral', $uid, (int)$give_integral, (int)$balance, $orderInfo['id']);
} catch (\Throwable $e) {
response_log_write([
'message' => '优惠活动下单赠送积分失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
}
$give_coupon = $promotions_give['give_coupon'] ?? [];
$this->giveCoupon($uid, $give_coupon);
return true;
}
/**
* 赠送优惠券
* @param int $uid
* @param array $give_coupon
* @return bool
*/
public function giveCoupon(int $uid, array $give_coupon)
{
if ($give_coupon) {
try {
/** @var StoreCouponIssueServices $storeCoupon */
$storeCoupon = app()->make(StoreCouponIssueServices::class);
$storeCoupon->orderPayGiveCoupon($uid, $give_coupon);
} catch (\Throwable $e) {
response_log_write([
'message' => '优惠活动下单赠送优惠券失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
}
return true;
}
/**
* 扣除优惠活动赠品限量
* @param array $promotions_give
* @param bool $isDec
* @rerunt bool
*/
public function changeGiveLimit(array $promotions_give, bool $isDec = true)
{
if ($promotions_give){
try {
$promotionsArr = $promotions_give['promotions'] ?? [];
if ($promotionsArr) {
/** @var StorePromotionsAuxiliaryServices $storePromotionsAuxiliaryServices */
$storePromotionsAuxiliaryServices = app()->make(StorePromotionsAuxiliaryServices::class);
$giveCoupon = $promotions_give['give_coupon'] ?? [];
$getPromotionsId = function($id, $key) use ($promotionsArr) {
$pid = 0;
foreach($promotionsArr as $promotions) {
$k = $key == 'coupon_id' ? 'giveCoupon' : 'giveProducts';
$arr = $promotions[$k] ?? [];
$ids = [];
if ($arr) $ids = array_column($arr, $key);
if ($ids && in_array($id, $ids)) $pid = $promotions['id'] ?? $promotionsArr['id'] ?? 0;
}
return $pid;
};
if ($giveCoupon) {
foreach ($giveCoupon as $coupon_id) {
$promotions_id = $getPromotionsId($coupon_id, 'coupon_id');
if ($promotions_id) $storePromotionsAuxiliaryServices->updateLimit([$promotions_id], 2, (int)$coupon_id, $isDec);
}
}
$giveProduct = $promotions_give['give_product'] ?? [];
if ($giveProduct) {
foreach ($giveProduct as $give) {
$promotions_id = (int)$give['promotions_id'] ?? 0;
$product_id = (int)$give['product_id'] ?? 0;
$unique = $give['unique'] ?? '';
$cart_num = (int)$give['cart_num'] ?? 1;
if ($promotions_id && $product_id && $unique) $storePromotionsAuxiliaryServices->updateLimit([$promotions_id], 3, (int)$product_id, $isDec, $unique, $cart_num);
}
}
}
} catch (\Throwable $e) {
response_log_write([
'message' => '订单创建优惠活动赠品限量扣除失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
}
return true;
}
/**
* 设置用户购买的标签
* @param $orderInfo
*/
public function setUserLabel($orderInfo)
{
try {
$promotions_give = [];
if (isset($orderInfo['promotions_give']) && $orderInfo['promotions_give']) {
$promotions_give = is_string($orderInfo['promotions_give']) ? json_decode($promotions_give, true) : $orderInfo['promotions_give'];
}
$promotions = $promotions_give['promotions'] ?? [];
if (!$promotions) {
return true;
}
$labelIds = [];
foreach ($promotions as $key => $value) {
$label_id = is_string($value['label_id']) ? explode(',', $value['label_id']) : $value['label_id'];
$labelIds = array_merge($labelIds, $label_id);
}
if (!$labelIds) {
return true;
}
$labelIds = array_unique($labelIds);
$store_id = $orderInfo['store_id'] ?? 0;
$type = $store_id ? 1 : 0;
/** @var UserLabelRelationServices $labelServices */
$labelServices = app()->make(UserLabelRelationServices::class);
$labelServices->setUserLable([$orderInfo['uid']], $labelIds, $type, $store_id);
} catch (\Throwable $e) {
response_log_write([
'message' => '用户标签添加失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,53 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\activity;
use app\services\activity\video\VideoServices;use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 营销:短视频
* Class VideoJob
* @package app\jobs\activity
*/
class VideoJob extends BaseJobs
{
use QueueTrait;
/**
* 增加短视频浏览播放量
* @param array $ids
* @param int $num
* @return bool
*/
public function setVideoPlayNum(array $ids, int $uid = 0, int $num = 1)
{
if (!$ids) {
return true;
}
try {
/** @var VideoServices $videoServices */
$videoServices = app()->make(VideoServices::class);
foreach ($ids as $id) {
$videoServices->userRelationVideo($uid, (int)$id, 'play', $num);
}
} catch (\Throwable $e) {
response_log_write([
'message' => '增加短视频浏览播放量失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,71 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\activity\card;
use app\services\activity\card\CardBatchServices;
use app\services\activity\card\CardCodeServices;
use app\services\activity\card\CardGiftServices;
use app\services\activity\coupon\StoreCouponIssueServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 营销:礼品卡
* Class CardJob
* @package app\jobs\user
*/
class CardJob extends BaseJobs
{
use QueueTrait;
/**
* 卡密分配数量矫正
* @param $id
* @return bool
*/
public function allocationCode($id)
{
try {
app()->make(CardBatchServices::class)->allocationCode($id);
} catch (\Throwable $e) {
response_log_write([
'message' => '卡密分配数量统计失败:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 校验使用数量
* @param $id
* @return true
* User: liusl
* DateTime: 2025/5/24 10:57
*/
public function allocationCardGift($id)
{
try {
app()->make(CardGiftServices::class)->allocationCardGift($id);
} catch (\Throwable $e) {
response_log_write([
'message' => '卡密分配数量统计失败:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,52 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\activity\pink;
use app\services\activity\combination\StorePinkServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
/**
* 分页处理拼团
* Class AuthPinkFail
* @package app\jobs\pink
*/
class AuthPinkFail extends BaseJobs
{
use QueueTrait;
/**
* @return string
*/
protected static function queueName()
{
return 'CRMEB_PRO_TASK';
}
/**
* @param $page
* @param $limit
* @return bool
* @throws DataNotFoundException
* @throws ModelNotFoundException
*/
public function doJob($page, $limit)
{
/** @var StorePinkServices $service */
$service = app()->make(StorePinkServices::class);
return $service->statusPink((int)$page, (int)$limit);
}
}

View File

@@ -0,0 +1,81 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\activity\pink;
use app\services\activity\combination\StorePinkServices;
use app\services\order\StoreOrderRefundServices;
use app\services\order\StoreOrderServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 拼团失败
* Class PinkJob
* @package app\jobs
*/
class PinkJob extends BaseJobs
{
use QueueTrait;
public function doJob($pinkId)
{
try {
/** @var StorePinkServices $pinkService */
$pinkService = app()->make(StorePinkServices::class);
$info = $pinkService->get((int)$pinkId);
if (!$info) {
return true;
}
//已经成功 || 失败处理
if (in_array($info['status'], [2, 3])) {
return true;
}
[$pinkAll, $pinkT, $count, $idAll, $uidAll] = $pinkService->getPinkMemberAndPinkK($info);
$pinkService->pinkFail($pinkAll, $pinkT, 0);
} catch (\Throwable $e) {
response_log_write([
'message' => '拼团超时处理失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 创建拼团
* @param $orderInfo
* @return bool
*/
public function createPink($orderInfo)
{
if (!$orderInfo) {
return true;
}
try {
/** @var StorePinkServices $pinkServices */
$pinkServices = app()->make(StorePinkServices::class);
/** @var StoreOrderServices $orderServices */
$orderServices = app()->make(StoreOrderServices::class);
$pinkServices->createPink($orderServices->tidyOrder($orderInfo, true));//创建拼团
} catch (\Throwable $e) {
response_log_write([
'message' => '创建拼团失败失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,70 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\agent;
use app\services\agent\AgentLevelServices;
use app\services\user\UserServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 检测分销员等级升级
* Class AgentJob
* @package app\jobs
*/
class AgentJob extends BaseJobs
{
use QueueTrait;
/**
* 执行分销检测升级
* @param $order
* @return bool
*/
public function doJob(int $uid)
{
//检测分销员等级升级
try {
//商城分销是否开启
if (!sys_config('brokerage_func_status')) {
return true;
}
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$userInfo = $userServices->getUserInfo($uid);
if (!$userInfo) {
return true;
}
//检测自己是否是分销员
// $userServices->checkIsAgent($uid);
///获取上级uid || 开启自购返回自己uid
$spread_uid = $userServices->getSpreadUid($uid, $userInfo);
$two_spread_uid = 0;
if ($spread_uid > 0 && $one_user_info = $userServices->getUserInfo($spread_uid)) {
$two_spread_uid = $userServices->getSpreadUid($spread_uid, $one_user_info, false);
}
$uids = array_unique([$uid, $spread_uid, $two_spread_uid]);
/** @var AgentLevelServices $agentLevelServices */
$agentLevelServices = app()->make(AgentLevelServices::class);
//检测升级
$agentLevelServices->checkUserLevelFinish($uid, $uids);
} catch (\Throwable $e) {
response_log_write([
'message' => '检测分销等级升级失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,57 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\agent;
use crmeb\basic\BaseJobs;
use app\services\agent\AgentManageServices;
use crmeb\traits\QueueTrait;
/**
* 自动解除上下级
* Class AutoAgentJob
* @package app\jobs\user
*/
class AutoAgentJob extends BaseJobs
{
use QueueTrait;
/**
* @return string
*/
protected static function queueName()
{
return 'CRMEB_PRO_TASK';
}
/**
* @param $page
* @param $limit
* @param $where
*/
public function doJob($page, $limit, $where)
{
//自动解绑上级绑定
try {
/** @var AgentManageServices $agentManage */
$agentManage = app()->make(AgentManageServices::class);
$agentManage->startRemoveSpread($page, $limit, $where);
} catch (\Throwable $e) {
response_log_write([
'message' => '自动解除上级绑定失败,失败原因:[' . class_basename($this) . ']' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,41 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\agent;
use app\services\agent\AgentManageServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 重置分销有效期
* Class SystemJob
* @package app\jobs
*/
class SystemJob extends BaseJobs
{
use QueueTrait;
/**
* 重置绑定时间
* @return bool
*/
public function resetSpreadTime()
{
/** @var AgentManageServices $agentManage */
$agentManage = app()->make(AgentManageServices::class);
$agentManage->resetSpreadTime();
return true;
}
}

View File

@@ -0,0 +1,84 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\community;
use app\services\community\CommunityCommentServices;
use app\services\community\CommunityRecordServices;
use app\services\community\CommunityServices;
use app\services\community\CommunityUserServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 社区帖子评论
* Class CommunityJob
* @package app\jobs\community
*/
class CommunityCommentJob extends BaseJobs
{
use QueueTrait;
/**
* 用户评论数数据矫正
* @param $id
* @return true
* User: liusl
* DateTime: 2024/9/10 11:08
*/
public function communityCommentSync($id)
{
try {
$communityCommentServices = app()->make(CommunityCommentServices::class);
$communityCommentServices->syncCommentNum($id);
} catch (\Throwable $e) {
response_log_write([
'message' => '用户评论数数据矫正失败:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
public function communityMessage($id)
{
try {
$communityServices = app()->make(CommunityServices::class);
$communityCommentServices = app()->make(CommunityCommentServices::class);
$communityRecordServices = app()->make(CommunityRecordServices::class);
$info = $communityCommentServices->get(['id' => $id, 'is_verify' => 1, 'is_show' => 1, 'is_del' => 0]);
if ($info) {
$relation_id = $communityServices->value(['id' => $info['community_id']], 'relation_id');
$communityRecordServices->save([
'uid' => $info['is_reply'] == 1 ? $relation_id : ($info['reply_id'] ? $info['reply_uid'] : $info['comment_reply_uid']),
'relation_id' => $info['uid'],
'type' => CommunityRecordServices::SET_TYPE_COMMENT,
'link_id' => $info['community_id'],
'comment_id' => $info['id'],
'comment_type' => $info['is_reply'] == 1 ? 1 : 2,
'content' => $info['content'],
'add_time' => time()
]);
}
} catch (\Throwable $e) {
response_log_write([
'message' => '新增帖子评论消息记录失败:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,287 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\community;
use app\services\community\CommunityCacheServices;
use app\services\community\CommunityCommentServices;
use app\services\community\CommunityRecordServices;
use app\services\community\CommunityRelevanceServices;
use app\services\community\CommunityServices;
use app\services\community\CommunityTopicServices;
use app\services\community\CommunityUserServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 社区帖子
* Class CommunityJob
* @package app\jobs\community
*/
class CommunityJob extends BaseJobs
{
use QueueTrait;
/**
* 用户发帖数数据矫正
* @param $id
* @return true
* User: liusl
* DateTime: 2024/9/9 17:56
*/
public function communityUserSync(int $id)
{
try {
/** @var CommunityUserServices $communityUserServices */
$communityUserServices = app()->make(CommunityUserServices::class);
$communityUserServices->syncUserNum($id);
} catch (\Throwable $e) {
response_log_write([
'message' => '用户发帖数数据矫正:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 评价同步社区
* @param $data
* @return true
* User: liusl
* DateTime: 2024/8/27 12:15
*/
public function computedSync(array $data)
{
if (!$data) return true;
try {
/** @var CommunityServices $communityServices */
$communityServices = app()->make(CommunityServices::class);
$data['image'] = $data['slider_image'][0] ?? '';
$data['slider_image'] = json_encode($data['slider_image']);
$data['is_verify'] = sys_config('community_verify', 1) ? 0 : 1;
$data['topic_id'] = [];
$communityServices->saveData($data);
} catch (\Throwable $e) {
response_log_write([
'message' => '商品评价同步到社区失败,错误原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 删除帖子后续
* @param $id
* @return true
* User: liusl
* DateTime: 2024/8/28 16:16
*/
public function communityDelete(int $id)
{
if (!$id) return true;
try {
/** @var CommunityServices $communityServices */
$communityServices = app()->make(CommunityServices::class);
$communityServices->deleteFollow($id);
// //用户发帖数数据矫正
// $this->communityUserSync($id);
} catch (\Throwable $e) {
response_log_write([
'message' => '帖子删除错误,错误原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 帖子评论删除后续操作
* @param $id
* @return true
* User: liusl
* DateTime: 2024/8/28 16:18
*/
public function CommunityCommentDelete(int $id)
{
if (!$id) return true;
try {
/** @var CommunityCommentServices $communityCommentServices */
$communityCommentServices = app()->make(CommunityCommentServices::class);
$communityCommentServices->deleteFollow($id);
} catch (\Throwable $e) {
response_log_write([
'message' => '帖子评论删除错误,错误原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 话题对应帖子数矫正
* @param $id
* @return true
* User: liusl
* DateTime: 2024/11/11 17:58
*/
public function communityTopicSync(int $id)
{
try {
/** @var CommunityServices $communityServices */
$communityServices = app()->make(CommunityServices::class);
$communityServices->syncTopicNum($id);
} catch (\Throwable $e) {
response_log_write([
'message' => '话题帖子数矫正:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* @return void
* User: liusl
* DateTime: 2025/1/2 下午4:53
*/
public function communityTopicStatus(int $id)
{
try {
app()->make(CommunityTopicServices::class)->setStatus($id);
} catch (\Throwable $e) {
response_log_write([
'message' => '用户发贴新增话题:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 发帖增加经验积分
* @param $id
* @return void
* User: liusl
* DateTime: 2024/12/3 上午11:03
*/
public function communityIncome(int $id)
{
try {
$communityServices = app()->make(CommunityServices::class);
$communityServices->giveIncome($id);
} catch (\Throwable $e) {
response_log_write([
'message' => '发帖增加经验积分:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 帖子点赞取消
* @param int $id
* @param int $type 1帖子,2评论
* @param int $status 1点赞 2取消
* @return true
* User: liusl
* DateTime: 2024/12/5 上午11:41
*/
public function communityLike($info, int $uid, int $type, int $status)
{
try {
$communityUserServices = app()->make(CommunityUserServices::class);
$communityCacheServices = app()->make(CommunityCacheServices::class);
$communityRecordServices = app()->make(CommunityRecordServices::class);
$communityServices = app()->make(CommunityServices::class);
$communityCommentServices = app()->make(CommunityCommentServices::class);
if ($type == 1) {
if ($status == 1) {
//帖子点赞数
$communityServices->incUpdate(['id' => $info['id']], 'like_num');
//作者获得点赞数
$communityUserServices->incUpdate(['relation_id' => $info['relation_id']], 'like_num');
//点赞消息记录
if (!$communityRecordServices->get([
'uid' => $info['relation_id'],
'relation_id' => $uid,
'type' => CommunityRecordServices::SET_TYPE_LIKE,
'link_id' => $info['id'],
])) {
$communityRecordServices->save([
'uid' => $info['relation_id'],
'relation_id' => $uid,
'type' => CommunityRecordServices::SET_TYPE_LIKE,
'link_id' => $info['id'],
'comment_type' => 1,
'add_time' => time()
]);
}
} else {
$communityServices->decUpdate(['id' => $info['id']], 'like_num');
$communityUserServices->decUpdate(['relation_id' => $info['relation_id']], 'like_num');
}
$communityCacheServices->setLike($info['id'], $uid, $status);
} else {
if ($status == 1) {
//帖子点赞数
$communityCommentServices->incUpdate(['id' => $info['id']], 'like_num');
if (!$communityRecordServices->get([
'uid' => $info['uid'],
'relation_id' => $uid,
'type' => CommunityRecordServices::SET_TYPE_LIKE,
'comment_type' => 2,
'link_id' => $info['community_id'],
'comment_id' => $info['id'],
])) {
//点赞消息记录
$communityRecordServices->save([
'uid' => $info['uid'],
'relation_id' => $uid,
'type' => CommunityRecordServices::SET_TYPE_LIKE,
'comment_type' => 2,
'link_id' => $info['community_id'],
'comment_id' => $info['id'],
'add_time' => time()
]);
}
} else {
$communityCommentServices->decUpdate(['id' => $info['id']], 'like_num');
}
$communityCacheServices->setLike($info['id'], $uid, $status, CommunityCacheServices::COMMUNITY_COMMENT_LIKE);
}
} catch (\Throwable $e) {
$str = $type == 1 ? '帖子点赞取消' : '帖子评论点赞取消';
response_log_write([
'message' => $str . ':' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,55 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\notice;
use crmeb\basic\BaseJobs;
use crmeb\services\HttpService;
use crmeb\traits\QueueTrait;
class EnterpriseWechatJob extends BaseJobs
{
use QueueTrait;
/**
* 给企业微信群发送消息
*/
public function doJob($data, $url, $ent_wechat_text)
{
try {
$str = $ent_wechat_text;
foreach ($data as $key => $item) {
$str = str_replace('{' . $key . '}', $item, $str);
}
$s = explode('\n', $str);
$d = '';
foreach ($s as $item) {
$d .= $item . "\n>";
}
$d = substr($d, 0, strlen($d) - 2);
$datas = [
'msgtype' => 'markdown',
'markdown' => ['content' => $d]
];
HttpService::postRequest($url, json_encode($datas));
} catch (\Throwable $e) {
response_log_write([
'message' => '发送企业群消息失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,56 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\notice;
use crmeb\basic\BaseJobs;
use crmeb\services\printer\Printer;
use crmeb\traits\QueueTrait;
/**
* 小票打印
* Class PrintJob
* @package app\jobs\notice
*/
class PrintJob extends BaseJobs
{
use QueueTrait;
/**
* 小票打印
* @param $type
* @param $configdata
* @param $order
* @param $product
* @return bool
*/
public function doJob($type, $configdata, $order, $product)
{
try {
$printer = new Printer($type, $configdata);
$printer->setPrinterContent([
'name' => sys_config('site_name'),
'orderInfo' => is_object($order) ? $order->toArray() : $order,
'product' => $product
])->startPrinter();
} catch (\Throwable $e) {
response_log_write([
'message' => '小票打印失败失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,106 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\notice;
use app\services\message\sms\SmsSendServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 短信通知管理员
* Class SmsAdminJob
* @package app\jobs
*/
class SmsAdminJob extends BaseJobs
{
use QueueTrait;
/**
* 退款发送管理员消息任务
* @param $switch
* @param $adminList
* @param $order
* @return bool
*/
public function sendAdminRefund($switch, $adminList, $order)
{
if (!$switch) {
return true;
}
try {
/** @var SmsSendServices $smsServices */
$smsServices = app()->make(SmsSendServices::class);
foreach ($adminList as $item) {
$data = ['order_id' => $order['order_id'], 'admin_name' => $item['nickname']];
$smsServices->send(true, $item['phone'], $data, 'ADMIN_RETURN_GOODS_CODE');
}
} catch (\Throwable $e) {
response_log_write([
'message' => '退款发送管理员消息失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 用户确认收货管理员短信提醒
* @param $switch
* @param $adminList
* @param $order
* @return bool
*/
public function sendAdminConfirmTakeOver($switch, $adminList, $order)
{
if (!$switch) {
return true;
}
try {
/** @var SmsSendServices $smsServices */
$smsServices = app()->make(SmsSendServices::class);
foreach ($adminList as $item) {
$data = ['order_id' => $order['order_id'], 'admin_name' => $item['nickname']];
$smsServices->send(true, $item['phone'], $data, 'ADMIN_TAKE_DELIVERY_CODE');
}
} catch (\Throwable $e) {
response_log_write([
'message' => '用户确认收货管理员短信提醒失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 下单成功给客服管理员发送短信
* @param $switch
* @param $adminList
* @param $order
* @return bool
*/
public function sendAdminPaySuccess($switch, $adminList, $order)
{
if (!$switch) {
return true;
}
/** @var SmsSendServices $smsServices */
$smsServices = app()->make(SmsSendServices::class);
foreach ($adminList as $item) {
$data = ['order_id' => $order['order_id'], 'admin_name' => $item['nickname']];
$smsServices->send(true, $item['phone'], $data, 'ADMIN_PAY_SUCCESS_CODE');
}
return true;
}
}

View File

@@ -0,0 +1,53 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\notice;
use app\services\message\sms\SmsSendServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 短信
* Class SmsJob
* @package app\jobs\notice
*/
class SmsJob extends BaseJobs
{
use QueueTrait;
/**
* 发送短信
* @param $switch
* @param $adminList
* @param $order
* @return bool
*/
public function doJob($phone, array $data, string $template)
{
try {
/** @var SmsSendServices $smsServices */
$smsServices = app()->make(SmsSendServices::class);
$smsServices->send(true, $phone, $data, $template);
} catch (\Throwable $e) {
response_log_write([
'message' => '发送短信消息失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,107 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\notice;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use app\webscoket\SocketPush;
/**
* socket推送
* Class SocketPushJob
* @package app\jobs\system
*/
class SocketPushJob extends BaseJobs
{
use QueueTrait;
/**
* 执行说明
* @var array|string[]
*/
protected array $typeArr = [
'WAIT_DELIVER_ORDER' => '向供应商后台发送待发货订单消息',
'ADMIN_NEW_PUSH' => '后台订单下单,评论,支付成功,后台消息提醒',
'WITHDRAW' => '用户申请提现',
];
/**
* 推送用户类型
* @var array|string[]
*/
protected array $userType = ['admin', 'kefu', 'supplier', 'user'];
/**
* @return mixed
*/
public static function queueName()
{
return 'CRMEB_PRO_SOCKET';
}
/**
* 推送socket 消息
* @param $to
* @param $type
* @param $data
* @param $userType
* @return bool
*/
public function doJob($to, $type, $data, $userType = 'admin')
{
if (!$type) {
return true;
}
if (!in_array($userType, $this->userType)) {
return true;
}
//发送消息
try {
if ($to) {
SocketPush::instance()->to($to)->setUserType($userType)->type($type)->data($data)->push();
} else {
SocketPush::instance()->setUserType($userType)->type($type)->data($data)->push();
}
} catch (\Throwable $e) {
}
return true;
}
/**
* 订单申请退款发送
* @param $order
* @return bool
*/
public function sendApplyRefund($order)
{
if (!$order) {
return true;
}
if ($order['supplier_id']) {
//向门店后台发送退款订单消息
try {
SocketPush::instance()->setUserType('supplier')->to($order['supplier_id'])->data(['order_id' => $order['order_id']])->type('NEW_REFUND_ORDER')->push();
} catch (\Exception $e) {
}
} else {
//向后台发送退款订单消息
try {
SocketPush::admin()->data(['order_id' => $order['order_id']])->type('NEW_REFUND_ORDER')->push();
} catch (\Exception $e) {
}
}
return true;
}
}

View File

@@ -0,0 +1,70 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\notice;
use app\services\message\SystemMessageServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 站内信
* Class SystemMsgJob
* @package app\jobs\notice
*/
class SystemMsgJob extends BaseJobs
{
use QueueTrait;
/**
* 发送站内信
* @param $uid
* @param $noticeInfo
* @param $data
* @param $type
* @return bool
*/
public function doJob($uid, $noticeInfo, $data, $type = 1)
{
if (!$uid || !$noticeInfo) {
return true;
}
try {
$title = $noticeInfo['system_title'];
$str = $noticeInfo['system_text'];
foreach ($data as $key => $item) {
$str = str_replace('{' . $key . '}', $item, $str);
$title = str_replace('{' . $key . '}', $item, $title);
}
$sdata = [];
$sdata['mark'] = $noticeInfo['mark'];
$sdata['uid'] = $uid;
$sdata['content'] = $str;
$sdata['title'] = $title;
$sdata['type'] = $type;
$sdata['add_time'] = time();
/** @var SystemMessageServices $systemMessageServices */
$systemMessageServices = app()->make(SystemMessageServices::class);
$systemMessageServices->save($sdata);
} catch (\Throwable $e) {
response_log_write([
'message' => '发送站内信失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,405 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\notice\template;
use app\services\message\TemplateMessageServices;
use crmeb\basic\BaseJobs;
use crmeb\services\wechat\MiniProgram;
use crmeb\traits\QueueTrait;
use crmeb\services\template\Template;
/**
* 小程序模板消息消息队列
* Class RoutineTemplateJob
* @package app\jobs
*/
class RoutineTemplateJob extends BaseJobs
{
use QueueTrait;
/**
* 同步订阅消息
* @return bool
*/
public function doJob(array $template, array $errMessage)
{
$time = time();
$works = [];
try {
$works = MiniProgram::getSubscribeTemplateKeyWords($template['tempkey']);
} catch (\Throwable $e) {
$wechatErr = $e->getMessage();
if (is_string($wechatErr)) {
response_log_write([
'message' => '同步订阅消息,获取关键词列表失败:' . $wechatErr,
'file' => $e->getFile(),
'line' => $e->getLine()
]);
} elseif (in_array($wechatErr->getCode(), array_keys($errMessage))) {
response_log_write([
'message' => '同步订阅消息,获取关键词列表失败:' . $wechatErr->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
}
$kid = [];
if ($works) {
$works = array_combine(array_column($works, 'name'), $works);
$content = is_array($template['content']) ? $template['content'] : explode("\n", $template['content']);
foreach ($content as $c) {
$name = explode('{{', $c)[0] ?? '';
if ($name && isset($works[$name])) {
$kid[] = $works[$name]['kid'];
}
}
}
if ($kid && isset($template['kid']) && !$template['kid']) {
$tempid = '';
try {
$tempid = MiniProgram::addSubscribeTemplate($template['tempkey'], $kid, $template['name']);
} catch (\Throwable $e) {
$wechatErr = $e->getMessage();
if (is_string($wechatErr)) {
response_log_write([
'message' => '同步订阅消息,添加订阅消息模版失败:' . $wechatErr,
'file' => $e->getFile(),
'line' => $e->getLine()
]);
} elseif (in_array($wechatErr->getCode(), array_keys($errMessage))) {
response_log_write([
'message' => '同步订阅消息,添加订阅消息模版失败:' . $wechatErr->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
}
if ($tempid != $template['tempid']) {
/** @var TemplateMessageServices $templateMessageServices */
$templateMessageServices = app()->make(TemplateMessageServices::class);
$templateMessageServices->update($template['id'], ['tempid' => $tempid, 'kid' => json_encode($kid), 'add_time' => $time], 'id');
}
}
return true;
}
/**
* 确认收货
* @param $openid
* @param $order
* @param $title
* @return bool
*/
public function sendOrderTakeOver($openid, $order, $title)
{
return $this->sendTemplate('ORDER_TAKEVER', $openid, [
'thing1' => $order['order_id'],
'thing2' => mb_substr_str($title, 20),
'date5' => date('Y-m-d H:i:s', time()),
], '/pages/users/order_details/index?order_id=' . $order['order_id']);
}
/**
* @param $openid
* @param $order
* @param $storeTitle
* @param int $isGive 0 = 同城配送, 1 = 快递发货
* @return bool
*/
public function sendOrderPostage($openid, $order, $storeTitle, int $isGive = 0)
{
if ($isGive) {//快递发货
return $this->sendTemplate('ORDER_DELIVER_SUCCESS', $openid, [
'character_string2' => $order['delivery_id'],
'thing1' => mb_substr_str($order['delivery_name'], 20),
'time3' => date('Y-m-d H:i:s', time()),
'thing5' => mb_substr_str($storeTitle, 20),
], '/pages/users/order_details/index?order_id=' . $order['order_id']);
} else {//同城配送
return $this->sendTemplate('ORDER_POSTAGE_SUCCESS', $openid, [
'thing8' => mb_substr_str($storeTitle, 20),
'character_string1' => $order['order_id'],
'name4' => mb_substr_str($order['delivery_name'], 10, '...', 1),
'phone_number10' => $order['delivery_id']
], '/pages/users/order_details/index?order_id=' . $order['order_id']);
}
}
/**
* 充值金额退款
* @param $UserRecharge
* @param $refund_price
* @return bool
*/
public function sendRechargeSuccess($openid, $UserRecharge, $now_money)
{
return $this->sendTemplate('RECHARGE_SUCCESS', $openid, [
'character_string1' => $UserRecharge['order_id'],
'amount3' => $UserRecharge['price'],
'amount4' => $now_money,
'date5' => date('Y-m-d H:i:s', time()),
], '/pages/users/user_bill/index?type=2');
}
/**
* 订单退款成功发送消息
* @param string $openid
* @param array $order
* @return bool
*/
public function sendOrderRefundSuccess($openid, $order, $storeTitle)
{
return $this->sendTemplate('ORDER_REFUND', $openid, [
'thing1' => '已成功退款',
'thing2' => mb_substr_str($storeTitle, 20),
'amount3' => $order['pay_price'],
'character_string6' => $order['order_id']
], '/pages/goods/order_after_details/index?order_id=' . $order['order_id'] . '&isReturen=1');
}
/**
* 订单退款失败
* @param string $openid
* @param $order
* @return bool
*/
public function sendOrderRefundFail($openid, $order, $storeTitle)
{
return $this->sendTemplate('ORDER_REFUND', $openid, [
'thing1' => '退款失败',
'thing2' => mb_substr_str($storeTitle, 20),
'amount3' => $order['pay_price'],
'character_string6' => $order['order_id']
], '/pages/goods/order_after_details/index?order_id=' . $order['order_id'] . '&isReturen=1');
}
/**
* 用户申请退款给管理员发送消息
* @param array $order
* @param string $refundReasonWap
* @param array $adminList
*/
public function sendOrderRefundStatus($openid, $order)
{
$data['character_string4'] = $order['order_id'];
$data['date5'] = date('Y-m-d H:i:s', time());
$data['amount2'] = $order['pay_price'];
$data['phrase7'] = '申请退款中';
$data['thing8'] = '请及时处理';
return $this->sendTemplate('ORDER_REFUND_STATUS', $openid, $data);
}
/**
* 砍价成功通知
* @param array $bargain
* @param array $bargainUser
* @param int $bargainUserId
* @return bool
*/
public function sendBargainSuccess($openid, $bargain = [], $bargainUser = [], $bargainUserId = 0)
{
$data['thing1'] = mb_substr_str($bargain['title'], 20);
$data['amount2'] = $bargain['min_price'];
$data['thing3'] = '恭喜您,已经砍到最低价了';
return $this->sendTemplate('BARGAIN_SUCCESS', $openid, $data, '/pages/activity/goods_bargain_details/index?id=' . $bargain['id'] . '&bargain=' . $bargainUserId);
}
/**
* 订单支付成功发送模板消息
* @param $openidf
* @param $pay_price
* @param $orderId
* @param $payTime
* @return bool|void
*/
public function sendOrderSuccess($openid, $pay_price, $orderId)
{
if ($orderId == '') return true;
$data['character_string1'] = $orderId;
$data['amount2'] = $pay_price . '元';
$data['date3'] = date('Y-m-d H:i:s', time());
return $this->sendTemplate('ORDER_PAY_SUCCESS', $openid, $data, '/pages/users/order_details/index?order_id=' . $orderId);
}
/**
* 会员订单支付成功发送消息
* @param $openid
* @param $pay_price
* @param $orderId
* @return bool
*/
public function sendMemberOrderSuccess($openid, $pay_price, $orderId)
{
if ($orderId == '') return true;
$data['character_string1'] = $orderId;
$data['amount2'] = $pay_price . '元';
$data['date3'] = date('Y-m-d H:i:s', time());
return $this->sendTemplate('ORDER_PAY_SUCCESS', $openid, $data, '/pages/annex/vip_paid/index');
}
/**
* 提现失败
* @param $openid
* @param $msg
* @param $extract_number
* @param $extract_type
* @return bool
*/
public function sendExtractFail($openid, $msg, $extract_number, $nickname)
{
return $this->sendTemplate('USER_EXTRACT', $openid, [
'thing1' => mb_substr_str('提现失败:' . $msg, 20),
'amount2' => $extract_number . '元',
'thing3' => mb_substr_str($nickname, 20),
'date4' => date('Y-m-d H:i:s', time())
], '/pages/users/user_spread_money/index?type=2');
}
/**
* 提现成功
* @param $openid
* @param $extract_number
* @param $nickname
* @return bool
*/
public function sendExtractSuccess($openid, $extract_number, $nickname)
{
return $this->sendTemplate('USER_EXTRACT', $openid, [
'thing1' => '提现成功',
'amount2' => $extract_number . '元',
'thing3' => mb_substr_str($nickname, 20),
'date4' => date('Y-m-d H:i:s', time())
], '/pages/users/user_spread_money/index?type=2');
}
/**
* 拼团成功通知
* @param $uid
* @param $pinkTitle
* @param $nickname
* @param $pinkTime
* @param $count
* @return bool
*/
public function sendPinkSuccess($openid, $pinkTitle, $nickname, $pinkTime, $count, string $link = '')
{
return $this->sendTemplate('PINK_TRUE', $openid, [
'thing1' => mb_substr_str($pinkTitle, 20),
'name3' => mb_substr_str($nickname, 10, '...', 1),
'date5' => date('Y-m-d H:i:s', $pinkTime),
'number2' => $count
], $link);
}
/**
* 拼团状态通知
* @param $openid
* @param $pinkTitle
* @param $count
* @param $remarks
* @return bool
*/
public function sendPinkFail($openid, $pinkTitle, $count, $remarks, $link)
{
return $this->sendTemplate('PINK_STATUS', $openid, [
'thing2' => mb_substr_str($pinkTitle, 20),
'thing1' => mb_substr_str($count, 20),
'thing3' => mb_substr_str($remarks, 20)
], $link);
}
/**
* 赠送积分消息提醒
* @param $openid
* @param $order
* @param $storeTitle
* @param $gainIntegral
* @param $integral
* @return bool
*/
public function sendUserIntegral($openid, $order, $storeTitle, $gainIntegral, $integral)
{
if (!$order || !$openid) return true;
if (is_string($order['cart_id']))
$order['cart_id'] = json_decode($order['cart_id'], true);
return $this->sendTemplate('INTEGRAL_ACCOUT', $openid, [
'character_string2' => $order['order_id'],
'thing3' => mb_substr_str($storeTitle, 20),
'amount4' => $order['pay_price'],
'number5' => $gainIntegral,
'number6' => $integral
], '/pages/users/user_integral/index');
}
/**
* 发送模板消息
* @param string $TempCode 模板消息常量名称
* @param int $openid 用户openid
* @param array $data 模板内容
* @param string $link 跳转链接
* @return bool
*/
public function sendTemplate(string $tempCode, $openid, array $data, string $link = '')
{
try {
if (!$openid) return true;
$template = new Template('subscribe');
$res = $template->to($openid)->url($link)->send($tempCode, $data);
if (!$res) {
response_log_write([
'message' => '订阅消息发送失败,原因:' . $template->getError() . '----参数:' . json_encode(compact('tempCode', 'openid', 'data', 'link'))
]);
}
return true;
} catch (\Exception $e) {
response_log_write([
'message' => '订阅消息发送失败,原因:' . $template->getError() . '----参数:' . json_encode(compact('tempCode', 'openid', 'data', 'link')),
'line' => $e->getLine(),
'file' => $e->getFile()
]);
return true;
}
}
/**
* 获得推广佣金发送提醒
* @param string $openid
* @param string $brokeragePrice
* @param string $goods_name
* @return bool
*/
public function sendOrderBrokerageSuccess(string $openid, string $brokeragePrice, string $goods_name)
{
return $this->sendTemplate('ORDER_BROKERAGE', $openid, [
'thing2' => mb_substr_str($goods_name, 20),
'amount4' => $brokeragePrice . '元',
'time1' => date('Y-m-d H:i:s', time())
], '/pages/users/user_spread_user/index');
}
/**
* 绑定推广关系发送消息提醒
* @param string $openid
* @param string $userName
* @return bool|mixed
*/
public function sendBindSpreadUidSuccess(string $openid, string $userName)
{
$name3 = $userName . "加入您的团队";
return $this->sendTemplate('BIND_SPREAD_UID', $openid, [
'name3' => mb_substr_str($name3, 10, '...', 1),
'date4' => date('Y-m-d H:i:s', time())
], '/pages/users/user_spread_user/index');
}
}

View File

@@ -0,0 +1,77 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\notice\template;
use crmeb\basic\BaseJobs;
use crmeb\services\template\Template;
use crmeb\traits\QueueTrait;
use think\facade\Route;
/**
* Class TemplateJob
* @package app\jobs
*/
class TemplateJob extends BaseJobs
{
use QueueTrait;
/**
* @param $type
* @param $openid
* @param $tempCode
* @param $data
* @param $link
* @param $color
* @return bool|mixed
*/
public function doJob($type, $openid, $tempCode, $data, $link, $color)
{
try {
if (!$openid) return true;
$template = new Template($type ?: 'wechat');
$template->to($openid);
if ($color) {
$template->color($color);
}
if ($link) {
switch ($type) {
case 'wechat':
$link =
sys_config('site_url') . Route::buildUrl($link)
->suffix('')
->domain(false)->build();
break;
}
$template->url($link);
}
$res = $template->send($tempCode, $data);
if (!$res) {
$msg = $type == 'wechat' ? '微信模版消息' : '订阅消息';
response_log_write([
'message' => $msg . '发送失败,原因:' . $template->getError() . '----参数:' . json_encode(compact('tempCode', 'openid', 'data', 'link')),
]);
}
return true;
} catch (\Exception $e) {
response_log_write([
'message' => $msg . '发送失败,原因:' . $template->getError() . '----参数:' . json_encode(compact('tempCode', 'openid', 'data', 'link')),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
return true;
}
}
}

View File

@@ -0,0 +1,463 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\notice\template;
use app\services\message\TemplateMessageServices;
use crmeb\basic\BaseJobs;
use crmeb\services\wechat\OfficialAccount;
use crmeb\traits\QueueTrait;
use crmeb\services\template\Template;
use think\facade\Log;
use think\facade\Route;
/**
* 公众号模版消息
* Class WechatTemplateJob
* @package app\jobs
*/
class WechatTemplateJob extends BaseJobs
{
use QueueTrait;
/**
* 同步模版消息
* @return bool
*/
public function doJob(array $template)
{
if ($template) {
try {
/*
* 删除所有模版ID
*/
//获取微信平台已经添加的模版
$list = OfficialAccount::getPrivateTemplates();//获取所有模版
foreach ($list['template_list'] as $v) {
//删除已有模版
OfficialAccount::deleleTemplate($v['template_id']);
}
/** @var TemplateMessageServices $templateMessageServices */
$templateMessageServices = app()->make(TemplateMessageServices::class);
foreach ($template as $temp) {
$keywordList = [];
$content = is_array($temp['content']) ? $temp['content'] : explode("\n", $temp['content']);
foreach ($content as $c) {
$name = explode('{{', $c)[0] ?? '';
if ($name) {
$keywordList[] = $name;
}
}
if(!$keywordList) continue;
//添加模版消息
$res = OfficialAccount::addTemplateId($temp['tempkey'], $keywordList);
if (!$res['errcode'] && $res['template_id']) {
$templateMessageServices->update($temp['id'], ['tempid' => $res['template_id']]);
}
}
} catch (\Throwable $e) {
response_log_write([
'message' => '同步模版消息失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
}
return true;
}
/**
* 支付成功发送模板消息
* @param $order
* @return bool
*/
public function sendOrderPaySuccess($openid, $order)
{
return $this->sendTemplate('ORDER_PAY_SUCCESS', $openid, [
'first' => '亲,您购买的商品已支付成功',
'keyword1' => $order['order_id'],
'keyword2' => $order['pay_price'],
'remark' => '点击查看订单详情'
], sys_config('site_url') . Route::buildUrl('/pages/users/order_details/index?order_id=' . $order['order_id'])->suffix('')->domain(false)->build());
}
/**
* 购买会员成功
* @param $openid
* @param $order
* @return bool|mixed
*/
public function sendMemberOrderPaySuccess($openid, $order)
{
return $this->sendTemplate('ORDER_PAY_SUCCESS', $openid, [
'first' => '亲,购买会员成功,恭喜您成为本平台尊贵会员!',
'keyword1' => $order['order_id'],
'keyword2' => $order['pay_price'],
'remark' => '点击查看订单详情'
], sys_config('site_url') . Route::buildUrl('/pages/annex/vip_paid/index')->suffix('')->domain(false)->build());
}
/**
* 服务消息(新)
* @param $openid
* @param $data
* @param $url
* @return bool|mixed
*/
public function sendServiceNoticeNew($openid, $data, $url)
{
return $this->sendTemplate('SERVICE_NOTICE_NEW', $openid, [
'first' => $data['first'],
'keyword1' => $data['keyword1'],
'keyword2' => $data['keyword2'],
'keyword3' => $data['keyword3'],
'remark' => $data['remark']
], $url);
}
/**
* 订单发货
* @param $order
* @param array $data
* @return bool|mixed
*/
public function sendOrderDeliver($openid, string $goodsName, $order, array $data)
{
return $this->sendTemplate('ORDER_DELIVER_SUCCESS', $openid, [
'keyword1' => $goodsName,
'keyword2' => $order['pay_type'] == 'offline' ? '线下支付' : date('Y-m-d H:i', $order['pay_time']),
'keyword3' => $order['user_address'],
'keyword4' => $data['delivery_name'],
'keyword5' => $data['delivery_id'],
'first' => '亲,您的订单已发货,请注意查收',
'remark' => '点击查看订单详情'
], sys_config('site_url') . Route::buildUrl('/pages/users/order_details/index?order_id=' . $order['order_id'])->suffix(false)->domain(false)->build());
}
/**
* 订单发货
* @param $order
* @param array $data
* @return bool|mixed
*/
public function sendOrderPostage($openid, $order, array $data)
{
return $this->sendTemplate('ORDER_POSTAGE_SUCCESS', $openid, [
'keyword1' => $order['order_id'],
'keyword2' => $data['delivery_name'],
'keyword3' => $data['delivery_id'],
'first' => '亲,您的订单已发货,请注意查收',
'remark' => '点击查看订单详情'
], sys_config('site_url') . Route::buildUrl('/pages/users/order_details/index?order_id=' . $order['order_id'])->suffix(false)->domain(false)->build());
}
/**
* 发送客服消息
* @param $order
* @param string|null $link
* @return bool
*/
public function sendServiceNotice($openid, $data, ?string $link = null)
{
return $this->sendTemplate('ADMIN_NOTICE', $openid, $data, $link);
}
/**
* 退款发送客服消息
* @param $order
* @param string|null $link
* @return bool
*/
public function sendRefundServiceNotice($openid, $data, ?string $link = null)
{
return $this->sendTemplate('ADMIN_NOTICE', $openid, $data, $link);
}
/**
* 确认收货发送模板消息
* @param $order
* @return bool|mixed
*/
public function sendOrderTakeSuccess($openid, $order, $title)
{
return $this->sendTemplate('ORDER_TAKE_SUCCESS', $openid, [
'first' => '亲,您的订单已收货',
'keyword1' => $order['order_id'],
'keyword2' => '已收货',
'keyword3' => date('Y-m-d H:i:s', time()),
'keyword4' => $title,
'remark' => '感谢您的光临!'
]);
}
/**
* 发送退款申请模板消息
* @param array $data
* @param $order
* @return bool|mixed
*/
public function sendOrderApplyRefund($openid, $order)
{
return $this->sendTemplate('ORDER_REFUND_STATUS', $openid, [
'amount2' => bcadd((string)$order['pay_price'],'0',2),
'time4' => date('Y-m-d H:i:s', $order['add_time']),
'character_string5' => $order['order_id']
], sys_config('site_url') . Route::buildUrl('/pages/users/order_details/index?order_id=' . $order['order_id'])->suffix('')->domain(false)->build());
}
/**
* 发送退款模板消息
* @param array $data
* @param $order
* @return bool|mixed
*/
public function sendOrderRefundSuccess($openid, array $data, $order)
{
return $this->sendTemplate('ORDER_REFUND_STATUS', $openid, [
'first' => '亲,您购买的商品已退款,本次退款' . $data['refund_price'] . '金额',
'keyword1' => $order['order_id'],
'keyword2' => $order['pay_price'],
'keyword3' => date('Y-m-d H:i:s', $order['add_time']),
'remark' => '点击查看订单详情'
], sys_config('site_url') . Route::buildUrl('/pages/users/order_details/index?order_id=' . $order['order_id'] . '&isReturen=1')->suffix('')->domain(false)->build());
}
/**
* 发送退款模板消息
* @param array $data
* @param $order
* @return bool|mixed
*/
public function sendOrderRefundNoStatus($openid, $order)
{
return $this->sendTemplate('ORDER_REFUND_STATUS', $openid, [
'first' => '亲,您的退款申请未申请通过',
'keyword1' => $order['order_id'],
'keyword2' => $order['pay_price'],
'keyword3' => date('Y-m-d H:i:s', $order['add_time']),
'remark' => '点击查看订单详情'
], sys_config('site_url') . Route::buildUrl('/pages/users/order_details/index?order_id=' . $order['order_id'])->suffix('')->domain(false)->build());
}
/**
* 发送用户充值退款模板消息
* @param array $data
* @param $userRecharge
* @return bool|mixed
*/
public function sendRechargeRefundStatus($openid, array $data, $userRecharge)
{
return $this->sendTemplate('ORDER_REFUND_STATUS', $openid, [
'first' => '亲,您充值的金额已退款,本次退款' .
$data['refund_price'] . '金额',
'keyword1' => $userRecharge['order_id'],
'keyword2' => $userRecharge['price'],
'keyword3' => date('Y-m-d H:i:s', $userRecharge['add_time']),
'remark' => '点击查看订单详情'
], sys_config('site_url') . Route::buildUrl('/pages/users/user_bill/index')->domain(false)->suffix(false)->build());
}
/**
* 佣金提现失败发送模板消息
* @param $uid
* @param $extract_number
* @param $fail_msg
* @return bool|mixed
*/
public function sendUserBalanceChangeFial($openid, $extract_number, $fail_msg)
{
return $this->sendTemplate('USER_BALANCE_CHANGE', $openid, [
'first' => '提现失败,退回佣金' . $extract_number . '元',
'keyword1' => '佣金提现',
'keyword2' => date('Y-m-d H:i:s', time()),
'keyword3' => $extract_number,
'remark' => '错误原因:' . $fail_msg
], sys_config('site_url') . Route::buildUrl('/pages/users/user_spread_money/index?type=1')->suffix(false)->domain(false)->build());
}
/**
* 佣金提现成功发送模板消息
* @param $uid
* @param $extractNumber
* @return bool|mixed
*/
public function sendUserBalanceChangeSuccess($openid, $extractNumber)
{
return $this->sendTemplate('USER_BALANCE_CHANGE', $openid, [
'first' => '成功提现佣金' . $extractNumber . '元',
'keyword1' => '佣金提现',
'keyword2' => date('Y-m-d H:i:s', time()),
'keyword3' => $extractNumber,
'remark' => '点击查看我的佣金明细'
], sys_config('site_url') . Route::buildUrl('/pages/users/user_spread_money/index?type=1')->suffix(false)->domain(false)->build());
}
/**
* 拼团成功发送模板消息
* @param $uid
* @param $order_id
* @param $title
* @return bool|mixed
*/
public function sendOrderPinkSuccess($openid, $order_id, $pinkId, $title)
{
return $this->sendTemplate('ORDER_USER_GROUPS_SUCCESS', $openid, [
'first' => '亲,您的拼团已经完成了',
'keyword1' => $order_id,
'keyword2' => $title,
'remark' => '点击查看订单详情'
], sys_config('site_url') . Route::buildUrl('/pages/activity/goods_combination_status/index?id=' . $pinkId)->suffix(false)->domain(false)->build());
}
/**
* 参团成功发送模板消息
* @param $uid
* @param $order_id
* @param $title
* @return bool|mixed
*/
public function sendOrderPinkUseSuccess($openid, string $order_id, string $title, int $pink_id)
{
return $this->sendTemplate('ORDER_USER_GROUPS_SUCCESS', $openid, [
'first' => '亲,您已成功参与拼团',
'keyword1' => $order_id,
'keyword2' => $title,
'remark' => '点击查看订单详情'
], sys_config('site_url') . Route::buildUrl('/pages/activity/goods_combination_status/index?id=' . $pink_id)->suffix(false)->domain(false)->build());
}
/**
* 取消拼团发送模板消息
* @param $uid
* @param StorePink $order_id
* @param $price
* @param string $title
* @return bool|mixed
*/
public function sendOrderPinkClone($openid, $pink, $title)
{
return $this->sendTemplate('ORDER_USER_GROUPS_LOSE', $openid, [
'first' => '亲,您的拼团取消',
'keyword1' => $title,
'keyword2' => $pink->price,
'keyword3' => $pink->price,
'remark' => '点击查看订单详情'
], sys_config('site_url') . Route::buildUrl('/pages/activity/goods_combination_status/index?id=' . $pink->id)->suffix(false)->domain(false)->build());
}
/**
* 拼团失败发送模板消息
* @param $uid
* @param StorePink $pink
* @param $title
* @return bool|mixed
*/
public function sendOrderPinkFial($openid, $pink, $title)
{
return $this->sendTemplate('ORDER_USER_GROUPS_LOSE', $openid, [
'first' => '亲,您的拼团失败',
'keyword1' => $title,
'keyword2' => $pink->price,
'keyword3' => $pink->price,
'remark' => '点击查看订单详情'
], sys_config('site_url') . Route::buildUrl('/pages/activity/goods_combination_status/index?id=' . $pink->id)->suffix(false)->domain(false)->build());
}
/**
* 开团成功发送模板消息
* @param $uid
* @param StorePink $pink
* @param $title
* @return bool|mixed
*/
public function sendOrderPinkOpenSuccess($openid, $pink, $title)
{
return $this->sendTemplate('OPEN_PINK_SUCCESS', $openid, [
'first' => '您好,您已成功开团!赶紧与小伙伴们分享吧!!!',
'keyword1' => $title,
'keyword2' => $pink['total_price'],
'keyword3' => $pink['people'],
'remark' => '点击查看订单详情'
], sys_config('site_url') . Route::buildUrl('/pages/activity/goods_combination_status/index?id=' . $pink['id'])->suffix(false)->domain(false)->build());
}
/**
* 砍价成功发送模板消息
* @param $uid
* @param StoreBargain $bargain
* @return bool|mixed
*/
public function sendBargainSuccess($openid, $bargain, $bargainUser = [], $bargainUserId = 0)
{
return $this->sendTemplate('BARGAIN_SUCCESS', $openid, [
'first' => '好腻害!你的朋友们已经帮你砍到底价了!',
'keyword1' => $bargain['title'],
'keyword2' => $bargain['min_price'],
'remark' => '点击查看订单详情'
], sys_config('site_url') . Route::buildUrl('/pages/activity/goods_bargain_details/index?id=' . $bargain['id'] . '&bargain=' . $bargainUserId)->suffix(false)->domain(false)->build());
}
/**
* 发送模板消息
* @param string $tempCode 模板消息常量名称
* @param $uid 用户uid
* @param array $data 模板内容
* @param string $link 跳转链接
* @param string|null $color 文字颜色
* @return bool|mixed
*/
public function sendTemplate(string $tempCode, $openid, array $data, string $link = null, string $color = null)
{
try {
if (!$openid) return true;
$template = new Template('wechat');
$template->to($openid)->color($color);
if ($link) $template->url($link);
return $template->send($tempCode, $data);
} catch (\Exception $e) {
Log::error('发送模版消息失败,原因:' . $e->getMessage());
return true;
}
}
/**
* 佣金到账发送模板消息
* @param $order
* @return bool
*/
public function sendOrderBrokerageSuccess(string $openid, string $brokeragePrice, string $goodsName, string $goodsPrice, $orderTime)
{
return $this->sendTemplate('ORDER_BROKERAGE', $openid, [
'first' => '亲,您有一笔佣金入账!',
'keyword1' => $goodsName,
'keyword2' => $goodsPrice . "元",
'keyword3' => $brokeragePrice . "元",
'keyword4' => date('Y-m-d H:i:s', $orderTime),
'remark' => '点击查看订单详情'
], sys_config('site_url') . Route::buildUrl('/pages/users/user_spread_user/index')->suffix('')->domain(false)->build());
}
/** 绑定推广关系发送消息提醒
* @param string $openid
* @param string $userName
* @return bool|mixed
*/
public function sendBindSpreadUidSuccess(string $openid, string $userName)
{
return $this->sendTemplate('BIND_SPREAD_UID', $openid, [
'first' => '恭喜,又一员猛将将永久绑定到您的团队',
'keyword1' => $userName . "加入您的团队",
'keyword2' => date('Y-m-d H:i:s', time()),
'remark' => '授人以鱼不如授人以渔,一起分享赚钱吧,点击查看详情!'
], sys_config('site_url') . Route::buildUrl('/pages/users/user_spread_user/index')->suffix('')->domain(false)->build());
}
}

View File

@@ -0,0 +1,58 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\order;
use app\services\order\StoreOrderCommentServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 自动执行默认好评
* Class AutoCommentOrderJob
* @package app\jobs\order
*/
class AutoCommentOrderJob extends BaseJobs
{
use QueueTrait;
/**
* @return string
*/
protected static function queueName()
{
return 'CRMEB_PRO_TASK';
}
/**
* @param $where
* @param $page
* @param $limit
* @return bool
*/
public function doJob($where, $page, $limit)
{
try {
/** @var StoreOrderCommentServices $service */
$service = app()->make(StoreOrderCommentServices::class);
$service->runAutoCommentOrder($where, $page, $limit);
} catch (\Throwable $e) {
response_log_write([
'message' => '自动默认好评,失败原因:[' . class_basename($this) . ']' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,58 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\order;
use app\services\order\StoreOrderTakeServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 自动执行确认收货
* Class AutoTakeOrderJob
* @package app\jobs\order
*/
class AutoTakeOrderJob extends BaseJobs
{
use QueueTrait;
/**
* @return string
*/
protected static function queueName()
{
return 'CRMEB_PRO_TASK';
}
/**
* @param $where
* @param $page
* @param $limit
* @return bool
*/
public function doJob($where, $page, $limit)
{
try {
/** @var StoreOrderTakeServices $service */
$service = app()->make(StoreOrderTakeServices::class);
$service->runAutoTakeOrder($where, $page, $limit);
} catch (\Throwable $e) {
response_log_write([
'message' => '自动执行确认收货,失败原因:[' . class_basename($this) . ']' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,51 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\order;
use app\services\order\StoreDeliveryOrderServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 同城配送
* Class CityDeliveryJob
* @package app\jobs
*/
class CityDeliveryJob extends BaseJobs
{
use QueueTrait;
/**
* 同步创建、更新达达门店信息
* @param $id
* @param $is_new
* @return bool
*/
public function syncCityShop($id, $is_new)
{
try {
/** @var StoreDeliveryOrderServices $deliveryOrderServices */
$deliveryOrderServices = app()->make(StoreDeliveryOrderServices::class);
$deliveryOrderServices->syncCityShop((int)$id);
} catch (\Throwable $e) {
response_log_write([
'message' => '同步创建同城配送达达门店失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,53 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\order;
use app\services\order\StoreOrderInvoiceServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 支付成功创建发票信息
* Class CreateInvoiceJob
* @package app\jobs\order
*/
class CreateInvoiceJob extends BaseJobs
{
use QueueTrait;
/**
* @param $orderInfo
* @return bool
*/
public function doJob(int $uid, int $order_id, $invoice_id)
{
if (!$uid || !$order_id || !$invoice_id) {
return true;
}
try {
//创建开票数据
/** @var StoreOrderInvoiceServices $storeOrderInvoiceServices */
$storeOrderInvoiceServices = app()->make(StoreOrderInvoiceServices::class);
$storeOrderInvoiceServices->makeUp($uid, $order_id, $invoice_id);
} catch (\Throwable $e) {
response_log_write([
'message' => '创建订单发票信息失败失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace app\jobs\order;
use crmeb\basic\BaseJobs;
use crmeb\services\wechat\MiniProgram;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 小程序订单处理
*/
class MiniOrderJob extends BaseJobs
{
use QueueTrait;
/**
* @param string $out_trade_no
* @param int $logistics_type
* @param array $shipping_list
* @param string $payer_openid
* @param string $path
* @param int $delivery_mode
* @param bool $is_all_delivered
* @return bool
*/
public function doJob(string $out_trade_no, int $logistics_type, array $shipping_list, string $payer_openid, string $path, int $delivery_mode = 1, bool $is_all_delivered = true)
{
try {
\think\facade\Log::info('小程序订单处理开始,订单号:' . $out_trade_no);
MiniProgram::shippingByTradeNo($out_trade_no, $logistics_type, $shipping_list, $payer_openid, $path, $delivery_mode, $is_all_delivered);
} catch (\Throwable $e) {
Log::error('小程序订单处理失败,原因:' . $e->getMessage());
}
return true;
}
}

View File

@@ -0,0 +1,161 @@
<?php
namespace app\jobs\order;
use app\services\order\StoreOrderCartInfoServices;
use app\services\order\StoreOrderCreateServices;
use app\services\order\StoreOrderComputedServices;
use app\services\user\UserServices;
use crmeb\basic\BaseJobs;
use crmeb\services\CacheService;
use crmeb\traits\QueueTrait;
/**
* 订单创建
* Class OrderCreateAfterJob
* @package app\jobs
*/
class OrderCreateAfterJob extends BaseJobs
{
use QueueTrait;
/**
* 清理订单确认生成缓存
* @param int $uid
* @param string $unique
* @param string $key
* @return bool
*/
public function delOrderCache(int $uid, string $unique, string $key = 'user_order_')
{
CacheService::redisHandler()->delete($key . $uid . $unique);
return true;
}
/**
* 设置默认地址、更新自提人信息
* @return bool
*/
public function updateUser($orderInfo, $group, $userInfo)
{
try {
/** @var StoreOrderCreateServices $orderCreate */
$orderCreate = app()->make(StoreOrderCreateServices::class);
$orderCreate->updateUserAddress($orderInfo, $group);
} catch (\Throwable $e) {
response_log_write([
'message' => '设置用户默认地址信息失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
try {
$uid = $orderInfo['uid'] ?? 0;
//记录自提人电话和姓名
if ($uid && ($userInfo['real_name'] != $orderInfo['real_name'] || $userInfo['record_phone'] != $orderInfo['user_phone'])) {
/** @var UserServices $userService */
$userService = app()->make(UserServices::class);
$userService->update(['uid' => $uid], ['real_name' => $orderInfo['real_name'], 'record_phone' => $orderInfo['user_phone']]);
}
} catch (\Throwable $e) {
response_log_write([
'message' => '更新用户自提人信息失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 删除购物车
* @return bool
*/
public function delCart($group)
{
try {
/** @var StoreOrderCreateServices $orderCreate */
$orderCreate = app()->make(StoreOrderCreateServices::class);
$orderCreate->delCart($group);
} catch (\Throwable $e) {
response_log_write([
'message' => '删除购物车失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 订单后置处理
* @param $userInfo
* @param $orderInfo
* @param $data
* @param $activity
* @return bool
*/
public function compute($userInfo, $orderInfo, $data, $activity)
{
if (($orderInfo['uid'] && !$userInfo) || !$orderInfo) {
return true;
}
$uid = (int)$orderInfo['uid'];
$orderId = (int)$orderInfo['id'];
try {
$spread_uid = $spread_two_uid = 0;
$cartInfo = $data['cartInfo'] ?? [];
$priceData = $data['priceData'] ?? [];
$addressId = $data['addressId'] ?? 0;
/** @var StoreOrderCreateServices $createService */
$createService = app()->make(StoreOrderCreateServices::class);
$spread_ids = [];
if ($cartInfo && $priceData) {
/** @var StoreOrderCartInfoServices $cartServices */
$cartServices = app()->make(StoreOrderCartInfoServices::class);
[$cartInfo, $spread_ids] = $createService->computeOrderProductTruePrice($orderInfo, $cartInfo, $priceData, $uid, $userInfo);
$cartServices->updateCartInfo($orderId, $cartInfo);
}
$orderData = [];
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
if ($spread_ids) {
[$spread_uid, $spread_two_uid] = $spread_ids;
$orderData['spread_uid'] = $spread_uid;
$orderData['spread_two_uid'] = $spread_two_uid;
} else {
$spread_uid = $userServices->getSpreadUid($uid);
if ($spread_uid > 0 && sys_config('brokerage_level', 2) == 2) {
$spread_two_uid = $userServices->getSpreadUid($spread_uid, [], false);
}
}
if ($spread_uid > 0) {
$orderData['spread_uid'] = $spread_uid;
}
if ($spread_two_uid > 0) {
$orderData['spread_two_uid'] = $spread_two_uid;
}
if ($cartInfo && (isset($activity['type']) && $activity['type'] == 0)) {
/** @var StoreOrderComputedServices $orderComputed */
$orderComputed = app()->make(StoreOrderComputedServices::class);
if ($userServices->checkUserPromoter($spread_uid)) $orderData['one_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'one_brokerage', false);
if ($userServices->checkUserPromoter($spread_two_uid)) $orderData['two_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'two_brokerage', false);
$orderData['division_staff_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'division_staff_brokerage', false);
$orderData['division_agent_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'division_agent_brokerage', false);
$orderData['division_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'division_brokerage', false);
}
if ($orderData) $createService->update(['id' => $orderId], $orderData);
} catch (\Throwable $e) {
response_log_write([
'message' => '计算订单实际优惠、积分、邮费、佣金失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,53 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\order;
use app\services\order\StoreOrderDeliveryServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 订单发货
* Class OrderDeliveryJob
* @package app\jobs
*/
class OrderDeliveryJob extends BaseJobs
{
use QueueTrait;
/**
* 确认收货
* @param $orderInfo
* @param $data
* @param $type
* @return bool
*/
public function doJob($orderInfo, $data, $type)
{
try {
/** @var StoreOrderDeliveryServices $storeOrderDeliveryServices */
$storeOrderDeliveryServices = app()->make(StoreOrderDeliveryServices::class);
$data['type'] = $type;
$storeOrderDeliveryServices->doDelivery((int)$orderInfo['id'], $orderInfo, $data);
} catch (\Throwable $e) {
response_log_write([
'message' => '收银台订单自动发货失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

429
app/jobs/order/OrderJob.php Normal file
View File

@@ -0,0 +1,429 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\order;
use app\jobs\user\UserLevelJob;
use app\services\activity\discounts\StoreDiscountsServices;
use app\services\activity\bargain\StoreBargainServices;
use app\services\activity\combination\StoreCombinationServices;
use app\services\activity\seckill\StoreSeckillServices;
use app\services\activity\coupon\StoreCouponUserServices;
use app\services\message\service\StoreServiceServices;
use app\services\message\sms\SmsSendServices;
use app\services\order\StoreOrderCartInfoServices;
use app\services\order\StoreOrderComputedServices;
use app\services\order\StoreOrderCreateServices;
use app\services\order\StoreOrderEconomizeServices;
use app\services\order\StoreOrderServices;
use app\services\product\product\StoreProductServices;
use app\services\user\member\MemberCardServices;
use app\services\user\label\UserLabelRelationServices;
use app\services\user\UserServices;
use app\services\wechat\WechatUserServices;
use app\webscoket\SocketPush;
use crmeb\basic\BaseJobs;
use crmeb\services\wechat\Messages;
use crmeb\services\wechat\OfficialAccount;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 订单消息队列
* Class OrderJob
* @package app\jobs
*/
class OrderJob extends BaseJobs
{
use QueueTrait;
/**
* 执行订单支付成功发送消息
* @param $order
* @return bool
*/
public function otherTake($order)
{
if ($order['supplier_id']) {
//向门店后台发送新订单消息
try {
SocketPush::supplier()->to($order['supplier_id'])->type('NEW_ORDER')->data(['order_id' => $order['order_id']])->push();
} catch (\Throwable $e) {
response_log_write([
'message' => '向后台发送新订单消息失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
} else {
//向后台发送新订单消息
try {
SocketPush::admin()->type('NEW_ORDER')->data(['order_id' => $order['order_id']])->push();
} catch (\Throwable $e) {
response_log_write([
'message' => '向后台发送新订单消息失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
}
return true;
}
/**
* 设置用户购买次数和检测时候成为推广人
* @param $order
*/
public function setUserPayCountAndPromoter($order)
{
try {
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$userInfo = $userServices->get($order['uid']);
if ($userInfo) {
$userInfo->pay_count = $userInfo->pay_count + 1;
if (!$userInfo->is_promoter) {
/** @var StoreOrderServices $orderServices */
$orderServices = app()->make(StoreOrderServices::class);
$price = $orderServices->sum(['pid' => 0, 'paid' => 1, 'refund_status' => 0, 'uid' => $userInfo['uid']], 'pay_price');
$status = is_brokerage_statu($price);
if ($status) {
$userInfo->is_promoter = 1;
}
}
$userInfo->save();
}
} catch (\Throwable $e) {
response_log_write([
'message' => '更新用户订单数失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 设置用户购买的标签
* @param $order
*/
public function setUserLabel($order)
{
try {
/** @var StoreOrderCartInfoServices $cartInfoServices */
$cartInfoServices = app()->make(StoreOrderCartInfoServices::class);
$cartInfos = $cartInfoServices->getCartColunm(['oid' => $order['id']], 'cart_info');
$cartInfo = [];
foreach ($cartInfos as $cart) {
$cartInfo[] = is_string($cart) ? json_decode($cart, true) : $cart;
}
$productIds = array_unique(array_column($cartInfo, 'product_id'));
/** @var StoreProductServices $productServices */
$productServices = app()->make(StoreProductServices::class);
$label = $productServices->getColumn([['id', 'in', $productIds]], 'label_id');
$labelIds = [];
if ($label) {
$labelIds = explode(',', implode(',', $label));
}
if ($order['type'] == 5 && $order['activity_id']) {
/** @var StoreDiscountsServices $storeDiscountsServices */
$storeDiscountsServices = app()->make(StoreDiscountsServices::class);
$discounts_label = $storeDiscountsServices->value(['id' => $order['activity_id']], 'link_ids');
if ($discounts_label) {
$labelIds = array_merge($labelIds, explode(',', $discounts_label));
}
}
if (!$labelIds) {
return true;
}
$store_id = $order['store_id'] ?? 0;
$type = $store_id ? 1 : 0;
$labelIds = array_unique($labelIds);
/** @var UserLabelRelationServices $labelServices */
$labelServices = app()->make(UserLabelRelationServices::class);
$labelServices->setUserLable([$order['uid']], $labelIds, $type, $store_id);
} catch (\Throwable $e) {
response_log_write([
'message' => '用户标签添加失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 发送模板消息和客服消息
* @param $order
* @return bool
*/
public function sendServicesAndTemplate($order)
{
try {
if (in_array($order['is_channel'], [1, 2])) {//小程序发送模板消息
//订单支付成功后给客服发送客服消息
$this->sendOrderPaySuccessCustomerService($order, 0);
} else {//公众号发送模板消息
//订单支付成功后给客服发送客服消息
$this->sendOrderPaySuccessCustomerService($order, 1);
}
} catch (\Exception $e) {
response_log_write([
'message' => '发送客服消息,短信消息失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 订单支付成功后给客服发送客服消息
* @param $order
* @param int $type 1 公众号 0 小程序
* @return string
*/
public function sendOrderPaySuccessCustomerService($order, $type = 0)
{
/** @var StoreServiceServices $services */
$services = app()->make(StoreServiceServices::class);
/** @var WechatUserServices $wechatUserServices */
$wechatUserServices = app()->make(WechatUserServices::class);
$serviceOrderNotice = $services->getStoreServiceOrderNotice();
if (count($serviceOrderNotice)) {
/** @var StoreProductServices $services */
$services = app()->make(StoreProductServices::class);
/** @var StoreSeckillServices $seckillServices */
$seckillServices = app()->make(StoreSeckillServices::class);
/** @var StoreCombinationServices $pinkServices */
$pinkServices = app()->make(StoreCombinationServices::class);
/** @var StoreBargainServices $bargainServices */
$bargainServices = app()->make(StoreBargainServices::class);
/** @var StoreOrderCartInfoServices $cartInfoServices */
$cartInfoServices = app()->make(StoreOrderCartInfoServices::class);
/** @var SmsSendServices $smsServices */
// $smsServices = app()->make(SmsSendServices::class);
// $switch = (bool)sys_config('admin_pay_success_switch');
$description = '';
$image = sys_config('site_logo');
switch ($order['type']) {
case 1://秒杀
$description .= '秒杀商品:' . $seckillServices->value(['id' => $order['activity_id']], 'title');
$image = $seckillServices->value(['id' => $order['activity_id']], 'image');
break;
case 2://砍价
$description .= '砍价商品:' . $bargainServices->value(['id' => $order['activity_id']], 'title');
$image = $bargainServices->value(['id' => $order['activity_id']], 'image');
break;
case 3://拼团
$description .= '拼团商品:' . $pinkServices->value(['id' => $order['activity_id']], 'title');
$image = $pinkServices->value(['id' => $order['activity_id']], 'image');
break;
default:
$productIds = $cartInfoServices->getCartIdsProduct((int)$order['id']);
$storeProduct = $services->getColumn([['id', 'in', $productIds]], 'image,store_name', 'id');
if (count($storeProduct)) {
foreach ($storeProduct as $value) {
$description .= $value['store_name'] . ' ';
$image = $value['image'];
}
}
break;
}
foreach ($serviceOrderNotice as $key => $item) {
$userInfo = $wechatUserServices->getOne(['uid' => $item['uid'], 'user_type' => 'wechat']);
if ($userInfo) {
$userInfo = $userInfo->toArray();
if ($userInfo['subscribe'] && $userInfo['openid']) {
if ($item['customer']) {
// 统计管理开启 推送图文消息
$head = '订单提醒 订单号:' . $order['order_id'];
$url = sys_config('site_url') . '/pages/admin/orderDetail/index?id=' . $order['order_id'];
$message = Messages::newsMessage($head, $description, $url, $image);
try {
OfficialAccount::staffSend($message, $userInfo['openid']);
} catch (\Exception $e) {
response_log_write([
'message' => $userInfo['nickname'] . '发送失败' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
} else {
// 推送文字消息
$head = "客服提醒:亲,您有一个新订单 \r\n订单单号:{$order['order_id']}\r\n支付金额:¥{$order['pay_price']}\r\n备注信息:{$order['mark']}\r\n订单来源:小程序";
if ($type) $head = "客服提醒:亲,您有一个新订单 \r\n订单单号:{$order['order_id']}\r\n支付金额:¥{$order['pay_price']}\r\n备注信息:{$order['mark']}\r\n订单来源:公众号";
try {
OfficialAccount::staffSend($head, $userInfo['openid']);
} catch (\Exception $e) {
response_log_write([
'message' => $userInfo['nickname'] . '发送失败' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
}
}
}
}
}
return true;
}
/**
* 计算节约金额
* @param $order
*/
public function setEconomizeMoney($order)
{
try {
/** @var UserServices $userService */
$userService = app()->make(UserServices::class);
/** @var StoreOrderCartInfoServices $cartInfoService */
$cartInfoService = app()->make(StoreOrderCartInfoServices::class);
/** @var StoreCouponUserServices $couponService */
$couponService = app()->make(StoreCouponUserServices::class);
/** @var StoreOrderEconomizeServices $economizeService */
$economizeService = app()->make(StoreOrderEconomizeServices::class);
/** @var MemberCardServices $memberCardService */
$memberCardService = app()->make(MemberCardServices::class);
$getOne = $economizeService->getOne(['order_id' => $order['order_id']]);
if ($getOne) return false;
//看是否是会员
if ($userService->checkUserIsSvip((int)$order['uid'])) {
$save = [];
$save['order_type'] = 1;
$save['add_time'] = time();
$save['pay_price'] = $order['pay_price'];
$save['order_id'] = $order['order_id'];
$save['uid'] = $order['uid'];
//计算商品节约金额
$isOpenVipPrice = $memberCardService->isOpenMemberCardCache('vip_price');
if ($isOpenVipPrice) {
$cartInfo = $cartInfoService->getOrderCartInfo($order['id']);
$memberPrice = 0.00;
if ($cartInfo) {
foreach ($cartInfo as $k => $item) {
foreach ($item as $value) {
if (isset($value['price_type']) && $value['price_type'] == 'member') $memberPrice = bcadd((string)$memberPrice, (string)bcmul((string)$value['vip_truePrice'], (string)$value['cart_num'] ?: '1', 2), 2);
}
}
}
$save['member_price'] = $memberPrice;
}
//计算邮费节约金额
$isOpenExpress = $memberCardService->isOpenMemberCardCache('express');
if ($isOpenExpress) {
$expressTotalMoney = bcdiv($order['total_postage'], bcdiv($isOpenExpress, 100, 2), 2);
$save['postage_price'] = bcsub($expressTotalMoney, $order['total_postage'], 2);
}
//计算会员券节省金额
if ($order['coupon_id'] && $order['coupon_price']) {
$coupon = $couponService->getOne(['id' => $order['coupon_id']], '*', ['issue']);
//是会员券
if ($coupon && $coupon['category'] == 2) {
$save['coupon_price'] = $order['coupon_price'];
}
}
return $economizeService->addEconomize($save);
}
} catch (\Throwable $e) {
response_log_write([
'message' => '计算节省金额,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
public function compute($uid, $oid)
{
if (!$oid) {
return true;
}
/** @var StoreOrderCreateServices $createService */
$createService = app()->make(StoreOrderCreateServices::class);
$orderInfo = $createService->get($oid);
if (!$orderInfo || $uid != $orderInfo['uid']) {
return true;
}
try {
$uid = (int)$orderInfo['uid'];
$userInfo = [];
if ($uid) {
/** @var UserServices $userService */
$userService = app()->make(UserServices::class);
$userInfo = $userService->getUserCacheInfo($uid);
}
$orderId = (int)$orderInfo['id'];
/** @var StoreOrderCartInfoServices $cartServices */
$cartServices = app()->make(StoreOrderCartInfoServices::class);
$cartInfoList = $cartServices->getColumn(['oid' => $orderId], 'cart_info');
if (!$cartInfoList) {
return true;
}
$cartInfo = [];
foreach ($cartInfoList as $cart) {
$cartInfo[] = is_string($cart) ? json_decode($cart, true) : $cart;
}
$priceData = [
'usedIntegral' => $orderInfo['use_integral'],
'deduction_price' => $orderInfo['deduction_price'],
'first_order_price' => $orderInfo['first_order_price']
];
$spread_ids = [];
$spread_uid = $spread_two_uid = 0;
if ($cartInfo && $priceData) {
[$cartInfo, $spread_ids] = $createService->computeOrderProductTruePrice($orderInfo, $cartInfo, $priceData, $uid, $userInfo);
$cartServices->updateCartInfo($orderId, $cartInfo);
}
$orderData = [];
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
if ($spread_ids) {
[$spread_uid, $spread_two_uid] = $spread_ids;
} else {
$spread_uid = $userServices->getSpreadUid($uid);
if ($spread_uid > 0 && sys_config('brokerage_level', 2) == 2) {
$spread_two_uid = $userServices->getSpreadUid($spread_uid, [], false);
}
}
if ($spread_uid > 0) {
$orderData['spread_uid'] = $spread_uid;
}
if ($spread_two_uid > 0) {
$orderData['spread_two_uid'] = $spread_two_uid;
}
if ($cartInfo && (isset($orderInfo['type']) && !in_array($orderInfo['type'], [1, 2, 3, 4, 5, 7, 8]))) {
/** @var StoreOrderComputedServices $orderComputed */
$orderComputed = app()->make(StoreOrderComputedServices::class);
if ($userServices->checkUserPromoter($spread_uid)) $orderData['one_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'one_brokerage', false);
if ($userServices->checkUserPromoter($spread_two_uid)) $orderData['two_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'two_brokerage', false);
$orderData['division_staff_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'division_staff_brokerage', false);
$orderData['division_agent_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'division_agent_brokerage', false);
$orderData['division_brokerage'] = $orderComputed->getOrderSumPrice($cartInfo, 'division_brokerage', false);
}
\think\facade\Log::error('计算订单实际优惠、积分、邮费、佣金成功:'.json_encode($orderData, JSON_UNESCAPED_UNICODE));
if ($orderData) $createService->update(['id' => $orderId], $orderData);
} catch (\Throwable $e) {
Log::error('计算订单实际优惠、积分、邮费、佣金失败,原因:' . $e->getMessage());
}
return true;
}
}

View File

@@ -0,0 +1,144 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\order;
use app\services\order\StoreOrderCartInfoServices;
use app\services\order\StoreOrderServices;
use app\services\order\StoreOrderStatusServices;
use app\services\product\sku\StoreProductAttrValueServices;
use app\services\product\sku\StoreProductVirtualServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 支付成功:自动发送卡密、处理次卡商品核销信息
* Class OrderPayHandelJob
* @package app\jobs\order
*/
class OrderPayHandelJob extends BaseJobs
{
use QueueTrait;
/**
* @param $orderInfo
* @return bool
*/
public function doJob($orderInfo)
{
if (!$orderInfo) {
return true;
}
//待发货状态
if ($orderInfo['status'] != 0) {
return true;
}
/** @var StoreOrderServices $orderService */
$orderService = app()->make(StoreOrderServices::class);
/** @var StoreOrderStatusServices $statusService */
$statusService = app()->make(StoreOrderStatusServices::class);
/** @var StoreOrderCartInfoServices $services */
$services = app()->make(StoreOrderCartInfoServices::class);
$orderInfo['cart_info'] = $cartInfoList = $services->getOrderCartInfo((int)$orderInfo['id']);
try {
switch ($orderInfo['product_type']) {
case 1://卡密商品:自动发送
$title = $content = '';
$disk_info = $orderInfo['cart_info'][$orderInfo['cart_id'][0] ?? 0]['cart_info']['productInfo']['attrInfo']['disk_info'] ?? '';
$unique = $orderInfo['cart_info'][$orderInfo['cart_id'][0]]['cart_info']['productInfo']['attrInfo']['unique'];
//活动订单共用原商品规格卡密
if ($orderInfo['type'] != 0 && $orderInfo['activity_id']) {
/** @var StoreProductAttrValueServices $skuValueServices */
$skuValueServices = app()->make(StoreProductAttrValueServices::class);
$attrValue = $skuValueServices->getUniqueByActivityUnique($unique, (int)$orderInfo['activity_id'], (int)$orderInfo['type'], ['unique', 'disk_info']);
if ($attrValue) {
$disk_info = $attrValue['disk_info'] ?? '';
$unique = $attrValue['unique'] ?? '';
}
}
if ($disk_info) {
$title = '虚拟密钥发放';
$content = '您购买的密钥商品已支付成功,支付金额' . $orderInfo['pay_price'] . '元,订单号:' . $orderInfo['order_id'] . ',密钥:' . $disk_info . ',感谢您的光临!';
$virtual_info = '密钥自动发放:' . $disk_info;
$value = '密钥:' . $disk_info;
// $remark = '密钥自动发放:' . $disk_info;
} else {
/** @var StoreProductVirtualServices $virtualService */
$virtualService = app()->make(StoreProductVirtualServices::class);
$cardList = $virtualService->getOrderCardList(['store_id' => $orderInfo['store_id'], 'attr_unique' => $unique, 'uid' => 0], (int)$orderInfo['total_num']);
$title = '虚拟卡密发放';
$virtual_info = [];
// $remark = '卡密已自动发放';
$value = '';
if ($cardList) {
$content = '您购买的卡密商品已支付成功,支付金额' . $orderInfo['pay_price'] . '元,订单号:' . $orderInfo['order_id'] . ',';
$update = [];
$update['order_id'] = $orderInfo['order_id'];
$update['uid'] = $orderInfo['uid'];
foreach ($cardList as $virtual) {
$virtualService->update($virtual['id'], $update);
$content .= '卡号:' . $virtual['card_no'] . ';密码:' . $virtual['card_pwd'] . "\n";
$virtual_info[] = ['card_no' => $virtual['card_no'], 'card_pwd' => $virtual['card_pwd']];
$value .= '卡号:' . $virtual['card_no'] . ';密码:' . $virtual['card_pwd'];
// $remark .= ',卡号:' . $virtual['card_no'] . ';密码:' . $virtual['card_pwd'] . ';';
}
$content .= ',感谢您的光临!';
}
}
//修改订单虚拟备注
$orderService->update(['id' => $orderInfo['id']], ['status' => 1, 'delivery_type' => 'fictitious', 'virtual_info' => json_encode($virtual_info)]);
$data['id'] = $orderInfo['id'];
$data['uid'] = $orderInfo['uid'];
$data['order_id'] = $orderInfo['order_id'];
$data['title'] = $title;
$data['value'] = $value;
$data['content'] = $content;
$data['is_integral'] = 0;
event('notice.notice', [$data, 'kami_deliver_goods_code']);
//记录订单状态
OrderStatusJob::dispatch([$orderInfo['id'], 'delivery_fictitious', ['change_message' => '卡密自动发货', 'change_manager_type' => 'system']]);
break;
case 4://次卡商品:处理核销数据
foreach ($cartInfoList as $cart_id => $cartInfo) {
$info = $cartInfo['cart_info'] ?? [];
$attrInfo = $info['productInfo']['attrInfo'] ?? [];
$data = ['write_start' => 0, 'write_end' => 0];
if ($attrInfo) {
switch ($attrInfo['write_valid'] ?? 1) {
case 1://永久
break;
case 2://购买后n天
if (isset($attrInfo['write_days']) && $attrInfo['write_days']) {
$data['write_start'] = time();
$data['write_end'] = bcadd((string)$data['write_start'], (string)bcmul((string)$attrInfo['write_days'], '86400'));
}
break;
case 3://具体时间段
if ((isset($attrInfo['write_start']) && $attrInfo['write_start']) || (isset($attrInfo['write_end']) && $attrInfo['write_end'])) {
$data['write_start'] = $attrInfo['write_start'] ?? 0;
$data['write_end'] = $attrInfo['write_end'] ?? 0;
}
break;
}
}
$services->update(['oid' => $orderInfo['id'], 'cart_id' => $cart_id], $data);
}
break;
}
} catch (\Throwable $e) {
Log::error('订单虚拟商品自动发放失败,原因:' . $e->getMessage());
}
return true;
}
}

View File

@@ -0,0 +1,149 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\order;
use app\services\order\StoreOrderServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 订单支付类型处理队列
* Class OrderPayTypeJob
* @package app\jobs\order
*/
class OrderPayTypeJob extends BaseJobs
{
use QueueTrait;
/**
* 直接执行订单支付类型处理
* 不需要传参数,直接处理所有需要处理的订单
* @return bool
*/
public function doJob()
{
try {
/** @var StoreOrderServices $storeOrderServices */
$storeOrderServices = app()->make(StoreOrderServices::class);
Log::info('开始执行订单支付类型处理任务');
// 查询所有已支付的订单
$where = [
'paid' => 1,
'is_del' => 0,
'is_system_del' => 0
];
// 分批处理,避免内存溢出
$limit = 100;
$page = 1;
$totalProcessed = 0;
$successCount = 0;
$failCount = 0;
do {
Log::info('开始执行订单支付类型处理任务111');
$orders = $storeOrderServices->getList($where, ['id', 'pay_type', 'pay_price', 'yue_price', 'online_price'], $page, $limit);
if (empty($orders)) {
break;
}
foreach ($orders as $order) {
if ($this->processOrder($order)) {
$successCount++;
} else {
$failCount++;
}
$totalProcessed++;
}
$page++;
Log::info("已处理第 {$page} 页,当前批次处理 " . count($orders) . " 条订单");
} while (count($orders) === $limit);
Log::info("订单支付类型处理任务完成,共处理:{$totalProcessed}条订单,成功:{$successCount},失败:{$failCount}");
return $failCount === 0;
} catch (\Exception $e) {
Log::error('订单支付类型处理任务异常:' . $e->getMessage());
return false;
}
}
/**
* 处理单个订单
* @param array $order 订单数据
* @return bool
*/
private function processOrder($order)
{
try {
/** @var StoreOrderServices $storeOrderServices */
$storeOrderServices = app()->make(StoreOrderServices::class);
$orderId = $order['id'];
$payType = $order['pay_type'] ?? '';
$payPrice = $order['pay_price'] ?? 0;
$currentYuePrice = $order['yue_price'] ?? 0;
$currentOnlinePrice = $order['online_price'] ?? 0;
// 准备更新数据
$updateData = [];
$needUpdate = false;
// 根据支付类型设置相应字段
if ($payType === 'yue') {
// 余额支付:yue_price = pay_price, online_price = 0
if ($currentYuePrice != $payPrice || $currentOnlinePrice != 0) {
$updateData['yue_price'] = $payPrice;
$updateData['online_price'] = 0;
$needUpdate = true;
Log::info("订单ID:{$orderId},余额支付,需要更新 yue_price:{$payPrice},online_price:0");
}
} else {
// 其他支付方式:online_price = pay_price, yue_price = 0
if ($currentOnlinePrice != $payPrice || $currentYuePrice != 0) {
$updateData['online_price'] = $payPrice;
$updateData['yue_price'] = 0;
$needUpdate = true;
Log::info("订单ID:{$orderId},线上支付({$payType}),需要更新 online_price:{$payPrice},yue_price:0");
}
}
// 如果需要更新则执行更新
if ($needUpdate) {
$result = $storeOrderServices->update($orderId, $updateData);
if ($result) {
Log::info("订单支付类型处理成功,订单ID:{$orderId},支付类型:{$payType}");
return true;
} else {
Log::error("订单支付类型处理失败,订单ID:{$orderId}");
return false;
}
} else {
// 数据已经正确,无需更新
Log::debug("订单ID:{$orderId} 数据已正确,无需更新");
return true;
}
} catch (\Exception $e) {
Log::error("处理订单ID:{$order['id']} 时发生异常:" . $e->getMessage());
return false;
}
}
}

View File

@@ -0,0 +1,57 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\order;
use app\services\order\StoreOrderStatusServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* Class OrderStatusJob
* @package app\jobs\order
*/
class OrderStatusJob extends BaseJobs
{
use QueueTrait;
/**
* 写入订单记录
* @param $orderId
* @param $changeType
* @param $data
* @return bool
*/
public function doJob($orderId, $changeType = '', $data = [])
{
if (!$orderId || !$data) {
return true;
}
try {
/** @var StoreOrderStatusServices $statusService */
$statusService = app()->make(StoreOrderStatusServices::class);
$changeManagerId = $data['change_manager_id'] ?? 0;
$changeManagerType = $data['change_manager_type'] ?? '';
$statusService->saveStatus((int)$orderId, (string)$changeType, (array)$data, (int)$changeManagerId, (string)$changeManagerType);
} catch (\Throwable $e) {
response_log_write([
'message' => '写入订单【'.$changeType.'】记录失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,122 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\order;
use app\services\erp\OrderServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* Class OrderSyncJob
* @package app\jobs\order
*/
class OrderSyncJob extends BaseJobs
{
use QueueTrait;
/**
* @return mixed
*/
public static function queueName()
{
return 'CRMEB_PRO_ERP';
}
/**
* 同步订单
* @param int $oid
* @return bool
*/
public function syncOrder(int $oid): bool
{
try {
/** @var OrderServices $orderServices */
$orderServices = app()->make(OrderServices::class);
$orderServices->upload($oid);
} catch (\Exception $e) {
response_log_write([
'message' => '订单信息同步失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 更新订单信息
* @param string $orderId
* @param string $erpOrderId
* @param int $oid
* @return bool
*/
public function reorderOrder(string $orderId, array $erpOrderId = [], int $oid = 0): bool
{
try {
/** @var OrderServices $orderServices */
$orderServices = app()->make(OrderServices::class);
$cancelRes = $orderServices->cancelOrder($orderId, $erpOrderId);
if ($cancelRes && $oid > 0) {
$orderServices->upload($oid);
}
} catch (\Exception $e) {
response_log_write([
'message' => '订单信息更新失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 回调取消
* @param array $data
* @return bool
*/
public function refundOrder(array $data): bool
{
try {
/** @var OrderServices $orderServices */
$orderServices = app()->make(OrderServices::class);
$orderServices->refundOrder($data);
} catch (\Exception $e) {
response_log_write([
'message' => '回调订单取消同步失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 同步退货单
* @param int $refundId
* @return bool
*/
public function refundOrderUpload(int $refundId): bool
{
try {
/** @var OrderServices $orderServices */
$orderServices = app()->make(OrderServices::class);
$orderServices->refundOrderUpload([$refundId]);
} catch (\Exception $e) {
response_log_write([
'message' => '同步退货单信息失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,53 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\order;
use app\services\order\StoreOrderStatusServices;
use app\services\order\StoreOrderTakeServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 订单收货任务
* Class OrderTakeJob
* @package app\jobs
*/
class OrderTakeJob extends BaseJobs
{
use QueueTrait;
/**
* @return string
*/
protected static function queueName()
{
return 'CRMEB_PRO_TASK';
}
public function doJob($order)
{
if (!$order) return true;
/** @var StoreOrderTakeServices $service */
$service = app()->make(StoreOrderTakeServices::class);
$res = $service->update($order['id'], ['status' => 2]);
$order = $service->get((int)$order['id']);
$res = $res && $service->storeProductOrderUserTakeDelivery($order);
if (!$res) {
Log::error('收货失败:' . $order['order_id']);
}
OrderStatusJob::dispatch([$order['id'], 'user_take_delivery', ['change_message' => '用户已收货', 'change_manager_type' => 'user', 'change_manager_id' => $order['uid']]]);
return true;
}
}

View File

@@ -0,0 +1,52 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\order;
use app\services\order\StoreOrderDeliveryServices;
use app\services\order\StoreOrderWriteOffServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 订单核销
* Class OrderWriteoffJob
* @package app\jobs
*/
class OrderWriteoffJob extends BaseJobs
{
use QueueTrait;
/**
* 写入核销记录
* @param int $oid
* @param array $cartIds
* @param array $data
* @param array $orderInfo
* @param array $cartInfo
* @return bool
*/
public function doJob(int $oid, array $cartIds, array $data, array $orderInfo = [], array $cartInfo = [])
{
try {
/** @var StoreOrderWriteOffServices $storeOrderWriteoffServices */
$storeOrderWriteoffServices = app()->make(StoreOrderWriteOffServices::class);
$storeOrderWriteoffServices->saveWriteOff($oid, $cartIds, $data, $orderInfo, $cartInfo);
} catch (\Throwable $e) {
Log::error('写入订单核销记录失败失败,原因:' . $e->getMessage());
}
return true;
}
}

View File

@@ -0,0 +1,203 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\order;
use app\services\message\sms\SmsSendServices;
use app\services\order\OtherOrderServices;
use app\services\order\StoreOrderEconomizeServices;
use app\services\user\member\MemberCardServices;
use app\services\user\UserBillServices;
use app\services\user\UserServices;
use app\services\wechat\WechatUserServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 订单消息队列
* Class OtherOrderJob
* @package app\jobs
*/
class OtherOrderJob extends BaseJobs
{
use QueueTrait;
/**
* 执行订单支付成功发送消息
* @param $order
* @return bool
*/
public function doJob($order)
{
//更新用户支付订单数量
try {
$this->setUserPayCountAndPromoter($order);
} catch (\Throwable $e) {
response_log_write([
'message' => '更新用户订单数失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
// 计算用户节省金额
try {
$this->setEconomizeMoney($order);
} catch (\Throwable $e) {
response_log_write([
'message' => '计算节省金额,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
try {
$this->sendMemberIntegral($order);
} catch (\Throwable $e) {
response_log_write([
'message' => '消费积分返还失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 设置用户购买次数和检测时候成为推广人
* @param $order
*/
public function setUserPayCountAndPromoter($order)
{
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$userInfo = $userServices->get($order['uid']);
if ($userInfo) {
if (!$userInfo->is_promoter) {
/** @var OtherOrderServices $orderServices */
$orderServices = app()->make(OtherOrderServices::class);
$price = $orderServices->sum(['paid' => 1, 'uid' => $userInfo['uid']], 'pay_price');
$status = is_brokerage_statu($price);
if ($status) {
$userInfo->is_promoter = 1;
}
}
$userInfo->save();
}
return true;
}
/**
* 发送模板消息和客服消息
* @param $order
* @return bool
*/
public function sendServicesAndTemplate($order)
{
try {
/** @var WechatUserServices $wechatUserServices */
$wechatUserServices = app()->make(WechatUserServices::class);
if ($order['is_channel'] == "wechat") {//公众号发送模板消息
$openid = $wechatUserServices->uidToOpenid($order['uid'], 'wechat');
if (!$openid) {
return true;
}
$wechatTemplate = new WechatTemplateJob();
$wechatTemplate->sendOrderPaySuccess($openid, $order);
} else if ($order['is_channel'] == "routine") {//小程序发送模板消息
$openid = $wechatUserServices->uidToOpenid($order['uid'], 'routine');
if (!$openid) {
return true;
}
$tempJob = new RoutineTemplateJob();
$tempJob->sendMemberOrderSuccess($openid, $order['pay_price'], $order['order_id']);
}
} catch (\Exception $e) {
}
return true;
}
/**
* 购买会员赠送优惠券
* @param $uid
*/
public function setCoupon($uid)
{
// /** @var StoreCouponIssueServices $couponService */
// $couponService = app()->make(StoreCouponIssueServices::class);
// $couponInfo = $couponService->sendMemberCoupon($uid);
// if (!$couponInfo) Log::error('优惠券发送失败,失败原因:没发现会员优惠券或者优惠券数量为0');
}
/**
* 线下付款奖励积分
* @param $order
* @return bool
*/
public function sendMemberIntegral($order)
{
//只有线下付款才奖励
if ($order['type'] == 3) {
$order_give_integral = sys_config('order_give_integral');
$order_integral = bcmul($order_give_integral, (string)$order['pay_price'], 0);
/** @var UserServices $userService */
$userService = app()->make(UserServices::class);
$userInfo = $userService->getUserCacheInfo($order['uid']);
if (!$userInfo) return false;
if ($userService->checkUserIsSvip((int)$order['uid'])) {
//看是否开启消费返积分翻倍奖励
/** @var MemberCardServices $memberCardService */
$memberCardService = app()->make(MemberCardServices::class);
$integral_rule_number = $memberCardService->isOpenMemberCardCache('integral');
if ($integral_rule_number) {
$order_integral = bcadd($order_integral, $integral_rule_number, 2);
}
}
if ($order_integral > 0) {
$balance = bcadd(abs($userInfo['integral']), abs($order_integral), 0);
$userService->update(['uid' => $order['uid']], ['integral' => $balance]);
/** @var UserBillServices $userBillServices */
$userBillServices = app()->make(UserBillServices::class);
$userBillServices->income('order_give_integral', $order['uid'], $order_integral, $balance, $order['id']);
}
}
return true;
}
/**
* @param $order
*/
public function setEconomizeMoney($order)
{
//只有线下付款才计算节省
if ($order['type'] == 3) {
/** @var StoreOrderEconomizeServices $economizeService */
$economizeService = app()->make(StoreOrderEconomizeServices::class);
/** @var MemberCardServices $memberRightService */
$memberRightService = app()->make(MemberCardServices::class);
$isOpenOfflin = $memberRightService->isOpenMemberCardCache('offline');
if ($isOpenOfflin) {
$save = [
'uid' => $order['uid'],
'order_id' => $order['order_id'],
'order_type' => 2,
'pay_price' => $order['pay_price'],
'offline_price' => bcsub($order['money'], $order['pay_price'], 2)
];
$economizeService->addEconomize($save);
}
}
return true;
}
}

View File

@@ -0,0 +1,140 @@
<?php
namespace app\jobs\order;
use app\jobs\supplier\SupplierFinanceJob;use app\services\order\StoreOrderCartInfoServices;
use app\services\order\StoreOrderServices;
use app\services\order\StoreOrderSplitServices;
use app\services\supplier\SystemSupplierServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 分配订单
* Class ShareOrderJob
* @package app\jobs
*/
class ShareOrderJob extends BaseJobs
{
use QueueTrait;
/**
* 门店分配订单
* @param $orderInfo
* @return bool
*/
public function doJob($orderInfo)
{
if (!$orderInfo) {
return true;
}
//整单分给门店
/** @var StoreOrderServices $storeOrderServices */
$storeOrderServices = app()->make(StoreOrderServices::class);
$order = $storeOrderServices->get($orderInfo['id']);
if (!$order) {
return true;
}
$orderInfo = $order->toArray();
try {
$id = (int)$orderInfo['id'];
/** @var StoreOrderCartInfoServices $storeOrderCartInfoServices */
$storeOrderCartInfoServices = app()->make(StoreOrderCartInfoServices::class);
//订单下原商品信息
$cartInfo = $storeOrderCartInfoServices->getCartColunm(['oid' => $id, 'split_status' => [0, 1]], 'cart_id,type,relation_id,is_gift,cart_num,split_surplus_num', 'cart_id');
if (!$cartInfo) {
return true;
}
$suppplierIds = $storeIds = [];
foreach ($cartInfo as $cart) {
$type = $cart['type'] ?? 0;
switch ($type) {
case 0://兼容之前供应商商品
if ($cart['relation_id']) {
$suppplierIds[] = $cart['relation_id'];
}
break;
case 1:
$storeIds[] = $cart['relation_id'];
break;
case 2:
$suppplierIds[] = $cart['relation_id'];
break;
}
}
if ($suppplierIds) {//验证供应商状态(关闭|删除不分配)
/** @var SystemSupplierServices $supplierServices */
$supplierServices = app()->make(SystemSupplierServices::class);
$suppplierIds = $supplierServices->getColumn([['id', 'in', $suppplierIds], ['is_show', '=', 1], ['is_del', '=', 0]], 'id');
}
$cart_ids = [];
$other_cart_ids = [];
//分配给供应商、门店
if ($suppplierIds) {
$suppplier_id = $suppplierIds[0] ?? 0;
$updateData = [];
//先拆分供应商
if ($suppplier_id) {
foreach ($cartInfo as $cart_id => $cart) {
if ($cart['type'] == 2 && $cart['relation_id'] == $suppplier_id) {//拆分
$cart_ids[] = ['cart_id' => $cart_id, 'cart_num' => $cart['cart_num']];
} else {
$other_cart_ids[] = ['cart_id' => $cart_id, 'cart_num' => $cart['cart_num']];
}
}
$updateData['supplier_id'] = $suppplier_id;
}
//下单商品都是某一个供应商|| 门店商品,不用拆分
if (!$other_cart_ids && count($suppplierIds) == 1) {
$storeOrderServices->update(['id' => $id], ['supplier_id' => $suppplier_id]);
if (isset($updateData['supplier_id'])) {
//供应商账单流水
SupplierFinanceJob::dispatch([$id, 1]);
SpliteStoreOrderJob::dispatchDo('splitAfter', [$orderInfo]);
}
} else {
//分配订单
/** @var StoreOrderSplitServices $storeOrderSplitServices */
$storeOrderSplitServices = app()->make(StoreOrderSplitServices::class);
$splitResult = $storeOrderSplitServices->equalSplit($id, $cart_ids);
$otherOrder = [];
if ($splitResult) {//拆分供应商订单
[$orderInfo, $otherOrder] = $splitResult;
}
$storeOrderServices->update(['id' => $orderInfo['id']], $updateData);
if (isset($updateData['store_id'])) {//拆分门店订单
SpliteStoreOrderJob::dispatchDo('splitAfter', [$orderInfo]);
} elseif (isset($updateData['supplier_id'])) {
//供应商账单流水
SupplierFinanceJob::dispatch([$orderInfo['id'], 1]);
SpliteStoreOrderJob::dispatchDo('splitAfter', [$orderInfo]);
}
//还有商品
if ($other_cart_ids && $otherOrder) {
//还有其他供应商 || 门店 继续分配
if (count($suppplierIds) >= 1) {
ShareOrderJob::dispatch([$otherOrder]);
}
}
}
} else {//平台配送
SpliteStoreOrderJob::dispatchDo('splitAfter', [$orderInfo]);
}
} catch (\Throwable $e) {
response_log_write([
'message' => '自动拆分供应商订单失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace app\jobs\order;
use app\services\order\StoreOrderStatusServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 拆分订单后置队列
* Class SpliteOrderAfterJob
* @package app\jobs\order
*/
class SpliteOrderAfterJob extends BaseJobs
{
use QueueTrait;
/**
* 门店分配订单
* @param $orderInfo
* @return bool
*/
public function doJob($oid, $orderData)
{
if (!$oid || !$orderData || count($orderData) != 2) {
return true;
}
[$orderInfo, $otherOrder] = $orderData;
try {
/** @var StoreOrderStatusServices $statusService */
$statusService = app()->make(StoreOrderStatusServices::class);
$statusData = $statusService->getColumn(['oid' => $oid], '*');
if (!$statusData) {
return true;
}
$ids = [];
if ($orderInfo['id'] != $oid) {
$ids[] = $orderInfo['id'];
}
if ($otherOrder['id'] != $oid) {
$ids[] = $otherOrder['id'];
}
if ($ids) {
$allData = [];
foreach ($ids as $id) {
foreach ($statusData as $data) {
$data['oid'] = $id;
$allData[] = $data;
}
}
if ($allData) {
$statusService->saveAll($allData);
}
}
} catch (\Throwable $e) {
response_log_write([
'message' => '处理拆分订单记录失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace app\jobs\order;
use app\services\message\NoticeService;
use app\services\order\StoreOrderCartInfoServices;use app\webscoket\SocketPush;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 门店分配订单
* Class SpliteStoreOrderJob
* @package app\jobs
*/
class SpliteStoreOrderJob extends BaseJobs
{
use QueueTrait;
/**
* 订单分配完成后置方法
* @param $orderInfo
*/
public function splitAfter($orderInfo, bool $only_print = false)
{
//分配好向用户设置标签
OrderJob::dispatchDo('setUserLabel', [$orderInfo]);
if ($only_print) {
/** @var NoticeService $NoticeService */
$NoticeService = app()->make(NoticeService::class);
$NoticeService->orderPrint($orderInfo);
} else {
$orderInfoServices = app()->make(StoreOrderCartInfoServices::class);
$storeName = $orderInfoServices->getCarIdByProductTitle((int)$orderInfo['id']);
$orderInfo['storeName'] = substrUTf8($storeName, 20, 'UTF-8', '');
$orderInfo['send_name'] = $orderInfo['real_name'];
//分配完成用户推送消息事件(门店小票打印)
event('notice.notice', [$orderInfo, 'order_pay_success']);
}
return true;
}
}

View File

@@ -0,0 +1,37 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\order;
use app\services\order\StoreOrderServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 未支付订单队列
* Class UnpaidOrderSend
* @package app\jobs
*/
class UnpaidOrderCancelJob extends BaseJobs
{
use QueueTrait;
/**
* 未支付订单取消任务执行
* @return bool
*/
public function doJob()
{
return true;
}
}

View File

@@ -0,0 +1,111 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\order;
use app\services\order\StoreOrderServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 未支付订单队列
* Class UnpaidOrderSend
* @package app\jobs
*/
class UnpaidOrderJob extends BaseJobs
{
use QueueTrait;
/**
* 提醒付款给用户通知
* @param $id
* @return bool
*/
public function sendNotice($id)
{
try {
/** @var StoreOrderServices $services */
$services = app()->make(StoreOrderServices::class);
$orderInfo = $services->get($id);
if (!$orderInfo) {
return true;
}
if ($orderInfo->paid) {
return true;
}
if ($orderInfo->is_del) {
return true;
}
//未支付用户发送消息
event('notice.notice', [['order' => $orderInfo], 'order_pay_false']);
} catch (\Throwable $e) {
response_log_write([
'message' => '未支付订单发送短信失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 取消未支付订单
* @param $orderId
* @return bool
*/
public function cancelOrder($orderId)
{
/** @var StoreOrderServices $services */
$services = app()->make(StoreOrderServices::class);
$orderInfo = $services->get($orderId);
if (!$orderInfo) {
return true;
}
if ($orderInfo->paid) {
return true;
}
if ($orderInfo->is_del) {
return true;
}
if ($orderInfo->pay_type == 'offline') {
return true;
}
try {
$services->cancelOrder((int)$orderId, 0, '订单未支付已超过系统预设时间');
} catch (\Throwable $e) {
response_log_write([
'message' => '自动取消订单失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 自动取消未支付订单
* @param $page
* @param $limit
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function autoCancelOrder($page, $limit)
{
/** @var StoreOrderServices $service */
$service = app()->make(StoreOrderServices::class);
$service->runOrderUnpaidCancel($page, $limit);
return true;
}
}

214
app/jobs/out/OutPushJob.php Normal file
View File

@@ -0,0 +1,214 @@
<?php
namespace app\jobs\out;
use app\services\out\OutStoreOrderRefundServices;
use app\services\out\OutStoreOrderServices;
use app\services\out\OutAccountServices;
use app\services\user\UserServices;
use crmeb\basic\BaseJobs;
use crmeb\services\CacheService;
use crmeb\services\HttpService;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 外部推送队列
* Class OutPushJob
* @package app\jobs\out
*/
class OutPushJob extends BaseJobs
{
use QueueTrait;
/**
* 执行推送任务
* @param string $type 推送类型
* @param array $data 推送数据
* @return bool
*/
public function push($type, $data)
{
/** @var OutAccountServices $outAccountServices */
$outAccountServices = app()->make(OutAccountServices::class);
$outAccountList = $outAccountServices->selectList(['is_del' => 0, 'status' => 1])->toArray();
foreach ($outAccountList as $item) {
if ($item['push_open'] == 1) {
$token = $this->getPushToken($item);
if ($type == 'order_create_push') {
OutPushJob::dispatchDo('orderCreate', [$data['order_id'], $item['order_create_push'] . '?pushToken=' . $token]);
} elseif ($type == 'order_pay_push') {
OutPushJob::dispatchDo('paySuccess', [$data['order_id'], $item['order_pay_push'] . '?pushToken=' . $token]);
} elseif ($type == 'refund_create_push') {
OutPushJob::dispatchDo('refundCreate', [$data['order_id'], $item['refund_create_push'] . '?pushToken=' . $token]);
} elseif ($type == 'refund_cancel_push') {
OutPushJob::dispatchDo('refundCancel', [$data['order_id'], $item['refund_cancel_push'] . '?pushToken=' . $token]);
} elseif ($type == 'user_update_push') {
OutPushJob::dispatchDo('userUpdate', [$data, $item['user_update_push'] . '?pushToken=' . $token]);
}
}
}
return true;
}
/**
* 获取推送token
* @param array $info
* @return false|mixed
*/
public function getPushToken(array $info)
{
$token = CacheService::redisHandler()->get('pushToken' . $info['id']);
if (!$token) {
$param = json_encode(['push_account' => $info['push_account'], 'push_password' => $info['push_password']], JSON_UNESCAPED_UNICODE);
$res = HttpService::postRequest($info['push_token_url'], $param, ['Content-Type:application/json', 'Content-Length:' . strlen($param)], 5);
$res = $res ? json_decode($res, true) : [];
if (!$res || !isset($res['code']) || $res['code'] != 0) {
Log::error('获取token失败',['msg' => $info['title']]);
return false;
}
CacheService::redisHandler()->set('pushToken' . $info['id'], $res['token'], $res['time']);
return $res['token'];
} else {
return $token;
}
}
/**
* 订单推送
* @param int $oid
* @param string $pushUrl
* @param int $step
* @return bool
*/
public function orderCreate(int $oid, string $pushUrl, int $step = 0): bool
{
if ($step > 2) {
Log::error('订单' . $oid . '推送失败');
return true;
}
try {
/** @var OutStoreOrderServices $services */
$services = app()->make(OutStoreOrderServices::class);
if (!$services->orderCreatePush($oid, $pushUrl)) {
OutPushJob::dispatchSece(($step + 1) * 5, 'orderCreate', [$oid, $pushUrl, $step + 1]);
}
} catch (\Exception $e) {
Log::error('订单' . $oid . '推送失败,失败原因:' . $e->getMessage());
OutPushJob::dispatchSece(($step + 1) * 5, 'orderCreate', [$oid, $pushUrl, $step + 1]);
}
return true;
}
/**
* 订单支付推送
* @param int $oid
* @param string $pushUrl
* @param int $step
* @return bool
*/
public function paySuccess(int $oid, string $pushUrl, int $step = 0): bool
{
if ($step > 2) {
Log::error('订单支付' . $oid . '推送失败');
return true;
}
try {
/** @var OutStoreOrderServices $services */
$services = app()->make(OutStoreOrderServices::class);
if (!$services->paySuccessPush($oid, $pushUrl)) {
OutPushJob::dispatchSece(($step + 1) * 5, 'paySuccess', [$oid, $pushUrl, $step + 1]);
}
} catch (\Exception $e) {
Log::error('订单支付' . $oid . '推送失败,失败原因:' . $e->getMessage());
OutPushJob::dispatchSece(($step + 1) * 5, 'paySuccess', [$oid, $pushUrl, $step + 1]);
}
return true;
}
/**
* 售后单生成
* @param int $oid
* @param string $pushUrl
* @param int $step
* @return bool
*/
public function refundCreate(int $oid, string $pushUrl, int $step = 0): bool
{
if ($step > 2) {
Log::error('售后单' . $oid . '推送失败');
return true;
}
try {
/** @var OutStoreOrderRefundServices $services */
$services = app()->make(OutStoreOrderRefundServices::class);
if (!$services->refundCreatePush($oid, $pushUrl)) {
OutPushJob::dispatchSece(($step + 1) * 5, 'refundCreate', [$oid, $pushUrl, $step + 1]);
}
} catch (\Exception $e) {
Log::error('售后单' . $oid . '推送失败,失败原因:' . $e->getMessage());
OutPushJob::dispatchSece(($step + 1) * 5, 'refundCreate', [$oid, $pushUrl, $step + 1]);
}
return true;
}
/**
* 取消申请
* @param int $oid
* @param string $pushUrl
* @param int $step
* @return bool
*/
public function refundCancel(int $oid, string $pushUrl, int $step = 0): bool
{
if ($step > 2) {
Log::error('取消售后单' . $oid . '推送失败');
return true;
}
try {
/** @var OutStoreOrderRefundServices $services */
$services = app()->make(OutStoreOrderRefundServices::class);
if (!$services->cancelApplyPush($oid, $pushUrl)) {
OutPushJob::dispatchSece(($step + 1) * 5, 'refundCancel', [$oid, $pushUrl, $step + 1]);
}
} catch (\Exception $e) {
Log::error('取消售后单' . $oid . '推送失败,失败原因:' . $e->getMessage());
OutPushJob::dispatchSece(($step + 1) * 5, 'refundCancel', [$oid, $pushUrl, $step + 1]);
}
return true;
}
/**
* 余额,积分,佣金,经验变动推送
* @param array $data
* @param string $pushUrl
* @param int $step
* @return bool
*/
public function userUpdate(array $data, string $pushUrl, int $step = 0): bool
{
if ($step > 2) {
Log::error('用户变动推送失败');
return true;
}
try {
/** @var UserServices $services */
$services = app()->make(UserServices::class);
if (!$services->userUpdate($data, $pushUrl)) {
OutPushJob::dispatchSece(($step + 1) * 5, 'userUpdate', [$data, $pushUrl, $step + 1]);
}
} catch (\Exception $e) {
OutPushJob::dispatchSece(($step + 1) * 5, 'userUpdate', [$data, $pushUrl, $step + 1]);
}
return true;
}
}

View File

@@ -0,0 +1,137 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\product;
use app\services\product\product\StoreProductBatchProcessServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 商品批量任务队列
* Class ProductBatchJob
* @package app\jobs\product
*/
class ProductBatchJob extends BaseJobs
{
use QueueTrait;
/**
* @return mixed
*/
public static function queueName()
{
$default = config('queue.default');
return config('queue.connections.' . $default . '.batch_queue');
}
/**
* 商品批量队列
* @param $type
* @param $ids
* @param $data
* @param $isBatch
* @return bool
*/
public function productBatch($type, $ids, $data, $isBatch = false)
{
if (!$type || !$ids || !$data) {
return true;
}
//是否批量多个修改
if ($isBatch) {
$length = 30;
} else {
$length = 100;
}
//拆分大数组 分批加入二级队列
$idsArr = array_chunk($ids, $length);
foreach ($idsArr as $ids) {
//加入分批队列
self::dispatchDo('chunkProductBatch', [$type, $ids, $data, $isBatch]);
}
return true;
}
/**
* 拆分分批队列
* @param $type
* @param $ids
* @param $data
* @param $isBatch
* @return bool
*/
public function chunkProductBatch($type, $ids, $data, $isBatch = false)
{
if (!$type || !$ids || !$data) {
return true;
}
//是否批量多个修改
if ($isBatch) {
self::dispatchDo('runProductBatch', [$type, $ids, $data]);
} else {//拆分id,单个队列执行
foreach ($ids as $id) {
self::dispatchDo('runProductBatch', [$type, $id, $data]);
}
}
return true;
}
/**
* 实际执行商品操作队列
* @param $type
* @param $ids
* @param $data
* @return bool
*/
public function runProductBatch($type, $id, $data)
{
if (!is_array($id)) {
$id = (int)$id;
}
if (!$type || !$id || !$data) {
return true;
}
try {
/** @var StoreProductBatchProcessServices $batchProcessServices */
$batchProcessServices = app()->make(StoreProductBatchProcessServices::class);
switch ($type) {
case 1://分类
$batchProcessServices->setPrdouctCate($id, $data);
break;
case 4://购买即送积分、优惠券
$batchProcessServices->setGiveIntegralCoupon($id, $data);
break;
case 2://商品标签
case 3://物流设置
case 5://关联用户标签
case 6://活动推荐
case 7://自定义留言
case 8://运费设置
case 9://商品品牌
case 10://商品佣金
$batchProcessServices->runBatch($id, $data, (int)$type);
break;
default:
break;
}
} catch (\Throwable $e) {
response_log_write([
'message' => '批量操作商品,type:' . $type . ';状态失败' . ';参数:' . json_encode(['id' => $id, 'data' => $data]) . ',失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,51 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\product;
use app\services\activity\bargain\StoreBargainServices;
use app\services\activity\combination\StoreCombinationServices;
use app\services\activity\integral\StoreIntegralServices;
use app\services\activity\seckill\StoreSeckillServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 商品佣金批量修改
* Class ProductSupplierJob
* @package app\jobs\product
*/
class ProductBrokerageJob extends BaseJobs
{
use QueueTrait;
/**
* 修改商品、活动商品供应商ID
* @param $product_id
* @param $supplier_id
* @return bool
*/
public function doJob(int $id, array $data)
{
try {
} catch (\Throwable $e) {
response_log_write([
'message' => '批量佣金设置发生错误,错误原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,51 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\product;
use app\services\product\product\StoreProductCateServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 商品分类
* Class ProductCateJob
* @package app\jobs\product
*/
class ProductCateJob extends BaseJobs
{
use QueueTrait;
/**
* @param int $id
* @param array $cate_id
* @param int $is_show
* @return bool
*/
public function doJob(int $id, array $cate_id, int $is_show = 0)
{
try {
/** @var StoreProductCateServices $storeProductCateServices */
$storeProductCateServices = app()->make(StoreProductCateServices::class);
//商品分类关联
$storeProductCateServices->saveCate($id, $cate_id, $is_show);
} catch (\Throwable $e) {
response_log_write([
'message' => '写入商品分类关联发生错误,错误原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,168 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\product;
use app\services\product\product\CopyTaobaoServices;
use app\services\product\product\StoreDescriptionServices;
use app\services\product\product\StoreProductServices;
use app\services\product\sku\StoreProductAttrValueServices;
use crmeb\basic\BaseJobs;
use crmeb\services\CacheService;
use crmeb\traits\QueueTrait;use think\facade\Log;
/**
* 复制商品
* Class ProductCopyJob
* @package app\jobs
*/
class ProductCopyJob extends BaseJobs
{
use QueueTrait;
/**
* 下载商品详情图片
* @param $id
* @param $description
* @param $image
* @param $count
* @return bool
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function copyDescriptionImage($id, $description, $image, $count)
{
try {
/** @var CopyTaobaoServices $copyTaobao */
$copyTaobao = app()->make(CopyTaobaoServices::class);
/** @var StoreDescriptionServices $storeDescriptionServices */
$storeDescriptionServices = app()->make(StoreDescriptionServices::class);
if (is_int(strpos($image, 'http'))) {
$d_image = $image;
} else {
$d_image = 'http://' . ltrim($image, '\//');
}
$description_cache = CacheService::getTokenBucket('desc_images_' . $id);
if ($description_cache === null) {
$description_cache = $description;
CacheService::setTokenBucket('desc_images_count' . $id, 0);
}
$res = $copyTaobao->downloadCopyImage($d_image);
$description_cache = str_replace($image, $res, $description_cache);
$desc_count = CacheService::getTokenBucket('desc_images_count' . $id) + 1;
if ($desc_count == $count) {
CacheService::clearToken('desc_images_' . $id);
CacheService::clearToken('desc_images_count' . $id);
$storeDescriptionServices->saveDescription((int)$id, $description_cache);
} else {
CacheService::setTokenBucket('desc_images_' . $id, $description_cache);
CacheService::setTokenBucket('desc_images_count' . $id, $desc_count);
}
} catch (\Throwable $e) {
response_log_write([
'message' => '下载商品详情图片失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 下载商品轮播图片
* @param $id
* @param $image
* @param $count
* @return bool
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function copySliderImage($id, $image, $count)
{
try {
/** @var CopyTaobaoServices $copyTaobao */
$copyTaobao = app()->make(CopyTaobaoServices::class);
/** @var StoreProductServices $StoreProductServices */
$StoreProductServices = app()->make(StoreProductServices::class);
//下载图片
$res = $copyTaobao->downloadCopyImage($image);
//获取缓存中的轮播图
$slider_images = CacheService::getTokenBucket('slider_images_' . $id);
//缓存为null则赋值[]
if ($slider_images === null) $slider_images = [];
//将下载的图片插入数组
$slider_images[] = $res;
//如果$slider_images中图片数量和传入的$count相等,说明已经下载完成,写入商品表,如果不等则继续插入缓存
if (count($slider_images) == $count) {
CacheService::clearToken('slider_images_' . $id);
$image = $slider_images[0];
$slider_images = $slider_images ? json_encode($slider_images) : '';
$StoreProductServices->update($id, ['slider_image' => $slider_images, 'image' => $image]);
} else {
CacheService::setTokenBucket('slider_images_' . $id, $slider_images);
}
} catch (\Throwable $e) {
response_log_write([
'message' => '下载商品轮播图片失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 采集商品规格,分批队列
* @param $id
* @param $type
* @return bool
*/
public function copyAttrImage($id, $type = 0)
{
if (!$id) {
return true;
}
try {
$productAttrValue = app()->make(StoreProductAttrValueServices::class);
$attrValueList = $productAttrValue->getColumn(['product_id' => $id, 'type' => $type], 'image', 'id');
foreach ($attrValueList as $value_id => $value_image) {
ProductCopyJob::dispatch('copyAttrImageDo', [$value_id, $value_image]);
}
} catch (\Throwable $e) {
Log::error('下载商品轮播图片失败,失败原因:' . $e->getMessage());
}
return true;
}
/**
* 采集规格图片
* @param $attrId
* @param $value_image
* @return bool
*/
public function copyAttrImageDo($attrId, $value_image)
{
if (!$attrId) {
return true;
}
try {
/** @var CopyTaobaoServices $copyTaobao */
$copyTaobao = app()->make(CopyTaobaoServices::class);
/** @var StoreProductAttrValueServices $StoreProductAttrValueServices */
$StoreProductAttrValueServices = app()->make(StoreProductAttrValueServices::class);
//下载图片
$res = $copyTaobao->downloadCopyImage($value_image);
$StoreProductAttrValueServices->update($attrId, ['image' => $res]);
} catch (\Throwable $e) {
Log::error('下载商品规格图片失败,失败原因:' . $e->getMessage() . '_' . $e->getFile() . '_' . $e->getLine());
}
return true;
}
}

View File

@@ -0,0 +1,72 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\product;
use app\services\product\product\StoreProductCouponServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 商品关联优惠券
* Class ProductCouponJob
* @package app\jobs\product
*/
class ProductCouponJob extends BaseJobs
{
use QueueTrait;
/**
* @param $orderInfo
* @return bool
*/
public function doJob($orderInfo)
{
if (!$orderInfo) return true;
try {
/** @var StoreProductCouponServices $storeProductCouponServices */
$storeProductCouponServices = app()->make(StoreProductCouponServices::class);
$storeProductCouponServices->giveOrderProductCoupon((int)$orderInfo['uid'], (int)$orderInfo['id']);
} catch (\Throwable $e) {
response_log_write([
'message' => '赠送订单商品关联优惠券发生错误,错误原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 设置保存商品关联优惠券
* @param $id
* @param $coupon_ids
* @return bool|void
*/
public function setProductCoupon($id, $coupon_ids)
{
if (!$id) return true;
try {
/** @var StoreProductCouponServices $storeProductCouponServices */
$storeProductCouponServices = app()->make(StoreProductCouponServices::class);
$storeProductCouponServices->setCoupon($id, $coupon_ids);
} catch (\Throwable $e) {
response_log_write([
'message' => '设置保存商品关联优惠券发生错误,错误原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,53 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\product;
use app\services\product\label\StoreProductLabelAuxiliaryServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 商品标签
* Class ProductLabelJob
* @package app\jobs\product
*/
class ProductLabelJob extends BaseJobs
{
use QueueTrait;
/**
* @param int $id
* @param array $storeLabelId
* @return bool
*/
public function doJob(int $id, array $storeLabelId)
{
if (!$id) {
return true;
}
try {
/** @var StoreProductLabelAuxiliaryServices $auxiliaryService */
$auxiliaryService = app()->make(StoreProductLabelAuxiliaryServices::class);
//标签关联
$auxiliaryService->saveLabelRelation($id, $storeLabelId);
} catch (\Throwable $e) {
response_log_write([
'message' => '写入商品标签发生错误,错误原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,83 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\product;
use app\services\product\product\StoreProductLogServices;
use app\services\product\product\StoreProductServices;
use app\services\product\product\StoreVisitServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 商品记录
* Class ProductLogJob
* @package app\jobs
*/
class ProductLogJob extends BaseJobs
{
use QueueTrait;
/**
* @return mixed
*/
public static function queueName()
{
return 'CRMEB_PRO_LOG';
}
/**
* @param $type 'visit','cart','order','pay','collect','refund'
* @param $data
* @return bool
*/
public function doJob($type, $data, $productType = 'product')
{
try {
/** @var StoreProductLogServices $productLogServices */
$productLogServices = app()->make(StoreProductLogServices::class);
$productLogServices->createLog($type, $data);
if ($type == 'visit') {
/** @var StoreVisitServices $storeVisit */
$storeVisit = app()->make(StoreVisitServices::class);
$storeVisit->setView($data['uid'] ?? 0, $data['id'] ?? 0, $productType, $data['product_id'] ?? [], 'view');
}
} catch (\Throwable $e) {
response_log_write([
'message' => '写入商品记录发生错误,错误原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 修改警戒库存配置,批量修改商品库存警戒
* @param $page
* @param $limit
* @return true
* @return true
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* User: liusl
* DateTime: 2024/9/13 17:43
*/
public function productStockTips($page, $limit)
{
/** @var StoreProductServices $storeProductServices */
$storeProductServices = app()->make(StoreProductServices::class);
$storeProductServices->runProductStockTips($page, $limit);
return true;
}
}

View File

@@ -0,0 +1,52 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\product;
use app\services\product\product\StoreProductRelationServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 商品关联关系
* Class ProductRelationJob
* @package app\jobs\product
*/
class ProductRelationJob extends BaseJobs
{
use QueueTrait;
/**
* @param int $id
* @param array $relation_id
* @param int $type
* @param int $is_show
* @return bool
*/
public function doJob(int $id, array $relation_id, int $type = 1, int $is_show = 1)
{
try {
/** @var StoreProductRelationServices $storeProductRelationServices */
$storeProductRelationServices = app()->make(StoreProductRelationServices::class);
//商品关联
$storeProductRelationServices->saveRelation($id, $relation_id, $type, $is_show);
} catch (\Throwable $e) {
response_log_write([
'message' => '写入商品关联[type:' . $type . ']发生错误,错误原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,60 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\product;
use app\services\product\product\StoreProductCateServices;
use app\services\product\product\StoreProductReplyServices;use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 商品分类
* Class ProductCateJob
* @package app\jobs\product
*/
class ProductReplyJob extends BaseJobs
{
use QueueTrait;
/**
* 计算商品评分
* @param $id
* @return bool
*/
public function computedProductStar($id)
{
if (!is_array($id)) {
$id = (int)$id;
if (!$id) {
return true;
}
$ids = [$id];
} else {
$ids = $id;
}
try {
/** @var StoreProductReplyServices $storeProductReplayServices */
$storeProductReplayServices = app()->make(StoreProductReplyServices::class);
foreach ($ids as $id) {
$storeProductReplayServices->computedProductStar((int)$id);
}
} catch (\Throwable $e) {
response_log_write([
'message' => '计算商品评分发生错误,错误原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,56 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\product;
use app\services\product\product\StoreProductServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
class ProductStockJob extends BaseJobs
{
use QueueTrait;
/**
* 拆分计算
* @param array $data
* @return bool
*/
public function distribute(array $data): bool
{
try {
foreach ($data as $key => $item) {
ProductStockJob::dispatch('calcValueStock', [$key]);
}
} catch (\Exception $e) {
Log::error(json_encode(['msg' => '拆分计算失败,错误原因:' . $e->getMessage(), 'data' => $data]));
}
return true;
}
/**
* 计算库存
* @param int $id
* @return bool
*/
public function calcValueStock(int $id): bool
{
try {
/** @var StoreProductServices $services */
$services = app()->make(StoreProductServices::class);
$services->calcStockByAttrValue($id);
} catch (\Exception $e) {
Log::error(json_encode(['msg' => '计算商品库存失败,错误原因:' . $e->getMessage(), 'data' => $id]));
}
return true;
}
}

View File

@@ -0,0 +1,52 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\product;
use app\services\product\product\StoreProductStockRecordServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 库存记录
* Class ProductStockRecordJob
* @package app\jobs\product
*/
class ProductStockRecordJob extends BaseJobs
{
use QueueTrait;
/**
* @author 等风来
* @email 136327134@qq.com
* @date 2022/12/8
* @param int $id
* @param array $valueGroup
* @return bool
*/
public function doJob(int $id, array $valueGroup)
{
try {
/** @var StoreProductStockRecordServices $storeProductStockRecordServices */
$storeProductStockRecordServices = app()->make(StoreProductStockRecordServices::class);
//保存库存记录
$storeProductStockRecordServices->saveRecord($id, $valueGroup);
} catch (\Throwable $e) {
response_log_write([
'message' => '写入商品库存记录发生错误,错误原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,57 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\product;
use app\services\product\product\StoreProductServices;
use app\services\product\sku\StoreProductAttrValueServices;
use app\jobs\notice\SocketPushJob;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 商品库存警戒提示
* Class ProductStockTips
* @package app\jobs\product
*/
class ProductStockTips extends BaseJobs
{
use QueueTrait;
public function doJob($productId, $send = 1)
{
/** @var StoreProductServices $make */
$make = app()->make(StoreProductServices::class);
$product = $make->get(['id' => $productId], ['store_name', 'stock', 'id', 'is_police', 'is_sold']);
$store_stock = sys_config('store_stock') ?? 0;//库存预警界限
/** @var StoreProductAttrValueServices $storeValueService */
$storeValueService = app()->make(StoreProductAttrValueServices::class);
$count = $storeValueService->getPolice([
['type', '=', 0],
['stock', '<=', $store_stock],
['product_id', '=', $productId]
]);
$product->is_sold = $storeValueService->get(['type' => 0, 'product_id' => $productId, 'stock' => 0]) ? 1 : 0;
if ($store_stock >= $product['stock'] || $count) {
$product->is_police = 1;
if ($send) {
SocketPushJob::dispatch(['', 'STORE_STOCK', ['id' => $product['store_name'] . '/' . $productId], 'admin']);
}
} else {
$product->is_police = 0;
}
$product->save();
return true;
}
}

View File

@@ -0,0 +1,44 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\product;
use app\jobs\notice\SocketPushJob;
use app\services\product\sku\StoreProductAttrValueServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 库存提醒
* Class ProductStockValueTips
* @package app\jobs\product
*/
class ProductStockValueTips extends BaseJobs
{
use QueueTrait;
public function doJob($productId, $unique, $type)
{
/** @var StoreProductAttrValueServices $make */
$make = app()->make(StoreProductAttrValueServices::class);
$stock = $make->value([
'product_id' => $productId,
'unique' => $unique,
'type' => $type
], 'stock');
$store_stock = sys_config('store_stock') ?? 0;//库存预警界限
if ($store_stock >= $stock) {
// SocketPushJob::dispatch(['', 'STORE_STOCK', ['id' => $productId], 'admin']);
}
return true;
}
}

View File

@@ -0,0 +1,66 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\product;
use app\services\activity\bargain\StoreBargainServices;
use app\services\activity\combination\StoreCombinationServices;
use app\services\activity\integral\StoreIntegralServices;
use app\services\activity\seckill\StoreSeckillServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 商品供应商修改
* Class ProductSupplierJob
* @package app\jobs\product
*/
class ProductSupplierJob extends BaseJobs
{
use QueueTrait;
/**
* 修改商品、活动商品供应商ID
* @param $product_id
* @param $supplier_id
* @return bool
*/
public function updateSupplierId($product_id, $supplier_id = 0)
{
$supplier_id = (int)$supplier_id;
$product_id = (int)$product_id;
if ($product_id && $supplier_id) {
try {
/** @var StoreSeckillServices $seckillServices */
$seckillServices = app()->make(StoreSeckillServices::class);
$seckillServices->update(['product_id' => $product_id], ['type' => 2, 'relation_id' => $supplier_id]);
/** @var StoreCombinationServices $pinkServices */
$pinkServices = app()->make(StoreCombinationServices::class);
$pinkServices->update(['product_id' => $product_id], ['type' => 2, 'relation_id' => $supplier_id]);
/** @var StoreBargainServices $bargainServices */
$bargainServices = app()->make(StoreBargainServices::class);
$bargainServices->update(['product_id' => $product_id], ['type' => 2, 'relation_id' => $supplier_id]);
/** @var StoreIntegralServices $integralServices */
$integralServices = app()->make(StoreIntegralServices::class);
$integralServices->update(['product_id' => $product_id], ['type' => 2, 'relation_id' => $supplier_id]);
} catch (\Throwable $e) {
response_log_write([
'message' => '修改商品供应商ID发生错误,错误原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
}
return true;
}
}

View File

@@ -0,0 +1,361 @@
<?php
namespace app\jobs\product;
use app\services\product\product\StoreProductServices;
use app\services\product\sku\StoreProductAttrServices;
use app\services\product\sku\StoreProductAttrValueServices;
use crmeb\basic\BaseJobs;
use crmeb\exceptions\AdminException;
use crmeb\services\erp\Erp as erpServices;
use crmeb\traits\QueueTrait;
class ProductSyncErp extends BaseJobs
{
use QueueTrait;
/**
* @return mixed
*/
public static function queueName()
{
return 'CRMEB_PRO_ERP';
}
/**
* 同步商品到erp
* @param $id
* @return mixed
*/
public function upProductToErp($id)
{
try {
/** @var StoreProductServices $productServices */
$productServices = app()->make(StoreProductServices::class);
// 获取商品信息
$productInfo = $productServices->getInfo($id)['productInfo'];
$data = [];
$attrs = $productInfo['attrs'];
if (!$attrs && $productInfo['attr']) {
$attrs = [$productInfo['attr']];
}
foreach ($attrs as $item) {
if ($item['pic'] && strstr($item['pic'], 'http') === false) {
$siteUrl = sys_config('site_url');
$item['pic'] = $siteUrl . $item['pic'];
}
$data[] = [
'i_id' => $productInfo['code'],
'sku_id' => $item['code'],
'name' => $productInfo['store_name'],
'properties_value' => str_replace(',', ' ', $item['values']),
's_price' => $item['price'],
'pic' => $item['pic'],
'c_price' => $item['cost'],
'market_price' => $item['ot_price'],
];
}
(new erpServices())->serviceDriver('product')->updateProduct($data);
} catch (\Exception $e) {
response_log_write([
'message' => '商品上传失败, 原因: ' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 上传店铺商品
* @param $id
* @param $shop
* @return bool
*/
public function upBranchProductToErp($id, $shop)
{
try {
/** @var StoreProductServices $productServices */
$productServices = app()->make(StoreProductServices::class);
// 获取商品信息
$productInfo = $productServices->getInfo($id)['productInfo'];
$data = [];
$attrs = $productInfo['attrs'];
if (!$attrs && $productInfo['attr']) {
$attrs = [$productInfo['attr']];
}
foreach ($attrs as $item) {
$data[] = [
'i_id' => $productInfo['code'],
'sku_id' => $item['code'],
'shop_i_id' => $shop['erp_shop_id'] . $productInfo['code'],
'shop_sku_id' => $shop['erp_shop_id'] . $item['code'],
'name' => $productInfo['store_name'],
'properties_value' => str_replace(',', ' ', $item['values']),
'shop_id' => $shop['erp_shop_id'],
];
}
(new erpServices())->serviceDriver('product')->updateShopProduct($data);
} catch (\Exception $e) {
response_log_write([
'message' => '店铺商品上传失败, 原因: ' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 同步商品
* @param $spuArr
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function productFromErp($spuArr)
{
try {
$result = (new erpServices())->serviceDriver('product')->syncProduct([$spuArr]);
$productList = $result['datas'];
$productInfo = [];
/** @var StoreProductServices $productServices */
$productServices = app()->make(StoreProductServices::class);
/** @var StoreProductAttrServices $productAttrServices */
$productAttrServices = app()->make(StoreProductAttrServices::class);
foreach ($productList as $item) {
$productInfo = [
'image' => (string)$item['pic'],
'slider_image' => json_encode([(string)$item['pic']]),
'store_name' => $item['name'],
'store_info' => $item['name'],
'cate_id' => 0,
'price' => floatval($item['s_price']),
'ot_price' => floatval($item['market_price']),
'delivery_type' => '1,2,3',
'freight' => 1,
'is_show' => 0,
'add_time' => time(),
'cost' => floatval($item['c_price']),
'ficti' => 0,
'spec_type' => 1,
'code' => $item['i_id'],
];
$detail = $details = $value = [];
foreach ($item['skus'] as $items) {
$detail[] = $items['properties_value'];
$details[] = [
'name' => $items['properties_value'],
'select' => false
];
$value[] = [
'bar_code' => '',
'brokerage' => 0,
'brokerage_two' => 0,
'code' => $items['sku_id'],
'cost' => floatval($items['cost_price']),
'detail' => ['规格' => $items['properties_value']],
'ot_price' => floatval($items['market_price']),
'pic' => (string)$items['pic'],
'price' => floatval($items['sale_price']),
'select' => true,
'value1' => $items['properties_value'],
'values' => $items['properties_value'],
'vip_price' => 0,
'volume' => 0,
'weight' => 0,
'stock' => 0,
];
}
$pid = $productServices->value(['code' => $item['i_id']], 'id');
if (!$pid) {
$pid = $productServices->ErpProductSave($productInfo);
}
$attr = [[
'value' => '规格',
'detail' => $detail,
'details' => $details,
]];
$skuList = $productAttrServices->validateProductAttr($attr, $value, $pid, 0, 0, 0);
$productAttrServices->saveProductAttr($skuList, $pid);
}
//清除数据缓存
$productServices->cacheTag()->clear();
$productAttrServices->cacheTag()->clear();
} catch (\Exception $e) {
response_log_write([
'message' => '商品同步失败, 原因: ' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 同步商品库存
* @param array $ids
* @return bool
*/
public function stockFromErp(array $ids)
{
try {
/** @var StoreProductServices $storeProductServices */
$storeProductServices = app()->make(StoreProductServices::class);
/** @var StoreProductAttrValueServices $storeProductAttrValueServices */
$storeProductAttrValueServices = app()->make(StoreProductAttrValueServices::class);
//查询ids下的所有规格对应的sku
$list = $storeProductAttrValueServices->getSkuArray(['product_id' => $ids, 'type' => 0], 'code', 'id');
$values = array_filter(array_values($list));
if (empty($values)) {
throw new AdminException('没有符合同步库存的商品');
}
$skuData = $skuMap = [];
$basic = 20; // 单次查询数量最多20
$num = count($values);
$rate = ceil($num / $basic);
for ($i = 0; $i < $rate; $i++) {
$code = array_slice($values, $i * $basic, $basic);
$codeStr = implode(',', $code);
$result = (new erpServices())->serviceDriver('product')->syncStock($codeStr);
if (!empty($result['inventorys'])) {
foreach ($result['inventorys'] as $inventory) {
$skuMap[$inventory['sku_id']] = $inventory['qty'] - $inventory['order_lock'];
}
}
}
// 拼装规格数据
if (!empty($skuMap)) {
foreach ($skuMap as $key => $item) {
if ($id = array_search($key, $list)) {
$skuData[] = ['id' => $id, 'stock' => $item, 'sum_stock' => $item];
}
}
}
// 同步库存
$storeProductServices->transaction(function () use ($ids, $skuData, $storeProductAttrValueServices, $storeProductServices) {
// 同步规格库存
$storeProductAttrValueServices->saveAll($skuData);
// 同步商品库存
$productData = $storeProductAttrValueServices->getProductStockByValues($ids);
$storeProductServices->saveAll($productData);
});
//清除缓存
$storeProductServices->cacheTag()->clear();
/** @var StoreProductAttrServices $attrService */
$attrService = app()->make(StoreProductAttrServices::class);
$attrService->cacheTag()->clear();
} catch (\Exception $e) {
response_log_write([
'message' => '库存获取失败, 原因: ' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 更新商品库存
* @param array $list
* @return bool
*/
public function updatePlatformStock(array $list): bool
{
try {
$data = array_column($list, 'qty', 'sku_id');
$shopData = array_keys(array_column($list, 'shop_id', 'shop_id'));
$erpShopId = $shopData[0] ?? 0;
if ($erpShopId < 1) {
return true;
}
// 更新平台商品库存
$defaultShopId = (int)sys_config('jst_default_shopid');
if ($defaultShopId == $erpShopId) {
$this->updateStoreProductValueStock($data);
}
} catch (\Exception $e) {
response_log_write([
'message' => '更新门店库存失败, 原因: ' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 更新平台商品库存
* @param array $data
* @return bool
*/
public function updateStoreProductValueStock(array $data): bool
{
try {
/** @var StoreProductServices $storeProductServices */
$storeProductServices = app()->make(StoreProductServices::class);
/** @var StoreProductAttrValueServices $storeProductAttrValueServices */
$storeProductAttrValueServices = app()->make(StoreProductAttrValueServices::class);
$skuList = $storeProductAttrValueServices->getSkuArray(['code' => array_keys($data), 'type' => 0], 'id, product_id,code', 'id');
if (empty($skuList)) {
throw new AdminException('没有符合同步库存的商品');
}
$ids = array_unique(array_column($skuList, 'product_id'));
$skuData = [];
foreach ($skuList as $key => $sku) {
if (array_key_exists($sku['code'], $data)) {
$skuData[] = ['id' => $key, 'stock' => $data[$sku['code']]];
}
}
if (empty($skuData)) {
return true;
}
// 同步库存
$storeProductServices->transaction(function () use ($ids, $skuData, $storeProductAttrValueServices, $storeProductServices) {
// 同步规格库存
$storeProductAttrValueServices->saveAll($skuData);
// 同步商品库存
$productData = $storeProductAttrValueServices->getProductStockByValues($ids);
$storeProductServices->saveAll($productData);
});
} catch (\Exception $e) {
response_log_write([
'message' => '平台商品库存更新失败, 原因: ' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,45 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\supplier;
use app\services\supplier\finance\SupplierFlowingWaterServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 供应商资金流水记录
* Class SupplierFinanceJob
* @package app\jobs
*/
class SupplierFinanceJob extends BaseJobs
{
use QueueTrait;
/**供应商流水
* @param int $oid
* @param int $type
* @return bool
*/
public function doJob(int $oid, int $type)
{
try {
/** @var SupplierFlowingWaterServices $supplierFlowServices */
$supplierFlowServices = app()->make(SupplierFlowingWaterServices::class);
$supplierFlowServices->setSupplierFinance($oid, $type);
} catch (\Throwable $e) {
Log::error('记录流水失败:' . $e->getMessage());
}
return true;
}
}

View File

@@ -0,0 +1,55 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\system;
use app\services\system\log\SystemLogServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 后台日志
* Class AdminLogJob
* @package app\jobs\system
*/
class AdminLogJob extends BaseJobs
{
use QueueTrait;
/**
* @return mixed
*/
public static function queueName()
{
return 'CRMEB_PRO_LOG';
}
/**
* @param $adminId
* @param $adminName
* @param $module
* @param $rule
* @param $ip
* @param $type
* @return bool
*/
public function doJob($adminId, $adminName, $module, $rule, $ip, $type)
{
try {
/** @var SystemLogServices $services */
$services = app()->make(SystemLogServices::class);
$services->recordAdminLog((int)$adminId, $adminName, $module, $rule, $ip, $type);
} catch (\Exception) {
}
return true;
}
}

View File

@@ -0,0 +1,55 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\system;
use crmeb\basic\BaseJobs;
use app\services\system\attachment\SystemAttachmentServices;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 自动清除海报
* Class AutoClearPosterJob
* @package app\jobs\user
*/
class AutoClearPosterJob extends BaseJobs
{
use QueueTrait;
/**
* @return string
*/
protected static function queueName()
{
return 'CRMEB_PRO_TASK';
}
/**
* @param $event
*/
public function doJob()
{
//清除昨日海报
try {
/** @var SystemAttachmentServices $attach */
$attach = app()->make(SystemAttachmentServices::class);
$attach->emptyYesterdayAttachment();
} catch (\Throwable $e) {
response_log_write([
'message' => '清除昨日海报,失败原因:[' . class_basename($this) . ']' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,54 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\system;
use crmeb\basic\BaseJobs;
use app\services\message\sms\SmsRecordServices;
use crmeb\traits\QueueTrait;
/**
* 自动更新短信状态
* Class AutoSmsCodeJob
* @package app\jobs\user
*/
class AutoSmsCodeJob extends BaseJobs
{
use QueueTrait;
/**
* @return string
*/
protected static function queueName()
{
return 'CRMEB_PRO_TASK';
}
/**
* @param $event
*/
public function doJob()
{
//清除昨日海报
try {
//修改短信发送记录短信状态
$smsRecord = app()->make(SmsRecordServices::class);
$smsRecord->modifyResultCode();
} catch (\Throwable $e) {
response_log_write([
'message' => '自动更新短信状态:[' . class_basename($this) . ']' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,121 @@
<?php
namespace app\jobs\system;
use app\services\system\CapitalFlowServices;
use app\services\user\UserServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 平台资金流水记录
* Class CapitalFlowJob
* @package app\jobs\system
*/
class CapitalFlowJob extends BaseJobs
{
use QueueTrait;
/**
* @param $order
* @param $type
* @return bool
*/
public function doJob($order, $type)
{
if (!$order || !$type) {
return true;
}
$data = [];
try {
switch ($type) {
case 'order'://订单
if (in_array($order['pay_type'], ['weixin', 'alipay', 'offline'])) {
$userServices = app()->make(UserServices::class);
$userInfo = $userServices->get($order['uid'], ['uid', 'nickname']);
$data = [
'order_id' => $order['order_id'],
'store_id' => $order['store_id'] ?? 0,
'uid' => $order['uid'] ?? 0,
'nickname' => $userInfo['nickname'] ?? '游客' . time(),
'phone' => $order['phone'] ?? '',
'price' => $order['pay_price'],
'pay_type' => $order['pay_type'],
];
}
break;
case 'refund'://退款
//退款写入资金流水
if (in_array($order['pay_type'], ['weixin', 'alipay', 'offline'])) {
$userServices = app()->make(UserServices::class);
$userInfo = $userServices->get($order['uid'], ['uid', 'nickname', 'phone']);
//记录资金流水队列
$data = [
'order_id' => $order['order_id'],
'store_id' => $order['store_id'],
'uid' => $order['uid'],
'nickname' => $userInfo['nickname'],
'phone' => $userInfo['phone'],
'price' => $order['refund_price'],
'pay_type' => $order['pay_type'],
];
}
break;
case 'pay_member'://购买付费会员
if ($order['pay_type'] != 'yue') {
$userServices = app()->make(UserServices::class);
$userInfo = $userServices->get($order['uid'], ['uid', 'nickname', 'phone']);
$data = [
'order_id' => $order['order_id'],
'store_id' => 0,
'uid' => $order['uid'],
'nickname' => $userInfo['nickname'],
'phone' => $userInfo['phone'],
'price' => $order['pay_price'],
'pay_type' => $order['pay_type'],
];
}
break;
case 'recharge'://充值
$data = [
'order_id' => $order['order_id'],
'store_id' => $order['store_id'] ?? 0,
'uid' => $order['uid'],
'nickname' => $order['nickname'],
'phone' => $order['phone'],
'price' => $order['price'],
'pay_type' => $order['recharge_type'] ?? 'weixin',
'add_time' => time(),
];
break;
case 'refund_recharge'://充值退款
$data = [
'order_id' => $order['order_id'],
'store_id' => $order['store_id'] ?? 0,
'uid' => $order['uid'],
'nickname' => $order['nickname'],
'phone' => $order['phone'],
'price' => $order['price'],
'pay_type' => $order['recharge_type'] ?? 'weixin',
];
break;
case 'extract'://提现
$data = $order;
break;
case 'luck'://抽奖
$data = $order;
break;
}
if ($data) {
/** @var CapitalFlowServices $capitalFlowServices */
$capitalFlowServices = app()->make(CapitalFlowServices::class);
$capitalFlowServices->setFlow($data, $type);
}
} catch (\Throwable $e) {
Log::error('写入资金流水错误:[' . class_basename($this) . ']' . $e->getMessage());
}
return true;
}
}

View File

@@ -0,0 +1,63 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\system;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use crmeb\services\SpreadsheetExcelService;
use think\facade\Log;
/**
* 导出数据队列
* Class ExportExcelJob
* @package app\jobs
*/
class ExportExcelJob extends BaseJobs
{
use QueueTrait;
/**
* 分批导出excel
* @param $order
* @return bool
*/
public function doJob(array $export = [], string $filename = '', array $header = [], array $title_arr = [], string $suffix = 'xlsx', bool $is_save = false)
{
if (!$export) {
return true;
}
try {
if ($header && $title_arr) {
$title = isset($title_arr[0]) && !empty($title_arr[0]) ? $title_arr[0] : '导出数据';
$name = isset($title_arr[1]) && !empty($title_arr[1]) ? $title_arr[1] : '导出数据';
$info = isset($title_arr[2]) && !empty($title_arr[2]) ? $title_arr[2] : date('Y-m-d H:i:s', time());
SpreadsheetExcelService::instance()
->setExcelHeader($header)
->setExcelTile($title, $name, $info)
->setExcelContent($export)
->excelSave($filename, $suffix, $is_save);
} else {
SpreadsheetExcelService::instance()
->setExcelContent($export)
->excelSave($filename, $suffix, $is_save);
}
} catch (\Throwable $e) {
response_log_write([
'message' => '导出excel' . $title . '失败,原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace app\jobs\system;
use app\services\system\form\SystemFormDataServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 系统表单数据收集
* Class SystemFormDataJob
* @package app\jobs\system
*/
class SystemFormDataJob extends BaseJobs
{
use QueueTrait;
/**
* @param $order
* @param $type
* @return bool
*/
public function doJob($data, $type = 1)
{
if (!$data || !(int)$type) {
return true;
}
$form = [];
try {
switch ($type) {
case '1'://订单
$form = [
'type' => 1,
'relation_id' => $data['id'] ?? 0,
'uid' => $data['uid'] ?? 0,
'system_form_id' => $data['system_form_id'] ?? 0,
'value' => is_string($data['custom_form']) ? json_decode($data['custom_form'], true) : $data['custom_form']
];
break;
}
if ($form) {
/** @var SystemFormDataServices $systemFormDataServices */
$systemFormDataServices = app()->make(SystemFormDataServices::class);
$systemFormDataServices->setFormData($form, (int)$type);
}
} catch (\Throwable $e) {
Log::error('写入系统表单收集数据失败,错误:' . $e->getMessage());
}
return true;
}
}

View File

@@ -0,0 +1,54 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use crmeb\basic\BaseJobs;
use app\services\user\UserIntegralServices;
use crmeb\traits\QueueTrait;
/**
* 自动清空用户积分
* Class AutoClearIntegralJob
* @package app\jobs\user
*/
class AutoClearIntegralJob extends BaseJobs
{
use QueueTrait;
/**
* @return string
*/
protected static function queueName()
{
return 'CRMEB_PRO_TASK';
}
public function doJob()
{
//清空积分
try {
/** @var UserIntegralServices $userIntegralServices */
$userIntegralServices = app()->make(UserIntegralServices::class);
[$clear_time, $start_time, $end_time] = $userIntegralServices->getTime();
//到清空积分的最后一天
if ($clear_time == strtotime(date('Y-m-d', time()))) {
$userIntegralServices->clearExpireIntegral();
}
} catch (\Throwable $e) {
response_log_write([
'message' => '清空积分,失败原因:[' . class_basename($this) . ']' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,92 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use app\services\activity\integral\StoreIntegralOrderServices;
use app\services\message\service\StoreServiceServices;
use app\services\order\OtherOrderServices;
use app\services\order\StoreCartServices;
use app\services\order\StoreOrderRefundServices;
use app\services\order\StoreOrderServices;
use app\services\store\DeliveryServiceServices;
use app\services\store\SystemStoreStaffServices;
use app\services\user\UserAddressServices;
use app\services\user\UserFriendsServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 注销用户队列
*/
class CancelUserJob extends BaseJobs
{
use QueueTrait;
/**
* 用户注销队列
* @param $uid
* @return bool
*/
public function doJob($uid)
{
try {
/** @var SystemStoreStaffServices $storeStaffServices */
$storeStaffServices = app()->make(SystemStoreStaffServices::class);
/** @var DeliveryServiceServices $deliveryServices */
$deliveryServices = app()->make(DeliveryServiceServices::class);
/** @var OtherOrderServices $otherOrderServices */
$otherOrderServices = app()->make(OtherOrderServices::class);
/** @var StoreCartServices $storeCartServices */
$storeCartServices = app()->make(StoreCartServices::class);
/** @var StoreOrderServices $storeOrderServices */
$storeOrderServices = app()->make(StoreOrderServices::class);
/** @var StoreOrderRefundServices $storeOrderRefundServices */
$storeOrderRefundServices = app()->make(StoreOrderRefundServices::class);
/** @var UserAddressServices $addressServices */
$addressServices = app()->make(UserAddressServices::class);
/** @var StoreIntegralOrderServices $integralOrderServices */
$integralOrderServices = app()->make(StoreIntegralOrderServices::class);
/** @var StoreServiceServices $storeServiceServices */
$storeServiceServices = app()->make(StoreServiceServices::class);
/** @var UserFriendsServices $userService */
$userService = app()->make(UserFriendsServices::class);
//删除好友关系记录
$userService->delete(['uid' => $uid]);
// 删除核销员,删除配送员,删除客服
$storeStaffServices->update(['uid' => $uid], ['is_del' => 1]);
$deliveryServices->update(['uid' => $uid], ['is_del' => 1]);
$storeServiceServices->update(['uid' => $uid], ['is_del' => 1]);
// 删除订单,删除退款单,删除其他订单,删除积分订单,删除购物车
$otherOrderServices->update(['uid' => $uid], ['is_del' => 1]);
$storeOrderServices->update(['uid' => $uid], ['is_del' => 1]);
$storeOrderRefundServices->update(['uid' => $uid], ['is_del' => 1]);
$integralOrderServices->update(['uid' => $uid], ['is_del' => 1]);
$storeCartServices->delete(['uid' => $uid]);
// 删除地址
$addressServices->update(['uid' => $uid], ['is_del' => 1]);
} catch (\Throwable $e) {
response_log_write([
'message' => '注销用户失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace app\jobs\user;
use app\services\user\UserServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
class LoginJob extends BaseJobs
{
use QueueTrait;
public function doJob($uid,$ip)
{
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$city = $userServices->convertIp($ip);
if ($city) {
$userInfo = $userServices->get($uid);
if ($userInfo->login_city != $city) {
if($userInfo->login_city != ''){
event('notice.notice', [['phone' => $userInfo->phone, 'time' => date('Y-m-d H:i:s'), 'city' => $city, 'login_city' => $userInfo->login_city], 'login_city_error']);
}
$userInfo->login_city = $city;
$userInfo->save();
}
}
return true;
}
}

View File

@@ -0,0 +1,111 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use app\services\order\StoreCartServices;
use app\services\order\StoreOrderCreateServices;
use app\services\order\StoreOrderSuccessServices;
use app\services\pay\PayServices;
use app\services\user\UserRechargeServices;
use crmeb\basic\BaseJobs;
use crmeb\services\wechat\Payment;
use crmeb\traits\QueueTrait;
use think\facade\Log;
use app\webscoket\SocketPush;
/**
* 付款码支付
* Class MicroPayOrderJob
* @package app\jobs\user
*/
class MicroPayOrderJob extends BaseJobs
{
use QueueTrait;
public function doJob(string $outTradeNo, int $type = 1, int $num = 1)
{
if ($type) {
/** @var UserRechargeServices $make */
$make = app()->make(UserRechargeServices::class);
} else {
/** @var StoreOrderSuccessServices $make */
$make = app()->make(StoreOrderSuccessServices::class);
}
$orderInfo = $make->get(['order_id' => $outTradeNo]);
if (!$orderInfo) {
return true;
}
if ($orderInfo->paid) {
return true;
}
if (!$type && $orderInfo->is_del) {
return true;
}
try {
//查询订单支付状态
$respones = Payment::queryOrder($outTradeNo);
if ($respones['paid'] && ($respones['payInfo']['trade_state'] ?? '') == 'SUCCESS') {
if ($type) {
$make->rechargeSuccess($outTradeNo);
} else {
//删除购物车
/** @var StoreCartServices $cartServices */
$cartServices = app()->make(StoreCartServices::class);
$cartServices->deleteCartStatus($orderInfo['cart_id'] ?? []);
//修改支付状态
$make->paySuccess($orderInfo->toArray(), PayServices::WEIXIN_PAY, [
'trade_no' => $respones['payInfo']['transaction_id'] ?? ''
]);
}
} else {
//15秒后还是状态异常直接取消订单
if ($num >= 3) {
try {
$respones = Payment::reverseOrder($outTradeNo);
if ($type) {
/** @var StoreOrderCreateServices $service */
$service = app()->make(StoreOrderCreateServices::class);
$make->update(
[
'order_id' => $outTradeNo
],
[
$type ? 'remarks' : 'remark' => '支付状态异常自动撤销订单,并从新生成订单号',
'order_id' => $type ? $make->getOrderId() : $service->getNewOrderId(),
]
);
}
} catch (\Throwable $e) {
Log::error(json_encode([
'message' => '撤销订单失败,订单号:' . $outTradeNo . ';错误原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]));
}
return true;
}
$secs = 5;
if (isset($respones['payInfo']['err_code']) && $respones['payInfo']['err_code'] === 'USERPAYING') {
$secs = 10;
}
self::dispatchSece($secs, [$outTradeNo, $type, $num + 1]);
}
} catch (\Throwable $e) {
}
return true;
}
}

View File

@@ -0,0 +1,654 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use app\services\order\StoreOrderServices;
use app\services\product\product\StoreProductLogServices;
use app\services\product\product\StoreProductRelationServices;
use app\services\user\label\UserLabelServices;
use app\services\user\label\UserLabelExtendServices;
use app\services\user\label\UserLabelRelationServices;
use app\services\user\UserBillServices;
use app\services\user\UserMoneyServices;
use app\services\user\UserServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 用户自动打标签队列任务
* Class UserAutoLabelJob
* @package app\jobs\user
*/
class UserAutoLabelJob extends BaseJobs
{
use QueueTrait;
/**
* 处理自动打标签
* @param array $data [uid|uids, trigger_type, trigger_data, ids]
* @return bool
*/
public function doJob($uids, $trigger_type = '', $trigger_data = [], $ids = [])
{
Log::info('开始批量处理自动标签:' . var_export([
'user_ids' => $uids,
'trigger_type' => $trigger_type,
'label_ids' => $ids
], true));
if (!$uids) {
return true;
}
// 兼容单个用户和批量用户处理
if (!is_array($uids)) {
$uids = [$uids];
}
return $this->batchAutoLabel($uids, $trigger_type, $trigger_data, $ids);
}
/**
* 批量处理自动打标签
* @param array $uids 用户ID数组
* @param string $trigger_type 触发类型
* @param array $trigger_data 触发数据
* @param array|null $ids 指定的标签ID
* @return bool
*/
public function batchAutoLabel(array $uids, string $trigger_type, array $trigger_data = [], $ids = null): bool
{
Log::info('开始批量处理自动标签2:' . var_export([
'user_count' => count($uids),
'trigger_type' => $trigger_type,
'label_ids' => $ids
], true));
if (empty($uids)) {
return true;
}
try {
Log::info('开始批量处理自动标签:' . var_export([
'user_count' => count($uids),
'trigger_type' => $trigger_type,
'label_ids' => $ids
], true));
/** @var UserLabelServices $labelServices */
$labelServices = app()->make(UserLabelServices::class);
/** @var UserLabelExtendServices $extendServices */
$extendServices = app()->make(UserLabelExtendServices::class);
/** @var UserLabelRelationServices $relationServices */
$relationServices = app()->make(UserLabelRelationServices::class);
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$where = [
'label_type' => 2, // 自动标签
'status' => 1
];
if ($ids) {
$where['id'] = $ids;
}
// 获取所有自动标签
$autoLabels = $labelServices->search($where)->select()->toArray();
if (!$autoLabels) {
Log::info('没有找到自动标签:' . var_export(['label_ids' => $ids], true));
return true;
}
// 批量获取用户当前标签关系,减少数据库查询
$userLabelsMap = $relationServices->getUserLabelsMap($uids);
$processedCount = 0;
$addedLabels = [];
$removedLabels = [];
foreach ($uids as $uid) {
foreach ($autoLabels as $label) {
// 检查标签是否需要处理当前触发类型
// if (!$this->shouldProcessLabel($label, $trigger_type)) {
// continue;
// }
// 获取标签的扩展规则
$extendRules = $extendServices->getLabelExtendList(['label_id' => $label['id']]);
Log::info('获取标签的扩展规则:' . var_export(['extendRules' => $extendRules], true));
if (!$extendRules) {
continue;
}
// 检查用户是否满足标签条件
$isMatch = $this->checkLabelConditions($uid, $label, $extendRules, $userServices, $trigger_data);
Log::info('检查用户是否满足标签条件:' . var_export([
'isMatch' => $isMatch,
'label_id' => $label['id'],
'label_name' => $label['label_name'],
'user_id' => $uid
], true));
// 获取用户当前是否有此标签
$userLabels = $userLabelsMap[$uid] ?? [];
$hasLabel = in_array($label['id'], $userLabels);
if ($isMatch && !$hasLabel) {
// 满足条件且没有标签,记录需要添加的标签
$addedLabels[] = [
'uid' => $uid,
'label_id' => $label['id'],
'label_name' => $label['label_name']
];
} elseif (!$isMatch && $hasLabel) {
// 不满足条件但有标签,记录需要移除的标签
$removedLabels[] = [
'uid' => $uid,
'label_id' => $label['id'],
'label_name' => $label['label_name']
];
}
}
$processedCount++;
}
// 批量处理标签添加
if (!empty($addedLabels)) {
$this->batchAddLabels($addedLabels, $relationServices);
}
// 批量处理标签移除
if (!empty($removedLabels)) {
$this->batchRemoveLabels($removedLabels, $relationServices);
}
Log::info('批量自动标签处理完成:' . var_export([
'processed_users' => $processedCount,
'added_labels' => count($addedLabels),
'removed_labels' => count($removedLabels),
'trigger_type' => $trigger_type
], true));
} catch (\Throwable $e) {
Log::error('批量自动打标签失败:' . var_export([
'user_count' => count($uids),
'trigger_type' => $trigger_type,
'error' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
], true));
return false;
}
return true;
}
/**
* 批量添加标签
* @param array $addedLabels
* @param UserLabelRelationServices $relationServices
* @return void
*/
protected function batchAddLabels(array $addedLabels, $relationServices): void
{
try {
// 按用户分组标签
$userLabelGroups = [];
foreach ($addedLabels as $item) {
$userLabelGroups[$item['uid']][] = $item['label_id'];
}
// 批量添加标签
foreach ($userLabelGroups as $uid => $labelIds) {
$relationServices->setUserLable($uid, $labelIds);
}
Log::info('批量添加标签完成:' . var_export([
'user_count' => count($userLabelGroups),
'total_labels' => count($addedLabels)
], true));
} catch (\Throwable $e) {
Log::error('批量添加标签失败:' . var_export([
'error' => $e->getMessage(),
'labels_count' => count($addedLabels)
], true));
}
}
/**
* 批量移除标签
* @param array $removedLabels
* @param UserLabelRelationServices $relationServices
* @return void
*/
protected function batchRemoveLabels(array $removedLabels, $relationServices): void
{
try {
// 按用户分组标签
$userLabelGroups = [];
foreach ($removedLabels as $item) {
$userLabelGroups[$item['uid']][] = $item['label_id'];
}
// 批量移除标签
foreach ($userLabelGroups as $uid => $labelIds) {
$relationServices->unUserLabel($uid, $labelIds);
}
Log::info('批量移除标签完成:' . var_export([
'user_count' => count($userLabelGroups),
'total_labels' => count($removedLabels)
], true));
} catch (\Throwable $e) {
Log::error('批量移除标签失败:' . var_export([
'error' => $e->getMessage(),
'labels_count' => count($removedLabels)
], true));
}
}
/**
* 检查标签是否需要处理当前触发类型
* @param array $label
* @param string $trigger_type
* @return bool
*/
private function shouldProcessLabel(array $label, string $trigger_type): bool
{
switch ($trigger_type) {
case 'product': // 商品相关触发
return $label['is_product'] == 1;
case 'property': // 资产相关触发
return $label['is_property'] == 1;
case 'trade': // 交易相关触发
return $label['is_trade'] == 1;
case 'customer': // 客户相关触发
return $label['is_customer'] == 1;
case 'all': // 处理所有类型
return true;
default:
return true; // 默认处理所有类型
}
}
/**
* 检查用户是否满足标签条件
* @param int $uid
* @param array $label
* @param array $extendRules
* @param UserServices $userServices
* @param array $trigger_data 触发数据
* @return bool
*/
private function checkLabelConditions(int $uid, array $label, array $extendRules, UserServices $userServices, array $trigger_data = []): bool
{
// 初始化各类条件检查结果,默认只初始化需要检查的类型
$is_product = $label['is_product'] == 1 ? true : null;
$is_property = $label['is_property'] == 1 ? true : null;
$is_trade = $label['is_trade'] == 1 ? true : null;
$is_customer = $label['is_customer'] == 1 ? true : null;
foreach ($extendRules as $rule) {
switch ($rule['rule_type']) {
case 1: // 商品条件
if ($label['is_product'] == 1) {
// 只有当标签启用商品条件时才进行检查
if (!$this->checkProductCondition($uid, $rule, $trigger_data)) {
$is_product = false;
}
}
break;
case 2: // 资产条件
if ($label['is_property'] == 1) {
// 只有当标签启用资产条件时才进行检查
if (!$this->checkPropertyCondition($uid, $rule, $trigger_data)) {
$is_property = false;
}
}
break;
case 3: // 交易条件
if ($label['is_trade'] == 1) {
// 只有当标签启用交易条件时才进行检查
if (!$this->checkTradeCondition($uid, $rule, $trigger_data)) {
$is_trade = false;
}
}
break;
case 4: // 客户条件
if ($label['is_customer'] == 1) {
// 只有当标签启用客户条件时才进行检查
if (!$this->checkCustomerCondition($uid, $rule, $userServices, $trigger_data)) {
$is_customer = false;
}
}
break;
}
}
// 构造用于日志记录的实际检查结果
$logData = [
'uid' => $uid,
'is_product' => $is_product,
'is_property' => $is_property,
'is_trade' => $is_trade,
'is_customer' => $is_customer
];
Log::info('标签条件检查结果:' . var_export($logData, true));
// 收集实际参与判断的条件结果
$conditions = [];
if ($label['is_product'] == 1) {
$conditions[] = $is_product !== false; // 如果未检查则默认为true
}
if ($label['is_property'] == 1) {
$conditions[] = $is_property !== false;
}
if ($label['is_trade'] == 1) {
$conditions[] = $is_trade !== false;
}
if ($label['is_customer'] == 1) {
$conditions[] = $is_customer !== false;
}
// 根据条件类型判断是否满足
if ($label['is_condition'] == 1) {
// 满足任一条件
return in_array(true, $conditions, true);
} else {
// 满足全部条件
return !in_array(false, $conditions, true);
}
}
/**
* 检查商品条件
* @param int $uid
* @param array $rule
* @param array $trigger_data 触发数据,可能包含商品ID、订单信息等
* @return bool
*/
private function checkProductCondition(int $uid, array $rule, array $trigger_data = []): bool
{
$storeProductRelationServices = app()->make(StoreProductRelationServices::class);
// TODO: 实现商品条件检查逻辑
//用户购买过的商品 id 总和
$pids = app()->make(StoreProductLogServices::class)->search(['uid' => $uid, 'type' => 'pay'])->column('product_id');
//去重
$pids = array_unique($pids);
$productIds = is_array($rule['product_ids']) ? $rule['product_ids'] : explode(',', $rule['product_ids']);
//记录日志
switch ($rule['specify_dimension']) {
// 1=>商品,2=>分类,3=>标签
case 1:
Log::info('商品条件(购买商品)检查日志:' . var_export(['uid' => $uid, 'pids' => $pids, 'productIds' => $productIds, 'rule' => $rule], true));
//判断$pids全部包含$product_ids
return $pids && count(array_diff($productIds, $pids)) == 0;
case 2:
//分类
$cateIds = $storeProductRelationServices->search(['product_id' => $pids, 'type' => 1])->column('relation_id');
$cateIds = array_unique($cateIds);
Log::info('商品条件(购买商品分类)检查日志:' . var_export([
'uid' => $uid,
'label_id'=>$rule['label_id'],
'productIds'=>$productIds,
'pids' => $pids,
'cateIds' => $cateIds,
'rule' => $rule
], true));
return $pids && count(array_diff($productIds, $cateIds)) == 0;
case 3:
//标签
$cateIds = $storeProductRelationServices->search(['product_id' => $pids, 'type' => 3])->column('relation_id');
$cateIds = array_unique($cateIds);
Log::info('商品条件(购买商品标签)检查日志:' . var_export([
'uid' => $uid,
'label_id'=>$rule['label_id'],
'productIds'=>$productIds,
'pids' => $pids,
'cateIds' => $cateIds,
'rule' => $rule
], true));
return $pids && count(array_diff($productIds, $cateIds)) == 0;
default :
return false;
}
}
/**
* 检查资产条件
* @param int $uid
* @param array $rule
* @param array $trigger_data 触发数据,可能包含充值金额、余额变动等
* @return bool
*/
private function checkPropertyCondition(int $uid, array $rule, array $trigger_data = []): bool
{
//数值
$amount_value_min = $rule['amount_value_min'];
$amount_value_max = $rule['amount_value_max'];
//次数
$operation_times_min = $rule['operation_times_min'];
$operation_times_max = $rule['operation_times_max'];
$userBillServices = app()->make(UserBillServices::class);
$userMoneyServices = app()->make(UserMoneyServices::class);
// TODO: 实现资产条件检查逻辑
if ($rule['sub_type'] == 1) {
//积分
$integral = $userBillServices->search(['uid' => $uid, 'category' => 'integral', 'type' => 'deduction'])->sum('number');
Log::info('资产条件(积分)检查日志:' . var_export(['uid' => $uid, 'integral' => $integral, 'rule' => $rule], true));
return $integral >= $amount_value_min && $integral <= $amount_value_max;
} else {
//余额充值消耗次数和金额
$where = ['uid' => $uid, 'type' => ['pay_product', 'recharge']];
$list = $userMoneyServices->search($where)->select()->toArray();
//充值金额,充值次数,消耗金额,消耗次数
$recharge_amount = $recharge_times = $consume_amount = $consume_times = 0;
foreach ($list as $item) {
if ($item['type'] == 'recharge') {
$recharge_amount += $item['number'];
$recharge_times++;
} else {
$consume_amount += $item['number'];
$consume_times++;
}
}
Log::info('资产条件(余额)检查日志:' . var_export([
'uid' => $uid,
'recharge_amount' => $recharge_amount,
'recharge_times' => $recharge_times,
'consume_amount' => $consume_amount,
'consume_times' => $consume_times,
'rule' => $rule
], true));
//余额
if ($rule['balance_type'] == 1) {
//充值
if ($rule['operation_type'] == 1) {
//次数
return $recharge_times >= $operation_times_min && $recharge_times <= $operation_times_max;
} else {
//金额
return $recharge_amount >= $amount_value_min && $recharge_amount <= $amount_value_max;
}
} else {
//消耗
if ($rule['operation_type'] == 1) {
//次数
return $consume_times >= $operation_times_min && $consume_times <= $operation_times_max;
} else {
//金额
return $consume_amount >= $amount_value_min && $consume_amount <= $amount_value_max;
}
}
}
}
/**
* 检查交易条件
* @param int $uid
* @param array $rule
* @param array $trigger_data 触发数据,可能包含订单金额、支付方式等
* @return bool
*/
private function checkTradeCondition(int $uid, array $rule, array $trigger_data = []): bool
{
//数值
$amount_value_min = $rule['amount_value_min'];
$amount_value_max = $rule['amount_value_max'];
//次数
$operation_times_min = $rule['operation_times_min'];
$operation_times_max = $rule['operation_times_max'];
$storeOrderServices = app()->make(StoreOrderServices::class);
$where = ['pid' => 0, 'uid' => $uid, 'paid' => 1, 'refund_status' => [0, 3], 'is_del' => 0, 'is_system_del' => 0];
if ($rule['operation_type'] == 1) {
$count = $storeOrderServices->count($where);
Log::info('交易条件(订单次数)检查日志:' . var_export([
'uid' => $uid,
'count' => $count,
'rule' => $rule
], true));
return $count >= $operation_times_min && $count <= $operation_times_max;
} else {
$pay_price = $storeOrderServices->together($where, 'pay_price');
Log::info('交易条件(订单金额)检查日志:' . var_export([
'uid' => $uid,
'pay_price' => $pay_price,
'rule' => $rule
], true));
return $pay_price >= $amount_value_min && $pay_price <= $amount_value_max;
}
}
/**
* 检查客户条件
* @param int $uid
* @param array $rule
* @param UserServices $userServices
* @param array $trigger_data 触发数据,可能包含用户行为信息等
* @return bool
*/
private function checkCustomerCondition(int $uid, array $rule, UserServices $userServices, array $trigger_data = []): bool
{
try {
$userInfo = $userServices->getUserInfo($uid);
if (!$userInfo) {
return false;
}
switch ($rule['customer_identity']) {
case 1: // 注册时间
$registerTime = $userInfo['add_time'];
$res = $this->checkTimeRange($registerTime, $rule['customer_time_start'], $rule['customer_time_end']);
Log::info('检查注册时间条件:' . var_export([
'registerTime' => $registerTime,
'rule' => [
'customer_time_start' => $rule['customer_time_start'],
'customer_time_end' => $rule['customer_time_end']
],
'res' => $res
],true));
return $res;
case 2: // 访问时间
$lastTime = $userInfo['last_time'];
$res = $this->checkTimeRange($lastTime, $rule['customer_time_start'], $rule['customer_time_end']);
Log::info('检查访问时间条件:' . var_export([
'lastTime' => $lastTime,
'rule' => [
'customer_time_start' => $rule['customer_time_start'],
'customer_time_end' => $rule['customer_time_end']
],
'res' => $res
],true));
return $res;
case 3: // 用户等级
$userLevel = $userInfo['level'] ?? 0;
$res = $userLevel == $rule['customer_num'];
Log::info('检查用户等级条件:' . var_export([
'userLevel' => $userLevel,
'rule' => [
'customer_num' => $rule['customer_num']
],
'res' => $res
],true));
return $res;
case 4: // 客户身份
//$checkUserTag是数组,包含 //1等级会员,2付费会员,3推广员,4采购商
$checkUserTag = $userServices->checkUserTag($uid);
$res = in_array($rule['customer_num'], $checkUserTag);
Log::info('检查客户身份条件:' . var_export([
'checkUserTag' => $checkUserTag,
'rule' => [
'customer_num' => $rule['customer_num']
],
'res' => $res
],true));
return $res;
default:
return false;
}
} catch (\Throwable $e) {
Log::error('检查客户条件失败:' . var_export([
'uid' => $uid,
'rule' => $rule,
'error' => $e->getMessage()
], true));
return false;
}
}
/**
* 检查时间范围
* @param int $time
* @param int $startTime
* @param int $endTime
* @return bool
*/
private function checkTimeRange(int $time, int $startTime, int $endTime): bool
{
if ($startTime && $time < $startTime) {
return false;
}
if ($endTime && $time > $endTime) {
return false;
}
return true;
}
/**
* 检查客户身份
* @param array $userInfo
* @param int $identityType
* @return bool
*/
private function checkCustomerIdentity(array $userInfo, int $identityType): bool
{
switch ($identityType) {
case 1: // 等级会员
return isset($userInfo['level']) && $userInfo['level'] > 0;
case 2: // 付费会员
return isset($userInfo['is_money_level']) && $userInfo['is_money_level'] > 0;
case 3: // 推广员
return isset($userInfo['is_promoter']) && $userInfo['is_promoter'] == 1;
case 4: // 采购商
// TODO: 根据实际业务逻辑判断采购商身份
return false;
default:
return false;
}
}
}

View File

@@ -0,0 +1,157 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use app\services\user\label\UserLabelRelationServices;
use app\services\user\UserServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 用户批量任务队列
* Class UserBatchJob
* @package app\jobs\user
*/
class UserBatchJob extends BaseJobs
{
use QueueTrait;
/**
* @return mixed
*/
public static function queueName()
{
$default = config('queue.default');
return config('queue.connections.' . $default . '.batch_queue');
}
/**
* 用户批量队列
* @param $type
* @param $uids
* @param $data
* @return bool
*/
public function userBatch($type, $uids, $data, $label_type = 0)
{
if (!$type || !$uids || !$data) {
return true;
}
//拆分大数组 分批加入二级队列
$uidsArr = array_chunk($uids, 100);
foreach ($uidsArr as $ids) {
//加入分批队列
self::dispatchDo('chunkUserBatch', [$type, $ids, $data, $label_type]);
}
return true;
}
/**
* 拆分分批队列
* @param $type
* @param $uids
* @param $data
* @return bool
*/
public function chunkUserBatch($type, $uids, $data, $label_type = 0)
{
if (!$type || !$uids || !$data) {
return true;
}
foreach ($uids as $id) {
self::dispatchDo('runUserBatch', [$type, $id, $data, $label_type]);
}
return true;
}
/**
* 实际执行用户操作队列
* @param $type
* @param $uid
* @param $data
* @return bool
*/
public function runUserBatch($type, $uid, $data, $label_type = 0)
{
$uid = (int)$uid;
if (!$type || !$uid || !$data) {
return true;
}
try {
switch ($type) {
case 1://分组
$group_id = (int)($data['group_id'] ?? 0);
if ($group_id) {
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$userServices->setUserGroup([$uid], $group_id);
}
break;
case 2://标签
$label_id = $data['label_id'] ?? [];
if ($label_id) {
/** @var UserLabelRelationServices $services */
$services = app()->make(UserLabelRelationServices::class);
$services->setUserLable($uid, $label_id, 0, 0, false, $label_type);
}
break;
case 3://等级
$level_id = (int)($data['level_id'] ?? 0);
if ($level_id) {
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$userServices->saveGiveLevel($uid, $level_id);
}
break;
case 4://积分余额
$data['money'] = (string)$data['money'];
$data['integration'] = (string)$data['integration'];
$data['is_other'] = true;
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$userServices->updateInfo($uid, $data);
break;
case 5://赠送会员
$day = (int)($data['day'] ?? 0);
if ($day) {
$day_status = (int)($data['days_status'] ?? 1);
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$userServices->saveGiveLevelTime($uid, $day, $day_status);
}
break;
case 6://上级推广人
$spread_uid = (int)($data['spread_uid'] ?? 0);
if ($spread_uid) {
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$userServices->saveUserSpreadUid($uid, $spread_uid);
}
break;
default:
break;
}
} catch (\Throwable $e) {
response_log_write([
'message' => '批量操作用户,type:' . $type . ';状态失败,' . ';参数:' . json_encode(['uid' => $uid, 'data' => $data]) . ', 失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,231 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use app\services\user\UserServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 用户生日格式转换队列任务
* Class UserBirthdayFormatJob
* @package app\jobs\user
*/
class UserBirthdayFormatJob extends BaseJobs
{
use QueueTrait;
/**
* 处理用户生日格式转换
* @param array $userIds 用户ID数组,如果为空则处理所有用户
* @param int $batchSize 批处理大小,默认100
* @return bool
*/
public function doJob($userIds = [], $batchSize = 100)
{
try {
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
Log::info('开始处理用户生日格式转换任务', [
'user_ids' => $userIds,
'batch_size' => $batchSize
]);
// 如果没有指定用户ID,则查询所有需要处理的用户
if (empty($userIds)) {
$userIds = $this->getUsersWithTimestampBirthday($userServices);
}
if (empty($userIds)) {
Log::info('没有找到需要处理的用户生日数据');
return true;
}
// 分批处理用户数据
$chunks = array_chunk($userIds, $batchSize);
$totalChunks = count($chunks);
Log::info('开始分批处理用户生日数据', [
'total_users' => count($userIds),
'total_chunks' => $totalChunks,
'batch_size' => $batchSize
]);
foreach ($chunks as $index => $chunk) {
$this->processBirthdayBatch($userServices, $chunk, $index + 1, $totalChunks);
}
Log::info('用户生日格式转换任务完成', [
'processed_users' => count($userIds)
]);
return true;
} catch (\Throwable $e) {
Log::error('用户生日格式转换任务执行失败', [
'message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString()
]);
return false;
}
}
/**
* 获取生日字段为时间戳格式的用户ID
* @param UserServices $userServices
* @return array
*/
private function getUsersWithTimestampBirthday($userServices)
{
try {
// 查询birthday字段不为空且不为0的用户
// 时间戳通常是10位数字,大于946684800(2000-01-01的时间戳)
$users = $userServices->search([])
->where('birthday', '<>', 0)
->where('is_del', 0)
->column('uid');
Log::info('查询到需要处理的用户', [
'count' => count($users)
]);
return $users;
} catch (\Throwable $e) {
Log::error('查询用户生日数据失败', [
'message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
return [];
}
}
/**
* 批量处理用户生日数据
* @param UserServices $userServices
* @param array $userIds
* @param int $currentBatch
* @param int $totalBatches
* @return void
*/
private function processBirthdayBatch($userServices, $userIds, $currentBatch, $totalBatches)
{
try {
Log::info("处理第 {$currentBatch}/{$totalBatches} 批用户数据", [
'user_ids' => $userIds,
'count' => count($userIds)
]);
// 获取用户数据
$users = $userServices->search([])
->whereIn('uid', $userIds)
->where('is_del', 0)
->field('uid,birthday')
->select()
->toArray();
$updateCount = 0;
$errorCount = 0;
foreach ($users as $user) {
try {
$uid = $user['uid'];
$birthday = $user['birthday'];
// 检查是否为时间戳格式(10位数字)
if (!$this->isTimestamp($birthday)) {
continue;
}
// 将时间戳转换为日期格式 Y-m-d
$birthdayDate = date('Y-m-d', $birthday);
// 更新用户生日数据
$result = $userServices->search([])
->where('uid', $uid)
->update(['birthday' => $birthdayDate]);
if ($result) {
$updateCount++;
Log::debug("用户 {$uid} 生日格式转换成功", [
'old_birthday' => $birthday,
'new_birthday' => $birthdayDate,
'timestamp' => strtotime($birthdayDate)
]);
}
} catch (\Throwable $e) {
$errorCount++;
Log::error("处理用户 {$uid} 生日数据失败", [
'uid' => $uid,
'birthday' => $birthday,
'message' => $e->getMessage()
]);
}
}
Log::info("第 {$currentBatch} 批处理完成", [
'total_users' => count($users),
'updated_count' => $updateCount,
'error_count' => $errorCount
]);
} catch (\Throwable $e) {
Log::error("批量处理用户生日数据失败", [
'batch' => $currentBatch,
'user_ids' => $userIds,
'message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
}
/**
* 检查是否为时间戳格式
* @param mixed $value
* @return bool
*/
private function isTimestamp($value)
{
// 检查是否为数字且在合理的时间戳范围内
if (!is_numeric($value)) {
return false;
}
$timestamp = (int)$value;
// 时间戳应该在1970年到2100年之间
return $timestamp > 0 && $timestamp > 946684800 && $timestamp < 4102444800;
}
/**
* 手动触发处理指定用户的生日格式转换
* @param array $userIds 指定的用户ID数组
* @return bool
*/
public function processSpecificUsers($userIds)
{
if (empty($userIds)) {
return false;
}
return $this->doJob($userIds);
}
}

View File

@@ -0,0 +1,65 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use app\services\order\StoreOrderServices;
use app\services\user\UserBrokerageServices;
use app\services\user\UserServices;
use app\services\user\UserSpreadServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 佣金记录
* Class UserSpreadJob
* @package app\jobs\user
*/
class UserBrokerageJob extends BaseJobs
{
use QueueTrait;
/**
* 老数据同步佣金
* @param $info
* @return true
* User: liusl
* DateTime: 2024/11/23 上午11:37
*/
public function syncOldBrokeragePrice()
{
try {
$userBrokerageServices = app()->make(UserBrokerageServices::class);
$storeOrderServices = app()->make(StoreOrderServices::class);
$userBrokerageServices->search([])->whereIn('type', $userBrokerageServices->isBrokerage)->chunk(100, function ($list) use ($userBrokerageServices, $storeOrderServices) {
$list = $list->toArray();
foreach ($list as $item) {
if (!$item['order_uid']) {
$orderInfo = $storeOrderServices->getOne(['id' => $item['link_id']], 'uid,pay_price');
if ($orderInfo) {
$userBrokerageServices->update($item['id'], ['order_uid' => $orderInfo['uid'] ?? 0, 'order_price' => $orderInfo['pay_price'] ?? 0]);
}
}
}
});
return true;
} catch (\Throwable $e) {
response_log_write([
'message' => '同步旧版佣金金额失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,55 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use app\services\user\UserFriendsServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 用户好友关系
* Class UserFriendsJob
* @package app\jobs\user
*/
class UserFriendsJob extends BaseJobs
{
use QueueTrait;
/**
* 记录用户好友关系
* @param int $uid
* @param int $spreadUid
* @return bool
*/
public function doJob(int $uid, int $spreadUid)
{
if (!$uid || !$spreadUid || $uid == $spreadUid) {
return true;
}
try {
/** @var UserFriendsServices $serviceFriend */
$serviceFriend = app()->make(UserFriendsServices::class);
$serviceFriend->saveFriend($uid, $spreadUid);
} catch (\Throwable $e) {
response_log_write([
'message' => '记录好友关系失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,51 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use app\services\other\Import\ImportRecordServices;
use app\services\user\UserServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 导入用户数据
* Class UserImportJob
* @package app\jobs\user
*/
class UserImportJob extends BaseJobs
{
use QueueTrait;
/**
* 导入用户数据
* @return bool
*/
public function doJob(int $id, array $data, bool $end)
{
if (!$id || !is_array($data)) {
return true;
}
try {
app()->make(ImportRecordServices::class)->userSingleImport($data, $id, $end);
} catch (\Throwable $e) {
response_log_write([
'message' => '导入用户数据失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,95 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use app\services\user\UserIntegralServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 清除到期积分
* Class UserIntegralJob
* @package app\jobs
*/
class UserIntegralJob extends BaseJobs
{
use QueueTrait;
/**
* 执行清除到期积分
* @param $openids
* @return bool
*/
public function doJob($uids)
{
if (!$uids || !is_array($uids)) {
return true;
}
try {
/** @var UserIntegralServices $userIntegralServices */
$userIntegralServices = app()->make(UserIntegralServices::class);
$userIntegralServices->doClearExpireIntegral($uids);
} catch (\Throwable $e) {
response_log_write([
'message' => '清除用户到期积分失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 赠送新人礼积分
* @param $uid
* @return bool
*/
public function newcomerGiveIntegral($uid)
{
try {
/** @var UserIntegralServices $userIntegralServices */
$userIntegralServices = app()->make(UserIntegralServices::class);
$userIntegralServices->newcomerGiveIntegral((int)$uid);
} catch (\Throwable $e) {
response_log_write([
'message' => '赠送新人礼积分失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 会员卡激活赠送积分
* @param $uid
* @return bool
*/
public function levelGiveIntegral($uid)
{
try {
/** @var UserIntegralServices $userIntegralServices */
$userIntegralServices = app()->make(UserIntegralServices::class);
$userIntegralServices->levelGiveIntegral((int)$uid);
} catch (\Throwable $e) {
response_log_write([
'message' => '会员卡激活赠送积分失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

320
app/jobs/user/UserJob.php Normal file
View File

@@ -0,0 +1,320 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use app\services\activity\lottery\LuckLotteryServices;
use app\services\activity\newcomer\StoreNewcomerServices;
use app\services\message\wechat\MessageServices;
use app\services\user\UserBillServices;
use app\services\user\UserServices;
use app\services\wechat\WechatUserServices;
use app\services\work\WorkClientServices;
use app\services\work\WorkMemberServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 同步用户
* Class UserJob
* @package app\jobs
*/
class UserJob extends BaseJobs
{
use QueueTrait;
/**
* 执行同步数据后
* @param $openids
* @return bool
*/
public function doJob($openids)
{
if (!$openids || !is_array($openids)) {
return true;
}
$noBeOpenids = [];
try {
/** @var WechatUserServices $wechatUser */
$wechatUser = app()->make(WechatUserServices::class);
$noBeOpenids = $wechatUser->syncWechatUser($openids);
} catch (\Throwable $e) {
response_log_write([
'message' => '更新wechatUser用户信息失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
if (!$noBeOpenids) {
return true;
}
try {
/** @var UserServices $user */
$user = app()->make(UserServices::class);
$user->importUser($noBeOpenids);
} catch (\Throwable $e) {
response_log_write([
'message' => '新增用户失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 关注推广新用户(发送抽奖消息 、推广用户增加抽奖次数)
* @param int $uid
* @param string $openid
* @param int $spread_uid
* @return bool
*/
public function subscribeSpreadLottery(int $uid, string $openid, int $spread_uid)
{
/** @var LuckLotteryServices $lotteryServices */
$lotteryServices = app()->make(LuckLotteryServices::class);
$lottery = $lotteryServices->getFactorLottery(5);
if (!$lottery) {
return true;
}
try {
/** @var MessageServices $messageServices */
$messageServices = app()->make(MessageServices::class);
$messageServices->wechatEvent(['third_type' => 'luckLottery-' . $uid, 'lottery' => $lottery], $openid);
} catch (\Throwable $e) {
response_log_write([
'message' => '发送关注抽奖消息失败,原因:' . $e->getMessage(),
'line' => $e->getLine(),
'file' => $e->getFile()
]);
}
if (!$spread_uid) {
return true;
}
try {
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$spreadUser = $userServices->getUserInfo($spread_uid, 'uid,spread_lottery');
//增加推广用户抽奖次数
if (!$spreadUser) {
return true;
}
if ($lottery['lottery_num_term'] == 1) {
$where = ['time' => 'today', 'timeKey' => 'spread_time'];
} else {
$where = ['spread_uid' => $spreadUser['uid']];
}
$spreadCount = $userServices->count($where);
if ($spreadCount) {
$lotterySum = bcmul((string)$spreadCount, (string)$lottery['spread_num'], 0);
if ($lotterySum < $lottery['lottery_num']) {
$update_lottery_num = $spreadUser['spread_lottery'] + (int)$lottery['spread_num'];
if ($update_lottery_num > $lottery['lottery_num']) {
$update_lottery_num = $lottery['lottery_num'];
}
$userServices->update($spreadUser['uid'], ['spread_lottery' => $update_lottery_num], 'uid');
}
}
} catch (\Throwable $e) {
response_log_write([
'message' => '增加推广用户抽奖次数失败,原因:' . $e->getMessage(),
'line' => $e->getLine(),
'file' => $e->getFile()
]);
}
return true;
}
/**
* 绑定企业微信成员
* @param $uid
* @param $unionid
* @return bool
*/
public function bindWorkMember($uid, $unionid)
{
if (!$unionid) {
return true;
}
/** @var WorkClientServices $service */
$service = app()->make(WorkClientServices::class);
$clienInfo = $service->get(['unionid' => $unionid], ['id', 'external_userid', 'uid'], ['followOne']);
if ($clienInfo) {
if (!$clienInfo->uid) {
$clienInfo->uid = $uid;
$clienInfo->save();
}
if (!empty($clienInfo->followOne->userid)) {
$userId = $clienInfo->followOne->userid;
/** @var WorkMemberServices $memberService */
$memberService = app()->make(WorkMemberServices::class);
$menber = $memberService->get(['userid' => $userId], ['uid', 'mobile']);
if (!$menber) {
response_log_write([
'message' => '绑定企业微信成员失败:没有查询到成员身份',
'request' => ['uid' => $uid, 'unionid' => $unionid],
]);
return true;
}
/** @var UserServices $userService */
$userService = app()->make(UserServices::class);
if (!$menber->uid && $menber->mobile) {
$menberUid = $userService->value(['phone' => $menber->mobile], 'uid');
if ($menberUid && $menberUid != $uid) {
$menber->uid = $menberUid;
$menber->save();
}
}
$userInfo = $userService->get($uid, ['uid', 'work_uid', 'work_userid']);
if (!$userInfo) {
return true;
}
if (!$userInfo->work_userid) {
$userInfo->work_userid = $userId;
$userInfo->work_uid = $menber->uid;
$userInfo->save();
}
}
}
return true;
}
/**
* 设置用户会员卡激活状态
* @param $uid
* @return bool
*/
public function setUserLevel($uid)
{
if (!(int)$uid) {
return true;
}
try {
/** @var StoreNewcomerServices $newcomerServices */
$newcomerServices = app()->make(StoreNewcomerServices::class);
$newcomerServices->setUserLevel((int)$uid);
} catch (\Throwable $e) {
Log::error('设置用户会员卡激活状态失败,失败原因:' . $e->getMessage());
}
return true;
}
/**
* 设置用户首单优惠、新人专享
* @param $uid
* @return bool
*/
public function setUserNewcomer($uid)
{
if (!(int)$uid) {
return true;
}
try {
/** @var StoreNewcomerServices $newcomerServices */
$newcomerServices = app()->make(StoreNewcomerServices::class);
$newcomerServices->setUserNewcomer((int)$uid);
} catch (\Throwable $e) {
response_log_write([
'message' => '设置用户首单优惠、新人专享失败,失败原因:' . $e->getMessage(),
'line' => $e->getLine(),
'file' => $e->getFile()
]);
}
return true;
}
/**
* 下单修改
* @param $uid
* @return bool|void
*/
public function updateUserNewcomer($uid, $order)
{
if (!(int)$uid) {
return true;
}
try {
/** @var StoreNewcomerServices $newcomerServices */
$newcomerServices = app()->make(StoreNewcomerServices::class);
$newcomerServices->updateUserNewcomer((int)$uid, $order);
} catch (\Throwable $e) {
response_log_write([
'message' => '修改用户首单优惠、新人专享使用状态失败,失败原因:' . $e->getMessage(),
'line' => $e->getLine(),
'file' => $e->getFile()
]);
}
return true;
}
/**
* 邀请新用户增加经验
* @param $spreadUid
* @return bool
* @author 等风来
* @email 136327134@qq.com
* @date 2022/12/8
*/
public function inviteUserIncExp($spreadUid)
{
try {
/** @var UserBillServices $userBill */
$userBill = app()->make(UserBillServices::class);
$userBill->inviteUserIncExp((int)$spreadUid);
} catch (\Throwable $e) {
response_log_write([
'message' => '邀请新用户增加经验失败,失败原因:' . $e->getMessage(),
'line' => $e->getLine(),
'file' => $e->getFile()
]);
}
return true;
}
/**
* 增加推广佣金
* @param $uid
* @param $spreadUid
* @return bool
* @author 等风来
* @email 136327134@qq.com
* @date 2022/12/8
*/
public function addBrokeragePrice($uid, $spreadUid)
{
try {
//增加推广佣金
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
$userServices->addBrokeragePrice((int)$uid, $spreadUid);
} catch (\Throwable $e) {
response_log_write([
'message' => '增加推广佣金失败,失败原因:' . $e->getMessage(),
'line' => $e->getLine(),
'file' => $e->getFile()
]);
}
return true;
}
}

View File

@@ -0,0 +1,82 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use app\services\user\label\UserLabelServices;
use app\services\work\WorkGroupChatAuthServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 用户标签
* Class UserLabelJob
* @package app\jobs\user
*/
class UserLabelJob extends BaseJobs
{
use QueueTrait;
/**
* 同步后台标签到企业微信客户后台
* @param $cateId
* @param $groupName
* @return bool
*/
public function authLabel($cateId, $groupName)
{
try{
/** @var UserLabelServices $make */
$make = app()->make(UserLabelServices::class);
$make->addCorpClientLabel($cateId, $groupName);
} catch (\Throwable $e) {
\think\facade\Log::error('同步后台标签到企业微信客户后台,失败原因:'.$e->getMessage());
}
return true;
}
/**
* 同步企业微信客户标签到平台
* @return bool
*/
public function authWorkLabel()
{
try {
/** @var UserLabelServices $make */
$make = app()->make(UserLabelServices::class);
$make->authWorkLabel();
} catch (\Throwable $e) {
\think\facade\Log::error('同步企业微信客户标签到平台,失败原因:'.$e->getMessage());
}
return true;
}
/**
* 编辑客户标签
* @param $userid
* @param $externalUserID
* @param $groupAuthId
* @return bool
*/
public function clientAddLabel($userid, $externalUserID, $groupAuthId)
{
try {
/** @var WorkGroupChatAuthServices $chatAuthService */
$chatAuthService = app()->make(WorkGroupChatAuthServices::class);
$chatAuthService->clientAddLabel((int)$groupAuthId, $userid, $externalUserID);
} catch (\Throwable $e) {
\think\facade\Log::error('编辑客户标签,失败原因:'.$e->getMessage());
}
return true;
}
}

View File

@@ -0,0 +1,51 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use app\services\user\level\UserLevelServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 检测会员等级
* Class UserLevelJob
* @package app\jobs\user
*/
class UserLevelJob extends BaseJobs
{
use QueueTrait;
/**
* 执行会员等级检测任务
* @param int $uid 用户ID
* @return bool
*/
public function doJob($uid)
{
try {
/** @var UserLevelServices $levelServices */
$levelServices = app()->make(UserLevelServices::class);
$levelServices->detection((int)$uid);
} catch (\Throwable $e) {
response_log_write([
'message' => '会员等级升级失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,73 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use app\services\user\UserMoneyServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 用户余额
* Class UserMoneyJob
* @package app\jobs
*/
class UserMoneyJob extends BaseJobs
{
use QueueTrait;
/**
* 赠送新人礼余额
* @param $uid
* @return bool
*/
public function newcomerGiveMoney($uid)
{
try {
/** @var UserMoneyServices $userMoneyServices */
$userMoneyServices = app()->make(UserMoneyServices::class);
$userMoneyServices->newcomerGiveMoney((int)$uid);
} catch (\Throwable $e) {
response_log_write([
'message' => '赠送新人礼余额失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
/**
* 会员卡激活赠送余额
* @param $uid
* @return bool
*/
public function levelGiveMoney($uid)
{
try {
/** @var UserMoneyServices $userMoneyServices */
$userMoneyServices = app()->make(UserMoneyServices::class);
$userMoneyServices->levelGiveMoney((int)$uid);
} catch (\Throwable $e) {
response_log_write([
'message' => '会员卡激活赠送余额失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,60 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use app\services\user\UserServices;
use app\services\user\UserSpreadServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 用户推广关系
* Class UserSpreadJob
* @package app\jobs\user
*/
class UserSpreadJob extends BaseJobs
{
use QueueTrait;
/**
* 记录用户推广关系
* @param int $uid
* @param int $spreadUid
* @return bool
*/
public function doJob(int $uid, int $spreadUid, int $spread_time = 0, int $admin_id = 0)
{
if (!$uid || !$spreadUid || $uid == $spreadUid) {
return true;
}
try {
/** @var UserSpreadServices $userSpreadServices */
$userSpreadServices = app()->make(UserSpreadServices::class);
//记录
$userSpreadServices->setSpread($uid, $spreadUid, $spread_time, $admin_id);
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
//增加推广人数
$userServices->incField($spreadUid, 'spread_count', 1);
} catch (\Throwable $e) {
response_log_write([
'message' => '记录用户推广失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,55 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use app\services\user\UserServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\facade\Log;
/**
* 清除到期svip
* Class UserSvipJob
* @package app\jobs\user
*/
class UserSvipJob extends BaseJobs
{
use QueueTrait;
/**
* 执行清除到期积分
* @param $openids
* @return bool
*/
public function doJob($uids)
{
if (!$uids || !is_array($uids)) {
return true;
}
try {
/** @var UserServices $userServices */
$userServices = app()->make(UserServices::class);
foreach ($uids as $uid) {
$userServices->offMemberLevel($uid);
}
} catch (\Throwable $e) {
response_log_write([
'message' => '清除到期用户svip失败,失败原因:' . $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
}
return true;
}
}

View File

@@ -0,0 +1,44 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\user;
use app\services\user\UserServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* Class UserUpdateJob
* @package app\jobs\user
*/
class UserUpdateJob extends BaseJobs
{
use QueueTrait;
/**
* @param $uid
* @param $realName
* @param $userPhone
* @return bool
*/
public function updateRealName($uid, $realName, $userPhone)
{
/** @var UserServices $userService */
$userService = app()->make(UserServices::class);
$userService->update(['uid' => $uid], ['real_name' => $realName, 'record_phone' => $userPhone]);
return true;
}
}

View File

@@ -0,0 +1,75 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\work;
use app\services\work\WorkClientServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
/**
* 同步客户
* Class WorkClientJob
* @package app\jobs\work
*/
class WorkClientJob extends BaseJobs
{
use QueueTrait;
/**
* @param $page
* @param $cursor
* @return bool
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function authClient($page, $cursor)
{
/** @var WorkClientServices $make */
$make = app()->make(WorkClientServices::class);
$make->authGetExternalcontact($page, $cursor);
return true;
}
/**
* 同步客户信息
* @param $corpId
* @param $externalUserID
* @param $userId
* @return bool
*/
public function saveClientInfo($corpId, $externalUserID, $userId)
{
/** @var WorkClientServices $make */
$make = app()->make(WorkClientServices::class);
$make->saveOrUpdateClient($corpId, $externalUserID, $userId);
return true;
}
/**
* 设置客户标签
* @param $markTag
* @return bool
*/
public function setLabel($markTag)
{
/** @var WorkClientServices $make */
$make = app()->make(WorkClientServices::class);
$make->setClientMarkTag($markTag);
return true;
}
}

View File

@@ -0,0 +1,50 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\work;
use app\services\work\WorkGroupChatServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 企业微信群
* Class WorkGroupChatJob
* @package app\jobs\work
*/
class WorkGroupChatJob extends BaseJobs
{
use QueueTrait;
public function authChat($corpId, $chatId)
{
/** @var WorkGroupChatServices $make */
$make = app()->make(WorkGroupChatServices::class);
return $make->saveWorkGroupChat($corpId, $chatId);
}
/**
* @param $nextCursor
* @return bool
* @author 等风来
* @email 136327134@qq.com
* @date 2022/10/10
*/
public function authGroupChat($nextCursor)
{
/** @var WorkGroupChatServices $make */
$make = app()->make(WorkGroupChatServices::class);
return $make->authGroupChat($nextCursor);
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace app\jobs\work;
use app\services\work\WorkGroupMsgSendResultServices;
use app\services\work\WorkGroupMsgTaskServices;
use app\services\work\WorkGroupTemplateServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 企业微信群发任务
* Class WorkGroupMsgJob
* @package app\jobs\work
*/
class WorkGroupMsgJob extends BaseJobs
{
use QueueTrait;
/**
* 批量
* @param $id
* @param $userId
* @param $count
* @return bool
*/
public function batch($id, $userId, $count)
{
/** @var WorkGroupTemplateServices $service */
$service = app()->make(WorkGroupTemplateServices::class);
return $service->batch((int)$id, $userId, (int)$count);
}
/**
* 获取群发成员发送任务列表
* @param $type
* @param $msgid
* @param $cursor
* @return mixed
*/
public function getTaks($type, $msgid, $cursor)
{
/** @var WorkGroupMsgTaskServices $service */
$service = app()->make(WorkGroupMsgTaskServices::class);
return $service->getTaks($type, $msgid, $cursor);
}
/**
* @param $type
* @param $userid
* @param $msgid
* @param $cursor
* @return bool
*/
public function getSendResult($type, $userid, $msgid, $cursor)
{
/** @var WorkGroupMsgSendResultServices $service */
$service = app()->make(WorkGroupMsgSendResultServices::class);
return $service->getSendResult($type, $userid, $msgid, $cursor);
}
}

View File

@@ -0,0 +1,53 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\jobs\work;
use app\services\work\WorkMemberServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* 企业微信成员
* Class WorkMemberJob
* @package app\jobs\work
*/
class WorkMemberJob extends BaseJobs
{
use QueueTrait;
/**
* 执行部门同步
* @param $id
* @return bool
*/
public function run($id)
{
/** @var WorkMemberServices $make */
$make = app()->make(WorkMemberServices::class);
$make->authUpdataMember((int)$id);
return true;
}
/**
* 保存数据
* @param $member
* @return bool
*/
public function save($member)
{
/** @var WorkMemberServices $make */
$make = app()->make(WorkMemberServices::class);
return $make->saveMember($member);
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace app\jobs\work;
use app\services\work\WorkMomentSendResultServices;
use app\services\work\WorkMomentServices;
use crmeb\basic\BaseJobs;
use crmeb\traits\QueueTrait;
/**
* Class WorkMomentJob
* @package app\jobs\work
*/
class WorkMomentJob extends BaseJobs
{
use QueueTrait;
/**
* @param $jobid
* @return mixed
*/
public function task($jobid)
{
/** @var WorkMomentServices $service */
$service = app()->make(WorkMomentServices::class);
return $service->getTaskInfo($jobid);
}
/**
* 获取任务详情
* @param $momentId
* @param $cursor
* @return mixed
*/
public function getTaskPage($momentId, $cursor)
{
/** @var WorkMomentSendResultServices $service */
$service = app()->make(WorkMomentSendResultServices::class);
return $service->getTaskInfo($momentId, $cursor);
}
/**
* 获取某个成员发送朋友圈详情
* @param $id
* @param $momentId
* @param $userId
* @param $cursor
* @return bool
*/
public function getCustomerPage($id, $momentId, $userId, $cursor)
{
/** @var WorkMomentSendResultServices $service */
$service = app()->make(WorkMomentSendResultServices::class);
return $service->getCustomerList((int)$id, $momentId, $userId, $cursor);
}
}