背调优化

发邮件记录添加姓名和邮箱模糊搜索
This commit is contained in:
wyn
2026-06-05 13:52:35 +08:00
parent 752494dbdb
commit 1d54946fef
6 changed files with 243 additions and 11 deletions

View File

@@ -4,6 +4,7 @@ namespace app\api\controller;
use app\common\service\AuthorBackgroundService;
use think\Controller;
use think\Db;
/**
* 作者背调HTML 报告页 + JSON API
@@ -15,6 +16,9 @@ class Author extends Controller
/** @var AuthorBackgroundService */
private $bgService;
/** @var string */
private $articleLookupError = '';
public function __construct(\think\Request $request = null)
{
parent::__construct($request);
@@ -25,7 +29,8 @@ class Author extends Controller
* 作者背调 HTML 页面入口
*
* 1. 传了 ORCID → 直接生成报告
* 2. 未传 ORCID + 姓氏(机构选填)→ 仅按姓名搜 ORCID1 条直接报告,多条显示选择列表
* 2. 传了 articleId稿件作者 ID即 art_aut_id→ 从 t_article_author 补全 ORCID / 姓名 / 机构
* 3. 未传 ORCID + 姓氏(机构选填)→ 仅按姓名搜 ORCID1 条直接报告,多条显示选择列表
*/
public function index()
{
@@ -33,6 +38,18 @@ class Author extends Controller
$formAction = $this->resolveFormAction();
$params = $this->resolveBackgroundParams();
if ($this->articleLookupError !== '') {
$this->assign([
'form_action' => $formAction,
'error_msg' => $this->articleLookupError,
'last_name' => $params['last_name'],
'first_name' => $params['first_name'],
'institution' => $params['institution'],
]);
return $this->fetch('author/index');
}
$orcidNorm = $this->bgService->normalizeOrcid($params['orcid']);
if ($orcidNorm === ''
@@ -129,6 +146,8 @@ class Author extends Controller
*/
private function resolveBackgroundParams()
{
$this->articleLookupError = '';
$pick = function (...$keys) {
foreach ($keys as $k) {
$v = trim((string) input('param.' . $k, ''));
@@ -145,14 +164,142 @@ class Author extends Controller
return '';
};
$orcid = $pick('orcid', 'orcid_id');
$lastName = $pick('lastName', 'last_name', 'lastname', 'surname');
$firstName = $pick('firstName', 'first_name', 'firstname', 'given_name');
$institution = $pick('institution', 'affiliation', 'affil', 'org');
$realname = $pick('realname', 'real_name');
$artAutId = $pick( 'art_aut_id', 'artAutId');
if ($artAutId !== '') {
$fromAuthor = $this->loadAuthorByArtAutId($artAutId);
if ($fromAuthor === null) {
$this->articleLookupError = '未找到该作者信息';
} else {
if ($orcid === '') {
$orcid = $fromAuthor['orcid'];
}
if ($lastName === '') {
$lastName = $fromAuthor['last_name'];
}
if ($firstName === '') {
$firstName = $fromAuthor['first_name'];
}
if ($institution === '') {
$institution = $fromAuthor['institution'];
}
}
}
if ($realname !== '' && ($lastName === '' || $firstName === '')) {
$parsed = $this->parseRealname($realname);
if ($lastName === '') {
$lastName = $parsed['last_name'];
}
if ($firstName === '') {
$firstName = $parsed['first_name'];
}
}
return [
'orcid' => $pick('orcid', 'orcid_id'),
'last_name' => $pick('lastName', 'last_name', 'lastname', 'surname'),
'first_name' => $pick('firstName', 'first_name', 'firstname', 'given_name'),
'institution' => $pick('institution', 'affiliation', 'affil', 'org'),
'orcid' => $orcid,
'last_name' => $lastName,
'first_name' => $firstName,
'institution' => $institution,
];
}
/**
* 按 art_aut_id 从 t_article_author 读取作者信息
*/
private function loadAuthorByArtAutId($artAutId)
{
$artAutId = (int) $artAutId;
if ($artAutId <= 0) {
return null;
}
$row = Db::name('article_author')
->field('orcid,firstname,lastname,company')
->where(['art_aut_id' => $artAutId, 'state' => 0])
->find();
if (empty($row)) {
return null;
}
return [
'orcid' => trim((string) ($row['orcid'] ?? '')),
'first_name' => trim((string) ($row['firstname'] ?? '')),
'last_name' => trim((string) ($row['lastname'] ?? '')),
'institution' => $this->extractInstitutionFromCompany($row['company'] ?? ''),
];
}
/**
* 从 company 字段提取机构名(去掉序号前缀,支持 ; 和 , 分隔)
*/
private function extractInstitutionFromCompany($company)
{
$company = trim((string) $company);
if ($company === '') {
return '';
}
$company = str_replace('', ',', $company);
$parts = preg_split('/[;,]/u', $company);
$institutions = [];
foreach ($parts as $part) {
$part = trim($part);
if ($part === '') {
continue;
}
$part = preg_replace('/^\d+\s*/', '', $part);
$part = trim($part);
if ($part !== '' && !in_array($part, $institutions, true)) {
$institutions[] = $part;
}
}
return implode('', $institutions);
}
/**
* 将整段姓名拆成名+姓(如 Chuanying ZHANG → first=Chuanying, last=ZHANG
*/
private function parseRealname($realname)
{
$realname = trim((string) $realname);
if ($realname === '') {
return ['first_name' => '', 'last_name' => ''];
}
if (strpos($realname, ',') !== false) {
$parts = array_map('trim', explode(',', $realname, 2));
$family = $parts[0] ?? '';
$given = $parts[1] ?? '';
if ($family !== '' && $given !== '') {
return ['first_name' => $given, 'last_name' => $family];
}
}
$tokens = preg_split('/\s+/u', $realname);
$tokens = array_values(array_filter($tokens, function ($t) {
return $t !== '';
}));
if (count($tokens) === 0) {
return ['first_name' => '', 'last_name' => ''];
}
if (count($tokens) === 1) {
return ['first_name' => '', 'last_name' => $tokens[0]];
}
$lastName = array_pop($tokens);
$firstName = implode(' ', $tokens);
return ['first_name' => $firstName, 'last_name' => $lastName];
}
private function resolveFormAction()
{
return rtrim($this->request->root(), '/') . '/api/author/index';