82 lines
3.2 KiB
PHP
82 lines
3.2 KiB
PHP
<?php
|
||||
|
|
/**
|
|||
|
|
* 「我对某个人的私人备注」(v24 用户 2026-10-03 第 5 条)。
|
|||
|
|
*
|
|||
|
|
* 用户原话:「名册中,每个人的备注,都有两个,一个是他自己填写的,就好像他自己的
|
|||
|
|
* 一个格言或者自我介绍;如果其他人打开这个人的信息,编辑备注,
|
|||
|
|
* 是这个人对他的独有的备注,例如记录怎么跟这个人认识的等等。」
|
|||
|
|
*
|
|||
|
|
* 所以名册里有**两种**备注,别混:
|
|||
|
|
*
|
|||
|
|
* · `persons.note` —— **本人写的**自我介绍/格言(每人一份,本人可改)。
|
|||
|
|
* 别人打开他的资料**看得到**(那是他愿意公开说的)。
|
|||
|
|
* · `person_notes` —— **"我"对他写的**私人备注(怎么认识的、要注意什么…)。
|
|||
|
|
* ⚠️ **只有写的人自己看得到** —— 它属于"我和他的关系",
|
|||
|
|
* 不是这个人的属性。所以它不落 persons,
|
|||
|
|
* 否则我写一句"这人借钱不还"全家都能看见。
|
|||
|
|
*
|
|||
|
|
* 这也正是为什么不复用 persons.note:一个字段存不下"两种语义 + 两种可见性"。
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
declare(strict_types=1);
|
|||
|
|
|
|||
|
|
namespace App;
|
|||
|
|
|
|||
|
|
final class PersonNote
|
|||
|
|
{
|
|||
|
|
/** 我对这个人的私人备注(没写过返回 '') */
|
|||
|
|
public static function get(int $personId, int $viewerId): string
|
|||
|
|
{
|
|||
|
|
if ($personId <= 0 || $viewerId <= 0) {
|
|||
|
|
return '';
|
|||
|
|
}
|
|||
|
|
$st = Database::get()->prepare(
|
|||
|
|
'SELECT note FROM person_notes WHERE person_id = ? AND viewer_id = ?'
|
|||
|
|
);
|
|||
|
|
$st->execute([$personId, $viewerId]);
|
|||
|
|
$v = $st->fetchColumn();
|
|||
|
|
return $v === false ? '' : (string)$v;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 写入/清空。**空串等于删除这条备注** —— 不留一行空记录,
|
|||
|
|
* 否则"我写过又删掉"会留下一条 forever 的空行,日后分不清"没写过"与"删掉了"。
|
|||
|
|
*/
|
|||
|
|
public static function set(int $personId, int $viewerId, string $note): void
|
|||
|
|
{
|
|||
|
|
if ($personId <= 0 || $viewerId <= 0) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
$note = trim($note);
|
|||
|
|
if ($note === '') {
|
|||
|
|
Database::get()->prepare(
|
|||
|
|
'DELETE FROM person_notes WHERE person_id = ? AND viewer_id = ?'
|
|||
|
|
)->execute([$personId, $viewerId]);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
Database::get()->prepare(
|
|||
|
|
'INSERT INTO person_notes (person_id, viewer_id, note) VALUES (?,?,?)
|
|||
|
|
ON DUPLICATE KEY UPDATE note = VALUES(note)'
|
|||
|
|
)->execute([$personId, $viewerId, mb_substr($note, 0, 4000, 'UTF-8')]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 一批人的私人备注(列表页要一次取完,别逐行查 —— N+1 在名册几十人时很明显)。
|
|||
|
|
* @return array<int,string> person_id => note
|
|||
|
|
*/
|
|||
|
|
public static function mapFor(int $viewerId): array
|
|||
|
|
{
|
|||
|
|
if ($viewerId <= 0) {
|
|||
|
|
return [];
|
|||
|
|
}
|
|||
|
|
$st = Database::get()->prepare(
|
|||
|
|
'SELECT person_id, note FROM person_notes WHERE viewer_id = ? AND note IS NOT NULL AND note <> ""'
|
|||
|
|
);
|
|||
|
|
$st->execute([$viewerId]);
|
|||
|
|
$out = [];
|
|||
|
|
foreach ($st->fetchAll() as $r) {
|
|||
|
|
$out[(int)$r['person_id']] = (string)$r['note'];
|
|||
|
|
}
|
|||
|
|
return $out;
|
|||
|
|
}
|
|||
|
|
}
|