Finish mzl_dev_xd
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\controller;
|
||||
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use app\common\utils\FeishuMessage;
|
||||
use app\inquiry\service\InquiryLogService;
|
||||
use app\common\model\CrmCustomer;
|
||||
use app\common\model\InquiryLog;
|
||||
use app\common\model\User;
|
||||
use support\exception\BusinessException;
|
||||
|
||||
class NotifyController
|
||||
{
|
||||
|
||||
/**
|
||||
* 不用头部数据
|
||||
* @var array
|
||||
*/
|
||||
protected $noNeedHeaderData = ['feishuCallback', 'feishuEvent'];
|
||||
|
||||
/**
|
||||
* 不登录不鉴权
|
||||
* @var array
|
||||
*/
|
||||
protected $noNeedLogin = ['feishuCallback', 'feishuEvent'];
|
||||
|
||||
/**
|
||||
* 飞书回调
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function feishuCallback(Request $request)
|
||||
{
|
||||
try {
|
||||
$param = $request->post();
|
||||
|
||||
// 解析数据
|
||||
// $param = json_decode($param['event'], true);
|
||||
$orderSn = $param['event']['action']['value'];
|
||||
if (strpos($orderSn, '"') !== false) {
|
||||
$orderSn = str_replace('"', '', $orderSn);
|
||||
}
|
||||
|
||||
// 处理询单&客户线索信息
|
||||
$openId = $param['event']['operator']['open_id'];
|
||||
|
||||
// 获取询单
|
||||
$order = InquiryLog::with(['channelInfo', 'countryInfo', 'enter'])->where('order_no', $orderSn)->first();
|
||||
if (!$order) {
|
||||
return $this->error('未找到询单记录');
|
||||
}
|
||||
|
||||
// 获取客户xians
|
||||
$customer = CrmCustomer::where('sn', $orderSn)->first();
|
||||
if (!$customer) {
|
||||
return $this->error('未找到客户线索');
|
||||
}
|
||||
|
||||
// 获取用户
|
||||
$uinfo = User::where('open_id', $openId)->first();
|
||||
|
||||
// 更新客户线索
|
||||
$customer->user_id = $uinfo->id;
|
||||
|
||||
// 更新询单数据
|
||||
$order->recipient = $uinfo->id;
|
||||
$order->status = 2;
|
||||
$order->t_time = time();
|
||||
|
||||
// 保存
|
||||
if (!$order->save() || !$customer->save()) {
|
||||
return $this->error('跟踪失败');
|
||||
}
|
||||
|
||||
// 获取飞书消息模板
|
||||
$feishuMessage = new FeishuMessage();
|
||||
$content = $feishuMessage->groupUpdateTemplates(
|
||||
(new InquiryLogService())->qualityName($order->quality),
|
||||
$order->order_no,
|
||||
$order->channelInfo ? $order->channelInfo->name : '',
|
||||
$order->countryInfo ? $order->countryInfo->cn_addr : '',
|
||||
$order->enter ? $order->enter->name : '',
|
||||
$order->r_time ? date('Y-m-d H:i:s', $order->r_time) : '',
|
||||
$order->t_time ? date('Y-m-d H:i:s', $order->t_time) : ''
|
||||
);
|
||||
|
||||
// 组装飞书消息模板
|
||||
$data = '{
|
||||
"toast": {
|
||||
"type": "success",
|
||||
"content": "操作成功"
|
||||
},
|
||||
"card": {
|
||||
"type": "raw",
|
||||
"data": '.$content.'
|
||||
}
|
||||
}';
|
||||
|
||||
// 响应消息
|
||||
return new Response(200, ['Content-Type' => 'application/json'], $data);
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function error($msg = '')
|
||||
{
|
||||
$data = '{
|
||||
"toast": {
|
||||
"type": "error",
|
||||
"content": "'.$msg.'"
|
||||
}
|
||||
}';
|
||||
return new Response(200, ['Content-Type' => 'application/json'], $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 飞书事件
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function feishuEvent(Request $request)
|
||||
{
|
||||
try {
|
||||
$data = $request->post();
|
||||
|
||||
var_dump($data);
|
||||
|
||||
return json($data);
|
||||
} catch (\Throwable $e) {
|
||||
return json($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ use support\Request;
|
||||
use app\common\service\CorpService;
|
||||
use app\common\service\CorpFeishuAppService;
|
||||
use app\common\service\SystemsService;
|
||||
use app\common\service\UserService;
|
||||
|
||||
class PresetController extends BaseController
|
||||
{
|
||||
@@ -48,4 +49,15 @@ class PresetController extends BaseController
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function users()
|
||||
{
|
||||
try {
|
||||
$result = (new UserService())->getList();
|
||||
return $this->success($result, '获取用户列表');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,4 +53,19 @@ class UserLogic
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
*/
|
||||
public function getList()
|
||||
{
|
||||
$list = User::where('status', 1)->orderBy('id', 'desc')->get();
|
||||
$arr = [];
|
||||
foreach ($list->toArray() as $item) {
|
||||
$arr[] = [
|
||||
'name' => $item['name'],
|
||||
'id' => $item['id'],
|
||||
];
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use support\Model;
|
||||
|
||||
class CrmCustomer extends Model
|
||||
{
|
||||
/**
|
||||
* The connection name for the model.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $connection = 'mysql';
|
||||
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'crm_customer';
|
||||
|
||||
/**
|
||||
* The primary key associated with the table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $primaryKey = 'id';
|
||||
|
||||
/**
|
||||
* Indicates if the model should be timestamped.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $timestamps = true;
|
||||
|
||||
|
||||
protected $dateFormat = 'U';
|
||||
|
||||
/**
|
||||
* 允许自动填充模型字段
|
||||
*/
|
||||
protected $fillable = ['id', 'sn', 'corp_abbr', 'user_id', 'user_sn', 'type', 'grade', 'sex', 'channel_id', 'country_id', 'car_type_id', 'magnitude', 'email', 'phone', 'WhatsApp', 'contacts', 'describe', 'desc_collect', 'address', 'lat', 'lng', 'follow_last', 'follow_next', 'warn', 'follow_remark', 'enter_user_id', 'created_at', 'updated_at', 'deleted_at'];
|
||||
|
||||
/**
|
||||
* 不允许自动填充模型字段
|
||||
*/
|
||||
protected $guarded = [];
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use support\Model;
|
||||
|
||||
class InquiryChannel extends Model
|
||||
{
|
||||
/**
|
||||
* The connection name for the model.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $connection = 'mysql';
|
||||
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'inquiry_channel';
|
||||
|
||||
/**
|
||||
* The primary key associated with the table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $primaryKey = 'id';
|
||||
|
||||
/**
|
||||
* Indicates if the model should be timestamped.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $timestamps = true;
|
||||
|
||||
|
||||
protected $dateFormat = 'U';
|
||||
|
||||
/**
|
||||
* 允许自动填充模型字段
|
||||
*/
|
||||
protected $fillable = ['id', 'name', 'sort', 'status', 'created_at', 'updated_at'];
|
||||
|
||||
/**
|
||||
* 不允许自动填充模型字段
|
||||
*/
|
||||
protected $guarded = [];
|
||||
}
|
||||
@@ -65,17 +65,12 @@ class InquiryLog extends Model
|
||||
return $this->hasOne(User::class, 'id', 'recipient');
|
||||
}
|
||||
|
||||
// public function enter()
|
||||
// {
|
||||
// return $this->belongsTo(User::class, 'enter_user_id');
|
||||
// }
|
||||
public function channelInfo()
|
||||
{
|
||||
return $this->hasOne(InquiryChannel::class, 'id', 'channel');
|
||||
}
|
||||
|
||||
// public function recipient()
|
||||
// {
|
||||
// return $this->belongsTo(User::class, 'recipient');
|
||||
// }
|
||||
|
||||
public function country()
|
||||
public function countryInfo()
|
||||
{
|
||||
return $this->hasOne(Country::class, 'id', 'country');
|
||||
}
|
||||
|
||||
@@ -96,4 +96,4 @@ class User extends Model
|
||||
->orWhere('phone', $account)
|
||||
->orWhere('email', $account);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ namespace app\common\service;
|
||||
use app\common\logic\UserLogic;
|
||||
use app\common\model\Corp;
|
||||
use app\common\model\User;
|
||||
use app\common\utils\CrudUtil;
|
||||
use app\crm\model\Country;
|
||||
use support\exception\BusinessException;
|
||||
|
||||
@@ -99,4 +100,12 @@ class UserService
|
||||
$user = $this->logic->savePassword($uid,$data);
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
*/
|
||||
public function getList()
|
||||
{
|
||||
return $this->logic->getList();
|
||||
}
|
||||
}
|
||||
@@ -38,14 +38,6 @@ trait CrudLogicTrait
|
||||
return CrudUtil::findOneBy(CrudUtil::buildQuery($config));
|
||||
}
|
||||
|
||||
/**
|
||||
* 任意条件查询单条(可带 dataLimit)
|
||||
*/
|
||||
// public function logicShowBy(array $where, array $with = [], array $dataLimit = [])
|
||||
// {
|
||||
// return CrudUtil::findOneBy($this->modelClass, $where, $with, $dataLimit);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 创建(可带 dataLimit)
|
||||
*/
|
||||
@@ -54,14 +46,6 @@ trait CrudLogicTrait
|
||||
return CrudUtil::create($this->modelClass, $data, $dataLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* 主键更新(可带 dataLimit)
|
||||
*/
|
||||
// public function logicUpdateByPk($id, array $data, array $dataLimit = [])
|
||||
// {
|
||||
// return CrudUtil::updateByPk($this->modelClass, $id, $data, $dataLimit);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 任意条件更新(可带 dataLimit)
|
||||
*/
|
||||
@@ -70,14 +54,6 @@ trait CrudLogicTrait
|
||||
return CrudUtil::updateBy(CrudUtil::buildQuery($config), $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 主键删除(批量)
|
||||
*/
|
||||
// public function logicDeleteByPk(array $ids)
|
||||
// {
|
||||
// return CrudUtil::deleteByPk($this->modelClass, $ids);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 任意条件删除(可带 dataLimit)
|
||||
*/
|
||||
@@ -93,4 +69,12 @@ trait CrudLogicTrait
|
||||
{
|
||||
return CrudUtil::executeComplex($this->modelClass, $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据主键查询
|
||||
*/
|
||||
public function findByPk(int $id, array $with = [])
|
||||
{
|
||||
return CrudUtil::findByPk($this->modelClass, $id, $with);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ trait CrudServiceTrait
|
||||
$result = $this->complexQuery($request->get());
|
||||
} else {
|
||||
$config = $this->buildQueryConfig($request, 'index');
|
||||
$limit = (int)$request->get('limit', 15);
|
||||
$page = (int)$request->get('page', 1);
|
||||
$limit = (int)$request->get('size', 15);
|
||||
$page = (int)$request->get('current', 1);
|
||||
$result = $this->logicList($config, $limit, $page);
|
||||
}
|
||||
return $this->postProcess('List', $result);
|
||||
@@ -62,7 +62,7 @@ trait CrudServiceTrait
|
||||
/** 创建 */
|
||||
public function serviceStore(Request $request, array $data = [])
|
||||
{
|
||||
// $data = $request->post();
|
||||
$data = $this->preProcess('Store', $data, $request);
|
||||
$dl = $this->getDataLimitFromRequest($request);
|
||||
$created = $this->logicCreate($data, $dl);
|
||||
return $this->postProcess('Store', $created);
|
||||
@@ -71,7 +71,7 @@ trait CrudServiceTrait
|
||||
/** 更新 */
|
||||
public function serviceUpdate(Request $request, array $data = [])
|
||||
{
|
||||
// $data= $request->post();
|
||||
$data = $this->preProcess('Update', $data, $request);
|
||||
$config = $this->buildQueryConfig($request, 'update');
|
||||
$updated = $this->logicUpdateBy($config, $data);
|
||||
return $this->postProcess('Update', $updated);
|
||||
@@ -88,16 +88,7 @@ trait CrudServiceTrait
|
||||
/** ----------------- 公共辅助方法 ----------------- */
|
||||
|
||||
/**
|
||||
* 构造 CrudUtil 的查询配置1
|
||||
*
|
||||
* 前端可以通过以下参数控制:
|
||||
* - filter_<column>=<value> → where
|
||||
* - sort_by=<column>&order=<asc|desc>
|
||||
* - fields=id,name,email → select
|
||||
* - with=roles,posts → 关联
|
||||
* - withFields=roles:id,name;... → 关联字段
|
||||
* - dataLimitType=personal|auth
|
||||
* - dataLimitField=admin_id
|
||||
* 构造 CrudUtil 查询配置
|
||||
*/
|
||||
protected function buildQueryConfig(Request $request, string $scene = 'default'): array
|
||||
{
|
||||
@@ -131,37 +122,6 @@ trait CrudServiceTrait
|
||||
}
|
||||
|
||||
return $config;
|
||||
|
||||
// // 1. where 从 filter_ 前缀自动映射
|
||||
// $where = [];
|
||||
// foreach ($p as $key => $val) {
|
||||
// if (strpos($key, 'filter_') === 0 && $val !== '') {
|
||||
// $col = substr($key, 7);
|
||||
// // 支持 %like% 查询
|
||||
// $where[$col] = strpos($val, '%') !== false
|
||||
// ? ['like', $val]
|
||||
// : $val;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 2. 其余配置
|
||||
// return [
|
||||
// 'model' => $this->modelClass,
|
||||
// 'where' => $where,
|
||||
// 'order' => [
|
||||
// $p['sort_by'] ?? 'id' => $p['order'] ?? 'desc'
|
||||
// ],
|
||||
// 'fields' => !empty($p['fields'])
|
||||
// ? explode(',', $p['fields'])
|
||||
// : [],
|
||||
// 'with' => !empty($p['with'])
|
||||
// ? explode(',', $p['with'])
|
||||
// : [],
|
||||
// 'withFields' => $this->parseWithFields(
|
||||
// $p['withFields'] ?? ''
|
||||
// ),
|
||||
// 'dataLimit' => $this->getDataLimitFromRequest($request),
|
||||
// ];
|
||||
}
|
||||
|
||||
/** 解析 withFields 字符串 "rel:field,field;..." */
|
||||
@@ -191,14 +151,20 @@ trait CrudServiceTrait
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理复杂查询
|
||||
* 覆盖此方法,实现复杂查询逻辑
|
||||
/**
|
||||
* $data 前置处理
|
||||
*
|
||||
* @param array $data
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
// protected function complexQuery(array $params): array
|
||||
// {
|
||||
// throw new \LogicException('请在子类实现 complexQuery');
|
||||
// }
|
||||
protected function preProcess(string $op, mixed $data, Request $request): mixed
|
||||
{
|
||||
$hook = "beforeService{$op}";
|
||||
return method_exists($this, $hook)
|
||||
? $this->{$hook}($data, $request)
|
||||
: $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据操作类型,调用对应的后置钩子
|
||||
@@ -214,4 +180,14 @@ trait CrudServiceTrait
|
||||
? $this->{$hook}($data)
|
||||
: $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 处理复杂查询
|
||||
* 覆盖此方法,实现复杂查询逻辑
|
||||
*/
|
||||
// protected function complexQuery(array $params): array
|
||||
// {
|
||||
// throw new \LogicException('请在子类实现 complexQuery');
|
||||
// }
|
||||
}
|
||||
@@ -326,7 +326,7 @@ class CrudUtil
|
||||
}
|
||||
|
||||
/**
|
||||
* 真正执行一个条件的 where
|
||||
* 执行条件 where
|
||||
*/
|
||||
protected static function applySingleWhere(Builder $q, string $col, string $op, $v): void
|
||||
{
|
||||
|
||||
@@ -0,0 +1,555 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\utils;
|
||||
|
||||
use Webman\Exception\BusinessException;
|
||||
|
||||
class FeishuMessage
|
||||
{
|
||||
|
||||
protected $app_id = 'cli_a72f13d6c022500d';
|
||||
protected $app_secret = 'Kxtbq70OQWrEhpltrufRZc76z7kjDqPT';
|
||||
protected $class = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->class = new Feishu($this->app_id, $this->app_secret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 飞书消息模板
|
||||
* @param string $scene
|
||||
* @param array $options
|
||||
*/
|
||||
public function messageTemplates(string $scene = 'group-send', array $options = [])
|
||||
{
|
||||
try {
|
||||
$template = match ($scene) {
|
||||
'inquiry-group-send' => $this->groupNewTemplates(
|
||||
$options['quality'],
|
||||
$options['order_no'],
|
||||
$options['channel'],
|
||||
$options['country'],
|
||||
$options['enter_user'],
|
||||
$options['r_time']
|
||||
),
|
||||
'inquiry-group-update' => $this->groupUpdateTemplates(
|
||||
$options['quality'],
|
||||
$options['order_no'],
|
||||
$options['channel'],
|
||||
$options['country'],
|
||||
$options['enter_user'],
|
||||
$options['r_time'],
|
||||
$options['t_time']
|
||||
),
|
||||
'inquiry-person-allocation' => $this->personAllocationTemplates(
|
||||
$options['quality'],
|
||||
$options['order_no'],
|
||||
$options['channel'],
|
||||
$options['country'],
|
||||
$options['enter_user'],
|
||||
$options['r_time'],
|
||||
$options['t_time']
|
||||
),
|
||||
'crm-person-follow-up' => $this->personFollowUpTemplates(
|
||||
$options['contacts'],
|
||||
$options['follow_next'],
|
||||
$options['follow_last']
|
||||
)
|
||||
};
|
||||
} catch (\UnhandledMatchError $e) {
|
||||
throw new BusinessException($e->getMessage());
|
||||
}
|
||||
return $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送飞书消息
|
||||
* @param array $options
|
||||
*/
|
||||
public function messageSend(string $scene = 'group-send', array $options = [])
|
||||
{
|
||||
$template = $this->messageTemplates($scene, $options);
|
||||
$result = $this->class->sendMessages($options['receive_id'], $template, $options['msg_type'], $options['receive_id_type']);
|
||||
if (!isset($result['code']) || $result['code'] !== 0) {
|
||||
throw new BusinessException('发送飞书消息失败');
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 线索消息发送
|
||||
*/
|
||||
public function groupNewTemplates($quality = '💛 银牌商机', $order_no = 'SN2025072365640', $channel = '谷歌', $country = '白俄罗斯', $enter_user = '木子李', $r_time = '2025-07-24 09:41:23')
|
||||
{
|
||||
$content = '{
|
||||
"schema": "2.0",
|
||||
"config": {
|
||||
"update_multi": true,
|
||||
"style": {
|
||||
"text_size": {
|
||||
"normal_v2": {
|
||||
"default": "normal",
|
||||
"pc": "normal",
|
||||
"mobile": "heading"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"direction": "vertical",
|
||||
"horizontal_spacing": "8px",
|
||||
"vertical_spacing": "16px",
|
||||
"horizontal_align": "left",
|
||||
"vertical_align": "top",
|
||||
"padding": "0px 20px 20px 20px",
|
||||
"elements": [
|
||||
{
|
||||
"tag": "hr",
|
||||
"margin": "0px 0px 0px 0px"
|
||||
},
|
||||
{
|
||||
"tag": "column_set",
|
||||
"horizontal_align": "left",
|
||||
"columns": [
|
||||
{
|
||||
"tag": "column",
|
||||
"width": "weighted",
|
||||
"elements": [
|
||||
{
|
||||
"tag": "markdown",
|
||||
"content": " **'.$quality.'**\n- **编号:** '.$order_no.'\n- **渠道:** '.$channel.'\n- **国家:** '.$country.'\n- **发布人:** '.$enter_user.'\n- **发布时间:** '.$r_time.'",
|
||||
"text_align": "left",
|
||||
"text_size": "normal_v2",
|
||||
"margin": "0px 0px 0px 0px"
|
||||
}
|
||||
],
|
||||
"vertical_spacing": "8px",
|
||||
"horizontal_align": "left",
|
||||
"vertical_align": "top",
|
||||
"weight": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "form",
|
||||
"elements": [
|
||||
{
|
||||
"tag": "hr",
|
||||
"margin": "0px 0px 0px 0px"
|
||||
},
|
||||
{
|
||||
"tag": "column_set",
|
||||
"flex_mode": "stretch",
|
||||
"horizontal_spacing": "8px",
|
||||
"horizontal_align": "left",
|
||||
"columns": [
|
||||
{
|
||||
"tag": "column",
|
||||
"width": "auto",
|
||||
"elements": [
|
||||
{
|
||||
"tag": "button",
|
||||
"text": {
|
||||
"tag": "plain_text",
|
||||
"content": "立即跟踪"
|
||||
},
|
||||
"type": "primary_filled",
|
||||
"width": "fill",
|
||||
"size": "medium",
|
||||
"icon": {
|
||||
"tag": "standard_icon",
|
||||
"token": "list-check-bold_outlined"
|
||||
},
|
||||
"confirm": {
|
||||
"title": {
|
||||
"tag": "plain_text",
|
||||
"content": "确认跟踪?"
|
||||
},
|
||||
"text": {
|
||||
"tag": "plain_text",
|
||||
"content": "客户线索:'.$order_no.'"
|
||||
}
|
||||
},
|
||||
"behaviors": [
|
||||
{
|
||||
"type": "callback",
|
||||
"value": "'.$order_no.'"
|
||||
}
|
||||
],
|
||||
"form_action_type": "submit",
|
||||
"name": "Button_m7d0zqa2",
|
||||
"element_id": "track"
|
||||
}
|
||||
],
|
||||
"direction": "vertical",
|
||||
"horizontal_spacing": "8px",
|
||||
"vertical_spacing": "8px",
|
||||
"horizontal_align": "left",
|
||||
"vertical_align": "top"
|
||||
},
|
||||
{
|
||||
"tag": "column",
|
||||
"width": "auto",
|
||||
"elements": [],
|
||||
"direction": "vertical",
|
||||
"horizontal_spacing": "8px",
|
||||
"vertical_spacing": "8px",
|
||||
"horizontal_align": "left",
|
||||
"vertical_align": "top"
|
||||
},
|
||||
{
|
||||
"tag": "column",
|
||||
"width": "auto",
|
||||
"elements": [],
|
||||
"padding": "0px 0px 0px 0px",
|
||||
"direction": "vertical",
|
||||
"horizontal_spacing": "8px",
|
||||
"vertical_spacing": "8px",
|
||||
"horizontal_align": "left",
|
||||
"vertical_align": "top",
|
||||
"margin": "0px 0px 0px 0px"
|
||||
}
|
||||
],
|
||||
"margin": "4px 0px 0px 0px"
|
||||
}
|
||||
],
|
||||
"direction": "vertical",
|
||||
"horizontal_spacing": "8px",
|
||||
"vertical_spacing": "12px",
|
||||
"horizontal_align": "left",
|
||||
"vertical_align": "top",
|
||||
"padding": "0px 0px 0px 0px",
|
||||
"margin": "0px 0px 0px 0px",
|
||||
"name": "Form_m7d0zqa1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"header": {
|
||||
"title": {
|
||||
"tag": "plain_text",
|
||||
"content": "新的【公海】客户线索"
|
||||
},
|
||||
"subtitle": {
|
||||
"tag": "plain_text",
|
||||
"content": ""
|
||||
},
|
||||
"template": "default",
|
||||
"icon": {
|
||||
"tag": "standard_icon",
|
||||
"token": "ai-common_colorful"
|
||||
},
|
||||
"padding": "12px 12px 12px 20px"
|
||||
}
|
||||
}';
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* 线索消息更新
|
||||
*/
|
||||
public function groupUpdateTemplates($quality = '💛 银牌商机', $order_no = 'SN2025072365640', $channel = '谷歌', $country = '白俄罗斯', $enter_user = '木子李', $r_time = '2025-07-24 09:41:23', $t_time = '2025-07-24 14:41:23')
|
||||
{
|
||||
$content = '{
|
||||
"schema": "2.0",
|
||||
"config": {
|
||||
"update_multi": true,
|
||||
"style": {
|
||||
"text_size": {
|
||||
"normal_v2": {
|
||||
"default": "normal",
|
||||
"pc": "normal",
|
||||
"mobile": "heading"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"direction": "vertical",
|
||||
"horizontal_spacing": "8px",
|
||||
"vertical_spacing": "16px",
|
||||
"horizontal_align": "left",
|
||||
"vertical_align": "top",
|
||||
"padding": "0px 20px 20px 20px",
|
||||
"elements": [
|
||||
{
|
||||
"tag": "hr",
|
||||
"margin": "0px 0px 0px 0px"
|
||||
},
|
||||
{
|
||||
"tag": "column_set",
|
||||
"horizontal_align": "left",
|
||||
"columns": [
|
||||
{
|
||||
"tag": "column",
|
||||
"width": "weighted",
|
||||
"elements": [
|
||||
{
|
||||
"tag": "markdown",
|
||||
"content": " **'.$quality.'**\n- **编号:** '.$order_no.'\n- **渠道:** '.$channel.'\n- **国家:** '.$country.'\n- **发布人:** '.$enter_user.'\n- **发布时间:** '.$r_time.'",
|
||||
"text_align": "left",
|
||||
"text_size": "normal_v2",
|
||||
"margin": "0px 0px 0px 0px"
|
||||
}
|
||||
],
|
||||
"vertical_spacing": "8px",
|
||||
"horizontal_align": "left",
|
||||
"vertical_align": "top",
|
||||
"weight": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "hr",
|
||||
"margin": "0px 0px 0px 0px"
|
||||
},
|
||||
{
|
||||
"tag": "div",
|
||||
"text": {
|
||||
"tag": "plain_text",
|
||||
"content": "跟踪时间:'.$t_time.'",
|
||||
"text_size": "notation",
|
||||
"text_align": "left",
|
||||
"text_color": "green"
|
||||
},
|
||||
"icon": {
|
||||
"tag": "standard_icon",
|
||||
"token": "chat-done_outlined",
|
||||
"color": "green"
|
||||
},
|
||||
"element_id": "track_time"
|
||||
}
|
||||
]
|
||||
},
|
||||
"header": {
|
||||
"title": {
|
||||
"tag": "plain_text",
|
||||
"content": "【公海】客户线索"
|
||||
},
|
||||
"subtitle": {
|
||||
"tag": "plain_text",
|
||||
"content": ""
|
||||
},
|
||||
"text_tag_list": [
|
||||
{
|
||||
"tag": "text_tag",
|
||||
"text": {
|
||||
"tag": "plain_text",
|
||||
"content": "已跟踪"
|
||||
},
|
||||
"color": "orange"
|
||||
}
|
||||
],
|
||||
"template": "green",
|
||||
"icon": {
|
||||
"tag": "standard_icon",
|
||||
"token": "ai-common_colorful"
|
||||
},
|
||||
"padding": "12px 12px 12px 20px"
|
||||
}
|
||||
}';
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* 线索分配消息
|
||||
*/
|
||||
public function personAllocationTemplates($quality = '💛 银牌商机', $order_no = 'SN2025072365640', $channel = '谷歌', $country = '白俄罗斯', $enter_user = '木子李', $r_time = '2025-07-24 09:41:23', $t_time = '2025-07-24 14:41:23')
|
||||
{
|
||||
$content = '{
|
||||
"schema": "2.0",
|
||||
"config": {
|
||||
"update_multi": true,
|
||||
"style": {
|
||||
"text_size": {
|
||||
"normal_v2": {
|
||||
"default": "normal",
|
||||
"pc": "normal",
|
||||
"mobile": "heading"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"direction": "vertical",
|
||||
"horizontal_spacing": "8px",
|
||||
"vertical_spacing": "16px",
|
||||
"horizontal_align": "left",
|
||||
"vertical_align": "top",
|
||||
"padding": "0px 20px 20px 20px",
|
||||
"elements": [
|
||||
{
|
||||
"tag": "hr",
|
||||
"margin": "0px 0px 0px 0px"
|
||||
},
|
||||
{
|
||||
"tag": "column_set",
|
||||
"horizontal_align": "left",
|
||||
"columns": [
|
||||
{
|
||||
"tag": "column",
|
||||
"width": "weighted",
|
||||
"elements": [
|
||||
{
|
||||
"tag": "markdown",
|
||||
"content": " **'.$quality.'**\n- **编号:** '.$order_no.'\n- **渠道:** '.$channel.'\n- **国家:** '.$country.'\n- **录单人:** '.$enter_user.'\n- **录入时间:** '.$r_time.'",
|
||||
"text_align": "left",
|
||||
"text_size": "normal_v2",
|
||||
"margin": "0px 0px 0px 0px"
|
||||
}
|
||||
],
|
||||
"vertical_spacing": "8px",
|
||||
"horizontal_align": "left",
|
||||
"vertical_align": "top",
|
||||
"weight": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "hr",
|
||||
"margin": "0px 0px 0px 0px"
|
||||
},
|
||||
{
|
||||
"tag": "div",
|
||||
"text": {
|
||||
"tag": "plain_text",
|
||||
"content": "分配时间:'.$t_time.'",
|
||||
"text_size": "notation",
|
||||
"text_align": "left",
|
||||
"text_color": "green"
|
||||
},
|
||||
"icon": {
|
||||
"tag": "standard_icon",
|
||||
"token": "chat-done_outlined",
|
||||
"color": "green"
|
||||
},
|
||||
"element_id": "allocation_time"
|
||||
}
|
||||
]
|
||||
},
|
||||
"header": {
|
||||
"title": {
|
||||
"tag": "plain_text",
|
||||
"content": "新的客户线索"
|
||||
},
|
||||
"subtitle": {
|
||||
"tag": "plain_text",
|
||||
"content": ""
|
||||
},
|
||||
"text_tag_list": [
|
||||
{
|
||||
"tag": "text_tag",
|
||||
"text": {
|
||||
"tag": "plain_text",
|
||||
"content": "指定"
|
||||
},
|
||||
"color": "yellow"
|
||||
}
|
||||
],
|
||||
"template": "blue",
|
||||
"icon": {
|
||||
"tag": "standard_icon",
|
||||
"token": "todo_colorful"
|
||||
},
|
||||
"padding": "12px 12px 12px 20px"
|
||||
}
|
||||
}';
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* 跟进提醒消息
|
||||
*/
|
||||
public function personFollowUpTemplates($contacts = '木子李', $follow_next = '2025-07-24 14:41:23', $follow_last = '2025-07-24 14:41:23')
|
||||
{
|
||||
$content = '{
|
||||
"schema": "2.0",
|
||||
"config": {
|
||||
"update_multi": true,
|
||||
"style": {
|
||||
"text_size": {
|
||||
"normal_v2": {
|
||||
"default": "normal",
|
||||
"pc": "normal",
|
||||
"mobile": "heading"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"direction": "vertical",
|
||||
"horizontal_spacing": "8px",
|
||||
"vertical_spacing": "16px",
|
||||
"horizontal_align": "left",
|
||||
"vertical_align": "top",
|
||||
"padding": "0px 20px 20px 20px",
|
||||
"elements": [
|
||||
{
|
||||
"tag": "hr",
|
||||
"margin": "0px 0px 0px 0px"
|
||||
},
|
||||
{
|
||||
"tag": "column_set",
|
||||
"horizontal_align": "left",
|
||||
"columns": [
|
||||
{
|
||||
"tag": "column",
|
||||
"width": "weighted",
|
||||
"elements": [
|
||||
{
|
||||
"tag": "markdown",
|
||||
"content": "- **客户名称:** '.$contacts.'\n- **跟进时间:** '.$follow_next.'",
|
||||
"text_align": "left",
|
||||
"text_size": "normal_v2",
|
||||
"margin": "0px 0px 0px 0px"
|
||||
}
|
||||
],
|
||||
"vertical_spacing": "8px",
|
||||
"horizontal_align": "left",
|
||||
"vertical_align": "top",
|
||||
"weight": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tag": "hr",
|
||||
"margin": "0px 0px 0px 0px"
|
||||
},
|
||||
{
|
||||
"tag": "div",
|
||||
"text": {
|
||||
"tag": "plain_text",
|
||||
"content": "最近跟进:'.$follow_last.'",
|
||||
"text_size": "notation",
|
||||
"text_align": "left",
|
||||
"text_color": "grey"
|
||||
},
|
||||
"icon": {
|
||||
"tag": "standard_icon",
|
||||
"token": "chat_outlined",
|
||||
"color": "grey"
|
||||
},
|
||||
"element_id": "track_time"
|
||||
}
|
||||
]
|
||||
},
|
||||
"header": {
|
||||
"title": {
|
||||
"tag": "plain_text",
|
||||
"content": "跟进提醒"
|
||||
},
|
||||
"subtitle": {
|
||||
"tag": "plain_text",
|
||||
"content": ""
|
||||
},
|
||||
"template": "green",
|
||||
"icon": {
|
||||
"tag": "standard_icon",
|
||||
"token": "calendar_colorful"
|
||||
},
|
||||
"padding": "12px 12px 12px 20px"
|
||||
}
|
||||
}';
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
@@ -24,44 +24,51 @@ class Generate
|
||||
{
|
||||
$fs = new Filesystem();
|
||||
|
||||
// 模板路径
|
||||
$templateDir = __DIR__ . '/templates/';
|
||||
$controllerPath = __DIR__ . "/../../../{$this->options['controller']['module']}/controller/".$this->rName($this->options['controller']['name'])."Controller.php";
|
||||
$servicePath = __DIR__ . "/../../../{$this->options['service']['module']}/service/".$this->rName($this->options['service']['name'])."Service.php";
|
||||
$logicPath = __DIR__ . "/../../../{$this->options['logic']['module']}/logic/".$this->rName($this->options['logic']['name'])."Logic.php";
|
||||
$modelPath = __DIR__ . "/../../../{$this->options['model']['module']}/model/".$this->rName($this->options['model']['name']).".php";
|
||||
$validatePath = __DIR__ . "/../../../{$this->options['validate']['module']}/validate/".$this->rName($this->options['validate']['name'])."Validate.php";
|
||||
|
||||
// 创建目录(如果不存在)
|
||||
$fs->mkdir(__DIR__ . "/../../../{$this->options['controller']['module']}/controller");
|
||||
$fs->mkdir(__DIR__ . "/../../../{$this->options['service']['module']}/service");
|
||||
$fs->mkdir(__DIR__ . "/../../../{$this->options['logic']['module']}/logic");
|
||||
$fs->mkdir(__DIR__ . "/../../../{$this->options['model']['module']}/model");
|
||||
$fs->mkdir(__DIR__ . "/../../../{$this->options['validate']['module']}/validate");
|
||||
$resultStr = '';
|
||||
|
||||
// // 删除已存在的文件并重新生成
|
||||
$this->deleteFileIfExists($controllerPath);
|
||||
$this->deleteFileIfExists($servicePath);
|
||||
$this->deleteFileIfExists($logicPath);
|
||||
$this->deleteFileIfExists($modelPath);
|
||||
$this->deleteFileIfExists($validatePath);
|
||||
if (!empty($this->options['controller'])) {
|
||||
$controllerPath = __DIR__ . "/../../../{$this->options['controller']['module']}/controller/".$this->rName($this->options['controller']['name'])."Controller.php";
|
||||
$fs->mkdir(__DIR__ . "/../../../{$this->options['controller']['module']}/controller");
|
||||
$this->deleteFileIfExists($controllerPath);
|
||||
$ControllerStub = $this->generateFile($templateDir, 'ControllerStub.stub', $controllerPath, 'controller');
|
||||
$resultStr .= $ControllerStub;
|
||||
}
|
||||
|
||||
// 生成控制器文件
|
||||
$ControllerStub = $this->generateFile($templateDir, 'ControllerStub.stub', $controllerPath, 'controller');
|
||||
|
||||
// 生成服务类文件
|
||||
$ServiceStub = $this->generateFile($templateDir, 'ServiceStub.stub', $servicePath, 'service');
|
||||
|
||||
// 生成逻辑类文件
|
||||
$LogicStub = $this->generateFile($templateDir, 'LogicStub.stub', $logicPath, 'logic');
|
||||
|
||||
// 生成模型类文件
|
||||
$ModelStub = $this->generateFile($templateDir, 'ModelStub.stub', $modelPath, 'model');
|
||||
|
||||
// 生成验证器类文件
|
||||
$ValidatorStub = $this->generateFile($templateDir, 'ValidateStub.stub', $validatePath, 'validate');
|
||||
|
||||
return $ControllerStub . $ServiceStub . $LogicStub . $ModelStub . $ValidatorStub . "<info>文件生成成功!</info> <br/>";
|
||||
if (!empty($this->options['service'])) {
|
||||
$servicePath = __DIR__ . "/../../../{$this->options['service']['module']}/service/".$this->rName($this->options['service']['name'])."Service.php";
|
||||
$fs->mkdir(__DIR__ . "/../../../{$this->options['service']['module']}/service");
|
||||
$this->deleteFileIfExists($servicePath);
|
||||
$ServiceStub = $this->generateFile($templateDir, 'ServiceStub.stub', $servicePath, 'service');
|
||||
$resultStr .= $ServiceStub;
|
||||
}
|
||||
|
||||
if (!empty($this->options['logic'])) {
|
||||
$logicPath = __DIR__ . "/../../../{$this->options['logic']['module']}/logic/".$this->rName($this->options['logic']['name'])."Logic.php";
|
||||
$fs->mkdir(__DIR__ . "/../../../{$this->options['logic']['module']}/logic");
|
||||
$this->deleteFileIfExists($logicPath);
|
||||
$LogicStub = $this->generateFile($templateDir, 'LogicStub.stub', $logicPath, 'logic');
|
||||
$resultStr .= $LogicStub;
|
||||
}
|
||||
|
||||
if (!empty($this->options['model'])) {
|
||||
$modelPath = __DIR__ . "/../../../{$this->options['model']['module']}/model/".$this->rName($this->options['model']['name']).".php";
|
||||
$fs->mkdir(__DIR__ . "/../../../{$this->options['model']['module']}/model");
|
||||
$this->deleteFileIfExists($modelPath);
|
||||
$ModelStub = $this->generateFile($templateDir, 'ModelStub.stub', $modelPath, 'model');
|
||||
$resultStr .= $ModelStub;
|
||||
}
|
||||
|
||||
if (!empty($this->options['validate'])) {
|
||||
$validatePath = __DIR__ . "/../../../{$this->options['validate']['module']}/validate/".$this->rName($this->options['validate']['name'])."Validate.php";
|
||||
$fs->mkdir(__DIR__ . "/../../../{$this->options['validate']['module']}/validate");
|
||||
$this->deleteFileIfExists($validatePath);
|
||||
$ValidatorStub = $this->generateFile($templateDir, 'ValidateStub.stub', $validatePath, 'validate');
|
||||
$resultStr .= $ValidatorStub;
|
||||
}
|
||||
|
||||
return $resultStr ? $resultStr . "<info>文件生成成功!</info> <br/>" : '未生成任何文件';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,27 +3,174 @@
|
||||
namespace app\common\validate;
|
||||
|
||||
use think\Validate;
|
||||
use app\common\model\InquiryLog;
|
||||
|
||||
class InquiryLogValidate extends Validate
|
||||
{
|
||||
// 规则
|
||||
protected $rule = [
|
||||
|
||||
'id' => 'require|integer|gt:0',
|
||||
'order_no' => 'require|alphaDash|length:36',
|
||||
'enter_user_id'=> 'integer|egt:0',
|
||||
'recipient' => 'integer|egt:0',
|
||||
'quality' => 'require|in:1,2,3',
|
||||
'channel' => 'integer|between:0,99',
|
||||
'email' => 'email|max:255|checkEmailContactUnique',
|
||||
'tel' => 'max:255|checkTelContactUnique',
|
||||
'whatsapp' => 'max:255|checkWhatsappContactUnique',
|
||||
'country' => 'integer|egt:0|requireWith:contacts',
|
||||
'contacts' => 'require|max:255|requireWithout:email,tel,whatsapp|checkContactUnique',
|
||||
'content' => 'string',
|
||||
'status' => 'in:0,1,2',
|
||||
'r_time' => 'integer|egt:0',
|
||||
't_time' => 'integer|egt:0'
|
||||
];
|
||||
|
||||
// 提示
|
||||
protected $message = [
|
||||
|
||||
'id.require' => 'ID不能为空',
|
||||
'id.integer' => 'ID必须是整数',
|
||||
'id.gt' => 'ID必须大于0',
|
||||
'order_no.require' => '订单号不能为空',
|
||||
'order_no.alphaDash'=> '订单号只能包含字母、数字和下划线',
|
||||
'order_no.length' => '订单号长度必须为36位',
|
||||
'enter_user_id.integer' => '录入人ID必须是整数',
|
||||
'enter_user_id.egt' => '录入人ID不能为负数',
|
||||
'recipient.integer' => '接单人ID必须是整数',
|
||||
'recipient.egt' => '接单人ID不能为负数',
|
||||
'quality.require' => '询单等级不能为空',
|
||||
'quality.in' => '询单等级只能是1、2或3',
|
||||
'channel.integer' => '渠道编号必须是整数',
|
||||
'channel.between' => '渠道编号范围0-99',
|
||||
'email.email' => '邮箱格式不正确',
|
||||
'email.max' => '邮箱长度不能超过255个字符',
|
||||
'tel.max' => '电话长度不能超过255个字符',
|
||||
'whatsapp.max' => 'WhatsApp长度不能超过255个字符',
|
||||
'country.integer' => '国家代码必须是整数',
|
||||
'country.egt' => '国家代码不能为负数',
|
||||
'contacts.require' => '联系人不能为空',
|
||||
'contacts.max' => '联系人长度不能超过255个字符',
|
||||
'content.string' => '询单内容必须是字符串',
|
||||
'status.in' => '状态值只能是0、1或2',
|
||||
'r_time.integer' => '发布时间必须是整数',
|
||||
'r_time.egt' => '发布时间不能为负数',
|
||||
't_time.integer' => '跟踪时间必须是整数',
|
||||
't_time.egt' => '跟踪时间不能为负数',
|
||||
'email.checkEmailContactUnique' => '邮箱联系方式已存在',
|
||||
'tel.checkTelContactUnique' => '电话联系方式已存在',
|
||||
'whatsapp.checkWhatsappContactUnique' => 'WhatsApp联系方式已存在',
|
||||
'contacts.requireWithout' => '至少需要提供一种联系方式',
|
||||
'contacts.checkContactUnique' => '联系人已存在',
|
||||
'country.requireWith' => '国家必须与联系人一起提供'
|
||||
];
|
||||
|
||||
// 场景
|
||||
protected $scene = [
|
||||
'store' => [
|
||||
|
||||
'enter_user_id', 'quality', 'channel', 'email', 'tel', 'whatsapp', 'country', 'contacts', 'content'
|
||||
],
|
||||
|
||||
'update' => [
|
||||
|
||||
'quality', 'channel', 'email', 'tel', 'whatsapp', 'country', 'contacts', 'content'
|
||||
],
|
||||
'release' => [
|
||||
'status', 'r_time'
|
||||
],
|
||||
'allocation' => [
|
||||
'status', 't_time'
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* 验证联系方式唯一性
|
||||
*/
|
||||
protected function checkContactUnique($value, $rule, $data, $field, $title)
|
||||
{
|
||||
// 如果是更新操作且联系人未修改,跳过检查
|
||||
if ($this->currentScene == 'update') {
|
||||
$original = InquiryLog::find($data['id']);
|
||||
if ($original && $original->contacts == $value && $original->country == ($data['country'] ?? 0)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($data['email']) && empty($data['tel']) && empty($data['whatsapp'])) {
|
||||
$query = InquiryLog::where('contacts', trim($value))
|
||||
->where('country', $data['country']);
|
||||
|
||||
if (!empty($data['id'])) {
|
||||
$query->where('id', '<>', $data['id']);
|
||||
}
|
||||
|
||||
return !$query->exists();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证邮箱联系方式唯一性
|
||||
*/
|
||||
protected function checkEmailContactUnique($value, $rule, $data, $field, $title)
|
||||
{
|
||||
if (empty($value)) return true;
|
||||
|
||||
// 如果是更新操作且邮箱未修改,跳过检查
|
||||
if ($this->currentScene == 'update' && !empty($data['id'])) {
|
||||
$original = InquiryLog::find($data['id']);
|
||||
if ($original && $original->email == $value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$query = InquiryLog::where('email', trim($value));
|
||||
if (!empty($data['id'])) {
|
||||
$query->where('id', '<>', $data['id']);
|
||||
}
|
||||
return !$query->exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证电话联系方式唯一性
|
||||
*/
|
||||
protected function checkTelContactUnique($value, $rule, $data, $field, $title)
|
||||
{
|
||||
if (empty($value)) return true;
|
||||
|
||||
// 如果是更新操作且电话未修改,跳过检查
|
||||
if ($this->currentScene == 'update' && !empty($data['id'])) {
|
||||
$original = InquiryLog::find($data['id']);
|
||||
if ($original && $original->tel == $value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$query = InquiryLog::where('tel', trim($value));
|
||||
if (!empty($data['id'])) {
|
||||
$query->where('id', '<>', $data['id']);
|
||||
}
|
||||
return !$query->exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证WhatsApp联系方式唯一性
|
||||
*/
|
||||
protected function checkWhatsappContactUnique($value, $rule, $data, $field, $title)
|
||||
{
|
||||
if (empty($value)) return true;
|
||||
|
||||
// 如果是更新操作且WhatsApp未修改,跳过检查
|
||||
if ($this->currentScene == 'update' && !empty($data['id'])) {
|
||||
$original = InquiryLog::find($data['id']);
|
||||
if ($original && $original->whatsapp == $value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$query = InquiryLog::where('whatsapp', trim($value));
|
||||
if (!empty($data['id'])) {
|
||||
$query->where('id', '<>', $data['id']);
|
||||
}
|
||||
return !$query->exists();
|
||||
}
|
||||
}
|
||||
@@ -9,13 +9,14 @@ use app\common\utils\scaffold\Generate;
|
||||
use support\Request;
|
||||
use support\Db;
|
||||
use support\Cache;
|
||||
use app\inquiry\service\InquiryLogService;
|
||||
|
||||
class IndexController
|
||||
{
|
||||
|
||||
protected $noNeedLogin = ['index', 'view', 'perm', 'createResource'];
|
||||
protected $noNeedLogin = ['index', 'view', 'perm', 'createResource', 'test'];
|
||||
|
||||
protected $noNeedHeaderData = ['index', 'view', 'perm', 'createResource'];
|
||||
protected $noNeedHeaderData = ['index', 'view', 'perm', 'createResource', 'test'];
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
@@ -70,30 +71,53 @@ class IndexController
|
||||
public function createResource()
|
||||
{
|
||||
$options = [
|
||||
'controller' => [
|
||||
'module' => 'inquiry',
|
||||
'name' => 'country'
|
||||
],
|
||||
// 'controller' => [
|
||||
// 'module' => 'inquiry',
|
||||
// 'name' => 'country'
|
||||
// ],
|
||||
'model' => [
|
||||
'module' => 'inquiry',
|
||||
'name' => 'country'
|
||||
'module' => 'common',
|
||||
'name' => 'crm_customer'
|
||||
],
|
||||
'service' => [
|
||||
'module' => 'inquiry',
|
||||
'name' => 'country'
|
||||
],
|
||||
'logic' => [
|
||||
'module' => 'inquiry',
|
||||
'name' => 'country'
|
||||
],
|
||||
'validate' => [
|
||||
'module' => 'inquiry',
|
||||
'name' => 'country'
|
||||
],
|
||||
'table' => 'country'
|
||||
// 'service' => [
|
||||
// 'module' => 'inquiry',
|
||||
// 'name' => 'country'
|
||||
// ],
|
||||
// 'logic' => [
|
||||
// 'module' => 'inquiry',
|
||||
// 'name' => 'country'
|
||||
// ],
|
||||
// 'validate' => [
|
||||
// 'module' => 'inquiry',
|
||||
// 'name' => 'country'
|
||||
// ],
|
||||
'table' => 'crm_customer'
|
||||
];
|
||||
|
||||
$result = (new Generate($options))->doGenerate();
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
public function test()
|
||||
{
|
||||
// $res = ['id'=>25714];
|
||||
// \Webman\RedisQueue\Redis::send('inquiry-to-crm', $res);
|
||||
|
||||
// $res = [
|
||||
// 'id'=>25717,
|
||||
// 'category'=>'inquiry',
|
||||
// 'scene'=>'inquiry-person-allocation',
|
||||
// 'receive_type'=>'person'
|
||||
// ];
|
||||
|
||||
// $res = [
|
||||
// 'id'=>1,
|
||||
// 'category'=>'crm',
|
||||
// 'scene'=>'crm-person-follow-up',
|
||||
// 'receive_type'=>'person'
|
||||
// ];
|
||||
// \Webman\RedisQueue\Redis::send('feishu-message', $res);
|
||||
return 'success';
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,15 @@ if (!function_exists('getConfig')) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 询单号生成
|
||||
*/
|
||||
if (!function_exists('orderNum')) {
|
||||
function orderNum() {
|
||||
return "SN".date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 调试用
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace app\inquiry\controller;
|
||||
use app\common\controller\BaseController;
|
||||
use app\common\traits\crud\CrudControllerTrait;
|
||||
use app\inquiry\service\InquiryLogService;
|
||||
use support\Request;
|
||||
|
||||
class InquiryLogController extends BaseController
|
||||
{
|
||||
@@ -22,544 +23,56 @@ class InquiryLogController extends BaseController
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
// protected function indexFormat($data)
|
||||
// {
|
||||
// if (isset($data['created_at']))
|
||||
// $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
// if (isset($data['updated_at']))
|
||||
// $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
|
||||
// return $data;
|
||||
// }
|
||||
|
||||
|
||||
// 列表
|
||||
public function list(Request $request)
|
||||
protected function indexFormat($data)
|
||||
{
|
||||
if ($request->method() == 'POST') {
|
||||
$data = $request->all();
|
||||
$limit = isset($data['limit']) && $data['limit'] ? $data['limit'] : 10;
|
||||
|
||||
// 状态
|
||||
$roleId = $request->user->role_id;
|
||||
$where = [];
|
||||
if (in_array($roleId, [RoleRulesModel::ALL_ROLE_ID, RoleRulesModel::KEFU_ROLE_ID])) {
|
||||
if (isset($data["status"]) && $data["status"] != "") {
|
||||
$where[] = [
|
||||
"status", "=", $data["status"]
|
||||
];
|
||||
} else {
|
||||
$where[] = [
|
||||
"status", ">", -1
|
||||
];
|
||||
}
|
||||
} else {
|
||||
$where[] = [
|
||||
"status", "=", 1
|
||||
];
|
||||
}
|
||||
|
||||
// 检索渠道
|
||||
if (isset($data["channel"]) && $data["channel"]) {
|
||||
$where[] = [
|
||||
"log_type", "=", $data["channel"]
|
||||
];
|
||||
}
|
||||
|
||||
// 检索国家
|
||||
if (isset($data["country"]) && $data["country"]) {
|
||||
$where[] = [
|
||||
"log_country", "=", $data["country"]
|
||||
];
|
||||
}
|
||||
|
||||
// 检索时间
|
||||
if (isset($data["ld_time"]) && $data["ld_time"]) {
|
||||
$times = explode(' - ', $data["ld_time"]);
|
||||
$specificDayStart = trim($times[0]);
|
||||
$specificDayEnd = trim($times[1]);
|
||||
$where[] = [
|
||||
"c_time", ">", strtotime($specificDayStart)
|
||||
];
|
||||
$where[] = [
|
||||
"c_time", "<=", strtotime($specificDayEnd)
|
||||
];
|
||||
}
|
||||
|
||||
// 检查渠道(不取缓存中的值)
|
||||
// $channel = $request->user->channel;
|
||||
$uinfos = UsersModel::where('id', $request->user->uid)->first();
|
||||
$channel = $uinfos->channel;
|
||||
if ($channel) {
|
||||
$channel = explode(",", $channel);
|
||||
$InquiryLogModelModel = InquiryLogModel::where($where)->whereIn("log_type", $channel);
|
||||
} else {
|
||||
$InquiryLogModelModel = InquiryLogModel::where($where);
|
||||
}
|
||||
|
||||
// 关键字
|
||||
if (isset($data["kwd"]) && $data["kwd"] != "") {
|
||||
$InquiryLogModelModel->whereRaw("concat(`log_contact_type`,`log_contact_tel`,`log_contact_whatsapp`,`log_contacts`,`order_no`) like '%".$data['kwd']."%'");
|
||||
}
|
||||
|
||||
$list = $InquiryLogModelModel
|
||||
->with([
|
||||
"eUserInfo"=>function($query) {
|
||||
$query->where("id", ">", 0);
|
||||
}, "rUserInfo"=>function($query) {
|
||||
$query->where("id", ">", 0);
|
||||
}, "countryInfo"
|
||||
])
|
||||
->orderBy("id", "desc")
|
||||
->paginate($limit);
|
||||
|
||||
$configsModel = new ConfigsModel();
|
||||
$logLevel = $configsModel->getConfig("log_level");
|
||||
$countdown = (int)($configsModel->getConfig("score_countdown")) * 60;
|
||||
$inquiryChannelList = ChannelModel::all(['id', 'name']);
|
||||
$inquiryChannel = [];
|
||||
foreach ($inquiryChannelList as $key => $val) {
|
||||
$inquiryChannel[$val->id] = $val->name;
|
||||
}
|
||||
|
||||
$arr = [];
|
||||
foreach ($list->items() as $key => $val) {
|
||||
$expiry_time = $val->r_time + $countdown;
|
||||
$is_expiry = 0;
|
||||
$expiry_ts = 0;
|
||||
if ($expiry_time <= time()) {
|
||||
$is_expiry = 1;
|
||||
} else {
|
||||
$diff = $expiry_time - (int)time();
|
||||
$expiry_ts = $diff * 1000;
|
||||
}
|
||||
$rUinfo = "";
|
||||
if ($val->rUserInfo) {
|
||||
$rUinfo = $val->rUserInfo->name;
|
||||
}
|
||||
$eUinfo = "";
|
||||
if ($val->eUserInfo) {
|
||||
$eUinfo = $val->eUserInfo->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示联系方式条件:
|
||||
* 1.已跟单并且当前用户是接单人
|
||||
* 2.主权限
|
||||
* 3.当前用户是录单人
|
||||
*/
|
||||
if (
|
||||
($val->status == 2 && $request->user->uid == $val->recipient) ||
|
||||
($roleId == RoleRulesModel::ALL_ROLE_ID) ||
|
||||
($request->user->uid == $val->enter_user_id)
|
||||
) {
|
||||
$log_contact_type = $val->log_contact_type == "" ? " 无 " : $val->log_contact_type;
|
||||
$log_contact_tel = $val->log_contact_tel == "" ? " 无 " : $val->log_contact_tel;
|
||||
$log_contact_whatsapp = $val->log_contact_whatsapp == "" ? " 无 " : $val->log_contact_whatsapp;
|
||||
} else {
|
||||
$log_contact_type = "******";
|
||||
$log_contact_tel = "******";
|
||||
$log_contact_whatsapp = "******";
|
||||
}
|
||||
$arr[] = [
|
||||
"id" => $val->id,
|
||||
"order_no" => $val->order_no,
|
||||
"enter_user_id" => $val->enter_user_id,
|
||||
"recipient" => $val->recipient,
|
||||
"log_quality" => $val->log_quality,
|
||||
"log_quality_desc" => $logLevel[$val->log_quality],
|
||||
"log_quality_color" => InquiryLogModel::LEVEL_BUTTON_COLOR[$val->log_quality],
|
||||
"log_type" => $val->log_type,
|
||||
"log_type_desc" => $inquiryChannel[$val->log_type],
|
||||
"log_contact_type" => $log_contact_type,
|
||||
"log_contact_tel" => $log_contact_tel,
|
||||
"log_contact_whatsapp" => $log_contact_whatsapp,
|
||||
"log_country" => $val->countryInfo->cn_addr."(".$val->countryInfo->two_letter.")",
|
||||
"log_country_steering" => $val->countryInfo->steering,
|
||||
"log_contacts" => $val->log_contacts,
|
||||
"log_content" => $val->log_content,
|
||||
"e_time" => $val->status==1?date("Y-m-d H:i:s", $expiry_time):"",
|
||||
"status" => $val->status,
|
||||
"status_color" => InquiryLogModel::STATUS_BUTTON_COLOR[$val->status],
|
||||
"status_desc" => InquiryLogModel::STATUS[$val->status],
|
||||
"is_expiry" => $is_expiry,
|
||||
"expiry_ts" => $expiry_ts,
|
||||
"rUinfo" => $rUinfo,
|
||||
"eUinfo" => $eUinfo,
|
||||
"r_time" => $val->r_time?date("Y-m-d H:i:s", $val->r_time):"",
|
||||
"n_time" => date("Y-m-d H:i:s", time()),
|
||||
"c_time" => date("Y-m-d H:i:s", strtotime($val->c_time)),
|
||||
"u_time" => date("Y-m-d H:i:s", strtotime($val->u_time))
|
||||
];
|
||||
}
|
||||
$data = [
|
||||
'lastPage' => $list->lastPage(),
|
||||
'currentPage' => $list->currentPage(),
|
||||
'hasMorePages' => $list->hasMorePages(),
|
||||
'list' => $arr,
|
||||
'counts' => $list->total()
|
||||
];
|
||||
return $this->successResponse($data);
|
||||
$data['countdown'] = time()-1;
|
||||
if (isset($data['r_time'])) {
|
||||
$countdown = 60 * 60;
|
||||
$data['countdown'] = (time() - $data['r_time']) < $countdown ? $data['r_time'] + (60*60) : time()-1;
|
||||
}
|
||||
return view('inquiry-log/list');
|
||||
if (isset($data['created_at']))
|
||||
$data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
|
||||
if (isset($data['updated_at']))
|
||||
$data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
|
||||
if (isset($data['r_time']))
|
||||
$data['r_time'] = $data['r_time'] > 0 ? date('Y-m-d H:i:s', $data['r_time']) : 0;
|
||||
if (isset($data['t_time']))
|
||||
$data['t_time'] = $data['t_time'] > 0 ? date('Y-m-d H:i:s', $data['t_time']) : 0;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
// 添加
|
||||
public function add(Request $request)
|
||||
{
|
||||
if ($request->method() == "POST") {
|
||||
$enterUserId = $request->user->uid;
|
||||
$data = $request->all();
|
||||
|
||||
if ($data["log_contact_type"]) {
|
||||
$check1 = InquiryLogModel::where("log_contact_type", trim($data["log_contact_type"]))->first();
|
||||
if ($check1 != NULL) {
|
||||
return $this->errorResponse('邮箱-联系方式已存在');
|
||||
}
|
||||
}
|
||||
|
||||
if ($data["log_contact_tel"]) {
|
||||
$check2 = InquiryLogModel::where("log_contact_tel", trim($data["log_contact_tel"]))->first();
|
||||
if ($check2 != NULL) {
|
||||
return $this->errorResponse('电话-联系方式已存在');
|
||||
}
|
||||
}
|
||||
|
||||
if ($data["log_contact_whatsapp"]) {
|
||||
$check3 = InquiryLogModel::where("log_contact_whatsapp", trim($data["log_contact_whatsapp"]))->first();
|
||||
if ($check3 != NULL) {
|
||||
return $this->errorResponse('whatsapp-联系方式已存在');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$data["log_contact_type"] && !$data["log_contact_tel"] && !$data["log_contact_whatsapp"]) {
|
||||
$check4 = InquiryLogModel::where("log_contacts", trim($data["log_contacts"]))->where("log_country", $data["country"])->first();
|
||||
if ($check4 != NULL) {
|
||||
return $this->errorResponse('联系人已存在');
|
||||
}
|
||||
}
|
||||
|
||||
$model = new InquiryLogModel();
|
||||
$model->order_no = orderNum();
|
||||
$model->enter_user_id = $enterUserId;
|
||||
$model->recipient = 0;
|
||||
$model->log_type = $data["log_type"];
|
||||
$model->log_contact_type = trim($data["log_contact_type"]);
|
||||
$model->log_contact_tel = trim($data["log_contact_tel"]);
|
||||
$model->log_contact_whatsapp = trim($data["log_contact_whatsapp"]);
|
||||
$model->log_country = $data["country"];
|
||||
$model->log_contacts = $data["log_contacts"];
|
||||
$model->log_content = $data["log_content"];
|
||||
$model->log_quality = $data["log_quality"];
|
||||
$model->status = 0;
|
||||
if ($model->save()) {
|
||||
return $this->successResponse([], '添加成功');
|
||||
} else {
|
||||
return $this->errorResponse('添加失败,请重试');
|
||||
}
|
||||
}
|
||||
return view('inquiry-log/add');
|
||||
}
|
||||
|
||||
// 编辑
|
||||
public function edit(Request $request)
|
||||
{
|
||||
if ($request->method() == "POST") {
|
||||
$data = $request->all();
|
||||
$model = new InquiryLogModel();
|
||||
$info = $model->where("id", $data["id"])->first();
|
||||
|
||||
if ($data["log_contact_type"]) {
|
||||
$check1 = InquiryLogModel::where("log_contact_type", trim($data["log_contact_type"]))->first();
|
||||
if ($check1 != NULL && $check1->id != $data["id"]) {
|
||||
return $this->errorResponse('邮箱-联系方式已存在');
|
||||
}
|
||||
}
|
||||
|
||||
if ($data["log_contact_tel"]) {
|
||||
$check2 = InquiryLogModel::where("log_contact_tel", trim($data["log_contact_tel"]))->first();
|
||||
if ($check2 != NULL && $check2->id != $data["id"]) {
|
||||
return $this->errorResponse('电话-联系方式已存在');
|
||||
}
|
||||
}
|
||||
|
||||
if ($data["log_contact_whatsapp"]) {
|
||||
$check3 = InquiryLogModel::where("log_contact_whatsapp", trim($data["log_contact_whatsapp"]))->first();
|
||||
if ($check3 != NULL && $check3->id != $data["id"]) {
|
||||
return $this->errorResponse('whatsapp-联系方式已存在');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$data["log_contact_type"] && !$data["log_contact_tel"] && !$data["log_contact_whatsapp"]) {
|
||||
$check4 = InquiryLogModel::where("log_contacts", trim($data["log_contacts"]))->where("log_country", $data["country"])->first();
|
||||
if ($check4 != NULL && $check4->id != $data["id"]) {
|
||||
return $this->errorResponse('联系人已存在');
|
||||
}
|
||||
}
|
||||
|
||||
$info->log_type = $data["log_type"];
|
||||
$info->log_contact_type = $data["log_contact_type"];
|
||||
$info->log_contact_tel = $data["log_contact_tel"];
|
||||
$info->log_contact_whatsapp = $data["log_contact_whatsapp"];
|
||||
$info->log_country = $data["country"];
|
||||
$info->log_contacts = $data["log_contacts"];
|
||||
$info->log_content = $data["log_content"];
|
||||
$info->log_quality = $data["log_quality"];
|
||||
if (!$info->save()) {
|
||||
return $this->errorResponse('操作失败,请重试');
|
||||
}
|
||||
return $this->successResponse([], '操作成功');
|
||||
}
|
||||
return view('inquiry-log/edit');
|
||||
}
|
||||
|
||||
// 删除
|
||||
public function del(Request $request)
|
||||
{
|
||||
if ($request->method() == "POST") {
|
||||
$id = $request->post("id");
|
||||
$rst = InquiryLogModel::where("id", $id)->first();
|
||||
if (!$rst) {
|
||||
return $this->errorResponse('询单未找到');
|
||||
}
|
||||
if ($rst->enter_user_id != $request->user->uid) {
|
||||
return $this->errorResponse('只能删除自己录入的询单');
|
||||
}
|
||||
$res = InquiryLogModel::where("id", $id)->where("enter_user_id", $request->user->uid)->delete();
|
||||
if (!$res) {
|
||||
return $this->errorResponse('操作失败,请重试');
|
||||
}
|
||||
fileLog('ID:'.$request->user->uid.' - 删除:询单ID:'.$id);
|
||||
return $this->successResponse([], '操作成功');
|
||||
}
|
||||
return $this->errorResponse('请求方式错误');
|
||||
}
|
||||
|
||||
// 单条信息
|
||||
public function info(Request $request)
|
||||
{
|
||||
if ($request->method() == "POST") {
|
||||
$id = $request->all("id");
|
||||
$info = InquiryLogModel::where("id", $id)->first()->toArray();
|
||||
$list = CountryModel::all(["cn_addr", "two_letter", "id"]);
|
||||
$arr = [];
|
||||
foreach ($list as $vo) {
|
||||
$arr[] = [
|
||||
"value" => $vo->id,
|
||||
"name" => $vo->cn_addr."(".$vo->two_letter.")"
|
||||
];
|
||||
}
|
||||
$info["guojia"] = $arr;
|
||||
$info["guojia_id"] = [$info["log_country"]];
|
||||
|
||||
$configsModel = new ConfigsModel();
|
||||
// $data = $configsModel->getConfig("inquiry_channel");
|
||||
$inquiryChannelList = ChannelModel::all(['id', 'name']);
|
||||
$data = [];
|
||||
foreach ($inquiryChannelList as $key => $val) {
|
||||
$data[$val->id] = $val->name;
|
||||
}
|
||||
|
||||
$arr = [];
|
||||
foreach ($data as $ky => $vo) {
|
||||
$arr[] = [
|
||||
"id" => $ky,
|
||||
"name" => $vo
|
||||
];
|
||||
}
|
||||
$info["qudao"] = $arr;
|
||||
|
||||
$data1 = $configsModel->getConfig("log_level");
|
||||
$arr1 = [];
|
||||
foreach ($data1 as $ky => $vo) {
|
||||
$arr1[] = [
|
||||
"id" => $ky,
|
||||
"name" => $vo
|
||||
];
|
||||
}
|
||||
$info["dengji"] = $arr1;
|
||||
if (!$info) {
|
||||
return $this->errorResponse('查询失败,请重试');
|
||||
}
|
||||
$info["log_content"] = strTh($info["log_content"]);
|
||||
return $this->successResponse($info, 'success');
|
||||
}
|
||||
return $this->errorResponse('请求方式错误');
|
||||
}
|
||||
|
||||
// 立即发布
|
||||
/**
|
||||
* 发布
|
||||
*
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function release(Request $request)
|
||||
{
|
||||
try {
|
||||
if ($request->method() == "POST") {
|
||||
$id = $request->post("id");
|
||||
if (!in_array($request->user->role_id, [RoleRulesModel::ALL_ROLE_ID, RoleRulesModel::KEFU_ROLE_ID])) {
|
||||
return $this->errorResponse('无操作权限');
|
||||
}
|
||||
$info = InquiryLogModel::where("id", $id)->first();
|
||||
if (!$info) {
|
||||
return $this->errorResponse('询单信息未找到');
|
||||
}
|
||||
if ($info->status != 0) {
|
||||
return $this->errorResponse('状态异常,无法发布');
|
||||
}
|
||||
$info->r_time = time();
|
||||
$info->status = 1;
|
||||
if (!$info->save()) {
|
||||
return $this->errorResponse('发布失败,请重试');
|
||||
}
|
||||
|
||||
// 发送飞书群消息通知
|
||||
$data = ["order_id"=>$id];
|
||||
RedisQueueRedis::send("release", $data);
|
||||
// 发送飞书群消息通知
|
||||
|
||||
return $this->successResponse([], '发布成功');
|
||||
}
|
||||
return $this->errorResponse('电话-请求方式错误');
|
||||
} catch (\Throwable $th) {
|
||||
fileLog($th->getFile()."|".$th->getLine()."|".$th->getMessage());
|
||||
return $this->errorResponse($th->getMessage());
|
||||
$data = $this->validate($this->service->getValidator(), $request->post(), 'release');
|
||||
$res = $this->service->serviceRelease($request, $data);
|
||||
return $this->success([], '发布成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 立即跟单
|
||||
public function track(Request $request)
|
||||
{
|
||||
// Db::beginTransaction();
|
||||
try {
|
||||
if ($request->method() == "POST") {
|
||||
$id = $request->post("id");
|
||||
$uid = $request->user->uid;
|
||||
if (!in_array($request->user->role_id, [RoleRulesModel::ALL_ROLE_ID, RoleRulesModel::YEWU_ROLE_ID])) {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('无操作权限');
|
||||
}
|
||||
$info = InquiryLogModel::where("id", $id)->first();
|
||||
if (!$info) {
|
||||
return $this->errorResponse('询单信息未找到');
|
||||
}
|
||||
if ($info->status != 1) {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('状态异常,无法跟单');
|
||||
}
|
||||
// 更新询单
|
||||
$info->recipient = $uid;
|
||||
$info->t_time = time();
|
||||
$info->status = 2;
|
||||
// 记录跟单
|
||||
$model = new UserOrderModel();
|
||||
$model->uid = $request->user->uid;
|
||||
$model->log_id = $id;
|
||||
$model->score = (new InquiryLogModel())->score($info->log_quality, $info->r_time);
|
||||
if (!$info->save() || !$model->save()) {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('操作失败,请重试');
|
||||
}
|
||||
// Db::commit();
|
||||
|
||||
// // 发送飞书群消息通知
|
||||
$data1 = ["order_id"=>$id];
|
||||
RedisQueueRedis::send("track", $data1);
|
||||
// // 发送飞书群消息通知
|
||||
|
||||
// // 同步询单到crm
|
||||
$data2 = ["order_id"=>$id];
|
||||
RedisQueueRedis::send("inquiry-sync", $data2);
|
||||
// // 同步询单到crm
|
||||
|
||||
return $this->successResponse([], '跟单操作成功');
|
||||
} else {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('请求方式错误');
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
// Db::rollBack();
|
||||
fileLog($th->getFile()."|".$th->getLine()."|".$th->getMessage());
|
||||
return $this->errorResponse($th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 详情
|
||||
public function detail(Request $request)
|
||||
{
|
||||
if ($request->method() == "POST") {
|
||||
$id = $request->all("id");
|
||||
$res = InquiryLogModel::where("id", $id)->first()->toArray();
|
||||
return $this->successResponse(["detail"=>$res["log_content"]], '操作成功');
|
||||
|
||||
}
|
||||
return view('inquiry-log/detail');
|
||||
}
|
||||
|
||||
// 客服分单给业务
|
||||
/**
|
||||
* 分配
|
||||
*
|
||||
* @param Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function allocation(Request $request)
|
||||
{
|
||||
// Db::beginTransaction();
|
||||
try {
|
||||
if ($request->method() == "POST") {
|
||||
$data = $request->all();
|
||||
|
||||
$userInfo = UsersModel::where("id", $data["gd_user"])->first();
|
||||
if (!$userInfo) {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('用户未找到');
|
||||
}
|
||||
|
||||
$model = new InquiryLogModel();
|
||||
$info = $model->where("id", $data["id"])->first();
|
||||
if (!$info) {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('询单未找到');
|
||||
}
|
||||
|
||||
$uomodel = new UserOrderModel();
|
||||
$uoInfo = $uomodel->where("log_id", $data["id"])->first();
|
||||
if (!$uoInfo) {
|
||||
// 记录跟单
|
||||
$HsUserOrderModel = new UserOrderModel();
|
||||
$HsUserOrderModel->uid = $data["gd_user"];
|
||||
$HsUserOrderModel->log_id = $data["id"];
|
||||
$HsUserOrderModel->score = (new InquiryLogModel())->score($info->log_quality, $info->r_time);
|
||||
if (!$HsUserOrderModel->save()) {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('记录跟单操作失败,请重试');
|
||||
}
|
||||
} else {
|
||||
$uoInfo->uid = $data["gd_user"];
|
||||
if (!$uoInfo->save()) {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('操作失败,请重试');
|
||||
}
|
||||
}
|
||||
|
||||
if ($info->status != 2) {
|
||||
$info->t_time = time();
|
||||
$info->status = 2;
|
||||
}
|
||||
$info->recipient = $data["gd_user"];
|
||||
if (!$info->save()) {
|
||||
// Db::rollBack();
|
||||
return $this->errorResponse('操作失败,请重试');
|
||||
}
|
||||
// Db::commit();
|
||||
|
||||
// 发送飞书群消息通知
|
||||
$data1 = ["order_id"=>$data["id"]];
|
||||
RedisQueueRedis::send("allocation", $data1);
|
||||
// 发送飞书群消息通知
|
||||
|
||||
// // 同步询单到crm
|
||||
$data2 = ["order_id"=>$data["id"]];
|
||||
RedisQueueRedis::send("inquiry-sync", $data2);
|
||||
// // 同步询单到crm
|
||||
|
||||
return $this->successResponse([], '操作成功');
|
||||
}
|
||||
return view('inquiry-log/allocation');
|
||||
} catch (\Throwable $th) {
|
||||
// Db::rollBack();
|
||||
fileLog($th->getFile()."|".$th->getLine()."|".$th->getMessage());
|
||||
return $this->errorResponse($th->getMessage());
|
||||
$data = $this->validate($this->service->getValidator(), $request->post(), 'allocation');
|
||||
$res = $this->service->serviceAllocation($request, $data);
|
||||
return $this->success([], '分配成功');
|
||||
} catch (\Throwable $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@ namespace app\inquiry\service;
|
||||
use app\common\validate\InquiryLogValidate;
|
||||
use app\common\traits\crud\CrudServiceTrait;
|
||||
use app\common\model\InquiryLog;
|
||||
use support\exception\BusinessException;
|
||||
use support\Request;
|
||||
use Webman\RedisQueue\Redis as RedisQueueRedis;
|
||||
|
||||
class InquiryLogService
|
||||
{
|
||||
@@ -30,7 +32,31 @@ class InquiryLogService
|
||||
return new $this->validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布
|
||||
*/
|
||||
public function serviceRelease(Request $request, array $data = [])
|
||||
{
|
||||
$data = $this->preProcess('Release', $data, $request);
|
||||
$config = $this->buildQueryConfig($request, 'release');
|
||||
$updated = $this->logicUpdateBy($config, $data);
|
||||
return $this->postProcess('Release', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配
|
||||
*/
|
||||
public function serviceAllocation(Request $request, array $data = [])
|
||||
{
|
||||
$data = $this->preProcess('Allocation', $data, $request);
|
||||
$config = $this->buildQueryConfig($request, 'allocation');
|
||||
$updated = $this->logicUpdateBy($config, $data);
|
||||
return $this->postProcess('Allocation', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建查询条件
|
||||
*/
|
||||
protected function buildQueryConfig(Request $request, string $scene = 'index'): array
|
||||
{
|
||||
$p = $request->all();
|
||||
@@ -39,37 +65,29 @@ class InquiryLogService
|
||||
$config['model'] = $this->modelClass;
|
||||
switch ($scene) {
|
||||
case 'index':
|
||||
// 排序
|
||||
// ====== ====== 排序 ====== ======
|
||||
$config['order']['id'] = 'desc';
|
||||
|
||||
// ====== ====== 筛选 ====== ======
|
||||
// 渠道
|
||||
if (isset($p['channel']) && $p['channel']) {
|
||||
$config['where']['channel'] = $p['channel'];
|
||||
}
|
||||
|
||||
// 国家
|
||||
if (isset($p['country']) && $p['country']) {
|
||||
$config['where']['country'] = $p['country'];
|
||||
}
|
||||
|
||||
// 时间
|
||||
if (isset($p['time']) && $p['time']) {
|
||||
// $time = explode(' - ', $p['time']);
|
||||
// $config['where']['created_at'] = [
|
||||
// ['>=', strtotime($time[0])],
|
||||
// ['<=', strtotime($time[1])],
|
||||
// ];
|
||||
$time = explode(' - ', $p['time']);
|
||||
$config['where']['created_at'] = [
|
||||
strtotime(explode(' - ', $p['time'])[0]),
|
||||
strtotime(explode(' - ', $p['time'])[1]),
|
||||
'between', [strtotime($time[0]), strtotime($time[1])]
|
||||
];
|
||||
}
|
||||
|
||||
// 状态
|
||||
if (isset($p['status']) && $p['status']) {
|
||||
if (isset($p['status']) && in_array($p['status'], [0,1,2])) {
|
||||
$config['where']['status'] = $p['status'];
|
||||
}
|
||||
|
||||
// 关键字
|
||||
if (isset($p['keyword']) && $p['keyword']) {
|
||||
$k = '%' . $p['keyword'] . '%';
|
||||
@@ -78,27 +96,131 @@ class InquiryLogService
|
||||
}
|
||||
}
|
||||
|
||||
// 关联
|
||||
$config['with'][] = 'country';
|
||||
$config['with']['enter'][] = 'id';
|
||||
// ====== ====== 关联 ====== ======
|
||||
$config['with']['countryInfo'][] = 'cn_addr';
|
||||
$config['with']['countryInfo'][] = 'steering';
|
||||
$config['with']['enter'][] = 'name';
|
||||
$config['with']['recipient'][] = 'id';
|
||||
$config['with']['recipient'][] = 'name';
|
||||
$config['with']['channelInfo'][] = 'name';
|
||||
break;
|
||||
case 'show':
|
||||
$config['where']['id'] = $p['id'];
|
||||
$config['where']['status'] = 1;
|
||||
break;
|
||||
case 'store':
|
||||
break;
|
||||
case 'update':
|
||||
$config['where']['id'] = $p['id'];
|
||||
break;
|
||||
case 'destroy':
|
||||
case 'release':
|
||||
case 'allocation':
|
||||
$config['where']['id'] = $p['id'];
|
||||
case 'store':
|
||||
break;
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加前置处理
|
||||
*/
|
||||
public function beforeServiceStore($data, Request $request)
|
||||
{
|
||||
$data['order_no'] = orderNum();
|
||||
$data['enter_user_id'] = $request->user->uid;
|
||||
$data['recipient'] = 0;
|
||||
$data['email'] = trim($data["email"]);
|
||||
$data['tel'] = trim($data['tel']);
|
||||
$data['whatsapp'] = trim($data['whatsapp']);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布前置处理
|
||||
*/
|
||||
public function beforeServiceRelease($data, Request $request)
|
||||
{
|
||||
$info = $this->findByPk($request->post('id'));
|
||||
if (!$info) {
|
||||
throw new BusinessException('数据不存在');
|
||||
}
|
||||
if ($info->status != 0) {
|
||||
throw new BusinessException('询单已被发布');
|
||||
}
|
||||
$data['r_time'] = time();
|
||||
$data['status'] = 1;
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配前置处理
|
||||
*/
|
||||
public function beforeServiceAllocation($data, Request $request)
|
||||
{
|
||||
$info = $this->findByPk($request->post('id'));
|
||||
if (!$info) {
|
||||
throw new BusinessException('数据不存在');
|
||||
}
|
||||
if ($info->status == 2) {
|
||||
throw new BusinessException('询单已被分配');
|
||||
}
|
||||
if ($info->status == 0) {
|
||||
$data['r_time'] = time();
|
||||
}
|
||||
$data['t_time'] = time();
|
||||
$data['status'] = 2;
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布后置处理
|
||||
*/
|
||||
protected function afterServiceRelease($res)
|
||||
{
|
||||
RedisQueueRedis::send('inquiry-to-crm', $res);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配后置处理
|
||||
*/
|
||||
protected function afterServiceAllocation($res)
|
||||
{
|
||||
RedisQueueRedis::send('inquiry-to-crm', $res);
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取询单ById
|
||||
* @param int|string $id
|
||||
* @param string $orderSn
|
||||
* @return Model|null
|
||||
*/
|
||||
public function getInquiryLogBy(int|string $id)
|
||||
{
|
||||
$config = [];
|
||||
$config['model'] = $this->modelClass;
|
||||
$config['with']['countryInfo'][] = 'cn_addr';
|
||||
$config['with']['countryInfo'][] = 'steering';
|
||||
$config['with']['enter'][] = 'name';
|
||||
$config['with']['recipient'][] = 'name';
|
||||
$config['with']['channelInfo'][] = 'name';
|
||||
$config['orWhere'][] = ['id', '=', $id];
|
||||
$config['orWhere'][] = ['order_no', '=', $id];
|
||||
return $this->logicShow($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取等级名称
|
||||
* @param $id
|
||||
* @return string
|
||||
*/
|
||||
public function qualityName($id)
|
||||
{
|
||||
if (!$id) {
|
||||
return '🤍 银牌商机';
|
||||
}
|
||||
$quality = [
|
||||
1 => '💛 金牌商机',
|
||||
2 => '🤍 银牌商机',
|
||||
3 => '🤍 银牌商机'
|
||||
];
|
||||
return $quality[$id];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace app\queue\redis;
|
||||
|
||||
use app\common\model\CorpFeishuApp;
|
||||
use app\common\model\CrmCustomer;
|
||||
use Webman\RedisQueue\Consumer;
|
||||
use app\common\model\User;
|
||||
use app\common\utils\FeishuMessage as FeishuMsg;
|
||||
use support\exception\BusinessException;
|
||||
use app\inquiry\service\InquiryLogService;
|
||||
|
||||
class FeishuMessage implements Consumer
|
||||
{
|
||||
// 要消费的队列名
|
||||
public $queue = 'feishu-message';
|
||||
|
||||
// 连接名,对应 plugin/webman/redis-queue/redis.php 里的连接`
|
||||
public $connection = 'default';
|
||||
|
||||
// 消费
|
||||
|
||||
/**
|
||||
* @param string $category 分类:crm | inquiry
|
||||
* @param string $scene 场景:group-send | group-update | person-send | person-update
|
||||
* @param string $id 数据ID:询单ID | 客户ID
|
||||
* @param string $receive_type 接收者类型:group | person
|
||||
*/
|
||||
public function consume($data)
|
||||
{
|
||||
try {
|
||||
if ($data['category'] === 'crm') {
|
||||
// 客户线索
|
||||
$crmCustomer = new CrmCustomer();
|
||||
$info = $crmCustomer->where('id', $data['id'])->first();
|
||||
|
||||
// 跟单人
|
||||
$reInfo = User::where('id', $info->user_id)->first();
|
||||
|
||||
// 飞书应用
|
||||
$feishuApp = new CorpFeishuApp();
|
||||
$feishuAppInfo = $feishuApp->where('corp_id', $reInfo->corp_id)->first();
|
||||
|
||||
// 推送数据
|
||||
$options = [
|
||||
'contacts' => $info->contacts,
|
||||
'follow_last' => $info->follow_last ? date('Y-m-d H:i', $info->follow_last) : '',
|
||||
'follow_next' => $info->follow_next ? date('Y-m-d H:i', $info->follow_next) : '',
|
||||
|
||||
'app_id' => $feishuAppInfo->app_id,
|
||||
'app_secret' => $feishuAppInfo->app_secret,
|
||||
'msg_type' => 'interactive',
|
||||
'receive_id_type' => 'open_id',
|
||||
'receive_id' => $reInfo->open_id
|
||||
];
|
||||
}
|
||||
|
||||
if ($data['category'] === 'inquiry') {
|
||||
// 询单信息
|
||||
$inquiryLogService = new InquiryLogService();
|
||||
$info = $inquiryLogService->getInquiryLogBy($data['id']);
|
||||
|
||||
// 接受者处理
|
||||
if ($data['receive_type'] == 'group') {
|
||||
$appId = 'cli_a72f13d6c022500d';
|
||||
$appSecret = 'Kxtbq70OQWrEhpltrufRZc76z7kjDqPT';
|
||||
$receiveId = 'oc_4f574e6f8bc5b8f3e5175e67ebc5725c';
|
||||
$receiveIdType = 'chat_id';
|
||||
} else {
|
||||
// 跟单人
|
||||
$reInfo = User::where('id', $info->recipient)->first();
|
||||
// 飞书应用
|
||||
$feishuApp = new CorpFeishuApp();
|
||||
$feishuAppInfo = $feishuApp->where('corp_id', $reInfo->corp_id)->first();
|
||||
// 推送信息
|
||||
$appId = $feishuAppInfo->app_id;
|
||||
$appSecret = $feishuAppInfo->app_secret;
|
||||
$receiveId = $reInfo->open_id;
|
||||
$receiveIdType = 'open_id';
|
||||
}
|
||||
|
||||
// 推送数据
|
||||
$options = [
|
||||
'order_no' => $info->order_no,
|
||||
'quality' => $inquiryLogService->qualityName($info->quality),
|
||||
'channel' => $info->channelInfo ? $info->channelInfo->name : '',
|
||||
'country' => $info->countryInfo ? $info->countryInfo->cn_addr : '',
|
||||
'enter_user' => $info->enter ? $info->enter->name : '',
|
||||
'r_time' => $info->r_time ? date('Y-m-d H:i:s', $info->r_time) : '',
|
||||
't_time' => $info->t_time ? date('Y-m-d H:i:s', $info->t_time) : '',
|
||||
|
||||
'app_id' => $appId,
|
||||
'app_secret' => $appSecret,
|
||||
'msg_type' => 'interactive',
|
||||
'receive_id_type' => $receiveIdType,
|
||||
'receive_id' => $receiveId
|
||||
];
|
||||
}
|
||||
|
||||
$feishuMsg = new FeishuMsg();
|
||||
$feishuMsg->messageSend($data['scene'], $options);
|
||||
} catch (\Throwable $th) {
|
||||
throw $th;
|
||||
}
|
||||
}
|
||||
|
||||
// 消费失败回调
|
||||
/*
|
||||
$package = [
|
||||
'id' => 1357277951, // 消息ID
|
||||
'time' => 1709170510, // 消息时间
|
||||
'delay' => 0, // 延迟时间
|
||||
'attempts' => 2, // 消费次数
|
||||
'queue' => 'send-mail', // 队列名
|
||||
'data' => ['to' => 'tom@gmail.com', 'content' => 'hello'], // 消息内容
|
||||
'max_attempts' => 5, // 最大重试次数
|
||||
'error' => '错误信息' // 错误信息
|
||||
]
|
||||
*/
|
||||
public function onConsumeFailure(\Throwable $e, $package)
|
||||
{
|
||||
echo "consume failure\n";
|
||||
echo $e->getMessage() . "\n";
|
||||
// 无需反序列化
|
||||
var_export($package);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace app\queue\redis;
|
||||
|
||||
use app\inquiry\service\InquiryLogService;
|
||||
use app\common\model\CrmCustomer;
|
||||
use app\common\model\InquiryLog;
|
||||
use Webman\RedisQueue\Consumer;
|
||||
use app\common\model\User;
|
||||
use app\common\utils\FeishuMessage;
|
||||
use support\exception\BusinessException;
|
||||
|
||||
class InquiryToCrm implements Consumer
|
||||
{
|
||||
// 要消费的队列名
|
||||
public $queue = 'inquiry-to-crm';
|
||||
|
||||
// 连接名,对应 plugin/webman/redis-queue/redis.php 里的连接`
|
||||
public $connection = 'default';
|
||||
|
||||
// 消费
|
||||
public function consume($data)
|
||||
{
|
||||
try {
|
||||
// 获取询盘信息
|
||||
$info = InquiryLog::with(['channelInfo', 'countryInfo', 'enter'])->where('id', $data['id'])->where('sync_crm', 0)->first();
|
||||
if ($info) {
|
||||
// 获取用户信息
|
||||
$recipient = 0;
|
||||
$corpId = 0;
|
||||
if ($info->recipient) {
|
||||
$recipient = $info->recipient;
|
||||
$uinfo = User::where('id', $info->recipient)->first();
|
||||
if ($uinfo) {
|
||||
$corpId = $uinfo->corp_id;
|
||||
}
|
||||
// 消息推送参数 分配
|
||||
$scene = 'inquiry-person-allocation';
|
||||
$receiveType = 'person';
|
||||
} else {
|
||||
// 消息推送参数 发布
|
||||
$scene = 'inquiry-group-send';
|
||||
$receiveType = 'group';
|
||||
}
|
||||
// 同步客户数据
|
||||
$crmCustomer = new CrmCustomer();
|
||||
$crmCustomer->sn = $info->order_no;
|
||||
$crmCustomer->corp_abbr = $corpId;
|
||||
$crmCustomer->user_id = $recipient;
|
||||
$crmCustomer->type = 1;
|
||||
$crmCustomer->channel_id = $info->channel;
|
||||
$crmCustomer->country_id = $info->country;
|
||||
$crmCustomer->magnitude = $info->quality - 1;
|
||||
$crmCustomer->email = $info->email;
|
||||
$crmCustomer->phone = $info->tel;
|
||||
$crmCustomer->WhatsApp = $info->whatsapp;
|
||||
$crmCustomer->contacts = $info->contacts;
|
||||
$crmCustomer->desc_collect = $info->content;
|
||||
$crmCustomer->enter_user_id = $info->enter_user_id;
|
||||
// 修改同步CRM状态
|
||||
$info->sync_crm = 1;
|
||||
// 保存
|
||||
if (!$crmCustomer->save() || !$info->save()) {
|
||||
throw new BusinessException('同步失败~');
|
||||
}
|
||||
|
||||
// 发送飞书消息
|
||||
$options = [
|
||||
'id' => $info->id,
|
||||
'category' => 'inquiry',
|
||||
'scene' => $scene,
|
||||
'receive_type' => $receiveType
|
||||
];
|
||||
\Webman\RedisQueue\Redis::send('feishu-message', $options);
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
throw $th;
|
||||
}
|
||||
}
|
||||
|
||||
// 消费失败回调
|
||||
/*
|
||||
$package = [
|
||||
'id' => 1357277951, // 消息ID
|
||||
'time' => 1709170510, // 消息时间
|
||||
'delay' => 0, // 延迟时间
|
||||
'attempts' => 2, // 消费次数
|
||||
'queue' => 'send-mail', // 队列名
|
||||
'data' => ['to' => 'tom@gmail.com', 'content' => 'hello'], // 消息内容
|
||||
'max_attempts' => 5, // 最大重试次数
|
||||
'error' => '错误信息' // 错误信息
|
||||
]
|
||||
*/
|
||||
public function onConsumeFailure(\Throwable $e, $package)
|
||||
{
|
||||
echo "consume failure\n";
|
||||
echo $e->getMessage() . "\n";
|
||||
// 无需反序列化
|
||||
var_export($package);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ return [
|
||||
'count' => getenv('REDIS_QUEUE_PROCESS_COUNT'), // 可以设置多进程同时消费
|
||||
'constructor' => [
|
||||
// 消费者类目录
|
||||
// 'consumer_dir' => app_path() . '/queue/redis'
|
||||
'consumer_dir' => app_path() . '/queue/redis',
|
||||
'consumer_dir' => app_path() . getenv('REDIS_QUEUE_CONSUMER_DIR')
|
||||
]
|
||||
]
|
||||
|
||||
+10
-4
@@ -29,6 +29,10 @@ use Webman\Route;
|
||||
Route::any('/c', [app\controller\IndexController::class, 'createResource']);
|
||||
Route::any('/perm', [app\controller\IndexController::class, 'perm']);
|
||||
|
||||
// 飞书
|
||||
Route::any('/feishu/event', [app\common\controller\NotifyController::class, 'feishuEvent']);
|
||||
// 飞书回调
|
||||
Route::any('/feishu/callback', [app\common\controller\NotifyController::class, 'feishuCallback']);
|
||||
|
||||
// 公共
|
||||
Route::group('/common', function () {
|
||||
@@ -77,10 +81,12 @@ Route::group('/admin', function () {
|
||||
// 询单
|
||||
Route::group('/inquiry', function () {
|
||||
Route::any('/list', [app\inquiry\controller\InquiryLogController::class, 'index']);
|
||||
// Route::any('/show', [app\admin\controller\CorpController::class, 'show']);
|
||||
// Route::any('/store', [app\admin\controller\CorpController::class, 'store']);
|
||||
// Route::any('/update', [app\admin\controller\CorpController::class, 'update']);
|
||||
// Route::any('/destroy', [app\admin\controller\CorpController::class, 'destroy']);
|
||||
Route::any('/show', [app\inquiry\controller\InquiryLogController::class, 'show']);
|
||||
Route::any('/store', [app\inquiry\controller\InquiryLogController::class, 'store']);
|
||||
Route::any('/update', [app\inquiry\controller\InquiryLogController::class, 'update']);
|
||||
Route::any('/destroy', [app\inquiry\controller\InquiryLogController::class, 'destroy']);
|
||||
Route::any('/release', [app\inquiry\controller\InquiryLogController::class, 'release']);
|
||||
Route::any('/allocation', [app\inquiry\controller\InquiryLogController::class, 'allocation']);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'basi_cdata' => [
|
||||
'/', // 首页
|
||||
'/index/index', // 首页
|
||||
'/index/view', // 飞书调试
|
||||
'/perm', // 调试-添加权限
|
||||
|
||||
'/common/preset/corps', // 公司列表
|
||||
'/common/preset/feishu/app', // 飞书应用信息
|
||||
]
|
||||
];
|
||||
Reference in New Issue
Block a user