更新
@@ -0,0 +1,110 @@
|
||||
# 100 个明确标识的测试用户
|
||||
|
||||
## 数据范围
|
||||
|
||||
- 固定批次:`cn-adults-20260831-v1`。
|
||||
- 用户数量:100,男 50、女 50;公开编号 `TESTCN000001` 至 `TESTCN000100`。
|
||||
- 所有资料都带独立字段 `users.is_test=1`、`users.test_batch`。正式注册用户默认 `is_test=0`,注册和资料修改接口不能将其改成测试标识或清除标识。
|
||||
- 昵称带“测试·”前缀,简介明确说明虚构身份;管理端有数据类型标签、类型/批次筛选和详情展示。客户端推荐、附近、搜索/关系列表、主页显示“测试用户”标签。
|
||||
- 仅创建用户、资料、隐私设置。无真实手机号、无可用密码、无登录会话、无虚假定位/在线时间、无认证/会员/订单/动态/聊天/粉丝记录。这批是展示用资料,不是自动聊天机器人,也不提供测试登录密码。
|
||||
- 测试用户不计入后台注册、新增、活跃及资料完善人数;测试人数单独显示。其他已有互动/订单指标的原口径未改动。
|
||||
- 头像为 imagegen 内置工具生成的虚构中国成年人形象,男 5 张、女 5 张;每张由 10 条同性别资料复用,共 10 张不同头像,并非 100 名真人或 100 张不同头像。文件与生成提示词见 `avatars/`、`avatar-provenance.json`。
|
||||
|
||||
`users.json` 是已经生成的 100 条本地预览数据,头像 URL 使用 `http://127.0.0.1:8888/uploads`。它不是已导入数据库的凭证。CLI 导入会按传入的公开域名重新生成 URL。
|
||||
|
||||
## 发布顺序
|
||||
|
||||
先确认要导入的环境。不要同时对本地和线上执行,也不要打开 `IM_SEED_DEMO`。
|
||||
|
||||
1. 备份目标库,按现有迁移机制应用 `backend/migrations/028_test_users.sql`(保留迁移校验记录)。它只新增测试字段/索引,原用户默认正式用户。
|
||||
2. 发布包含本次字段的后端,再发布管理端和 H5;原生 App 需重新构建。不要让新后端连接未迁移的库,否则列表会因字段缺失报错。
|
||||
3. 确认后台文件存储设置的 `storage.local.directory` 实际值;未设置时使用 `IM_MEDIA_DIR`。头像必须拷贝到此目录,不能仅拷贝到一个任意的 uploads 目录。
|
||||
4. 先运行预览,检查数量/性别/域名;再显式执行导入命令。
|
||||
5. 验证 SQL 统计、管理端筛选和客户端标识;抽查每张头像地址都返回图片而不是 HTML/404。
|
||||
|
||||
头像采用项目已有的数字文件名规则,经 `/uploads/:name` 访问。`--public-base` 必须是本地媒体服务的真实公开 URL;即使普通用户上传切换到云存储,这批内置测试素材仍需配置可访问的本地媒体目录或事先将相同文件发布到指定公开 URL。
|
||||
|
||||
## 本地 PowerShell
|
||||
|
||||
在 `backend` 目录执行,项目自带 Go 在 `..\.tools\go\bin\go.exe`。
|
||||
|
||||
```powershell
|
||||
# 只输出预览 JSON,不连接或修改数据库。
|
||||
& '..\.tools\go\bin\go.exe' run ./cmd/seed-test-users --public-base http://127.0.0.1:8888/uploads
|
||||
|
||||
# 先在本机环境变量设置 IM_DB_DSN;不要把密码提交到代码仓库。
|
||||
$env:IM_ENV = 'development'
|
||||
& '..\.tools\go\bin\go.exe' run ./cmd/seed-test-users --apply --confirm-database im --public-base http://127.0.0.1:8888/uploads --avatars-dir ../fixtures/test-users/avatars --media-dir ./uploads
|
||||
```
|
||||
|
||||
## 服务器 / 宝塔
|
||||
|
||||
先将 `fixtures/test-users/avatars` 和编译好的导入工具上传服务器。Go 项目运行环境的 `IM_DB_DSN` 必须是实际目标库;注意该项目曾使用 3307 端口,不要误连到面板默认 3306 的另一个数据库。
|
||||
|
||||
```sh
|
||||
# 在 backend 目录构建 Linux 工具;也可在服务器原生 go build。
|
||||
GOOS=linux GOARCH=amd64 go build -o seed-test-users ./cmd/seed-test-users
|
||||
|
||||
# 服务器上,加载已经存在且可信的后端环境文件,不回显内容。
|
||||
set -a
|
||||
. /etc/xingyu-im-bt.env
|
||||
set +a
|
||||
|
||||
# 以下路径必须对应已上传的素材和实际本地存储配置。
|
||||
./seed-test-users --apply --allow-production-test-data \
|
||||
--confirm-database im \
|
||||
--public-base https://im.bchongw.com/uploads \
|
||||
--avatars-dir ./avatars \
|
||||
--media-dir /www/wwwroot/xingyu-data/uploads
|
||||
```
|
||||
|
||||
如果目标库名字不是 `im`,请使用真实名称;程序会校验确认名称与当前连接的 `DATABASE()` 完全一致。生产环境导入还需要显式 `--allow-production-test-data`。启动普通后端不会自动生成这些测试账号。
|
||||
|
||||
## 幂等性与出错行为
|
||||
|
||||
整批数据在一个事务中写入,并持有批次互斥锁。成功应返回 `created=100, male=50, female=50`。再次执行应返回 `created=0, skipped=100`。
|
||||
|
||||
遇到现有正式用户编号冲突、批次不完整、测试用户已删除或性别被修改时,程序拒绝覆盖,事务回滚。请人工核查,不要清空用户表或删库重来。程序不会为了补足 100 人而覆盖现有数据。已复制而未引用的头像可能保留在媒体目录,重试会复用内容相同的文件;内容不同的同名文件不会被覆盖。
|
||||
|
||||
验证:
|
||||
|
||||
```sql
|
||||
SELECT u.test_batch, p.gender, COUNT(*) AS total
|
||||
FROM users u JOIN user_profiles p ON p.user_id=u.id
|
||||
WHERE u.is_test=1 AND u.test_batch='cn-adults-20260831-v1' AND u.deleted_at IS NULL
|
||||
GROUP BY u.test_batch, p.gender;
|
||||
|
||||
SELECT is_test, COUNT(*) FROM users WHERE deleted_at IS NULL GROUP BY is_test;
|
||||
```
|
||||
|
||||
第一条应是 gender=1、gender=2 各 50。管理端“用户管理”选择“测试用户”,批次输入 `cn-adults-20260831-v1` 应显示 100 条;选择“正式注册用户”不应包含本批次。
|
||||
|
||||
## 测试
|
||||
|
||||
`go test ./...` 包含数据数量/性别/年龄/标签/URL、素材复制防覆盖和过滤参数测试。
|
||||
|
||||
设置 `IM_TEST_MYSQL_DSN` 为不带数据库名的本机 MySQL 连接后,`go test ./internal/testusers -v` 还会创建两个独立的 `im_fixture_test_<数字>` 临时库,验证真实 MySQL 的重复执行、原用户保留、冲突回滚。测试结束只删除自己创建的临时库,不连接应用数据库。测试不接受远程主机或带数据库名的 DSN。
|
||||
|
||||
## 已导入测试头像迁移至 COS
|
||||
|
||||
2026-08-31 已将线上本批次的 10 张头像上传到 `gz-1349751149`,并把 100 条资料的头像链接更新为 COS 的持久 HTTPS URL;男女各 50 和测试标签不变。原图片和旧链接备份仍在服务器,详细结果见 `deploy/im.bchongw.com_部署记录.md`。
|
||||
|
||||
专用工具 `backend/cmd/migrate-test-avatars-cos` 只操作本批次,不改变系统存储配置,不删除本地图片、云端对象或其他用户。凭证从服务器环境及数据库加密配置读取,禁止通过命令行参数或日志传递密钥。它严格确认生产库 `127.0.0.1:3307/im` 和指定存储桶;默认只做读取预览。
|
||||
|
||||
在服务器使用已加载可信后端环境变量的 shell 中:
|
||||
|
||||
```sh
|
||||
# 只读核对,不上传或更新数据库。
|
||||
/www/server/xingyu-im/ops/migrate-test-avatars-cos \
|
||||
--confirm-database im --confirm-bucket gz-1349751149 \
|
||||
--media-dir /www/wwwroot/xingyu-data/uploads
|
||||
|
||||
# 正式执行需额外添加 --apply,以及一个尚不存在的专用备份目录:
|
||||
# --backup-dir /www/backup/xingyu-cos-avatars-YYYYMMDD-HHMMSS
|
||||
```
|
||||
|
||||
每个 COS 文件必须匿名下载成功且内容与原 PNG 完全一致,才会在一个事务中替换数据库链接。已有同名对象内容不符、测试头像曾被编辑、部分资料缺失或上传验证失败时均拒绝覆盖。已迁移的同内容对象会复用,已相同的数据库链接不重复更新。
|
||||
|
||||
上传遵循现有对象权限。工具只允许对本次新上传、确需公开显示的测试头像设置对象级公有读作为回退;不会修改存储桶 ACL 或已有对象 ACL。本次迁移未触发该回退,权限改动数量为 0。相关接口行为见 [腾讯云 PUT Object](https://cloud.tencent.com/document/product/436/7749)。
|
||||
|
||||
离线测试:在 `backend` 运行 `go test ./cmd/migrate-test-avatars-cos -v`,测试使用内存 HTTP 服务,不访问腾讯云或生产数据库。
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"generator": "built-in image_gen",
|
||||
"date": "2026-08-31",
|
||||
"uniquePortraits": 10,
|
||||
"reuse": "每个性别5张头像,50条同性别测试资料循环使用;并非100名真人或100张不同头像。",
|
||||
"assets": [
|
||||
{
|
||||
"file": "90002811-1.png",
|
||||
"gender": 1,
|
||||
"description": "AI生成的虚构中国成年人,不是真人身份",
|
||||
"prompt": "Use case: photorealistic-natural. Asset type: square test-user avatar for a Chinese social app. Primary request: create a single photorealistic head-and-shoulders portrait of a fictional Chinese man aged 27, short black hair, gentle smile, navy casual shirt, blurred green park background. Natural skin texture, soft daylight, centered face fully visible with comfortable margin for circle cropping. Only one person, fictional AI-generated adult, not a celebrity or an existing person. No text, no watermarks, no logos, no collage."
|
||||
},
|
||||
{
|
||||
"file": "90002812-1.png",
|
||||
"gender": 1,
|
||||
"description": "AI生成的虚构中国成年人,不是真人身份",
|
||||
"prompt": "Use case: photorealistic-natural. Asset type: square test-user avatar for a Chinese social app. Primary request: create a single photorealistic head-and-shoulders portrait of a fictional Chinese man aged 30, oval face, neatly parted short black hair, thin round glasses, light grey knit shirt, relaxed bookshop background. Natural skin texture, soft daylight, centered face fully visible with comfortable margin for circle cropping. Only one person, fictional AI-generated adult, not a celebrity or an existing person. No text, no watermark, no logos, no collage."
|
||||
},
|
||||
{
|
||||
"file": "90002813-1.png",
|
||||
"gender": 1,
|
||||
"description": "AI生成的虚构中国成年人,不是真人身份",
|
||||
"prompt": "Use case: photorealistic-natural. Asset type: square test-user avatar for a Chinese social app. Primary request: create a single photorealistic head-and-shoulders portrait of a fictional Chinese man aged 24, short textured black hair, broad friendly smile, teal T-shirt, softly blurred riverside walkway. Natural skin texture, soft daylight, centered face fully visible with comfortable margin for circle cropping. Only one person, fictional AI-generated adult, not a celebrity or an existing person. No text, no watermark, no logos, no collage."
|
||||
},
|
||||
{
|
||||
"file": "90002814-1.png",
|
||||
"gender": 1,
|
||||
"description": "AI生成的虚构中国成年人,不是真人身份",
|
||||
"prompt": "Use case: photorealistic-natural. Asset type: square test-user avatar for a Chinese social app. Primary request: create a single photorealistic head-and-shoulders portrait of a fictional Chinese man aged 33, short cropped black hair, light facial stubble, earth brown casual jacket, soft urban cafe background. Natural skin texture, soft daylight, centered face fully visible with comfortable margin for circle cropping. Only one person, fictional AI-generated adult, not a celebrity or an existing person. No text, no watermark, no logos, no collage."
|
||||
},
|
||||
{
|
||||
"file": "90002815-1.png",
|
||||
"gender": 1,
|
||||
"description": "AI生成的虚构中国成年人,不是真人身份",
|
||||
"prompt": "Use case: photorealistic-natural. Asset type: square test-user avatar for a Chinese social app. Primary request: create a single photorealistic head-and-shoulders portrait of a fictional Chinese man aged 28, longer swept black hair, clean shaven, white crewneck and blue overshirt, neutral blue-grey studio backdrop. Natural skin texture, soft daylight, centered face fully visible with comfortable margin for circle cropping. Only one person, fictional AI-generated adult, not a celebrity or an existing person. No text, no watermark, no logos, no collage."
|
||||
},
|
||||
{
|
||||
"file": "90002821-1.png",
|
||||
"gender": 2,
|
||||
"description": "AI生成的虚构中国成年人,不是真人身份",
|
||||
"prompt": "Use case: photorealistic-natural. Asset type: square test-user avatar for a Chinese social app. Primary request: create a single photorealistic head-and-shoulders portrait of a fictional Chinese woman aged 26, shoulder-length black hair, gentle smile, cream casual blouse, blurred green park background. Natural skin texture, soft daylight, centered face fully visible with comfortable margin for circle cropping. Only one person, fictional AI-generated adult, not a celebrity or an existing person. No text, no watermarks, no logos, no collage."
|
||||
},
|
||||
{
|
||||
"file": "90002822-1.png",
|
||||
"gender": 2,
|
||||
"description": "AI生成的虚构中国成年人,不是真人身份",
|
||||
"prompt": "Use case: photorealistic-natural. Asset type: square test-user avatar for a Chinese social app. Primary request: create a single photorealistic head-and-shoulders portrait of a fictional Chinese woman aged 29, long straight black hair, thin oval glasses, sage green blouse, softly blurred bookshop background. Natural skin texture, soft daylight, centered face fully visible with comfortable margin for circle cropping. Only one person, fictional AI-generated adult, not a celebrity or an existing person. No text, no watermark, no logos, no collage."
|
||||
},
|
||||
{
|
||||
"file": "90002823-1.png",
|
||||
"gender": 2,
|
||||
"description": "AI生成的虚构中国成年人,不是真人身份",
|
||||
"prompt": "Use case: photorealistic-natural. Asset type: square test-user avatar for a Chinese social app. Primary request: create a single photorealistic head-and-shoulders portrait of a fictional Chinese woman aged 24, short black bob with light bangs, cheerful smile, light blue denim shirt, softly blurred riverside walkway. Natural skin texture, soft daylight, centered face fully visible with comfortable margin for circle cropping. Only one person, fictional AI-generated adult, not a celebrity or an existing person. No text, no watermark, no logos, no collage."
|
||||
},
|
||||
{
|
||||
"file": "90002824-1.png",
|
||||
"gender": 2,
|
||||
"description": "AI生成的虚构中国成年人,不是真人身份",
|
||||
"prompt": "Use case: photorealistic-natural. Asset type: square test-user avatar for a Chinese social app. Primary request: create a single photorealistic head-and-shoulders portrait of a fictional Chinese woman aged 32, tied-back black hair, natural friendly expression, burgundy casual knit top, soft urban cafe background. Natural skin texture, soft daylight, centered face fully visible with comfortable margin for circle cropping. Only one person, fictional AI-generated adult, not a celebrity or an existing person. No text, no watermark, no logos, no collage."
|
||||
},
|
||||
{
|
||||
"file": "90002825-1.png",
|
||||
"gender": 2,
|
||||
"description": "AI生成的虚构中国成年人,不是真人身份",
|
||||
"prompt": "Use case: photorealistic-natural. Asset type: square test-user avatar for a Chinese social app. Primary request: create a single photorealistic head-and-shoulders portrait of a fictional Chinese woman aged 27, wavy shoulder-length dark hair, natural smile, pale blue blouse, neutral warm-grey studio backdrop. Natural skin texture, soft daylight, centered face fully visible with comfortable margin for circle cropping. Only one person, fictional AI-generated adult, not a celebrity or an existing person. No text, no watermark, no logos, no collage."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 1.8 MiB |