diff --git a/.ai/product/feature-spec/README.md b/.ai/product/feature-spec/README.md index 78cb3c3..54da7c9 100644 --- a/.ai/product/feature-spec/README.md +++ b/.ai/product/feature-spec/README.md @@ -25,6 +25,7 @@ | [ops-content.md](ops-content.md) | 运营内容(宫格+测评上下架) | §7 | `admin-h5` `/content` · `GET /home/tools` | Ops-C · ECR-008 Implemented | | [ops-commerce.md](ops-commerce.md) | 运营商业加深(订单筛选+展示价+退款只读) | §7 | `admin-h5` `/orders` `/pricing` | Ops-D · ECR-009 | | [ops-system.md](ops-system.md) | 运营系统(RBAC+封禁+推送占位) | §7 | `admin-h5` `/push` `/admins` | Ops-E · ECR-010 | +| [input-compliance.md](input-compliance.md) | 用户文字输入合规 | 横切 · 安全 | 各写接口 · code 40060 | P2 · ECR-012 | 新功能:复制 `_TEMPLATE.md` → 填满 → 在本表登记 → 再编码。 diff --git a/.ai/product/feature-spec/account-auth.md b/.ai/product/feature-spec/account-auth.md index e1ff26b..cd05c40 100644 --- a/.ai/product/feature-spec/account-auth.md +++ b/.ai/product/feature-spec/account-auth.md @@ -84,14 +84,16 @@ Device 绑定到账号 User | R5 | 登出作废 session;设备可再登录其他账号 | | R6 | 正式环境恢复校验前须改回本 Spec | | R7 | 新账号未填昵称时,服务端用「意象词+场景词」词库(100×100)随机生成,如心语岛、微光谷 | -| R8 | 账号昵称可在个人档案页修改(PATCH `/auth/me`);首页展示昵称而非「自己」 | +| R8 | 账号昵称可在个人档案页修改(PATCH `/auth/me`);首页与各页「自己」展示位统一用昵称(合盘/问答/星座/档案卡) | +| R9 | 账号头像可在「我的」页更换:相册或拍照上传;服务端持久化;GET `/auth/me` 返回 `avatar_url`;未设置时 UI 用愈心小人正面默认头像(`public/default-avatar.png`,源图 `public/logo/愈心小人1.png`) | --- ## 8. 数据模型影响 -- `users.phone` UNIQUE · `users.password_hash` · `users.nickname` +- `users.phone` UNIQUE · `users.password_hash` · `users.nickname` · `users.avatar_url` - `user_sessions(token, user_id, expires_at)` +- 本地文件:`data/avatars/{user_id}.{jpg|png|webp}`(进程相对路径) --- @@ -102,8 +104,10 @@ Device 绑定到账号 User | POST | `/api/v1/auth/register` | 注册(可带 nickname) | | POST | `/api/v1/auth/login` | 登录 | | POST | `/api/v1/auth/logout` | 登出 | -| GET | `/api/v1/auth/me` | 当前账号 | +| GET | `/api/v1/auth/me` | 当前账号(含 avatar_url) | | PATCH | `/api/v1/auth/me` | 更新昵称 `{ nickname }` | +| POST | `/api/v1/auth/me/avatar` | multipart `file`;jpeg/png/webp;≤2MB → 更新 avatar_url | +| GET | `/api/v1/media/avatars/:file` | 公开读头像文件 | --- @@ -113,12 +117,30 @@ Device 绑定到账号 User |---|---|---| | register/login | ✓ | ✓ | | profiles / reports 写读 | ✗ | ✓ | +| 上传头像 | ✗ | ✓ | +| 读头像媒体 | ✓ | ✓ | --- ## 11. 埋点 -`auth_register` · `auth_login` · `auth_logout` +经统一 `track()`(见 [analytics.md](analytics.md) · [ops-analytics.md](ops-analytics.md))。 +**非** P1 核心漏斗 5 事件;接入后走自有 `POST /analytics/events`(及可选 GA)。 +禁止参数含手机号、明文密码、头像绝对 URL / `user_id`。 + +| Event | 触发 | 可选 params | +|---|---|---| +| `auth_register` | 账号新建成功(含 OpenLogin 自动建号,`is_new=true`) | `source`: login_page | +| `auth_login` | 已有账号登录成功(`is_new=false`) | `source`: login_page | +| `auth_logout` | 用户在「我的」点退出且本地 session 已清 | `surface`: mine | +| `avatar_sheet_opened` | 「我的」打开更换头像 sheet | `surface`: mine | +| `avatar_upload_succeeded` | 头像上传 API 成功且 UI 刷新为新图 | `source`: album \| camera | +| `avatar_upload_failed` | 头像上传失败(校验/网络/服务端) | `source`: album \| camera · `reason`: too_large \| bad_type \| network \| server \| unknown | +| `nickname_updated` | PATCH 昵称成功 | `surface`: profile | + +`page_view` 对 `/login` · `/mine` 由路由自动采集,本 Spec 不重复定义。 + +**实现状态:** 事件名以本表为准;H5 已挂 Login / Mine / Profile(`track` → 自有 ingest + 可选 GA)。 --- diff --git a/.ai/product/feature-spec/ask.md b/.ai/product/feature-spec/ask.md index c244f98..def597e 100644 --- a/.ai/product/feature-spec/ask.md +++ b/.ai/product/feature-spec/ask.md @@ -65,6 +65,8 @@ ```text /ask +├── 愈心 AI / 顾问 Tab +├── 顾问列表 → 顾问专属对话(?advisor=key · 顶栏返回回列表) ├── Empty(无档案) ├── Loading(发送中) ├── Normal(历史 + 输入) diff --git a/.ai/product/feature-spec/companion.md b/.ai/product/feature-spec/companion.md index 134a18f..5a50c6e 100644 --- a/.ai/product/feature-spec/companion.md +++ b/.ai/product/feature-spec/companion.md @@ -111,10 +111,15 @@ Tab 陪伴 → /companion ## 11. 埋点 -| Event | 触发 | -|---|---| -| `companion_viewed` | 打开 | -| `mood_saved` | P2 | +| Event | 触发 | 可选 params | +|---|---|---| +| `companion_viewed` | 打开 `/companion` | — | +| `mood_saved` | 心情保存成功 | `score`(整数分,非正文) | +| `growth_plan_viewed` | 打开 `/growth-plan` 且列表加载结束 | — | +| `growth_plan_created` | 创建计划成功 | — | +| `growth_plan_checkin` | 今日打卡成功 | — | + +禁止参数含计划 title/focus/note 明文。 --- diff --git a/.ai/product/feature-spec/explore-test.md b/.ai/product/feature-spec/explore-test.md index 3a57cee..0508748 100644 --- a/.ai/product/feature-spec/explore-test.md +++ b/.ai/product/feature-spec/explore-test.md @@ -45,9 +45,9 @@ ↓ 进入 /scales/:slug ↓ -加载题目 - ↓ -逐题作答(须全部完成) +已有结果? → 直接展示最近结果 +「重新测试」 + ↓(无结果 / 点重测) +加载题目 · 逐题作答(须全部完成) ↓ 无 Self? → 引导建档 ↓ @@ -60,10 +60,13 @@ POST result → 展示丰富结果 | 子能力 | P1 | |---|---| -| 测试入口(探索 Tab) | ✓ | -| 测试列表 | ✓ | +| 测试入口(探索 Tab · 首页宫格) | ✓ · 产品向 `mbti-lite`;探索主路径为 curated 题库(A 集) | +| 测试列表 | ✓ · 探索「题库精选」宫格(每类 1~2)+「题库分类」;分类页 `/explore/bank/:key` | +| 题库范围(A) | ✓ 人格 / 情绪能力 / 智能 / 生活与关系;**不含**抑郁焦虑强迫躁狂双相等临床筛查 | | 问题流程 | ✓ | | 答题保存(服务端结果落库) | ✓ | +| 最近结果回看 | ✓ GET `/scales/{slug}/result`;有结果进页不重复作答 | +| 重新测试 | ✓ 结果页按钮 → 清空草稿再答;新结果落库并覆盖展示 | | 中断恢复 | ✓ localStorage 草稿(`scaleDraft`);提交后清除 | | 结果生成(丰富结构) | ✓ | | 免费层 | ✓ 全量 result | @@ -79,8 +82,10 @@ POST result → 展示丰富结果 | 路由 | 页面 | |---|---| -| `/explore` | ExplorePage | -| `/scales/:slug` | ScalePage | +| `/explore` | ExplorePage(题库精选宫格 + 题库分类 + 其它工具) | +| `/explore/bank/:category` | ExploreBankCategoryPage · curated 题库分类列表 | +| `/explore/:category` | ExploreCategoryPage · 产品工具分类(解码/星座等) | +| `/scales/:slug` | ScalePage(含 bank slug) | ```text /scales/:slug @@ -116,6 +121,13 @@ POST result → 展示丰富结果 | R5 | result 含 label/summary/overview/dimensions/tips/scripts/growth_plan/faq | | R6 | 结果「不是固定标签」需在文案中提示 | | R7 | 作答过程写入本地草稿(按 slug);提交成功后清除;刷新可恢复未提交答案 | +| R8 | 同一用户同一 slug(含 curated 题库 slug)若已有 `scale_results`,再次进入直接展示**最近一次**结果,并提供「重新测试」;未点重测不得自动进入答题 | +| R9 | `mbti-lite` 产品展示名统一为「MBTI测试」(首页宫格 / 探索入口 / 量表 title) | +| R10 | **标准版 `mbti-lite`**:开源 OEJTS 1.2 · **32 题**(四维各 8)· 双极 1–5 Likert;按维累加,阈值判出 E/I·S/N·T/F·J/P 一侧,合成四字母类型;**免费** | +| R11 | **完整版 `mbti-full`**:60 题(四维各 15)· 须**成长会员**;未开通时 GET 返回 `locked=true` 且无题目;提交返回 403 | +| R12 | 禁止使用官方 MBTI® 版权题干;结果须提示「不是固定标签」;题库重大更新须 soft-delete 旧 `scale_results` | +| R13 | curated 题库(`scalebank`)仅含 A 集非临床探索量表;文案须声明「非诊断」;临床类(抑郁/焦虑/强迫等)不得进入 C 端 | +| R14 | curated 题库作答走同一 `/scales/:slug`;完成后再次点击入口须遵守 R8(只看结果或显式重测),不得每次从头作答 | --- @@ -134,6 +146,7 @@ POST result → 展示丰富结果 |---|---|---| | GET | `/api/v1/scales` | 列表 | | GET | `/api/v1/scales/{slug}` | 题目 | +| GET | `/api/v1/scales/{slug}/result` | 当前用户该量表最近一次结果;无则 404 | | POST | `/api/v1/scales/{slug}/result` | 提交计分 | --- @@ -144,18 +157,27 @@ POST result → 展示丰富结果 |---|---|---| | 看列表/题目 | ✓ | ✓ | | 提交结果 | ✗ | ✓ | +| `mbti-full` 作答 | ✗(须成长会员) | ✓(会员 active) | --- ## 11. 埋点 -| Event | 触发 | -|---|---| -| `scale_list_viewed` | 探索列表 | -| `scale_started` | 进入作答 | -| `scale_completed` | 出结果 | -| `scale_share_clicked` | 分享 | -| `scale_cta_relation` / `scale_cta_ask` | 导流 | +经统一 `track()`;非 P1 核心 5 事件。禁止参数含题干全文、答案明文、档案 ID。 + +| Event | 触发 | 可选 params | +|---|---|---| +| `scale_list_viewed` | 打开 `/explore` 且题库 catalog 加载成功 | — | +| `scale_bank_category_viewed` | 打开 `/explore/bank/:category` 且分类加载成功 | `category`(key) | +| `scale_started` | 用户点开始进入作答(含「重新测试」后再开始) | `slug` · `access`: free\|member | +| `scale_completed` | 提交计分成功并展示结果 | `slug` · `access`: free\|member | +| `scale_result_reopened` | 再次进入已有结果直接展示(R8,未重测) | `slug` | +| `scale_retake_clicked` | 点「重新测试」 | `slug` | +| `scale_locked_viewed` | 会员锁页展示(如 mbti-full) | `slug` | +| `scale_share_clicked` | 结果页打开分享 | `slug` | +| `scale_cta_relation` / `scale_cta_ask` | 结果导流(若 UI 有) | `slug` | + +`page_view` 对 `/explore` · `/explore/bank/*` · `/scales/*` 由路由自动采集。 --- @@ -165,6 +187,14 @@ POST result → 展示丰富结果 **When** 答完提交 **Then** 返回 label 与 overview/tips 等丰富字段 +**Given** 已提交过结果 +**When** 再次进入 `/scales/{slug}` +**Then** 直接展示最近结果与「重新测试」;不进入答题 + +**Given** 结果页点「重新测试」并完成提交 +**When** 再次进入 +**Then** 展示新结果 + **Given** 未答完 **When** 提交 **Then** 前端拦截;不成功落库 @@ -186,7 +216,8 @@ POST result → 展示丰富结果 | 项 | 内容 | |---|---| | Packages | `internal/scale` · `service/scale` · `ExplorePage` · `ScalePage` | -| Seeds | communication-style · emotion-pattern | +| Seeds | communication-style · emotion-pattern · **mbti-lite(OEJTS 32)** · **mbti-full(60·会员)** | | Gaps | 结果付费墙若要做须先改 Spec;全量 §11 埋点未挂(核心漏斗见 analytics) | -| Tests | score/result L1;`scaleDraft.spec`;Scale 流程组件测 | -| Process Review | 草稿恢复已实现 · P1 收口 | +| Tests | score/result L1;`ScoreJungian`;`scaleDraft.spec`;Scale 流程组件测 | +| Process Review | OEJTS 标准/完整双轨 · 最近结果回看 · P1 收口 | +| Credit | OEJTS / Open Psychometrics · openjung MIT | diff --git a/.ai/product/feature-spec/home.md b/.ai/product/feature-spec/home.md index 8dc629d..1386876 100644 --- a/.ai/product/feature-spec/home.md +++ b/.ai/product/feature-spec/home.md @@ -62,7 +62,7 @@ ```text / -├── Hero / 品牌 +├── 全局顶栏:透明愈心谷 Logo(AppHeader,全站) ├── 「自己」卡片标题展示账号昵称(默认意象词+场景词;档案页可改) ├── 穿衣指数 · 颜色搭配 · 养生推荐 ├── 功能入口(4 列固定网格 · 多行换行 · 禁止横向滑动) @@ -91,14 +91,16 @@ Empty:首页本身是入口,不因无档案空白死页。 | R2 | 不展示内部运维信息(API 连接状态等) | | R3 | 入口文案符合 lexicon(个人画像/关系理解/成长会员…) | | R4 | Tab 五名冻结:首页·探索·问答·陪伴·我的 | -| R5 | 「自己」卡片:穿衣指数 / 颜色搭配 / 养生推荐;有 Self 档案生日时按生日+本地时刻易经卦象种子调大模型生成;无档案或 LLM 不可用则本地回退 | +| R5 | 「自己」卡片:穿衣指数 / 颜色搭配 / 养生推荐;有 Self 生日时按生日+**本地日历**+**十二时辰**易经种子生成;**每一时辰准点切换**;无档案或 LLM 不可用则本地回退 | | R6 | 文案禁止占卜/算命恐吓与医疗疗效承诺;卦象仅作节律意象 | +| R7 | 贴士按 `user × 时辰起点` 持久缓存;GET 优先读缓存**即时返回**;缓存未命中时先回退/旧值,后台异步生成写入,禁止每次打开同步等 LLM | +| R8 | 响应含 `shichen` / `shichen_name` / `valid_until`(下一时辰起点);前端在 `valid_until` 自动静默刷新 | --- ## 8. 数据模型影响 -经首页建档时写 `profiles`(见 profile Spec)。每日贴士可缓存(同用户约 45 分钟 / 按时段刷新)。 +经首页建档时写 `profiles`。`home_daily_tips(user_id, shichen_start, tips jsonb)` 缓存时辰贴士。 --- @@ -107,7 +109,7 @@ Empty:首页本身是入口,不因无档案空白死页。 | Method | Path | 说明 | |---|---|---| | GET | `/api/v1/home/tools` | 宫格(已有) | -| GET | `/api/v1/home/daily-tips` | 自己卡片贴士(DeviceAuth;有 birthday 则 LLM) | +| GET | `/api/v1/home/daily-tips` | 自己卡片贴士(读缓存;含 valid_until) | | — | 复用 | `POST /profiles`、`POST /reports/portrait` | --- @@ -142,9 +144,13 @@ Empty:首页本身是入口,不因无档案空白死页。 **When** 提交主 CTA **Then** 进入画像基础结果路径 -**Given** 已登录且有 Self 生日、已配 deepseek +**Given** 已登录且有 Self 生日、该时辰已有缓存 **When** GET `/home/daily-tips` -**Then** `source=llm` 且含 clothing_index / palette / wellness +**Then** 立即返回缓存(含 clothing/palette/wellness / valid_until),不阻塞 LLM + +**Given** 时辰切换到点 +**When** 前端到达 `valid_until` +**Then** 静默刷新;穿衣/颜色/养生随新时辰更新 **Given** 无档案或无 LLM **When** GET `/home/daily-tips` diff --git a/.ai/product/feature-spec/input-compliance.md b/.ai/product/feature-spec/input-compliance.md new file mode 100644 index 0000000..402e127 --- /dev/null +++ b/.ai/product/feature-spec/input-compliance.md @@ -0,0 +1,123 @@ +# Feature Spec: 用户文字输入合规校验 + +> Status: `Active` · Map: `横切 · 安全/合规` · Phase: `P2` +> 关联:[lexicon.md](../lexicon.md) · [.ai/security.md](../../security.md) · account-auth / profile / ask / companion + +--- + +## 1. 功能定义 + +| 字段 | 内容 | +|---|---| +| Name | 文字输入合规(Text Compliance) | +| Purpose | 所有用户提交的**自由文字**在服务端统一做合法性/合规校验;前端可做即时提示,**以后端拒绝为准** | +| Business Goal | 降低 XSS/注入、恐吓与医疗疗效话术、垃圾刷屏进入 DB 与模型上下文的风险 | + +| In | Out | +|---|---| +| 昵称 · 档案显示名 · 问答 content · 心情/打卡 note · 成长计划 title/focus · 邀请 display_name · 意象场景自填 | 纯数字字段(生日年月日、分数、经纬度) | +| 长度 · 格式清洗 · XSS/控制字符 · lexicon 硬禁止 · 简易刷屏特征 | 完整内容审核平台 / 人工审 / 语音 | +| 错误码统一 | 改开放登录策略本身 | + +--- + +## 2. 用户价值 + +1. 避免有害/违规文案入库与进模型。 +2. 提交失败时得到可读中文原因。 +3. N/A(安全横切,非付费面)。 + +--- + +## 3. 用户角色 + +Visitor / User / Admin 凡提交自由文字均适用(Admin 运营文案可后续加强;本 Spec **先 C 端用户 API**)。 + +--- + +## 4. 用户流程 + +```text +用户输入文字 →(可选)前端即时校验 + → API Handler/Service 调用 textsafe.Check(kind, text) + → OK:规范化后入库/进模型 + → 拒绝:HTTP 400 · code 40060 · message 可读原因 +``` + +--- + +## 5–6. 页面 / 状态 + +各既有表单;Error 态展示 `message`。无新页面。 + +--- + +## 7. Business Rules + +| ID | Rule | +|---|---| +| R1 | **后端必须校验**所有用户自由文字;前端校验不得替代后端 | +| R2 | 种类与上限(rune):`nickname` 1–16;`display_name` 1–24;`ask_content` 1–2000;`note` 0–200;`title` 1–40;`focus` 0–40;`scene` 1–80 | +| R3 | 拒绝控制字符(允许消息内 `\n` `\t`);拒绝 HTML/脚本片段(如 ` +ECR: +Phase: +Execution Context: +Allowed: <...> +Forbidden: <...> +Action: CONTINUE | STOP +Reason: <...> +``` + +- `Action: STOP` 或 `L2-BLOCKED` → **禁止**改 `apps/` / `packages/` / `proto/` / `migrations/` +- 本仓 `ess_intake: strict`(见 `docs/PROJECT_RULES.md`):Retro ECR 须四字段;新主题 OUT OF SCOPE +- Solo multi-role 允许同 Session 串行换 Phase;**同一 review turn 禁止 Approve + Modify** + ## Load order (every task) -1. `.ai/ai-contract.md` -2. `.ai/constitution.md` -3. `.ai/architecture.md` -4. `.ai/domain.md` (+ product/API tasks: `domain/domain-map.md`) -5. `.ai/forbidden.md` -6. `.ai/definition-of-done.md` — **完成标准(强制)**;Done ≠ build 通过 -7. `.ai/environment.md` + `.ai/development.md`(本地)· 部署任务再读 `deployment.md` / `docker.md` -8. `.ai/file-map.md` + `.ai/workflow.md` -9. Task rules: `.ai/coding.md` / `api.md` / `database.md` / `ui.md` / `security.md` / `testing.md` … -10. **Product scope:** `.ai/product/lexicon.md` + `feature-map.md` + **`feature-design.md`** + 对应 **`feature-spec/.md`** + `user-journey.md` + `page-tree.md` · 状态 `product/p1-status.md` -11. **Competitor parity / reverse engineering:** `.ai/design/reverse-engineering-spec.md`(强制 STEP 1–18 · Evidence First · 禁止 Demo 式省略)→ 再映射 lexicon / feature-spec -12. **Any UI work:** `.ai/design/design-system.md` + `component-catalog.md` + matching `design/platform/*.md` (H5 default) -13. Matching **ADR** in `.ai/adr/` before changing stack or API style -14. Prefer **patterns/** + **examples/** + **playbooks/**(含 `feature-spec`) over inventing structure -15. Before claiming Done: `.ai/definition-of-done.md` + `.ai/review.md` + `.ai/checklists/*` → 输出 **Review Report** -16. Verify via `.ai/commands.md`(本地默认本机 Go/Vite + compose.dev 仅 DB) -17. `prompts/` are optional helpers — not a substitute for rules above -18. **ESS process (when L2+ / architecture / release):** `docs/PROJECT_PROFILE.md` → role from `$ESS_ROOT/agents/` → `docs/ECR/` · `docs/TASKS/` · `docs/HANDOFF/`;勿把 ESS 整树复制进仓 +1. **§0 ESS Mode 块**(上)→ `docs/PROJECT_PROFILE.md` · `docs/PROJECT_RULES.md` +2. `.ai/ai-contract.md` +3. `.ai/constitution.md` +4. `.ai/architecture.md` +5. `.ai/domain.md` (+ product/API tasks: `domain/domain-map.md`) +6. `.ai/forbidden.md` +7. `.ai/definition-of-done.md` — **完成标准(强制)**;Done ≠ build 通过 +8. `.ai/environment.md` + `.ai/development.md`(本地)· 部署任务再读 `deployment.md` / `docker.md` +9. `.ai/file-map.md` + `.ai/workflow.md` +10. Task rules: `.ai/coding.md` / `api.md` / `database.md` / `ui.md` / `security.md` / `testing.md` … +11. **Product scope:** `.ai/product/lexicon.md` + `feature-map.md` + **`feature-design.md`** + 对应 **`feature-spec/.md`** + `user-journey.md` + `page-tree.md` · 状态 `product/p1-status.md` +12. **Competitor parity / reverse engineering:** `.ai/design/reverse-engineering-spec.md`(强制 STEP 1–18 · Evidence First · 禁止 Demo 式省略)→ 再映射 lexicon / feature-spec +13. **Any UI work:** `.ai/design/design-system.md` + `component-catalog.md` + matching `design/platform/*.md` (H5 default) +14. Matching **ADR** in `.ai/adr/` before changing stack or API style +15. Prefer **patterns/** + **examples/** + **playbooks/**(含 `feature-spec`) over inventing structure +16. Before claiming Done: `.ai/definition-of-done.md` + `.ai/review.md` + `.ai/checklists/*` → 输出 **Review Report** +17. Verify via `.ai/commands.md`(本地默认本机 Go/Vite + compose.dev 仅 DB) +18. `prompts/` are optional helpers — not a substitute for rules above +19. **ESS process (L2+ / architecture / release):** `$ESS_ROOT/SKILL.md` · `SESSION_BOOTSTRAP` · role from `$ESS_ROOT/agents/` → `docs/ECR/` · `docs/TASKS/` · `docs/HANDOFF/`;勿把 ESS 整树复制进仓 ## ESS dual-track | Concern | Source of truth | |---------|-----------------| | Lexicon · Feature Spec · DoD · domain · architecture freeze | `.ai/` | -| Roles · ECR · Task Contract · Handoff · validate gates | ESS + `docs/` | +| Intake Mode · Roles · ECR · Task · Handoff · validate | ESS + `docs/` | ```text Load Agent Profile: ARCHITECT | ENGINEER | REVIEWER | RELEASE_MANAGER ``` -- Cursor → ARCHITECT / REVIEWER(禁改生产实现) -- Engineer 实现前:Active Feature Spec +(L2+)Approved ECR + HANDOFF +- Cursor Session 可 Solo 串行三角色;**当前 Phase 权限唯一** +- ARCHITECT / REVIEWER phase:禁改生产实现;REVIEWER 禁 Approve+Modify 同 turn +- Engineer:Active Feature Spec +(L2+)Approved ECR + HANDOFF;无 ECR → `L2-BLOCKED` - `python scripts/ess-validate.py --phase --ecr ECR-xxx` ## Hard constraints diff --git a/apps/admin-h5/src/pages/AnalyticsPage.vue b/apps/admin-h5/src/pages/AnalyticsPage.vue index 5c3cb27..7a55185 100644 --- a/apps/admin-h5/src/pages/AnalyticsPage.vue +++ b/apps/admin-h5/src/pages/AnalyticsPage.vue @@ -65,6 +65,9 @@ function fmtMs(ms: number) { } const funnelLabel: Record = { + scale_list_viewed: '探索列表', + scale_started: '开始作答', + scale_completed: '量表完成', portrait_completed: '画像完成', deep_access_clicked: '深度 CTA', purchase_completed: '支付成功', diff --git a/apps/api/internal/avatar/store.go b/apps/api/internal/avatar/store.go new file mode 100644 index 0000000..0342e50 --- /dev/null +++ b/apps/api/internal/avatar/store.go @@ -0,0 +1,119 @@ +// Package avatar stores and serves user profile photos. +package avatar + +import ( + "errors" + "fmt" + "io" + "mime/multipart" + "os" + "path/filepath" + "strings" + + "github.com/google/uuid" +) + +const MaxBytes = 2 << 20 // 2 MiB + +var ( + ErrTooLarge = errors.New("图片过大,请选择 2MB 以内") + ErrBadType = errors.New("仅支持 JPG / PNG / WebP") + ErrEmpty = errors.New("请选择图片") + ErrBadName = errors.New("无效头像") +) + +// Store writes multipart image under dir as {userID}{ext}; returns public API path. +func Store(dir string, userID uuid.UUID, fh *multipart.FileHeader) (publicPath string, err error) { + if fh == nil || fh.Size <= 0 { + return "", ErrEmpty + } + if fh.Size > MaxBytes { + return "", ErrTooLarge + } + ext, err := extFor(fh.Filename, fh.Header.Get("Content-Type")) + if err != nil { + return "", err + } + if err := os.MkdirAll(dir, 0o755); err != nil { + return "", err + } + src, err := fh.Open() + if err != nil { + return "", err + } + defer src.Close() + + name := userID.String() + ext + dstPath := filepath.Join(dir, name) + tmp := dstPath + ".tmp" + out, err := os.Create(tmp) + if err != nil { + return "", err + } + n, copyErr := io.Copy(out, io.LimitReader(src, MaxBytes+1)) + _ = out.Close() + if copyErr != nil { + _ = os.Remove(tmp) + return "", copyErr + } + if n > MaxBytes { + _ = os.Remove(tmp) + return "", ErrTooLarge + } + // remove previous extensions for same user + for _, old := range []string{".jpg", ".jpeg", ".png", ".webp"} { + p := filepath.Join(dir, userID.String()+old) + if p != dstPath { + _ = os.Remove(p) + } + } + if err := os.Rename(tmp, dstPath); err != nil { + _ = os.Remove(tmp) + return "", err + } + return "/api/v1/media/avatars/" + name, nil +} + +// ResolveAbs validates file name and returns absolute path under dir. +func ResolveAbs(dir, name string) (string, error) { + base := filepath.Base(name) + if base != name || strings.Contains(base, "..") { + return "", ErrBadName + } + ext := strings.ToLower(filepath.Ext(base)) + if ext != ".jpg" && ext != ".jpeg" && ext != ".png" && ext != ".webp" { + return "", ErrBadName + } + idPart := strings.TrimSuffix(base, ext) + if _, err := uuid.Parse(idPart); err != nil { + return "", ErrBadName + } + full := filepath.Join(dir, base) + if _, err := os.Stat(full); err != nil { + return "", ErrBadName + } + return full, nil +} + +func extFor(filename, contentType string) (string, error) { + ct := strings.ToLower(contentType) + switch { + case strings.Contains(ct, "jpeg"), strings.Contains(ct, "jpg"): + return ".jpg", nil + case strings.Contains(ct, "png"): + return ".png", nil + case strings.Contains(ct, "webp"): + return ".webp", nil + } + ext := strings.ToLower(filepath.Ext(filename)) + switch ext { + case ".jpg", ".jpeg": + return ".jpg", nil + case ".png": + return ".png", nil + case ".webp": + return ".webp", nil + default: + return "", fmt.Errorf("%w", ErrBadType) + } +} diff --git a/apps/api/internal/avatar/store_test.go b/apps/api/internal/avatar/store_test.go new file mode 100644 index 0000000..7e9d108 --- /dev/null +++ b/apps/api/internal/avatar/store_test.go @@ -0,0 +1,112 @@ +package avatar + +import ( + "bytes" + "mime/multipart" + "net/textproto" + "os" + "path/filepath" + "testing" + + "github.com/google/uuid" +) + +func TestResolveAbsRejectsTraversal(t *testing.T) { + dir := t.TempDir() + id := uuid.New() + name := id.String() + ".jpg" + if err := os.WriteFile(filepath.Join(dir, name), []byte("x"), 0o644); err != nil { + t.Fatal(err) + } + if _, err := ResolveAbs(dir, "../"+name); err == nil { + t.Fatal("expected reject ..") + } + if _, err := ResolveAbs(dir, "not-a-uuid.jpg"); err == nil { + t.Fatal("expected reject bad id") + } + if _, err := ResolveAbs(dir, id.String()+".gif"); err == nil { + t.Fatal("expected reject gif") + } + full, err := ResolveAbs(dir, name) + if err != nil { + t.Fatal(err) + } + if filepath.Base(full) != name { + t.Fatalf("full=%s", full) + } +} + +func TestStoreRejectsBadTypeAndSize(t *testing.T) { + dir := t.TempDir() + uid := uuid.New() + + fhExe := mustFormFile(t, "x.exe", "application/octet-stream", []byte("MZ")) + if _, err := Store(dir, uid, fhExe); err == nil { + t.Fatal("expected bad type") + } + + big := bytes.Repeat([]byte("a"), MaxBytes+10) + fhBig := mustFormFile(t, "big.jpg", "image/jpeg", big) + if _, err := Store(dir, uid, fhBig); err == nil { + t.Fatal("expected too large") + } +} + +func TestStoreOKAndOverwrite(t *testing.T) { + dir := t.TempDir() + uid := uuid.New() + fh := mustFormFile(t, "a.png", "image/png", []byte{0x89, 0x50, 0x4e, 0x47}) + path, err := Store(dir, uid, fh) + if err != nil { + t.Fatal(err) + } + want := "/api/v1/media/avatars/" + uid.String() + ".png" + if path != want { + t.Fatalf("path=%s want=%s", path, want) + } + if _, err := os.Stat(filepath.Join(dir, uid.String()+".png")); err != nil { + t.Fatal(err) + } + + fh2 := mustFormFile(t, "b.jpg", "image/jpeg", []byte{0xff, 0xd8, 0xff}) + path2, err := Store(dir, uid, fh2) + if err != nil { + t.Fatal(err) + } + if path2 != "/api/v1/media/avatars/"+uid.String()+".jpg" { + t.Fatalf("path2=%s", path2) + } + if _, err := os.Stat(filepath.Join(dir, uid.String()+".png")); !os.IsNotExist(err) { + t.Fatal("old png should be removed") + } +} + +func mustFormFile(t *testing.T, filename, contentType string, data []byte) *multipart.FileHeader { + t.Helper() + var buf bytes.Buffer + w := multipart.NewWriter(&buf) + h := make(textproto.MIMEHeader) + h.Set("Content-Disposition", `form-data; name="file"; filename="`+filename+`"`) + h.Set("Content-Type", contentType) + part, err := w.CreatePart(h) + if err != nil { + t.Fatal(err) + } + if _, err := part.Write(data); err != nil { + t.Fatal(err) + } + if err := w.Close(); err != nil { + t.Fatal(err) + } + r := multipart.NewReader(&buf, w.Boundary()) + form, err := r.ReadForm(int64(len(data)) + 1024) + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { _ = form.RemoveAll() }) + files := form.File["file"] + if len(files) == 0 { + t.Fatal("no file part") + } + return files[0] +} diff --git a/apps/api/internal/explore/catalog.go b/apps/api/internal/explore/catalog.go index 196a65c..7399728 100644 --- a/apps/api/internal/explore/catalog.go +++ b/apps/api/internal/explore/catalog.go @@ -1,6 +1,8 @@ // Package explore provides the L1→L3 explore catalog. package explore +import "github.com/yuxingu/digital-psychology/apps/api/internal/repository" + // Item is a leaf tool in the catalog. type Item struct { Key string `json:"key"` @@ -22,8 +24,8 @@ type Category struct { Items []Item `json:"items"` } -// Catalog returns the full explore tree (deterministic, no DB). -// Order: 四核心优先,量表后置。 +// Catalog returns the full explore tree (deterministic base; tests filled by WithPublishedScales). +// Order: 解码 → 量表题库 → 星座 / 匹配 / 节律 … func Catalog() []Category { return []Category{ { @@ -33,6 +35,11 @@ func Catalog() []Category { {Key: "portrait", Title: "愈心解码", Description: "生日生成性格解码报告", Path: "/portrait", Icon: "△", Tone: "gold", Badge: "热"}, }, }, + { + Key: "tests", Title: "量表题库", Description: "人格与偏好测评(已发布)", + Icon: "◆", Tone: "blue", + Items: defaultScaleItems(), + }, { Key: "star", Title: "星座", Description: "排盘 · 运势 · 合盘", Icon: "✦", Tone: "night", @@ -72,24 +79,56 @@ func Catalog() []Category { {Key: "ask", Title: "AI 成长助手", Description: "结合档案整理感受", Path: "/ask", Icon: "◎", Tone: "gold"}, }, }, - { - Key: "tests", Title: "更多测评", Description: "轻量量表(次要入口)", - Icon: "◆", Tone: "blue", - Items: []Item{ - {Key: "mbti-lite", Title: "人格类型探索", Description: "能量与决策偏好(轻量)", Path: "/scales/mbti-lite", Icon: "◆", Tone: "blue"}, - {Key: "enneagram-lite", Title: "动机模式探索", Description: "内在动机九型向轻测", Path: "/scales/enneagram-lite", Icon: "⑨", Tone: "purple"}, - {Key: "bigfive-lite", Title: "性格五维探索", Description: "稳定特质速览", Path: "/scales/bigfive-lite", Icon: "◈", Tone: "teal"}, - {Key: "love-style", Title: "亲密互动探索", Description: "亲密关系中的互动偏好", Path: "/scales/love-style", Icon: "♡", Tone: "rose"}, - {Key: "eq-lite", Title: "情绪觉察探索", Description: "识别与调节情绪的习惯", Path: "/scales/eq-lite", Icon: "♥", Tone: "pink"}, - {Key: "stress-index", Title: "压力负荷探索", Description: "近期压力与恢复方式", Path: "/scales/stress-index", Icon: "☯", Tone: "green"}, - {Key: "career-interest", Title: "职业兴趣探索", Description: "工作动力与环境偏好", Path: "/scales/career-interest", Icon: "◎", Tone: "gold"}, - {Key: "communication-style", Title: "沟通方式探索", Description: "表达与倾听偏好", Path: "/scales/communication-style", Icon: "◆", Tone: "blue"}, - {Key: "emotion-pattern", Title: "情绪模式探索", Description: "情绪起伏与自我照顾", Path: "/scales/emotion-pattern", Icon: "♥", Tone: "pink"}, - }, - }, } } +func defaultScaleItems() []Item { + return []Item{ + {Key: "mbti-lite", Title: "MBTI测试", Description: "标准版 32 题免费 · 完整版会员", Path: "/scales/mbti-lite", Icon: "◆", Tone: "blue", Badge: "热"}, + {Key: "mbti-full", Title: "MBTI完整版", Description: "60 题 · 成长会员", Path: "/scales/mbti-full", Icon: "◆", Tone: "gold"}, + {Key: "enneagram-lite", Title: "动机模式探索", Description: "内在动机九型向轻测", Path: "/scales/enneagram-lite", Icon: "⑨", Tone: "purple"}, + {Key: "bigfive-lite", Title: "性格五维探索", Description: "稳定特质速览", Path: "/scales/bigfive-lite", Icon: "◈", Tone: "teal"}, + {Key: "love-style", Title: "亲密互动探索", Description: "亲密关系中的互动偏好", Path: "/scales/love-style", Icon: "♡", Tone: "rose"}, + {Key: "eq-lite", Title: "情绪觉察探索", Description: "识别与调节情绪的习惯", Path: "/scales/eq-lite", Icon: "♥", Tone: "pink"}, + {Key: "stress-index", Title: "压力负荷探索", Description: "近期压力与恢复方式", Path: "/scales/stress-index", Icon: "☯", Tone: "green"}, + {Key: "career-interest", Title: "职业兴趣探索", Description: "工作动力与环境偏好", Path: "/scales/career-interest", Icon: "◎", Tone: "gold"}, + {Key: "communication-style", Title: "沟通方式探索", Description: "表达与倾听偏好", Path: "/scales/communication-style", Icon: "◆", Tone: "blue"}, + {Key: "emotion-pattern", Title: "情绪模式探索", Description: "情绪起伏与自我照顾", Path: "/scales/emotion-pattern", Icon: "♥", Tone: "pink"}, + } +} + +// WithPublishedScales replaces the 量表题库 items with live published scales from DB. +func WithPublishedScales(cats []Category, scales []repository.ScaleListItem) []Category { + if len(scales) == 0 { + return cats + } + items := make([]Item, 0, len(scales)) + for _, s := range scales { + badge := "" + tone := "blue" + switch s.Slug { + case "mbti-lite": + badge = "热" + case "mbti-full": + tone = "gold" + } + items = append(items, Item{ + Key: s.Slug, Title: s.Title, Description: s.Description, + Path: "/scales/" + s.Slug, Icon: "◆", Tone: tone, Badge: badge, + }) + } + out := make([]Category, len(cats)) + copy(out, cats) + for i := range out { + if out[i].Key == "tests" { + out[i].Title = "量表题库" + out[i].Description = "人格与偏好测评(已发布)" + out[i].Items = items + } + } + return out +} + // CategoryByKey returns one category or nil. func CategoryByKey(key string) *Category { for _, c := range Catalog() { diff --git a/apps/api/internal/explore/catalog_test.go b/apps/api/internal/explore/catalog_test.go index cf11824..6847471 100644 --- a/apps/api/internal/explore/catalog_test.go +++ b/apps/api/internal/explore/catalog_test.go @@ -1,58 +1,38 @@ package explore import ( - "strings" "testing" + + "github.com/yuxingu/digital-psychology/apps/api/internal/repository" ) -func TestCatalogShape(t *testing.T) { +func TestCatalogHasScaleBankNearTop(t *testing.T) { cats := Catalog() - if len(cats) < 6 { - t.Fatalf("want ≥6 L1 categories, got %d", len(cats)) + if len(cats) < 2 { + t.Fatal("expected categories") } - keys := map[string]bool{} - for _, c := range cats { - keys[c.Key] = true - if len(c.Items) < 1 { - t.Fatalf("category %s empty", c.Key) - } - for _, it := range c.Items { - if it.Path == "" || !strings.HasPrefix(it.Path, "/") { - t.Fatalf("bad path %#v", it) - } - } + if cats[1].Key != "tests" || cats[1].Title != "量表题库" { + t.Fatalf("second cat=%#v want 量表题库", cats[1]) } - for _, k := range []string{"decode", "star", "relation", "tests", "rhythm", "cards", "growth"} { - if !keys[k] { - t.Fatalf("missing category %s", k) - } - } - // 四核心应排在量表之前 - if indexOf(cats, "tests") < indexOf(cats, "star") { - t.Fatal("tests should come after star") + if len(cats[1].Items) < 5 { + t.Fatalf("expected scale items, got %d", len(cats[1].Items)) } } -func indexOf(cats []Category, key string) int { - for i, c := range cats { - if c.Key == key { - return i - } +func TestWithPublishedScalesReplacesItems(t *testing.T) { + cats := Catalog() + out := WithPublishedScales(cats, nil) + if len(out[1].Items) < 5 { + t.Fatal("nil scales should keep defaults") } - return -1 -} - -func TestLexiconHardBanOnly(t *testing.T) { - blob := "" - for _, c := range Catalog() { - blob += c.Title + c.Description - for _, it := range c.Items { - blob += it.Title + it.Description - } + out = WithPublishedScales(cats, []repository.ScaleListItem{ + {Slug: "mbti-lite", Title: "MBTI测试", Description: "from-db"}, + {Slug: "eq-lite", Title: "情绪觉察探索", Description: "eq"}, + }) + if len(out[1].Items) != 2 { + t.Fatalf("items=%d", len(out[1].Items)) } - for _, bad := range []string{"占卜", "算命", "测测"} { - if strings.Contains(blob, bad) { - t.Fatalf("forbidden %q", bad) - } + if out[1].Items[0].Description != "from-db" || out[1].Items[0].Badge != "热" { + t.Fatalf("unexpected %#v", out[1].Items[0]) } } diff --git a/apps/api/internal/handler/ask.go b/apps/api/internal/handler/ask.go index f69e4f1..a68a583 100644 --- a/apps/api/internal/handler/ask.go +++ b/apps/api/internal/handler/ask.go @@ -2,6 +2,7 @@ package handler import ( "encoding/json" + "errors" "fmt" "net/http" "strings" @@ -11,6 +12,7 @@ import ( "github.com/yuxingu/digital-psychology/apps/api/internal/middleware" asksvc "github.com/yuxingu/digital-psychology/apps/api/internal/service/ask" + "github.com/yuxingu/digital-psychology/apps/api/internal/textsafe" "github.com/yuxingu/digital-psychology/apps/api/pkg/response" ) @@ -67,6 +69,9 @@ func (h *AskHandler) CreateThread(c *gin.Context) { ProfileID: pid, Scene: req.Scene, }) if err != nil { + if failTextCompliance(c, err) { + return + } response.Fail(c, http.StatusBadRequest, 40010, err.Error()) return } @@ -142,6 +147,9 @@ func (h *AskHandler) SendMessage(c *gin.Context) { out, err := h.Svc.SendMessage(c.Request.Context(), userID, tid, req.Content) if err != nil { + if failTextCompliance(c, err) { + return + } if asksvc.IsQuotaExhausted(err) { response.Fail(c, http.StatusPaymentRequired, 40210, "问答次数已用完,可购买额度或开通成长会员") return @@ -180,7 +188,9 @@ func (h *AskHandler) sendMessageStream(c *gin.Context, userID, tid uuid.UUID, co if err != nil { msg := err.Error() code := 40011 - if asksvc.IsQuotaExhausted(err) { + if errors.Is(err, textsafe.ErrRejected) { + code = 40060 + } else if asksvc.IsQuotaExhausted(err) { msg = "问答次数已用完,可购买额度或开通成长会员" code = 40210 } diff --git a/apps/api/internal/handler/auth.go b/apps/api/internal/handler/auth.go index 660ba4f..2ca324d 100644 --- a/apps/api/internal/handler/auth.go +++ b/apps/api/internal/handler/auth.go @@ -24,6 +24,7 @@ func (h *AuthHandler) Register(api *gin.RouterGroup) { g.POST("/logout", h.Logout) g.GET("/me", h.Me) g.PATCH("/me", h.PatchMe) + g.POST("/me/avatar", h.UploadAvatar) } type authBody struct { @@ -47,6 +48,9 @@ func (h *AuthHandler) RegisterAccount(c *gin.Context) { deviceKey := c.GetHeader(middleware.DeviceKeyHeader) res, err := h.Svc.Register(c.Request.Context(), userID, deviceKey, body.Phone, body.Password, body.Nickname) if err != nil { + if failTextCompliance(c, err) { + return + } response.Fail(c, http.StatusBadRequest, 40110, err.Error()) return } @@ -116,12 +120,35 @@ func (h *AuthHandler) PatchMe(c *gin.Context) { } me, err := h.Svc.UpdateNickname(c.Request.Context(), userID, body.Nickname) if err != nil { + if failTextCompliance(c, err) { + return + } response.Fail(c, http.StatusBadRequest, 40113, err.Error()) return } response.OK(c, me) } +// UploadAvatar handles POST /auth/me/avatar (multipart file). +func (h *AuthHandler) UploadAvatar(c *gin.Context) { + userID, ok := middleware.UserIDFromContext(c) + if !ok { + response.Fail(c, http.StatusUnauthorized, 40100, "unauthorized") + return + } + fh, err := c.FormFile("file") + if err != nil { + response.Fail(c, http.StatusBadRequest, 10000, "请选择图片") + return + } + me, err := h.Svc.UpdateAvatar(c.Request.Context(), userID, fh) + if err != nil { + response.Fail(c, http.StatusBadRequest, 40114, err.Error()) + return + } + response.OK(c, me) +} + func bearerToken(c *gin.Context) string { h := c.GetHeader("Authorization") if strings.HasPrefix(strings.ToLower(h), "bearer ") { diff --git a/apps/api/internal/handler/companion.go b/apps/api/internal/handler/companion.go index f12e699..0f9785d 100644 --- a/apps/api/internal/handler/companion.go +++ b/apps/api/internal/handler/companion.go @@ -55,6 +55,9 @@ func (h *CompanionHandler) SaveMood(c *gin.Context) { } m, err := h.Svc.SaveMood(c.Request.Context(), userID, in) if err != nil { + if failTextCompliance(c, err) { + return + } response.Fail(c, http.StatusBadRequest, 30010, err.Error()) return } diff --git a/apps/api/internal/handler/explore.go b/apps/api/internal/handler/explore.go index c625d71..8edf8a4 100644 --- a/apps/api/internal/handler/explore.go +++ b/apps/api/internal/handler/explore.go @@ -6,11 +6,14 @@ import ( "github.com/gin-gonic/gin" "github.com/yuxingu/digital-psychology/apps/api/internal/explore" + "github.com/yuxingu/digital-psychology/apps/api/internal/service/scale" "github.com/yuxingu/digital-psychology/apps/api/pkg/response" ) // ExploreHandler serves the explore catalog. -type ExploreHandler struct{} +type ExploreHandler struct { + Scales *scale.Service +} // Register mounts explore routes. func (h *ExploreHandler) Register(rg *gin.RouterGroup) { @@ -20,7 +23,13 @@ func (h *ExploreHandler) Register(rg *gin.RouterGroup) { // Catalog handles GET /explore/catalog. func (h *ExploreHandler) Catalog(c *gin.Context) { - response.OK(c, gin.H{"categories": explore.Catalog()}) + cats := explore.Catalog() + if h.Scales != nil { + if items, err := h.Scales.List(c.Request.Context()); err == nil { + cats = explore.WithPublishedScales(cats, items) + } + } + response.OK(c, gin.H{"categories": cats}) } // Category handles GET /explore/catalog/:key. @@ -30,5 +39,14 @@ func (h *ExploreHandler) Category(c *gin.Context) { response.Fail(c, http.StatusNotFound, 40402, "category not found") return } + if cat.Key == "tests" && h.Scales != nil { + if items, err := h.Scales.List(c.Request.Context()); err == nil { + enriched := explore.WithPublishedScales([]explore.Category{*cat}, items) + if len(enriched) > 0 { + response.OK(c, enriched[0]) + return + } + } + } response.OK(c, cat) } diff --git a/apps/api/internal/handler/growth.go b/apps/api/internal/handler/growth.go index 147a34b..dfb5b6b 100644 --- a/apps/api/internal/handler/growth.go +++ b/apps/api/internal/handler/growth.go @@ -2,7 +2,6 @@ package handler import ( "net/http" - "strings" "time" "github.com/gin-gonic/gin" @@ -10,6 +9,7 @@ import ( "github.com/yuxingu/digital-psychology/apps/api/internal/middleware" "github.com/yuxingu/digital-psychology/apps/api/internal/repository" + "github.com/yuxingu/digital-psychology/apps/api/internal/textsafe" "github.com/yuxingu/digital-psychology/apps/api/pkg/response" ) @@ -57,12 +57,17 @@ func (h *GrowthHandler) CreatePlan(c *gin.Context) { response.Fail(c, http.StatusBadRequest, 10000, "invalid request") return } - title := strings.TrimSpace(req.Title) - if title == "" || len([]rune(title)) > 40 { - response.Fail(c, http.StatusBadRequest, 10000, "invalid title") + title, err := textsafe.Check(textsafe.Title, req.Title) + if err != nil { + _ = failTextCompliance(c, err) return } - p, err := h.Plans.CreatePlan(c.Request.Context(), userID, title, strings.TrimSpace(req.Focus)) + focus, err := textsafe.Check(textsafe.Focus, req.Focus) + if err != nil { + _ = failTextCompliance(c, err) + return + } + p, err := h.Plans.CreatePlan(c.Request.Context(), userID, title, focus) if err != nil { response.Fail(c, http.StatusBadRequest, 30020, err.Error()) return @@ -86,6 +91,18 @@ func (h *GrowthHandler) Checkin(c *gin.Context) { Note *string `json:"note"` } _ = c.ShouldBindJSON(&req) + if req.Note != nil { + n, err := textsafe.Check(textsafe.Note, *req.Note) + if err != nil { + _ = failTextCompliance(c, err) + return + } + if n == "" { + req.Note = nil + } else { + req.Note = &n + } + } out, err := h.Plans.Checkin(c.Request.Context(), userID, pid, time.Now(), req.Note) if err != nil { response.Fail(c, http.StatusBadRequest, 30021, err.Error()) diff --git a/apps/api/internal/handler/media.go b/apps/api/internal/handler/media.go new file mode 100644 index 0000000..3ac9196 --- /dev/null +++ b/apps/api/internal/handler/media.go @@ -0,0 +1,36 @@ +package handler + +import ( + "net/http" + "path/filepath" + + "github.com/gin-gonic/gin" + + "github.com/yuxingu/digital-psychology/apps/api/internal/avatar" +) + +// MediaHandler serves uploaded media files. +type MediaHandler struct { + AvatarDir string +} + +// Register mounts public media routes. +func (h *MediaHandler) Register(api *gin.RouterGroup) { + api.GET("/media/avatars/:file", h.ServeAvatar) +} + +// ServeAvatar streams a stored avatar image. +func (h *MediaHandler) ServeAvatar(c *gin.Context) { + dir := h.AvatarDir + if dir == "" { + dir = "data/avatars" + } + full, err := avatar.ResolveAbs(dir, c.Param("file")) + if err != nil { + c.Status(http.StatusNotFound) + return + } + c.Header("Cache-Control", "public, max-age=86400") + c.File(full) + _ = filepath.Ext(full) +} diff --git a/apps/api/internal/handler/profile.go b/apps/api/internal/handler/profile.go index 6f6d1ac..5c7757f 100644 --- a/apps/api/internal/handler/profile.go +++ b/apps/api/internal/handler/profile.go @@ -57,6 +57,9 @@ func (h *ProfileHandler) Create(c *gin.Context) { RelationType: req.RelationType, BirthTime: req.BirthTime, BirthPlace: req.BirthPlace, }) if err != nil { + if failTextCompliance(c, err) { + return + } if errors.Is(err, profile.ErrSelfExists) { response.Fail(c, http.StatusConflict, 40902, err.Error()) return @@ -122,6 +125,9 @@ func (h *ProfileHandler) Update(c *gin.Context) { GeoLat: req.GeoLat, GeoLng: req.GeoLng, GeoVisible: req.GeoVisible, }) if err != nil { + if failTextCompliance(c, err) { + return + } response.Fail(c, http.StatusNotFound, 40401, err.Error()) return } diff --git a/apps/api/internal/handler/scale.go b/apps/api/internal/handler/scale.go index 15ff862..f58d505 100644 --- a/apps/api/internal/handler/scale.go +++ b/apps/api/internal/handler/scale.go @@ -1,6 +1,7 @@ package handler import ( + "errors" "net/http" "github.com/gin-gonic/gin" @@ -19,10 +20,33 @@ type ScaleHandler struct { // Register mounts routes. func (h *ScaleHandler) Register(rg *gin.RouterGroup) { rg.GET("/scales", h.List) + rg.GET("/scale-bank/catalog", h.BankCatalog) + rg.GET("/scale-bank/categories/:key", h.BankCategory) rg.GET("/scales/:slug", h.Get) + rg.GET("/scales/:slug/result", h.LatestResult) rg.POST("/scales/:slug/result", h.Submit) } +// BankCatalog handles GET /scale-bank/catalog. +func (h *ScaleHandler) BankCatalog(c *gin.Context) { + out, err := h.Svc.BankCatalog() + if err != nil { + response.Fail(c, http.StatusInternalServerError, 50003, "bank catalog failed") + return + } + response.OK(c, out) +} + +// BankCategory handles GET /scale-bank/categories/:key. +func (h *ScaleHandler) BankCategory(c *gin.Context) { + cat, items, err := h.Svc.BankCategory(c.Param("key")) + if err != nil { + response.Fail(c, http.StatusNotFound, 40402, "category not found") + return + } + response.OK(c, gin.H{"category": cat, "items": items}) +} + // List handles GET /scales. func (h *ScaleHandler) List(c *gin.Context) { items, err := h.Svc.List(c.Request.Context()) @@ -35,7 +59,8 @@ func (h *ScaleHandler) List(c *gin.Context) { // Get handles GET /scales/:slug. func (h *ScaleHandler) Get(c *gin.Context) { - d, err := h.Svc.Get(c.Request.Context(), c.Param("slug")) + userID, _ := middleware.UserIDFromContext(c) + d, err := h.Svc.Get(c.Request.Context(), userID, c.Param("slug")) if err != nil { response.Fail(c, http.StatusNotFound, 40402, err.Error()) return @@ -43,6 +68,25 @@ func (h *ScaleHandler) Get(c *gin.Context) { response.OK(c, d) } +// LatestResult handles GET /scales/:slug/result. +func (h *ScaleHandler) LatestResult(c *gin.Context) { + userID, ok := middleware.UserIDFromContext(c) + if !ok { + response.Fail(c, http.StatusUnauthorized, 40100, "unauthorized") + return + } + out, err := h.Svc.LatestResult(c.Request.Context(), userID, c.Param("slug")) + if err != nil { + if err.Error() == "scale not found" { + response.Fail(c, http.StatusNotFound, 40402, err.Error()) + return + } + response.Fail(c, http.StatusNotFound, 40411, "result not found") + return + } + response.OK(c, out) +} + // Submit handles POST /scales/:slug/result. func (h *ScaleHandler) Submit(c *gin.Context) { userID, ok := middleware.UserIDFromContext(c) @@ -67,6 +111,10 @@ func (h *ScaleHandler) Submit(c *gin.Context) { ProfileID: pid, Answers: req.Answers, }) if err != nil { + if errors.Is(err, scale.ErrMembershipRequired) { + response.Fail(c, http.StatusForbidden, 40310, "需要成长会员") + return + } response.Fail(c, http.StatusBadRequest, 30006, err.Error()) return } diff --git a/apps/api/internal/handler/synastry.go b/apps/api/internal/handler/synastry.go index 23a3771..21deeb7 100644 --- a/apps/api/internal/handler/synastry.go +++ b/apps/api/internal/handler/synastry.go @@ -116,6 +116,9 @@ func (h *SynastryHandler) AcceptInvite(c *gin.Context) { } rep, err := h.Svc.AcceptInvite(c.Request.Context(), userID, c.Param("token"), req.DisplayName, req.BirthDate, req.BirthTime, req.BirthPlace) if err != nil { + if failTextCompliance(c, err) { + return + } response.Fail(c, http.StatusBadRequest, 30002, err.Error()) return } diff --git a/apps/api/internal/handler/text_fail.go b/apps/api/internal/handler/text_fail.go new file mode 100644 index 0000000..8167586 --- /dev/null +++ b/apps/api/internal/handler/text_fail.go @@ -0,0 +1,23 @@ +package handler + +import ( + "errors" + "net/http" + + "github.com/gin-gonic/gin" + + "github.com/yuxingu/digital-psychology/apps/api/internal/textsafe" + "github.com/yuxingu/digital-psychology/apps/api/pkg/response" +) + +// failTextCompliance maps textsafe rejections to HTTP 400 / code 40060. +func failTextCompliance(c *gin.Context, err error) bool { + if err == nil { + return false + } + if errors.Is(err, textsafe.ErrRejected) { + response.Fail(c, http.StatusBadRequest, 40060, err.Error()) + return true + } + return false +} diff --git a/apps/api/internal/httpserver/router.go b/apps/api/internal/httpserver/router.go index c0d2634..aa3416f 100644 --- a/apps/api/internal/httpserver/router.go +++ b/apps/api/internal/httpserver/router.go @@ -54,7 +54,7 @@ func NewRouter(pool *pgxpool.Pool, cfg config.Config) *gin.Engine { membershipSvc := &membership.Service{Reports: reportRepo} relationSvc := &relation.Service{Profiles: profileRepo, Reports: reportRepo, Relations: relationRepo} scaleRepo := &repository.ScaleRepo{Pool: pool} - scaleSvc := &scale.Service{Repo: scaleRepo, Profiles: profileRepo} + scaleSvc := &scale.Service{Repo: scaleRepo, Profiles: profileRepo, Membership: membershipSvc} askSvc := &ask.Service{Profiles: profileRepo, Reports: reportRepo, Ask: askRepo, LLM: llm} companionSvc := &companionsvc.Service{Moods: &repository.MoodRepo{Pool: pool}} imageCardSvc := &imagecardsvc.Service{ @@ -64,6 +64,7 @@ func NewRouter(pool *pgxpool.Pool, cfg config.Config) *gin.Engine { } homeSvc := &homesvc.Service{ Repo: &repository.HomeToolsRepo{Pool: pool}, + Tips: &repository.HomeDailyTipsRepo{Pool: pool}, Profiles: profileRepo, LLM: llm, } @@ -71,7 +72,7 @@ func NewRouter(pool *pgxpool.Pool, cfg config.Config) *gin.Engine { adminSvc := &adminsvc.Service{ Repo: adminRepo, Reports: reportRepo, Home: homeSvc, Scales: scaleRepo, } - authSvc := &authsvc.Service{Repo: authRepo} + authSvc := &authsvc.Service{Repo: authRepo, AvatarDir: "data/avatars"} if err := adminSvc.EnsureBootstrap(context.Background(), adminsvc.BootstrapConfig{ Username: cfg.Admin.BootstrapUsername, Password: cfg.Admin.BootstrapPassword, @@ -91,6 +92,7 @@ func NewRouter(pool *pgxpool.Pool, cfg config.Config) *gin.Engine { api.GET("/ping", func(c *gin.Context) { response.OK(c, gin.H{"pong": true}) }) + (&handler.MediaHandler{AvatarDir: "data/avatars"}).Register(api) (&handler.AdminHandler{Svc: adminSvc, Analytics: analyticsSvc}).Register(api) authed := api.Group("") @@ -109,7 +111,7 @@ func NewRouter(pool *pgxpool.Pool, cfg config.Config) *gin.Engine { (&handler.AskHandler{Svc: askSvc}).Register(gated) (&handler.CompanionHandler{Svc: companionSvc}).Register(gated) (&handler.ImageCardHandler{Svc: imageCardSvc}).Register(gated) - (&handler.ExploreHandler{}).Register(gated) + (&handler.ExploreHandler{Scales: scaleSvc}).Register(gated) (&handler.GrowthHandler{ Plans: &repository.GrowthRepo{Pool: pool}, }).Register(gated) diff --git a/apps/api/internal/integration/explore_catalog_test.go b/apps/api/internal/integration/explore_catalog_test.go index ed06b5f..55fecdd 100644 --- a/apps/api/internal/integration/explore_catalog_test.go +++ b/apps/api/internal/integration/explore_catalog_test.go @@ -43,3 +43,49 @@ func TestGrowthPlanCheckin(t *testing.T) { t.Fatal("expected checkin") } } + +func TestScaleBankResultRoundtrip(t *testing.T) { + r, _ := setupAPI(t) + key := mustRegister(t, r) + + env, key := doJSON(t, r, http.MethodGet, "/api/v1/scale-bank/catalog", nil, key) + cat := decodeData[map[string]any](t, env.Data) + featured, _ := cat["featured"].([]any) + if len(featured) < 1 { + t.Fatal("expected featured bank scales") + } + + env, key = doJSON(t, r, http.MethodPost, "/api/v1/profiles", map[string]any{ + "relation": "self", "birth_date": "1991-07-07", "display_name": "我", + }, key) + profile := decodeData[map[string]any](t, env.Data) + profileID, _ := profile["id"].(string) + + env, key = doJSON(t, r, http.MethodGet, "/api/v1/scales/sm1", nil, key) + detail := decodeData[map[string]any](t, env.Data) + qs, _ := detail["questions"].([]any) + if len(qs) < 1 { + t.Fatal("expected sm1 questions") + } + answers := map[string]string{} + for _, raw := range qs { + q, _ := raw.(map[string]any) + id, _ := q["id"].(string) + answers[id] = "3" + } + + env, key = doJSON(t, r, http.MethodPost, "/api/v1/scales/sm1/result", map[string]any{ + "profile_id": profileID, "answers": answers, + }, key) + submitted := decodeData[map[string]any](t, env.Data) + if submitted["result"] == nil { + t.Fatalf("missing result: %#v", submitted) + } + + env, _ = doJSON(t, r, http.MethodGet, "/api/v1/scales/sm1/result", nil, key) + latest := decodeData[map[string]any](t, env.Data) + res, ok := latest["result"].(map[string]any) + if !ok || res["label"] == nil || res["label"] == "" { + t.Fatalf("expected latest label, got %#v", latest) + } +} diff --git a/apps/api/internal/portrait/engine.go b/apps/api/internal/portrait/engine.go index 2ade9ba..3a74f5a 100644 --- a/apps/api/internal/portrait/engine.go +++ b/apps/api/internal/portrait/engine.go @@ -30,7 +30,6 @@ func Build(birth time.Time, displayName string) Output { bz := getBazi(y, int(m), d, 12) pct := calc5E(bz) strong := strongestEl(pct) - weak := weakestEl(pct) cst := constitutionByElement[strong] emo := emotionByElement[strong] @@ -68,16 +67,7 @@ func Build(birth time.Time, displayName string) Output { "lock_teaser_wuxing": "体质特征、调养要点、易感倾向、食疗与作息节律,解锁后查看完整方案。", "pattern_key": main, "pyramid": tri.PyramidMap(), - "wuxing": map[string]any{ - "bars": wuxingBars(pct), - "primary": cst.Primary, - "strong": cst.Strong, - "weak": cst.Weak, - "strong_el": strong, - "weak_el": weak, - "emotion": emo.Strength, - "care_dir": "养" + cst.Strong + " · 需呵护" + cst.Weak, - }, + "wuxing": WuxingBlock(birth), "today_tip": tip, "dimensions": dims, "strengths_preview": []string{ diff --git a/apps/api/internal/portrait/wuxing.go b/apps/api/internal/portrait/wuxing.go index eb25344..1bc9894 100644 --- a/apps/api/internal/portrait/wuxing.go +++ b/apps/api/internal/portrait/wuxing.go @@ -115,6 +115,27 @@ func wuxingBars(p map[string]int) []map[string]any { return bars } +// WuxingBlock builds the shared 五行 summary block (bars + tendency labels). +func WuxingBlock(birth time.Time) map[string]any { + y, m, d := birth.Date() + bz := getBazi(y, int(m), d, 12) + pct := calc5E(bz) + strong := strongestEl(pct) + weak := weakestEl(pct) + cst := constitutionByElement[strong] + emo := emotionByElement[strong] + return map[string]any{ + "bars": wuxingBars(pct), + "primary": cst.Primary, + "strong": cst.Strong, + "weak": cst.Weak, + "strong_el": strong, + "weak_el": weak, + "emotion": emo.Strength, + "care_dir": "养" + cst.Strong + " · 需呵护" + cst.Weak, + } +} + func todayTip(now time.Time) map[string]any { st := companion.TodaySolar(now) el := seasonEl[int(now.Month())-1] diff --git a/apps/api/internal/repository/auth_repo.go b/apps/api/internal/repository/auth_repo.go index 0f55dc5..cb466d9 100644 --- a/apps/api/internal/repository/auth_repo.go +++ b/apps/api/internal/repository/auth_repo.go @@ -21,38 +21,35 @@ type AccountRow struct { Phone string PasswordHash string Nickname string + AvatarURL string Status string } // GetByPhone loads a registered user by phone. func (r *AuthRepo) GetByPhone(ctx context.Context, phone string) (*AccountRow, error) { row := &AccountRow{} - var nick *string err := r.Pool.QueryRow(ctx, ` - SELECT id, phone, password_hash, COALESCE(nickname,''), status + SELECT id, phone, password_hash, COALESCE(nickname,''), COALESCE(avatar_url,''), status FROM users WHERE phone=$1 AND deleted_at IS NULL`, phone, - ).Scan(&row.ID, &row.Phone, &row.PasswordHash, &nick, &row.Status) + ).Scan(&row.ID, &row.Phone, &row.PasswordHash, &row.Nickname, &row.AvatarURL, &row.Status) if errors.Is(err, pgx.ErrNoRows) { return nil, err } if err != nil { return nil, err } - if nick != nil { - row.Nickname = *nick - } return row, nil } // GetAccount loads account fields for a user id. func (r *AuthRepo) GetAccount(ctx context.Context, userID uuid.UUID) (*AccountRow, error) { row := &AccountRow{} - var phone, hash, nick *string + var phone, hash *string err := r.Pool.QueryRow(ctx, ` - SELECT id, phone, password_hash, nickname, status + SELECT id, phone, password_hash, COALESCE(nickname,''), COALESCE(avatar_url,''), status FROM users WHERE id=$1 AND deleted_at IS NULL`, userID, - ).Scan(&row.ID, &phone, &hash, &nick, &row.Status) + ).Scan(&row.ID, &phone, &hash, &row.Nickname, &row.AvatarURL, &row.Status) if err != nil { return nil, err } @@ -62,9 +59,6 @@ func (r *AuthRepo) GetAccount(ctx context.Context, userID uuid.UUID) (*AccountRo if hash != nil { row.PasswordHash = *hash } - if nick != nil { - row.Nickname = *nick - } return row, nil } @@ -105,6 +99,14 @@ func (r *AuthRepo) UpdateNickname(ctx context.Context, userID uuid.UUID, nicknam return err } +// UpdateAvatarURL sets users.avatar_url. +func (r *AuthRepo) UpdateAvatarURL(ctx context.Context, userID uuid.UUID, url string) error { + _, err := r.Pool.Exec(ctx, ` + UPDATE users SET avatar_url=$2, updated_at=now() + WHERE id=$1 AND deleted_at IS NULL`, userID, url) + return err +} + // TouchPassword updates stored password hash (open-login record). func (r *AuthRepo) TouchPassword(ctx context.Context, userID uuid.UUID, hash string) error { _, err := r.Pool.Exec(ctx, ` diff --git a/apps/api/internal/repository/home_tips_repo.go b/apps/api/internal/repository/home_tips_repo.go new file mode 100644 index 0000000..aefc8bb --- /dev/null +++ b/apps/api/internal/repository/home_tips_repo.go @@ -0,0 +1,52 @@ +package repository + +import ( + "context" + "encoding/json" + "time" + + "github.com/google/uuid" + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgxpool" +) + +// HomeDailyTipsRepo persists per-时辰 homepage tips. +type HomeDailyTipsRepo struct { + Pool *pgxpool.Pool +} + +// GetTips returns cached tips JSON for user + shichen start. +func (r *HomeDailyTipsRepo) GetTips(ctx context.Context, userID uuid.UUID, start time.Time) (json.RawMessage, string, error) { + var raw json.RawMessage + var source string + err := r.Pool.QueryRow(ctx, ` + SELECT tips, source FROM home_daily_tips + WHERE user_id=$1 AND shichen_start=$2`, userID, start, + ).Scan(&raw, &source) + if err != nil { + return nil, "", err + } + return raw, source, nil +} + +// UpsertTips stores tips for user × shichen. +func (r *HomeDailyTipsRepo) UpsertTips( + ctx context.Context, + userID uuid.UUID, + start time.Time, + shichen int, + tips json.RawMessage, + source string, +) error { + _, err := r.Pool.Exec(ctx, ` + INSERT INTO home_daily_tips(user_id, shichen_start, shichen, tips, source) + VALUES ($1,$2,$3,$4,$5) + ON CONFLICT (user_id, shichen_start) DO UPDATE + SET tips=EXCLUDED.tips, source=EXCLUDED.source, shichen=EXCLUDED.shichen`, + userID, start, shichen, tips, source, + ) + return err +} + +// ErrNoTips is pgx.ErrNoRows alias for callers. +var ErrNoTips = pgx.ErrNoRows diff --git a/apps/api/internal/repository/report_repo.go b/apps/api/internal/repository/report_repo.go index 3e5fe88..3570fae 100644 --- a/apps/api/internal/repository/report_repo.go +++ b/apps/api/internal/repository/report_repo.go @@ -68,6 +68,21 @@ func (r *ReportRepo) UpsertWithPeer(ctx context.Context, userID, profileID uuid. return r.CreateWithPeer(ctx, userID, profileID, peer, typ, summary, detail) } +// UpdateContent patches summary/detail in place (keeps report id for deep access). +func (r *ReportRepo) UpdateContent(ctx context.Context, userID, reportID uuid.UUID, summary, detail json.RawMessage) error { + tag, err := r.Pool.Exec(ctx, ` + UPDATE growth_reports SET summary=$3, detail=$4, updated_at=now() + WHERE id=$1 AND user_id=$2 AND deleted_at IS NULL`, + reportID, userID, summary, detail) + if err != nil { + return err + } + if tag.RowsAffected() == 0 { + return pgx.ErrNoRows + } + return nil +} + // GetLatest returns newest non-deleted report for profile+type(+peer). func (r *ReportRepo) GetLatest(ctx context.Context, userID, profileID uuid.UUID, typ string, peer *uuid.UUID) (*model.GrowthReport, error) { rep := &model.GrowthReport{} diff --git a/apps/api/internal/repository/scale_repo.go b/apps/api/internal/repository/scale_repo.go index 491f466..1c79c60 100644 --- a/apps/api/internal/repository/scale_repo.go +++ b/apps/api/internal/repository/scale_repo.go @@ -28,6 +28,8 @@ type ScaleDetail struct { Slug string `json:"slug"` Title string `json:"title"` Description string `json:"description"` + Access string `json:"access,omitempty"` // free | membership + Locked bool `json:"locked,omitempty"` Questions []ScaleQuestion `json:"questions"` } @@ -171,6 +173,24 @@ func (r *ScaleRepo) SaveResult(ctx context.Context, userID, scaleID, profileID u return id, err } +// LatestResult returns the newest result for user + published slug. +func (r *ScaleRepo) LatestResult(ctx context.Context, userID uuid.UUID, slug string) (*ScaleResultRow, error) { + var row ScaleResultRow + err := r.Pool.QueryRow(ctx, ` + SELECT sr.id, s.slug, sr.result + FROM scale_results sr + JOIN scales s ON s.id = sr.scale_id + WHERE sr.user_id = $1 AND s.slug = $2 AND s.deleted_at IS NULL + AND sr.deleted_at IS NULL + ORDER BY sr.created_at DESC + LIMIT 1`, userID, slug, + ).Scan(&row.ID, &row.ScaleSlug, &row.Result) + if err != nil { + return nil, err + } + return &row, nil +} + // ScaleIDBySlug resolves id for a published scale. func (r *ScaleRepo) ScaleIDBySlug(ctx context.Context, slug string) (uuid.UUID, error) { var id uuid.UUID @@ -179,3 +199,20 @@ func (r *ScaleRepo) ScaleIDBySlug(ctx context.Context, slug string) (uuid.UUID, WHERE slug=$1 AND status='published' AND deleted_at IS NULL`, slug).Scan(&id) return id, err } + +// EnsurePublished upserts scale metadata (curated bank stubs; questions served from embed). +func (r *ScaleRepo) EnsurePublished(ctx context.Context, slug, title, description string) (uuid.UUID, error) { + var id uuid.UUID + err := r.Pool.QueryRow(ctx, ` + INSERT INTO scales (slug, title, description, status) + VALUES ($1,$2,$3,'published') + ON CONFLICT (slug) DO UPDATE SET + title=EXCLUDED.title, + description=EXCLUDED.description, + status='published', + updated_at=now(), + deleted_at=NULL + RETURNING id`, slug, title, description, + ).Scan(&id) + return id, err +} diff --git a/apps/api/internal/rhythm/engine.go b/apps/api/internal/rhythm/engine.go index ddc4d40..ca92182 100644 --- a/apps/api/internal/rhythm/engine.go +++ b/apps/api/internal/rhythm/engine.go @@ -4,6 +4,9 @@ package rhythm import ( "fmt" "time" + + "github.com/yuxingu/digital-psychology/apps/api/internal/companion" + "github.com/yuxingu/digital-psychology/apps/api/internal/portrait" ) // Output free summary + gated detail. @@ -14,8 +17,13 @@ type Output struct { var elements = []string{"木", "火", "土", "金", "水"} -// Build from birth date. +// Build from birth date (asOf = now). func Build(birth time.Time, displayName string) Output { + return BuildWith(birth, displayName, time.Time{}) +} + +// BuildWith anchors today/week tips to asOf (zero = now CST). +func BuildWith(birth time.Time, displayName string, asOf time.Time) Output { name := displayName if name == "" { name = "你" @@ -36,9 +44,20 @@ func Build(birth time.Time, displayName string) Output { {"key": "mood", "title": "情绪调节", "teaser": tip.Mood, "score": 71}, } - todayTip := tip.Sleep - weekday := int(time.Now().Weekday()) + when := asOf + if when.IsZero() { + when = time.Now().In(time.FixedZone("CST", 8*3600)) + } else { + when = when.In(time.FixedZone("CST", 8*3600)) + } + todayTips := []string{tip.Sleep, tip.Diet, tip.Move, tip.Mood} + todayTip := todayTips[when.YearDay()%len(todayTips)] + weekday := int(when.Weekday()) weekHints := []string{tip.Mood, tip.Move, tip.Diet, tip.Sleep, tip.WeekTip, tip.Move, tip.Mood} + dayKey := when.Format("2006-01-02") + validUntil := time.Date(when.Year(), when.Month(), when.Day()+1, 0, 0, 0, 0, when.Location()) + wx := portrait.WuxingBlock(birth) + st := companion.TodaySolar(when) summary := map[string]any{ "title": "身心节律·基础", "style_label": primary + "倾向", @@ -48,12 +67,20 @@ func Build(birth time.Time, displayName string) Output { "life_tip": tip.WeekTip, "today_tip": todayTip, "week_focus": weekHints[weekday%len(weekHints)], - "keywords": []string{primary, secondary, "生活建议", "节律"}, - "dimensions": dims, - "primary_element": primary, - "secondary_element": secondary, - "strengths_preview": tip.Strengths[:min(3, len(tip.Strengths))], - "blind_spots_preview": []string{"完整习惯方案见深度版。"}, + "as_of": dayKey, + "valid_until": validUntil.Format(time.RFC3339), + "wuxing": wx, + "solar_term": map[string]any{ + "name": st.Name, + "tip": st.Tip, + }, + "keywords": []string{primary, secondary, "生活建议", "节律"}, + "dimensions": dims, + "primary_element": primary, + "secondary_element": secondary, + "strengths_preview": tip.Strengths[:min(3, len(tip.Strengths))], + "blind_spots_preview": tip.BlindSpots[:min(3, len(tip.BlindSpots))], + "disclaimer_constitution": "体质与调养内容为生活方式参考,非医疗建议。", } detail := map[string]any{ @@ -65,8 +92,8 @@ func Build(birth time.Time, displayName string) Output { {"title": "活动与放松", "body": tip.MoveDeep, "bullets": tip.MoveBullets}, {"title": "情绪与压力", "body": tip.MoodDeep, "bullets": tip.MoodBullets}, {"title": "与节气联动", "body": "可结合「节气生活」调整当季节奏;变化慢一点,观察身体反馈即可。", "bullets": []string{"查看今日节气", "一次只改一个习惯", "不适就医,勿自行当治疗"}}, - {"title": "今日生活建议", "body": tip.Sleep + " " + tip.Mood, "bullets": []string{tip.Move, tip.Diet}}, - {"title": "本周节奏", "body": tip.WeekTip, "bullets": tip.OverviewBullets}, + {"title": "今日生活建议", "body": todayTip + " " + tip.Mood, "bullets": []string{tip.Move, tip.Diet}}, + {"title": "本周节奏", "body": weekHints[weekday%len(weekHints)], "bullets": tip.OverviewBullets}, }, "strengths": tip.Strengths, "blind_spots": tip.BlindSpots, diff --git a/apps/api/internal/rhythm/engine_test.go b/apps/api/internal/rhythm/engine_test.go index 772468a..6e13798 100644 --- a/apps/api/internal/rhythm/engine_test.go +++ b/apps/api/internal/rhythm/engine_test.go @@ -1,21 +1,36 @@ package rhythm import ( - "encoding/json" "strings" "testing" "time" ) -func TestBuild(t *testing.T) { - out := Build(time.Date(1992, 6, 8, 0, 0, 0, 0, time.UTC), "我") - if out.Summary["primary_element"] == nil { - t.Fatal("missing element") +func TestBuildIncludesWuxingBars(t *testing.T) { + birth := time.Date(1992, 6, 8, 0, 0, 0, 0, time.UTC) + out := BuildWith(birth, "测", time.Date(2026, 8, 12, 12, 0, 0, 0, time.FixedZone("CST", 8*3600))) + wx, ok := out.Summary["wuxing"].(map[string]any) + if !ok { + t.Fatal("missing wuxing") } - raw, _ := json.Marshal(out) - for _, bad := range []string{"运势", "吉凶", "算命", "疗效", "治病"} { - if strings.Contains(string(raw), bad) { - t.Fatalf("forbidden %q", bad) + bars, ok := wx["bars"].([]map[string]any) + if !ok || len(bars) != 5 { + t.Fatalf("bars=%#v", wx["bars"]) + } + if wx["strong_el"] == nil || wx["care_dir"] == nil { + t.Fatalf("incomplete wuxing: %#v", wx) + } + prev, ok := out.Summary["blind_spots_preview"].([]string) + if !ok || len(prev) == 0 { + t.Fatalf("blind_spots_preview=%#v", out.Summary["blind_spots_preview"]) + } + for _, s := range prev { + if strings.Contains(s, "深度版") { + t.Fatalf("preview should not be upsell: %q", s) } } + st, ok := out.Summary["solar_term"].(map[string]any) + if !ok || st["name"] == nil { + t.Fatalf("missing solar_term: %#v", out.Summary["solar_term"]) + } } diff --git a/apps/api/internal/scale/jungian.go b/apps/api/internal/scale/jungian.go new file mode 100644 index 0000000..a35e1bd --- /dev/null +++ b/apps/api/internal/scale/jungian.go @@ -0,0 +1,122 @@ +package scale + +import ( + "encoding/json" + "strconv" +) + +// JungianQuestionMeta is parsed from scale_questions.body for OEJTS-style items. +type JungianQuestionMeta struct { + Dimension string `json:"dimension"` + Format string `json:"format"` + Left string `json:"left"` + Right string `json:"right"` + Prompt string `json:"prompt"` +} + +// ScoreJungian tallies 1–5 Likert answers per EI/SN/TF/JP (OEJTS rules). +// Left poles: E, S, F, J · Right poles: I, N, T, P · threshold = perDim*3. +func ScoreJungian(answers map[string]string, qMeta map[string]JungianQuestionMeta, perDim int) (typeCode string, raw map[string]int, pct map[string]int) { + raw = map[string]int{"EI": 0, "SN": 0, "TF": 0, "JP": 0} + if perDim <= 0 { + perDim = 8 + } + for qid, ans := range answers { + meta, ok := qMeta[qid] + if !ok || meta.Dimension == "" { + continue + } + v, err := strconv.Atoi(ans) + if err != nil || v < 1 || v > 5 { + v = 3 + } + raw[meta.Dimension] += v + } + thr := perDim * 3 + pick := func(score int, left, right string) string { + if score > thr { + return right + } + return left + } + typeCode = pick(raw["EI"], "E", "I") + + pick(raw["SN"], "S", "N") + + pick(raw["TF"], "F", "T") + + pick(raw["JP"], "J", "P") + + pct = map[string]int{} + minS, maxS := perDim, perDim*5 + span := float64(maxS - minS) + rightPct := func(score int) int { + p := int(float64(score-minS)/span*100 + 0.5) + if p < 0 { + return 0 + } + if p > 100 { + return 100 + } + return p + } + eiR := rightPct(raw["EI"]) + snR := rightPct(raw["SN"]) + tfR := rightPct(raw["TF"]) + jpR := rightPct(raw["JP"]) + pct["E"], pct["I"] = 100-eiR, eiR + pct["S"], pct["N"] = 100-snR, snR + pct["F"], pct["T"] = 100-tfR, tfR + pct["J"], pct["P"] = 100-jpR, jpR + return typeCode, raw, pct +} + +// ParseJungianMeta extracts dimension metadata from question body JSON. +func ParseJungianMeta(body json.RawMessage) JungianQuestionMeta { + var m JungianQuestionMeta + _ = json.Unmarshal(body, &m) + return m +} + +// BuildJungianResult builds rich result with 4-letter code + preference bars. +func BuildJungianResult(typeCode string, pct map[string]int) map[string]interface{} { + label := MBTILabel(typeCode) + base := mbtiPack(typeCode, label) + base.Label = typeCode + " · " + label + base.ShareLine = "我的类型探索:" + typeCode + " · " + label + base.Dimensions = []map[string]interface{}{ + {"title": "E/I 能量", "score": maxPct(pct, "E", "I"), "note": prefNote("E", "I", pct, "外向互动", "内向思考")}, + {"title": "S/N 信息", "score": maxPct(pct, "S", "N"), "note": prefNote("S", "N", pct, "具体事实", "模式可能")}, + {"title": "T/F 决策", "score": maxPct(pct, "T", "F"), "note": prefNote("T", "F", pct, "逻辑一致", "价值与人际")}, + {"title": "J/P 节奏", "score": maxPct(pct, "J", "P"), "note": prefNote("J", "P", pct, "计划结构", "灵活开放")}, + } + out := map[string]interface{}{ + "title": "MBTI 探索结果", + "style_key": typeCode, + "type_code": typeCode, + "label": base.Label, + "summary": base.Summary, + "overview": base.Overview, + "share_line": base.ShareLine, + "dimensions": base.Dimensions, + "preferences": pct, + "strengths": base.Strengths, + "watchouts": base.Watchouts, + "tips": base.Tips, + "scripts": base.Scripts, + "growth_plan": base.GrowthPlan, + "faq": base.FAQ, + } + return out +} + +func maxPct(pct map[string]int, a, b string) int { + if pct[a] >= pct[b] { + return pct[a] + } + return pct[b] +} + +func prefNote(a, b string, pct map[string]int, aDesc, bDesc string) string { + if pct[a] >= pct[b] { + return a + " " + strconv.Itoa(pct[a]) + "% · " + aDesc + } + return b + " " + strconv.Itoa(pct[b]) + "% · " + bDesc +} diff --git a/apps/api/internal/scale/mbti_result.go b/apps/api/internal/scale/mbti_result.go new file mode 100644 index 0000000..3e9831e --- /dev/null +++ b/apps/api/internal/scale/mbti_result.go @@ -0,0 +1,97 @@ +package scale + +// mbtiPack returns exploration copy for a 4-letter preference code (原创,非官方题库). +func mbtiPack(code, fallback string) pack { + label := MBTILabel(code) + if label == "平衡探索型" && fallback != "" { + label = fallback + } + base := mbtiBase(code, label) + dims := []map[string]interface{}{ + {"title": "能量", "score": dimScore(code, 0, 'E'), "note": axisNote(code, 0)}, + {"title": "信息", "score": dimScore(code, 1, 'S'), "note": axisNote(code, 1)}, + {"title": "决策", "score": dimScore(code, 2, 'T'), "note": axisNote(code, 2)}, + {"title": "节奏", "score": dimScore(code, 3, 'J'), "note": axisNote(code, 3)}, + } + base.Dimensions = dims + base.ShareLine = "我的 MBTI 探索:" + code + " · " + label + base.FAQ = append(base.FAQ, map[string]string{ + "q": "这是固定人格吗?", + "a": "不是。这是当前情境下的偏好快照,可随经历变化,请当作自我了解工具。", + }) + return base +} + +func dimScore(code string, i int, left rune) int { + if i >= len(code) { + return 70 + } + if rune(code[i]) == left { + return 82 + } + return 78 +} + +func axisNote(code string, i int) string { + if i >= len(code) { + return "" + } + switch code[i] { + case 'E': + return "外向充能偏多" + case 'I': + return "内向充能偏多" + case 'S': + return "更抓具体与当下" + case 'N': + return "更抓可能与意义" + case 'T': + return "更重逻辑与标准" + case 'F': + return "更重感受与关系" + case 'J': + return "更爱结构与收束" + case 'P': + return "更爱弹性与开放" + } + return "" +} + +func mbtiBase(code, label string) pack { + switch code { + case "INTJ": + return pack{Label: label, Summary: "你习惯先看见长期结构,再一步步落地。独处思考是你的燃料。", Overview: "你擅长把模糊目标拆成路径,讨厌无效社交与反复改口。成长点是:在推进前多留一句对人的确认,让方案更容易被接纳。", Strengths: []string{"战略感强", "独立推进", "标准清晰"}, Watchouts: []string{"显得疏离", "对低效不耐烦", "过度封闭计划"}, Tips: []string{"关键节点先同步再独断", "给情绪留 10 分钟再决策", "用清单外的「弹性项」练习放手"}, Scripts: []string{"我的建议是……,你最担心哪一步?", "我想先对齐目标,再谈细节可以吗?"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "一次决策前先问对方感受"}, {"phase": "本月", "focus": "公开一个半成品计划收集反馈"}}} + case "INTP": + return pack{Label: label, Summary: "你靠好奇与逻辑拆解世界,喜欢把概念想透再行动。", Overview: "分析是你的舒适区,拖延常来自还想再想清楚。成长点是设定「够好就提交」的截止点,把洞见变成可验证的小实验。", Strengths: []string{"抽象思考", "问题拆解", "开放好奇"}, Watchouts: []string{"迟迟不落地", "忽略关系节奏", "过度纠结定义"}, Tips: []string{"每个想法配一个 48 小时小实验", "讨论时先复述对方一句", "用番茄钟切分析与执行"}, Scripts: []string{"我还在梳理,今晚给你一个阶段性结论。", "我理解你的点;我补充一个角度……"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "完成一个未收尾的小输出"}, {"phase": "本月", "focus": "建立「思考→验证」双清单"}}} + case "ENTJ": + return pack{Label: label, Summary: "你天然想把事情推动到结果,目标感强、节奏快。", Overview: "你适合带队攻坚,但速度可能压到他人感受。成长点是:在下达目标时同步「为什么」与「需要的支持」。", Strengths: []string{"决策果断", "组织推进", "结果导向"}, Watchouts: []string{"控制欲过强", "忽视情绪成本", "把慢当成错"}, Tips: []string{"每周一次只听不评判的同步", "目标拆成共同里程碑", "表扬过程不只结果"}, Scripts: []string{"我们要达成……,你卡在哪里我可以支援?", "我的时间表是……,你的约束是什么?"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "一次会议先听完再给方案"}, {"phase": "本月", "focus": "把一个目标改成共创版"}}} + case "ENTP": + return pack{Label: label, Summary: "你爱挑战既有假设,点子多、辩论感强,讨厌无聊重复。", Overview: "灵感是你的超能力,落地与收尾是课题。成长点是选一个点子陪它走完最小闭环。", Strengths: []string{"快速联想", "打破僵局", "说服力"}, Watchouts: []string{"虎头蛇尾", "为辩而辩", "承诺过多"}, Tips: []string{"新点子先写「不做清单」", "找一个落地搭档", "争论前先确认共同目标"}, Scripts: []string{"换个角度看:如果……会怎样?", "我可以先做一版原型,我们再决定。"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "只推进一个点子到可演示"}, {"phase": "本月", "focus": "练习结束争论的收束句"}}} + case "INFJ": + return pack{Label: label, Summary: "你敏感于意义与人心走向,常在安静处看见别人没说出口的事。", Overview: "理想驱动你,也容易负荷过重。成长点是把关怀加上边界:不是所有情绪都要你接住。", Strengths: []string{"洞察力", "长期愿景", "深度共情"}, Watchouts: []string{"过度负责", "理想落差挫败", "表达拐弯"}, Tips: []string{"每天留无负担独处", "重要请求直接说", "区分「关心」与「承包」"}, Scripts: []string{"我感受到你……,我能做的是……,但我需要……", "这件事对我意义很大,我想认真谈一次。"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "拒绝一次超出负荷的请求"}, {"phase": "本月", "focus": "把一个愿景写成三步小行动"}}} + case "INFP": + return pack{Label: label, Summary: "你按内在价值行动,重视真实与温柔,讨厌被强迫表演。", Overview: "当环境违背价值观你会撤退或内耗。成长点是把「我在意什么」说清楚,让他人有机会配合你。", Strengths: []string{"价值感强", "创造力", "真诚"}, Watchouts: []string{"逃避冲突", "理想化他人", "自我怀疑"}, Tips: []string{"冲突时先写三句再谈", "每周做一件对齐价值的小事", "接受「足够好」的交付"}, Scripts: []string{"这件事触及我很在意的……,我们可以一起找折中吗?", "我需要一点时间整理感受,晚点认真回复你。"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "一次温和但清楚的表达"}, {"phase": "本月", "focus": "建立个人价值清单并对照日程"}}} + case "ENFJ": + return pack{Label: label, Summary: "你擅长点燃群体、照顾节奏,常成为大家的「主心骨」。", Overview: "你容易把别人的成长扛在肩上。成长点是学会把责任还回去,并照顾自己的能量账户。", Strengths: []string{"召集力", "鼓励他人", "氛围敏感"}, Watchouts: []string{"自我耗竭", "讨好倾向", "过度介入"}, Tips: []string{"帮助前先问「你需要什么」", "每周固定自我补给", "把表扬与界限一起说"}, Scripts: []string{"我很想支持你;这次我能做到的是……", "我们一起定个节奏,好让彼此都不透支。"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "一次帮助改为赋能提问"}, {"phase": "本月", "focus": "建立个人恢复仪式"}}} + case "ENFP": + return pack{Label: label, Summary: "你热情、好奇、连接人与可能性,讨厌被框死。", Overview: "开始很容易,专注收尾较难。成长点是给热情加一点结构:选少做深。", Strengths: []string{"感染力", "创意联想", "关系活力"}, Watchouts: []string{"分心多线", "承诺膨胀", "情绪起伏大"}, Tips: []string{"同时只养 2 个重点项目", "用伙伴盯收尾", "低能量日允许缩小社交圈"}, Scripts: []string{"我超有感觉!我们先定最小一步……", "今天我状态一般,改天再深聊可以吗?"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "砍掉一个分心事项"}, {"phase": "本月", "focus": "完成一个从灵感到交付的闭环"}}} + case "ISTJ": + return pack{Label: label, Summary: "你可靠、重承诺,喜欢把规则与流程做清楚。", Overview: "稳定是你的礼物,变化可能让你紧绷。成长点是在原则内留一个「可谈判区」。", Strengths: []string{"执行力", "细节准确", "责任感"}, Watchouts: []string{"固执流程", "不善表达情感", "对新法抵触"}, Tips: []string{"变更前先写利弊表", "主动说一句关心", "把例外规则写进清单"}, Scripts: []string{"按计划我们该……;若要改,影响是……", "我在意可靠,所以想先确认时间点。"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "接受一次小范围变更"}, {"phase": "本月", "focus": "练习情绪用词清单"}}} + case "ISFJ": + return pack{Label: label, Summary: "你细心照顾日常与人情,默默把安全感建起来。", Overview: "你常先顾别人。成长点是让需要被看见:被照顾也是关系的一部分。", Strengths: []string{"体贴", "记忆细节", "稳定支持"}, Watchouts: []string{"压抑需求", "怕冲突", "过度付出"}, Tips: []string{"每周提出一个真实偏好", "把付出写成可轮换的任务", "疲惫时直接说停"}, Scripts: []string{"我一直在帮忙……,这次我也需要……", "我有点累了,今晚想安静一下。"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "一次主动提出需要"}, {"phase": "本月", "focus": "建立付出与回收的平衡表"}}} + case "ESTJ": + return pack{Label: label, Summary: "你讲效率、抓标准,擅长把混乱整理成秩序。", Overview: "你推动系统运转,也可能被看成强硬。成长点是解释标准背后的公平意图。", Strengths: []string{"组织力", "决断", "落地快"}, Watchouts: []string{"命令口吻", "忽视个别情况", "急于纠正"}, Tips: []string{"指令后加一句「你怎么看」", "例外审批透明化", "表扬合规与创新并重"}, Scripts: []string{"标准是为了……,特殊情况我们可以……", "先按这个做一版,再一起复盘。"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "一次决策征求异议"}, {"phase": "本月", "focus": "写清团队共同规则"}}} + case "ESFJ": + return pack{Label: label, Summary: "你重视和谐与归属,善于把人连接成互相照顾的圈。", Overview: "和谐重要,但回避真实分歧会累积委屈。成长点是温和地谈不同意。", Strengths: []string{"协调", "热心", "仪式感"}, Watchouts: []string{"过度在意评价", "讨好", "压抑不满"}, Tips: []string{"分歧用「我观察/我需要」句式", "减少即时回消息压力", "为自己保留无角色时间"}, Scripts: []string{"我很在乎我们关系,所以想说一下我的不适……", "大家开心很重要,我也需要……被考虑。"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "一次诚实但不伤人的反馈"}, {"phase": "本月", "focus": "减少一次为和谐的妥协"}}} + case "ISTP": + return pack{Label: label, Summary: "你冷静拆解问题,动手能力强,讨厌空洞说教。", Overview: "你用行动证明理解。成长点是在关系里多给一点过程说明,避免被当成冷淡。", Strengths: []string{"实操", "危机冷静", "独立"}, Watchouts: []string{"话少被误解", "回避情绪话题", "承诺随意"}, Tips: []string{"行动前后各说一句意图", "定期短同步代替长会议", "练习命名当下感受"}, Scripts: []string{"我去处理……,大概多久回来。", "我不一定能立刻共情,但我可以帮忙做……"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "三次行动前口头同步"}, {"phase": "本月", "focus": "一次情绪向长谈不逃开"}}} + case "ISFP": + return pack{Label: label, Summary: "你活在感受与美感里,用体验表达自己,讨厌被强迫。", Overview: "你需要空间与节奏。成长点是在被压时及时说「停」,而不是默默消失。", Strengths: []string{"审美敏感", "温和", "当下投入"}, Watchouts: []string{"逃避压力", "需求不清", "突然抽离"}, Tips: []string{"压力信号出现就说", "用创作或散步调节", "重要约定写成双方可见"}, Scripts: []string{"我现在有点满,需要安静恢复一下。", "这件事的感觉对我很重要,我们慢慢谈。"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "一次及时表达边界"}, {"phase": "本月", "focus": "建立个人恢复清单"}}} + case "ESTP": + return pack{Label: label, Summary: "你抓当下机会、行动快,喜欢真刀真枪地试。", Overview: "冲劲带来结果,也可能低估后果。成长点是重大行动前留 10 分钟风险评估。", Strengths: []string{"应变", "胆识", "现实感"}, Watchouts: []string{"冲动", "忽略长远", "听不进劝"}, Tips: []string{"大决定用「最坏情况」三问", "找一个踩刹车的伙伴", "运动发泄代替硬刚冲突"}, Scripts: []string{"我想先试一版,失败了我们立刻收。", "你提醒的风险我记下了,我的底线是……"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "一次冲动决定延后 24 小时"}, {"phase": "本月", "focus": "建立行动前检查卡"}}} + case "ESFP": + return pack{Label: label, Summary: "你把活力带给现场,重视体验、分享与即时快乐。", Overview: "你点亮气氛,也可能回避沉闷的深度议题。成长点是留下处理难聊话题的固定时段。", Strengths: []string{"感染力", "体贴当下", "乐观"}, Watchouts: []string{"回避严肃议题", "过度取悦", "财务/计划松散"}, Tips: []string{"每周一次「认真聊」预约", "快乐预算设上限", "用日历保护恢复日"}, Scripts: []string{"今天先开心,明天我们认真谈……可以吗?", "我很想让大家轻松,但这件事我也有压力……"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "完成一次被拖延的认真对话"}, {"phase": "本月", "focus": "建立简单收支或计划习惯"}}} + default: + return pack{Label: label, Summary: "你的四维偏好组合较均衡或尚未充分显现主导面。", Overview: "可把本次结果当作起点,过一段时间在不同情境再测,观察哪一维更稳定。", Strengths: []string{"灵活", "可塑", "情境适应"}, Watchouts: []string{"自我描述模糊", "随大流", "缺少稳定策略"}, Tips: []string{"记录一周高能/耗能场景", "对争议维多做情景题自问", "与信任的人对照描述"}, Scripts: []string{"我还在认识自己,目前更接近……", "在……情境里我更像……"}, GrowthPlan: []map[string]string{{"phase": "本周", "focus": "日记标注能量来源"}, {"phase": "本月", "focus": "复测并对比变化"}}} + } +} diff --git a/apps/api/internal/scale/result.go b/apps/api/internal/scale/result.go index ea95224..1cb27bf 100644 --- a/apps/api/internal/scale/result.go +++ b/apps/api/internal/scale/result.go @@ -32,11 +32,43 @@ func resultPack(slug, key, fallbackLabel string) pack { switch slug { case "emotion-pattern": return emotionPack(key, fallbackLabel) + case "mbti-lite": + return mbtiPack(key, fallbackLabel) default: + if key == "high" || key == "mid" || key == "low" { + return bankExplorePack(fallbackLabel) + } return communicationPack(key, fallbackLabel) } } +func bankExplorePack(label string) pack { + if label == "" { + label = "节奏适中型" + } + return pack{ + Label: label, ShareLine: "我的探索结果:" + label, + Summary: "这是基于题库作答的自我探索速览,用于觉察倾向与日常参考,不是能力定论,更不是心理或医学诊断。", + Overview: "题库结果会随作答波动。你可以把它当成一面镜子:哪些选项更容易选中、身体与情绪有什么反应,比「分数高低」更重要。", + Dimensions: []map[string]interface{}{ + {"title": "自我觉察", "score": 72, "note": "留意答题时的身体感受"}, + {"title": "可行动性", "score": 68, "note": "挑一条小习惯试一周"}, + {"title": "非定论", "score": 90, "note": "结果可随阶段变化"}, + }, + Strengths: []string{"愿意自我观察", "愿意花时间完成题库"}, + Watchouts: []string{"不要把结果当标签钉死", "不适情绪请寻求专业支持"}, + Tips: []string{"截图保存一句对你有感的描述", "把一条建议写成今日小行动", "可与问答助手聊聊具体情境"}, + Scripts: []string{"这份结果让我想到……", "我想先观察一周再决定要不要改习惯。"}, + GrowthPlan: []map[string]string{ + {"phase": "本周", "focus": "选一条建议做一次小实验"}, + {"phase": "本月", "focus": "复盘:哪些描述仍然贴切"}, + }, + FAQ: []map[string]string{ + {"q": "这是心理诊断吗?", "a": "不是。愈心谷题库只做自我探索参考,不能替代专业评估或治疗。"}, + }, + } +} + func communicationPack(key, fallback string) pack { switch key { case "A": diff --git a/apps/api/internal/scale/score.go b/apps/api/internal/scale/score.go index dbe3ab0..c99ee1e 100644 --- a/apps/api/internal/scale/score.go +++ b/apps/api/internal/scale/score.go @@ -40,3 +40,45 @@ func EmotionLabels() map[string]string { "C": "行动调节型", } } + +// ScoreMBTI tallies E/I · S/N · T/F · J/P and returns a 4-letter type code + Chinese label. +func ScoreMBTI(answers map[string]string) (typeCode, label string) { + count := func(a, b string) (na, nb int) { + for _, v := range answers { + switch v { + case a: + na++ + case b: + nb++ + } + } + return + } + pick := func(a, b string, na, nb int) string { + if nb > na { + return b + } + return a + } + e, i := count("E", "I") + s, n := count("S", "N") + t, f := count("T", "F") + j, p := count("J", "P") + code := pick("E", "I", e, i) + pick("S", "N", s, n) + pick("T", "F", t, f) + pick("J", "P", j, p) + return code, MBTILabel(code) +} + +// MBTILabel maps 4-letter exploration code to a lexicon-safe Chinese label. +func MBTILabel(code string) string { + if l, ok := mbtiLabels[code]; ok { + return l + } + return "平衡探索型" +} + +var mbtiLabels = map[string]string{ + "INTJ": "战略建构者", "INTP": "概念探路者", "ENTJ": "目标推动者", "ENTP": "灵感挑战者", + "INFJ": "愿景洞察者", "INFP": "价值守护者", "ENFJ": "共鸣召集者", "ENFP": "热情启发者", + "ISTJ": "稳健执行者", "ISFJ": "细致守护者", "ESTJ": "秩序统筹者", "ESFJ": "温暖协调者", + "ISTP": "务实拆解者", "ISFP": "感受体验者", "ESTP": "当下行动者", "ESFP": "活力分享者", +} diff --git a/apps/api/internal/scale/score_test.go b/apps/api/internal/scale/score_test.go index 0a2a2fe..83bbbc9 100644 --- a/apps/api/internal/scale/score_test.go +++ b/apps/api/internal/scale/score_test.go @@ -1,6 +1,9 @@ package scale -import "testing" +import ( + "strconv" + "testing" +) func TestScoreMajority_communication(t *testing.T) { key, label := ScoreMajority(map[string]string{ @@ -20,6 +23,30 @@ func TestScoreMajority_emotion(t *testing.T) { } } +func TestScoreJungian_ENFP(t *testing.T) { + // 8 Qs per dim: EI low→E, SN high→N, TF low→F, JP high→P + meta := map[string]JungianQuestionMeta{} + answers := map[string]string{} + add := func(dim string, ids []string, vals []int) { + for i, id := range ids { + meta[id] = JungianQuestionMeta{Dimension: dim} + answers[id] = strconv.Itoa(vals[i]) + } + } + add("EI", []string{"e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8"}, []int{1, 1, 2, 1, 2, 1, 1, 2}) // sum 11 → E + add("SN", []string{"s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8"}, []int{5, 5, 4, 5, 4, 5, 5, 4}) // sum 37 → N + add("TF", []string{"t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8"}, []int{1, 2, 1, 2, 1, 1, 2, 1}) // sum 11 → F + add("JP", []string{"j1", "j2", "j3", "j4", "j5", "j6", "j7", "j8"}, []int{5, 4, 5, 5, 4, 5, 5, 4}) // sum 37 → P + code, _, pct := ScoreJungian(answers, meta, 8) + if code != "ENFP" { + t.Fatalf("code=%s want ENFP", code) + } + r := BuildJungianResult(code, pct) + if r["type_code"] != "ENFP" { + t.Fatalf("type_code=%v", r["type_code"]) + } +} + func TestScoreMajority_empty(t *testing.T) { _, label := ScoreMajority(nil, CommunicationLabels(), "平衡探索型") if label != "平衡探索型" { diff --git a/apps/api/internal/scalebank/bank.go b/apps/api/internal/scalebank/bank.go new file mode 100644 index 0000000..4d8b66c --- /dev/null +++ b/apps/api/internal/scalebank/bank.go @@ -0,0 +1,266 @@ +package scalebank + +import ( + _ "embed" + "encoding/json" + "fmt" + "strconv" + "sync" + + "github.com/google/uuid" +) + +//go:embed curated.json +var curatedJSON []byte + +var ( + bankNS = uuid.MustParse("6b1e9c2a-4d5f-4a8b-9c0d-1e2f3a4b5c6d") + once sync.Once + root *Root + loadErr error +) + +// Root is the curated bank file. +type Root struct { + Version int `json:"version"` + Categories []Category `json:"categories"` + Scales []Scale `json:"scales"` +} + +// Category groups scales for explore UI. +type Category struct { + Key string `json:"key"` + Title string `json:"title"` + Description string `json:"description"` + Icon string `json:"icon"` + Slugs []string `json:"slugs"` + Featured []string `json:"featured"` +} + +// Scale is one exploration instrument. +type Scale struct { + Slug string `json:"slug"` + Category string `json:"category"` + Title string `json:"title"` + Description string `json:"description"` + Icon string `json:"icon"` + QuestionCount int `json:"question_count"` + Questions []Question `json:"questions"` + Disclaimer string `json:"disclaimer"` +} + +// Question is prompt + options. +type Question struct { + Prompt string `json:"prompt"` + Options []Option `json:"options"` +} + +// Option is a choice. +type Option struct { + Key string `json:"key"` + Text string `json:"text"` +} + +// CatalogOut is explore bank payload. +type CatalogOut struct { + Featured []FeaturedItem `json:"featured"` + Categories []CategoryCard `json:"categories"` +} + +// FeaturedItem is icon+title tile. +type FeaturedItem struct { + Slug string `json:"slug"` + Title string `json:"title"` + Description string `json:"description"` + CategoryKey string `json:"category_key"` + Icon string `json:"icon"` + Path string `json:"path"` +} + +// CategoryCard is a category row / detail header. +type CategoryCard struct { + Key string `json:"key"` + Title string `json:"title"` + Description string `json:"description"` + Icon string `json:"icon"` + Count int `json:"count"` + Featured []FeaturedItem `json:"featured"` + Path string `json:"path"` +} + +// ScaleListItem is a scale in a category list. +type ScaleListItem struct { + Slug string `json:"slug"` + Title string `json:"title"` + Description string `json:"description"` + Icon string `json:"icon"` + QuestionCount int `json:"question_count"` + Path string `json:"path"` +} + +func load() (*Root, error) { + once.Do(func() { + var r Root + if err := json.Unmarshal(curatedJSON, &r); err != nil { + loadErr = err + return + } + root = &r + }) + return root, loadErr +} + +// MustLoad panics only in tests if embed broken; production returns error via helpers. +func MustLoad() *Root { + r, err := load() + if err != nil || r == nil { + panic(fmt.Sprintf("scalebank: %v", err)) + } + return r +} + +func bySlug(r *Root) map[string]Scale { + m := make(map[string]Scale, len(r.Scales)) + for _, s := range r.Scales { + m[s.Slug] = s + } + return m +} + +func catIcon(r *Root, key string) string { + for _, c := range r.Categories { + if c.Key == key { + return c.Icon + } + } + return "mbti" +} + +func scaleIcon(s Scale) string { + if s.Icon != "" { + return s.Icon + } + return "mbti" +} + +// Has reports whether slug is in the curated bank. +func Has(slug string) bool { + r, err := load() + if err != nil || r == nil { + return false + } + _, ok := bySlug(r)[slug] + return ok +} + +// Catalog builds featured tiles + category cards. +func Catalog() (*CatalogOut, error) { + r, err := load() + if err != nil { + return nil, err + } + m := bySlug(r) + out := &CatalogOut{} + for _, c := range r.Categories { + card := CategoryCard{ + Key: c.Key, Title: c.Title, Description: c.Description, Icon: c.Icon, + Count: len(c.Slugs), Path: "/explore/bank/" + c.Key, + } + for _, slug := range c.Featured { + s, ok := m[slug] + if !ok { + continue + } + item := FeaturedItem{ + Slug: s.Slug, Title: s.Title, Description: s.Description, + CategoryKey: c.Key, Icon: scaleIcon(s), Path: "/scales/" + s.Slug, + } + card.Featured = append(card.Featured, item) + out.Featured = append(out.Featured, item) + } + out.Categories = append(out.Categories, card) + } + return out, nil +} + +// CategoryScales lists scales in a category. +func CategoryScales(key string) (*CategoryCard, []ScaleListItem, error) { + r, err := load() + if err != nil { + return nil, nil, err + } + m := bySlug(r) + for _, c := range r.Categories { + if c.Key != key { + continue + } + card := CategoryCard{ + Key: c.Key, Title: c.Title, Description: c.Description, Icon: c.Icon, + Count: len(c.Slugs), Path: "/explore/bank/" + c.Key, + } + items := make([]ScaleListItem, 0, len(c.Slugs)) + for _, slug := range c.Slugs { + s, ok := m[slug] + if !ok { + continue + } + items = append(items, ScaleListItem{ + Slug: s.Slug, Title: s.Title, Description: s.Description, Icon: scaleIcon(s), + QuestionCount: s.QuestionCount, Path: "/scales/" + s.Slug, + }) + } + return &card, items, nil + } + return nil, nil, fmt.Errorf("category not found") +} + +// Get returns scale detail questions in repository-compatible shape fields. +func Get(slug string) (*Scale, error) { + r, err := load() + if err != nil { + return nil, err + } + s, ok := bySlug(r)[slug] + if !ok { + return nil, fmt.Errorf("scale not found") + } + cp := s + return &cp, nil +} + +// QuestionID stable id for answer keys. +func QuestionID(slug string, index int) uuid.UUID { + return uuid.NewSHA1(bankNS, []byte(fmt.Sprintf("%s/%d", slug, index))) +} + +// ScoreSum maps option keys (1..n) to a soft exploration band. +func ScoreSum(answers map[string]string, questionCount int) (styleKey, label string, score, ceiling int) { + sum := 0 + maxOpt := 1 + for _, v := range answers { + n, err := strconv.Atoi(v) + if err != nil || n < 1 { + continue + } + sum += n + if n > maxOpt { + maxOpt = n + } + } + ceiling = questionCount * maxOpt + if ceiling <= 0 { + ceiling = questionCount * 5 + } + pct := 0 + if ceiling > 0 { + pct = sum * 100 / ceiling + } + switch { + case pct >= 75: + return "high", "感受偏强烈型", sum, ceiling + case pct >= 45: + return "mid", "节奏适中型", sum, ceiling + default: + return "low", "感受偏轻柔型", sum, ceiling + } +} diff --git a/apps/api/internal/scalebank/bank_test.go b/apps/api/internal/scalebank/bank_test.go new file mode 100644 index 0000000..8e0156b --- /dev/null +++ b/apps/api/internal/scalebank/bank_test.go @@ -0,0 +1,34 @@ +package scalebank + +import "testing" + +func TestCatalogCuratedASet(t *testing.T) { + out, err := Catalog() + if err != nil { + t.Fatal(err) + } + if len(out.Categories) != 4 { + t.Fatalf("cats=%d", len(out.Categories)) + } + if len(out.Featured) < 6 { + t.Fatalf("featured=%d", len(out.Featured)) + } + seen := map[string]bool{} + for _, f := range out.Featured { + if f.Icon == "" || seen[f.Icon] { + t.Fatalf("featured icons must be unique nonempty: %#v", out.Featured) + } + seen[f.Icon] = true + } + if !Has("mbti") || !Has("gd3") || Has("yyzcs") { + t.Fatal("unexpected slug set") + } + s, err := Get("eq1") + if err != nil || len(s.Questions) == 0 { + t.Fatalf("eq1 %#v %v", s, err) + } + key, label, sum, ceil := ScoreSum(map[string]string{"a": "3", "b": "4"}, 2) + if key == "" || label == "" || sum == 0 || ceil == 0 { + t.Fatalf("%s %s %d %d", key, label, sum, ceil) + } +} diff --git a/apps/api/internal/scalebank/curated.json b/apps/api/internal/scalebank/curated.json new file mode 100644 index 0000000..3031b1f --- /dev/null +++ b/apps/api/internal/scalebank/curated.json @@ -0,0 +1 @@ +{"version":1,"source":"curated-from-scales_data A-set","categories":[{"key":"personality","title":"人格探索","description":"气质 · 动机 · 特质倾向","icon":"mbti","slugs":["mbti","jxrg","xl16","xl3","xl6","gd7"],"featured":["mbti","jxrg"]},{"key":"eq","title":"情绪能力","description":"觉察与调节习惯","icon":"ask","slugs":["eq1","eq2"],"featured":["eq1","eq2"]},{"key":"intellect","title":"智能探索","description":"多元智能倾向","icon":"astro","slugs":["duoyuan80"],"featured":["duoyuan80"]},{"key":"life","title":"生活与关系","description":"睡眠 · 压力 · 亲密与家庭","icon":"companion","slugs":["gd3","sm1","gd2","gd1","gd4","xl13"],"featured":["gd3","sm1"]}],"scales":[{"slug":"mbti","category":"personality","title":"人格倾向探索","description":"四维能量与决策偏好的自我探索","question_count":93,"questions":[{"prompt":"当你某日想去一个地方,你会?","options":[{"key":"1","text":"计划好将做的事情以及何时做"},{"key":"2","text":"去了再说"}]},{"prompt":"如果你是一位老师,你愿教?","options":[{"key":"1","text":"注重实践的课程"},{"key":"2","text":"理论研究的课程"}]},{"prompt":"遇到问题时,你通常喜欢?","options":[{"key":"1","text":"和别人讨论解决方法"},{"key":"2","text":"自己想办法解决"}]},{"prompt":"你认为?","options":[{"key":"1","text":"很早就应该开始为聚会,约会等做准备"},{"key":"2","text":"到时候想做什么就做什么"}]},{"prompt":"你通常和_____相处得更好?","options":[{"key":"1","text":"有想象力的人"},{"key":"2","text":"现实的人"}]},{"prompt":"你更多时候是?","options":[{"key":"1","text":"让情感驾驭理智"},{"key":"2","text":"让理智驾驭情感"}]},{"prompt":"当你和一群人在一起时,你常常是更愿意____?","options":[{"key":"1","text":"加入到大家的谈话中去"},{"key":"2","text":"独自和熟识的人交谈"}]},{"prompt":"你最喜欢____做事情?","options":[{"key":"1","text":"按兴致"},{"key":"2","text":"按照计划"}]},{"prompt":"你希望自己被看作是一个?","options":[{"key":"1","text":"实干家"},{"key":"2","text":"天才发明家"}]},{"prompt":"当别人问你一个问题时,你经常会?","options":[{"key":"1","text":"马上就做回答"},{"key":"2","text":"先在脑子里想一想"}]},{"prompt":"你喜欢与____打交道?","options":[{"key":"1","text":"头脑敏捷,想法出人意料的人"},{"key":"2","text":"按常理行事,中规中矩的人"}]},{"prompt":"按日程表办事?","options":[{"key":"1","text":"正合你意"},{"key":"2","text":"束缚了你"}]},{"prompt":"你觉得通常别人?","options":[{"key":"1","text":"要花很长的时间才能和你相熟"},{"key":"2","text":"很快就能和你熟识"}]},{"prompt":"为如何过周末定一个计划?","options":[{"key":"1","text":"是有必要的"},{"key":"2","text":"完全没必要"}]},{"prompt":"下列哪一个是对你更好的评价?","options":[{"key":"1","text":"性情中人"},{"key":"2","text":"理智的人"}]},{"prompt":"更多的时候,你倾向于?","options":[{"key":"1","text":"独处"},{"key":"2","text":"同他人在一起"}]},{"prompt":"在日常工作中,你更喜欢?","options":[{"key":"1","text":"在时间紧迫的情况下,争分夺秒地工作"},{"key":"2","text":"做好提前量,尽早把工作做完"}]},{"prompt":"你更愿把____作为朋友?","options":[{"key":"1","text":"总能有新想法的人"},{"key":"2","text":"脚踏实地的人"}]},{"prompt":"你是一个?","options":[{"key":"1","text":"兴趣广泛,什么都想尝试的人"},{"key":"2","text":"专注的投入某个兴趣的人"}]},{"prompt":"当你有一项特别的工作要做时,你喜欢先?","options":[{"key":"1","text":"察看到工作的全貌"},{"key":"2","text":"找出必须要做的环节"}]},{"prompt":"你更接受?","options":[{"key":"1","text":"以情动人"},{"key":"2","text":"以理服人"}]},{"prompt":"当你为了消遣而阅读时,你____?","options":[{"key":"1","text":"欣赏作者奇特、独创的表达"},{"key":"2","text":"喜欢作者的表达直接、明确"}]},{"prompt":"新认识你的人____了解到你的兴趣所在?","options":[{"key":"1","text":"马上就能"},{"key":"2","text":"只有真正和你熟悉以后才能"}]},{"prompt":"在旅行时,你喜欢?","options":[{"key":"1","text":"随兴致行事"},{"key":"2","text":"事先知道一天中该做的事"}]},{"prompt":"做许多人都做的事时,你喜欢?","options":[{"key":"1","text":"按惯例去做"},{"key":"2","text":"发明自己的新方法"}]},{"prompt":"多数人说你是一个?","options":[{"key":"1","text":"不爱吐露心事的人"},{"key":"2","text":"非常坦率的人"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"看不见的"},{"key":"2","text":"看的见的"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"计划"},{"key":"2","text":"随意"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"温情"},{"key":"2","text":"坚定"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"事实"},{"key":"2","text":"想法"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"思维"},{"key":"2","text":"情感"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"热忱"},{"key":"2","text":"平静"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"说服"},{"key":"2","text":"打动"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"陈述"},{"key":"2","text":"概念"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"分析"},{"key":"2","text":"同情"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"系统性"},{"key":"2","text":"随机性"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"敏感"},{"key":"2","text":"精确"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"缄默"},{"key":"2","text":"健谈"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"常识性的"},{"key":"2","text":"理论性的"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"侠肝义胆"},{"key":"2","text":"深谋远虑"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"正式"},{"key":"2","text":"非正式"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"沉静"},{"key":"2","text":"活跃"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"利益"},{"key":"2","text":"祝福"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"理论性"},{"key":"2","text":"确定性"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"坚定的"},{"key":"2","text":"忠诚的"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"理想"},{"key":"2","text":"现实"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"雄心"},{"key":"2","text":"柔肠"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"想象中的"},{"key":"2","text":"事实上的"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"冷静的"},{"key":"2","text":"激情的"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"制作"},{"key":"2","text":"创造"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"热情的"},{"key":"2","text":"中立的"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"明理的"},{"key":"2","text":"迷人的"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"有同情心"},{"key":"2","text":"有逻辑头脑"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"生产"},{"key":"2","text":"设计"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"冲动"},{"key":"2","text":"决择"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"公正的"},{"key":"2","text":"体谅的"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"安静的"},{"key":"2","text":"爱交际的"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"理性"},{"key":"2","text":"感性"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"不受限制的"},{"key":"2","text":"安排好的"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"具体"},{"key":"2","text":"抽象"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"能干的"},{"key":"2","text":"细腻的"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"开放"},{"key":"2","text":"私密"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"建造"},{"key":"2","text":"发明"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"有序的"},{"key":"2","text":"随便的"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"想象"},{"key":"2","text":"现实"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"好胜的"},{"key":"2","text":"好心的"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"理论"},{"key":"2","text":"事实"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"很少的朋友"},{"key":"2","text":"很多的朋友"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"可能"},{"key":"2","text":"确知"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"宽容的"},{"key":"2","text":"坚决的"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"新异的"},{"key":"2","text":"己知的"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"温柔"},{"key":"2","text":"力量"}]},{"prompt":"您更喜欢或倾向哪一个词","options":[{"key":"1","text":"实用"},{"key":"2","text":"创新"}]},{"prompt":"和一群人在一起聚会通常会让你感到?","options":[{"key":"1","text":"兴致勃勃"},{"key":"2","text":"筋疲力尽"}]},{"prompt":"你在做一个决定时,更多地会?","options":[{"key":"1","text":"权衡实际的得失"},{"key":"2","text":"考虑其他人的感受"}]},{"prompt":"通常你更喜欢?","options":[{"key":"1","text":"提前安排好该做什么"},{"key":"2","text":"到时候率性而为"}]},{"prompt":"当你一个人在家时,你?","options":[{"key":"1","text":"能够安静的冥想"},{"key":"2","text":"总觉的得做点什么"}]},{"prompt":"多数情况下,你?","options":[{"key":"1","text":"随兴致做事"},{"key":"2","text":"按日程表做事"}]},{"prompt":"你通常?","options":[{"key":"1","text":"容易和大家打成一片"},{"key":"2","text":"独处的时候更多"}]},{"prompt":"你做事更倾向于?","options":[{"key":"1","text":"等到各方面的信息都全了以后再做计划"},{"key":"2","text":"提前很久就定计划"}]},{"prompt":"别人____交上朋友?","options":[{"key":"1","text":"容易和你"},{"key":"2","text":"较难和你"}]},{"prompt":"你通常喜欢上____的课程?","options":[{"key":"1","text":"探讨理论和概念"},{"key":"2","text":"列举事实和图表"}]},{"prompt":"在聚会时,你?","options":[{"key":"1","text":"说的时候多"},{"key":"2","text":"听的时候多"}]},{"prompt":"你觉的自己更倾向于是一个?","options":[{"key":"1","text":"随意的人"},{"key":"2","text":"有秩序的人"}]},{"prompt":"你____?","options":[{"key":"1","text":"只同那些兴趣相同的人才能长谈"},{"key":"2","text":"只要愿意,和任何人都可以长聊"}]},{"prompt":"当你有一个报告需要在一个星期内交出时,你?","options":[{"key":"1","text":"常留出足够的时间并能提早完成"},{"key":"2","text":"常常是在最后一刻赶出来"}]},{"prompt":"哪一个对你来说是更高的评价?","options":[{"key":"1","text":"有好胜心的"},{"key":"2","text":"有同情心的"}]},{"prompt":"你觉得按日程表办事?","options":[{"key":"1","text":"虽有必要,但不喜欢"},{"key":"2","text":"有帮助的,非常喜欢"}]},{"prompt":"你更愿在一个____的老板手下工作?","options":[{"key":"1","text":"态度亲切,但有时会感情用事"},{"key":"2","text":"态度严厉,但始终按逻辑办事"}]},{"prompt":"在完成一项大任务时,你常常是?","options":[{"key":"1","text":"边做边考虑下一步"},{"key":"2","text":"事先想好每个步骤"}]},{"prompt":"在社交场合,你通常觉得?","options":[{"key":"1","text":"很难和不认识的人进行交谈"},{"key":"2","text":"很容易和多数人谈笑风生"}]},{"prompt":"你常常是?","options":[{"key":"1","text":"按已经有效的方法做事"},{"key":"2","text":"尝试一下有没有更好的办法"}]},{"prompt":"你更喜欢按____做事情?","options":[{"key":"1","text":"当天的感觉"},{"key":"2","text":"已订好的日程表"}]}],"disclaimer":"本内容仅供自我探索与生活参考,不构成心理或医学诊断。","icon":"mbti"},{"slug":"jxrg","category":"personality","title":"九型动机探索","description":"内在驱力与压力下的反应倾向","question_count":180,"questions":[{"prompt":"当我有困难时,我会试着不让人知道:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我不想成为一个喜欢批评的人,但很难做到:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我喜欢当主角,希望得到大家的注意:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"被人误解对我而言是一件十分痛苦的事:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我喜欢研究宇宙的道理、哲理:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常常设想最糟的结果而使自己陷入苦恼中:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我喜欢让事情呈现得轻松、幽默:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我是个易于满足的人,极少感到忧虑,几乎常是心平气和的:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我很善于挺身而出,为自己的需要争持到底:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常为事情未能按意想中的方向发展而烦躁不乐:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我需要在别人生活上占重要席位,我喜欢别人需要我:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我是一个天生的推销员,说服别人对我来说是一件轻易的事:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我不善于小组讨论或作简短谈话,我需要很多私人时间和空间:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我对过去的事有着一份近乎执着的怀恋:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常常试探或考验朋友、伴侣的忠诚:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我善于计划却不善于施行:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我喜欢独立自主,一切都靠自己:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"身体上的舒适对我非常重要:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我对现存的总觉不满:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我做事有效率,也会找捷径,模仿力特强:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"许多人感到很愿意和我接近:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常被有象征性的事物吸引:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"当我感到窘促或被人询问实时感受时,我脑里常是一片空白:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我很难违抗有权者的意见:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我对于别人和他们做事的动机从不抱很大的怀疑态度:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我知错能改,但由于执著好强,周围的人还是感觉到压力:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我喜欢享有完全不用工作的时间:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"别人不能完成他的分内事,会令我失望和愤怒:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"帮助不到别人会让我觉得痛苦:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我似具有策划,组织工作的本能而且能使工作顺利完成:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"别人常欠缺那份深度去了解我的感受:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我讨厌自己貌似愚笨也憎恶被人视为愚笨:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我似乎比大多数人更懂得享受生命:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我在作任何抉择前必先搜集多方面资料,确保准确充足:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"当沉浸在工作或我擅长的领域时,别人会觉得我冷酷无情:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我是很容易说话的人,凡事都有商量余地:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我的面部表情严肃而生硬:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我喜欢把别人从困难或尴尬的境况下解救出来:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我习惯推销自己,对自己的能力十分有信心:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我认为自己非常的不完善:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我喜欢从旁观看别人怎样做而自己却不参与:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我需要较长时间才能做出决定,一般来说,我喜欢行事谨慎:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"生命中没有很多事物是我不能欣赏的:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我向往掌权的职位,喜欢行使权力:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"即使存在着个别差异,但我仍觉得大多数人是善良的、美好的:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常对自己挑剔,期望不断改善自己的缺点,以成为一个完美的人:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我知道如何让别人喜欢我:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我外向、精力充沛,喜欢不断追求成就,这使我的自我感觉十分良好:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我有时很欣赏自己充满权威,有时却又优柔寡断,依赖别人:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我喜欢把事情安排得井井有条和具有高贵品味,亦很重视仪态:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常怀疑自己有否足够的勇气去完成那应做的事:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我生命中经验过的痛苦和不愉快的事很少:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我野心勃勃,喜欢挑战和登上高峰的经验:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"一般来说,我不会过分投入任何一件事:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我经常因少许细节而破坏了整件事:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我感到助人是应份的,不论我是否喜欢,我也会迫使自己这样做:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我做事喜欢事先知道自己在进展途上所在的位置:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我不喜欢想象自己仅只是个平凡人,在很多方面我都是与众不同:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我较其它人沉默,别人往往要问我在想什么:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我认为没有严格的规律很难指示人该作什么:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我很注意自己是否年轻,因为那是快乐的本钱:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"如果周遭的人行为太过分时,我准会让他难堪:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"别人批评我,我也不会回应和辩解,因为我不想发生任何争执与冲突:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我很容易知道别人的功劳和好处:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我对别人做的事总是不放心,批评一番后,自己会动手再做:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我喜欢用进度表、等级表或其它指针显示自己工作进展状况:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常常表现得十分忧郁的样子,充满痛苦而且内向:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"当别人请教我一些问题,我会巨细无遗地分析得很清楚:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我很重视别人对我所持的原则的观点,不论他们是赞成或反对:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在我生命里不论任何事物都是以最佳状态出现的:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我是一个很主动甚或具攻击性和自我肯定的人:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我需要有外来的动力,或刺激我继续工作、行动:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我脑子里常自我批评,也批评别人:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我多次感到别人对我的倚赖成了我无法负荷的重担:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常因所完成的工作较多而招人妒忌:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我的忧苦和重压,别人常觉察不到:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我不喜欢人家问我广泛、笼统的问题:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我觉得任何事情在采取行动前应先取得有职权人士的批准才好:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我是个近乎反常的乐观主义者,“理想”对于我来说重于一切:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我爱依惯例行事,不大喜欢改变:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我十分抗拒别人干预我的行径,或强把他们的行径加诸我:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我似乎不太懂得幽默,没有弹性:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我不觉得自己有许多需要,总是最后才想到自己:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我重视在人眼前展示一个成功的形象:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"初见陌生人时,我会表现得很冷漠、高傲:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我通常是等别人来接近我,而不是我去接近他们:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常受怀疑所困扰,对存在着的矛盾别具警觉,也很敏感:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我希望别人对事情看得轻松点:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我觉得很难把自己品性上较温柔的一面呈露出來,例如温柔、接纳关怀等:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我可被尊为最公正的仲裁者,因为我认为诉讼双方都是同样好的:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我重视做事准确无误:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我有时会觉得别人不欣赏我为他们所做的一切:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"要成功有时要对自己的原则或标准适度协调:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我很飘忽,常常不知自己下一刻想要什么:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我很有包容力,彬彬有礼,但跟人的感情互动不深:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我工作纯为了责任和职务:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我经常想事情光明的一面而不看生命中黑暗的另一面:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我处事通常选择没有太多阻力的途径:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我会极力保护我所爱的人:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常感到要和时间竞赛,许多应做的事情仍待完成:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"有时候,我觉得自己是个受害者,别人都尽在利用我:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我喜欢展露出一个年轻活泼的形像:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我似乎较其它人更深刻地感受人际关系终断时的那份困扰:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"如果不能完美地表态,我宁愿不说:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我对一切不清楚的事,一定要问个明白,含糊不清是我最接受不了的:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我想自己是个怀有赤子童心的人,能与人同乐:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我要求光明正大,为此不惜与人发生冲突:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我被动而优柔寡断:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我待人热情而有耐性:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我觉得必须对自己每时每刻负责:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"每遇到新事物的出现,我通常会走在活动的最前端:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我感受特别深刻,并怀疑那些总是很快乐的人:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我对时间、金钱和所拥有的一切都很吝啬:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"面对威胁时,我一是变得焦虑,一是对抗迎面而来的危险:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我喜欢把事情“描绘”出來,看看我曾到过那些地方也计划往哪儿去:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我很有正义感,有时会支持不利的一方:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我为自己性情稳定而自豪:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"每天晚上,我定要细心反省当日所做的,看是否每件工作都做得妥当:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"帮助别人达到快乐和成功是我重要的成就:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我是活跃的竞争份子,亦很渴望别人的赞赏:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常因感到被遗弃,孤独而饱受煎熬:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我比任何人更关心自己,更重视如何保护自己和自己的地位:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我对别人侵犯性的行为很敏感,我不喜欢别人勉强我作任何事:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我喜欢戏剧性、多彩多姿的生活:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我想我是个不受限制、不易妥协的人:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我喜欢以低调处理事情,让别人也因而安稳下来:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我不但不会说甜言蜜语,而且别人会觉得我唠叨不停:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"付出时,别人若不欣然接纳,我便会挫折感:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我争强好胜,喜欢跟别人比较:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我理解小丑笑脸背后隐藏着忧伤,也对这事实很共鸣:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我声线柔弱,人们常要我说话大声点,而这却使我动怒:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"当我和有权势的人接近时,我一方面感到安全,但另一方面却惧怕他们:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我对感官的需求特别强烈,喜欢美食、服装、身体的触觉刺激,并纵情享乐:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我能够坚持己见,甚至在处于下风的时候:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我总没法记得前次我睡不安宁是多久以前的事:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我是循规蹈矩的人,秩序对我十分有意义:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我觉得许多人依赖我的帮忙和慷慨:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常常刻意保持兴奋的情绪:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我有很强的创造天分和想象力,喜欢将事情重新整合:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我倾向于独自判断并自己解决问题:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我有时期待别人的指导,有时却忽略别人的忠告径直去做我想做的事:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常觉得很多事情都很好玩,很有趣,人生真是快乐:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我觉得大多数事件都是无关重要的,那又如何需如此紧张让它们牵着走呢?:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我若按自己安排的计划去工作,定然较按别人为我编排的工作会有更佳成绩:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"“感情”对我来说很重要:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我极其投入自己的工作,认同工作上的角色,有时甚而忘记“我”是谁:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我注重小节而效率不高:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我非常情绪化,一天的喜怒哀乐多变:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我保留我所拥有的,也收集一些日后可能适用的物资:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常常保持警觉:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我不喜欢要对人尽义务的感觉:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我很重视现在,我常感到一份催迫,现在应是要行动的一刻:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我不要求得到很多的注意力:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我认为要别人爱我,和认同我,我必先样样做到最好:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我若有一天假期,我常不知道可以为自己做些什么:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"有时我会讲求效率而牺牲完美和原则:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"艺术及艺术性的表达方式对我很重要,他们可以帮助我疏导情绪:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常幻想自己是某方面的英雄人物或属于某重要阶层:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常静悄悄地进出,不为同室中人觉察:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我大部分时间都避免卷入严肃的问题:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在危机发生时,我会挺身而出,控制大局:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我很容易认同别人所做的事和所知的一切:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我习惯将自己对外界的不满压抑在心中而非释放出来:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我觉得因我所作的一切,我堪当在人们心中占重要席位:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我认为大多数人都不懂得欣赏生命的内在美:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我认为必须多方面有成就别人才会注意我:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"当我觉我自己处于无大作为的景况时,我会一事不理:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我衡量他人时,常以他们会否对我构成威胁为据点:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我的计划目标通常高于我的实际完成:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我容易感到沮丧和麻木更多于愤怒:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我很容易觉察到欺骗和羞辱,我当我意识到受骗时,我会极度愤怒:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我对事物的观点似乎紧于事情的“对与错”或“好与坏”:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我认为自己能滋养别人比任何工作更令我自豪:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我喜欢告诉别人我所做的事和所知的一切:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我对大部分的社交集会不太有兴趣,除非那是我熟识的和喜爱的人:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我感到有些时候自己像是一个被流放的贵族:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我常担心自由被剥夺,因此不爱作承诺:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我是一位忠实的朋友和伙伴:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我感到有必要向别人表示我的不满:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我温和平静,不自夸,不爱与人竞争:","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]}],"disclaimer":"本内容仅供自我探索与生活参考,不构成心理或医学诊断。","icon":"nine"},{"slug":"xl16","category":"personality","title":"五维特质探索","description":"开放 · 尽责 · 外向 · 宜人 · 情绪敏感","question_count":60,"questions":[{"prompt":"我不是一个喜欢担忧的人","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我喜欢和许多人呆在一起","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我不喜欢把时间耗费在白日梦/胡思乱想上","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我对遇到的每一个人,都尽量保持礼貌、谦虚有礼","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我会保持我的物品整齐和清洁","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我常常觉得自己不如别人","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我很容易开怀大笑","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"当我发现一个正确做事的方式时,我会坚持采用这个方法","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我经常和家人或同伴有一些争执/争论","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我可以督促我自己,使工作准时完成","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"面对巨大的压力时,我有时会觉得要崩溃了","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我不认为我是一个很活泼的人","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我对于艺术作品和自然景观很有兴趣","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我的一些做法使别人认为我太顾自己或自我中心","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我不是一个做事有条理的人","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我很少感到孤独或沮丧","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我非常喜欢和别人交谈","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我认为让学生听有争议性的演讲只会混淆和误导他们的思想","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我宁愿与别人合作而不愿与他们竞争","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我善于计划时间安排要做的事情,能够完成被指派的任务","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我经常感到紧张不安","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我喜欢热闹的场合","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我很少被电影或诗词而感动","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"当别人对我很好时,我会怀疑他们是否出自真心","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我颇能接受按照自己的步伐,把事情准时办妥","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我有时感到自己完全一文不值","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我一向喜欢单独做事","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我经常品尝以前没有吃过的食物","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我认为如果你容忍人们欺骗、利用你的话,那么大多数人都会这么做","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我要花很多时间才能安顿下来","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我常感到恐慌或焦虑","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我做事情时常感到精力充沛","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我很少注意自己在不同环境下的情绪或感觉","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"大部分认识我的人都喜欢我","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我努力完成一切我能做到的事","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我经常因为别人对待我的方式而感到愤怒","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我是个容易开心、精神饱满的人。","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我坚信应该依据世俗或权威的观点进行道德问题的判断","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"人们认为我比较冷漠且爱计较","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"当我对别人有承诺时,通常我能贯彻到底","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我经常在事情不顺利时感到挫折并因此想半途而废","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我不是一个乐观主义者","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"当我在阅读诗词或欣赏艺术时,我会感到兴奋或惊喜","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"在态度上,我顽固不妥协","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"有些时候,我并不像我所应该的那样可靠和值得信赖","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我很少感到伤心或意志消沉","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我的生活步调相当紧凑而快速","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我没有兴趣思索宇宙的本质或人类的现状","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我总是尽力考虑周全,关心、体谅他人","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我是一个高效率完成工作的人","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我经常觉得很无助,并希望有人帮我解决问题","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我是一个乐观进取的人","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我对陌生的事物充满好奇","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"如果我不喜欢一个人,我会让他知道","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我好像总是不能把事情安排得井然有序","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我有时候会羞愧到只想躲起来","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我宁愿独自行动,而不愿领着他人一起做事","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我对理论和抽象的概念很感兴趣","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"必要时,我会操纵、控制他人以达到我的目的","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]},{"prompt":"我会努力完成一切我所能做到的","options":[{"key":"1","text":"非常不符合"},{"key":"2","text":"不符合"},{"key":"3","text":"中立"},{"key":"4","text":"符合"},{"key":"5","text":"非常符合"}]}],"disclaimer":"本内容仅供自我探索与生活参考,不构成心理或医学诊断。","icon":"portrait"},{"slug":"xl3","category":"personality","title":"气质倾向探索","description":"内外向 · 神经质 · 精神质等气质维度","question_count":88,"questions":[{"prompt":"你是否有许多不同的业余爱好?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否在做任何事情以前都有要停下来仔细思考?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你的心境是否常有起伏?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你曾有过明知是别人的功劳而你去接受奖励的事吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否健谈?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"欠债会使你不安吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你曾无缘无故觉得“真是难受”吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你曾经贪图过份外之物吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否在晚上小心翼翼地关好门窗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否比较活跃?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你在见到一小孩或一动物受折磨时是否会感受到非常难过?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否常常为自己不该做而做了的事,不该说而说了的话而紧张吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你喜欢跳降落伞吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"通常你能在热闹联欢会中尽情地玩吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你容易激动吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你曾经将自己的过错推给别人吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你喜欢会见陌生人吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否相信保险制度是一种好办法?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是一个容易伤感情的人吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你所有的习惯都是好的吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在社交场合你是否总不愿露头角?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你会服用有奇异或危险作用的药物吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你常有“厌倦”之感吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你曾拿过别人的东西(哪怕一针一线)吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否常爱外出?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否从伤害你所爱的人中而感到乐趣?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你常为有罪恶之感所苦恼吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你在谈论中是否有时不懂装懂?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否宁愿去看些书而不愿去多见人?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你有要伤害你的仇人吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你觉得自己是一个神经过敏的人吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"对人有所失礼时,你是否经常要表示歉意?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你有许多朋友吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否喜欢讲些有时确能伤害人的笑话?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是一个多忧多虑的人吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你在童年时是否按照吩咐要做什么便做什么,毫无怨言?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你认为你是一个乐天派吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你很讲究礼貌和整洁吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否总在担心会发生可怕的事情?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你曾损坏或遗失过别人的东西吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"交新朋友时一般是你采取主动吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"当别人向你诉苦时,你是否容易理解他们的苦衷?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你认为自己很紧张,如同“拉紧的弦”一样吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在没有废纸篓时,你是否将废纸扔在地板上?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"当你与别人在一起时,你是否言语很少?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否认为结婚制度是过时了,应该废止?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否有时感到自己可怜?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否有时有点自夸?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否很容易将一个沉寂的集会搞得活跃起来?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否讨厌那种小心翼翼地开车的人?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你为你的健康担忧吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你曾讲过什么人的坏话吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否喜欢对朋友讲笑话和有趣的故事?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你小时候曾对父母粗暴无礼吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否喜欢与人混在一起?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你如知道自己工作有错误,这会使你感到难过吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你患失眠吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你吃饭前必定洗手吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你常无缘无故感到无精打采和倦怠吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"和别人玩游戏时,你有过欺骗行为吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否喜欢从事一些动作迅速的工作?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你的母亲是一位善良的妇人吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否常常觉得人生非常无味?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你曾利用过某人为自己取得好处吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否常常参加许多活动,超过你的时间所允许?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"是否有几个人总在躲避你?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否为你的容貌而非常烦恼?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否觉得人们为了未来有保障而办理储蓄和保险所花的时间太多?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你曾有过不如死了为好的愿望吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"如果有把握永远不会被人发现,你会逃税吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你能使一个集会顺利进行吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你能克制自己不对人无礼吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"遇到一次难堪的经历后,你是否在一段长时间内还感到难受?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你患有“神经过敏”吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你曾经故意说些什么来伤害别人的感情吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否与别人的友谊容易破裂,虽然不是你的过错?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你常感到孤单吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"当人家寻你的差错,找你工作中的缺点时,你是否容易在精神上受挫伤?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你赴约会或上班曾迟到过吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你喜欢忙忙碌碌和热热闹闹地过日子吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你愿意别人怕你吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否觉得有时浑身是劲,而有时又是懒懒洋洋的吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你有时把今天应做的事拖到明天去做吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"别人认为你生气勃勃的吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"别人是否对你说了许多谎话?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你是否对某些事物容易冒火?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"当你犯了错误时,你是否常常愿意承认它?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"你会为一动物落入圈套被捉拿而感到很难过吗?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]}],"disclaimer":"本内容仅供自我探索与生活参考,不构成心理或医学诊断。","icon":"astro"},{"slug":"xl6","category":"personality","title":"十六型特质探索","description":"卡特尔十六种人格特质速览","question_count":187,"questions":[{"prompt":"我很明了本测验的说明:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"我对本测验每个问题都会按自己的真实情况作答:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不同意"}]},{"prompt":"有度假机会时,我宁愿:","options":[{"key":"1","text":"去一个繁华的都市"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"闲居清静而偏僻的郊区"}]},{"prompt":"我有足够的能力应付困难:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"即使是关在铁笼内的猛兽,我见了也会惴惴不安:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"我总避免批评别人的言行:","options":[{"key":"1","text":"是的"},{"key":"2","text":"有时如此"},{"key":"3","text":"不是的"}]},{"prompt":"我的思想似乎:","options":[{"key":"1","text":"走在了时代前面"},{"key":"2","text":"不太一定"},{"key":"3","text":"正符合时代"}]},{"prompt":"我不擅长说笑话讲趣事:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"当我看到亲友邻居争执时,我总是:","options":[{"key":"1","text":"任其自己解决"},{"key":"2","text":"置之不理"},{"key":"3","text":"予以劝解"}]},{"prompt":"在社交场合中,我:","options":[{"key":"1","text":"谈吐自然"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"退避三舍,保持沉默"}]},{"prompt":"我愿做一名:","options":[{"key":"1","text":"建筑工程师"},{"key":"2","text":"不确定"},{"key":"3","text":"社会科学的教员"}]},{"prompt":"阅读时,我宁愿选读:","options":[{"key":"1","text":"著名的宗教教义"},{"key":"2","text":"不确定"},{"key":"3","text":"国家政治组织的理论"}]},{"prompt":"我相信许多人都有些心理不正常,但他们都不愿意这样承认:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我所希望的结婚对象应擅长交际而无须有文艺才能:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"对于头脑简单和不讲理的人,我仍然能待之以礼:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"受人侍奉时我常感到不安:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"从事体力或脑力劳动后,我比平常人需要更多的休息才能恢复工作效率:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"半夜醒来,我会为种种忧虑而不能再入眠:","options":[{"key":"1","text":"常常如此"},{"key":"2","text":"有时如此"},{"key":"3","text":"极少如此"}]},{"prompt":"事情进行不顺利时,我常会急得掉眼泪:","options":[{"key":"1","text":"从不如此"},{"key":"2","text":"有时如此"},{"key":"3","text":"时常如此"}]},{"prompt":"我认为只要双方同意就可以离婚,不应当受传统礼教的束缚:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我对于人或物的兴趣都很容易改变:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"筹划事务时,我宁愿:","options":[{"key":"1","text":"和别人合作"},{"key":"2","text":"不确定"},{"key":"3","text":"自己单独进行"}]},{"prompt":"我常会无端地自言自语:","options":[{"key":"1","text":"常常如此"},{"key":"2","text":"偶然如此"},{"key":"3","text":"从不如此"}]},{"prompt":"无论工作,饮食或出游,我总:","options":[{"key":"1","text":"很匆忙,不能尽兴"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"很从容不迫"}]},{"prompt":"有时我会怀疑别人是否对我的言谈真正有兴趣:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"在工厂中,我宁愿负责:","options":[{"key":"1","text":"机械组"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"人事组"}]},{"prompt":"在阅读时,我宁愿选读:","options":[{"key":"1","text":"太空旅行"},{"key":"2","text":"不太确定"},{"key":"3","text":"家庭教育"}]},{"prompt":"下列三个字中哪个字与其它两个字属于不同类别:","options":[{"key":"1","text":"狗"},{"key":"2","text":"石"},{"key":"3","text":"牛"}]},{"prompt":"如果我能重新做人,我要:","options":[{"key":"1","text":"把生活安排得和以前不同"},{"key":"2","text":"不确定"},{"key":"3","text":"生活得和以前相仿"}]},{"prompt":"在我的一生中,我总能达到我所预期的目标:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"当我说谎时,我总觉得内心不安,不敢正视对方:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"假使我手持一支装有子弹的手抢,我必须取出子弹后才能心安:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"朋友们大都认为我是一个说话有风趣的人:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"如果人们知道我的内心世界,他们都会感到惊讶:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"在社交场合中,如果我突然成为众所注意的中心,我会感到局促不安:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我总喜欢参加规模庞大的聚会,舞会或公共集会:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"在下列工作中,我喜欢的是:","options":[{"key":"1","text":"音乐"},{"key":"2","text":"不一定"},{"key":"3","text":"手工"}]},{"prompt":"我常常怀疑那些过于友善的人动机是否如此:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我宁愿自己的生活象:","options":[{"key":"1","text":"一个艺人或博物学家"},{"key":"2","text":"不确定"},{"key":"3","text":"会计师或保险公司的经纪人"}]},{"prompt":"目前世界所需要的是:","options":[{"key":"1","text":"多产生一些富有改善世界计划的理想家"},{"key":"2","text":"不确定"},{"key":"3","text":"脚踏实地的可靠公民"}]},{"prompt":"有时候我觉得我需要做剧烈的体力活动:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我愿意与有礼貌有教养的人来往,而不愿和粗卤野蛮的人为伍:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"在处理一些必须凭籍智慧的事务中,我的父母的确:","options":[{"key":"1","text":"较一般人差"},{"key":"2","text":"普通"},{"key":"3","text":"超人一等"}]},{"prompt":"当上司(或教师)召见我时,我:","options":[{"key":"1","text":"总觉得可以趁机会提出建议"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"总怀疑自己做错了什么事"}]},{"prompt":"假使薪俸优厚,我愿意专任照料精神病人的职务:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"看报时,我喜欢读:","options":[{"key":"1","text":"当前世界基本社会问题的辩论"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"地方新闻的报道"}]},{"prompt":"我曾担任过:","options":[{"key":"1","text":"一般职务"},{"key":"2","text":"多种职务"},{"key":"3","text":"非常多的职务"}]},{"prompt":"逛街时,我宁愿观看一个画家写生,而不愿听人家的辩论:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"我的神经脆弱,稍有刺激的声音就会使我战惊:","options":[{"key":"1","text":"时常如此"},{"key":"2","text":"有时如此"},{"key":"3","text":"从未如此"}]},{"prompt":"我在清晨起身时,就常常感到疲乏不堪:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我宁愿是一个:","options":[{"key":"1","text":"管森林的工作人员"},{"key":"2","text":"不一定"},{"key":"3","text":"中小学教员"}]},{"prompt":"每逢年节或亲友生日,我:","options":[{"key":"1","text":"喜欢互相赠送礼物"},{"key":"2","text":"不太确定"},{"key":"3","text":"觉得交换礼物是麻烦多事"}]},{"prompt":"下列数字中,哪个数字与其他两个数字属于不同类别:","options":[{"key":"1","text":"5"},{"key":"2","text":"2"},{"key":"3","text":"7"}]},{"prompt":"[猫]与[鱼]就如同[牛]与:","options":[{"key":"1","text":"牛乳"},{"key":"2","text":"牧草"},{"key":"3","text":"盐"}]},{"prompt":"在做人处事的各个方面,我的父母很值得敬佩:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"我觉得我有一些别人所不及的优良品质:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"只要有利于大家,尽管别人认为卑贱的工作,我也乐而为之,不以为耻:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不太确定"},{"key":"3","text":"不是的"}]},{"prompt":"我喜欢看电影或参加其他娱乐活动:","options":[{"key":"1","text":"每周一次以上(比一般人多)"},{"key":"2","text":"每周一次(与通常人相似)"},{"key":"3","text":"偶然一次(比通常人少)"}]},{"prompt":"我喜欢从事需要精确技术的工作:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"在有思想,有地位的长者面前,我总较为缄默:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"就我来说,在大众前演讲或表演是一件不容易的事:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我宁愿:","options":[{"key":"1","text":"指挥几个人工作"},{"key":"2","text":"不确定"},{"key":"3","text":"和团体共同工作"}]},{"prompt":"纵使我做了一桩贻笑大方的事,我也仍然能够将它淡然忘却:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"没有人会幸灾乐祸地希望我遭遇困难:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不确定"},{"key":"3","text":"不是的"}]},{"prompt":"堂堂男子汉应该:","options":[{"key":"1","text":"考虑人生的意义"},{"key":"2","text":"不确定"},{"key":"3","text":"谋家庭的温饱"}]},{"prompt":"我喜欢解决别人已弄得一塌糊涂的问题:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我十分高兴的时候总有[好景不常]之感:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"在一般困难处境下,我总能保持乐观:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"迁居是一桩极不愉快的事:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"在我年轻的时候,如果我和父母的意见不同,我经常:","options":[{"key":"1","text":"坚持自己的意见"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"接受他们的意见"}]},{"prompt":"我希望我的爱人能够使家庭:","options":[{"key":"1","text":"有其本身的欢乐与活动"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"成为邻里社交活动的一部分"}]},{"prompt":"我解决问题多数依靠:","options":[{"key":"1","text":"个人独立思考"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"与人互相讨论"}]},{"prompt":"需要[当机立断]时,我总:","options":[{"key":"1","text":"镇静地运用理智"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"常常紧张兴奋,不能冷静思考"}]},{"prompt":"最近,在一两桩事情上,我觉得自己是无辜受累:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我善于控制我的表情:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"如果薪俸相等,我宁愿做:","options":[{"key":"1","text":"一个化学研究师"},{"key":"2","text":"不确定"},{"key":"3","text":"旅行社经理"}]},{"prompt":"[惊讶]与[新奇]犹如[惧怕]与:","options":[{"key":"1","text":"勇敢"},{"key":"2","text":"焦虑"},{"key":"3","text":"恐怖"}]},{"prompt":"下列三个分数中,哪一个与其他两个属不同类别:","options":[{"key":"1","text":"3/7"},{"key":"2","text":"3/9"},{"key":"3","text":"3/11"}]},{"prompt":"不知什么缘故,有些人故意回避或冷淡我:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"我虽善意待人,却得不到好报:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"我不喜欢那些夜郎自大,目空一切的人:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"和一般人相比,我的朋友的确太少:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"出于万不得已时,我才参加社交集会,否则我总设法回避:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"在服务机关中,对上级的逢迎得当,比工作上的表现更为重要:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"参加竞赛时,我看重的是竞赛活动,而不计较其成败:","options":[{"key":"1","text":"总是如此"},{"key":"2","text":"一般如此"},{"key":"3","text":"偶然如此"}]},{"prompt":"我宁愿我所就的职业有:","options":[{"key":"1","text":"固定可靠的薪水"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"薪资高低能随我工作的表现而随时调整"}]},{"prompt":"我宁愿阅读:","options":[{"key":"1","text":"军事与政治的事实记载"},{"key":"2","text":"不一定"},{"key":"3","text":"一部富有情感与幻想的作品"}]},{"prompt":"有许多人不敢欺骗或犯罪,主要原因是怕受到惩罚:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我的父母(或保护人)从未很严格地要我事事顺从:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"[百折不挠][再接再厉]的精神似乎完全被现代人忽视了:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"如果有人对我发怒,我总:","options":[{"key":"1","text":"设法使他镇静下来"},{"key":"2","text":"不太确定"},{"key":"3","text":"也会恼怒起来"}]},{"prompt":"我希望大家都提倡:","options":[{"key":"1","text":"多吃水果以避免杀生"},{"key":"2","text":"不一定"},{"key":"3","text":"发展农业捕灭对农产品有害的动物"}]},{"prompt":"无论在极高的屋顶上或极深的隧道中,我很少觉得胆怯不安:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我只要没有过错,不管人家怎样归咎于我,我总能心安理得:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"凡是无法运用理智来解决的问题,有时就不得不靠权力来处理:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我十六、七岁时与异性朋友的交游:","options":[{"key":"1","text":"极多"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不很多"}]},{"prompt":"我在交际场或所参加的组织中是一个活跃分子:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"在人声噪杂中,我仍能不受妨碍,专心工作:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"在某环境下,我常因困惑引起幻想而将工作搁置下来:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我很少用难堪的话去中伤别人的感情:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不太确定"},{"key":"3","text":"不是的"}]},{"prompt":"我更愿意做一名:","options":[{"key":"1","text":"商店经理"},{"key":"2","text":"不确定"},{"key":"3","text":"建筑师"}]},{"prompt":"[理不胜辞]的意思是:","options":[{"key":"1","text":"理不如辞"},{"key":"2","text":"理多而辞寡"},{"key":"3","text":"辞藻丰富而理由不足"}]},{"prompt":"[锄头]与[挖掘]犹如[刀子]与:","options":[{"key":"1","text":"雕刻"},{"key":"2","text":"切剖"},{"key":"3","text":"铲除"}]},{"prompt":"我常横过街道,以回避我不愿招乎的人:","options":[{"key":"1","text":"很少如此"},{"key":"2","text":"偶然如此"},{"key":"3","text":"有时如此"}]},{"prompt":"在我倾听音乐时,如果人家高谈阔论:","options":[{"key":"1","text":"我仍然能够专心听,不受影响"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"我会不能专心欣赏而感到恼恐"}]},{"prompt":"在课堂上,如果我的意见与教师不同,我常:","options":[{"key":"1","text":"保持缄默"},{"key":"2","text":"不一定"},{"key":"3","text":"当场表明立场"}]},{"prompt":"我和异性友伴交谈时,竭力避免涉及有关[性]的话题:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我待人接物的确不太成功:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不尽然"},{"key":"3","text":"不是的"}]},{"prompt":"每当考虑困难问题时,我总是:","options":[{"key":"1","text":"一切都未雨稠缪"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"相信到时候会自然解决"}]},{"prompt":"我所结交的朋友中,男女各占一半:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我宁可:","options":[{"key":"1","text":"结识很多的人"},{"key":"2","text":"不一定"},{"key":"3","text":"维持几个深交的朋友"}]},{"prompt":"我宁为哲学家,而不做机械工程师:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不确定"},{"key":"3","text":"不是的"}]},{"prompt":"如果我发现某人自私不义,我总不计一切指摘他的弱点:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我善用心机去影响同伴,使他们能协助实现我的目标:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我喜欢做戏剧、音乐、歌舞或新闻采访方面工作:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"当人们颂扬我时,我总觉得不好意思:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我以为现代最需要解决的问题是:","options":[{"key":"1","text":"政治纠纷"},{"key":"2","text":"不太确定"},{"key":"3","text":"道德标准的有无"}]},{"prompt":"我有时会无故地产生一种面临横祸的恐惧:","options":[{"key":"1","text":"是的"},{"key":"2","text":"有时如此"},{"key":"3","text":"不是的"}]},{"prompt":"我在童年时,害怕黑暗的次数:","options":[{"key":"1","text":"极多"},{"key":"2","text":"不太多"},{"key":"3","text":"没有"}]},{"prompt":"黄昏闲暇,我喜欢:","options":[{"key":"1","text":"看一部历史探险影片"},{"key":"2","text":"不一定"},{"key":"3","text":"念一本科学幻想小说"}]},{"prompt":"当人们批评我古怪时,我觉得:","options":[{"key":"1","text":"非常气恼"},{"key":"2","text":"有些动气"},{"key":"3","text":"无所谓"}]},{"prompt":"在一个陌生的城市找住址时,我经常:","options":[{"key":"1","text":"就人问路"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"参考市区地图"}]},{"prompt":"朋友们申言要在家休息时,我仍设法怂恿他们外出:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"在就寝时,我:","options":[{"key":"1","text":"不易入睡"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"极容易入睡"}]},{"prompt":"有人烦扰我时,我:","options":[{"key":"1","text":"能不露生色"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"要说给别人听,以泄气愤"}]},{"prompt":"如果待遇相等,我宁愿做一个:","options":[{"key":"1","text":"律师"},{"key":"2","text":"不确定"},{"key":"3","text":"飞行员或航海员"}]},{"prompt":"时间永恒是比喻:","options":[{"key":"1","text":"时间过得很慢"},{"key":"2","text":"忘了时间"},{"key":"3","text":"光阴一去不复返"}]},{"prompt":"下列三项记号中,哪一项应接在 ×OOOO××OOO××× 后面:","options":[{"key":"1","text":"×O×"},{"key":"2","text":"OO×"},{"key":"3","text":"O××"}]},{"prompt":"在陌生的地方,我仍能清楚地辨别东西南北的方向:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我的确比一般人幸运,因为我能从事自己所乐的工作:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"如果我急于想借用别人的东西而物主恰又不在,我认为不告而取亦无大碍:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我喜欢向友人追述一些已往有趣的社交经验:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我更愿意做一名:","options":[{"key":"1","text":"演员"},{"key":"2","text":"不确定"},{"key":"3","text":"建筑师"}]},{"prompt":"工作学习之余,我总要安排计划,不使时间浪费:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"与人交际时,我常会无端地产生一种自卑感:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"主动与陌生人交谈:","options":[{"key":"1","text":"是一桩难事"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"毫无困难"}]},{"prompt":"我喜欢的音乐,多数是:","options":[{"key":"1","text":"轻快活泼"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"富于情感"}]},{"prompt":"我爱做[白日梦]即[完全沉浸于幻想之中]:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"未来二十年的世界局势定将好:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"童年时,我喜欢阅读:","options":[{"key":"1","text":"战争故事"},{"key":"2","text":"不确定"},{"key":"3","text":"神仙幻想故事"}]},{"prompt":"我素来对机械、汽车、飞机等有兴趣:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我愿意做一个缓刑释放罪犯的管理监视人:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"人们认为我只不过是一个能苦干,稍有成就的人而已:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"在逆境中,我总能保持精神振奋:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不太确定"},{"key":"3","text":"不是的"}]},{"prompt":"我以为人工节育是解决世界经济与和平问题的要诀:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不太确定"},{"key":"3","text":"不是的"}]},{"prompt":"我喜欢独自筹划,避免人家的干涉和猜议:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我相信[上司不可能没有过错,但他仍有权做当权者]:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"我总设法使自己不粗心大意,忽略细节:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"与人争辩或险遭事故后,我常发抖,精疲力竭,不能安心工作:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"没有医生处方,我从不乱用药:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"为了培养个人的兴趣,我愿意参加:","options":[{"key":"1","text":"摄影组"},{"key":"2","text":"不确定"},{"key":"3","text":"辩论会"}]},{"prompt":"星火,燎原对等于姑息:","options":[{"key":"1","text":"同情"},{"key":"2","text":"养奸"},{"key":"3","text":"纵容"}]},{"prompt":"[钟表]与[时间]犹如[载缝]与:","options":[{"key":"1","text":"西装"},{"key":"2","text":"剪刀"},{"key":"3","text":"布料"}]},{"prompt":"生动的梦境常常滋扰我的睡眠:","options":[{"key":"1","text":"时常如此"},{"key":"2","text":"偶然如此"},{"key":"3","text":"从未如此"}]},{"prompt":"我过去曾撕毁一些禁止人们自由的布告:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"在一个陌生的城市中,我会:","options":[{"key":"1","text":"到处闲游"},{"key":"2","text":"不确定"},{"key":"3","text":"避免去较不安全的地方"}]},{"prompt":"我宁愿服饰素洁大方,而不愿争奇斗艳惹人注目:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不太确定"},{"key":"3","text":"不是的"}]},{"prompt":"黄昏时,安静的娱乐远胜过热闹的宴会:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不太确定"},{"key":"3","text":"不是的"}]},{"prompt":"我常常明知故犯,不愿意接受好心的建议:","options":[{"key":"1","text":"偶然如此"},{"key":"2","text":"罕有如此"},{"key":"3","text":"从不如此"}]},{"prompt":"我总把[是非][善恶]作为判断或取舍的原则:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我工作时不喜欢有许多人在旁参观:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"故意去为难一般有教养的人,如医生,教师等人的尊严,是一件有趣的事:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"在各种课程中,我较喜欢:","options":[{"key":"1","text":"语文"},{"key":"2","text":"不确定"},{"key":"3","text":"数学"}]},{"prompt":"那些自以为是、道貌岸然的人最使我生气:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"与平常循规蹈矩的人交谈:","options":[{"key":"1","text":"亦有所得"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"他们思想的肤浅使我厌烦"}]},{"prompt":"我喜欢:","options":[{"key":"1","text":"有几个有时对我很苛求而富有感情的朋友"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不受别人的牵涉"}]},{"prompt":"如果做民意投票时,我宁愿投票赞同:","options":[{"key":"1","text":"切实根绝有生理缺陷者的生育"},{"key":"2","text":"不确定"},{"key":"3","text":"对杀人犯判处死刑"}]},{"prompt":"我有时会无端地感到沮丧痛苦:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"当我与立场相反的人辩论时,我主张:","options":[{"key":"1","text":"尽量找出基本观点的差异"},{"key":"2","text":"不一定"},{"key":"3","text":"彼此让步以解决矛盾"}]},{"prompt":"我一向重感情而不重理智,因此我的观点常动摇不定:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不敢如此"},{"key":"3","text":"不是的"}]},{"prompt":"我的学习效率多有赖于:","options":[{"key":"1","text":"阅读好书"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"参加团体讨论"}]},{"prompt":"我宁选一个薪俸高的工作,不在乎有无保障,而不愿任薪俸低的固定工作:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不太确定"},{"key":"3","text":"不是的"}]},{"prompt":"在参加辩论以前,我总先把握住自己的立场:","options":[{"key":"1","text":"经常如此"},{"key":"2","text":"一般如此"},{"key":"3","text":"必要时才如此"}]},{"prompt":"我常被一些无所谓的琐事所烦扰:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我宁愿住在嘈杂的城市,而不愿住在安静的乡村:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不太确定"},{"key":"3","text":"不是的"}]},{"prompt":"我宁愿:","options":[{"key":"1","text":"负责领导儿童游戏"},{"key":"2","text":"不确定"},{"key":"3","text":"协助钟表修理"}]},{"prompt":"一人()事,众人受累:","options":[{"key":"1","text":"愤"},{"key":"2","text":"偾"},{"key":"3","text":"喷"}]},{"prompt":"望子成龙的家长往往()苗助长:","options":[{"key":"1","text":"揠"},{"key":"2","text":"堰"},{"key":"3","text":"偃"}]},{"prompt":"气候的转变并不影响我的情绪:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"因为我对于一切问题都有些见解,大家都公认我富于思想:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我讲话的声音:","options":[{"key":"1","text":"宏亮"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"低沉"}]},{"prompt":"人们公认我是一个活跃热情的人:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我喜欢有旅行和变动机会的工作,而不计较工作本身之是否有保障:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我治事严格,凡事都务求正确尽善:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"在取回或归还东西时,我总仔细检查是否东西还保持原状:","options":[{"key":"1","text":"是的"},{"key":"2","text":"介于上、下选项之间"},{"key":"3","text":"不是的"}]},{"prompt":"我通常精力充沛,忙碌多事:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不一定"},{"key":"3","text":"不是的"}]},{"prompt":"我确信我没有遗漏或不经心回答上面任何问题:","options":[{"key":"1","text":"是的"},{"key":"2","text":"不确定"},{"key":"3","text":"不是的"}]}],"disclaimer":"本内容仅供自我探索与生活参考,不构成心理或医学诊断。","icon":"reports"},{"slug":"gd7","category":"personality","title":"职业兴趣探索","description":"霍兰德六型兴趣与环境偏好","question_count":120,"questions":[{"prompt":"装配修理电器或玩具?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"修理自行车?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"用木头做东西?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"开汽车或摩托车?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"用机器做东西?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"参加木工技术学习班?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"参加制图描图学习班?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"驾驶卡车或拖拉机?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"参加机械和电气学习?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"装配修理电器?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"素描/制图或绘画?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"参加话剧戏曲?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"设计家具布置室内?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"练习乐器/参加乐队?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"欣赏音乐或戏剧?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"看小说/读剧本?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"从事摄影创作?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"写诗或吟诗?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"进艺术(美/音)培训班?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"练习书法?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"读科技图书和杂志?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"在试验室工作?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"改良品种,培育新水果?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"分析土和金属等的成分?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"研究自己选择的问题?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"解算式或数学游戏?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"学物理课?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"学化学课?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"学几何课?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"学生物课?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"学校或单位的正式活动?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"参加社会团体或俱乐部?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"帮助别人解决困难?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"照顾儿童?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"晚会、联欢会、茶话会?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"和大家一起出去郊游?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"获得心理方面的知识?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"参加讲座会或辩论会?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"观看或参加体育比赛?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"结交新朋友?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"说服鼓动他人?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"卖东西?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"谈论政治?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"制定计划、参加会议?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"影响别人的行为?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"在社会团体中任职?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"检查与评价别人的工作?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"结识名流?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"指导项目小组?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"参与政治活动?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"整理好桌面和房间?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"抄写文件和信件?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"为领导写报告或公函?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"查收个人收支情况?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"参加打字培训班?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"参加算盘,文秘等培训?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"参加商业会计培训班?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"参加情报处理培训班?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"整理信件、报告、记录等?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"写商业贸易信?","options":[{"key":"1","text":"感兴趣"},{"key":"2","text":"不感兴趣"}]},{"prompt":"能使用电锯、电钻和锉刀等木工工具?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"知道万用表的使用方法?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能够修理自行车或其他机械?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能够使用电钻床、磨床或缝纫机?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能给家具和木制品刷漆?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能看建筑等设计图?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能够修理简单的电气用品?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能够修理家具?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能修收录机?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能简单地修理水管?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能演奏乐器?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能参加二部或四部合唱?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"独唱或独奏?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"扮演剧中角色?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能创作简单的乐曲?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"会跳舞?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能绘画、素描或书法?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能雕该刻、剪纸或泥塑?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能设计海报、服装或家具?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"写得一手好文章?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"懂得真空管或晶体管的作用?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能够举例三种含蛋白质多的食品?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"理解铀的裂变?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能用计算尺、计算器、对数表?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"会使用显微镜?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能找到三个星座?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能独立进行调查研究?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能解释简单的化学式?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"理解人造卫星为什么不落地?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"经常参加学术的会议?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"有向各种人说明解释的能力?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"常参加社会福利活动?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能和大家一起友好相处地工作?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"善于与年长者相处?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"会邀请人招待人?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能简单易懂地教育儿童?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能安排会议等活动顺序?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"善于体察人心和帮助他人?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"帮助护理病人或伤员?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"安排社团组织的各种事务?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"担任过学生干部并且干得不错?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"工作上能指导和监督他人?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"做事充满活力和热情?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"有效地用自身的做法调动他人?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"销售能力强?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"曾作为俱乐部或社团的负责人?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"向领导提出建议或反映意见?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"有开创事业的能力?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"知道怎样做能成为一个优秀的领导者?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"健谈善辩?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"会熟练地打印中文?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"会用外文打字机或复印机?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能快速记笔记和抄写文章?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"善于整理保管文件和资料?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"善于从事事务性的工作?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"会用算盘?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能在短时间内分类和处理大量文件?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能使用计算机?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"能搜集数据?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"善于为自己或集体作财务预算表?","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]}],"disclaimer":"本内容仅供自我探索与生活参考,不构成心理或医学诊断。","icon":"growth"},{"slug":"eq1","category":"eq","title":"情绪能力探索","description":"自我觉察与情绪习惯","question_count":50,"questions":[{"prompt":"对自己的性格类型有比较清晰的了解","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"无法确知自己是在为何生气、高兴、伤心或妒忌","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"知道自己在什么样的情况下容易发生情绪波动","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"即使有生气、高兴、伤心或妒忌的事也不愿或不能表达出来","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"懂得从他人的言谈与表情中发现自己的情绪变化","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"情绪起伏很大,自己都不了解自己是为什么","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"有扪心自问的反思习惯","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"不知道自己的感情是脆弱还是坚强","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"性情不够开朗,很少湛露笑容","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"很难找到表达情绪的适当方式,要么表示愤怒,要么隐忍或委屈","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"遇到不顺心的事能够抑制自己的烦恼","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"情绪波动的起伏,往往不能自控","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"遇到意想不到的突发事件,能够冷静应对","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"精神处于紧张状态,不能自我放松","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"受到挫折或委屈,能够保持能屈能伸的乐观心态","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"对自己的期望很高,达不到标准时会很生气或发脾气","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"出现感情冲动或发怒时,能够较快的“自我熄火”","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"做什么事都很急,觉得自己属于耐不住性子的人","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"听取批评意见包括与实际情况不符的意见时,没有耿耿于怀或不乐意","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"对人对事不喜欢深思熟虑,主张“跟着感觉走”","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"在人生道路上的拼搏中,相信自己能够成功","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"不愿尝试所谓的新事物,对自己不会的事情会感到无聊、低级趣味","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"决定了要做的事不轻言放弃","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"一次想做很多事,因此显得不够专心","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"工作或学习上遇到困难,能够自我鼓励克服困难","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"对于自己该做的事,很难主动的负责到底","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"相信“失败乃成功之母”","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"没有必要要求自己什么,觉得自己做不到的事不如干脆放弃","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"办事错了差错自己总结经验教训,不怨天尤人","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"不敢担任新的职责,因为怕自己会犯错","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"对同学、同事们的脾气性格有一定的了解","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"在意别人对自己的看法,生活无法轻松自在","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"经常留意自己周围人们情绪变化","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"但别人提出问题时会不知怎样回答才让人满意","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"与人交往时知道怎样去了解和尊重他人的情感","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"与人相处时不善于了解对方的想法或怎样看待事物","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"能够说出亲人和朋友各自的一些优点和长处","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"触痛别人或伤及别人的感情是自己不能觉察","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"不认为参加社交活动是浪费时间","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"别人的感受是什么对我来说没有必要去考虑","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"没有不愿同别人合作的心态","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"对单位、学校及家庭既定的制度规则不能照章行事","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"见到他人的进步和成就没有不高兴的心情","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"对有约定在先的事,无法履行兑现,或草率了事","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"与人共事懂得不能“争功于己,诿过于人”","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"担心自己的意见或建议不好时,宁愿随声附和","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"与人相处能够“严于律己,宽以待人”","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"别人不同意自己的意见时就会表现出不满,或避而远之","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"知道失信和欺骗是友谊的大敌","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]},{"prompt":"觉得委屈就全是解决矛盾的好方法","options":[{"key":"1","text":"总是"},{"key":"2","text":"有时"},{"key":"3","text":"从不"}]}],"disclaimer":"本内容仅供自我探索与生活参考,不构成心理或医学诊断。","icon":"ask"},{"slug":"eq2","category":"eq","title":"情绪智力探索","description":"识别、理解与调节情绪的倾向","question_count":33,"questions":[{"prompt":"我知道什么时候该和别人谈论我的私人问题","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"当我面对某种困难时,我能够回忆起面对同样困难并克服它们的时候","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"我期望我能够做好我想做的大多数的事情","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"别人很容易信任我","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"我觉得我很难理解别人的身体语言","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"我生命中的一些重大事件让我重新评估了什么是重要的什么是不重要的","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"心境好的时候我就能看到新的希望","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"我的生活是否有意义,情绪是影响因素之一","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"我能清楚意识到自己体验的情绪","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"我希望能够有好的事情发生","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"我喜欢和别人分享自己的情感","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"情绪好的时候,我知道如何把它延长","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"安排有关事情,我尽可能使别人感到满意","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"我会去找一些让我感到开心的活动","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"我很清楚我传递给别人的非言语信息","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"我尽量做的好一些,以给别人留下好的印象","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"当我心情好的时候,解决问题对我来说很容易","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"通过观察面部表情,我可以辨别别人的情绪","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"我知道自己情绪变化的原因","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"心情好的时候,新奇的想法就会多一些","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"我能够控制自己的情绪","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"我很清楚自己在某一刻的情绪","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"学习时我会想象自己即将取得好成绩,以激励自己","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"当别人在某个方面做的很好时,我会称赞他们","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"我能够了解别人传递给我的非言语信息","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"当别人告诉我他人生中的某件重大事件时,我感觉好像发生在自己身上一样","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"当我感到情绪变化时,就会涌现一些新颖的想法","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"遇到困难时,一想到可能会失败,我就会退却","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"只要看一眼,我就知道别人的情绪怎样","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"当别人消沉时我能够帮助他,使他感觉好一点","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"在挫折面前,我让自己保持良好的情绪以应对挑战","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"我能够通过别人讲话的语调判断他当时的情绪","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]},{"prompt":"我很难理解别人的想法和感受","options":[{"key":"1","text":"很不符合"},{"key":"2","text":"较不符合"},{"key":"3","text":"不清楚"},{"key":"4","text":"较符合"},{"key":"5","text":"很符合"}]}],"disclaimer":"本内容仅供自我探索与生活参考,不构成心理或医学诊断。","icon":"eq"},{"slug":"duoyuan80","category":"intellect","title":"多元智能探索","description":"语言、逻辑、空间等多种智能倾向","question_count":80,"questions":[{"prompt":"词汇丰富,能够正确运用超乎年龄水平的字词。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"学习语言快速。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"语言表达流畅,善于描述、说故事等。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"喜欢阅读超乎年龄水平的书籍,阅读理解能力佳。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"对于文词的意义掌握良好,善用比喻或成语典故。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"语文推理能力良好,擅长辩论演说。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"说话及写作能够把握重点,具有高度组织能力。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"喜好文学创作,能用文字抒发情感。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"具有多种语言的能力。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"语文联想能力丰富,对于文字的敏感度高。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"喜欢思考、阅读、或谈论与数理相关的问题。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"计算能力优异,数字概念良好。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"符号运用的能力优异,抽象思考能力强。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"能利用图形、符号等代表或简化复杂的信息。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"归纳能力强,统合能力良好。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"演绎能力强,逻辑推理清晰。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"能够觉察问题,找出问题的症结所在。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"能用多种方式解题,思考灵活。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"愿意尝试超乎其年龄水平的数理题目。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"喜欢动手作实验,具有独立研究的能力。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"平面图形推理能力良好。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"立体空间透视能力良好。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"绘图能力优异,作品充满画趣。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"善用视觉记忆或思考,常用图形方式表现思考内容。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"擅长图形、模型的设计。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"美术鉴赏能力优秀,对于色彩、图形、与意象的感觉十分敏锐。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"阅读图表、地图的能力优异。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"地理位置概念清楚,在陌生的地方很快能找到方向。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"善于玩拼图、迷津、积木等视觉游戏。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"善于运用照相机、摄影机、幻灯机等拍下周围事物。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"肢体动作协调,姿态优雅。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"说话交谈时,经常使用肢体操作表达意见及情感。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"能变化各种不同的动作,表现同一主题。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"触觉优异,擅长以操作方式学习。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"善于动作模仿,拟人、拟物均极活泼生动。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"能灵活操作工具。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"学习新的技能(如:骑车、游泳等),甚为快速。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"很快便能跟着音乐节拍起舞,是个良好的表演者。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"运动能力佳,是个优秀的运动员。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"表演逼真,是很好的演剧人才。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"主动欣赏音乐,接触音乐、注意音乐活动的讯息。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"经常唱歌、吹口哨、哼曲子及打拍子等。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"能够运用生活当中的器材来表现音乐。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"能把音乐溶入日常生活中。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"听觉记忆超强,听过的曲子能说出曲名或作曲者。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"具音感、节奏、视谱能力,很快便学会新曲子。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"能够自己编曲或者改编一首歌。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"擅长某种乐器的演奏。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"音乐鉴赏能力佳,欣赏、评析乐曲有独到的见解。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"常是舞台上的演奏(唱)者。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"到户外活动,能够细心观察自然景物,喜好发问。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"对自然界的事物有浓厚的兴趣,肯关心、肯负责、肯思考。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"选取与自然界的事物有关的书籍或电视节目。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"参与垃圾分类与废弃物处理。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"常与人分享饲养小动物或种植花草树木的心得。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"尊重自然界的生命,和欣赏自然景物。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"喜欢搜集古董旧物,具有怀旧的乡土情怀。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"喜欢以大自然为题的音乐、摄影、美术或文学作品。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"参加关心野生动物、保护海洋水资源及有关的义工行为。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"常选择登山、健行、攀岩、露营、浮潜、赏鸟等休闲活动。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"经常参加团体性的活动。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"朋友很多。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"能够正确体察别人的情感。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"清楚别人对他的看法。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"能够参与团体的讨论。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"能够主动关心别人。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"受到同侪的尊重与喜爱。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"是同侪喜欢合作的对象。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"与同侪意见不同时,能够协调沟通。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"常被选为班级干部或社团领袖。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"能够了解自己的优点和缺点。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"会朝自己的目标努力,不需他人督促。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"能够修正自己的做事方式。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"独立性强,不须依赖他人。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"会自我增强,不需藉助外在的回馈。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"能以理性的方式面对别人的批评。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"能够清楚自己在团体中所应扮演的角色。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"与不同年龄背景的人相处,能够调整应对的方式。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"面对团体压力,能肯定自己的意见。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]},{"prompt":"能够调整自己错误,适时融入团体的意见。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"小部分符合"},{"key":"3","text":"部分符合"},{"key":"4","text":"大致符合"},{"key":"5","text":"完全符合"}]}],"disclaimer":"本内容仅供自我探索与生活参考,不构成心理或医学诊断。","icon":"star"},{"slug":"gd3","category":"life","title":"压力感受探索","description":"近期压力体验与负荷感","question_count":50,"questions":[{"prompt":"我受背疼之苦","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我的睡眠不足、且睡不安稳","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我有头疼","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我额部疼痛","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"若须等候,我会不安","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我的后颈感到疼痛","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我比多数人更神经紧张","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我很难入睡","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我的头感到紧或疼","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我的胃有病","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我对自己没有信心","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我对自己说话","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我忧虑财务问题","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"与人见面时,我会窘怯","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我怕发生可怕的事","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"白天我觉得累","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"下午我感到喉咙痛,但并非由于染上感冒 ","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我心情不安,无法静坐","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我感到非常口干","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我心脏有病","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我觉得自己不是很有用","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我吸烟","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我肚子不舒服","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我觉得不快乐","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我流汗","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我喝酒","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我很自觉","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我觉得自己像四分五裂","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我的眼睛又酸又累","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我的腿或脚抽筋","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我的心跳过速","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我怕结识人","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我手脚冰冷","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我患便秘","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我未经医师指示使用各种药","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我发现自己很容易哭","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我消化不良","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我咬指甲","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我耳中有嗡嗡声","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我小便频密","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我有胃溃疡","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我有皮肤方面的病","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我的咽喉很紧","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我有十二指肠溃疡病","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我担心我的工作","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我口腔溃烂","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我为琐事忧虑","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我呼吸浅促","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我觉得胸部紧迫","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]},{"prompt":"我发现很难做决定","options":[{"key":"1","text":"没有"},{"key":"2","text":"很少"},{"key":"3","text":"有时"},{"key":"4","text":"经常"},{"key":"5","text":"总是"}]}],"disclaimer":"本内容仅供自我探索与生活参考,不构成心理或医学诊断。","icon":"stress"},{"slug":"sm1","category":"life","title":"睡眠节奏自评","description":"入睡与睡眠质量的自我观察","question_count":8,"questions":[{"prompt":"入睡时间(关灯后到睡着的时间)","options":[{"key":"1","text":"没问题"},{"key":"2","text":"轻微延迟"},{"key":"3","text":"显著延迟"},{"key":"4","text":"严重延迟或没有睡觉"}]},{"prompt":"夜间苏醒","options":[{"key":"1","text":"没问题"},{"key":"2","text":"轻微影响"},{"key":"3","text":"显著影响"},{"key":"4","text":"严重影响或没有睡觉"}]},{"prompt":"比期望的时间早醒","options":[{"key":"1","text":"没问题"},{"key":"2","text":"轻微提早"},{"key":"3","text":"显著提早"},{"key":"4","text":"严重提早或没有睡觉"}]},{"prompt":"总睡眠时间","options":[{"key":"1","text":"足够"},{"key":"2","text":"轻微不足"},{"key":"3","text":"显著不足"},{"key":"4","text":"严重不足或没有睡觉"}]},{"prompt":"总睡眠质量(无论睡多长)","options":[{"key":"1","text":"满意"},{"key":"2","text":"轻微不满"},{"key":"3","text":"显著不满"},{"key":"4","text":"严重不满或没有睡觉"}]},{"prompt":"白天情绪","options":[{"key":"1","text":"正常"},{"key":"2","text":"轻微低落"},{"key":"3","text":"显著低落"},{"key":"4","text":"严重低落"}]},{"prompt":"白天身体功能(体力和精神,如记忆力、认识和注意力等)","options":[{"key":"1","text":"足够"},{"key":"2","text":"轻微影响"},{"key":"3","text":"显著影响"},{"key":"4","text":"严重影响"}]},{"prompt":"白天思睡","options":[{"key":"1","text":"无思睡"},{"key":"2","text":"轻微思睡"},{"key":"3","text":"显著思睡"},{"key":"4","text":"严重思睡"}]}],"disclaimer":"本内容仅供自我探索与生活参考,不构成心理或医学诊断。","icon":"sleep"},{"slug":"gd2","category":"life","title":"爱情态度探索","description":"亲密关系中的态度与期待","question_count":42,"questions":[{"prompt":"我和他/她属于一见钟情型。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我很难明确地说我和他/她是何时从友情变成爱情","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"对他/她做承诺之前,我会考虑他/她将来可能变成的样子","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我总是试着帮他/她度过难关。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"和他/她的关系不太对劲时,我的身体就会不舒服。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我试着不给他/她明确的承诺。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"在选择他/她之前,我会先试着仔细规划我的人生。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我宁愿自己痛苦,也不愿意让他/她受苦。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"失恋时,我会十分沮丧,甚至会有自杀的念头。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我相信他/她不知道我的一些事,也不会受到伤害。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我和他/她很来电。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我需要先经过一阵子的关心和照顾,才有可能产生爱情","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我和他/她最好有相似的背景。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"有时候,我得防范他/她发现我还有其他情人。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我和他/她的亲密行为是很热情且很令我满意。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我有时会因为想到自己正在谈恋爱而兴奋地睡不着觉","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我可以很容易很快地忘掉过往的恋情。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"他/她如何看待我的家人是我选择他/她的主要考量","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我希望和曾经相爱的他/她是永远的朋友。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"当他/她不注意我时,我会全身不舒服。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我和他/她的爱情关系是最理想因为是由长久的友谊发展而成的","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我觉得我和他/她是天生一对。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"自从和他/她谈恋爱后,我很难专心在其他任何事情上","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"他/她将来会不会是一个好父亲/母亲是我选择他/她的一个重要因素","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"除非我先让他/她快乐,否则我不会感到快乐。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"如果他/她知道我和其他人做了某些事,他/她会不高兴","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我和他/她的感情亲密行为进展得很快。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我和他/她的友情随着时间逐渐转变为爱情。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"当他/她太依赖我时,我会想和他/她疏远一些。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我通常愿意牺牲自己的愿望,达成他/她的愿望。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我和他/她的爱情是一种深刻的友情,而不是一种很神秘的情感","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"他/她可以任意使用我的东西。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我和他/她非常了解彼此。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"当我怀疑他/她和其他人在一起时,我就无法放松。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"他/她如何看待我的职业会是我选择他/她的一个考量","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"他/她的外貌符合我的理想标准。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我享受和他/她及一些不同的情人玩爱情游戏。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"当他/她对我发脾气时,我仍然全心全意无条件的爱他/她。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"在和他/她深入交往之前,我会试着了解他/她是否有良好的遗传基因","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"为了他/她,我愿意忍受任何事情。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"如果他/她忽略我一阵子,我会做出一些傻事来吸/她的注意力。","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]},{"prompt":"我和他/她的爱情关系是最令人满意,因为是由良好友情发展成的","options":[{"key":"1","text":"完全不符合"},{"key":"2","text":"有点不符合"},{"key":"3","text":"没意见"},{"key":"4","text":"有点符合"},{"key":"5","text":"完全符合"}]}],"disclaimer":"本内容仅供自我探索与生活参考,不构成心理或医学诊断。","icon":"relation"},{"slug":"gd1","category":"life","title":"亲密关系质量探索","description":"伴侣互动与关系满意度参考","question_count":124,"questions":[{"prompt":"夫妻双方都喜爱同一类的社会活动","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"向配偶表达我真实的感受是非常容易的","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"对我所受到的有关宗教信仰的教育,我很难全盘接受","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"为了尽早结束争吵,我常立即让步","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"在我们家里,父亲和孩子呆在一起所花的时间不够","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"当夫妻间出现矛盾时,我的配偶常沉默不语","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"亲友中一些人使我们的婚姻变得紧张","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我的配偶过于挑剔或经常持否定的观点","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我完全满意配偶对我的感情","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我和配偶就如何采取最佳方法解决矛盾常常意见不一","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我认为夫妻双方对宗教应有相同的理解","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我认为妇女主要应呆在家里","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"有时,我对配偶的脾气很在意","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我不喜欢配偶的性格和个人习惯","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"为了使性关系保持乐趣,我们尝试找一些新的方法","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"有时,我希望配偶别乱花钱","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我的配偶似乎缺少时间与精力与我一起娱乐","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我宁愿做别的任何事情,也不愿独自呆一个晚上","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我非常满意夫妻双方在婚姻中承担的责任","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我和配偶对怎样花钱总是意见一致","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我很满意我们对抚养子女的责任分工","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"共同的信仰有助于我们的关系发展","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"如果夫妻双方都有工作,丈夫应该与妻子承担同样多的家务劳动","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"有时,我对配偶显得不愉快和孤僻感到担心","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我担心配偶可能在性方面对我不感兴趣","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我们很难在经济安排上作出决定","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我们为亲友花费的时间很恰当","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"对配偶兴趣或爱好过少,我很在意","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"除非经济上需要,我的妻子不应外出工作","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我配偶抽烟和/或饮酒成问题","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"与配偶参加社交活动,我很少感到压力","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我不满意夫妻间的交流,我的配偶并不理解我","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"对于我们家怎样和在何处度假,我总是觉得满意","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我们夫妻间完全相互理解","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"在管教子女方面,夫妻意见一致","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我非常满意我们作决定和解决冲突的方式","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"有时,我的配偶不依赖我,不总是人云亦云","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"对于家庭应储蓄多少钱的决定,我感到满意","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"当讨论某一问题时,我通常感到配偶是理解我的","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我的配偶有时发表一些贬低我的意见","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"与配偶谈论性问题,对我来说是很容易和轻松的","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我的配偶对我的每一次情绪变化都完全理解并有相同的感受","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"在我们的婚姻中,妻子应更加顺从丈夫的愿望","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"当我们与别人共处时,有时我为配偶的行为感到不安","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我们都知道我们所欠的债务,而且它不成问题","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我的宗教信仰是影响我们婚姻的一个重要部分","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"有时,我担心配偶会有寻求婚外性关系的想法","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我认为配偶与他/她的家里过于密切或受其影响太大","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"子女似乎是我们婚姻中矛盾的一个主要来源","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我们对所需子女的数量意见一致","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我们按我们的经济实力有规律地花钱","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我不满意我们的经济地位和决定经济事务的方法","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我非常满意我们的业余活动和夫妻一起度过的时间","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"有时,我不敢找配偶要我需要的东西","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"即使妻子在外工作,也应该负担管理家务的责任","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"夫妻双方在与宗教信仰有关的活动中意见不一","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"与我的或配偶家的亲戚在一起,我感到不愉快","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"当我遇到困难时,我总是告诉配偶","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我的配偶对子女的关注超过对我们的婚姻,这使我不舒服","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我觉得我们的假期与旅游过得很好","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我们家丈夫是一家之主","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"对我来说,我们的性关系是满意与完美的","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"有时,我的配偶太固执","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我们的婚姻是非常成功的","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"与配偶一起祈祷,对我很重要","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我希望配偶更愿意与我分享他/她的感受","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"有了孩子,使我们的婚姻关系更密切","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我的配偶喜欢我所有的朋友","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我不愿对配偶表现出很温柔,因为它经常被误解为是一种性的表示","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我觉得我们的婚姻关系缺少某些东西","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"有时在一些不重要的问题上我们常产生严重的争执","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我感到夫妻双方没有花费足够的时间一起度过业余空暇","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"有时,我很难相信配偶告诉我的每一件事","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我尽量避免与配偶发生冲突","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"对于我们来说,丈夫的职业较妻子的职业更重要","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我觉得我们的婚姻受到宗教观念影响","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我们的经济已变得紧张,如赊帐过多","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"配偶经常拖拖拉拉,使我很烦恼","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"有时,我觉得夫妻之间的争执没完没了,从得不到解决","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"如果家里有很小的子女,妻子不应外出工作","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我经常不把我的感受告诉配偶,因为他/她应该体会得到","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"对于我们夫妻之间怎样表达情感与性有关的事,我很满意","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"当夫妻间出现意见不一时,我们开诚布公地交流感受和决定怎样来解决它","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"除非与配偶在一起,否则我很少开玩笑","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我们很注重决定怎样把钱花在最重要的事情上","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"有时我的配偶与朋友在一起的时间太多","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我和配偶在对子女进行宗教教育方面有不同的意见","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"对于承担做父母的责任分工上,我不满意","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"爱配偶,使我更深地体会到:上帝是慈爱的","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我觉得双方的父母过高地期望得到我们的关心和帮助","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我非常满意夫妻之间相互谈话的方式","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我觉得我们的父母给我们的婚姻造成问题","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我很烦恼,没有配偶的允许我不能花钱","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"自从有了孩子,夫妻间很少有时间单独在一起","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"对于配偶的喜怒无常,有时我感到束手无策","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我经常感到配偶没有认真对待我们的分岐","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"在我们家里,丈夫在大多数重要的事情上应有最后的决定权","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"因为担心配偶发脾气,所以我不总是把心里的一些烦恼告诉他/她","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我不满意我们与双方父母、朋友的关系","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我和配偶对我所受的宗教方面的教育意见不一","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我从不后悔与我父母的关系,哪怕是一瞬间","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"应该为子女做多少事,是我们发生冲突的一个原因","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我确实很高兴与配偶所有的朋友来往","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"因为我们的宗教信仰,我和配偶觉得很亲密","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"妻子在重要问题上应该相信与接受丈夫的判断","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"有时,我很在意配偶的性兴趣与我不一致","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我很满意关于家庭计划和生育子女数的决定","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我不在意配偶与异性朋友在一起","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我说话时,配偶总是认真听着","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我很在意谁管钱","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"配偶应用不公平的方式同意或拒绝性生活,使我很烦恼","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"当我们争吵时,我通常不去想这是我的过错","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"对于我们的宗教信仰与价值观,我觉得很好","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我和配偶在一起和分开度过的业余时间分配很公平","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"有时,我认为配偶过于盛气凌人","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我认为任何生活在一起的配偶都没有我们夫妻和睦","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"有时我觉得对配偶感觉不到爱和感情","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"有时配偶做一些使我不愉快的事","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"如果配偶有何过错,我也没意识到","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"即使世界上每一个异性都愿与我结婚,我也不能做出比现在婚姻更好的选择","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我们夫妻比世界上任何人都相互适应得好","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"关于配偶的每一件新鲜事都使我高兴","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"我们的关系比它应有的状况更好","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]},{"prompt":"当我和配偶在一起时,我觉得任何人都不可能比我们幸福","options":[{"key":"1","text":"确实这样"},{"key":"2","text":"可能这样"},{"key":"3","text":"不同意不反对"},{"key":"4","text":"可能不是这样"},{"key":"5","text":"确实不是这样"}]}],"disclaimer":"本内容仅供自我探索与生活参考,不构成心理或医学诊断。","icon":"synastry"},{"slug":"gd4","category":"life","title":"家庭氛围探索","description":"家庭互动与氛围感受","question_count":90,"questions":[{"prompt":"我们家庭成员都总是互相给予最大的帮助和支持","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员总是把自己的感情藏在心里,不向其他家庭成员透露","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家中经常吵架","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在家中我们很少自己单独活动","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员无论做什么事情都是尽力而为的","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们家经常谈论政治和社会问题","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"大多数周末和晚上家庭成员都是在家中度过,而不外出参加社交和娱乐活动","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们都认为不管有多大困难,子女应该首先满足老人的各种需求","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家中较大的活动都是经过仔细安排的","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家里人很少强求其他家庭成员遵守家规","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在家里我们感到很无聊","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在家里我们想说什么就可以说什么","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员彼此之间很少公开发怒","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们都非常鼓励家里人具有独立精神","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"为了有好的前途,家庭成员都花了几乎所有的精力","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们很少外出听讲座、看电影或去博物馆以及看展览","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员常外出到朋友家去玩并在一起吃饭","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员都认为做事应顺应社会风气","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"一般来说,我们大家都注意把家收拾得井井有条","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家中很少有固定的生活规律和家规","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员愿意花很大的精力做家里的事","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在家中诉苦很容易使家人厌烦","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"有时家庭成员发怒时摔东西","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员都独立思考问题","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员都认为使生活水平提高比其他任何事情都重要","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们都认为学会新的知识比其他任何事都重要","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家中没人参加各种体育活动","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员在生活上经常帮助周围的老年人和残疾人","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在我们家里,当需要用某些东西时却常常找不到","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在我们家吃饭和睡觉的时间都是一成不变的","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在我们家里有一种和谐一致的气氛","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家中每一个人都可以诉说自己的困难和烦恼","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员之间极少发脾气","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们家的每个人的出入是完全自由的","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们都相信在任何情况下竞争是好事","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们对文化活动不那么感兴趣","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们常看电影或体育比赛、外出郊游等","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们认为行贿受贿是一种可以接受的现象","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在我们家很重视做事要准时","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们家做任何事都有固定的方式","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家里有事时很少有人自愿去做","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员经常公开地表达相互之间的感情","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员之间常互相责备和批评","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员做事时很少考虑家里其他人的意见","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们总是不断反省自己,强迫自己尽力把事情做得一次比一次好","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们很少讨论有关科技知识方面的问题","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们家每个人都对1~2项娱乐活动特别感兴趣","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们认为无论怎么样,晚辈都应该接受长辈的劝导","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们家的人常常改变他们的计划","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们家非常强调要遵守固定的生活规律和家规","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员都总是衷心地互相支持","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"如果在家里说出对家事的不满,会有人觉得不舒服","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员有时互相打架","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员都依赖家人的帮助去解决他们遇到的困难","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员不太关心职务升级、学习成绩等问题","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家中有人玩乐器","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员除工作学习外,不常进行娱乐活动","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员都自愿维护公共环境卫生","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员认真地保持自己房间的整洁","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员夜间可以随意外出,不必事先与家人商量","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们家的集体精神很少","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们家里可以公开地谈论家里的经济问题","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员的意见产生分歧时,我们都一直回避它,以保持和气","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员希望家里人独立解决问题","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们家里人对获得成就并不那么积极","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员常去图书馆","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员有时按个人爱好或兴趣参加娱乐性学习","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员都认为要死守道德教条去办事","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在我们家每个人的分工是明确的","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在我们家没有严格的规则来约束我们","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员彼此之间都一直合得来","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员之间讲话时都很注意避免伤害对方的感情","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员常彼此想胜过对方","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"如果家庭成员经常独自活动,会伤家里其他人的感情","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"先工作后享受是我们家的老习惯","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在我们家看电视比读书更重要","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员常在业余时间参加家庭以外的社交活动","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们认为无论怎么样,离婚是不道德的","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们家花钱没有计划","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们家的生活规律或家规是不能改变的","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭的每个成员都一直得到充分的关心","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们家经常自发地谈论家人很敏感的问题","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家人有矛盾时,有时会大声争吵","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在我们家确实鼓励成员都自由活动","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员常常与别人比较,看谁的学习工作好","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"家庭成员很喜欢音乐、艺术和文学","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们娱乐活动的方式是看电视、听广播而不是外出活动","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们认为提高家里的生活水平比严守道德标准还要重要","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"我们家饭后必须立即有人去洗碗","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]},{"prompt":"在家里违反家规者会受到严厉的批评","options":[{"key":"1","text":"是"},{"key":"2","text":"否"}]}],"disclaimer":"本内容仅供自我探索与生活参考,不构成心理或医学诊断。","icon":"companion"},{"slug":"xl13","category":"life","title":"应对方式探索","description":"面对压力时的惯用策略","question_count":88,"questions":[{"prompt":"我因帮助他人而获得满足,如果不这样做,我就会变得情绪抑郁","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"人们常说我是个脾气暴躁的人","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"在我没有时间处理某个棘手的事情时,我可以把它搁置一边","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"人们总是不公平地对待我","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我通过做一些积极的或创见性的事情来摆脱自己的焦虑不安,如绘画、做木工活等","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"偶尔,我把一些今天该做的事情推迟到明天再做","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我不知道为什么会遇到相同的受挫情境","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我能够相当轻松地嘲笑我自己","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我受到挫折时,表现就象个孩子","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"在维护我的利益方面,我羞于与人计较","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我比我认识人中的大多数都强","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"人们往往虐待我","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"如果某人骗了我或偷了我的钱,我宁愿他得到帮助,而不是受惩罚","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"偶尔,我想一些坏得不能说出口的事情","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"偶尔,我因一些下流的笑话而大笑","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"人们说我象一只驼鸟,把自己的头埋入沙中,换句话说,我往往有意忽视一些不愉快的事情","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我常常不能竭尽全力地与人竞争","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我常感到我比和我在一起的人强","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"某人正在想剥夺我所得到的一切","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我有时发怒","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我时常在某种内在力量的驱使下,不由自主地做出些行为","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我宁愿饿死而不愿被迫吃饭","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我常常故意忽视一些危险,似乎我是个超人","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我以有贬低别人威望的能力而自豪","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"人们告诉我:我总有被害的感觉","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"有时感觉不好时,我就发脾气","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"当某些事情使我烦脑时,我常常不由自主地做出些行为","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"当遇事不顺心时,我就会生病","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我是一个很有自制力的人","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我简直就像一个不得志的艺术家一样","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我不总是说真话","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"当我感到自尊心受伤害时,我就会回避","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我常常不由自主地迫使自己干些过头的事情,以至于其他人不得不限制我","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我的朋友们把我看做乡下佬","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"在我愤怒的时候,我常常回避","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我往往对那些确实对我友好的人,比我应该怀疑的人保持更高的警惕性","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我已学得特殊的才能,足以使我毫无问题地渡过一生","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"有时,在选举的时候,我往往选那些我几乎不了解的人","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我常常不能按时赴约","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我幻想的多,可在现实生活中做的少","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我羞于与人打交道","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我什么都不怕","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"有时我认为我是个天使,有时我认为我是个恶魔","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"在比赛时,我宁要赢而不愿输","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"在我愤怒的时候,我变得很愿挖苦人","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"在我自尊心受伤害时,我就公开还击","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我认为当我受伤害时,我就应该翻脸","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我每天读报时,不是每个版面都读","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我沮丧时,就会避开","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我对性问题感到害羞","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我总是感到我所认识的某个人象个保护神","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我的处世哲学是:“非理勿信,非理勿做,非理勿视”","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我认为:人有好坏之分","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"如果我的上司惹我生气,我可能会在工作中找麻烦或磨洋工,以报复他","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"每个人都和我对着干","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我往往对那些我讨厌的人而表示友好","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"如果我乘坐的飞机一个发动机失灵,我就会非常紧张","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我认识这样一个人,他什么都能做而且做得合理正直","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"如果我感情的发泄会防碍我正从事的事业,那么我就能控制住它","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"一些人正在密谋要害我","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我通常可以看到恶境当中的好的一面","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"在我不得不去做一些我不愿做的事情时,就头痛","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我常常发现我对那些理应仇视的人,表示很友好","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我认为:“人人都有善意”是不存在的,如果你不好,那么你一切都不好","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我决不会对那些我讨厌的人表示愤怒","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我确信生活对我是不公正的","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"在严重的打击下,我就会垮下来","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"在我意识到不得不面临一场困境的时候,如考试,招工会谈","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"医生们决不会真的弄清我患的是什么病","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"当某个和我很亲近的人死去时,我并不悲伤","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"在我为了利益和人争斗之后,我往往因为我的粗鲁而向人道歉","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"发生与我有关的大部分事情并不是我的责任","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"当我感觉情绪压抑或焦虑不安时,吃点东西,可以使我感觉好些","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"勤奋工作使我感觉好些","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"医生不能真的帮我解决问题","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我常听人们说我不暴露自己的感情","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我认为,人们在看电影,戏剧或书籍对所领悟的意义,比这些作品所要表达的意义要多","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我感觉到我有一些不由自主要去做的习惯或仪式行为,并给我带来很多麻烦","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"当我紧张时,就喝酒或吃药","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"当我心情不愉快时,就想和别人呆在一起","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"如果我能够预感到我会沮丧的话,我就能更好地应付它","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"无论我怎样发牢骚,从未得到过满意的结果","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"我常常发现当环境要引起我强烈的情绪反应时,我就会麻木不仁","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"忘我地工作,可使我摆脱情绪上的忧郁和焦虑","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"紧张的时候,我就吸烟","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"如果我陷入某种危机时,我就会寻找另一个和我具有同样命运的人","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"如我做错了事情,不能受责备","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]},{"prompt":"如果我有攻击他人的想法,我就感觉有种做点事情的需要,以转移这种想法","options":[{"key":"1","text":"1.完全反对"},{"key":"2","text":"2.很反对"},{"key":"3","text":"3.比较反对"},{"key":"4","text":"4.稍微反对"},{"key":"5","text":"5.不反对也不同意"},{"key":"6","text":"6.稍微同意"},{"key":"7","text":"7.比较同意"},{"key":"8","text":"8.很同意"},{"key":"9","text":"9.完全同意"}]}],"disclaimer":"本内容仅供自我探索与生活参考,不构成心理或医学诊断。","icon":"rhythm"}]} \ No newline at end of file diff --git a/apps/api/internal/service/analytics/service.go b/apps/api/internal/service/analytics/service.go index e99fd0e..1f259e7 100644 --- a/apps/api/internal/service/analytics/service.go +++ b/apps/api/internal/service/analytics/service.go @@ -46,6 +46,15 @@ var allowedNames = map[string]struct{}{ "synastry_invite_created": {}, "synastry_invite_accepted": {}, "synastry_nearby_opened": {}, "star_wheel_viewed": {}, "companion_viewed": {}, "mood_saved": {}, "cards_scene_selected": {}, "cards_drawn": {}, "cards_quota_exhausted": {}, + "star_completed": {}, "rhythm_completed": {}, + "auth_register": {}, "auth_login": {}, "auth_logout": {}, + "avatar_sheet_opened": {}, "avatar_upload_succeeded": {}, "avatar_upload_failed": {}, + "nickname_updated": {}, + "scale_list_viewed": {}, "scale_bank_category_viewed": {}, + "scale_started": {}, "scale_completed": {}, "scale_result_reopened": {}, + "scale_retake_clicked": {}, "scale_locked_viewed": {}, "scale_share_clicked": {}, + "scale_cta_relation": {}, "scale_cta_ask": {}, + "growth_plan_viewed": {}, "growth_plan_created": {}, "growth_plan_checkin": {}, } var allowedPropKeys = map[string]struct{}{ @@ -53,9 +62,11 @@ var allowedPropKeys = map[string]struct{}{ "element_id": {}, "exit_page": {}, "duration_ms": {}, "cold": {}, "app_ver": {}, "source": {}, "kind": {}, "surface": {}, "label": {}, "plan": {}, "count": {}, "depth": {}, "scene": {}, "score": {}, "planet": {}, "report_id": {}, + "slug": {}, "category": {}, "reason": {}, "access": {}, } var funnelDefault = []string{ + "scale_list_viewed", "scale_started", "scale_completed", "portrait_completed", "deep_access_clicked", "purchase_completed", } diff --git a/apps/api/internal/service/ask/service.go b/apps/api/internal/service/ask/service.go index 5da01d5..a529d52 100644 --- a/apps/api/internal/service/ask/service.go +++ b/apps/api/internal/service/ask/service.go @@ -15,6 +15,7 @@ import ( "github.com/yuxingu/digital-psychology/apps/api/internal/llm/deepseek" "github.com/yuxingu/digital-psychology/apps/api/internal/model" "github.com/yuxingu/digital-psychology/apps/api/internal/repository" + "github.com/yuxingu/digital-psychology/apps/api/internal/textsafe" ) // FreeQuota is the number of assistant replies allowed without membership. @@ -42,7 +43,11 @@ func (s *Service) CreateThread(ctx context.Context, userID uuid.UUID, in CreateT return nil, errors.New("profile not found") } var scene *string - if sc := strings.TrimSpace(in.Scene); sc != "" { + if strings.TrimSpace(in.Scene) != "" { + sc, err := textsafe.Check(textsafe.Scene, in.Scene) + if err != nil { + return nil, err + } scene = &sc } return s.Ask.CreateThread(ctx, userID, in.ProfileID, scene) @@ -137,12 +142,10 @@ type SendResult struct { // SendMessage stores user content, consumes quota, generates assistant reply. func (s *Service) SendMessage(ctx context.Context, userID, threadID uuid.UUID, content string) (*SendResult, error) { - content = strings.TrimSpace(content) - if content == "" { - return nil, errors.New("content required") - } - if len([]rune(content)) > 2000 { - return nil, errors.New("content too long") + var err error + content, err = textsafe.Check(textsafe.AskContent, content) + if err != nil { + return nil, err } thread, err := s.Ask.GetThreadForUser(ctx, userID, threadID) @@ -281,12 +284,10 @@ func (s *Service) StreamMessage(ctx context.Context, userID, threadID uuid.UUID, if emit == nil { return errors.New("emit required") } - content = strings.TrimSpace(content) - if content == "" { - return errors.New("content required") - } - if len([]rune(content)) > 2000 { - return errors.New("content too long") + var err error + content, err = textsafe.Check(textsafe.AskContent, content) + if err != nil { + return err } thread, err := s.Ask.GetThreadForUser(ctx, userID, threadID) diff --git a/apps/api/internal/service/auth/service.go b/apps/api/internal/service/auth/service.go index e2c9f3f..4fcdc65 100644 --- a/apps/api/internal/service/auth/service.go +++ b/apps/api/internal/service/auth/service.go @@ -5,6 +5,7 @@ import ( "crypto/rand" "encoding/hex" "errors" + "mime/multipart" "strings" "time" @@ -12,21 +13,25 @@ import ( "github.com/jackc/pgx/v5" "golang.org/x/crypto/bcrypt" + "github.com/yuxingu/digital-psychology/apps/api/internal/avatar" nickgen "github.com/yuxingu/digital-psychology/apps/api/internal/nickname" "github.com/yuxingu/digital-psychology/apps/api/internal/repository" + "github.com/yuxingu/digital-psychology/apps/api/internal/textsafe" ) // Service handles register/login sessions. // Temporary open mode: any non-empty phone+password can enter; missing accounts are created. type Service struct { - Repo *repository.AuthRepo + Repo *repository.AuthRepo + AvatarDir string } // Me is the public account payload. type Me struct { - ID string `json:"id"` - Phone string `json:"phone"` - Nickname string `json:"nickname"` + ID string `json:"id"` + Phone string `json:"phone"` + Nickname string `json:"nickname"` + AvatarURL string `json:"avatar_url,omitempty"` } // SessionResult is returned after register/login. @@ -34,6 +39,7 @@ type SessionResult struct { Token string `json:"token"` ExpiresAt time.Time `json:"expires_at"` User Me `json:"user"` + IsNew bool `json:"is_new"` } // Register upgrades or opens an account (same open rules as Login). @@ -52,7 +58,14 @@ func (s *Service) OpenLogin(ctx context.Context, deviceUserID uuid.UUID, deviceK if phone == "" { return nil, errors.New("请填写手机号") } - nickIn = nickgen.Normalize(nickIn) + nickIn = strings.TrimSpace(nickIn) + if nickIn != "" { + n, err := textsafe.Check(textsafe.Nickname, nickIn) + if err != nil { + return nil, err + } + nickIn = n + } hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { return nil, err @@ -73,7 +86,7 @@ func (s *Service) OpenLogin(ctx context.Context, deviceUserID uuid.UUID, deviceK nick = nickgen.Random() _ = s.Repo.UpdateNickname(ctx, acc.ID, nick) } - return s.issue(ctx, acc.ID, acc.Phone, nick) + return s.issue(ctx, acc.ID, acc.Phone, nick, false) } if !errors.Is(err, pgx.ErrNoRows) { return nil, err @@ -99,18 +112,23 @@ func (s *Service) OpenLogin(ctx context.Context, deviceUserID uuid.UUID, deviceK if deviceKey != "" { _ = s.Repo.BindDevice(ctx, deviceKey, uid) } - return s.issue(ctx, uid, phone, nick) + return s.issue(ctx, uid, phone, nick, true) } // UpdateNickname changes account display nickname (1–16 chars). func (s *Service) UpdateNickname(ctx context.Context, userID uuid.UUID, nick string) (*Me, error) { - nick = nickgen.Normalize(nick) - if nick == "" { - return nil, errors.New("请填写昵称") + nick, err := textsafe.Check(textsafe.Nickname, nick) + if err != nil { + return nil, err } if err := s.Repo.UpdateNickname(ctx, userID, nick); err != nil { return nil, err } + return s.Me(ctx, userID) +} + +// UpdateAvatar stores profile photo and returns updated me. +func (s *Service) UpdateAvatar(ctx context.Context, userID uuid.UUID, fh *multipart.FileHeader) (*Me, error) { acc, err := s.Repo.GetAccount(ctx, userID) if err != nil { return nil, err @@ -118,7 +136,18 @@ func (s *Service) UpdateNickname(ctx context.Context, userID uuid.UUID, nick str if acc.Phone == "" { return nil, errors.New("未登录") } - return &Me{ID: acc.ID.String(), Phone: maskPhone(acc.Phone), Nickname: acc.Nickname}, nil + dir := s.AvatarDir + if dir == "" { + dir = "data/avatars" + } + path, err := avatar.Store(dir, userID, fh) + if err != nil { + return nil, err + } + if err := s.Repo.UpdateAvatarURL(ctx, userID, path); err != nil { + return nil, err + } + return s.Me(ctx, userID) } // Logout revokes the current bearer session and unbinds the device from the account @@ -141,7 +170,7 @@ func (s *Service) Me(ctx context.Context, userID uuid.UUID) (*Me, error) { if acc.Phone == "" { return nil, errors.New("未登录") } - return &Me{ID: acc.ID.String(), Phone: maskPhone(acc.Phone), Nickname: acc.Nickname}, nil + return toMe(acc), nil } // ResolveSessionUser returns user id for a live token. @@ -154,18 +183,32 @@ func (s *Service) IsRegistered(ctx context.Context, userID uuid.UUID) (bool, err return s.Repo.IsRegistered(ctx, userID) } -func (s *Service) issue(ctx context.Context, userID uuid.UUID, phone, nickname string) (*SessionResult, error) { +func (s *Service) issue(ctx context.Context, userID uuid.UUID, phone, nickname string, isNew bool) (*SessionResult, error) { tok := "usr_" + randomHex(24) exp := time.Now().Add(30 * 24 * time.Hour) if err := s.Repo.CreateSession(ctx, userID, tok, exp); err != nil { return nil, err } + me := &Me{ID: userID.String(), Phone: maskPhone(phone), Nickname: nickname} + if acc, err := s.Repo.GetAccount(ctx, userID); err == nil { + me = toMe(acc) + } return &SessionResult{ Token: tok, ExpiresAt: exp, - User: Me{ID: userID.String(), Phone: maskPhone(phone), Nickname: nickname}, + User: *me, + IsNew: isNew, }, nil } +func toMe(acc *repository.AccountRow) *Me { + return &Me{ + ID: acc.ID.String(), + Phone: maskPhone(acc.Phone), + Nickname: acc.Nickname, + AvatarURL: acc.AvatarURL, + } +} + func maskPhone(p string) string { if len(p) != 11 { return p diff --git a/apps/api/internal/service/bootstrap/service.go b/apps/api/internal/service/bootstrap/service.go index 02d345b..b186a51 100644 --- a/apps/api/internal/service/bootstrap/service.go +++ b/apps/api/internal/service/bootstrap/service.go @@ -67,8 +67,10 @@ func (s *Service) genSolo(ctx context.Context, userID uuid.UUID, p *model.Profil log.Printf("bootstrap portrait: %v", err) } + now := time.Now().In(time.FixedZone("CST", 8*3600)) outS, err := star.BuildWith(star.BuildOpts{ Birth: p.BirthDate, BirthTime: p.BirthTime, BirthPlace: p.BirthPlace, Name: p.DisplayName, + AsOf: now, }) if err != nil { log.Printf("bootstrap star: %v", err) @@ -80,7 +82,7 @@ func (s *Service) genSolo(ctx context.Context, userID uuid.UUID, p *model.Profil } } - outR := rhythm.Build(p.BirthDate, p.DisplayName) + outR := rhythm.BuildWith(p.BirthDate, p.DisplayName, now) sum, _ = json.Marshal(outR.Summary) det, _ = json.Marshal(outR.Detail) if _, err := s.Reports.UpsertWithPeer(ctx, userID, p.ID, nil, "rhythm", sum, det); err != nil { diff --git a/apps/api/internal/service/companion/service.go b/apps/api/internal/service/companion/service.go index 1d72a84..eacb1cb 100644 --- a/apps/api/internal/service/companion/service.go +++ b/apps/api/internal/service/companion/service.go @@ -3,7 +3,6 @@ package companion import ( "context" "errors" - "strings" "time" "github.com/google/uuid" @@ -12,6 +11,7 @@ import ( core "github.com/yuxingu/digital-psychology/apps/api/internal/companion" "github.com/yuxingu/digital-psychology/apps/api/internal/model" "github.com/yuxingu/digital-psychology/apps/api/internal/repository" + "github.com/yuxingu/digital-psychology/apps/api/internal/textsafe" ) // Service exposes solar terms and moods. @@ -37,11 +37,15 @@ func (s *Service) SaveMood(ctx context.Context, userID uuid.UUID, in SaveMoodInp return nil, errors.New("score must be 1-5") } if in.Note != nil { - n := strings.TrimSpace(*in.Note) - if len([]rune(n)) > 200 { - return nil, errors.New("note too long") + n, err := textsafe.Check(textsafe.Note, *in.Note) + if err != nil { + return nil, err + } + if n == "" { + in.Note = nil + } else { + in.Note = &n } - in.Note = &n } day := time.Now() if in.Day != nil { diff --git a/apps/api/internal/service/home/daily_tips.go b/apps/api/internal/service/home/daily_tips.go index 970e3cb..44f2224 100644 --- a/apps/api/internal/service/home/daily_tips.go +++ b/apps/api/internal/service/home/daily_tips.go @@ -14,6 +14,7 @@ import ( "github.com/yuxingu/digital-psychology/apps/api/internal/llm/deepseek" "github.com/yuxingu/digital-psychology/apps/api/internal/model" + "github.com/yuxingu/digital-psychology/apps/api/internal/repository" "github.com/yuxingu/digital-psychology/apps/api/internal/yijing" ) @@ -33,58 +34,131 @@ type DailyTips struct { Source string `json:"source"` // llm | fallback GuaName string `json:"gua_name,omitempty"` DayPart string `json:"day_part,omitempty"` + AsOf string `json:"as_of"` // YYYY-MM-DD + Shichen int `json:"shichen"` + ShichenName string `json:"shichen_name"` + ValidUntil string `json:"valid_until"` // RFC3339 next 时辰 start NeedBirth bool `json:"need_birth"` } -type tipsCacheEntry struct { +type tipsMemEntry struct { tips DailyTips - exp time.Time } -var tipsCache sync.Map // key string → tipsCacheEntry +var ( + tipsMem sync.Map // cacheKey → tipsMemEntry + tipsInflight sync.Map // cacheKey → *sync.Mutex generating +) -// DailyTips returns personalized tips; falls back when LLM / profile unavailable. +func tipsCacheKey(userID uuid.UUID, start time.Time) string { + return userID.String() + ":" + start.UTC().Format(time.RFC3339) +} + +// DailyTips returns tips for the current 时辰; prefers cache, never blocks on LLM. func (s *Service) DailyTips(ctx context.Context, userID uuid.UUID) (*DailyTips, error) { now := time.Now() + loc, err := time.LoadLocation("Asia/Shanghai") + if err != nil { + loc = time.FixedZone("CST", 8*3600) + } + now = now.In(loc) + win := CurrentShichen(now) + asOf := now.Format("2006-01-02") + self, ok := s.findSelf(ctx, userID) - if !ok { - fb := fallbackTips(now, "", nil) - fb.NeedBirth = true + if !ok || userID == uuid.Nil { + fb := decorateTips(fallbackTips(now, "", nil), win, asOf, true) return fb, nil } birth := self.BirthDate.Format("2006-01-02") - yc := yijing.Seed(birth, self.BirthTime, now) - cacheKey := fmt.Sprintf("%s:%s:%s:%d", userID, birth, now.Format("2006-01-02"), now.Hour()/3) - if v, hit := tipsCache.Load(cacheKey); hit { - e := v.(tipsCacheEntry) - if time.Now().Before(e.exp) { - out := e.tips - return &out, nil + key := tipsCacheKey(userID, win.Start) + + if v, hit := tipsMem.Load(key); hit { + out := v.(tipsMemEntry).tips + return decorateTips(&out, win, asOf, false), nil + } + if s.Tips != nil { + if raw, source, err := s.Tips.GetTips(ctx, userID, win.Start); err == nil { + var t DailyTips + if json.Unmarshal(raw, &t) == nil { + t.Source = source + tipsMem.Store(key, tipsMemEntry{tips: t}) + return decorateTips(&t, win, asOf, false), nil + } + } else if err != repository.ErrNoTips { + log.Printf("home daily-tips db: %v", err) } } - if s.LLM == nil || !s.LLM.Enabled() { - fb := fallbackTips(now, birth, self.BirthTime) - fb.GuaName = yc.GuaName - fb.DayPart = yc.DayPart - return fb, nil - } + // Instant path: deterministic fallback, warm LLM in background. + fb := fallbackTips(now, birth, self.BirthTime) + out := decorateTips(fb, win, asOf, false) + tipsMem.Store(key, tipsMemEntry{tips: *out}) + s.persistTips(userID, win, out) + s.warmLLMAsync(userID, birth, self.BirthTime, win, asOf, key) + return out, nil +} - tips, err := s.generateLLMTips(ctx, yc) - if err != nil { - log.Printf("home daily-tips llm: %v", err) - fb := fallbackTips(now, birth, self.BirthTime) - fb.GuaName = yc.GuaName - fb.DayPart = yc.DayPart - return fb, nil +func decorateTips(t *DailyTips, win ShichenWindow, asOf string, needBirth bool) *DailyTips { + cp := *t + cp.AsOf = asOf + cp.Shichen = win.Index + cp.ShichenName = win.Name + "时" + cp.ValidUntil = win.End.Format(time.RFC3339) + cp.NeedBirth = needBirth + return &cp +} + +func (s *Service) persistTips(userID uuid.UUID, win ShichenWindow, tips *DailyTips) { + if s.Tips == nil || tips == nil { + return } - tips.Source = "llm" - tips.GuaName = yc.GuaName - tips.DayPart = yc.DayPart - tips.NeedBirth = false - tipsCache.Store(cacheKey, tipsCacheEntry{tips: *tips, exp: now.Add(45 * time.Minute)}) - return tips, nil + raw, err := json.Marshal(tips) + if err != nil { + return + } + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + if err := s.Tips.UpsertTips(ctx, userID, win.Start, win.Index, raw, tips.Source); err != nil { + log.Printf("home daily-tips upsert: %v", err) + } +} + +func (s *Service) warmLLMAsync(userID uuid.UUID, birth string, birthTime *string, win ShichenWindow, asOf, key string) { + if s.LLM == nil || !s.LLM.Enabled() { + return + } + if _, loaded := tipsInflight.LoadOrStore(key, true); loaded { + return + } + go func() { + defer tipsInflight.Delete(key) + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + now := win.Start.Add(30 * time.Minute) // representative instant inside 时辰 + if now.After(win.End) { + now = win.Start + } + yc := yijing.Seed(birth, birthTime, now) + tips, err := s.generateLLMTips(ctx, yc, now, win) + if err != nil { + log.Printf("home daily-tips llm warm: %v", err) + return + } + tips.Source = "llm" + tips.ClothingIndex = clothingIndexFromSeed(yc, now, win.Index) + tips.GuaName = yc.GuaName + tips.DayPart = yc.DayPart + out := decorateTips(tips, win, asOf, false) + tipsMem.Store(key, tipsMemEntry{tips: *out}) + s.persistTips(userID, win, out) + }() +} + +func clothingIndexFromSeed(yc yijing.Context, now time.Time, shichen int) int { + n := yc.GuaIndex*11 + yc.Line*5 + now.YearDay()*3 + shichen*17 + return 55 + n%41 } func (s *Service) findSelf(ctx context.Context, userID uuid.UUID) (*model.Profile, bool) { @@ -103,17 +177,22 @@ func (s *Service) findSelf(ctx context.Context, userID uuid.UUID) (*model.Profil return nil, false } -func (s *Service) generateLLMTips(ctx context.Context, yc yijing.Context) (*DailyTips, error) { - sys := `你是愈心谷的生活节律助手。根据用户出生信息与当前时刻的易经卦象种子,给出温和的生活建议。 +func (s *Service) generateLLMTips(ctx context.Context, yc yijing.Context, now time.Time, win ShichenWindow) (*DailyTips, error) { + weekday := []string{"日", "一", "二", "三", "四", "五", "六"}[now.Weekday()] + sys := `你是愈心谷的生活节律助手。根据用户出生信息与当前时辰的易经卦象种子,给出温和的生活建议。 硬性要求: - 禁止占卜/算命/改命恐吓/吉凶祸福话术 - 禁止医疗疗效承诺 - 用探索向、身心节律语气;可参考卦象意象,不要说「必有」类断言 +- 文案必须贴合「此刻时辰」与日期,体现与上一时辰不同的节律侧重 - 只输出 JSON,不要 markdown: {"clothing_index":70,"clothing":"一句穿衣建议","color_note":"一句颜色说明","palette":[{"name":"色名","hex":"#RRGGBB"},{"name":"色名","hex":"#RRGGBB"}],"wellness":"一句养生建议"} - clothing_index 为 55–95 整数;palette 恰好 2 项;文案各不超过 40 字` - user := yc.PromptLine() + "\n请生成今日穿衣指数、颜色搭配与养生推荐。" + user := fmt.Sprintf( + "%s\n今天是 %s(星期%s),当前%s时。请生成贴合本时辰的穿衣指数、颜色搭配与养生推荐,勿与通用套话雷同。", + yc.PromptLine(), now.Format("2006-01-02"), weekday, win.Name, + ) raw, err := s.LLM.Chat(ctx, []deepseek.Message{ {Role: "system", Content: sys}, {Role: "user", Content: user}, @@ -181,12 +260,20 @@ func fallbackTips(now time.Time, birth string, birthTime *string) *DailyTips { if birth == "" { yc = yijing.Seed(now.Format("2006-01-02"), nil, now) } + win := CurrentShichen(now) palettes := [][]ColorChip{ {{Name: "米白", Hex: "#F5F0E8"}, {Name: "雾霾蓝", Hex: "#A8C4D8"}}, {{Name: "燕麦色", Hex: "#E8DCC8"}, {Name: "浅杏", Hex: "#F0C9A8"}}, {{Name: "浅灰", Hex: "#D8D6D4"}, {Name: "雾粉", Hex: "#E8B8C4"}}, {{Name: "象牙白", Hex: "#F7F4EC"}, {Name: "鼠尾草", Hex: "#A8C4B0"}}, {{Name: "浅卡其", Hex: "#DCC8A8"}, {Name: "浅蓝", Hex: "#B0D0E8"}}, + {{Name: "天青", Hex: "#9BB8D4"}, {Name: "陶土", Hex: "#C4A484"}}, + {{Name: "豆沙", Hex: "#C9A0A0"}, {Name: "雾绿", Hex: "#B5C9B8"}}, + {{Name: "奶油", Hex: "#F3EADF"}, {Name: "烟灰", Hex: "#B8B4B0"}}, + {{Name: "浅咖", Hex: "#C8B09A"}, {Name: "靛蓝", Hex: "#6B8CAE"}}, + {{Name: "杏白", Hex: "#F6EBDD"}, {Name: "藕荷", Hex: "#D4B8C4"}}, + {{Name: "竹青", Hex: "#A8BFA8"}, {Name: "沙色", Hex: "#E0D0B8"}}, + {{Name: "月白", Hex: "#EEF2F5"}, {Name: "焦糖", Hex: "#C4A070"}}, } clothing := []string{ "轻薄透气更舒服,外套可备一件薄衫应付温差。", @@ -194,18 +281,41 @@ func fallbackTips(now time.Time, birth string, birthTime *string) *DailyTips { "上下同色系更省心,再加一件小配饰点睛即可。", "宽松剪裁更自在,适合慢节奏出门与散步。", "内里干净简约,外搭一件有质感的外套就够。", + "今日宜层搭:薄内搭+透气外衫,方便随时增减。", + "选垂感面料更显松弛,走路也会轻一点。", + "少用厚重配饰,让肩颈更轻松。", + "浅色上衣更提气色,下装选舒适脚感即可。", + "风大时加一件防风薄外套,比厚羽绒服更灵活。", + "本时辰适合干净线条,少印花更省心。", + "运动鞋或软底鞋更友好,站久也不累。", + } + notes := []string{ + "清爽干净,不抢戏。", "温柔耐看,适合日常。", "柔和提气色,不显沉。", + "安静又有呼吸感。", "干净利落,好搭配。", "此刻偏清透,层次更轻。", + "暖调一点点,气色更稳。", "冷暖各一,对比柔和。", "低饱和更耐看。", + "偏自然色,贴近户外光线。", "雾感配色,不刺眼。", "柔对比,适合慢节奏。", } - notes := []string{"清爽干净,不抢戏。", "温柔耐看,适合日常。", "柔和提气色,不显沉。", "安静又有呼吸感。", "干净利落,好搭配。"} well := []string{ "午后泡一杯温茶,给身心一点缓冲。", "今晚早点放下屏幕,让眼睛歇一会儿。", "走路时把肩膀放松,呼吸会顺很多。", "饭后慢走十分钟,比猛坐着更舒服。", "喝水提醒自己小口多次,别等口渴再灌。", + "此刻做三次深呼吸,拉长呼气更易放松。", + "站起来伸个懒腰,活动一下髋与肩。", + "晚饭少一点刺激,给肠胃留空档。", + "睡前把明天三件小事写下来,心会静些。", + "听一首慢歌,跟着节奏把呼吸放慢。", + "把窗帘开一条缝,让自然光进一点。", + "洗手洗脸用温水,给皮肤一点温柔。", + } + n := len(palettes) + i := (yc.GuaIndex*13 + yc.Line*7 + now.YearDay()*3 + win.Index*19) % n + if i < 0 { + i = -i } - i := (yc.GuaIndex + yc.Line + now.Hour()) % 5 return &DailyTips{ - ClothingIndex: 62 + (yc.GuaIndex % 31), + ClothingIndex: clothingIndexFromSeed(yc, now, win.Index), Clothing: clothing[i], ColorNote: notes[i], Palette: palettes[i], @@ -213,5 +323,6 @@ func fallbackTips(now time.Time, birth string, birthTime *string) *DailyTips { Source: "fallback", GuaName: yc.GuaName, DayPart: yc.DayPart, + AsOf: now.Format("2006-01-02"), } } diff --git a/apps/api/internal/service/home/service.go b/apps/api/internal/service/home/service.go index 8f1fca4..5fbdaaf 100644 --- a/apps/api/internal/service/home/service.go +++ b/apps/api/internal/service/home/service.go @@ -29,6 +29,7 @@ var allowedIcons = map[string]struct{}{ // Service serves homepage tool catalog and daily tips. type Service struct { Repo *repository.HomeToolsRepo + Tips *repository.HomeDailyTipsRepo Profiles *repository.ProfileRepo LLM *deepseek.Client } diff --git a/apps/api/internal/service/home/service_test.go b/apps/api/internal/service/home/service_test.go index 0067e46..43c83cf 100644 --- a/apps/api/internal/service/home/service_test.go +++ b/apps/api/internal/service/home/service_test.go @@ -1,6 +1,9 @@ package home -import "testing" +import ( + "testing" + "time" +) func TestNormalizeToolOK(t *testing.T) { b := "热" @@ -28,3 +31,53 @@ func TestNormalizeToolRejects(t *testing.T) { } } } + +func TestFallbackTipsChangeByDay(t *testing.T) { + loc := time.FixedZone("CST", 8*3600) + d1 := time.Date(2026, 8, 11, 19, 0, 0, 0, loc) + d2 := time.Date(2026, 8, 12, 19, 0, 0, 0, loc) + a := fallbackTips(d1, "1990-05-12", nil) + b := fallbackTips(d2, "1990-05-12", nil) + if a.ClothingIndex == b.ClothingIndex && a.Clothing == b.Clothing && a.Wellness == b.Wellness { + t.Fatalf("expected day-varying tips, got same %+v", a) + } + if a.AsOf == b.AsOf { + t.Fatalf("as_of should differ: %s", a.AsOf) + } +} + +func TestCurrentShichenBoundaries(t *testing.T) { + loc := time.FixedZone("CST", 8*3600) + cases := []struct { + h, wantIdx int + wantName string + }{ + {23, 0, "子"}, + {0, 0, "子"}, + {9, 5, "巳"}, + {10, 5, "巳"}, + {11, 6, "午"}, + } + for _, c := range cases { + now := time.Date(2026, 8, 12, c.h, 15, 0, 0, loc) + w := CurrentShichen(now) + if w.Index != c.wantIdx || w.Name != c.wantName { + t.Fatalf("h=%d got %d %s want %d %s", c.h, w.Index, w.Name, c.wantIdx, c.wantName) + } + if !w.Start.Before(now) && !w.Start.Equal(now) { + t.Fatalf("start should be <= now: %v %v", w.Start, now) + } + if !w.End.After(now) { + t.Fatalf("end should be > now") + } + } +} + +func TestFallbackTipsChangeByShichen(t *testing.T) { + loc := time.FixedZone("CST", 8*3600) + a := fallbackTips(time.Date(2026, 8, 12, 9, 0, 0, 0, loc), "1990-05-12", nil) + b := fallbackTips(time.Date(2026, 8, 12, 11, 0, 0, 0, loc), "1990-05-12", nil) + if a.Clothing == b.Clothing && a.Wellness == b.Wellness && a.ClothingIndex == b.ClothingIndex { + t.Fatalf("expected shichen-varying tips") + } +} diff --git a/apps/api/internal/service/home/shichen.go b/apps/api/internal/service/home/shichen.go new file mode 100644 index 0000000..a4c6563 --- /dev/null +++ b/apps/api/internal/service/home/shichen.go @@ -0,0 +1,32 @@ +package home + +import ( + "time" +) + +var shichenNames = [12]string{"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"} + +// ShichenWindow is the current Chinese double-hour window. +type ShichenWindow struct { + Index int + Name string + Start time.Time + End time.Time +} + +// CurrentShichen returns the 十二时辰 window for now (子时 23:00–01:00 …). +func CurrentShichen(now time.Time) ShichenWindow { + h := now.Hour() + idx := ((h + 1) % 24) / 2 + startHour := (idx*2 + 23) % 24 + start := time.Date(now.Year(), now.Month(), now.Day(), startHour, 0, 0, 0, now.Location()) + if start.After(now) { + start = start.Add(-24 * time.Hour) + } + return ShichenWindow{ + Index: idx, + Name: shichenNames[idx], + Start: start, + End: start.Add(2 * time.Hour), + } +} diff --git a/apps/api/internal/service/membership/service.go b/apps/api/internal/service/membership/service.go index befc34e..31522cf 100644 --- a/apps/api/internal/service/membership/service.go +++ b/apps/api/internal/service/membership/service.go @@ -76,3 +76,12 @@ func (s *Service) Get(ctx context.Context, userID uuid.UUID) (*Me, error) { AskQuotaLeft: row.AskQuotaLeft, }, nil } + +// IsActive reports whether the user has an active成长会员. +func (s *Service) IsActive(ctx context.Context, userID uuid.UUID) (bool, error) { + me, err := s.Get(ctx, userID) + if err != nil { + return false, err + } + return me.Active, nil +} diff --git a/apps/api/internal/service/profile/service.go b/apps/api/internal/service/profile/service.go index bd563ef..c069367 100644 --- a/apps/api/internal/service/profile/service.go +++ b/apps/api/internal/service/profile/service.go @@ -11,6 +11,7 @@ import ( "github.com/yuxingu/digital-psychology/apps/api/internal/model" "github.com/yuxingu/digital-psychology/apps/api/internal/repository" "github.com/yuxingu/digital-psychology/apps/api/internal/service/bootstrap" + "github.com/yuxingu/digital-psychology/apps/api/internal/textsafe" ) // Service manages personal archives. @@ -58,6 +59,10 @@ func (s *Service) Create(ctx context.Context, userID uuid.UUID, in CreateInput) name = "TA" } } + name, err := textsafe.Check(textsafe.DisplayName, name) + if err != nil { + return nil, err + } p, err := s.Repo.Create(ctx, userID, in.Relation, name, in.BirthDate, in.RelationType, in.BirthTime, in.BirthPlace) if err != nil { return nil, err @@ -94,6 +99,12 @@ func (s *Service) Update(ctx context.Context, userID, profileID uuid.UUID, in Up name := strings.TrimSpace(in.DisplayName) if name == "" { name = cur.DisplayName + } else { + var err error + name, err = textsafe.Check(textsafe.DisplayName, name) + if err != nil { + return nil, err + } } birth := in.BirthDate if birth.IsZero() { diff --git a/apps/api/internal/service/report/service.go b/apps/api/internal/service/report/service.go index 07edf1d..f63925e 100644 --- a/apps/api/internal/service/report/service.go +++ b/apps/api/internal/service/report/service.go @@ -14,6 +14,7 @@ import ( "github.com/yuxingu/digital-psychology/apps/api/internal/rhythm" "github.com/yuxingu/digital-psychology/apps/api/internal/star" "github.com/yuxingu/digital-psychology/apps/api/internal/star/synastry" + "github.com/yuxingu/digital-psychology/apps/api/internal/textsafe" ) // Service creates and reads growth reports with entitlement trimming. @@ -98,6 +99,10 @@ func (s *Service) AcceptInvite(ctx context.Context, guestUser uuid.UUID, token, if name == "" { name = "TA" } + name, err = textsafe.Check(textsafe.DisplayName, name) + if err != nil { + return nil, err + } host, err := s.Profiles.GetByID(ctx, inv.HostProfileID) if err != nil { return nil, errors.New("host profile missing") @@ -147,6 +152,7 @@ func (s *Service) CreateStar(ctx context.Context, userID, profileID uuid.UUID) ( } out, err := star.BuildWith(star.BuildOpts{ Birth: p.BirthDate, BirthTime: p.BirthTime, BirthPlace: p.BirthPlace, Name: p.DisplayName, + AsOf: time.Now().In(time.FixedZone("CST", 8*3600)), }) if err != nil { return nil, err @@ -212,7 +218,7 @@ func (s *Service) CreateRhythm(ctx context.Context, userID, profileID uuid.UUID) if err != nil { return nil, errors.New("profile not found") } - out := rhythm.Build(p.BirthDate, p.DisplayName) + out := rhythm.BuildWith(p.BirthDate, p.DisplayName, time.Now().In(time.FixedZone("CST", 8*3600))) sum, _ := json.Marshal(out.Summary) det, _ := json.Marshal(out.Detail) rep, err := s.Reports.UpsertWithPeer(ctx, userID, profileID, nil, "rhythm", sum, det) @@ -222,21 +228,23 @@ func (s *Service) CreateRhythm(ctx context.Context, userID, profileID uuid.UUID) return s.applyEntitlement(ctx, userID, rep) } -// GetLatest returns cached report by profile+type(+peer). +// GetLatest returns cached report by profile+type(+peer); refreshes star/rhythm day tips. func (s *Service) GetLatest(ctx context.Context, userID, profileID uuid.UUID, typ string, peer *uuid.UUID) (*model.GrowthReport, error) { rep, err := s.Reports.GetLatest(ctx, userID, profileID, typ, peer) if err != nil { return nil, errors.New("report not found") } + rep, _ = s.refreshTemporalIfNeeded(ctx, userID, rep) return s.applyEntitlement(ctx, userID, rep) } -// Get returns a report with detail gated. +// Get returns a report with detail gated; refreshes star/rhythm day tips. func (s *Service) Get(ctx context.Context, userID, reportID uuid.UUID) (*model.GrowthReport, error) { rep, err := s.Reports.GetForUser(ctx, userID, reportID) if err != nil { return nil, errors.New("report not found") } + rep, _ = s.refreshTemporalIfNeeded(ctx, userID, rep) return s.applyEntitlement(ctx, userID, rep) } diff --git a/apps/api/internal/service/report/temporal.go b/apps/api/internal/service/report/temporal.go new file mode 100644 index 0000000..0eefd32 --- /dev/null +++ b/apps/api/internal/service/report/temporal.go @@ -0,0 +1,127 @@ +package report + +import ( + "context" + "encoding/json" + "strings" + "time" + + "github.com/google/uuid" + + "github.com/yuxingu/digital-psychology/apps/api/internal/model" + "github.com/yuxingu/digital-psychology/apps/api/internal/rhythm" + "github.com/yuxingu/digital-psychology/apps/api/internal/star" +) + +func cstLoc() *time.Location { + return time.FixedZone("CST", 8*3600) +} + +func dayKey(t time.Time) string { + return t.In(cstLoc()).Format("2006-01-02") +} + +func summaryDay(raw json.RawMessage) string { + var m map[string]any + if err := json.Unmarshal(raw, &m); err != nil { + return "" + } + s, _ := m["as_of"].(string) + return s +} + +func hasWuxingBars(raw json.RawMessage) bool { + var m map[string]any + if err := json.Unmarshal(raw, &m); err != nil { + return false + } + wx, _ := m["wuxing"].(map[string]any) + if wx == nil { + return false + } + bars, ok := wx["bars"].([]any) + return ok && len(bars) > 0 +} + +func rhythmNeedsContentBackfill(raw json.RawMessage) bool { + if !hasWuxingBars(raw) { + return true + } + var m map[string]any + if err := json.Unmarshal(raw, &m); err != nil { + return true + } + prev, _ := m["blind_spots_preview"].([]any) + if len(prev) == 0 { + return true + } + for _, item := range prev { + s, _ := item.(string) + if s == "完整习惯方案见深度版。" || strings.Contains(s, "见深度版") { + return true + } + } + return false +} + +// refreshTemporalIfNeeded updates star/rhythm day-scoped tips in place when as_of is stale. +func (s *Service) refreshTemporalIfNeeded(ctx context.Context, userID uuid.UUID, rep *model.GrowthReport) (*model.GrowthReport, error) { + if rep == nil || (rep.Type != "star" && rep.Type != "rhythm") { + return rep, nil + } + now := time.Now().In(cstLoc()) + today := dayKey(now) + staleDay := summaryDay(rep.Summary) != today + needBackfill := rep.Type == "rhythm" && rhythmNeedsContentBackfill(rep.Summary) + if !staleDay && !needBackfill { + return stampValidUntil(rep, now), nil + } + p, err := s.Profiles.GetForUser(ctx, userID, rep.ProfileID) + if err != nil { + return rep, nil + } + var sum, det json.RawMessage + switch rep.Type { + case "star": + out, err := star.BuildWith(star.BuildOpts{ + Birth: p.BirthDate, BirthTime: p.BirthTime, BirthPlace: p.BirthPlace, + Name: p.DisplayName, AsOf: now, + }) + if err != nil { + return rep, nil + } + sum, _ = json.Marshal(out.Summary) + det, _ = json.Marshal(out.Detail) + case "rhythm": + out := rhythm.BuildWith(p.BirthDate, p.DisplayName, now) + sum, _ = json.Marshal(out.Summary) + det, _ = json.Marshal(out.Detail) + default: + return rep, nil + } + if err := s.Reports.UpdateContent(ctx, userID, rep.ID, sum, det); err != nil { + return rep, nil + } + rep.Summary = sum + rep.Detail = det + return rep, nil +} + +func stampValidUntil(rep *model.GrowthReport, now time.Time) *model.GrowthReport { + var m map[string]any + if err := json.Unmarshal(rep.Summary, &m); err != nil { + return rep + } + if _, ok := m["valid_until"].(string); ok && m["as_of"] == dayKey(now) { + return rep + } + m["as_of"] = dayKey(now) + next := time.Date(now.Year(), now.Month(), now.Day()+1, 0, 0, 0, 0, now.Location()) + m["valid_until"] = next.Format(time.RFC3339) + raw, err := json.Marshal(m) + if err != nil { + return rep + } + rep.Summary = raw + return rep +} diff --git a/apps/api/internal/service/report/temporal_test.go b/apps/api/internal/service/report/temporal_test.go new file mode 100644 index 0000000..ed9bc11 --- /dev/null +++ b/apps/api/internal/service/report/temporal_test.go @@ -0,0 +1,69 @@ +package report + +import ( + "encoding/json" + "testing" + "time" + + "github.com/yuxingu/digital-psychology/apps/api/internal/rhythm" + "github.com/yuxingu/digital-psychology/apps/api/internal/star" +) + +func TestDayKeyCST(t *testing.T) { + // 2026-08-12 23:30 UTC = 2026-08-13 07:30 CST + utc := time.Date(2026, 8, 12, 23, 30, 0, 0, time.UTC) + if got := dayKey(utc); got != "2026-08-13" { + t.Fatalf("dayKey=%s", got) + } +} + +func TestStarOutlookChangesByDay(t *testing.T) { + birth := time.Date(1990, 5, 15, 0, 0, 0, 0, time.UTC) + d1 := time.Date(2026, 8, 12, 10, 0, 0, 0, cstLoc()) + d2 := time.Date(2026, 8, 13, 10, 0, 0, 0, cstLoc()) + a, err := star.BuildWith(star.BuildOpts{Birth: birth, Name: "测", AsOf: d1}) + if err != nil { + t.Fatal(err) + } + b, err := star.BuildWith(star.BuildOpts{Birth: birth, Name: "测", AsOf: d2}) + if err != nil { + t.Fatal(err) + } + if a.Summary["as_of"] != "2026-08-12" || b.Summary["as_of"] != "2026-08-13" { + t.Fatalf("as_of a=%v b=%v", a.Summary["as_of"], b.Summary["as_of"]) + } + oa, _ := a.Summary["outlook"].(map[string]any) + ob, _ := b.Summary["outlook"].(map[string]any) + da, _ := oa["daily"].(map[string]any) + db, _ := ob["daily"].(map[string]any) + if da["score"] == db["score"] && da["tip"] == db["tip"] { + t.Fatalf("expected daily outlook to differ across days") + } + if a.Summary["valid_until"] == nil || b.Summary["valid_until"] == nil { + t.Fatal("missing valid_until") + } +} + +func TestRhythmTipsChangeByDay(t *testing.T) { + birth := time.Date(1992, 6, 8, 0, 0, 0, 0, time.UTC) + d1 := time.Date(2026, 8, 10, 12, 0, 0, 0, cstLoc()) // Mon + d2 := time.Date(2026, 8, 11, 12, 0, 0, 0, cstLoc()) // Tue + a := rhythm.BuildWith(birth, "测", d1) + b := rhythm.BuildWith(birth, "测", d2) + if a.Summary["as_of"] != "2026-08-10" || b.Summary["as_of"] != "2026-08-11" { + t.Fatalf("as_of a=%v b=%v", a.Summary["as_of"], b.Summary["as_of"]) + } + if a.Summary["week_focus"] == b.Summary["week_focus"] && a.Summary["today_tip"] == b.Summary["today_tip"] { + t.Fatalf("expected tips to differ") + } +} + +func TestSummaryDay(t *testing.T) { + raw, _ := json.Marshal(map[string]any{"as_of": "2026-08-12"}) + if summaryDay(raw) != "2026-08-12" { + t.Fatal(summaryDay(raw)) + } + if summaryDay(json.RawMessage(`{}`)) != "" { + t.Fatal("empty") + } +} diff --git a/apps/api/internal/service/scale/service.go b/apps/api/internal/service/scale/service.go index 340f061..0d00239 100644 --- a/apps/api/internal/service/scale/service.go +++ b/apps/api/internal/service/scale/service.go @@ -8,13 +8,23 @@ import ( "github.com/google/uuid" sc "github.com/yuxingu/digital-psychology/apps/api/internal/scale" + "github.com/yuxingu/digital-psychology/apps/api/internal/scalebank" "github.com/yuxingu/digital-psychology/apps/api/internal/repository" ) +// ErrMembershipRequired when full MBTI requires growth membership. +var ErrMembershipRequired = errors.New("membership required") + +// MembershipChecker reports whether成长会员 is active. +type MembershipChecker interface { + IsActive(ctx context.Context, userID uuid.UUID) (bool, error) +} + // Service serves 探索测试. type Service struct { - Repo *repository.ScaleRepo - Profiles *repository.ProfileRepo + Repo *repository.ScaleRepo + Profiles *repository.ProfileRepo + Membership MembershipChecker } // List returns published scales. @@ -22,12 +32,42 @@ func (s *Service) List(ctx context.Context) ([]repository.ScaleListItem, error) return s.Repo.ListPublished(ctx) } -// Get returns scale detail. -func (s *Service) Get(ctx context.Context, slug string) (*repository.ScaleDetail, error) { +// Get returns scale detail; bank slugs served from curated embed; mbti-full may be locked. +func (s *Service) Get(ctx context.Context, userID uuid.UUID, slug string) (*repository.ScaleDetail, error) { + if bank, err := scalebank.Get(slug); err == nil { + if _, err := s.Repo.EnsurePublished(ctx, bank.Slug, bank.Title, bank.Description); err != nil { + return nil, errors.New("scale not found") + } + d := &repository.ScaleDetail{ + Slug: bank.Slug, Title: bank.Title, Description: bank.Description, Access: "free", + } + for i, q := range bank.Questions { + body, _ := json.Marshal(map[string]any{ + "prompt": q.Prompt, "options": q.Options, + }) + d.Questions = append(d.Questions, repository.ScaleQuestion{ + ID: scalebank.QuestionID(slug, i), Sort: i + 1, Body: body, + }) + } + return d, nil + } d, err := s.Repo.GetBySlug(ctx, slug) if err != nil { return nil, errors.New("scale not found") } + if slug == "mbti-full" { + d.Access = "membership" + ok := false + if s.Membership != nil && userID != uuid.Nil { + ok, _ = s.Membership.IsActive(ctx, userID) + } + if !ok { + d.Locked = true + d.Questions = nil + } + } else { + d.Access = "free" + } return d, nil } @@ -43,19 +83,58 @@ type SubmitResult struct { Result map[string]interface{} `json:"result"` } -// Submit scores a simple majority style. +// Submit scores answers and stores result. func (s *Service) Submit(ctx context.Context, userID uuid.UUID, slug string, in SubmitInput) (*SubmitResult, error) { if _, err := s.Profiles.GetForUser(ctx, userID, in.ProfileID); err != nil { return nil, errors.New("profile not found") } - scaleID, err := s.Repo.ScaleIDBySlug(ctx, slug) - if err != nil { - return nil, errors.New("scale not found") + if slug == "mbti-full" { + ok := false + if s.Membership != nil { + ok, _ = s.Membership.IsActive(ctx, userID) + } + if !ok { + return nil, ErrMembershipRequired + } } - labels, _, _ := labelsForSlug(slug) - key, label := sc.ScoreMajority(in.Answers, labels, "平衡探索型") - result := sc.BuildResult(slug, key, label) + var result map[string]interface{} + var scaleID uuid.UUID + + if bank, err := scalebank.Get(slug); err == nil { + scaleID, err = s.Repo.EnsurePublished(ctx, bank.Slug, bank.Title, bank.Description) + if err != nil { + return nil, errors.New("scale not found") + } + key, label, _, _ := scalebank.ScoreSum(in.Answers, bank.QuestionCount) + result = sc.BuildResult(slug, key, label) + result["disclaimer"] = bank.Disclaimer + } else { + detail, err := s.Repo.GetBySlug(ctx, slug) + if err != nil { + return nil, errors.New("scale not found") + } + scaleID, err = s.Repo.ScaleIDBySlug(ctx, slug) + if err != nil { + return nil, errors.New("scale not found") + } + if slug == "mbti-lite" || slug == "mbti-full" { + meta := map[string]sc.JungianQuestionMeta{} + for _, q := range detail.Questions { + meta[q.ID.String()] = sc.ParseJungianMeta(q.Body) + } + perDim := 8 + if slug == "mbti-full" { + perDim = 15 + } + code, _, pct := sc.ScoreJungian(in.Answers, meta, perDim) + result = sc.BuildJungianResult(code, pct) + } else { + labels, _, _ := labelsForSlug(slug) + key, label := sc.ScoreMajority(in.Answers, labels, "平衡探索型") + result = sc.BuildResult(slug, key, label) + } + } ansJSON, _ := json.Marshal(in.Answers) resJSON, _ := json.Marshal(result) id, err := s.Repo.SaveResult(ctx, userID, scaleID, in.ProfileID, ansJSON, resJSON) @@ -65,15 +144,36 @@ func (s *Service) Submit(ctx context.Context, userID uuid.UUID, slug string, in return &SubmitResult{ID: id, Result: result}, nil } +// LatestResult returns the newest stored result for this user + slug. +func (s *Service) LatestResult(ctx context.Context, userID uuid.UUID, slug string) (*SubmitResult, error) { + if scalebank.Has(slug) { + bank, err := scalebank.Get(slug) + if err != nil { + return nil, errors.New("scale not found") + } + if _, err := s.Repo.EnsurePublished(ctx, bank.Slug, bank.Title, bank.Description); err != nil { + return nil, errors.New("scale not found") + } + } else if _, err := s.Repo.ScaleIDBySlug(ctx, slug); err != nil { + return nil, errors.New("scale not found") + } + row, err := s.Repo.LatestResult(ctx, userID, slug) + if err != nil { + return nil, err + } + var result map[string]interface{} + if err := json.Unmarshal(row.Result, &result); err != nil { + return nil, errors.New("invalid result") + } + return &SubmitResult{ID: row.ID, Result: result}, nil +} + func labelsForSlug(slug string) (labels map[string]string, sharePrefix, summary string) { switch slug { case "emotion-pattern": return sc.EmotionLabels(), "我的情感模式:", "这是你当前情绪调节偏好的探索结果,可用于自我了解与日常调整,不是固定标签。" - case "mbti-lite": - return map[string]string{"E": "外向充能型", "I": "内向充能型", "T": "理性决策型", "F": "感受决策型", "J": "结构安排型", "P": "弹性探索型"}, - "我的人格偏好:", "轻量人格偏好探索,不是固定分类。" case "enneagram-lite": return map[string]string{"A": "尽责驱动型", "B": "联结驱动型", "C": "独立驱动型"}, "我的动机模式:", "内在动机轻量探索,用于自我觉察。" @@ -98,3 +198,13 @@ func labelsForSlug(slug string) (labels map[string]string, sharePrefix, summary "这是你当前沟通偏好的探索结果,可用于自我了解与关系理解,不是固定标签。" } } + +// BankCatalog returns curated exploration bank tiles + categories. +func (s *Service) BankCatalog() (*scalebank.CatalogOut, error) { + return scalebank.Catalog() +} + +// BankCategory lists scales in a curated category. +func (s *Service) BankCategory(key string) (*scalebank.CategoryCard, []scalebank.ScaleListItem, error) { + return scalebank.CategoryScales(key) +} diff --git a/apps/api/internal/star/engine.go b/apps/api/internal/star/engine.go index 36fd348..49f29ed 100644 --- a/apps/api/internal/star/engine.go +++ b/apps/api/internal/star/engine.go @@ -66,11 +66,15 @@ func BuildWith(opts BuildOpts) (Output, error) { asOf := opts.AsOf if asOf.IsZero() { - asOf = time.Now() + asOf = time.Now().In(time.FixedZone("CST", 8*3600)) + } else { + asOf = asOf.In(time.FixedZone("CST", 8*3600)) } fort := outlook.Build(chart, asOf) daily := fort.Daily fortMap := fort.AsMap() + dayKey := asOf.Format("2006-01-02") + validUntil := time.Date(asOf.Year(), asOf.Month(), asOf.Day()+1, 0, 0, 0, 0, asOf.Location()) planetsOut := make([]map[string]any, 0, len(chart.Planets)) for _, p := range chart.Planets { @@ -121,6 +125,8 @@ func BuildWith(opts BuildOpts) (Output, error) { "title": daily.Title, "focus": daily.Focus, "tip": daily.Tip, "energy": daily.Score, "note": daily.Label, "score": daily.Score, "label": daily.Label, }, + "as_of": dayKey, + "valid_until": validUntil.Format(time.RFC3339), "strengths_preview": pack.Strengths[:min(3, len(pack.Strengths))], "blind_spots_preview": []string{"完整相位与年运详解见深度版。"}, "interaction_tags": []string{ diff --git a/apps/api/internal/textsafe/textsafe.go b/apps/api/internal/textsafe/textsafe.go new file mode 100644 index 0000000..67bb0a6 --- /dev/null +++ b/apps/api/internal/textsafe/textsafe.go @@ -0,0 +1,184 @@ +// Package textsafe validates user free-text at the API boundary (Spec input-compliance). +package textsafe + +import ( + "errors" + "fmt" + "strings" + "unicode" + "unicode/utf8" +) + +// Kind selects length limits and whether empty is allowed. +type Kind int + +const ( + Nickname Kind = iota + DisplayName + AskContent + Note // optional + Title + Focus // optional + Scene +) + +// ErrRejected is returned for compliance failures (map to HTTP 400 / code 40060). +var ErrRejected = errors.New("文案不合规") + +type limits struct { + min, max int + allowNL bool +} + +func lim(k Kind) limits { + switch k { + case Nickname: + return limits{1, 16, false} + case DisplayName: + return limits{1, 24, false} + case AskContent: + return limits{1, 2000, true} + case Note: + return limits{0, 200, true} + case Title: + return limits{1, 40, false} + case Focus: + return limits{0, 40, false} + case Scene: + return limits{1, 80, false} + default: + return limits{1, 200, false} + } +} + +var banned = []string{ + "占卜", "算命", "改命", "测测", + "疗效", "包治", "根治", "治疗疾病", "治愈癌症", + "不测就有灾", "大师算卦", "神棍", +} + +// Check normalizes and validates. Empty optional kinds return ("", nil). +func Check(kind Kind, raw string) (string, error) { + s := Normalize(raw, lim(kind).allowNL) + l := lim(kind) + n := utf8.RuneCountInString(s) + if n < l.min { + if l.min == 0 { + return "", nil + } + return "", reject("请填写内容") + } + if n > l.max { + return "", reject("内容过长") + } + if err := rejectControls(s, l.allowNL); err != nil { + return "", err + } + if err := rejectMarkup(s); err != nil { + return "", err + } + if err := rejectBanned(s); err != nil { + return "", err + } + if err := rejectSpam(s); err != nil { + return "", err + } + return s, nil +} + +// Normalize trims; optionally keeps internal newlines. +func Normalize(s string, allowNL bool) string { + s = strings.TrimSpace(s) + if !allowNL { + s = strings.Map(func(r rune) rune { + if r == '\n' || r == '\r' || r == '\t' { + return ' ' + } + return r + }, s) + s = strings.Join(strings.Fields(s), " ") + } + return s +} + +func reject(msg string) error { + return fmt.Errorf("%w:%s", ErrRejected, msg) +} + +func rejectControls(s string, allowNL bool) error { + for _, r := range s { + if r == 0 { + return reject("含非法字符") + } + if r == '\n' || r == '\r' || r == '\t' { + if !allowNL { + return reject("含非法空白") + } + continue + } + if r < 0x20 || r == 0x7f { + return reject("含非法字符") + } + } + return nil +} + +func rejectMarkup(s string) error { + low := strings.ToLower(s) + if strings.Contains(low, " + for i := 0; i < len(s); i++ { + if s[i] != '<' { + continue + } + if i+1 < len(s) { + c := s[i+1] + if c == '/' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '!' { + return reject("含不安全内容") + } + } + } + return nil +} + +func rejectBanned(s string) error { + for _, b := range banned { + if b != "" && strings.Contains(s, b) { + return reject("含不允许的表述,请换一种说法") + } + } + return nil +} + +func rejectSpam(s string) error { + runes := []rune(s) + if len(runes) >= 6 { + allSame := true + for i := 1; i < len(runes); i++ { + if runes[i] != runes[0] { + allSame = false + break + } + } + if allSame && !unicode.IsSpace(runes[0]) { + return reject("请勿重复刷屏") + } + } + streak := 1 + for i := 1; i < len(runes); i++ { + if runes[i] == runes[i-1] && !unicode.IsSpace(runes[i]) { + streak++ + if streak >= 8 { + return reject("请勿重复刷屏") + } + } else { + streak = 1 + } + } + return nil +} diff --git a/apps/api/internal/textsafe/textsafe_test.go b/apps/api/internal/textsafe/textsafe_test.go new file mode 100644 index 0000000..0f4a006 --- /dev/null +++ b/apps/api/internal/textsafe/textsafe_test.go @@ -0,0 +1,54 @@ +package textsafe_test + +import ( + "strings" + "testing" + + "github.com/yuxingu/digital-psychology/apps/api/internal/textsafe" +) + +func TestOK(t *testing.T) { + got, err := textsafe.Check(textsafe.Nickname, " 心语岛 ") + if err != nil || got != "心语岛" { + t.Fatalf("got %q err=%v", got, err) + } + got, err = textsafe.Check(textsafe.DisplayName, "小愈") + if err != nil || got != "小愈" { + t.Fatalf("got %q err=%v", got, err) + } +} + +func TestBanned(t *testing.T) { + if _, err := textsafe.Check(textsafe.Nickname, "算命达人"); err == nil { + t.Fatal("expected reject") + } + if _, err := textsafe.Check(textsafe.AskContent, "帮我占卜一下"); err == nil { + t.Fatal("expected reject") + } +} + +func TestXSS(t *testing.T) { + if _, err := textsafe.Check(textsafe.AskContent, `hi `); err == nil { + t.Fatal("expected reject") + } +} + +func TestSpam(t *testing.T) { + if _, err := textsafe.Check(textsafe.Note, "啊啊啊啊啊啊啊啊"); err == nil { + t.Fatal("expected reject") + } +} + +func TestLength(t *testing.T) { + long := strings.Repeat("字", 20) + if _, err := textsafe.Check(textsafe.Nickname, long); err == nil { + t.Fatal("expected reject") + } +} + +func TestOptionalEmpty(t *testing.T) { + got, err := textsafe.Check(textsafe.Note, " ") + if err != nil || got != "" { + t.Fatalf("got %q err=%v", got, err) + } +} diff --git a/apps/api/internal/yijing/seed_test.go b/apps/api/internal/yijing/seed_test.go index 4a4ffcf..3f8230e 100644 --- a/apps/api/internal/yijing/seed_test.go +++ b/apps/api/internal/yijing/seed_test.go @@ -18,12 +18,12 @@ func TestSeedStableSameInputs(t *testing.T) { } } -func TestSeedChangesWithHour(t *testing.T) { - now1 := time.Date(2026, 8, 11, 9, 0, 0, 0, time.FixedZone("CST", 8*3600)) - now2 := time.Date(2026, 8, 11, 18, 0, 0, 0, time.FixedZone("CST", 8*3600)) - a := Seed("1990-05-12", nil, now1) - b := Seed("1990-05-12", nil, now2) - if a.DayPart == b.DayPart { - t.Fatalf("expected different day parts, both %s", a.DayPart) +func TestSeedChangesWithDay(t *testing.T) { + d1 := time.Date(2026, 8, 11, 19, 0, 0, 0, time.FixedZone("CST", 8*3600)) + d2 := time.Date(2026, 8, 12, 19, 0, 0, 0, time.FixedZone("CST", 8*3600)) + a := Seed("1990-05-12", nil, d1) + b := Seed("1990-05-12", nil, d2) + if a.GuaIndex == b.GuaIndex && a.Line == b.Line { + t.Fatalf("expected seed to change across days, both gua=%d line=%d", a.GuaIndex, a.Line) } } diff --git a/apps/api/migrations/000018_user_avatar.down.sql b/apps/api/migrations/000018_user_avatar.down.sql new file mode 100644 index 0000000..f00bf91 --- /dev/null +++ b/apps/api/migrations/000018_user_avatar.down.sql @@ -0,0 +1 @@ +ALTER TABLE users DROP COLUMN IF EXISTS avatar_url; diff --git a/apps/api/migrations/000018_user_avatar.up.sql b/apps/api/migrations/000018_user_avatar.up.sql new file mode 100644 index 0000000..93f5fdc --- /dev/null +++ b/apps/api/migrations/000018_user_avatar.up.sql @@ -0,0 +1,2 @@ +-- ECR avatar: account profile photo URL +ALTER TABLE users ADD COLUMN IF NOT EXISTS avatar_url varchar(512) NULL; diff --git a/apps/api/migrations/000019_mbti_label.down.sql b/apps/api/migrations/000019_mbti_label.down.sql new file mode 100644 index 0000000..670c677 --- /dev/null +++ b/apps/api/migrations/000019_mbti_label.down.sql @@ -0,0 +1,9 @@ +UPDATE home_tools +SET label = '人格测试', updated_at = now() +WHERE path = '/scales/mbti-lite' AND icon = 'mbti'; + +UPDATE scales +SET title = '人格类型探索', + description = '了解能量来源与决策偏好的轻量探索。', + updated_at = now() +WHERE slug = 'mbti-lite' AND deleted_at IS NULL; diff --git a/apps/api/migrations/000019_mbti_label.up.sql b/apps/api/migrations/000019_mbti_label.up.sql new file mode 100644 index 0000000..645fe67 --- /dev/null +++ b/apps/api/migrations/000019_mbti_label.up.sql @@ -0,0 +1,11 @@ +-- Rename mbti-lite display to MBTI测试 (ECR-adjacent · explore-test R9) + +UPDATE scales +SET title = 'MBTI测试', + description = '了解能量来源与决策偏好的轻量探索。', + updated_at = now() +WHERE slug = 'mbti-lite' AND deleted_at IS NULL; + +UPDATE home_tools +SET label = 'MBTI测试', updated_at = now() +WHERE path = '/scales/mbti-lite' AND icon = 'mbti'; diff --git a/apps/api/migrations/000020_mbti_questions.down.sql b/apps/api/migrations/000020_mbti_questions.down.sql new file mode 100644 index 0000000..54a497a --- /dev/null +++ b/apps/api/migrations/000020_mbti_questions.down.sql @@ -0,0 +1,20 @@ +-- Revert mbti-lite to previous 3-question lite set (best-effort) + +UPDATE scale_questions +SET deleted_at = now(), updated_at = now() +WHERE scale_id = '22222222-2222-2222-2222-222222222201' + AND deleted_at IS NULL; + +UPDATE scales +SET title = 'MBTI测试', + description = '了解能量来源与决策偏好的轻量探索。', + updated_at = now() +WHERE id = '22222222-2222-2222-2222-222222222201'; + +INSERT INTO scale_questions (scale_id, sort, body) VALUES +('22222222-2222-2222-2222-222222222201', 1, + '{"prompt":"周末充电,你更想?","options":[{"key":"E","text":"和朋友见面聊天"},{"key":"I","text":"独处安静恢复"}]}'), +('22222222-2222-2222-2222-222222222201', 2, + '{"prompt":"做决定时你更看重?","options":[{"key":"T","text":"逻辑与公平"},{"key":"F","text":"感受与关系"}]}'), +('22222222-2222-2222-2222-222222222201', 3, + '{"prompt":"面对计划,你更倾向?","options":[{"key":"J","text":"提前安排清楚"},{"key":"P","text":"保持弹性随机"}]}'); diff --git a/apps/api/migrations/000020_mbti_questions.up.sql b/apps/api/migrations/000020_mbti_questions.up.sql new file mode 100644 index 0000000..76dc4e8 --- /dev/null +++ b/apps/api/migrations/000020_mbti_questions.up.sql @@ -0,0 +1,47 @@ +-- MBTI测试:替换极简 3 题为四维 12 题;旧结果失效(explore-test R10/R11) + +UPDATE scale_questions +SET deleted_at = now(), updated_at = now() +WHERE scale_id = '22222222-2222-2222-2222-222222222201' + AND deleted_at IS NULL; + +UPDATE scale_results +SET deleted_at = now(), updated_at = now() +WHERE scale_id = '22222222-2222-2222-2222-222222222201' + AND deleted_at IS NULL; + +UPDATE scales +SET title = 'MBTI测试', + description = '四维偏好探索(能量 · 信息 · 决策 · 节奏),约 5 分钟。结果用于自我了解,不是固定标签。', + updated_at = now() +WHERE id = '22222222-2222-2222-2222-222222222201'; + +INSERT INTO scale_questions (scale_id, sort, body) VALUES +-- E / I +('22222222-2222-2222-2222-222222222201', 1, + '{"prompt":"参加不太熟的聚会时,你更常?","options":[{"key":"E","text":"主动找人聊天、很快融入"},{"key":"I","text":"先观察一会儿,和少数人深聊"}]}'), +('22222222-2222-2222-2222-222222222201', 2, + '{"prompt":"连续社交一天后,你更想?","options":[{"key":"E","text":"再约人聊聊,延续热闹"},{"key":"I","text":"回家独处,安静恢复"}]}'), +('22222222-2222-2222-2222-222222222201', 3, + '{"prompt":"想清楚一件难事时,你更习惯?","options":[{"key":"E","text":"边说边想,找人讨论"},{"key":"I","text":"先自己想透,再开口"}]}'), +-- S / N +('22222222-2222-2222-2222-222222222201', 4, + '{"prompt":"听别人讲经历,你更抓住?","options":[{"key":"S","text":"具体细节和实际经过"},{"key":"N","text":"背后的含义与可能趋势"}]}'), +('22222222-2222-2222-2222-222222222201', 5, + '{"prompt":"学新技能时,你更喜欢?","options":[{"key":"S","text":"按步骤练熟,先把基础做扎实"},{"key":"N","text":"先看整体框架,再联想用法"}]}'), +('22222222-2222-2222-2222-222222222201', 6, + '{"prompt":"讨论未来计划,你更容易?","options":[{"key":"S","text":"关注眼下可执行的安排"},{"key":"N","text":"先想象多种可能性与愿景"}]}'), +-- T / F +('22222222-2222-2222-2222-222222222201', 7, + '{"prompt":"朋友来倾诉冲突,你更先?","options":[{"key":"T","text":"帮对方理清对错与可行方案"},{"key":"F","text":"先接住情绪,让对方感到被理解"}]}'), +('22222222-2222-2222-2222-222222222201', 8, + '{"prompt":"团队做决定时,你更看重?","options":[{"key":"T","text":"标准一致、结果是否公正有效"},{"key":"F","text":"大家感受如何、关系是否受伤"}]}'), +('22222222-2222-2222-2222-222222222201', 9, + '{"prompt":"收到批评时,你内心更在意?","options":[{"key":"T","text":"对方说的是否准确、可改进"},{"key":"F","text":"语气是否尊重、关系有没有裂痕"}]}'), +-- J / P +('22222222-2222-2222-2222-222222222201', 10, + '{"prompt":"出门旅行,你更倾向?","options":[{"key":"J","text":"行程大体订好,心里踏实"},{"key":"P","text":"留白多一点,走到哪儿算哪儿"}]}'), +('22222222-2222-2222-2222-222222222201', 11, + '{"prompt":"面对截止日期,你通常?","options":[{"key":"J","text":"尽早推进,提前收尾更安心"},{"key":"P","text":"压力临近时效率最高,灵活赶完"}]}'), +('22222222-2222-2222-2222-222222222201', 12, + '{"prompt":"书桌/手机桌面,你更舒服的是?","options":[{"key":"J","text":"归类清楚,东西有固定位置"},{"key":"P","text":"随用随放,需要时再整理"}]}'); diff --git a/apps/api/migrations/000021_oejts_mbti.down.sql b/apps/api/migrations/000021_oejts_mbti.down.sql new file mode 100644 index 0000000..58f2227 --- /dev/null +++ b/apps/api/migrations/000021_oejts_mbti.down.sql @@ -0,0 +1,10 @@ +-- revert OEJTS seed (best-effort soft-delete full scale) + +UPDATE scale_questions SET deleted_at = now(), updated_at = now() +WHERE scale_id IN ( + '22222222-2222-2222-2222-222222222201', + '22222222-2222-2222-2222-222222222210' +) AND deleted_at IS NULL; + +UPDATE scales SET deleted_at = now(), updated_at = now() +WHERE id = '22222222-2222-2222-2222-222222222210'; diff --git a/apps/api/migrations/000021_oejts_mbti.up.sql b/apps/api/migrations/000021_oejts_mbti.up.sql new file mode 100644 index 0000000..c51e101 --- /dev/null +++ b/apps/api/migrations/000021_oejts_mbti.up.sql @@ -0,0 +1,101 @@ +-- OEJTS 1.2 standard (32, free) + full (48, membership) · explore-test +-- Credit: Open Extended Jungian Type Scales / Open Psychometrics · openjung MIT + +UPDATE scale_questions SET deleted_at=now(), updated_at=now() WHERE scale_id='22222222-2222-2222-2222-222222222201' AND deleted_at IS NULL; +UPDATE scale_results SET deleted_at=now(), updated_at=now() WHERE scale_id='22222222-2222-2222-2222-222222222201' AND deleted_at IS NULL; +UPDATE scales SET title='MBTI测试', description='开源 OEJTS 标准版:四维各 8 题,共 32 题。能量·信息·决策·节奏偏好探索(非官方 MBTI 版权题)。', updated_at=now() WHERE id='22222222-2222-2222-2222-222222222201'; + +INSERT INTO scale_questions (scale_id, sort, body) VALUES +('22222222-2222-2222-2222-222222222201', 1, '{"prompt": "你如何记录任务?", "format": "likert5", "dimension": "JP", "left": "制定清单", "right": "依靠记忆", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 2, '{"prompt": "你如何看待新信息?", "format": "likert5", "dimension": "TF", "left": "愿意相信", "right": "持怀疑态度", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 3, '{"prompt": "你对独处有什么感受?", "format": "likert5", "dimension": "EI", "left": "独处时感到无聊", "right": "需要独处时间", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 4, '{"prompt": "你如何看待现状?", "format": "likert5", "dimension": "SN", "left": "接受事物的本来面目", "right": "对现状不满足", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 5, '{"prompt": "你如何整理空间?", "format": "likert5", "dimension": "JP", "left": "保持房间整洁", "right": "随手放置东西", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 6, '{"prompt": "你如何看待逻辑思维?", "format": "likert5", "dimension": "TF", "left": "认为「像机器人」是侮辱", "right": "追求机械般的思维", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 7, '{"prompt": "你的能量状态如何?", "format": "likert5", "dimension": "EI", "left": "精力充沛", "right": "平静温和", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 8, '{"prompt": "你喜欢什么类型的考试?", "format": "likert5", "dimension": "SN", "left": "喜欢选择题", "right": "喜欢论述题", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 9, '{"prompt": "你如何形容自己的生活方式?", "format": "likert5", "dimension": "JP", "left": "有条理", "right": "随性混乱", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 10, '{"prompt": "你如何应对批评?", "format": "likert5", "dimension": "TF", "left": "容易受伤", "right": "脸皮厚", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 11, '{"prompt": "你在什么环境下工作最好?", "format": "likert5", "dimension": "EI", "left": "在团队中表现最佳", "right": "独自工作表现最佳", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 12, '{"prompt": "你的时间焦点在哪里?", "format": "likert5", "dimension": "SN", "left": "关注过去", "right": "关注未来", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 13, '{"prompt": "你何时制定计划?", "format": "likert5", "dimension": "JP", "left": "提前规划", "right": "最后一刻才计划", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 14, '{"prompt": "你希望从他人那里得到什么?", "format": "likert5", "dimension": "TF", "left": "渴望他人的爱", "right": "渴望他人的尊重", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 15, '{"prompt": "聚会让你感觉如何?", "format": "likert5", "dimension": "EI", "left": "因聚会而兴奋", "right": "因聚会而疲惫", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 16, '{"prompt": "在群体中,你倾向于?", "format": "likert5", "dimension": "SN", "left": "融入群体", "right": "与众不同", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 17, '{"prompt": "你如何做决定?", "format": "likert5", "dimension": "JP", "left": "做出承诺", "right": "保留选择", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 18, '{"prompt": "你想擅长什么?", "format": "likert5", "dimension": "TF", "left": "想擅长帮助他人", "right": "想擅长修理事物", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 19, '{"prompt": "在交谈中,你更倾向于?", "format": "likert5", "dimension": "EI", "left": "话比较多", "right": "更善于倾听", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 20, '{"prompt": "讲故事时,你会?", "format": "likert5", "dimension": "SN", "left": "描述发生了什么", "right": "描述这意味着什么", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 21, '{"prompt": "你何时完成任务?", "format": "likert5", "dimension": "JP", "left": "立即完成工作", "right": "拖延", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 22, '{"prompt": "你做选择时更信?", "format": "likert5", "dimension": "TF", "left": "跟随内心", "right": "跟随理性", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 23, '{"prompt": "周末你更喜欢做什么?", "format": "likert5", "dimension": "EI", "left": "喜欢外出活动", "right": "喜欢待在家里", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 24, '{"prompt": "学习新事物时,你想要什么?", "format": "likert5", "dimension": "SN", "left": "想要细节", "right": "想要大局观", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 25, '{"prompt": "你如何应对新情况?", "format": "likert5", "dimension": "JP", "left": "提前准备", "right": "即兴发挥", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 26, '{"prompt": "道德的基础更接近?", "format": "likert5", "dimension": "TF", "left": "道德基于同情", "right": "道德基于正义", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 27, '{"prompt": "你的自然音量如何?", "format": "likert5", "dimension": "EI", "left": "自然而然大声说话", "right": "很难大声喊叫", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 28, '{"prompt": "你如何获取知识?", "format": "likert5", "dimension": "SN", "left": "经验主义", "right": "理论主义", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 29, '{"prompt": "什么更能驱动你?", "format": "likert5", "dimension": "JP", "left": "努力工作", "right": "尽情玩乐", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 30, '{"prompt": "你如何看待情感?", "format": "likert5", "dimension": "TF", "left": "重视情感", "right": "对情感感到不自在", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 31, '{"prompt": "你对成为焦点有什么感受?", "format": "likert5", "dimension": "EI", "left": "喜欢表演", "right": "避免公开演讲", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222201', 32, '{"prompt": "什么问题最让你感兴趣?", "format": "likert5", "dimension": "SN", "left": "想知道「谁/什么/何时」", "right": "想知道「为什么」", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb); + +INSERT INTO scales (id, slug, title, description, status) +VALUES ( + '22222222-2222-2222-2222-222222222210', + 'mbti-full', + 'MBTI完整版', + '成长会员专享:四维各 12 题,共 48 题,偏好更稳定。含 OEJTS 标准题 + 扩展题。', + 'published' +) ON CONFLICT (slug) DO UPDATE SET title=EXCLUDED.title, description=EXCLUDED.description, status='published', updated_at=now(), deleted_at=NULL; + +UPDATE scale_questions SET deleted_at=now(), updated_at=now() WHERE scale_id='22222222-2222-2222-2222-222222222210' AND deleted_at IS NULL; +UPDATE scale_results SET deleted_at=now(), updated_at=now() WHERE scale_id='22222222-2222-2222-2222-222222222210' AND deleted_at IS NULL; +INSERT INTO scale_questions (scale_id, sort, body) VALUES +('22222222-2222-2222-2222-222222222210', 1, '{"prompt": "你如何记录任务?", "format": "likert5", "dimension": "JP", "left": "制定清单", "right": "依靠记忆", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 2, '{"prompt": "你如何看待新信息?", "format": "likert5", "dimension": "TF", "left": "愿意相信", "right": "持怀疑态度", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 3, '{"prompt": "你对独处有什么感受?", "format": "likert5", "dimension": "EI", "left": "独处时感到无聊", "right": "需要独处时间", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 4, '{"prompt": "你如何看待现状?", "format": "likert5", "dimension": "SN", "left": "接受事物的本来面目", "right": "对现状不满足", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 5, '{"prompt": "你如何整理空间?", "format": "likert5", "dimension": "JP", "left": "保持房间整洁", "right": "随手放置东西", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 6, '{"prompt": "你如何看待逻辑思维?", "format": "likert5", "dimension": "TF", "left": "认为「像机器人」是侮辱", "right": "追求机械般的思维", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 7, '{"prompt": "你的能量状态如何?", "format": "likert5", "dimension": "EI", "left": "精力充沛", "right": "平静温和", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 8, '{"prompt": "你喜欢什么类型的考试?", "format": "likert5", "dimension": "SN", "left": "喜欢选择题", "right": "喜欢论述题", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 9, '{"prompt": "你如何形容自己的生活方式?", "format": "likert5", "dimension": "JP", "left": "有条理", "right": "随性混乱", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 10, '{"prompt": "你如何应对批评?", "format": "likert5", "dimension": "TF", "left": "容易受伤", "right": "脸皮厚", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 11, '{"prompt": "你在什么环境下工作最好?", "format": "likert5", "dimension": "EI", "left": "在团队中表现最佳", "right": "独自工作表现最佳", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 12, '{"prompt": "你的时间焦点在哪里?", "format": "likert5", "dimension": "SN", "left": "关注过去", "right": "关注未来", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 13, '{"prompt": "你何时制定计划?", "format": "likert5", "dimension": "JP", "left": "提前规划", "right": "最后一刻才计划", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 14, '{"prompt": "你希望从他人那里得到什么?", "format": "likert5", "dimension": "TF", "left": "渴望他人的爱", "right": "渴望他人的尊重", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 15, '{"prompt": "聚会让你感觉如何?", "format": "likert5", "dimension": "EI", "left": "因聚会而兴奋", "right": "因聚会而疲惫", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 16, '{"prompt": "在群体中,你倾向于?", "format": "likert5", "dimension": "SN", "left": "融入群体", "right": "与众不同", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 17, '{"prompt": "你如何做决定?", "format": "likert5", "dimension": "JP", "left": "做出承诺", "right": "保留选择", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 18, '{"prompt": "你想擅长什么?", "format": "likert5", "dimension": "TF", "left": "想擅长帮助他人", "right": "想擅长修理事物", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 19, '{"prompt": "在交谈中,你更倾向于?", "format": "likert5", "dimension": "EI", "left": "话比较多", "right": "更善于倾听", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 20, '{"prompt": "讲故事时,你会?", "format": "likert5", "dimension": "SN", "left": "描述发生了什么", "right": "描述这意味着什么", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 21, '{"prompt": "你何时完成任务?", "format": "likert5", "dimension": "JP", "left": "立即完成工作", "right": "拖延", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 22, '{"prompt": "你做选择时更信?", "format": "likert5", "dimension": "TF", "left": "跟随内心", "right": "跟随理性", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 23, '{"prompt": "周末你更喜欢做什么?", "format": "likert5", "dimension": "EI", "left": "喜欢外出活动", "right": "喜欢待在家里", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 24, '{"prompt": "学习新事物时,你想要什么?", "format": "likert5", "dimension": "SN", "left": "想要细节", "right": "想要大局观", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 25, '{"prompt": "你如何应对新情况?", "format": "likert5", "dimension": "JP", "left": "提前准备", "right": "即兴发挥", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 26, '{"prompt": "道德的基础更接近?", "format": "likert5", "dimension": "TF", "left": "道德基于同情", "right": "道德基于正义", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 27, '{"prompt": "你的自然音量如何?", "format": "likert5", "dimension": "EI", "left": "自然而然大声说话", "right": "很难大声喊叫", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 28, '{"prompt": "你如何获取知识?", "format": "likert5", "dimension": "SN", "left": "经验主义", "right": "理论主义", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 29, '{"prompt": "什么更能驱动你?", "format": "likert5", "dimension": "JP", "left": "努力工作", "right": "尽情玩乐", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 30, '{"prompt": "你如何看待情感?", "format": "likert5", "dimension": "TF", "left": "重视情感", "right": "对情感感到不自在", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 31, '{"prompt": "你对成为焦点有什么感受?", "format": "likert5", "dimension": "EI", "left": "喜欢表演", "right": "避免公开演讲", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 32, '{"prompt": "什么问题最让你感兴趣?", "format": "likert5", "dimension": "SN", "left": "想知道「谁/什么/何时」", "right": "想知道「为什么」", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 33, '{"prompt": "充电后你更想?", "format": "likert5", "dimension": "EI", "left": "继续跟人互动", "right": "继续安静独处", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 34, '{"prompt": "陌生场合开场,你更常?", "format": "likert5", "dimension": "EI", "left": "先开口搭话", "right": "等别人来找你", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 35, '{"prompt": "想法未成形时,你更习惯?", "format": "likert5", "dimension": "EI", "left": "边说边理清", "right": "想清楚再开口", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 36, '{"prompt": "长时间会议后,你通常?", "format": "likert5", "dimension": "EI", "left": "还想再聊聊", "right": "急需一个人待着", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 37, '{"prompt": "听报告时你更抓?", "format": "likert5", "dimension": "SN", "left": "数据和步骤", "right": "含义与趋势", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 38, '{"prompt": "解决问题更依赖?", "format": "likert5", "dimension": "SN", "left": "已被验证的做法", "right": "新的可能性", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 39, '{"prompt": "描述一个人时你更说?", "format": "likert5", "dimension": "SN", "left": "具体言行细节", "right": "整体给人的感觉", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 40, '{"prompt": "读说明书你更喜欢?", "format": "likert5", "dimension": "SN", "left": "逐步照做", "right": "先看整体再试", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 41, '{"prompt": "同事出错时你更先?", "format": "likert5", "dimension": "TF", "left": "考虑对方感受", "right": "指出问题本身", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 42, '{"prompt": "评价方案更看?", "format": "likert5", "dimension": "TF", "left": "对人是否友好", "right": "是否高效正确", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 43, '{"prompt": "争执后你更在意?", "format": "likert5", "dimension": "TF", "left": "关系有没有裂痕", "right": "道理有没有说清", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 44, '{"prompt": "给反馈时你更倾向?", "format": "likert5", "dimension": "TF", "left": "先肯定再建议", "right": "直接说关键点", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 45, '{"prompt": "旅行行李你更?", "format": "likert5", "dimension": "JP", "left": "提前打包清单", "right": "临走再塞", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 46, '{"prompt": "工作日历你更?", "format": "likert5", "dimension": "JP", "left": "日程排满更安心", "right": "留白机动更舒服", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 47, '{"prompt": "规则变化时你?", "format": "likert5", "dimension": "JP", "left": "希望尽早确定新规", "right": "可以边走边调整", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 48, '{"prompt": "桌面文件你更?", "format": "likert5", "dimension": "JP", "left": "分类归档", "right": "先堆着再用时找", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb); diff --git a/apps/api/migrations/000022_mbti_full_60.down.sql b/apps/api/migrations/000022_mbti_full_60.down.sql new file mode 100644 index 0000000..320c16b --- /dev/null +++ b/apps/api/migrations/000022_mbti_full_60.down.sql @@ -0,0 +1,2 @@ +UPDATE scale_questions SET deleted_at=now(), updated_at=now() +WHERE scale_id='22222222-2222-2222-2222-222222222210' AND deleted_at IS NULL AND sort > 48; diff --git a/apps/api/migrations/000022_mbti_full_60.up.sql b/apps/api/migrations/000022_mbti_full_60.up.sql new file mode 100644 index 0000000..62a1829 --- /dev/null +++ b/apps/api/migrations/000022_mbti_full_60.up.sql @@ -0,0 +1,67 @@ +-- Expand mbti-full to 60 questions (15 per dimension) +UPDATE scale_questions SET deleted_at=now(), updated_at=now() WHERE scale_id='22222222-2222-2222-2222-222222222210' AND deleted_at IS NULL; +UPDATE scale_results SET deleted_at=now(), updated_at=now() WHERE scale_id='22222222-2222-2222-2222-222222222210' AND deleted_at IS NULL; +UPDATE scales SET title='MBTI完整版', + description='成长会员专享:四维各 15 题,共 60 题。含 OEJTS 标准 32 题 + 扩展题,偏好更稳定。', + updated_at=now() WHERE id='22222222-2222-2222-2222-222222222210'; +INSERT INTO scale_questions (scale_id, sort, body) VALUES +('22222222-2222-2222-2222-222222222210', 1, '{"prompt": "你如何记录任务?", "format": "likert5", "dimension": "JP", "left": "制定清单", "right": "依靠记忆", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 2, '{"prompt": "你如何看待新信息?", "format": "likert5", "dimension": "TF", "left": "愿意相信", "right": "持怀疑态度", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 3, '{"prompt": "你对独处有什么感受?", "format": "likert5", "dimension": "EI", "left": "独处时感到无聊", "right": "需要独处时间", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 4, '{"prompt": "你如何看待现状?", "format": "likert5", "dimension": "SN", "left": "接受事物的本来面目", "right": "对现状不满足", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 5, '{"prompt": "你如何整理空间?", "format": "likert5", "dimension": "JP", "left": "保持房间整洁", "right": "随手放置东西", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 6, '{"prompt": "你如何看待逻辑思维?", "format": "likert5", "dimension": "TF", "left": "认为「像机器人」是侮辱", "right": "追求机械般的思维", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 7, '{"prompt": "你的能量状态如何?", "format": "likert5", "dimension": "EI", "left": "精力充沛", "right": "平静温和", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 8, '{"prompt": "你喜欢什么类型的考试?", "format": "likert5", "dimension": "SN", "left": "喜欢选择题", "right": "喜欢论述题", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 9, '{"prompt": "你如何形容自己的生活方式?", "format": "likert5", "dimension": "JP", "left": "有条理", "right": "随性混乱", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 10, '{"prompt": "你如何应对批评?", "format": "likert5", "dimension": "TF", "left": "容易受伤", "right": "脸皮厚", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 11, '{"prompt": "你在什么环境下工作最好?", "format": "likert5", "dimension": "EI", "left": "在团队中表现最佳", "right": "独自工作表现最佳", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 12, '{"prompt": "你的时间焦点在哪里?", "format": "likert5", "dimension": "SN", "left": "关注过去", "right": "关注未来", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 13, '{"prompt": "你何时制定计划?", "format": "likert5", "dimension": "JP", "left": "提前规划", "right": "最后一刻才计划", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 14, '{"prompt": "你希望从他人那里得到什么?", "format": "likert5", "dimension": "TF", "left": "渴望他人的爱", "right": "渴望他人的尊重", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 15, '{"prompt": "聚会让你感觉如何?", "format": "likert5", "dimension": "EI", "left": "因聚会而兴奋", "right": "因聚会而疲惫", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 16, '{"prompt": "在群体中,你倾向于?", "format": "likert5", "dimension": "SN", "left": "融入群体", "right": "与众不同", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 17, '{"prompt": "你如何做决定?", "format": "likert5", "dimension": "JP", "left": "做出承诺", "right": "保留选择", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 18, '{"prompt": "你想擅长什么?", "format": "likert5", "dimension": "TF", "left": "想擅长帮助他人", "right": "想擅长修理事物", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 19, '{"prompt": "在交谈中,你更倾向于?", "format": "likert5", "dimension": "EI", "left": "话比较多", "right": "更善于倾听", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 20, '{"prompt": "讲故事时,你会?", "format": "likert5", "dimension": "SN", "left": "描述发生了什么", "right": "描述这意味着什么", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 21, '{"prompt": "你何时完成任务?", "format": "likert5", "dimension": "JP", "left": "立即完成工作", "right": "拖延", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 22, '{"prompt": "你做选择时更信?", "format": "likert5", "dimension": "TF", "left": "跟随内心", "right": "跟随理性", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 23, '{"prompt": "周末你更喜欢做什么?", "format": "likert5", "dimension": "EI", "left": "喜欢外出活动", "right": "喜欢待在家里", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 24, '{"prompt": "学习新事物时,你想要什么?", "format": "likert5", "dimension": "SN", "left": "想要细节", "right": "想要大局观", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 25, '{"prompt": "你如何应对新情况?", "format": "likert5", "dimension": "JP", "left": "提前准备", "right": "即兴发挥", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 26, '{"prompt": "道德的基础更接近?", "format": "likert5", "dimension": "TF", "left": "道德基于同情", "right": "道德基于正义", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 27, '{"prompt": "你的自然音量如何?", "format": "likert5", "dimension": "EI", "left": "自然而然大声说话", "right": "很难大声喊叫", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 28, '{"prompt": "你如何获取知识?", "format": "likert5", "dimension": "SN", "left": "经验主义", "right": "理论主义", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 29, '{"prompt": "什么更能驱动你?", "format": "likert5", "dimension": "JP", "left": "努力工作", "right": "尽情玩乐", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 30, '{"prompt": "你如何看待情感?", "format": "likert5", "dimension": "TF", "left": "重视情感", "right": "对情感感到不自在", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 31, '{"prompt": "你对成为焦点有什么感受?", "format": "likert5", "dimension": "EI", "left": "喜欢表演", "right": "避免公开演讲", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 32, '{"prompt": "什么问题最让你感兴趣?", "format": "likert5", "dimension": "SN", "left": "想知道「谁/什么/何时」", "right": "想知道「为什么」", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 33, '{"prompt": "充电后你更想?", "format": "likert5", "dimension": "EI", "left": "继续跟人互动", "right": "继续安静独处", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 34, '{"prompt": "陌生场合开场,你更常?", "format": "likert5", "dimension": "EI", "left": "先开口搭话", "right": "等别人来找你", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 35, '{"prompt": "想法未成形时,你更习惯?", "format": "likert5", "dimension": "EI", "left": "边说边理清", "right": "想清楚再开口", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 36, '{"prompt": "长时间会议后,你通常?", "format": "likert5", "dimension": "EI", "left": "还想再聊聊", "right": "急需一个人待着", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 37, '{"prompt": "学习时你更有效的是?", "format": "likert5", "dimension": "EI", "left": "小组讨论", "right": "独自钻研", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 38, '{"prompt": "电话响了你更常?", "format": "likert5", "dimension": "EI", "left": "立刻接听很自然", "right": "先看是谁再决定", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 39, '{"prompt": "庆祝好事时你更想?", "format": "likert5", "dimension": "EI", "left": "叫上朋友一起", "right": "自己慢慢回味", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 40, '{"prompt": "听报告时你更抓?", "format": "likert5", "dimension": "SN", "left": "数据和步骤", "right": "含义与趋势", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 41, '{"prompt": "解决问题更依赖?", "format": "likert5", "dimension": "SN", "left": "已被验证的做法", "right": "新的可能性", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 42, '{"prompt": "描述一个人时你更说?", "format": "likert5", "dimension": "SN", "left": "具体言行细节", "right": "整体给人的感觉", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 43, '{"prompt": "读说明书你更喜欢?", "format": "likert5", "dimension": "SN", "left": "逐步照做", "right": "先看整体再试", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 44, '{"prompt": "回忆旅行你先想起?", "format": "likert5", "dimension": "SN", "left": "吃了什么、走了哪", "right": "当时的气氛与意义", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 45, '{"prompt": "面对新工具你更?", "format": "likert5", "dimension": "SN", "left": "先摸清每个按钮", "right": "先想它能改变什么", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 46, '{"prompt": "听建议时你更信?", "format": "likert5", "dimension": "SN", "left": "有案例与证据的", "right": "有洞见与方向的", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 47, '{"prompt": "同事出错时你更先?", "format": "likert5", "dimension": "TF", "left": "考虑对方感受", "right": "指出问题本身", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 48, '{"prompt": "评价方案更看?", "format": "likert5", "dimension": "TF", "left": "对人是否友好", "right": "是否高效正确", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 49, '{"prompt": "争执后你更在意?", "format": "likert5", "dimension": "TF", "left": "关系有没有裂痕", "right": "道理有没有说清", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 50, '{"prompt": "给反馈时你更倾向?", "format": "likert5", "dimension": "TF", "left": "先肯定再建议", "right": "直接说关键点", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 51, '{"prompt": "看电影你更容易?", "format": "likert5", "dimension": "TF", "left": "代入角色情绪", "right": "分析结构与逻辑", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 52, '{"prompt": "团队冲突你更想?", "format": "likert5", "dimension": "TF", "left": "先缓和气氛", "right": "先对齐标准", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 53, '{"prompt": "做艰难决定时你更问?", "format": "likert5", "dimension": "TF", "left": "谁会受伤", "right": "哪边更合理", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 54, '{"prompt": "旅行行李你更?", "format": "likert5", "dimension": "JP", "left": "提前打包清单", "right": "临走再塞", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 55, '{"prompt": "工作日历你更?", "format": "likert5", "dimension": "JP", "left": "日程排满更安心", "right": "留白机动更舒服", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 56, '{"prompt": "规则变化时你?", "format": "likert5", "dimension": "JP", "left": "希望尽早确定新规", "right": "可以边走边调整", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 57, '{"prompt": "桌面文件你更?", "format": "likert5", "dimension": "JP", "left": "分类归档", "right": "先堆着再用时找", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 58, '{"prompt": "周末安排你更?", "format": "likert5", "dimension": "JP", "left": "大致几点做什么", "right": "看当天心情", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 59, '{"prompt": "项目收尾你更?", "format": "likert5", "dimension": "JP", "left": "尽早关掉待办", "right": "一直改到不得不停", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb), +('22222222-2222-2222-2222-222222222210', 60, '{"prompt": "约会迟到风险时你?", "format": "likert5", "dimension": "JP", "left": "宁可早到等待", "right": "卡点出发也行", "options": [{"key": "1", "text": "非常接近左侧"}, {"key": "2", "text": "比较接近左侧"}, {"key": "3", "text": "居中"}, {"key": "4", "text": "比较接近右侧"}, {"key": "5", "text": "非常接近右侧"}]}'::jsonb); diff --git a/apps/api/migrations/000023_home_daily_tips.down.sql b/apps/api/migrations/000023_home_daily_tips.down.sql new file mode 100644 index 0000000..15318be --- /dev/null +++ b/apps/api/migrations/000023_home_daily_tips.down.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS home_daily_tips; diff --git a/apps/api/migrations/000023_home_daily_tips.up.sql b/apps/api/migrations/000023_home_daily_tips.up.sql new file mode 100644 index 0000000..6354f61 --- /dev/null +++ b/apps/api/migrations/000023_home_daily_tips.up.sql @@ -0,0 +1,14 @@ +-- Persist homepage tips per user × 时辰 (ECR-adjacent · home R7) + +CREATE TABLE IF NOT EXISTS home_daily_tips ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + user_id uuid NOT NULL REFERENCES users(id), + shichen_start timestamptz NOT NULL, + shichen smallint NOT NULL CHECK (shichen BETWEEN 0 AND 11), + tips jsonb NOT NULL, + source varchar(16) NOT NULL DEFAULT 'fallback', + created_at timestamptz NOT NULL DEFAULT now(), + UNIQUE (user_id, shichen_start) +); +CREATE INDEX IF NOT EXISTS idx_home_daily_tips_user_start + ON home_daily_tips (user_id, shichen_start DESC); diff --git a/apps/user-h5/e2e/p2-explore-paths.spec.ts b/apps/user-h5/e2e/p2-explore-paths.spec.ts index b1de475..3b90e5f 100644 --- a/apps/user-h5/e2e/p2-explore-paths.spec.ts +++ b/apps/user-h5/e2e/p2-explore-paths.spec.ts @@ -100,7 +100,8 @@ test('star / rhythm / cards pages render with mocked API', async ({ page }) => { await expect(page.getByText('E2E节律')).toBeVisible() await page.goto('/psy/cards') - await expect(page.getByRole('heading', { name: 'Hi,我是愈心 AI' })).toBeVisible() + await expect(page.getByRole('heading', { name: '意象卡片' })).toBeVisible() + await expect(page.getByText('投射整理 · 自我反思')).toBeVisible() await page.getByRole('button', { name: '关联生日' }).click() await page.locator('input[type="number"]').nth(0).fill('1990') await page.locator('input[type="number"]').nth(1).fill('5') diff --git a/apps/user-h5/package.json b/apps/user-h5/package.json index c1563f4..084e4cf 100644 --- a/apps/user-h5/package.json +++ b/apps/user-h5/package.json @@ -24,6 +24,7 @@ }, "devDependencies": { "@playwright/test": "^1.50.1", + "@types/node": "^26.2.0", "@vitejs/plugin-vue": "^5.2.1", "@vue/test-utils": "^2.4.6", "jsdom": "^26.0.0", diff --git a/apps/user-h5/public/default-avatar.png b/apps/user-h5/public/default-avatar.png new file mode 100644 index 0000000..5f1a4bd Binary files /dev/null and b/apps/user-h5/public/default-avatar.png differ diff --git a/apps/user-h5/public/logo/愈心小人-正面.png b/apps/user-h5/public/logo/愈心小人-正面.png new file mode 100644 index 0000000..d22f214 Binary files /dev/null and b/apps/user-h5/public/logo/愈心小人-正面.png differ diff --git a/apps/user-h5/public/logo/愈心小人.png b/apps/user-h5/public/logo/愈心小人.png new file mode 100644 index 0000000..4608773 Binary files /dev/null and b/apps/user-h5/public/logo/愈心小人.png differ diff --git a/apps/user-h5/public/logo/愈心小人1.png b/apps/user-h5/public/logo/愈心小人1.png new file mode 100644 index 0000000..002277b Binary files /dev/null and b/apps/user-h5/public/logo/愈心小人1.png differ diff --git a/apps/user-h5/src/App.vue b/apps/user-h5/src/App.vue index 6323a10..0c74ea6 100644 --- a/apps/user-h5/src/App.vue +++ b/apps/user-h5/src/App.vue @@ -1,34 +1,12 @@ - - diff --git a/apps/user-h5/src/components/AppHeader.vue b/apps/user-h5/src/components/AppHeader.vue index c4e6396..15053a8 100644 --- a/apps/user-h5/src/components/AppHeader.vue +++ b/apps/user-h5/src/components/AppHeader.vue @@ -1,29 +1,74 @@ - diff --git a/apps/user-h5/src/components/BackButton.vue b/apps/user-h5/src/components/BackButton.vue index d6a01da..64596aa 100644 --- a/apps/user-h5/src/components/BackButton.vue +++ b/apps/user-h5/src/components/BackButton.vue @@ -1,11 +1,14 @@ @@ -21,15 +24,32 @@ function go() { diff --git a/apps/user-h5/src/components/HomeToolIcon.vue b/apps/user-h5/src/components/HomeToolIcon.vue index e2fd7f7..c3db575 100644 --- a/apps/user-h5/src/components/HomeToolIcon.vue +++ b/apps/user-h5/src/components/HomeToolIcon.vue @@ -205,6 +205,35 @@ + + + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + · @@ -214,20 +243,9 @@ diff --git a/apps/user-h5/src/components/ask/AskAdvisorChat.vue b/apps/user-h5/src/components/ask/AskAdvisorChat.vue new file mode 100644 index 0000000..583a214 --- /dev/null +++ b/apps/user-h5/src/components/ask/AskAdvisorChat.vue @@ -0,0 +1,172 @@ + + + + + diff --git a/apps/user-h5/src/components/ask/AskAiPane.vue b/apps/user-h5/src/components/ask/AskAiPane.vue index 1787288..5405b53 100644 --- a/apps/user-h5/src/components/ask/AskAiPane.vue +++ b/apps/user-h5/src/components/ask/AskAiPane.vue @@ -15,6 +15,7 @@ - {{ p.relation === 'self' ? '我' : 'TA' }} - {{ p.relation === 'self' ? '我的档案' : p.display_name || '未命名' }} + {{ p.relation === 'self' ? selfMark : 'TA' }} + {{ + p.relation === 'self' ? selfLabel : p.display_name || '未命名' + }}
@@ -34,14 +36,19 @@ diff --git a/apps/user-h5/src/components/imagecard/ImageCardGreeting.vue b/apps/user-h5/src/components/imagecard/ImageCardGreeting.vue index 78d8d55..912f88a 100644 --- a/apps/user-h5/src/components/imagecard/ImageCardGreeting.vue +++ b/apps/user-h5/src/components/imagecard/ImageCardGreeting.vue @@ -1,19 +1,11 @@ + + diff --git a/apps/user-h5/src/components/mine/MineAvatarSheet.vue b/apps/user-h5/src/components/mine/MineAvatarSheet.vue new file mode 100644 index 0000000..8524a05 --- /dev/null +++ b/apps/user-h5/src/components/mine/MineAvatarSheet.vue @@ -0,0 +1,121 @@ + + + + + diff --git a/apps/user-h5/src/components/mine/MineHero.vue b/apps/user-h5/src/components/mine/MineHero.vue new file mode 100644 index 0000000..cdef899 --- /dev/null +++ b/apps/user-h5/src/components/mine/MineHero.vue @@ -0,0 +1,111 @@ + + + + + diff --git a/apps/user-h5/src/components/mine/MineNavSection.vue b/apps/user-h5/src/components/mine/MineNavSection.vue new file mode 100644 index 0000000..1942a17 --- /dev/null +++ b/apps/user-h5/src/components/mine/MineNavSection.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/apps/user-h5/src/components/profile/AccountNicknameCard.vue b/apps/user-h5/src/components/profile/AccountNicknameCard.vue index 7d339c2..d2e3eb0 100644 --- a/apps/user-h5/src/components/profile/AccountNicknameCard.vue +++ b/apps/user-h5/src/components/profile/AccountNicknameCard.vue @@ -4,7 +4,7 @@

