修改自动推广的相关任务
This commit is contained in:
@@ -1362,84 +1362,48 @@ class EmailClient extends Base
|
||||
// ==================== Promotion Tasks ====================
|
||||
|
||||
/**
|
||||
* Create a promotion sending task
|
||||
* Params:
|
||||
* - journal_id, template_id, style_id, scene, task_name
|
||||
* - expert_ids (comma separated) OR field + major_id (auto-query from DB)
|
||||
* - smtp_ids (comma separated, optional: restrict to specific SMTP accounts)
|
||||
* - min_interval, max_interval (seconds between emails)
|
||||
* - max_bounce_rate (%), no_repeat_days
|
||||
* - send_start_hour, send_end_hour (UTC, default 8-22)
|
||||
* - send_date (Y-m-d,计划发送日期;有则「今日准备明日发」由定时任务处理,无则创建后需手动 startTask)
|
||||
* 基于任务工厂创建单个推广任务(手动触发)
|
||||
*
|
||||
* 参数:
|
||||
* - promotion_factory_id (必填)工厂ID,任务的模板/领域/国家/发送参数均从工厂读取
|
||||
* - send_date (可选,默认明天)Y-m-d
|
||||
* - task_name (可选,默认 "Manual-{journal_title}-F{factory_id}-{send_date}")
|
||||
* - no_repeat_days (可选,默认 30)覆盖默认不重复天数
|
||||
* - min_interval/max_interval/max_bounce_rate/send_start_hour/send_end_hour 可选覆盖
|
||||
*/
|
||||
public function createTask()
|
||||
{
|
||||
$journalId = intval($this->request->param('journal_id', 0));
|
||||
$templateId = intval($this->request->param('template_id', 0));
|
||||
$styleId = intval($this->request->param('style_id', 0));
|
||||
$scene = trim($this->request->param('scene', ''));
|
||||
$taskName = trim($this->request->param('task_name', ''));
|
||||
$expertIds = trim($this->request->param('expert_ids', ''));
|
||||
$field = trim($this->request->param('field', ''));
|
||||
$fetchIds = trim($this->request->param('fetch_ids', ''));
|
||||
$smtpIds = trim($this->request->param('smtp_ids', ''));
|
||||
$minInterval = intval($this->request->param('min_interval', 30));
|
||||
$maxInterval = intval($this->request->param('max_interval', 60));
|
||||
$factoryId = intval($this->request->param('promotion_factory_id', 0));
|
||||
$sendDate = trim($this->request->param('send_date', date('Y-m-d', strtotime('+1 day'))));
|
||||
$taskName = trim($this->request->param('task_name', ''));
|
||||
$noRepeatDays = intval($this->request->param('no_repeat_days', 30));
|
||||
$minInterval = intval($this->request->param('min_interval', 30));
|
||||
$maxInterval = intval($this->request->param('max_interval', 60));
|
||||
$maxBounceRate = intval($this->request->param('max_bounce_rate', 5));
|
||||
$noRepeatDays = intval($this->request->param('no_repeat_days', 7));
|
||||
$sendStartHour = intval($this->request->param('send_start_hour', 8));
|
||||
$sendEndHour = intval($this->request->param('send_end_hour', 22));
|
||||
$sendDate = trim($this->request->param('send_date', date("Y-m-d",strtotime('+1 day'))));
|
||||
$targetPartitions = trim($this->request->param('target_partitions', ''));
|
||||
$targetCountryIds = trim($this->request->param('target_country_ids', ''));
|
||||
$type = intval($this->request->param('type', 0));
|
||||
$expertType = intval($this->request->param('expert_type', 5));
|
||||
$sendStartHour = intval($this->request->param('send_start_hour', 8));
|
||||
$sendEndHour = intval($this->request->param('send_end_hour', 22));
|
||||
|
||||
if (!$journalId) {
|
||||
return jsonError('journal_id is required');
|
||||
if (!$factoryId) {
|
||||
return jsonError('promotion_factory_id is required');
|
||||
}
|
||||
$journal_info = $this->journal_obj->where("journal_id",$journalId)->find();
|
||||
$templateId = ($templateId == 0) ? intval($journal_info['default_template_id']) : $templateId;
|
||||
$styleId = ($styleId == 0) ? intval(isset($journal_info['default_style_id']) ? $journal_info['default_style_id'] : 0) : $styleId;
|
||||
if($templateId==0){
|
||||
return jsonError("template is not set!");
|
||||
}
|
||||
$tpl = Db::name('mail_template')
|
||||
->where('template_id', $templateId)
|
||||
->where('journal_id', $journalId)
|
||||
->where('state', 0)
|
||||
|
||||
$factory = Db::name('promotion_factory')
|
||||
->where('promotion_factory_id', $factoryId)
|
||||
->find();
|
||||
if (!$tpl) {
|
||||
return jsonError('Template not found for this journal');
|
||||
if (!$factory) {
|
||||
return jsonError('Factory not found');
|
||||
}
|
||||
if (intval($factory['state']) !== 0) {
|
||||
return jsonError('Factory is disabled');
|
||||
}
|
||||
if (intval($factory['expert_type']) !== 5) {
|
||||
return jsonError('Only expert_type=5 is supported currently');
|
||||
}
|
||||
|
||||
if (empty($scene)) {
|
||||
$scene = $tpl['scene'];
|
||||
}
|
||||
|
||||
$experts = [];
|
||||
if (!empty($expertIds)) {
|
||||
$ids = array_map('intval', explode(',', $expertIds));
|
||||
$experts = Db::name('expert')
|
||||
->where('expert_id', 'in', $ids)
|
||||
->where('state', 0)
|
||||
->select();
|
||||
} else {
|
||||
// 领域来源优先级:前端传 field > 前端传 fetch_ids > journal_promotion_field
|
||||
$fields = [];
|
||||
if ($field !== '') {
|
||||
$fields = [$field];
|
||||
} elseif ($fetchIds !== '') {
|
||||
$fields = $this->resolveFieldsByFetchIds($fetchIds);
|
||||
} else {
|
||||
$fields = $this->resolveFieldsByJournal($journalId);
|
||||
}
|
||||
|
||||
$experts = $this->findEligibleExperts($fields, $noRepeatDays, 100, $targetPartitions, $targetCountryIds);
|
||||
}
|
||||
|
||||
if (empty($experts)) {
|
||||
return jsonError('No eligible experts found (all may have been promoted recently)');
|
||||
$journalId = intval($factory['journal_id']);
|
||||
$journal = Db::name('journal')->where('journal_id', $journalId)->find();
|
||||
if (!$journal) {
|
||||
return jsonError('Journal not found');
|
||||
}
|
||||
|
||||
$sendDateVal = null;
|
||||
@@ -1450,16 +1414,78 @@ class EmailClient extends Base
|
||||
}
|
||||
}
|
||||
|
||||
$now = time();
|
||||
if ($sendDateVal) {
|
||||
$existTask = Db::name('promotion_task')
|
||||
->where('factory_id', $factoryId)
|
||||
->where('send_date', $sendDateVal)
|
||||
->where('state', 'in', [0, 1, 5])
|
||||
->find();
|
||||
if ($existTask) {
|
||||
return jsonError('Factory already has an active task for send_date=' . $sendDateVal . ' (task_id=' . $existTask['task_id'] . ')');
|
||||
}
|
||||
}
|
||||
|
||||
$templateId = intval($factory['template_id']) > 0
|
||||
? intval($factory['template_id'])
|
||||
: intval($journal['default_template_id']);
|
||||
$styleId = intval($factory['style_id']) > 0
|
||||
? intval($factory['style_id'])
|
||||
: intval(isset($journal['default_style_id']) ? $journal['default_style_id'] : 0);
|
||||
|
||||
if ($templateId <= 0) {
|
||||
return jsonError('template_id is not set on factory or journal');
|
||||
}
|
||||
|
||||
$tpl = Db::name('mail_template')
|
||||
->where('template_id', $templateId)
|
||||
->where('journal_id', $journalId)
|
||||
->where('state', 0)
|
||||
->find();
|
||||
if (!$tpl) {
|
||||
return jsonError('Template not found for this journal');
|
||||
}
|
||||
$scene = $tpl['scene'] ?? 'promotion';
|
||||
|
||||
$smtpIds = trim((string)$factory['email_ids']);
|
||||
if ($smtpIds === '') {
|
||||
$smtpCount = Db::name('journal_email')
|
||||
->where('journal_id', $journalId)
|
||||
->where('state', 0)
|
||||
->count();
|
||||
if ($smtpCount == 0) {
|
||||
return jsonError('No active SMTP account for this journal');
|
||||
}
|
||||
}
|
||||
|
||||
$fields = $this->resolveFieldsByFetchIds($factory['fetch_ids']);
|
||||
if (empty($fields)) {
|
||||
return jsonError('No valid fields resolved from factory.fetch_ids');
|
||||
}
|
||||
|
||||
$targetPartitions = trim((string)$factory['target_partitions']);
|
||||
$targetCountryIds = trim((string)$factory['target_country_ids']);
|
||||
$dailyLimit = max(1, intval($factory['send_count']));
|
||||
|
||||
$experts = $this->findEligibleExperts($fields, $noRepeatDays, $dailyLimit, $targetPartitions, $targetCountryIds);
|
||||
|
||||
if (empty($experts)) {
|
||||
return jsonError('No eligible experts found (all may have been promoted recently)');
|
||||
}
|
||||
|
||||
if ($taskName === '') {
|
||||
$taskName = 'Manual-' . ($journal['title'] ?? $journalId) . '-F' . $factoryId . '-' . ($sendDateVal ?: date('Y-m-d H:i'));
|
||||
}
|
||||
|
||||
$now = time();
|
||||
$taskId = Db::name('promotion_task')->insertGetId([
|
||||
'journal_id' => $journalId,
|
||||
'factory_id' => 0,
|
||||
'factory_id' => $factoryId,
|
||||
'template_id' => $templateId,
|
||||
'style_id' => $styleId,
|
||||
'scene' => $scene,
|
||||
'type' => $type,
|
||||
'expert_type' => $expertType,
|
||||
'task_name' => $taskName ?: ('Task ' . date('Y-m-d H:i')),
|
||||
'type' => intval($factory['type']),
|
||||
'expert_type' => intval($factory['expert_type']),
|
||||
'task_name' => $taskName,
|
||||
'total_count' => count($experts),
|
||||
'sent_count' => 0,
|
||||
'fail_count' => 0,
|
||||
@@ -1501,6 +1527,7 @@ class EmailClient extends Base
|
||||
}
|
||||
return jsonSuccess([
|
||||
'task_id' => $taskId,
|
||||
'factory_id' => $factoryId,
|
||||
'total_count' => count($experts),
|
||||
'state' => 0,
|
||||
'send_date' => $sendDateVal,
|
||||
@@ -1583,32 +1610,7 @@ class EmailClient extends Base
|
||||
|
||||
// ==================== Journal Promotion Field Mapping ====================
|
||||
|
||||
/**
|
||||
* 获取某期刊已选的推广领域
|
||||
* 参数: journal_id
|
||||
*/
|
||||
public function getJournalPromotionFields()
|
||||
{
|
||||
$journalId = intval($this->request->param('journal_id', 0));
|
||||
if (!$journalId) {
|
||||
return jsonError('journal_id is required');
|
||||
}
|
||||
|
||||
$list = Db::name('journal_promotion_field')
|
||||
->alias('jpf')
|
||||
->join('t_expert_fetch ef', 'ef.expert_fetch_id = jpf.expert_fetch_id', 'left')
|
||||
->where('jpf.journal_id', $journalId)
|
||||
->where('jpf.state', 0)
|
||||
->field('jpf.jpf_id, jpf.expert_fetch_id, ef.field, ef.source, ef.state as fetch_state, jpf.ctime')
|
||||
->order('jpf.jpf_id asc')
|
||||
->select();
|
||||
|
||||
foreach ($list as &$item) {
|
||||
$item['ctime_text'] = $item['ctime'] ? date('Y-m-d H:i:s', $item['ctime']) : '';
|
||||
}
|
||||
|
||||
return jsonSuccess($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置/更新期刊的推广领域(全量覆盖)
|
||||
@@ -1872,6 +1874,8 @@ class EmailClient extends Base
|
||||
public function getTaskList()
|
||||
{
|
||||
$journalId = intval($this->request->param('journal_id', 0));
|
||||
$factoryId = $this->request->param('factory_id', '');
|
||||
$type = $this->request->param('type', '');
|
||||
$state = $this->request->param('state', '-1');
|
||||
$page = max(1, intval($this->request->param('page', 1)));
|
||||
$perPage = max(1, min(intval($this->request->param('per_page', 20)), 100));
|
||||
@@ -1880,6 +1884,12 @@ class EmailClient extends Base
|
||||
if ($journalId) {
|
||||
$where['journal_id'] = $journalId;
|
||||
}
|
||||
if ($factoryId !== '' && $factoryId !== '-1') {
|
||||
$where['factory_id'] = intval($factoryId);
|
||||
}
|
||||
if ($type !== '' && $type !== '-1') {
|
||||
$where['type'] = intval($type);
|
||||
}
|
||||
if ($state !== '-1' && $state !== '') {
|
||||
$where['state'] = intval($state);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user