162 lines
5.3 KiB
PHP
162 lines
5.3 KiB
PHP
<?php
|
||
|
||
namespace app\api\controller;
|
||
|
||
use think\Db;
|
||
use app\common\ExpertFieldAiService;
|
||
|
||
/**
|
||
* Expert 领域总结(方案 C - 阶段1:邮箱关联 user.field_ai)
|
||
*
|
||
* POST startLinkChain 启动链式队列,批量关联
|
||
* POST linkOne 同步关联单个 expert_id
|
||
* POST linkBatch 同步批量关联 expert_ids
|
||
* POST syncByUser user 有 field_ai 后,同步到同邮箱 expert
|
||
* GET preview 预览是否可关联
|
||
* GET statistics 统计 field_ai 覆盖情况
|
||
*/
|
||
class ExpertFieldAi extends Base
|
||
{
|
||
/**
|
||
* 启动链式关联队列
|
||
* Worker: php think queue:work --queue ExpertFieldAi
|
||
*/
|
||
public function startLinkChain()
|
||
{
|
||
$force = intval($this->request->param('force', 0)) === 1;
|
||
$delay = max(0, intval($this->request->param('delay', 1)));
|
||
|
||
$svc = new ExpertFieldAiService();
|
||
$started = $svc->startLinkChain($force, $delay);
|
||
|
||
return jsonSuccess([
|
||
'started' => $started,
|
||
'queue' => ExpertFieldAiService::QUEUE_NAME,
|
||
'force' => $force,
|
||
'msg' => $started ? 'link chain enqueued' : 'no pending experts',
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* 同步关联单个 expert
|
||
*/
|
||
public function linkOne()
|
||
{
|
||
$expertId = intval($this->request->param('expert_id', 0));
|
||
$force = intval($this->request->param('force', 0)) === 1;
|
||
if ($expertId <= 0) {
|
||
return jsonError('expert_id required');
|
||
}
|
||
|
||
$svc = new ExpertFieldAiService();
|
||
$result = $svc->linkFromUser($expertId, $force);
|
||
if (empty($result['ok'])) {
|
||
return jsonError(isset($result['error']) ? $result['error'] : 'failed');
|
||
}
|
||
return jsonSuccess($result);
|
||
}
|
||
|
||
/**
|
||
* 同步批量关联
|
||
* expert_ids: 逗号分隔,或传 limit 扫描待处理前 N 条
|
||
*/
|
||
public function linkBatch()
|
||
{
|
||
$force = intval($this->request->param('force', 0)) === 1;
|
||
$idsRaw = trim((string)$this->request->param('expert_ids', ''));
|
||
$limit = min(max(intval($this->request->param('limit', 0)), 0), 200);
|
||
|
||
$ids = [];
|
||
if ($idsRaw !== '') {
|
||
$ids = array_filter(array_map('intval', explode(',', $idsRaw)));
|
||
} elseif ($limit > 0) {
|
||
$ids = Db::name('expert')
|
||
->where('state', '<>', 5)
|
||
->where(function ($q) {
|
||
$q->where('field_ai_status', ExpertFieldAiService::STATUS_PENDING)
|
||
->whereOr('field_ai_status', ExpertFieldAiService::STATUS_FAILED);
|
||
})
|
||
->order('expert_id asc')
|
||
->limit($limit)
|
||
->column('expert_id');
|
||
}
|
||
|
||
if (empty($ids)) {
|
||
return jsonError('expert_ids 或 limit 必填');
|
||
}
|
||
|
||
$svc = new ExpertFieldAiService();
|
||
$result = $svc->batchLinkFromUser($ids, $force);
|
||
return jsonSuccess($result);
|
||
}
|
||
|
||
/**
|
||
* user 更新 field_ai 后,同步到同邮箱 expert
|
||
*/
|
||
public function syncByUser()
|
||
{
|
||
$userId = intval($this->request->param('user_id', 0));
|
||
$force = intval($this->request->param('force', 0)) === 1;
|
||
if ($userId <= 0) {
|
||
return jsonError('user_id required');
|
||
}
|
||
|
||
$svc = new ExpertFieldAiService();
|
||
$result = $svc->syncExpertsByUserId($userId, $force);
|
||
if (empty($result['ok'])) {
|
||
return jsonError(isset($result['error']) ? $result['error'] : 'failed');
|
||
}
|
||
return jsonSuccess($result);
|
||
}
|
||
|
||
/**
|
||
* 预览是否可关联
|
||
*/
|
||
public function preview()
|
||
{
|
||
$expertId = intval($this->request->param('expert_id', 0));
|
||
if ($expertId <= 0) {
|
||
return jsonError('expert_id required');
|
||
}
|
||
|
||
$svc = new ExpertFieldAiService();
|
||
$result = $svc->previewLink($expertId);
|
||
if (empty($result['ok'])) {
|
||
return jsonError(isset($result['error']) ? $result['error'] : 'failed');
|
||
}
|
||
|
||
$result['field_ai_status_text'] = $svc->statusLabel(intval($result['expert_field_ai_status']));
|
||
return jsonSuccess($result);
|
||
}
|
||
|
||
/**
|
||
* 统计 field_ai 覆盖
|
||
*/
|
||
public function statistics()
|
||
{
|
||
$total = Db::name('expert')->where('state', '<>', 5)->count();
|
||
$done = Db::name('expert')->where('state', '<>', 5)->where('field_ai_status', ExpertFieldAiService::STATUS_DONE)->count();
|
||
$userLink = Db::name('expert')
|
||
->where('state', '<>', 5)
|
||
->where('field_ai_source', ExpertFieldAiService::SOURCE_USER_LINK)
|
||
->count();
|
||
$noUserLink = Db::name('expert')
|
||
->where('state', '<>', 5)
|
||
->where('field_ai_status', ExpertFieldAiService::STATUS_NO_USER_LINK)
|
||
->count();
|
||
$pending = Db::name('expert')
|
||
->where('state', '<>', 5)
|
||
->where('field_ai_status', ExpertFieldAiService::STATUS_PENDING)
|
||
->count();
|
||
|
||
return jsonSuccess([
|
||
'total' => $total,
|
||
'done' => $done,
|
||
'user_link' => $userLink,
|
||
'no_user_link' => $noUserLink,
|
||
'pending' => $pending,
|
||
'coverage_rate' => $total > 0 ? round($done / $total * 100, 2) . '%' : '0%',
|
||
]);
|
||
}
|
||
}
|