账号昵称

{{ nickname || '未设置' }}

-

首页「自己」处展示;默认如心语岛、微光谷

+

首页展示此昵称;默认如心语岛、微光谷

@@ -29,7 +29,9 @@ diff --git a/apps/user-h5/src/components/scale/ScaleResult.vue b/apps/user-h5/src/components/scale/ScaleResult.vue index c9f7953..7577502 100644 --- a/apps/user-h5/src/components/scale/ScaleResult.vue +++ b/apps/user-h5/src/components/scale/ScaleResult.vue @@ -5,23 +5,38 @@
- 用结果去做关系理解 → - 去问答聊聊 → + + + 用结果去做关系理解 → + + + 去问答聊聊 → +
diff --git a/apps/user-h5/src/pages/CompanionPage.vue b/apps/user-h5/src/pages/CompanionPage.vue index 021413d..80f190b 100644 --- a/apps/user-h5/src/pages/CompanionPage.vue +++ b/apps/user-h5/src/pages/CompanionPage.vue @@ -2,8 +2,11 @@ @@ -92,6 +95,7 @@ diff --git a/apps/user-h5/src/pages/ExploreCategoryPage.vue b/apps/user-h5/src/pages/ExploreCategoryPage.vue index caf4136..7e95771 100644 --- a/apps/user-h5/src/pages/ExploreCategoryPage.vue +++ b/apps/user-h5/src/pages/ExploreCategoryPage.vue @@ -2,9 +2,11 @@ @@ -32,10 +34,9 @@ diff --git a/apps/user-h5/src/pages/LoginPage.vue b/apps/user-h5/src/pages/LoginPage.vue index 2da6227..61a54c2 100644 --- a/apps/user-h5/src/pages/LoginPage.vue +++ b/apps/user-h5/src/pages/LoginPage.vue @@ -2,11 +2,6 @@