Merge branch 'master' of https://git.nuttyreading.com/zm/tougao
This commit is contained in:
@@ -6,39 +6,81 @@ use think\Db;
|
||||
use app\common\ExpertFieldAiService;
|
||||
|
||||
/**
|
||||
* Expert 领域总结(方案 C - 阶段1:邮箱关联 user.field_ai)
|
||||
* Expert 领域 AI 总结(方案 C:少量 user 关联 + 主流程 AI)
|
||||
*
|
||||
* POST startLinkChain 启动链式队列,批量关联
|
||||
* POST linkOne 同步关联单个 expert_id
|
||||
* POST linkBatch 同步批量关联 expert_ids
|
||||
* POST syncByUser user 有 field_ai 后,同步到同邮箱 expert
|
||||
* GET preview 预览是否可关联
|
||||
* GET statistics 统计 field_ai 覆盖情况
|
||||
* POST startChain 启动链式队列(关联 + AI,主入口)
|
||||
* POST processOne 同步处理单个 expert_id
|
||||
* POST processBatch 同步批量处理
|
||||
* POST linkOne 仅 user 关联(调试)
|
||||
* POST syncByUser user 有 field_ai 后同步到 expert
|
||||
* GET preview 预览可关联 / 可 AI 总结 / 上下文
|
||||
* GET statistics 覆盖统计
|
||||
*/
|
||||
class ExpertFieldAi extends Base
|
||||
{
|
||||
/**
|
||||
* 启动链式关联队列
|
||||
* 启动链式处理(主入口)
|
||||
* Worker: php think queue:work --queue ExpertFieldAi
|
||||
*/
|
||||
public function startLinkChain()
|
||||
public function startChain()
|
||||
{
|
||||
$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);
|
||||
$started = $svc->startChain($force, $delay);
|
||||
|
||||
return jsonSuccess([
|
||||
'started' => $started,
|
||||
'queue' => ExpertFieldAiService::QUEUE_NAME,
|
||||
'force' => $force,
|
||||
'msg' => $started ? 'link chain enqueued' : 'no pending experts',
|
||||
'msg' => $started ? 'chain enqueued' : 'no pending experts',
|
||||
]);
|
||||
}
|
||||
|
||||
/** 兼容旧接口名 */
|
||||
public function startLinkChain()
|
||||
{
|
||||
return $this->startChain();
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步关联单个 expert
|
||||
* 同步处理单个 expert(关联 + AI)
|
||||
*/
|
||||
public function processOne()
|
||||
{
|
||||
$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->processExpert($expertId, $force);
|
||||
if (empty($result['ok'])) {
|
||||
return jsonError(isset($result['error']) ? $result['error'] : 'failed');
|
||||
}
|
||||
return jsonSuccess($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步批量处理
|
||||
* expert_ids 逗号分隔,或 limit 扫描待处理前 N 条
|
||||
*/
|
||||
public function processBatch()
|
||||
{
|
||||
$force = intval($this->request->param('force', 0)) === 1;
|
||||
$ids = $this->resolveExpertIds();
|
||||
if (empty($ids)) {
|
||||
return jsonError('expert_ids 或 limit 必填');
|
||||
}
|
||||
|
||||
$svc = new ExpertFieldAiService();
|
||||
return jsonSuccess($svc->batchProcess($ids, $force));
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅 user 关联(不 AI)
|
||||
*/
|
||||
public function linkOne()
|
||||
{
|
||||
@@ -56,43 +98,18 @@ class ExpertFieldAi extends Base
|
||||
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');
|
||||
}
|
||||
|
||||
$ids = $this->resolveExpertIds(true);
|
||||
if (empty($ids)) {
|
||||
return jsonError('expert_ids 或 limit 必填');
|
||||
}
|
||||
|
||||
$svc = new ExpertFieldAiService();
|
||||
$result = $svc->batchLinkFromUser($ids, $force);
|
||||
return jsonSuccess($result);
|
||||
return jsonSuccess($svc->batchLinkFromUser($ids, $force));
|
||||
}
|
||||
|
||||
/**
|
||||
* user 更新 field_ai 后,同步到同邮箱 expert
|
||||
*/
|
||||
public function syncByUser()
|
||||
{
|
||||
$userId = intval($this->request->param('user_id', 0));
|
||||
@@ -110,7 +127,7 @@ class ExpertFieldAi extends Base
|
||||
}
|
||||
|
||||
/**
|
||||
* 预览是否可关联
|
||||
* 预览:是否可 user 关联、是否可 AI、上下文摘要
|
||||
*/
|
||||
public function preview()
|
||||
{
|
||||
@@ -120,7 +137,7 @@ class ExpertFieldAi extends Base
|
||||
}
|
||||
|
||||
$svc = new ExpertFieldAiService();
|
||||
$result = $svc->previewLink($expertId);
|
||||
$result = $svc->preview($expertId);
|
||||
if (empty($result['ok'])) {
|
||||
return jsonError(isset($result['error']) ? $result['error'] : 'failed');
|
||||
}
|
||||
@@ -129,33 +146,58 @@ class ExpertFieldAi extends Base
|
||||
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();
|
||||
$base = Db::name('expert')->where('state', '<>', 5);
|
||||
$total = (clone $base)->count();
|
||||
$done = (clone $base)->where('field_ai_status', ExpertFieldAiService::STATUS_DONE)->count();
|
||||
$userLink = (clone $base)->where('field_ai_source', ExpertFieldAiService::SOURCE_USER_LINK)->count();
|
||||
$aiDone = (clone $base)->where('field_ai_source', ExpertFieldAiService::SOURCE_AI)->count();
|
||||
$pending = (clone $base)->where('field_ai_status', ExpertFieldAiService::STATUS_PENDING)->count();
|
||||
$noUserLink = (clone $base)->where('field_ai_status', ExpertFieldAiService::STATUS_NO_USER_LINK)->count();
|
||||
$insufficient = (clone $base)->where('field_ai_status', ExpertFieldAiService::STATUS_INSUFFICIENT)->count();
|
||||
$failed = (clone $base)->where('field_ai_status', ExpertFieldAiService::STATUS_FAILED)->count();
|
||||
|
||||
return jsonSuccess([
|
||||
'total' => $total,
|
||||
'done' => $done,
|
||||
'user_link' => $userLink,
|
||||
'no_user_link' => $noUserLink,
|
||||
'ai_done' => $aiDone,
|
||||
'pending' => $pending,
|
||||
'no_user_link' => $noUserLink,
|
||||
'insufficient' => $insufficient,
|
||||
'failed' => $failed,
|
||||
'coverage_rate' => $total > 0 ? round($done / $total * 100, 2) . '%' : '0%',
|
||||
]);
|
||||
}
|
||||
|
||||
private function resolveExpertIds($linkOnly = false)
|
||||
{
|
||||
$idsRaw = trim((string)$this->request->param('expert_ids', ''));
|
||||
$limit = min(max(intval($this->request->param('limit', 0)), 0), 200);
|
||||
|
||||
if ($idsRaw !== '') {
|
||||
return array_filter(array_map('intval', explode(',', $idsRaw)));
|
||||
}
|
||||
|
||||
if ($limit <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$query = Db::name('expert')->where('state', '<>', 5);
|
||||
if ($linkOnly) {
|
||||
$query->where(function ($q) {
|
||||
$q->where('field_ai_status', ExpertFieldAiService::STATUS_PENDING)
|
||||
->whereOr('field_ai_status', ExpertFieldAiService::STATUS_FAILED);
|
||||
});
|
||||
} else {
|
||||
$query->where(function ($q) {
|
||||
$q->where('field_ai_status', ExpertFieldAiService::STATUS_PENDING)
|
||||
->whereOr('field_ai_status', ExpertFieldAiService::STATUS_FAILED)
|
||||
->whereOr('field_ai_status', ExpertFieldAiService::STATUS_NO_USER_LINK);
|
||||
});
|
||||
}
|
||||
|
||||
return $query->order('expert_id asc')->limit($limit)->column('expert_id');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user