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

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;
}
}