Merge branch 'develop' into yongpxu-dev
This commit is contained in:
@@ -98,6 +98,7 @@ export default function NewPlan() {
|
||||
sceneId: Number(detail.scenario) || 1,
|
||||
remarkFormat: detail.remarkFormat ?? "",
|
||||
addFriendInterval: detail.addFriendInterval ?? 1,
|
||||
tips: detail.tips ?? "",
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
@@ -178,6 +179,7 @@ export default function NewPlan() {
|
||||
case 1:
|
||||
return (
|
||||
<BasicSettings
|
||||
isEdit={isEdit}
|
||||
formData={formData}
|
||||
onChange={onChange}
|
||||
onNext={handleNext}
|
||||
|
||||
@@ -12,6 +12,7 @@ import EyeIcon from "@/components/icons/EyeIcon";
|
||||
import { uploadFile } from "@/api/utils";
|
||||
|
||||
interface BasicSettingsProps {
|
||||
isEdit: boolean;
|
||||
formData: any;
|
||||
onChange: (data: any) => void;
|
||||
onNext?: () => void;
|
||||
@@ -89,6 +90,7 @@ const generatePosterMaterials = (): Material[] => {
|
||||
};
|
||||
|
||||
export function BasicSettings({
|
||||
isEdit,
|
||||
formData,
|
||||
onChange,
|
||||
onNext,
|
||||
@@ -123,6 +125,7 @@ export function BasicSettings({
|
||||
// 自定义标签相关状态
|
||||
const [customTagInput, setCustomTagInput] = useState("");
|
||||
const [customTags, setCustomTags] = useState(formData.customTags || []);
|
||||
const [tips, setTips] = useState(formData.tips || "");
|
||||
const [selectedScenarioTags, setSelectedScenarioTags] = useState(
|
||||
formData.scenarioTags || []
|
||||
);
|
||||
@@ -188,7 +191,11 @@ export function BasicSettings({
|
||||
const today = new Date().toLocaleDateString("zh-CN").replace(/\//g, "");
|
||||
const sceneItem = sceneList.find((v) => formData.scenario === v.id);
|
||||
onChange({ ...formData, name: `${sceneItem?.name || "海报"}${today}` });
|
||||
}, [sceneList]);
|
||||
}, [isEdit]);
|
||||
|
||||
useEffect(() => {
|
||||
setTips(formData.tips || "");
|
||||
}, [formData.tips]);
|
||||
|
||||
// 选中场景
|
||||
const handleScenarioSelect = (sceneId: number) => {
|
||||
@@ -494,6 +501,22 @@ export function BasicSettings({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 输入获客成功提示 */}
|
||||
<div className="flex pt-4">
|
||||
<div className="border p-2 flex-1">
|
||||
<input
|
||||
type="text"
|
||||
value={tips}
|
||||
onChange={(e) => {
|
||||
setTips(e.target.value);
|
||||
onChange({ ...formData, tips: e.target.value });
|
||||
}}
|
||||
placeholder="请输入获客成功提示"
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 选素材 */}
|
||||
<div className="my-4" style={openPoster}>
|
||||
<div className="mb-4">选择海报</div>
|
||||
|
||||
@@ -97,9 +97,6 @@ Route::group('v1', function () {
|
||||
Route::get('autoCreate', 'app\api\controller\AllotRuleController@autoCreateAllotRules');// 自动创建分配规则 √
|
||||
});
|
||||
|
||||
Route::group('scenarios', function () {
|
||||
Route::any('', 'app\cunkebao\controller\plan\PostExternalApiV1Controller@index');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
@@ -118,8 +118,13 @@ Route::group('v1/', function () {
|
||||
|
||||
|
||||
|
||||
Route::group('v1/frontend', function () {
|
||||
Route::group('v1/api/scenarios', function () {
|
||||
Route::any('', 'app\cunkebao\controller\plan\PostExternalApiV1Controller@index');
|
||||
});
|
||||
|
||||
|
||||
//小程序
|
||||
Route::group('v1/frontend', function () {
|
||||
Route::group('business/poster', function () {
|
||||
Route::post('getone', 'app\cunkebao\controller\plan\PosterWeChatMiniProgram@getPosterTaskData');
|
||||
Route::post('decryptphone', 'app\cunkebao\controller\plan\PosterWeChatMiniProgram@getPhoneNumber');
|
||||
@@ -129,5 +134,4 @@ Route::group('v1/frontend', function () {
|
||||
|
||||
|
||||
|
||||
|
||||
return [];
|
||||
121
Server/application/cunkebao/controller/TrafficController.php
Normal file
121
Server/application/cunkebao/controller/TrafficController.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
namespace app\cunkebao\controller;
|
||||
|
||||
use think\Controller;
|
||||
use think\Db;
|
||||
|
||||
class TrafficController extends Controller
|
||||
{
|
||||
|
||||
public function getList(){
|
||||
$page = $this->request->param('page',1);
|
||||
$pageSize = $this->request->param('pageSize',10);
|
||||
$device = $this->request->param('device','');
|
||||
$packageId = $this->request->param('packageId',''); // 流量池id
|
||||
$userValue = $this->request->param('userValue',''); // 1高价值客户 2中价值客户 3低价值客户
|
||||
$addStatus = $this->request->param('addStatus',''); // 1待添加 2已添加 3添加失败 4重复用户
|
||||
$keyword = $this->request->param('keyword','');
|
||||
|
||||
$companyId = $this->request->userInfo['companyId'];
|
||||
|
||||
// 1 文字 3图片 47动态图片 34语言 43视频 42名片 40/20链接 49文件 419430449转账 436207665红包
|
||||
|
||||
$where = [];
|
||||
|
||||
// 添加筛选条件
|
||||
if (!empty($device)) {
|
||||
$where['d.id'] = $device;
|
||||
}
|
||||
|
||||
if (!empty($packageId)) {
|
||||
$where['tp.id'] = $packageId;
|
||||
}
|
||||
|
||||
if (!empty($userValue)) {
|
||||
$where['tp.userValue'] = $userValue;
|
||||
}
|
||||
|
||||
if (!empty($addStatus)) {
|
||||
$where['tp.addStatus'] = $addStatus;
|
||||
}
|
||||
|
||||
|
||||
// 构建查询 - 通过traffic_pool的identifier关联wechat_account的wechatId、alias或phone
|
||||
$query = Db::name('traffic_pool')->alias('tp')
|
||||
->join('wechat_account wa', 'wa.wechatId = tp.wechatId', 'LEFT')
|
||||
->field('tp.id, tp.identifier,tp.createTime, tp.updateTime,
|
||||
wa.wechatId, wa.alias, wa.phone, wa.nickname, wa.avatar')
|
||||
->where($where);
|
||||
|
||||
// 关键词搜索 - 支持通过wechat_friendship的identifier关联wechat_account的wechatId、alias或phone
|
||||
if (!empty($keyword)) {
|
||||
$query->where(function($q) use ($keyword) {
|
||||
$q->where('tp.identifier', 'like', '%' . $keyword . '%')
|
||||
->whereOr('wa.wechatId', 'like', '%' . $keyword . '%')
|
||||
->whereOr('wa.alias', 'like', '%' . $keyword . '%')
|
||||
->whereOr('wa.phone', 'like', '%' . $keyword . '%')
|
||||
->whereOr('wa.nickname', 'like', '%' . $keyword . '%');
|
||||
});
|
||||
}
|
||||
|
||||
// 获取总数
|
||||
$total = $query->count();
|
||||
|
||||
|
||||
// 分页查询
|
||||
$list = $query->order('tp.createTime desc')
|
||||
->group('tp.identifier')
|
||||
->order('tp.id desc')
|
||||
->page($page, $pageSize)
|
||||
->select();
|
||||
|
||||
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '获取成功',
|
||||
'data' => [
|
||||
'list' => $list,
|
||||
'total' => $total,
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 用户旅程
|
||||
* @return false|string
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function getUserJourney()
|
||||
{
|
||||
$page = $this->request->param('page',1);
|
||||
$pageSize = $this->request->param('pageSize',10);
|
||||
$userId = $this->request->param('userId','');
|
||||
if(empty($userId)){
|
||||
return json_encode(['code' => 500, 'msg' => '用户id不能为空']);
|
||||
}
|
||||
|
||||
$query = Db::name('user_portrait')
|
||||
->field('id,type,trafficPoolId,remark,count,createTime,updateTime')
|
||||
->where(['trafficPoolId' => $userId]);
|
||||
|
||||
$total = $query->count();
|
||||
|
||||
$list = $query->order('createTime desc')
|
||||
->page($page,$pageSize)
|
||||
->select();
|
||||
|
||||
|
||||
foreach ($list as $k=>$v){
|
||||
$list[$k]['createTime'] = date('Y-m-d H:i:s',$v['createTime']);
|
||||
$list[$k]['updateTime'] = date('Y-m-d H:i:s',$v['updateTime']);
|
||||
}
|
||||
return json_encode(['code' => 200,'data'=>['list' => $list,'total'=>$total],'获取成功']);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -96,7 +96,8 @@ class PostExternalApiV1Controller extends Controller
|
||||
if (!$trafficPool) {
|
||||
$trafficPoolId =Db::name('traffic_pool')->insertGetId([
|
||||
'identifier' => $identifier,
|
||||
'mobile' => $params['phone']
|
||||
'mobile' => !empty($params['phone']) ? $params['phone'] : '',
|
||||
'createTime' => time()
|
||||
]);
|
||||
}else{
|
||||
$trafficPoolId = $trafficPool['id'];
|
||||
|
||||
@@ -126,7 +126,10 @@ class PosterWeChatMiniProgram extends Controller
|
||||
// todo 获取海报获客任务的任务/海报数据 -- 表还没设计好,不急 ck_customer_acquisition_task
|
||||
public function getPosterTaskData() {
|
||||
$id = request()->param('id');
|
||||
$task = Db::name('customer_acquisition_task')->where(['id' => $id,'deleteTime' => 0])->find();
|
||||
$task = Db::name('customer_acquisition_task')
|
||||
->where(['id' => $id,'deleteTime' => 0])
|
||||
->field('id,name,sceneConf,status')
|
||||
->find();
|
||||
if (!$task) {
|
||||
return json([
|
||||
'code' => 400,
|
||||
@@ -150,13 +153,20 @@ class PosterWeChatMiniProgram extends Controller
|
||||
}
|
||||
|
||||
|
||||
if(isset($sceneConf['tips'])) {
|
||||
$sTip = $sceneConf['tips'];
|
||||
} else {
|
||||
$sTip = '';
|
||||
}
|
||||
|
||||
unset($task['sceneConf']);
|
||||
$task['sTip'] = $sTip;
|
||||
|
||||
$data = [
|
||||
'id' => $task['id'],
|
||||
'name' => $task['name'],
|
||||
'poster' => ['sUrl' => $posterUrl],
|
||||
'sTip' => '',
|
||||
'task' => $task,
|
||||
];
|
||||
|
||||
|
||||
|
||||
@@ -191,7 +191,6 @@ class Adapter implements WeChatServiceInterface
|
||||
}
|
||||
//筛选出设备在线微信在线
|
||||
$wechatIdAccountIdMap = $this->getWeChatIdsAccountIdsMapByDeviceIds($task_info['reqConf']['device']);
|
||||
|
||||
if (empty($wechatIdAccountIdMap)) {
|
||||
continue;
|
||||
}
|
||||
@@ -213,11 +212,9 @@ class Adapter implements WeChatServiceInterface
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 判断24h内加的好友数量,friend_task 先固定10个人 getLast24hAddedFriendsCount
|
||||
$last24hAddedFriendsCount = $this->getLast24hAddedFriendsCount($wechatId);
|
||||
if ($last24hAddedFriendsCount >= 10) {
|
||||
if ($last24hAddedFriendsCount >= 20) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -233,14 +230,15 @@ class Adapter implements WeChatServiceInterface
|
||||
$task['processed_wechat_ids'] = $task['processed_wechat_ids'] . ',' . $wechatId; // 处理失败任务用,用于过滤已处理的微信号
|
||||
break;
|
||||
}
|
||||
Db::name('task_customer')
|
||||
$res = Db::name('task_customer')
|
||||
->where('id', $task['id'])
|
||||
->update([
|
||||
'status' => $friendAddTaskCreated ? 1 : 3,
|
||||
'fail_reason' => $friendAddTaskCreated ? '' : '已经是好友了',
|
||||
'processed_wechat_ids' => $task['processed_wechat_ids'],
|
||||
'updated_at' => time()
|
||||
]); // ~~不用管,回头再添加再判断即可~~
|
||||
'updateTime' => time()
|
||||
]);
|
||||
// ~~不用管,回头再添加再判断即可~~
|
||||
// 失败一定是另一个进程/定时器在检查的
|
||||
|
||||
}
|
||||
@@ -254,9 +252,9 @@ class Adapter implements WeChatServiceInterface
|
||||
|
||||
$tasks = Db::name('task_customer')
|
||||
->whereIn('status', [1,2])
|
||||
->where('updated_at', '>=', (time() - 86400 * 3))
|
||||
->where('updateTime', '>=', (time() - 86400 * 3))
|
||||
->limit(50)
|
||||
->order('updated_at DESC')
|
||||
->order('updateTime DESC')
|
||||
->select();
|
||||
|
||||
if (empty($tasks)) {
|
||||
@@ -296,7 +294,7 @@ class Adapter implements WeChatServiceInterface
|
||||
|
||||
Db::name('task_customer')
|
||||
->where('id', $task['id'])
|
||||
->update(['status' => 4, 'updated_at' => time()]);
|
||||
->update(['status' => 4, 'updateTime' => time()]);
|
||||
|
||||
$wechatFriendRecord = $this->getWeChatAccoutIdAndFriendIdByWeChatIdAndFriendPhone($passedWeChatId, $task['phone']);
|
||||
$msgConf = is_string($task_info['msgConf']) ? json_decode($task_info['msgConf'], 1) : $task_info['msgConf'];
|
||||
@@ -316,7 +314,7 @@ class Adapter implements WeChatServiceInterface
|
||||
if (isset($latestFriendTask['status']) && $latestFriendTask['status'] == 1) {
|
||||
Db::name('task_customer')
|
||||
->where('id', $task['id'])
|
||||
->update(['status' => 2, 'updated_at' => time()]);
|
||||
->update(['status' => 2, 'updateTime' => time()]);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -324,7 +322,7 @@ class Adapter implements WeChatServiceInterface
|
||||
if (isset($latestFriendTask['status']) && $latestFriendTask['status'] == 2) {
|
||||
Db::name('task_customer')
|
||||
->where('id', $task['id'])
|
||||
->update(['status' => 3, 'fail_reason' => $latestFriendTask['extra'] ?? '未知原因', 'updated_at' => time()]);
|
||||
->update(['status' => 3, 'fail_reason' => $latestFriendTask['extra'] ?? '未知原因', 'updateTime' => time()]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user