commit 1da4d8cf1f2ee0a1b8e4873c8c16845274067b00 Author: rain <982766701@qq.com> Date: Mon Jul 13 00:23:04 2026 +0800 家谱APP首页样式设计完成,落地80% diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..82682d7 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,115 @@ +# AGENTS.md +Behavioral guidelines to reduce common LLM coding mistakes. Merge with project-specific instructions as needed. + +Tradeoff: These guidelines bias toward caution over speed. For trivial tasks, use judgment. + +1. Think Before Coding +Don't assume. Don't hide confusion. Surface tradeoffs. + +Before implementing: + +State your assumptions explicitly. If uncertain, ask. +If multiple interpretations exist, present them instead of picking silently. +If a simpler approach exists, say so. Push back when warranted. +If something is unclear, stop. Name what is confusing. Ask. + +2. Simplicity First +Minimum code that solves the problem. Nothing speculative. + +No features beyond what was asked. +No abstractions for single-use code. +No "flexibility" or "configurability" that was not requested. +No error handling for impossible scenarios. +If you write 200 lines and it could be 50, rewrite it. +Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify. + +3. Surgical Changes +Touch only what you must. Clean up only your own mess. + +When editing existing code: + +Do not "improve" adjacent code, comments, or formatting. +Do not refactor things that are not broken. +Match existing style, even if you would do it differently. +If you notice unrelated dead code, mention it instead of deleting it. + +When your changes create orphans: + +Remove imports, variables, functions, files, docs, and references that YOUR changes made unused. +Do not remove pre-existing dead code unless asked. +The test: Every changed line should trace directly to the user's request. + +4. Contract Discipline +When a new contract lands, make it the only contract in the same change. + +A contract means any source-of-truth rule that code depends on: data shape, API boundary, schema, field name, config key, prompt format, file layout, runtime entrypoint, ownership boundary, or workflow. + +When introducing or changing a contract, do all three in the same round: + +Specify the single owner. + +Identify the one module, function, schema, document, or service that owns the contract. +Do not leave the same rule duplicated across frontend, backend, scripts, prompts, docs, or tests. +If multiple places need the value, they should consume it from the owner rather than redefine it. + +Delete old fields and old entrypoints. + +Remove obsolete fields, fallback reads, compatibility branches, legacy routes, stale config keys, old scripts, and old docs. +Do not keep the old path "just in case" unless the user explicitly asks for a compatibility period. +If compatibility is required, name it as temporary, define the removal condition, and keep it narrow. + +Tighten validators and runtime together. + +Update schemas, validators, tests, fixtures, seed data, docs, and runtime code in the same change. +Make invalid old inputs fail early and loudly. +Do not allow runtime behavior to accept shapes that validators reject, or validators to allow shapes that runtime no longer supports. +The rule: New owner, old path removed, validator and runtime tightened. If one is missing, the contract migration is not complete. + +5. Goal-Driven Execution +Define success criteria. Loop until verified. + +Transform tasks into verifiable goals: + +"Add validation" -> "Write tests for invalid inputs, then make them pass." +"Fix the bug" -> "Write a test that reproduces it, then make it pass." +"Refactor X" -> "Ensure tests pass before and after." +"Change a contract" -> "Identify owner, remove old paths, tighten validators and runtime, then verify old inputs fail." + +For multi-step tasks, state a brief plan: + +1. [Step] -> verify: [check] +2. [Step] -> verify: [check] +3. [Step] -> verify: [check] + +Strong success criteria let you loop independently. Weak criteria like "make it work" require clarification. + +6. Verification Before Closure +A change is not finished until the relevant behavior is checked. + +Before reporting completion: + +Run the smallest relevant test, script, typecheck, build, or manual verification. +Prefer focused verification over broad, noisy suites when the task is narrow. +If verification cannot be run, say exactly why. +If verification is only by inspection, say that clearly. +If the task changed a contract, verify both the new valid path and the old invalid path. +Do not claim success from intent. Claim success from evidence. + +7. Reporting Results +Be concise, concrete, and honest. + +When summarizing work: + +Say what changed. +Say how it was verified. +Mention any remaining risk or skipped verification. +Do not bury important caveats in vague language. +Do not over-explain routine edits. + +Good final answer shape: + +Changed: [short summary] +Verified: [command/check] +Notes: [only if needed] + +These guidelines are working if: fewer unnecessary changes in diffs, fewer rewrites due to overcomplication, fewer hidden compatibility paths, clearer ownership of contracts, and clarifying questions happen before implementation rather than after mistakes. diff --git a/APP.openapi.yaml b/APP.openapi.yaml new file mode 100644 index 0000000..7a55ab6 --- /dev/null +++ b/APP.openapi.yaml @@ -0,0 +1,5287 @@ +openapi: 3.0.1 +info: + title: APP + description: | + 家谱业务 APP/PC 用户侧接口文档,用于 Apifox 导入。 + + 导入方式:Apifox -> 导入 API 数据 -> OpenAPI/Swagger -> 选择本文件。 + + 约定: + - APP 路径前缀为 `/genealogy/app` + - PC/H5 路径前缀为 `/genealogy/pc` + - 后台管理接口不包含在本文件内 + - 登录后接口需要携带 token,且请求 Header 需携带 `clientid` + version: 1.0.0 +tags: + - name: 验证中心 + - name: 认证登录 + - name: 文件上传 + - name: 行政区划 + - name: 家谱 + - name: 家谱成员 + - name: 字辈谱 + - name: 世系人物 + - name: 家族圈 + - name: 内容文章 + - name: 相册 + - name: 祭祀 + - name: 族务记录 + - name: 消息通知 + - name: 意见反馈 + - name: VIP +paths: + /captcha/require: + get: + summary: 查询当前场景是否需要验证 + deprecated: false + description: 用于登录、注册、换绑手机等场景。按租户、客户端和场景编码匹配后台验证策略。 + tags: + - 验证中心 + parameters: + - name: tenantId + in: query + description: 租户ID,用于区分不同租户的数据和验证策略 + required: false + example: '000000' + schema: + type: string + - name: clientId + in: query + description: 客户端ID,对应后台客户端管理中的APP/PC/小程序等终端 + required: false + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + - name: sceneCode + in: query + description: 验证场景编码,例如APP_LOGIN、PC_LOGIN、APP_REGISTER + required: true + example: APP_LOGIN + schema: + type: string + - name: subject + in: query + description: 验证主体,通常为手机号、用户ID或登录账号 + required: false + example: '13800000000' + schema: + type: string + - name: clientid + in: header + description: '' + required: false + example: ced7e5f0498645c6ec642dcf450b036f + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VerificationRequireResult' + description: 验证需求查询结果 + security: + - SaToken: [] + /captcha/challenge: + post: + summary: 生成验证挑战 + deprecated: false + description: 统一生成验证码。策略为天爱时返回行为验证数据;策略为系统图形时返回 uuid 和 img。 + tags: + - 验证中心 + parameters: + - name: clientid + in: header + description: 客户端ID + example: ced7e5f0498645c6ec642dcf450b036f + schema: + type: string + default: ced7e5f0498645c6ec642dcf450b036f + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/VerificationChallengeBody' + example: + tenantId: '000000' + clientId: 428a8310cd442757ae699df5d894f051 + sceneCode: APP_LOGIN + subject: '13800000000' + required: true + responses: + '200': + $ref: '#/components/responses/VerificationChallengeResult' + description: 验证挑战生成结果 + security: + - SaToken: [] + /captcha/verify: + post: + summary: 校验验证结果并换取 validToken + deprecated: false + description: 验证通过后返回 validToken,登录、注册、发短信等业务接口将 validToken 随请求体一起提交。 + tags: + - 验证中心 + parameters: + - name: clientid + in: header + description: 客户端ID + example: ced7e5f0498645c6ec642dcf450b036f + schema: + type: string + default: ced7e5f0498645c6ec642dcf450b036f + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/VerificationCheckBody' + examples: + tianai_behavior: + value: + tenantId: '000000' + clientId: 428a8310cd442757ae699df5d894f051 + sceneCode: APP_LOGIN + subject: '13800000000' + challengeId: CAPTCHA_CHALLENGE_ID + providerCode: tianai + captchaType: SLIDER + payload: + id: tianai-captcha-id + data: + bgImageWidth: 340 + bgImageHeight: 180 + startSlidingTime: 1720000000000 + endSlidingTime: 1720000001500 + trackList: [] + summary: 天爱滑块/旋转/滑动还原/文字点选验证 + system_image: + value: + tenantId: '000000' + clientId: 428a8310cd442757ae699df5d894f051 + sceneCode: APP_LOGIN + subject: '13800000000' + challengeId: CAPTCHA_CHALLENGE_ID + providerCode: ruoyi_image + captchaType: math + payload: + uuid: captcha-uuid + code: '6' + summary: 系统图形验证码 + required: true + responses: + '200': + $ref: '#/components/responses/VerificationCheckResult' + description: 验证校验结果 + security: + - SaToken: [] + /auth/code: + get: + summary: 兼容旧系统图形验证码 + deprecated: false + description: >- + 老版后台登录图形验证码入口。新的 APP/PC 业务优先使用 /captcha/require + /captcha/challenge + + /captcha/verify。 + tags: + - 验证中心 + parameters: + - name: clientid + in: header + description: 客户端ID + example: ced7e5f0498645c6ec642dcf450b036f + schema: + type: string + default: ced7e5f0498645c6ec642dcf450b036f + responses: + '200': + $ref: '#/components/responses/LegacyCaptchaResult' + description: 兼容旧图形验证码结果 + security: + - SaToken: [] + /genealogy/app/auth/register: + post: + summary: APP 用户注册 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordRegisterBody' + required: true + responses: + '200': + $ref: '#/components/responses/LoginResult' + description: 登录结果 + security: + - SaToken: [] + /genealogy/app/auth/login: + post: + summary: APP 密码登录 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordLoginBody' + required: true + responses: + '200': + $ref: '#/components/responses/LoginResult' + description: 登录结果 + security: + - SaToken: [] + /genealogy/app/auth/login/sms: + post: + summary: APP 短信登录 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/SmsLoginBody' + required: true + responses: + '200': + $ref: '#/components/responses/LoginResult' + description: 登录结果 + security: + - SaToken: [] + /genealogy/app/auth/sms/code: + post: + summary: APP 发送短信验证码 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/SmsCodeBody' + required: true + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/auth/profile: + get: + summary: APP 当前用户资料 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + put: + summary: APP 修改用户资料 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileUpdateBody' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/auth/password: + put: + summary: APP 修改密码 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordChangeBody' + required: true + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/auth/password/reset: + put: + summary: APP 找回密码 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordResetBody' + required: true + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/auth/phone: + put: + summary: APP 换绑手机号 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PhoneChangeBody' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/auth/account/deactivate: + post: + summary: APP 注销账号 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AccountDeactivateBody' + required: true + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/auth/logout: + delete: + summary: APP 退出登录 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/pc/auth/register: + post: + summary: PC 用户注册 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordRegisterBody' + required: true + responses: + '200': + $ref: '#/components/responses/LoginResult' + description: 登录结果 + security: + - SaToken: [] + /genealogy/pc/auth/login: + post: + summary: PC 密码登录 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordLoginBody' + required: true + responses: + '200': + $ref: '#/components/responses/LoginResult' + description: 登录结果 + security: + - SaToken: [] + /genealogy/pc/auth/login/sms: + post: + summary: PC 短信登录 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/SmsLoginBody' + required: true + responses: + '200': + $ref: '#/components/responses/LoginResult' + description: 登录结果 + security: + - SaToken: [] + /genealogy/pc/auth/sms/code: + post: + summary: PC 发送短信验证码 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/SmsCodeBody' + required: true + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/pc/auth/profile: + get: + summary: PC 当前用户资料 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + put: + summary: PC 修改用户资料 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileUpdateBody' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/pc/auth/password: + put: + summary: PC 修改密码 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordChangeBody' + required: true + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/pc/auth/password/reset: + put: + summary: PC 找回密码 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordResetBody' + required: true + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/pc/auth/phone: + put: + summary: PC 换绑手机号 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PhoneChangeBody' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/pc/auth/account/deactivate: + post: + summary: PC 注销账号 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AccountDeactivateBody' + required: true + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/pc/auth/logout: + delete: + summary: PC 退出登录 + deprecated: false + description: '' + tags: + - 认证登录 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/files/upload: + post: + summary: APP 单文件上传 + deprecated: false + description: '' + tags: + - 文件上传 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + file: + type: string + format: binary + example: '' + required: + - file + example: + file: '' + required: true + responses: + '200': + $ref: '#/components/responses/FileUploadResult' + description: 文件上传结果 + security: + - SaToken: [] + /genealogy/app/files/resumable/init: + post: + summary: APP 分片上传初始化 + deprecated: false + description: '' + tags: + - 文件上传 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ResumableInitBody' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/files/resumable/chunk: + post: + summary: APP 上传分片 + deprecated: false + description: '' + tags: + - 文件上传 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + uploadId: + type: string + example: '' + chunkIndex: + type: integer + example: 0 + chunkMd5: + type: string + example: d41d8cd98f00b204e9800998ecf8427e + file: + type: string + format: binary + example: '' + required: + - uploadId + - chunkIndex + - chunkMd5 + - file + example: + uploadId: '' + chunkIndex: 0 + chunkMd5: d41d8cd98f00b204e9800998ecf8427e + file: '' + required: true + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/files/resumable/complete: + post: + summary: APP 完成分片上传 + deprecated: false + description: '' + tags: + - 文件上传 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ResumableCompleteBody' + required: true + responses: + '200': + $ref: '#/components/responses/FileUploadResult' + description: 文件上传结果 + security: + - SaToken: [] + /genealogy/app/files/reference: + post: + summary: APP 绑定文件业务引用 + deprecated: false + description: '' + tags: + - 文件上传 + parameters: + - name: clientid + in: header + description: 客户端ID,请求Header携带,用于区分APP/PC/小程序等终端 + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/FileReferenceBody' + example: + bizType: family_feed + bizName: family feed image + bizTable: gen_family_feed + bizId: 900013001 + bizField: media_oss_ids + ossId: '2060000000000000000' + usageScene: feed_image + required: true + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + delete: + summary: APP 释放文件业务引用 + deprecated: false + description: '' + tags: + - 文件上传 + parameters: + - name: bizTable + in: query + description: 业务表名,用于文件引用绑定 + required: true + example: gen_family_feed + schema: + type: string + - name: bizId + in: query + description: 业务数据ID,用于文件引用绑定 + required: true + example: 900013001 + schema: + type: integer + format: int64 + - name: bizField + in: query + description: 业务字段名,例如avatar_oss_id、cover_oss_id + required: true + example: media_ids + schema: + type: string + - name: clientid + in: header + description: 客户端ID,请求Header携带,用于区分APP/PC/小程序等终端 + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/pc/files/upload: + post: + summary: PC 单文件上传 + deprecated: false + description: '' + tags: + - 文件上传 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + file: + type: string + format: binary + example: '' + required: + - file + example: + file: '' + required: true + responses: + '200': + $ref: '#/components/responses/FileUploadResult' + description: 文件上传结果 + security: + - SaToken: [] + /genealogy/pc/files/resumable/init: + post: + summary: PC 分片上传初始化 + deprecated: false + description: '' + tags: + - 文件上传 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ResumableInitBody' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/pc/files/resumable/chunk: + post: + summary: PC 上传分片 + deprecated: false + description: '' + tags: + - 文件上传 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + uploadId: + type: string + example: '' + chunkIndex: + type: integer + example: 0 + chunkMd5: + type: string + example: d41d8cd98f00b204e9800998ecf8427e + file: + type: string + format: binary + example: '' + required: + - uploadId + - chunkIndex + - chunkMd5 + - file + example: + uploadId: '' + chunkIndex: 0 + chunkMd5: d41d8cd98f00b204e9800998ecf8427e + file: '' + required: true + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/pc/files/resumable/complete: + post: + summary: PC 完成分片上传 + deprecated: false + description: '' + tags: + - 文件上传 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ResumableCompleteBody' + required: true + responses: + '200': + $ref: '#/components/responses/FileUploadResult' + description: 文件上传结果 + security: + - SaToken: [] + /genealogy/region/children: + get: + summary: 查询下级行政区划 + deprecated: false + description: '' + tags: + - 行政区划 + parameters: + - name: parentCode + in: query + description: '' + required: false + example: '51' + schema: + type: string + - name: clientid + in: header + description: 客户端ID + example: ced7e5f0498645c6ec642dcf450b036f + schema: + type: string + default: ced7e5f0498645c6ec642dcf450b036f + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/region/path/{regionCode}: + get: + summary: 查询行政区划路径 + deprecated: false + description: '' + tags: + - 行政区划 + parameters: + - name: regionCode + in: path + description: '' + required: true + example: '510000' + schema: + type: string + - name: clientid + in: header + description: 客户端ID + example: ced7e5f0498645c6ec642dcf450b036f + schema: + type: string + default: ced7e5f0498645c6ec642dcf450b036f + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/region/search: + get: + summary: 搜索行政区划 + deprecated: false + description: '' + tags: + - 行政区划 + parameters: + - name: keyword + in: query + description: '' + required: true + example: 北京 + schema: + type: string + - name: level + in: query + description: '' + required: false + example: 3 + schema: + type: integer + - name: limit + in: query + description: '' + required: false + example: 20 + schema: + type: integer + - name: clientid + in: header + description: 客户端ID + example: ced7e5f0498645c6ec642dcf450b036f + schema: + type: string + default: ced7e5f0498645c6ec642dcf450b036f + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/region/{regionCode}: + get: + summary: 查询行政区划详情 + deprecated: false + description: '' + tags: + - 行政区划 + parameters: + - name: regionCode + in: path + description: '' + required: true + example: '510000' + schema: + type: string + - name: clientid + in: header + description: 客户端ID + example: ced7e5f0498645c6ec642dcf450b036f + schema: + type: string + default: ced7e5f0498645c6ec642dcf450b036f + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies: + post: + summary: APP 创建家谱 + deprecated: false + description: '' + tags: + - 家谱 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/mine: + get: + summary: APP 我的家谱 + deprecated: false + description: '' + tags: + - 家谱 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/app/genealogies/public: + get: + summary: APP 公开家谱 + deprecated: false + description: '' + tags: + - 家谱 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/app/genealogies/options: + get: + summary: APP 家谱下拉选项 + deprecated: false + description: '' + tags: + - 家谱 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}: + get: + summary: APP 家谱详情 + deprecated: false + description: '' + tags: + - 家谱 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + put: + summary: APP 修改家谱 + deprecated: false + description: '' + tags: + - 家谱 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/overview: + get: + summary: APP 家谱概览 + deprecated: false + description: '' + tags: + - 家谱 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/join-applies: + post: + summary: APP 申请加入家谱 + deprecated: false + description: '' + tags: + - 家谱 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/join-applies/mine: + get: + summary: APP 我的加入申请 + deprecated: false + description: '' + tags: + - 家谱 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/join-applies/pending: + get: + summary: APP 待审核加入申请 + deprecated: false + description: '' + tags: + - 家谱 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/join-applies/{applyId}/audit: + put: + summary: APP 审核加入申请 + deprecated: false + description: '' + tags: + - 家谱 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: applyId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/genealogies/join-applies/{applyId}: + delete: + summary: APP 撤销加入申请 + deprecated: false + description: '' + tags: + - 家谱 + parameters: + - name: applyId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/members: + get: + summary: APP 家谱成员列表 + deprecated: false + description: '' + tags: + - 家谱成员 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/members/options: + get: + summary: APP 家谱成员选项 + deprecated: false + description: '' + tags: + - 家谱成员 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/members/{memberId}: + put: + summary: APP 修改成员 + deprecated: false + description: '' + tags: + - 家谱成员 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: memberId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + delete: + summary: APP 移除成员 + deprecated: false + description: '' + tags: + - 家谱成员 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: memberId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/members/me: + delete: + summary: APP 退出家谱 + deprecated: false + description: '' + tags: + - 家谱成员 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/members/owner-transfer: + put: + summary: APP 转让家谱所有者 + deprecated: false + description: '' + tags: + - 家谱成员 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/generation-poems: + get: + summary: APP 查询字辈谱 + deprecated: false + description: '' + tags: + - 字辈谱 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + post: + summary: APP 新增字辈 + deprecated: false + description: '' + tags: + - 字辈谱 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/generation-poems/batch/preview: + post: + summary: APP 批量字辈预览 + deprecated: false + description: '' + tags: + - 字辈谱 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GenerationPoemBatchBody' + required: true + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/generation-poems/batch/save: + post: + summary: APP 批量保存字辈 + deprecated: false + description: '' + tags: + - 字辈谱 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GenerationPoemBatchBody' + required: true + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/generation-poems/{poemId}: + put: + summary: APP 修改字辈 + deprecated: false + description: '' + tags: + - 字辈谱 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: poemId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/lineage/persons: + get: + summary: APP 世系人物列表 + deprecated: false + description: '' + tags: + - 世系人物 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + post: + summary: APP 新增世系人物 + deprecated: false + description: '' + tags: + - 世系人物 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/LineagePersonBody' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/lineage/persons/page: + get: + summary: APP 世系人物分页 + deprecated: false + description: '' + tags: + - 世系人物 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: pageNum + in: query + description: '' + required: false + schema: + type: integer + default: 1 + - name: pageSize + in: query + description: '' + required: false + schema: + type: integer + default: 10 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/PageResult' + description: 通用分页响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/lineage/persons/options: + get: + summary: APP 世系人物选项 + deprecated: false + description: '' + tags: + - 世系人物 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/lineage/tree: + get: + summary: APP 世系树 + deprecated: false + description: '' + tags: + - 世系人物 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}: + get: + summary: APP 世系人物详情 + deprecated: false + description: '' + tags: + - 世系人物 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: personId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + put: + summary: APP 修改世系人物 + deprecated: false + description: '' + tags: + - 世系人物 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: personId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/LineagePersonBody' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + delete: + summary: APP 删除世系人物 + deprecated: false + description: '' + tags: + - 世系人物 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: personId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/children: + post: + summary: APP 给人物添加子女 + deprecated: false + description: '' + tags: + - 世系人物 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: personId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/LineagePersonBody' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/parents: + post: + summary: APP 给人物添加父母 + deprecated: false + description: '' + tags: + - 世系人物 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: personId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/LineagePersonBody' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/siblings: + post: + summary: APP 给人物添加兄弟姐妹 + deprecated: false + description: '' + tags: + - 世系人物 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: personId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/LineagePersonBody' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/spouses: + post: + summary: APP 给人物添加配偶 + deprecated: false + description: '' + tags: + - 世系人物 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: personId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/LineagePersonBody' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/pc/genealogies/{genealogyId}/feeds: + get: + summary: PC 家族圈动态列表 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + post: + summary: PC 发布家族圈动态 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/FamilyFeedBody' + example: + feedType: text + feedContent: 今天上传一张老照片。 + mediaOssIds: 2060000000000000001,2060000000000000002 + sortOrder: 0 + status: '0' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/feeds: + get: + summary: APP 家族圈动态列表 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + post: + summary: APP 发布家族圈动态 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/FamilyFeedBody' + example: + feedType: text + feedContent: 今天上传一张老照片。 + mediaOssIds: 2060000000000000001,2060000000000000002 + sortOrder: 0 + status: '0' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/pc/genealogies/{genealogyId}/feeds/page: + get: + summary: PC 家族圈动态分页 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: pageNum + in: query + description: '' + required: false + schema: + type: integer + default: 1 + - name: pageSize + in: query + description: '' + required: false + schema: + type: integer + default: 10 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/PageResult' + description: 通用分页响应 + security: + - SaToken: [] + /genealogy/pc/genealogies/{genealogyId}/feeds/{feedId}: + get: + summary: PC 家族圈动态详情 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + put: + summary: PC 修改家族圈动态 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/FamilyFeedBody' + example: + feedType: text + feedContent: 今天上传一张老照片。 + mediaOssIds: 2060000000000000001,2060000000000000002 + sortOrder: 0 + status: '0' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + delete: + summary: PC 删除家族圈动态 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/feeds/page: + get: + summary: APP 家族圈动态分页 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: pageNum + in: query + description: '' + required: false + schema: + type: integer + default: 1 + - name: pageSize + in: query + description: '' + required: false + schema: + type: integer + default: 10 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/PageResult' + description: 通用分页响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}: + get: + summary: APP 家族圈动态详情 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + put: + summary: APP 修改家族圈动态 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/FamilyFeedBody' + example: + feedType: text + feedContent: 今天上传一张老照片。 + mediaOssIds: 2060000000000000001,2060000000000000002 + sortOrder: 0 + status: '0' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + delete: + summary: APP 删除家族圈动态 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/pc/genealogies/{genealogyId}/feeds/{feedId}/likes: + post: + summary: PC 点赞动态 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + delete: + summary: PC 取消点赞动态 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/likes: + post: + summary: APP 点赞动态 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + delete: + summary: APP 取消点赞动态 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/pc/genealogies/{genealogyId}/feeds/{feedId}/comments: + get: + summary: PC 动态评论列表 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + post: + summary: PC 评论动态 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/FamilyFeedCommentBody' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments: + get: + summary: APP 动态评论列表 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + post: + summary: APP 评论动态 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/FamilyFeedCommentBody' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/pc/genealogies/{genealogyId}/feeds/{feedId}/comments/page: + get: + summary: PC 动态评论分页 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: pageNum + in: query + description: '' + required: false + schema: + type: integer + default: 1 + - name: pageSize + in: query + description: '' + required: false + schema: + type: integer + default: 10 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/PageResult' + description: 通用分页响应 + security: + - SaToken: [] + /genealogy/pc/genealogies/{genealogyId}/feeds/{feedId}/comments/{commentId}: + delete: + summary: PC 删除动态评论 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: commentId + in: path + description: 评论ID + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments/page: + get: + summary: APP 动态评论分页 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: pageNum + in: query + description: '' + required: false + schema: + type: integer + default: 1 + - name: pageSize + in: query + description: '' + required: false + schema: + type: integer + default: 10 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/PageResult' + description: 通用分页响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments/{commentId}: + delete: + summary: APP 删除动态评论 + deprecated: false + description: '' + tags: + - 家族圈 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: feedId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: commentId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/article-categories: + get: + summary: APP 谱文分类 + deprecated: false + description: '' + tags: + - 内容文章 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/articles: + get: + summary: APP 谱文列表 + deprecated: false + description: '' + tags: + - 内容文章 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + post: + summary: APP 新增谱文 + deprecated: false + description: '' + tags: + - 内容文章 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/articles/{articleId}: + get: + summary: APP 谱文详情 + deprecated: false + description: '' + tags: + - 内容文章 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: articleId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + put: + summary: APP 修改谱文 + deprecated: false + description: '' + tags: + - 内容文章 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: articleId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/help-articles: + get: + summary: APP 帮助文章列表 + deprecated: false + description: '' + tags: + - 内容文章 + parameters: + - name: clientid + in: header + description: 客户端ID + example: ced7e5f0498645c6ec642dcf450b036f + schema: + type: string + default: ced7e5f0498645c6ec642dcf450b036f + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/app/help-articles/{helpId}: + get: + summary: APP 帮助文章详情 + deprecated: false + description: '' + tags: + - 内容文章 + parameters: + - name: helpId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: 客户端ID + example: ced7e5f0498645c6ec642dcf450b036f + schema: + type: string + default: ced7e5f0498645c6ec642dcf450b036f + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/promotions: + get: + summary: APP 应用推广列表 + deprecated: false + description: '' + tags: + - 内容文章 + parameters: + - name: clientid + in: header + description: 客户端ID + example: ced7e5f0498645c6ec642dcf450b036f + schema: + type: string + default: ced7e5f0498645c6ec642dcf450b036f + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/albums: + get: + summary: APP 相册列表 + deprecated: false + description: '' + tags: + - 相册 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + post: + summary: APP 创建相册 + deprecated: false + description: '' + tags: + - 相册 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/albums/{albumId}: + put: + summary: APP 修改相册 + deprecated: false + description: '' + tags: + - 相册 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: albumId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/albums/{albumId}/photos: + get: + summary: APP 相册图片列表 + deprecated: false + description: '' + tags: + - 相册 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: albumId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + post: + summary: APP 上传相册图片记录 + deprecated: false + description: '' + tags: + - 相册 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: albumId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/ceremonies: + get: + summary: APP 祭祀列表 + deprecated: false + description: '' + tags: + - 祭祀 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + post: + summary: APP 创建祭祀 + deprecated: false + description: '' + tags: + - 祭祀 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}: + get: + summary: APP 祭祀详情 + deprecated: false + description: '' + tags: + - 祭祀 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: ceremonyId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + put: + summary: APP 修改祭祀 + deprecated: false + description: '' + tags: + - 祭祀 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: ceremonyId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}/gifts: + get: + summary: APP 祭祀献礼列表 + deprecated: false + description: '' + tags: + - 祭祀 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: ceremonyId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + post: + summary: APP 新增祭祀献礼 + deprecated: false + description: '' + tags: + - 祭祀 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: ceremonyId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/growth-records: + get: + summary: APP 成长记录列表 + deprecated: false + description: '' + tags: + - 族务记录 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + post: + summary: APP 新增成长记录 + deprecated: false + description: '' + tags: + - 族务记录 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/growth-records/{recordId}: + get: + summary: APP 成长记录详情 + deprecated: false + description: '' + tags: + - 族务记录 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: recordId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + put: + summary: APP 修改成长记录 + deprecated: false + description: '' + tags: + - 族务记录 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: recordId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/memos: + get: + summary: APP 备忘录列表 + deprecated: false + description: '' + tags: + - 族务记录 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + post: + summary: APP 新增备忘录 + deprecated: false + description: '' + tags: + - 族务记录 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/memos/{memoId}: + get: + summary: APP 备忘录详情 + deprecated: false + description: '' + tags: + - 族务记录 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: memoId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + put: + summary: APP 修改备忘录 + deprecated: false + description: '' + tags: + - 族务记录 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: memoId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/genealogies/{genealogyId}/merit-records: + get: + summary: APP 功德记录列表 + deprecated: false + description: '' + tags: + - 族务记录 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + post: + summary: APP 新增功德记录 + deprecated: false + description: '' + tags: + - 族务记录 + parameters: + - name: genealogyId + in: path + description: '' + required: true + example: 900001001 + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/notifications: + get: + summary: APP 消息通知列表 + deprecated: false + description: '' + tags: + - 消息通知 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/app/notifications/{notificationId}/read: + post: + summary: APP 标记通知已读 + deprecated: false + description: '' + tags: + - 消息通知 + parameters: + - name: notificationId + in: path + description: '' + required: true + example: '' + schema: + type: integer + format: int64 + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/notifications/read-all: + post: + summary: APP 全部标记已读 + deprecated: false + description: '' + tags: + - 消息通知 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/VoidResult' + description: 通用成功响应 + security: + - SaToken: [] + /genealogy/app/feedback: + get: + summary: APP 我的反馈列表 + deprecated: false + description: '' + tags: + - 意见反馈 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + post: + summary: APP 提交反馈 + deprecated: false + description: '' + tags: + - 意见反馈 + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] + /genealogy/app/vip/packages: + get: + summary: APP VIP 套餐列表 + deprecated: false + description: '' + tags: + - VIP + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + /genealogy/app/vip/orders: + get: + summary: APP VIP 订单列表 + deprecated: false + description: '' + tags: + - VIP + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + responses: + '200': + $ref: '#/components/responses/ListResult' + description: 通用列表响应 + security: + - SaToken: [] + post: + summary: APP 创建 VIP 订单 + deprecated: false + description: '' + tags: + - VIP + parameters: + - name: clientid + in: header + description: '' + required: true + example: 428a8310cd442757ae699df5d894f051 + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/JsonObject' + required: true + responses: + '200': + $ref: '#/components/responses/ObjectResult' + description: 通用对象响应 + security: + - SaToken: [] +components: + schemas: + JsonObject: + type: object + additionalProperties: true + properties: {} + PasswordRegisterBody: + type: object + required: + - grantType + - tenantId + - phone + - password + properties: + clientId: + type: string + grantType: + type: string + example: password + tenantId: + type: string + example: '000000' + phone: + type: string + example: '13800000000' + password: + type: string + description: 32 位 MD5 + example: e10adc3949ba59abbe56e057f20f883e + nickName: + type: string + registerSource: + type: string + validToken: + type: string + PasswordLoginBody: + type: object + required: + - grantType + - tenantId + - phone + - password + properties: + clientId: + type: string + grantType: + type: string + example: password + tenantId: + type: string + example: '000000' + phone: + type: string + example: '13800000000' + password: + type: string + description: 32 位 MD5 + example: e10adc3949ba59abbe56e057f20f883e + validToken: + type: string + SmsLoginBody: + type: object + required: + - grantType + - tenantId + - phone + - smsCode + properties: + clientId: + type: string + grantType: + type: string + example: sms + tenantId: + type: string + example: '000000' + phone: + type: string + example: '13800000000' + smsCode: + type: string + example: '1234' + SmsCodeBody: + type: object + required: + - grantType + - tenantId + - sceneCode + - phone + - validToken + properties: + clientId: + type: string + grantType: + type: string + example: sms + tenantId: + type: string + example: '000000' + sceneCode: + type: string + example: APP_LOGIN + phone: + type: string + example: '13800000000' + validToken: + type: string + ProfileUpdateBody: + type: object + properties: + nickName: + type: string + avatarOssId: + type: integer + format: int64 + sex: + type: string + birthday: + type: string + format: date + provinceCode: + type: string + cityCode: + type: string + districtCode: + type: string + PasswordChangeBody: + type: object + required: + - oldPassword + - newPassword + properties: + oldPassword: + type: string + description: 32 位 MD5 + newPassword: + type: string + description: 32 位 MD5 + PasswordResetBody: + type: object + required: + - tenantId + - phone + - smsCode + - newPassword + properties: + tenantId: + type: string + example: '000000' + phone: + type: string + smsCode: + type: string + newPassword: + type: string + description: 32 位 MD5 + validToken: + type: string + PhoneChangeBody: + type: object + required: + - newPhone + - smsCode + properties: + newPhone: + type: string + smsCode: + type: string + validToken: + type: string + AccountDeactivateBody: + type: object + required: + - password + properties: + password: + type: string + description: 32 位 MD5 + reason: + type: string + ResumableInitBody: + type: object + required: + - fileName + - fileSize + - fileMd5 + - chunkSize + - totalChunks + properties: + fileName: + type: string + fileSize: + type: integer + format: int64 + fileMd5: + type: string + contentType: + type: string + chunkSize: + type: integer + example: 4194304 + totalChunks: + type: integer + bizType: + type: string + usageScene: + type: string + ResumableCompleteBody: + type: object + required: + - uploadId + - fileMd5 + - fileSize + properties: + uploadId: + type: string + fileMd5: + type: string + fileSize: + type: integer + format: int64 + FileReferenceBody: + type: object + required: + - bizType + - bizTable + - bizId + - bizField + properties: + bizType: + description: 业务类型,例如avatar、cover、feed_image + type: string + example: family_feed + bizName: + description: 业务名称,用于后台展示文件引用来源 + type: string + example: 家族圈动态 + bizTable: + description: 业务表名,用于文件引用绑定 + type: string + example: gen_family_feed + bizId: + description: 业务数据ID,用于文件引用绑定 + type: integer + format: int64 + bizField: + description: 业务字段名,例如avatar_oss_id、cover_oss_id + type: string + example: media_ids + ossId: + description: OSS文件ID,表单内部使用,用户侧应通过上传组件获取 + type: integer + format: int64 + ossIds: + type: string + example: 2060001,2060002 + usageScene: + description: 文件使用场景,便于后续引用统计和清理 + type: string + usageName: + type: string + GenerationPoemBatchBody: + type: object + properties: + content: + type: string + example: 德承家亦 + stopMissingOldGeneration: + type: boolean + example: false + LineagePersonBody: + type: object + properties: + appUserId: + type: integer + format: int64 + personNo: + type: string + personName: + type: string + aliasName: + type: string + sex: + type: string + example: '0' + generationNo: + type: integer + generationName: + type: string + avatarOssId: + type: integer + format: int64 + birthDate: + type: string + deathDate: + type: string + introduction: + type: string + FamilyFeedBody: + type: object + required: + - feedContent + properties: + feedType: + description: 动态类型,未传时默认为 text + type: string + example: text + feedContent: + description: 动态内容,不能为空 + type: string + example: 今天上传一张老照片。 + mediaOssIds: + description: 媒体文件 OSS ID 列表,多个 ID 使用英文逗号分隔 + type: string + example: 2060000000000000001,2060000000000000002 + sortOrder: + description: 排序值,未传时默认为 0 + type: integer + format: int64 + example: 0 + status: + description: 动态状态,未传时默认为正常状态 + type: string + example: '0' + FamilyFeedCommentBody: + type: object + required: + - content + properties: + parentCommentId: + type: integer + format: int64 + nullable: true + replyUserId: + type: integer + format: int64 + nullable: true + content: + type: string + VerificationChallengeBody: + type: object + required: + - sceneCode + properties: + tenantId: + type: string + description: 租户 ID + clientId: + type: string + description: 客户端 ID + sceneCode: + type: string + description: 验证场景编码,如 ADMIN_LOGIN/APP_LOGIN/APP_REGISTER + subject: + type: string + description: 验证主体,如手机号/用户名/IP + example: + tenantId: '000000' + clientId: 428a8310cd442757ae699df5d894f051 + sceneCode: APP_LOGIN + subject: '13800000000' + VerificationCheckBody: + type: object + required: + - sceneCode + properties: + tenantId: + description: 租户ID,用于区分不同租户的数据和验证策略 + type: string + clientId: + description: 客户端ID,对应后台客户端管理中的APP/PC/小程序等终端 + type: string + sceneCode: + description: 验证场景编码,例如APP_LOGIN、PC_LOGIN、APP_REGISTER + type: string + subject: + description: 验证主体,通常为手机号、用户ID或登录账号 + type: string + challengeId: + description: 验证挑战ID,由验证挑战接口返回 + type: string + providerCode: + type: string + description: 验证服务,tianai 或 ruoyi_image + captchaType: + type: string + description: SLIDER/ROTATE/CONCAT/WORD_IMAGE_CLICK/math/char + payload: + type: object + additionalProperties: true + description: 前端验证控件返回的轨迹/点击/图形验证码数据 + properties: {} + RVoid: + type: object + properties: + code: + type: integer + example: 200 + msg: + type: string + example: 操作成功 + data: + type: 'null' + RObject: + type: object + properties: + code: + type: integer + example: 200 + msg: + type: string + example: 操作成功 + data: + type: object + additionalProperties: true + properties: {} + RList: + type: object + properties: + code: + type: integer + example: 200 + msg: + type: string + example: 操作成功 + data: + type: array + items: + type: object + additionalProperties: true + properties: {} + PageResult: + type: object + properties: + code: + type: integer + example: 200 + msg: + type: string + example: 操作成功 + rows: + type: array + items: + type: object + additionalProperties: true + properties: {} + total: + type: integer + example: 0 + RLogin: + type: object + properties: + code: + type: integer + example: 200 + msg: + type: string + example: 操作成功 + data: + $ref: '#/components/schemas/LoginVo' + LoginVo: + type: object + properties: + token: + type: string + accessToken: + type: string + tokenValue: + type: string + userId: + type: integer + format: int64 + tenantId: + type: string + clientId: + type: string + clientKey: + type: string + RFileUpload: + type: object + properties: + code: + type: integer + example: 200 + msg: + type: string + example: 操作成功 + data: + $ref: '#/components/schemas/FileUploadVo' + FileUploadVo: + type: object + properties: + ossId: + type: integer + format: int64 + url: + type: string + thumbnailUrl: + type: string + nullable: true + fileName: + type: string + originalName: + type: string + RVerificationRequire: + type: object + properties: + code: + description: 系统图形验证码或响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + example: 操作成功 + data: + description: 响应数据主体 + $ref: '#/components/schemas/VerificationRequireVo' + VerificationRequireVo: + type: object + properties: + required: + description: 当前场景是否需要验证 + type: boolean + providerCode: + description: 第三方服务商编码 + type: string + captchaType: + description: 验证码类型,例如SLIDER、ROTATE、CONCAT、WORD_IMAGE_CLICK + type: string + sceneCode: + description: 验证场景编码,例如APP_LOGIN、PC_LOGIN、APP_REGISTER + type: string + ttlSeconds: + description: 验证或票据有效秒数 + type: integer + example: + required: true + providerCode: tianai + captchaType: SLIDER + sceneCode: APP_LOGIN + ttlSeconds: 300 + RVerificationChallenge: + type: object + properties: + code: + description: 系统图形验证码或响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + example: 操作成功 + data: + description: 响应数据主体 + $ref: '#/components/schemas/VerificationChallengeVo' + VerificationChallengeVo: + type: object + properties: + required: + description: 当前场景是否需要验证 + type: boolean + providerCode: + description: 第三方服务商编码 + type: string + captchaType: + description: 验证码类型,例如SLIDER、ROTATE、CONCAT、WORD_IMAGE_CLICK + type: string + challengeId: + description: 验证挑战ID,由验证挑战接口返回 + type: string + uuid: + type: string + description: 系统图形验证码 uuid + img: + type: string + description: 系统图形验证码 base64 图片 + payload: + type: object + additionalProperties: true + description: 天爱验证码数据,包括背景图、模板图、尺寸等 + properties: {} + expireSeconds: + description: 验证挑战过期秒数 + type: integer + example: + required: true + providerCode: tianai + captchaType: SLIDER + challengeId: CAPTCHA_CHALLENGE_ID + payload: + backgroundImage: data:image/png;base64,... + templateImage: data:image/png;base64,... + backgroundImageWidth: 340 + backgroundImageHeight: 180 + expireSeconds: 300 + RVerificationCheck: + type: object + properties: + code: + description: 系统图形验证码或响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + example: 操作成功 + data: + description: 响应数据主体 + $ref: '#/components/schemas/VerificationCheckVo' + VerificationCheckVo: + type: object + properties: + passed: + description: 验证是否通过 + type: boolean + validToken: + type: string + description: 验证通过后交给业务接口的票据 + expireSeconds: + description: 验证挑战过期秒数 + type: integer + message: + description: 返回消息 + type: string + example: + passed: true + validToken: captcha-ticket + expireSeconds: 300 + message: 验证通过 + RLegacyCaptcha: + type: object + properties: + code: + description: 系统图形验证码或响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + example: 操作成功 + data: + description: 响应数据主体 + $ref: '#/components/schemas/LegacyCaptchaVo' + LegacyCaptchaVo: + type: object + properties: + captchaEnabled: + type: boolean + uuid: + description: 系统图形验证码UUID + type: string + img: + type: string + description: base64 图形验证码 + example: + captchaEnabled: true + uuid: captcha-uuid + img: data:image/png;base64,... + responses: + VoidResult: + description: 通用成功响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RVoid' + ObjectResult: + description: 通用对象响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RObject' + ListResult: + description: 通用列表响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RList' + PageResult: + description: 通用分页响应 + content: + application/json: + schema: + $ref: '#/components/schemas/PageResult' + LoginResult: + description: 登录结果 + content: + application/json: + schema: + $ref: '#/components/schemas/RLogin' + FileUploadResult: + description: 文件上传结果 + content: + application/json: + schema: + $ref: '#/components/schemas/RFileUpload' + VerificationRequireResult: + description: 验证需求查询结果 + content: + application/json: + schema: + $ref: '#/components/schemas/RVerificationRequire' + VerificationChallengeResult: + description: 验证挑战生成结果 + content: + application/json: + schema: + $ref: '#/components/schemas/RVerificationChallenge' + VerificationCheckResult: + description: 验证校验结果 + content: + application/json: + schema: + $ref: '#/components/schemas/RVerificationCheck' + LegacyCaptchaResult: + description: 兼容旧图形验证码结果 + content: + application/json: + schema: + $ref: '#/components/schemas/RLegacyCaptcha' + securitySchemes: + SaToken: + type: apiKey + in: header + name: Authorization + description: 登录后返回的 token。若本地配置使用 sa-token 名称,请按项目实际 token-name 调整。 +servers: [] +security: + - SaToken: [] diff --git a/App.vue b/App.vue new file mode 100644 index 0000000..91156d5 --- /dev/null +++ b/App.vue @@ -0,0 +1,11 @@ + + + diff --git a/components/AppTabbar.vue b/components/AppTabbar.vue new file mode 100644 index 0000000..2bc77e7 --- /dev/null +++ b/components/AppTabbar.vue @@ -0,0 +1,64 @@ + + + + + diff --git a/components/GenealogyCard.vue b/components/GenealogyCard.vue new file mode 100644 index 0000000..63a1eee --- /dev/null +++ b/components/GenealogyCard.vue @@ -0,0 +1,138 @@ + + + + + diff --git a/components/PageHeader.vue b/components/PageHeader.vue new file mode 100644 index 0000000..f1c3212 --- /dev/null +++ b/components/PageHeader.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/data/mock.js b/data/mock.js new file mode 100644 index 0000000..8249dd2 --- /dev/null +++ b/data/mock.js @@ -0,0 +1,68 @@ +export const currentUser = { + id: 1, + name: '汤文远', + phone: '138****1024', + role: '创建者' +} + +export const genealogies = [ + { + id: 1001, + surname: '汤', + name: '汤氏家谱', + hall: '敦睦堂', + location: '河南·洛阳', + memberCount: 158, + updatedAt: '2024-05-12', + activeCount: 8, + visibility: '仅成员可见', + motto: '敦亲睦族,敬祖传家。' + }, + { + id: 1002, + surname: '汤', + name: '汤氏宗谱', + hall: '承志堂', + location: '山东·济宁', + memberCount: 286, + updatedAt: '2024-04-28', + activeCount: 15, + visibility: '公开可申请', + motto: '继往开来,世守家风。' + } +] + +export const treeMembers = [ + { id: 1, name: '汤文远', relation: '始祖', generation: 1, years: '1940—2012', branch: '主支', x: 50, y: 7 }, + { id: 2, name: '汤正国', relation: '长子', generation: 2, years: '1965—', branch: '主支', x: 20, y: 38 }, + { id: 3, name: '汤正华', relation: '次子', generation: 2, years: '1968—', branch: '主支', x: 50, y: 38 }, + { id: 4, name: '汤正强', relation: '三子', generation: 2, years: '1972—', branch: '支系', x: 80, y: 38 }, + { id: 5, name: '汤凯', relation: '长孙', generation: 3, years: '1992—', branch: '主支', x: 16, y: 70 }, + { id: 6, name: '汤悦', relation: '长女', generation: 3, years: '1995—', branch: '主支', x: 35, y: 70 }, + { id: 7, name: '汤晨', relation: '次子', generation: 3, years: '1998—', branch: '主支', x: 54, y: 70 }, + { id: 8, name: '汤昊', relation: '三子', generation: 3, years: '2001—', branch: '支系', x: 73, y: 70 }, + { id: 9, name: '汤宁', relation: '四女', generation: 3, years: '2005—', branch: '支系', x: 90, y: 70 } +] + +export const familyFeeds = [ + { id: 1, author: '汤正华', title: '清明祭祖通知', content: '本周六上午举行清明祭祖,敬请各支系族亲相互转告。', date: '今天 09:30', type: '族务' }, + { id: 2, author: '汤悦', title: '老宅修缮旧影', content: '整理出一组敦睦堂老宅照片,已收入家族相册。', date: '昨天 20:18', type: '相册' } +] + +export const familyContent = { + article: [{ id: 1, title: '敦睦堂家训摘录', summary: '孝友传家,勤俭立业,敬祖睦族。', date: '2025年4月' }], + album: [{ id: 1, title: '敦睦堂老宅旧影', summary: '收录修缮前后的珍贵照片,共 6 张。', date: '2025年3月' }], + ceremony: [{ id: 1, title: '清明祭祖', summary: '本周六上午举行祭祖仪式,请族人相互转告。', date: '3 天后' }], + record: [{ id: 1, title: '老宅修缮备忘', summary: '屋脊木构加固方案已确认,等待施工。', date: '今天' }] +} + +export const notifications = [ + { id: 1, title: '有新的入谱申请', content: '陈先生申请加入四川武胜汤氏族谱,等待你的审核。', time: '10:24', unread: true }, + { id: 2, title: '祭祀活动提醒', content: '清明祭祖将在 3 天后开始。', time: '昨天', unread: true }, + { id: 3, title: '相册有新照片', content: '汤悦上传了 6 张老宅修缮照片。', time: '4月9日', unread: false } +] + +export const joinApplications = [ + { id: 1, name: '汤志成', phone: '139****6421', relation: '自述为汤正华堂侄', appliedAt: '今天 10:24', status: 'PENDING' }, + { id: 2, name: '汤雨薇', phone: '136****2798', relation: '自述为汤正国之女', appliedAt: '昨天 18:02', status: 'PENDING' } +] diff --git a/docs/PROJECT_PLAN.md b/docs/PROJECT_PLAN.md new file mode 100644 index 0000000..642b71d --- /dev/null +++ b/docs/PROJECT_PLAN.md @@ -0,0 +1,34 @@ +# 家谱 App 项目计划 + +## 已确定的产品规则 + +- 端:uni-app 用户端,面向 Android 与 iOS 的 HBuilderX 打包。 +- 导航:家谱、家族、我的;通知入口只做提醒与跳转。 +- 主流程:管理员创建家谱并录入首代关系,族人申请加入后由管理员审核。 +- 访问规则:家谱默认仅成员可见;管理员可开放为可搜索、可申请加入。 +- 视觉:家祠卷轴——朱砂红、宣纸暖白、黛青、鎏金细线、竖式人物牌位。 +- 素材:自制图标均为透明背景 PNG;必要时采用可商用在线 PNG 图标并统一风格。 +- 接口:`APP.openapi.yaml` 是 App 端接口契约;地址、`clientid`、`tenantId` 与测试账号通过本地配置注入。 + +## 进度 + +- [x] 阅读思维导图、现有界面稿、参考 uni-app 工程与 OpenAPI 文档。 +- [x] 确定三 Tab 信息架构、核心创建流程、加入审核规则和视觉方向。 +- [x] 创建 uni-app 工程骨架、设计令牌与透明 PNG 图标资产。 +- [x] 完成登录、我的家谱、创建家谱、家谱总览、世系树、成员档案和申请审核的首版界面与本地交互闭环。 +- [x] 实现登录、我的家谱、创建家谱与公开家谱申请加入。 +- [x] 修复 Vue 3 工程入口:补齐根目录 `index.html`,并加入配置与入口自检。 +- [x] 完成当前已实现页面的 HBuilderX Web 编译、全量语言诊断与缓存排查;本地 H5 发行构建仍受 HBuilderX 登录状态限制。 +- [x] 参照完整 uni-app 工程修复 Sass 注入:令牌直接置于 `uni.scss`,重启 Vite 后登录页样式请求已验证为 200。 +- [x] 完成显式 Mock/Remote 模式、密码登录链路、token 保存、接口 `data` 解包与当前家谱 ID 上下文。 +- [x] 完成创建家谱后录入首代,并按当前家谱加载详情、世系树、成员档案、申请审核与通知已读。 +- [x] 完成家族动态发布、谱文/相册/祭祀/族务内容入口,以及动态个人资料读取。 +- [ ] 实现家谱总览、世系树、成员资料和亲属关系编辑。 +- [ ] 实现家族圈、谱文、相册、祭祀、贺礼、成长记录、备忘和功德。 +- [ ] 实现通知、个人中心、帮助、反馈、VIP 与接口配置。 +- [ ] 在 HBuilderX 验证运行、Android/iOS 打包配置和关键流程。 + +## 当前接口限制 + +- 已支持:认证、家谱、成员、字辈、世系树、家族圈、文章、相册、祭祀、族务记录、通知、反馈与 VIP。 +- 暂不实现为可用功能:邀请码、视频与多管理员分级权限;接口文档尚未提供对应端点。 diff --git a/docs/REFERENCE_PROJECT_AUDIT.md b/docs/REFERENCE_PROJECT_AUDIT.md new file mode 100644 index 0000000..49c30b1 --- /dev/null +++ b/docs/REFERENCE_PROJECT_AUDIT.md @@ -0,0 +1,28 @@ +# 参考 uni-app 工程结构核对 + +参考工程:`C:\Users\Rain\Desktop\软件\JOB\3dyjsapp` + +## 已确认并采纳 + +- 参考工程是完整的 HBuilderX uni-app 工程,根目录使用 `App.vue`、`main.js`、`pages.json`、`manifest.json`、`index.html` 与 `uni.scss`。 +- 参考工程的 `manifest.json` 已声明 Vue 3;`main.js` 同时保留 Vue 2 与 Vue 3 的条件入口。家谱项目固定使用 Vue 3,因此保留精简的 Vue 3 入口即可。 +- 参考工程的 `uni.scss` 直接定义 Sass 变量,而不是在其中使用相对路径导入。家谱项目已按此方式调整:`uni.scss` 是唯一的设计令牌来源。 +- 参考工程把页面清单集中在 `pages.json`,家谱项目已用自动审计校验每条路由都有对应页面文件。 + +## 本项目的对应实现 + +- `uni.scss`:朱砂红、宣纸暖白、墨色、鎏金等 Sass 令牌。 +- `styles/global.scss`:只由 `App.vue` 从根目录引入的全局通用样式。 +- `tests/compile-audit.ps1`:校验路由、入口、Sass 引用与模块引用。 +- `tests/uni-scss-injection.ps1`:防止在 `uni.scss` 中再次写入会被页面按错误目录解析的相对 Sass 导入。 + +## 不照搬的部分 + +- 彩票业务页面、接口、数据模型与大量业务组件。 +- 参考工程中的第三方 UI 模块、OAuth 配置和过宽设备权限;家谱 App 按实际功能逐项添加,避免无关权限与凭据进入工程。 + +## 后续仍需补齐 + +- 家谱 App 的 Android/iOS 应用图标尺寸与启动图资源。 +- 登录后的真实接口配置与测试账号联调。 +- HBuilderX 登录后的本地 H5 发行构建及 Android/iOS 云打包验证。 diff --git a/docs/design/D1_安卓视觉规范与页面壳.md b/docs/design/D1_安卓视觉规范与页面壳.md new file mode 100644 index 0000000..093944a --- /dev/null +++ b/docs/design/D1_安卓视觉规范与页面壳.md @@ -0,0 +1,265 @@ +# D1:安卓视觉规范与页面壳 + +> 对应《规划》:P-02、P-03、P-04 +> 适用范围:Android 手机端全部页面 +> 设计锚点:用户提供的“汤氏家谱世系图”参考图 + +## 1. 设计锚点与不可偏离项 + +参考图不是只借用“红色”,而是整套视觉语言的依据。后续每一页必须具备以下共性: + +1. **家祠红头图**:核心家谱页面使用朱砂红顶部,左侧为低对比古建筑线描,标题使用金色或暖白色。 +2. **宣纸正文区**:主内容始终落在暖白纸面上,背景只允许极浅的山峦、竹影、亭台或纸纤维纹理,不能影响文字阅读。 +3. **墨字与古金线**:正文使用墨褐色,分隔、牌位、题签和次级结构使用古金细线。 +4. **礼制化状态**:当前选中、重要操作与未读提醒使用朱砂;不可用荧光色、大面积渐变或通用蓝色按钮替代。 +5. **牌位不是卡片**:世系树、人物录核心信息使用竖式牌位;其他列表保留纸签和金线的秩序感,不能变成白底大圆角信息卡。 + +### 1.1 一比一还原的验收定义 + +“一比一”指以参考图为唯一视觉锚点,不能只借用红色后另行发挥。以 `360 × 800dp` 设计画布验收时,必须同时还原:朱砂红头的高度与留白、祠堂线描的位置和低对比度、金色标题比例、宣纸与山水底纹、古金牌位线框、朱砂选中描边、纸面底部抽屉与底部导航的层级效果。 + +不同业务页的内容结构可以不同,但不能把世系图页面原样复制到每个页面;它们必须在同一套材质、颜色、字体、线框和动效逻辑中变化。为适配 `320 × 568` 等小屏,元素可流式换行或缩放,**不得**为追求固定像素而造成重叠或不可点击。 + +每张后续设计稿都要和参考图并排核对上述八项;没有通过核对,不能标为设计完成。 + +## 2. Android 基础尺寸 + +设计坐标以 `750rpx` 宽度为基准。实现时允许流式收缩,但不得缩小关键点击区。 + +| 元素 | 设计值 | 小屏规则 | +| --- | ---: | --- | +| 页面左右安全边距 | `32rpx` | `320px` 小屏可缩至 `24rpx`。 | +| 页面标题 | `34rpx` | 不换成两行;长标题使用省略号。 | +| 主标题 | `48rpx` | 家谱名最大两行,超出截断。 | +| 正文 | `28rpx` | 不低于 `24rpx`。 | +| 辅助文字 | `24rpx` | 仅用于时间、状态、说明。 | +| 主按钮高度 | `88rpx` | 最小点击高度,不因小屏减小。 | +| 图标触控框 | `88rpx × 88rpx` | 图标视觉大小可为 `40–48rpx`。 | +| 列表行高度 | `104rpx` 起 | 多行信息自动增高。 | +| 底部操作栏 | `128rpx` 起 | 加系统导航保底内边距。 | + +## 3. 色彩、字体与图标 + +### 3.1 色彩 + +| Token | 色值 | 使用位置 | +| --- | --- | --- | +| `paper-page` | `#F6F0E5` | 页面整体纸底。 | +| `paper-surface` | `#FFF9EE` | 抽屉、表单、列表承载面。 | +| `cinnabar` | `#A33B2B` | 主操作、选中描边、徽章。 | +| `cinnabar-deep` | `#7E251C` | 顶部红底的层次和按下态。 | +| `ink` | `#342A24` | 标题、主正文。 | +| `ink-muted` | `#7A6958` | 次级正文、时间。 | +| `antique-gold` | `#B58A4B` | 牌位描边、细分割线、装饰。 | +| `gold-soft` | `#E4D4B8` | 弱分割线、未选中轮廓。 | +| `danger` | `#B63A2C` | 删除、审核拒绝;不额外引入鲜红。 | + +绿色不进入页面的背景、导航、主按钮或状态色。若用户照片中含绿色,保持原图,不再叠加绿色 UI 元素。 + +### 3.2 字体 + +- 页面标题、家谱名、人物姓名:系统衬线回退链 `serif`;仅用于短标题和牌位姓名,体现家谱的书卷感。 +- 正文、表单、数字、按钮:Android 系统无衬线字体 `sans-serif`;优先保证低版本设备的字形和行高稳定。 +- 不下载网络字体,不依赖单一厂商字体,不用细于常规字重的中文字体。 +- 姓名为两至四字时居中竖排;超过四字改为横排或两行,禁止压缩字距造成难读。 + +### 3.3 透明 PNG 图标规范 + +- 图标文件一律是 RGBA PNG,四角透明;不把乳白或绿色底色烘焙进图标。 +- 功能图标以官方 `24dp × 24dp` 视口为唯一留白标准,导出为 `96 × 96px`(4 倍)透明 PNG;不得再从大幅生成图中裁出图标、不得人为叠加 `25%` 以上的额外空白。图标的边距只保留官方图形本身的标准边距。 +- 正常态使用墨褐或古金单色;选中态使用朱砂;不使用渐变、投影或多色填充。 +- 图标命名采用 `功能-状态.png`,例如 `tree-active.png`、`notice-default.png`、`profile-active.png`。 +- 首批需要的图标:返回、搜索、更多、通知、家谱、家族、我的、世系图、列表、编辑、新增、相册、礼仪、消息、设置、关闭。 + +### 3.4 资产优先规则 + +- 所有具备明确动作或状态的元素必须使用透明 PNG 图标:导航、返回、搜索、通知、更多、关闭、编辑、新增、上传、相册、成员、世系、礼仪、设置、删除、分享、点赞、评论。 +- 禁止使用 Emoji、Unicode 符号、临时文字(例如“返回”“更多”)替代功能图标;功能图标旁的文字仅用于解释,不承担唯一识别职责。 +- 文字只保留在用户必须阅读或选择的内容上:页面标题、家谱名称、成员资料、表单标签、状态说明与按钮动作。 +- 每一个图标必须有默认态与需要时的选中态;选中态仅改变为朱砂色,不改变图形轮廓,保证低端 Android 设备上也能一眼识别。 +- **后续强制规则**:任何后续页面设计中新增加的图标,必须同步生成对应的 RGBA 透明 PNG,保存到项目 `static/assets/icons/` 后才能将该页面标记为“设计完成”。设计图中的图形、文字占位、Emoji 或系统默认图标均不能替代实际资产。 +- 每个新增图标都要在资产清单登记:用途、文件路径、默认 / 选中状态、设计页编号和透明背景检查结果;页面实现只能引用清单中的已验收资产。 + +### 3.4.1 功能图标的标准骨架与视觉风格 + +- Android / Material 的在线规范用于锁定**图标语义、24dp 视口、触控区、默认 / 选中状态和可识别性**,不是要求本项目的每个图标都长成默认黑色 Material 图标。 +- 项目 Logo、祠堂纹样、宣纸、山水竹影属于品牌与背景插画,可以定制生成;顶部和通用操作图标允许采用本项目的“古金双线 + 克制云纹收口”风格,风格锚点见 [公共操作图标风格锚点](references/公共操作图标-风格锚点.png)。 +- 自定义图标仍须保留标准语义:返回一眼识别为左箭头、搜索为放大镜、通知为铃铛、更多为三点、关闭为 X;不得因装饰而改变动作含义。 +- 底部导航固定为三项且每项同时显示图标与短标签:`家谱`、`家族`、`我的`。现有 Tab 图标不通过验收,必须重设计为等视觉重量的简洁轮廓;不能出现云纹、枝叶和双层复杂装饰。选中项使用同一图形的朱砂色与填充 / 加粗状态,非选中项用墨褐或古金描边。 +- 顶部与通用操作采用标准语义:返回、搜索、通知、更多、关闭、新增、编辑、上传、删除、分享、设置。图标可定制风格,但不以文字、Emoji 或难以识别的自造图形替代。 + +### 3.4.2 按钮图标风格分级 + +- **大部分按钮与顶部操作**:返回、搜索、通知、更多、关闭、新增、编辑、上传、删除、分享、设置,以及家谱 / 家族模块中的快捷入口,采用“古金双线 + 轻云纹收口”风格。 +- **主操作按钮**:图标可置于“新建家谱、保存、发布、提交”等文字前;图标为古金双线简化版,按钮本身仍以朱砂描边或朱砂实底表达主次,不用纯文字按钮。 +- **底部 Tab**:不得直接使用复杂云纹版本;使用更简洁的同色系轮廓,优先保证 24dp 识别度和三个目的地的差异。 +- **状态与危险操作**:成功、失败、删除、无权限等不使用花纹干扰信息;保留标准清晰的符号,颜色按状态区分。 + +> 来源依据:Google Material Symbols 官方库提供适用于 Android 的 PNG / SVG 图标、`FILL` 状态轴和 20–48dp 光学尺寸;Android 官方将导航栏用于 3–5 个同等级目的地。项目以这些规则做底线,并在其上保留家祠卷轴的视觉个性。 + +### 3.5 图标资产清单与路径 + +所有最终资产均保存在 `static/assets/icons/`,由页面直接引用;不使用在线 URL。 + +| 资产组 | 文件 | 状态 | +| --- | --- | --- | +| 项目标识 | `brand/jiapu-seal-logo.png` | 自定义生成,待缩小尺寸验收 | +| 顶部操作 | `common/back.png`、`common/search.png`、`common/notice.png`、`common/more.png`、`common/close.png` | 保留已确认的古金双线风格,待逐个紧凑导出 | +| 底部导航 | `tab/genealogy.png`、`tab/family.png`、`tab/profile.png` 及各自 `-active.png` | 待按标准 24dp 语义重绘为简洁同风格版本 | +| 家谱操作 | `genealogy/tree.png`、`members.png`、`generation-poem.png`、`application.png`、`create.png`、`edit.png` | 页面设计时按 Material Symbols 官方源导出 | +| 家族内容 | `family/feed.png`、`article.png`、`album.png`、`ceremony.png`、`gift.png`、`archive.png` | 页面设计时按 Material Symbols 官方源导出 | +| 通用操作 | `action/add.png`、`upload.png`、`delete.png`、`share.png`、`like.png`、`comment.png`、`setting.png` | 待按古金双线风格逐个紧凑导出 | + +### 3.5 已否决的资产(不得引用) + +`static/assets/icons/common/`、`static/assets/icons/tab/`、`static/assets/icons/action/` 当前是从大幅绿色底图裁切的原始试验文件,仍不得直接引用。其问题是**画布和缩放方式**,不是用户已确认的顶部操作图标美术方向。 + +**根因记录**:这些文件来自带大块绿色空白的 3 × 2 AI 图稿,再按格子裁切;生成图没有稳定的标准视口,导致图标周围出现过多空白、主体大小不一致。顶部操作图标的古金双线与轻云纹风格保留;Tab 图标的复杂枝叶、过多装饰和不统一轮廓不保留。 + +**新生产方式**:每个图标单独制作并紧凑导出到 `96px` PNG,实际图形占官方 24dp 视口的正常范围;不得再批量盲裁。顶部 / 操作图标以风格锚点为准,Tab 按简洁语义重新制作。每个文件在 `46rpx` 实际显示尺寸检查后才可引用。 + +### 3.6 功能图标验收 + +功能图标只有同时满足以下条件,才可标记为“已生成”: + +1. 语义、视口与状态符合 Google Material Symbols / Android 规范;若为本项目定制图标,记录其对应的标准语义与风格锚点。 +2. 默认 / 选中态为同一语义符号,保持 `24dp` 标准画布与固定留白;不得改变动作含义来冒充选中态。 +3. 项目内文件为 RGBA 透明 PNG,四角透明;默认墨褐、选中朱砂;在纸白底和红头上均满足清晰可见。 +4. 在 `46rpx` Tab 显示尺寸及 `320 × 568` 小屏中检查可识别性、标签不换行、点击区不小于 `88rpx`。 + +### 3.7 背景资产规则 + +- 所有装饰性背景都必须生成并保存在项目 `static/assets/backgrounds/`;禁止依赖网络背景图,也不能只用临时 CSS 渐变假装纸纹。 +- 背景分层使用:`header-hall-lineart.png` 用于朱砂顶部;`paper-rice-texture.jpg` 用于宣纸底;`footer-mountain-bamboo.png` 用于页面底部的淡山水竹影。页面按需组合,不把它们烘焙成一张全屏超大图。 +- 祠堂线描、山水、竹影等叠加背景应使用透明 PNG;宣纸纸纹使用压缩后的 JPG。所有背景必须无文字、无 Logo、无人物、无绿色调。 +- 为兼容老款 Android:顶部纹样显示尺寸不超过 `750 × 288rpx`,底部山水显示尺寸不超过 `750 × 360rpx`;背景只在首屏和固定区域加载,不在长列表中重复解码。 +- 背景完成验收需检查:`320 × 568` 下不遮挡标题或操作、纸纹不影响文字对比度、图片已压缩到适合移动端的尺寸。 +- **页面背景完成条件**:每一个页面必须在其设计记录中写清“红头 / 纸纹 / 山水竹影 / 侧边竹影 / 无”的组合与对应资产路径;没有背景组合的页面不得标记为“设计完成”。背景可以复用基础资产,但不能是未设计的纯色空白页面或临时 CSS 渐变。 + +| 页面类型 | 必须使用的背景组合 | +| --- | --- | +| 家谱总览、世系树、成员档案 | 朱砂红头 + 祠堂线描 + 宣纸纸纹;底部或抽屉使用淡山水竹影。 | +| 家族动态、谱文、相册、礼仪、消息 | 紧凑朱砂题签 + 宣纸纸纹;内容尾部按需叠加竹影或山水。 | +| 创建、编辑、申请、设置、反馈 | 紧凑题签 + 宣纸纸纹;表单区域保持干净,不让山水压住输入内容。 | +| 登录、注册、找回密码 | 独立生成的红头 / 纸纹欢迎背景;不能直接复用列表页大山水。 | +| 无数据、失败、审核中 | 宣纸纸纹 + 对应低对比卷轴 / 印章背景资产;不能只显示文字。 | + +| 背景资产 | 路径 | 用途 | 状态 | +| --- | --- | --- | --- | +| 祠堂线描 | `backgrounds/header-hall-lineart.png` | 家谱红头左侧或底部纹样 | 生成中 | +| 宣纸纸纹 | `backgrounds/paper-rice-texture.jpg` | 全局纸面底色 | 未生成 | +| 山水竹影 | `backgrounds/footer-mountain-bamboo.png` | 列表页、抽屉页底部装饰 | 未生成 | + +## 4. 公共页面壳 + +### 4.1 核心家谱页面壳 + +适用于:家谱总览、世系图、成员目录、人物档案。 + +- 顶部 `256–288rpx`:朱砂红,左下放置低对比祠堂屋檐线描,禁止使用满屏建筑照片。 +- 根页面左上角放项目 Logo(祠堂屋檐 + “谱”字印章,透明 PNG,视觉 `40rpx`、触控区 `88rpx`);详情页该位置优先保留返回按钮,Logo 收入建筑纹样中的小印记。 +- 搜索、通知、更多均为 `88rpx` 触控框;图标为暖白或金色线稿 PNG。通知铃铛仅在未读消息数大于 0 时显示朱砂小圆点;未读为 0 时不显示圆点和数字。 +- 家谱名称位于视觉中心,最大两行;名称下可放地域或代系提示,但不能与图标重叠。 +- 红头结束后立即进入纸面 Tab/分段导航,使用古金底线标记当前项。 + +### 4.2 普通列表与详情页面壳 + +适用于:家族动态、谱文、相册、人物录、礼仪、消息、我的。 + +- 顶部使用 `144–176rpx` 紧凑朱砂题签,保留建筑线描的局部纹样。 +- 内容区采用纸白承载面与古金细分割线,列表项不使用夸张圆角;圆角最大 `16rpx`。 +- 每页只保留一个视觉主操作:新增、发布、保存或提交。它固定在底部操作栏或右下角,不能同时出现两个醒目的红按钮。 + +### 4.3 表单与编辑页面壳 + +适用于:创建家谱、录入始祖、申请加入、发布内容、编辑成员、反馈、设置。 + +- 顶部为紧凑题签,正文使用逐行纸签式表单,标签在左、输入值在右或下一行。 +- 必填项用朱砂小印记表示;校验说明用暖灰褐,不使用大面积红色报错框。 +- 键盘出现时页面可滚动,底部“保存 / 提交”保持可操作。 + +### 4.4 底部导航与抽屉 + +- 三 Tab:家谱、家族、我的。纸白底、顶部古金细线;当前图标和文字用朱砂,未选中用墨褐。 +- 无底部 Tab 的详情页,底部保留返回区域或单主操作栏,不能出现空白黑条。 +- 成员、相册、礼仪的详情采用半屏至全屏底部抽屉:纸白底、顶部金色短握条、右上关闭按钮、淡竹影或山影作为低对比装饰。 + +## 5. 核心组件规则 + +### 5.1 世系人物牌位 + +- 牌位为暖白底、古金双线边框、上下折角;不使用普通矩形卡片。 +- 始祖牌位比同层成员高一级;当前选中人物外框换成朱砂双线,并使用小圆点连接标识。 +- 牌内信息顺序:姓名 → 字 / 号 → 生卒或年份;信息不足时显示“生卒不详”,不留大段空白。 +- 代际标签固定在树左侧,不随横向滚动丢失;横向树区域与底部档案抽屉互不遮挡。 + +### 5.2 纸签列表 + +- 左侧为功能图标或缩略图,中间为标题和两行信息,右侧是状态或箭头。 +- 每行以古金细线分隔;红色仅用于“待审核”“未读”“进行中”等需要注意的状态。 +- 长标题最多两行;日期、人数、地域等元信息单独一行,不与操作按钮抢空间。 + +### 5.3 主操作与次操作 + +- 主操作:朱砂描边或朱砂实底,圆角 `44rpx` 的胶囊形;文字白色或纸白。 +- 次操作:纸白底、古金描边、墨褐文字。 +- 删除和退出:先显示纸面确认抽屉,再允许使用 `danger` 色;不可直接用红色文字替代确认流程。 + +### 5.4 空状态与异常 + +- 空状态使用纸纹中的淡印章、卷轴、山影或未展开牌位,不使用卡通人物。 +- 网络失败使用“纸页未送达”图标、明确重试按钮;不把错误码直接展示给用户。 +- 审核中使用朱砂印章和预计提示;无权限使用合拢卷轴与申请/返回入口。 + +## 6. 首屏结构:家谱首页(G-01) + +G-01 是所有设计页的公共还原样板,不等同于最终代码。 + +1. 顶部:朱砂祠堂红头,左侧项目 Logo,中央为“我的家谱”,右侧通知 PNG 图标;只有未读消息时才带朱砂小圆点。 +2. 主区:当前家谱以横向家谱题签展示名称、地域、成员数和身份;这个题签的朱砂印章代表“当前选中的家谱”,不是另一种家谱颜色。没有家谱时替换为卷轴空状态。 +3. 快捷区:世系图、成员、字辈诗、申请审核四项,使用透明 PNG 图标与古金分隔。 +4. 家谱列表:明确分为“我创建的”和“我加入的”两个标题区;每项使用同一套纸签和古金线,不用红色 / 金色印章暗示未说明的身份差异。当前选中项可用朱砂细边标记。 +5. 底部:三 Tab;主操作“创建家谱”在内容末尾或空状态中出现,避免遮挡 Tab。 + +### 6.1 G-01 数据文案规则 + +- 家谱名称后不得出现无意义横线、破折号、模拟字符或“待补充”占位。 +- 有数据时按真实字段显示,例如“河南省 · 洛阳市”“158 位成员”“管理员”;无数据时整行隐藏,或显示明确的“地区待完善 / 成员待录入”。 +- “当前家谱”与下方列表不得无说明地重复同一名称;当前题签显示选中的家谱,下方列表用于切换,选中项需要清晰标记。 + +### 6.2 G-01 固定设计栅格(360 × 800dp) + +这是后续页面还原的硬尺寸基准,不再交给整页 AI 图自行猜测: + +| 区域 | 尺寸 / 间距 | 约束 | +| --- | --- | --- | +| 系统状态栏 | `24dp` | 只预留系统空间,不放页面内容。 | +| 家祠红头 | `112dp`(含标题区) | Logo 左 `16dp`,标题居中,铃铛右 `16dp`;红头结束后不得出现大块空白。 | +| 当前家谱题签 | 顶距 `16dp`,高 `136dp`,左右 `16dp` | 只展示当前家谱一次;名称、成员数、地域、身份均为真实字段。 | +| 快捷入口 | 题签后 `16dp`,行高 `84dp` | 四项等宽;图标实际 `24dp`,标签 `14sp`,不使用大号装饰图。 | +| 分隔与列表标题 | 上距 `16dp`,标题区 `36dp` | 细古金线 + “我创建的 / 我加入的”,不能留无内容的整屏空白。 | +| 家谱列表项 | 每项 `72dp`,项间 `8dp` | 一项只显示名称、必要元信息、右箭头;不重复当前题签内容。 | +| 新建家谱 | 列表后 `16dp`,高 `48dp` | 朱砂描边胶囊按钮,不用巨大的上下留白烘托。 | +| 底部导航 | `64dp` + 系统导航保底 | 纸白底、三项等宽,图标 `24dp`、标签 `12sp`、每项触控区至少 `48dp`。 | + +上述内容总高度在 `360 × 800dp` 首屏内保持紧凑;数据较多时由内容区滚动,而不是拉大首屏留白。`320 × 568` 下题签和快捷入口仍在首屏可见,列表向下滚动。 + +### 6.3 已否决的 G-01 生成整页图 + +此前 AI 生成的“我的家谱”整页图**保留为美术锚点**:[G01 我的家谱美术锚点](references/G01-我的家谱-美术锚点.png)。它明确了本项目应该保留的整体效果:朱砂祠堂红头、暖金标题、宣纸纸纹、金线题签、淡山水竹影、纸白底部导航和庄重的色彩层级。 + +该图**不直接作为尺寸与功能验收稿**,因此不计入 G-01 的“页面设计完成”。需要按 6.2 的固定栅格修正:红头后与题签之间的过大留白、快捷入口与列表之间的过大留白、缺失的左上 Logo、当前家谱与列表的重复、无意义横线占位、以及非标准来源图标。 + +从此以后,页面设计采用“双锚点”:本图锁定美术氛围和视觉效果;6.2 固定栅格锁定尺寸、内容密度与 Android 小屏可用性。AI 只可生成 Logo、背景等独立视觉资产,不能决定页面间距、文字排版、列表高度或交互层级。 + +### 6.4 标准来源验收备注 + +- Material Symbols 官方指南: +- Android Navigation Bar 官方指南: + +## 7. 设计状态记录 + +- P-02:完成。颜色、字体、尺寸、透明 PNG 图标规范已锁定。 +- P-03:完成。核心、普通、表单三类页面壳及底部导航、抽屉已锁定。 +- P-04:完成。加载、空数据、失败、无权限、审核中与确认操作规则已锁定。 +- 下一阶段:D2 账户与首次使用页面;全部页面均按本规范出高保真稿后,才进入 uni-app 还原。 diff --git a/docs/design/G01_我的家谱_设计记录.md b/docs/design/G01_我的家谱_设计记录.md new file mode 100644 index 0000000..d25b760 --- /dev/null +++ b/docs/design/G01_我的家谱_设计记录.md @@ -0,0 +1,106 @@ +# G-01:我的家谱设计记录 + +> 状态:资产准备中 +> 美术锚点:[G01 我的家谱美术锚点](references/G01-我的家谱-美术锚点.png) +> 布局锚点:[D1 安卓视觉规范与页面壳](D1_安卓视觉规范与页面壳.md#62-g-01-固定设计栅格360--800dp) + +## 页面目标 + +让已登录用户一眼查看当前家谱、进入四个高频入口、切换已创建 / 已加入家谱,并在无家谱时创建或搜索加入。 + +## 背景组合 + +- 红头:`static/assets/backgrounds/header-hall-lineart.png` 叠加朱砂底色。 +- 内容纸面:`static/assets/backgrounds/paper-rice-texture.jpg`。 +- 页面底部:`static/assets/backgrounds/footer-mountain-bamboo.png`,只用于列表尾部与新建按钮附近。 + +## 图标资产清单 + +所有项目完成后均为独立、紧凑的 RGBA 透明 PNG;不能从大图裁切后直接使用。 + +| 区域 | 语义 | 目标文件 | 风格 | 状态 | +| --- | --- | --- | --- | --- | +| 顶部左侧 | 项目 Logo | `brand/jiapu-seal-logo.png` | 用户确认的家祠 Logo 原图 | 已确认使用;待页面小尺寸摆放验收 | +| 顶部右侧 | 通知 | `common/notice-v3.png` | 古金双线 + 轻云纹 | 已生成;`70 × 94px` 主体通过紧凑尺寸检查 | +| 列表入口 | 右箭头 | `common/chevron-right-v2.png` | 古金简洁单线 | 已生成;`96 × 96px`、RGBA 四角透明、48px 检查通过 | +| 快捷入口 | 世系图 | `genealogy/tree-v2.png` | 古金双线简化版 | 已生成;`96 × 96px`、RGBA 四角透明、48px 检查通过 | +| 快捷入口 | 家族成员 | `genealogy/members-v2.png` | 古金双线简化版 | 已生成;`96 × 96px`、RGBA 四角透明、48px 检查通过 | +| 快捷入口 | 字辈诗 | `genealogy/generation-poem-v2.png` | 古金双线简化版 | 已生成;`96 × 96px`、RGBA 四角透明、48px 检查通过 | +| 快捷入口 | 申请审核 | `genealogy/application-v2.png` | 古金双线简化版 | 已生成;`96 × 96px`、RGBA 四角透明、48px 检查通过 | +| 主操作 | 新建家谱 | `action/add-v2.png` | 古金双线 + 轻云纹 | 已生成;`96 × 96px`、RGBA 四角透明、48px 检查通过 | +| 底部 Tab | 家谱 | `tab/genealogy-v4.png`、`genealogy-active-v4.png` | 简洁谱册 / 世系语义 | 已生成;同轮廓墨褐 / 朱砂成对导出,`96 × 96px`、48px 检查通过 | +| 底部 Tab | 家族 | `tab/family-v4.png`、`family-active-v4.png` | 简洁双人群组语义 | 已生成;同轮廓墨褐 / 朱砂成对导出,`96 × 96px`、48px 检查通过 | +| 底部 Tab | 我的 | `tab/profile-v4.png`、`profile-active-v4.png` | 简洁人物档案语义 | 已生成;同轮廓墨褐 / 朱砂成对导出,`96 × 96px`、48px 检查通过 | + +## 页面完成条件 + +- [ ] 图标资产清单全部生成并在 `46rpx` / `24dp` 下逐个检查。 +- [ ] 背景组合在 `320 × 568` 下不遮挡标题、按钮和列表。 +- [ ] 按固定栅格完成正常态、无家谱态与加载态设计。 +- [ ] 不存在横线占位、重复家谱层级或无业务含义的颜色差异。 + +## Tabbar 重设计规则 + +- 当前 `static/assets/icons/tab/` 和 `static/icons/tab-*.png` 的图标不通过验收,不得使用。 +- 三个 Tab 重新采用等视觉重量的简洁符号:家谱为“世系关系 / 谱册”语义,家族为“双人群组”语义,我的为“人物档案”语义。 +- 三个图标同为 `24dp` 标准视口、无文字嵌入、无枝叶和云纹等细碎装饰;默认态为墨褐 / 古金描边,选中态为朱砂色的同一图形加粗或填充。 +- Logo 是品牌标识,不能拿来代替家谱 Tab 图标;Tab 图标只服务于快速识别目的地。 + +## 2026-07-11 当日确认记录 + +- 当前交接视觉稿:[G01-我的家谱-紧凑版设计稿-v5-Tabbar安全区.png](screens/G01-我的家谱-紧凑版设计稿-v5-Tabbar安全区.png)。它是明日施工时的美术与布局锚点,不替代真实页面和资产验收。 +- 顶部品牌使用项目原有 `static/assets/icons/brand/jiapu-seal-logo.png`;缩小后固定在左上安全区,避免与居中标题及殿宇线稿争夺视觉焦点。 +- 底部 Tabbar 仍然贴合屏幕底部;三个图标和文字整体上移至 Android 手势/三键导航安全区内,标签“家谱 / 家族 / 我的”加大,任何屏幕尺寸下不得被底边裁切。 +- 上述确认只锁定 G-01 的方向和版式。真实透明 PNG 图标、背景组合、320 × 568 小屏校验、空状态与加载状态尚未完成,因此 **G-01 仍不勾选为设计完成**。 +- 明日从 G-01 的可施工项开始:先按 D1 规范落实真实图标与背景资产、再还原页面布局;全量页面设计完成前,不恢复接口联调或 Android 打包工作。 + +## 2026-07-12 施工记录 + +- 已完成 G-01 独立图标资产:四个快捷入口、主操作、列表右箭头,以及三组 Tab 默认 / 选中态;全部为 `96 × 96px` RGBA PNG,四角透明,并按实际 `48px` 显示尺寸检查。 +- 已完成 G-01 首轮页面还原:朱砂祠堂红头、左上原 Logo、条件式消息圆点、宣纸与山水背景、当前家谱题签、快捷入口、已创建 / 已加入列表、空状态、加载状态和 Android 安全区 Tabbar。 +- 本页暂时使用 `data/mock.js` 的展示数据;已移除 G-01 的远程接口调用,接口联调仍按总规划暂停。 +- 已通过:`g01-visual-contract.ps1`、`compile-audit.ps1`、`uni-scss-injection.ps1`、`vue3-entry.ps1`。 +- 待完成:在已打开的 HBuilderX 中按 `360 × 800`、`320 × 568` 预览并记录无重叠、无底部裁切的证据。完成前不勾选本页“设计完成”条件。 + +## 2026-07-12 视觉校正记录 + +- 用户预览反馈首轮还原与确认稿差异过大。已定位为:祠堂线稿直接铺在红头导致视觉过满,且题签 / 列表使用普通圆角边框而不是确认稿的纸签资产。 +- 红头已改为纯朱砂底 + 独立 `header-hall-lineart.png` 低对比背景层(不透明度 `0.22`);Logo 放大并上移,标题与通知保持独立层级。 +- 已新增并接入 `backgrounds/genealogy-current-slip-frame.png` 与 `backgrounds/genealogy-list-slip-frame.png`;两者为透明 PNG 双金线纸签框,透明角检查通过。 +- 此次只修正可见还原偏差,不改变 G-01 的数据、路由和状态范围;仍待用户重新运行后的两组小屏预览确认。 + +## 2026-07-12 尺寸校正记录 + +- 原始品牌 Logo 的透明留白导致顶部显示偏小,已从同一原图无损裁切为 `brand/jiapu-seal-logo-header.png` 后接入;不改变 Logo 的图形、配色或品牌含义。 +- 快捷入口图标由 `52rpx` 调整为 `68rpx`;Tab 图标由 `48rpx` 调整为 `56rpx`,标签由 `24rpx` 调整为 `28rpx`,使实际显示尺寸靠近确认稿。 +- 校正后已重新通过 G-01 资产/页面契约、编译审计和 SCSS 注入审计;仍需 HBuilderX 截图作最终视觉依据。 + +## 2026-07-12 第三轮背景与栅格校正 + +- 红头高度由 `216rpx` 收至 `184rpx`,改用 `backgrounds/header-cinnabar-texture-v2.jpg`;祠堂线稿仅作为 `0.16` 不透明度的独立底纹层。 +- 内容左右边距由 `32rpx` 调整为 `48rpx`,当前家谱题签高度收至 `250rpx`,并在快捷入口和列表之间恢复 `backgrounds/genealogy-section-divider-v2.png` 金线云纹分隔。 +- 页面底色改用浅宣纸 `backgrounds/paper-rice-texture-v2.jpg`;山水竹影改用透明 `backgrounds/footer-mountain-bamboo-v2.png` 作为整页底部淡层,不再出现矩形背景块;已检查不含绿色像素。 +- 标题、分区标题与家谱名称增加宋/楷书本机回退链;题签框统一压为古金 `#B58A4B`。 +- 已通过:G-01 页面/资产契约、编译审计、SCSS 注入审计及页脚透明区域检查。仍待新截图比对,页面不标记为完成。 + +## 2026-07-12 第四轮底图与题签边角校正 + +- 根因核验:`genealogy-current-slip-frame.png` 与 `genealogy-list-slip-frame.png` 的四个角均为 Alpha 0;白色直角边并非 PNG 资产本身,而是题签容器在透明镂空角下铺了接近白色的矩形底色。 +- 已移除当前家谱题签和两条列表题签的矩形底色,让透明镂空角直接透出宣纸底纹;文字、边框和点击区域不变。 +- 已撤回错误的 `footer-mountain-bamboo-v2.png`(该图是连续实心灰山,无法还原设计稿的淡墨层次),恢复使用带亭、远山和竹影的 `footer-mountain-bamboo.png`,以 `0.48` 透明度贴在 Tabbar 上沿,不形成独立灰色矩形带。 +- `tests/g01-visual-contract.ps1` 先新增回归断言并确认旧实现失败,再完成最小改动后通过;仍需在 HBuilderX 的同一设备尺寸下由新截图确认最终观感,G-01 不标记为完成。 + +## 2026-07-12 第五轮信息层级与谱印施工 + +- 施工依据固定为 `screens/G01-我的家谱-紧凑版设计稿-v5-Tabbar安全区.png`,对应用户箭头指出的谱印、元信息、快捷入口、两条列表和新建按钮;未改接口、路由、页头、背景或 Tabbar。 +- 新增并接入透明 PNG:`common/location-v1.png`、`common/member-meta-v1.png`、`common/admin-v1.png`、`genealogy/seal-current-frame-v1.png`、`genealogy/seal-row-frame-v1.png`、`action/create-cloud-v1.png`。谱印框只承载朱砂和金白边框,谱印固定显示“家谱”,家谱名称和数值仍为动态文本。 +- 当前家谱改为地点、成员数、管理员三组图标化元信息;快捷入口显示框提升至 `82rpx`;新建按钮加入两侧云纹 PNG。 +- 家谱列表改为谱印框、标题、地点/成员元信息和“更新于”日期的两层结构;`320px` 小屏隐藏更新时间,优先保证标题、元信息、角色和箭头不重叠。 +- 已新增资产透明角/有效图形审计。验证通过:`g01-visual-contract.ps1`、`g01-asset-alpha-audit.ps1`、`compile-audit.ps1`、`uni-scss-injection.ps1`。待 HBuilderX 新截图与参考稿并排确认后,G-01 才能标记设计完成。 + +## 2026-07-12 第六轮参考稿字段与右侧基线校正 + +- 预览字段已切换为参考稿:当前家谱“汤氏家谱 / 河南·洛阳 / 158 位成员 / 管理员”,已加入家谱“汤氏宗谱 / 山东·济宁 / 286 位成员 / 成员”;不再使用四川、达州、刘氏等旧演示字段。 +- 当前题签恢复标题与元信息之间的细金线;短字段确保 430px 验收宽度内三组元信息同一行显示。 +- 列表谱印固定为竖排“家谱”;右侧角色与箭头改为同一水平基线;“更新于”保留为文本,移除参考稿中不存在的日历图标和对应闲置资产。 +- 新增字段/基线契约先失败后通过。完整验证再次通过:G-01 视觉契约、PNG 透明角审计、编译审计、SCSS 注入审计、Vue 3 入口审计。仍待用户提供 HBuilderX 新截图完成视觉验收。 diff --git a/docs/design/references/G01-我的家谱-美术锚点.png b/docs/design/references/G01-我的家谱-美术锚点.png new file mode 100644 index 0000000..eeb72df Binary files /dev/null and b/docs/design/references/G01-我的家谱-美术锚点.png differ diff --git a/docs/design/references/公共操作图标-风格锚点.png b/docs/design/references/公共操作图标-风格锚点.png new file mode 100644 index 0000000..9983776 Binary files /dev/null and b/docs/design/references/公共操作图标-风格锚点.png differ diff --git a/docs/design/screens/G01-我的家谱-紧凑版设计稿-v1.png b/docs/design/screens/G01-我的家谱-紧凑版设计稿-v1.png new file mode 100644 index 0000000..bc7f846 Binary files /dev/null and b/docs/design/screens/G01-我的家谱-紧凑版设计稿-v1.png differ diff --git a/docs/design/screens/G01-我的家谱-紧凑版设计稿-v2-logo.png b/docs/design/screens/G01-我的家谱-紧凑版设计稿-v2-logo.png new file mode 100644 index 0000000..ad01dff Binary files /dev/null and b/docs/design/screens/G01-我的家谱-紧凑版设计稿-v2-logo.png differ diff --git a/docs/design/screens/G01-我的家谱-紧凑版设计稿-v3-小Logo.png b/docs/design/screens/G01-我的家谱-紧凑版设计稿-v3-小Logo.png new file mode 100644 index 0000000..661b808 Binary files /dev/null and b/docs/design/screens/G01-我的家谱-紧凑版设计稿-v3-小Logo.png differ diff --git a/docs/design/screens/G01-我的家谱-紧凑版设计稿-v4-左上Logo.png b/docs/design/screens/G01-我的家谱-紧凑版设计稿-v4-左上Logo.png new file mode 100644 index 0000000..0a8fe42 Binary files /dev/null and b/docs/design/screens/G01-我的家谱-紧凑版设计稿-v4-左上Logo.png differ diff --git a/docs/design/screens/G01-我的家谱-紧凑版设计稿-v5-Tabbar安全区.png b/docs/design/screens/G01-我的家谱-紧凑版设计稿-v5-Tabbar安全区.png new file mode 100644 index 0000000..e25f14c Binary files /dev/null and b/docs/design/screens/G01-我的家谱-紧凑版设计稿-v5-Tabbar安全区.png differ diff --git a/docs/superpowers/plans/2026-07-11-real-api-core-flow.md b/docs/superpowers/plans/2026-07-11-real-api-core-flow.md new file mode 100644 index 0000000..741d462 --- /dev/null +++ b/docs/superpowers/plans/2026-07-11-real-api-core-flow.md @@ -0,0 +1,62 @@ +# 真实接口核心流程 Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 让家谱 App 的认证、当前家谱上下文、创建首代和世系浏览形成可验证的 Mock/远端双模式核心闭环。 + +**Architecture:** `utils/config.js` 显式决定数据模式;`utils/api.js` 是唯一远端响应解包和错误转换位置;`utils/session.js` 与新增的上下文模块持久化 token 和当前家谱 ID。页面只调用 `appApi` 并从路由读取对象 ID。 + +**Tech Stack:** uni-app Vue 3、HBuilderX、uni.request、PowerShell 合同测试。 + +## Global Constraints + +- 不将测试账号、密码或 token 写入源码、测试或文档。 +- 远端模式失败必须显示错误,不能自动返回 Mock 数据。 +- 所有新增页面必须登记在 `pages.json` 并纳入编译审计。 + +--- + +### Task 1: API 会话与响应契约 + +**Files:** +- Modify: `utils/config.js`, `utils/session.js`, `utils/api.js` +- Create: `utils/genealogy-context.js`, `tests/core-flow-contract.ps1` + +- [x] 写失败测试,要求存在显式模式、登录方法、`data` 解包、token 与当前家谱 ID 持久化。 +- [x] 运行 PowerShell 合同测试并确认因方法缺失失败。 +- [x] 实现最小 API 适配层和上下文模块。 +- [x] 重跑合同测试,确认通过。 + +### Task 2: 认证与我的家谱 + +**Files:** +- Modify: `pages/auth/login.vue`, `pages/genealogy/index.vue`, `components/GenealogyCard.vue` +- Test: `tests/core-flow-contract.ps1` + +- [x] 写失败测试,要求登录页调用 API、保存 token,家谱卡片和列表使用真实 ID。 +- [x] 运行测试确认失败。 +- [x] 实现密码登录、错误状态与列表加载状态。 +- [ ] 重跑测试并在 Mock 模式下手动走通登录至列表。 + +### Task 3: 当前家谱与首代录入 + +**Files:** +- Modify: `pages.json`, `pages/genealogy/create.vue`, `pages/genealogy/detail.vue`, `pages/tree/index.vue`, `pages/member/detail.vue` +- Create: `pages/lineage/first-person.vue` +- Test: `tests/core-flow-contract.ps1` + +- [x] 写失败测试,要求新页面、路由参数和 API 方法存在,且不得写死 `1001`/`3`。 +- [x] 运行测试确认失败。 +- [x] 实现创建家谱后录入首代、按路由 ID 加载详情/树/成员。 +- [x] 重跑合同测试与 HBuilderX Sass/语言诊断。 + +### Task 4: 加入审核与通知的上下文修复 + +**Files:** +- Modify: `pages/genealogy/search.vue`, `pages/genealogy/applications.vue`, `pages/notification/index.vue`, `utils/api.js` +- Test: `tests/core-flow-contract.ps1` + +- [x] 写失败测试,要求申请和审核使用当前家谱 ID,通知读取操作有对应 API 方法。 +- [x] 运行测试确认失败。 +- [x] 实现上下文传递与明确的本地状态更新。 +- [x] 重跑所有项目测试及 HBuilderX 实际样式/模块请求验证。 diff --git a/docs/superpowers/plans/2026-07-12-g01-information-hierarchy.md b/docs/superpowers/plans/2026-07-12-g01-information-hierarchy.md new file mode 100644 index 0000000..8c33dba --- /dev/null +++ b/docs/superpowers/plans/2026-07-12-g01-information-hierarchy.md @@ -0,0 +1,230 @@ +# G01 信息层级与谱印校正 Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 让“我的家谱”内容区按已确认的 v5 参考稿呈现谱印、元信息、快捷入口、列表和新建按钮的视觉层级。 + +**Architecture:** 视觉资产只放在 `static/assets/icons/`,页面和卡片组件只引用资产与渲染动态数据。`pages/genealogy/index.vue` 负责当前家谱、快捷入口和新建按钮;`components/GenealogyCard.vue` 负责每条列表的谱印、两层元信息和右侧操作列。 + +**Tech Stack:** uni-app Vue 3、SCSS、项目本地 RGBA PNG、PowerShell 契约审计。 + +## Global Constraints + +- 视觉基准:`docs/design/screens/G01-我的家谱-紧凑版设计稿-v5-Tabbar安全区.png`。 +- Android only;继续使用 rpx、flex、小屏 `max-width: 340px` 规则,不使用 `clip-path` 或 CSS 绘图。 +- 所有新增可见图标、谱印框、云纹均为项目内透明 PNG;动态姓名/数字使用 Vue 文本,不嵌死在图片中。 +- 不改接口、路由、页头、背景、Tabbar 或其他页面;仅为现有展示用 `data/mock.js` 家谱条目补充 `updatedAt` 日期字段。 +- 工作目录不是 Git 仓库,本轮不初始化仓库、不创建提交。 + +--- + +### Task 1: 谱印与元信息 PNG 资产 + +**Files:** +- Create: `static/assets/icons/common/location-v1.png` +- Create: `static/assets/icons/common/member-meta-v1.png` +- Create: `static/assets/icons/common/admin-v1.png` +- Create: `static/assets/icons/genealogy/seal-current-frame-v1.png` +- Create: `static/assets/icons/genealogy/seal-row-frame-v1.png` +- Create: `static/assets/icons/action/create-cloud-v1.png` +- Modify: `tests/g01-visual-contract.ps1` + +**Interfaces:** +- Produces 96×96 RGBA metadata icons, separate transparent current/list seal-frame PNGs, and a transparent cloud ornament consumed by Tasks 2–3. +- Each asset corner alpha must be 0; the current seal frame must have taller visible bounds than the row seal frame. + +- [x] **Step 1: Write the failing asset contract** + +Add the six paths to `$requiredAssets`, then add these assertions to `tests/g01-visual-contract.ps1`: + +```powershell +foreach ($asset in @('location-v1.png', 'member-meta-v1.png', 'admin-v1.png', 'seal-current-frame-v1.png', 'seal-row-frame-v1.png', 'create-cloud-v1.png')) { + if ($page -notmatch [regex]::Escape($asset) -and $card -notmatch [regex]::Escape($asset)) { + throw "G-01 does not consume $asset" + } +} +``` + +- [x] **Step 2: Run the contract and verify it fails** + +Run: `powershell -ExecutionPolicy Bypass -File tests\g01-visual-contract.ps1` +Expected: `FAIL` because the asset files and component references do not exist. + +- [x] **Step 3: Generate and inspect the assets** + +Generate one asset at a time on a flat chroma-key background, remove the chroma key to alpha, and inspect the selected PNG before adding it. Use this visual language: antique-gold single/double outline, Chinese genealogy motif, no text, no shadow, transparent canvas. For the seal frames, generate only the red-and-gold frame; do not include surname or “家谱” text. + +- [x] **Step 4: Verify transparent corners** + +Run a PowerShell `System.Drawing.Bitmap` alpha audit that checks the four canvas corners of every new PNG are 0. + +Expected: all six assets report `PASS ... transparent corners`. + +### Task 2: 当前家谱题签、快捷入口与新建按钮 + +**Files:** +- Modify: `pages/genealogy/index.vue` +- Modify: `tests/g01-visual-contract.ps1` + +**Interfaces:** +- Consumes the Task 1 metadata icons, `seal-current-frame-v1.png`, and `create-cloud-v1.png`. +- Keeps `currentGenealogy` as the data owner; does not add API calls. + +- [x] **Step 1: Write the failing page-layout contract** + +Require the current title block to render three `.current-meta-item` entries and the current seal to include a `.current-seal-frame` image. Require the shortcut display size and create cloud image: + +```powershell +foreach ($token in @('current-meta-item', 'current-seal-frame', 'location-v1.png', 'member-meta-v1.png', 'admin-v1.png', 'create-cloud-v1.png')) { + if ($page -notmatch $token) { throw "G-01 current panel is missing $token" } +} +if ($page -notmatch 'width:\s*82rpx') { throw 'G-01 shortcut icons remain below the reference visual size.' } +``` + +- [x] **Step 2: Run the contract and verify it fails** + +Run: `powershell -ExecutionPolicy Bypass -File tests\g01-visual-contract.ps1` +Expected: `FAIL` because current content is still a pure text metadata row and has no seal/cloud image references. + +- [x] **Step 3: Implement the minimum current-panel markup** + +Replace the pure red `current-seal` block with an image layer and dynamic text overlay: + +```vue + + + 家谱 + +``` + +Render three icon/text metadata groups using the created `location-v1.png`, `member-meta-v1.png`, and `admin-v1.png`; retain `currentGenealogy.location` and `currentGenealogy.memberCount` as the text values. + +- [x] **Step 4: Implement the spacing-only CSS changes** + +Set shortcut image box to `82rpx`; increase label size and give the shortcut grid the reference-like vertical space. Use flex wrapping for current metadata and keep the existing `@media screen and (max-width: 340px)` behavior so no item overlaps. + +- [x] **Step 5: Implement the create-button ornament** + +Place two instances of `create-cloud-v1.png` inside `.create-action`; mirror only the right PNG with `transform: scaleX(-1)`. Keep the existing add PNG and navigation handler. + +- [x] **Step 6: Run the contract and verify it passes** + +Run: `powershell -ExecutionPolicy Bypass -File tests\g01-visual-contract.ps1` +Expected: `PASS G-01 visual contract`. + +### Task 3: 家谱列表谱印与信息层级 + +**Files:** +- Modify: `components/GenealogyCard.vue` +- Modify: `data/mock.js` +- Modify: `tests/g01-visual-contract.ps1` + +**Interfaces:** +- Consumes `genealogy` (`surname`, `name`, `location`, `memberCount`, `updatedAt`), `role`, and the Task 1 row seal asset. +- Emits the unchanged `select` event. + +- [x] **Step 1: Write the failing card-layout contract** + +Require `seal-row-frame-v1.png` and an explicit `.card-detail-row`: + +```powershell +foreach ($token in @('seal-row-frame-v1.png', 'card-detail-row', 'card-updated')) { + if ($card -notmatch $token) { throw "G-01 list card is missing $token" } +} +if ($card -match 'background:\s*#b93b2e') { throw 'G-01 list seal is still a plain CSS red block.' } +``` + +- [x] **Step 2: Run the contract and verify it fails** + +Run: `powershell -ExecutionPolicy Bypass -File tests\g01-visual-contract.ps1` +Expected: `FAIL` because the current list card has no frame asset or two-level detail markup. + +- [x] **Step 3: Implement the minimal list-card markup** + +Use a `.surname-seal` image frame with text overlay, then split metadata into title/detail/update rows: + +```vue + + {{ genealogy.location }} · {{ genealogy.memberCount }} 位成员 + 更新于 {{ genealogy.updatedAt }} + +``` + +On narrow screens, hide `.card-updated`; preserve the role and chevron column. + +- [x] **Step 3a: Add the visual fixture dates** + +Add `updatedAt: '2024-05-12'` to genealogy `1001` and `updatedAt: '2024-04-28'` to genealogy `1002` in `data/mock.js`. These fields are display-only fixtures and do not change the API contract. + +- [x] **Step 4: Implement CSS sizing and small-screen fallback** + +Increase card name/title prominence, keep row-frame as the only paper frame, set right-side role/chevron to a centered fixed column, and make `.card-updated` disappear at `max-width: 340px` before text can collide. + +- [x] **Step 5: Run the contract and verify it passes** + +Run: `powershell -ExecutionPolicy Bypass -File tests\g01-visual-contract.ps1` +Expected: `PASS G-01 visual contract`. + +### Task 4: Documentation and full verification + +**Files:** +- Modify: `docs/design/G01_我的家谱_设计记录.md` +- Modify: `docs/规划.md` + +**Interfaces:** +- Records only completed implementation and verification; leaves G01 unchecked until an HBuilderX comparison screenshot is accepted. + +- [x] **Step 1: Record the completed implementation scope** + +Append the new asset paths, the explicit visual reference, and the small-screen fallback to the G01 design record. Mark the implementation subtask complete in `docs/规划.md`; do not mark the full G01 design complete. + +- [x] **Step 2: Run focused verification** + +Run: + +```powershell +powershell -ExecutionPolicy Bypass -File tests\g01-visual-contract.ps1 +powershell -ExecutionPolicy Bypass -File tests\compile-audit.ps1 +powershell -ExecutionPolicy Bypass -File tests\uni-scss-injection.ps1 +``` + +Expected: three `PASS` lines and no warnings. + +- [ ] **Step 3: Capture visual evidence in HBuilderX** + +At the same phone viewport as the supplied comparison, capture G01 and compare it side-by-side with the v5 reference. Confirm the current title/meta row, all three seals, four shortcut icon sizes, list row hierarchy, and cloud button ornament. If a mismatch remains, record it rather than marking G01 complete. + +## Plan self-review + +- Spec coverage: Tasks 1–3 implement every asset, layout, small-screen, and visual hierarchy requirement; Task 4 records and verifies it. +- No placeholders: all new paths, CSS tokens, component classes, commands, and expected outputs are named. +- Consistency: page uses current panel assets; card uses row seal and metadata assets; both are enforced by one G01 visual contract. + +### Task 5: 参考稿字段与列表基线校正 + +**Files:** +- Modify: `data/mock.js` +- Modify: `pages/genealogy/index.vue` +- Modify: `components/GenealogyCard.vue` +- Modify: `tests/g01-visual-contract.ps1` + +**Interfaces:** +- Produces reference-matched visual fixture fields without changing any remote API contract. +- Keeps the existing navigation and card `select` event unchanged. + +- [x] **Step 1: Write the failing visual-fixture contract** + +Require the four reference names/locations/counts, `.current-info-divider`, a row-direction `.card-side`, and no `calendar-v1.png` use in the list component. + +- [x] **Step 2: Run the contract and verify it fails** + +Run: `powershell -ExecutionPolicy Bypass -File tests\g01-visual-contract.ps1` +Expected: `FAIL` because the old demonstration fields, missing current divider, vertical role/arrow, and calendar icon are still present. + +- [x] **Step 3: Apply the smallest source correction** + +Replace only G01 mock fixture fields with the strings in the approved reference. Add the current-panel divider; render fixed vertical “家谱” list seal text; remove the list calendar icon; align `.card-role` and `.card-chevron` horizontally. + +- [x] **Step 4: Run focused verification** + +Run the G01 visual contract, PNG alpha audit, compile audit, SCSS injection audit, and Vue 3 entry audit. Keep Task 4 visual capture unchecked until the user accepts a new HBuilderX screenshot. diff --git a/docs/superpowers/plans/2026-07-12-g01-visual-shell.md b/docs/superpowers/plans/2026-07-12-g01-visual-shell.md new file mode 100644 index 0000000..ca44576 --- /dev/null +++ b/docs/superpowers/plans/2026-07-12-g01-visual-shell.md @@ -0,0 +1,221 @@ +# G-01 Visual Shell Implementation Plan + +> For agentic workers: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox syntax for tracking. + +**Goal:** Rebuild the Android “我的家谱” G-01 page as the approved 家祠卷轴 design with verified local PNG assets and stable mock presentation data. + +**Architecture:** pages/genealogy/index.vue owns local visual states only. It composes a heritage header, paper-slip list items, and safe bottom navigation; it does not make remote API calls during this visual-construction phase. + +**Tech Stack:** uni-app, Vue 3 script setup, SCSS/rpx, local RGBA PNG/JPG assets, PowerShell checks. + +## Global Constraints + +- Android only; verify 360 × 800 and 320 × 568 without overlap. +- No API, authentication, packaging, dependency, or unrelated-flow changes. +- Every functional icon is a local RGBA PNG under static/assets/icons/. +- Header uses the confirmed original brand/jiapu-seal-logo.png in the left safe area; title is centered; notification dot renders only for unread messages. +- Tabbar is fixed at the bottom, has 64dp content plus Android navigation inset, and keeps the icon and label clear of the lower edge. +- Do not mark G-01 design complete until assets, normal/empty/loading states, and small-screen checks have evidence. + +## File Responsibilities + +| File | Responsibility | +| --- | --- | +| static/assets/icons/genealogy/*-v2.png | Four compact antique-gold G-01 shortcut icons. | +| static/assets/icons/action/add-v2.png | The compact 新建家谱 icon. | +| static/assets/icons/common/chevron-right-v2.png | Compact right-arrow asset for the paper-slip list row. | +| static/assets/icons/tab/*-v4.png | Default and active 24dp tab icon pairs. | +| components/PageHeader.vue | Heritage header, original Logo, notification PNG and optional dot. | +| components/AppTabbar.vue | Fixed Android-safe three-tab navigation. | +| components/GenealogyCard.vue | Compact paper-slip genealogy list row. | +| pages/genealogy/index.vue | G-01 content, local state and route actions. | +| tests/g01-visual-contract.ps1 | Asset and static page-contract checks. | + +## Task 1: Produce and register G-01 visual assets + +**Files:** +- Create: static/assets/icons/genealogy/tree-v2.png +- Create: static/assets/icons/genealogy/members-v2.png +- Create: static/assets/icons/genealogy/generation-poem-v2.png +- Create: static/assets/icons/genealogy/application-v2.png +- Create: static/assets/icons/action/add-v2.png +- Create: static/assets/icons/common/chevron-right-v2.png +- Create: static/assets/icons/tab/{genealogy,family,profile}-v4.png +- Create: static/assets/icons/tab/{genealogy,family,profile}-active-v4.png +- Create: tests/g01-visual-contract.ps1 +- Modify: docs/design/G01_我的家谱_设计记录.md + +**Interfaces:** +- Consumes: D1 icon rules and the G-01 asset table. +- Produces: the listed asset paths; no legacy static/icons/tab-*.png consumer remains. + +- [x] **Step 1: Write the failing asset contract** + + $root = Split-Path -Parent $PSScriptRoot + $requiredAssets = @( + 'static/assets/icons/brand/jiapu-seal-logo.png', + 'static/assets/icons/common/notice-v3.png', + 'static/assets/icons/genealogy/tree-v2.png', + 'static/assets/icons/genealogy/members-v2.png', + 'static/assets/icons/genealogy/generation-poem-v2.png', + 'static/assets/icons/genealogy/application-v2.png', + 'static/assets/icons/action/add-v2.png', + 'static/assets/icons/common/chevron-right-v2.png', + 'static/assets/icons/tab/genealogy-v4.png', + 'static/assets/icons/tab/genealogy-active-v4.png', + 'static/assets/icons/tab/family-v4.png', + 'static/assets/icons/tab/family-active-v4.png', + 'static/assets/icons/tab/profile-v4.png', + 'static/assets/icons/tab/profile-active-v4.png' + ) + foreach ($asset in $requiredAssets) { + if (-not (Test-Path -LiteralPath (Join-Path $root $asset))) { + throw "Missing G-01 visual asset: $asset" + } + } + Write-Output 'PASS G-01 visual contract' + +- [x] **Step 2: Run the contract and confirm it fails** + +Run: powershell -ExecutionPolicy Bypass -File C:\Users\Rain\Desktop\job\jiapuapp\tests\g01-visual-contract.ps1 + +Expected: an error that names tree-v2.png as missing. + +- [x] **Step 3: Generate and validate every icon** + +Generate each asset separately as a tight 96 × 96px transparent PNG. Shortcut and add icons use antique-gold #B58A4B with the approved restrained double-line style. Tab pairs use the same 24dp silhouette in default ink #342A24 and selected cinnabar #A33B2B; no text, clouds, leaves, shadows, or excess transparent padding. + +- [x] **Step 4: Inspect and register accepted assets** + +Inspect Tabs at 46rpx and shortcuts at 48rpx. Reject opaque corners, excess canvas padding, unrecognizable semantics, and any default/selected silhouette mismatch. Update the G-01 asset table with actual path, 96 × 96px, transparency result, and display-size result. Do not tick page-completion boxes yet. + +- [x] **Step 5: Re-run the asset contract** + +Expected: PASS G-01 visual contract. + +## Task 2: Rebuild header and Android-safe Tabbar + +**Files:** +- Modify: components/PageHeader.vue +- Modify: components/AppTabbar.vue +- Modify: tests/g01-visual-contract.ps1 + +**Interfaces:** +- Produces: PageHeader title=我的家谱 with unreadCount, and AppTabbar active=genealogy. + +- [x] **Step 1: Extend the failing static contract** + + $header = Get-Content -Raw -Encoding UTF8 (Join-Path $root 'components/PageHeader.vue') + $tabbar = Get-Content -Raw -Encoding UTF8 (Join-Path $root 'components/AppTabbar.vue') + if ($header -notmatch 'jiapu-seal-logo\.png') { throw 'Header does not use the approved brand PNG.' } + if ($header -notmatch 'notice-v3\.png') { throw 'Header does not use the approved notice PNG.' } + if ($header -notmatch 'unreadCount\s*>\s*0') { throw 'Header badge is not conditional on unread count.' } + if ($tabbar -match '/static/icons/tab-') { throw 'Tabbar still references rejected legacy tab assets.' } + if ($tabbar -notmatch 'safe-area-inset-bottom') { throw 'Tabbar has no Android safe-area padding.' } + if ($tabbar -notmatch 'font-size:\s*24rpx') { throw 'Tabbar label size is below the approved G-01 size.' } + +- [x] **Step 2: Confirm the contract fails before components change** + +Run the focused contract. + +Expected: failure describing the legacy header or Tabbar implementation. + +- [x] **Step 3: Implement the header** + +Use image-only controls: an 88rpx Logo touch area, centered title, and equal-width 88rpx notice touch area using notice-v3.png. Add v-if unreadCount > 0 for the cinnabar dot. Use the header line-art PNG over a cinnabar base. Do not render text labels for Logo or notification action. + +- [x] **Step 4: Implement the Tabbar** + +Map every item to its v4 default/active PNG paths and choose by active === item.key. Keep a paper-white fixed bar, visible content height 128rpx, padding-bottom env(safe-area-inset-bottom), icon 48rpx, label 24rpx, and each touch target at least 96rpx. Do not use gap. + +- [x] **Step 5: Re-run the contract** + +Expected: PASS G-01 visual contract. + +## Task 3: Rebuild G-01 content and presentation states + +**Files:** +- Modify: components/GenealogyCard.vue +- Modify: pages/genealogy/index.vue +- Modify: tests/g01-visual-contract.ps1 + +**Interfaces:** +- Consumes: genealogies and notifications from @/data/mock.js. +- Produces: isLoading, hasGenealogies, createdGenealogies, and joinedGenealogies visual branches. + +- [x] **Step 1: Add the failing local-state contract** + + $page = Get-Content -Raw -Encoding UTF8 (Join-Path $root 'pages/genealogy/index.vue') + if ($page -match "from '@/utils/api\.js'") { throw 'G-01 visual phase must not call the remote API.' } + foreach ($state in @('isLoading', 'hasGenealogies', 'createdGenealogies', 'joinedGenealogies')) { + if ($page -notmatch $state) { throw "G-01 is missing presentation state: $state" } + } + foreach ($asset in @('tree-v2.png', 'members-v2.png', 'generation-poem-v2.png', 'application-v2.png', 'add-v2.png')) { + if ($page -notmatch [regex]::Escape($asset)) { throw "G-01 does not consume $asset" } + } + +- [x] **Step 2: Confirm the contract fails on the legacy page** + +Expected: failure for the API import or missing visual state. + +- [x] **Step 3: Implement the page state owner** + +Remove appApi, genealogyContext, and the mounted API call. Import genealogies and notifications from @/data/mock.js, then define: + + const isLoading = ref(false) + const list = ref(genealogies) + const hasGenealogies = computed(() => list.value.length > 0) + const createdGenealogies = computed(() => list.value.filter((item, index) => index === 0)) + const joinedGenealogies = computed(() => list.value.filter((item, index) => index > 0)) + +Retain only route navigation: tree /pages/tree/index, members /pages/genealogy/detail, generation poem /pages/content/list?type=poem, applications /pages/genealogy/applications, create /pages/genealogy/create, search /pages/genealogy/search, and notifications /pages/notification/index. + +- [x] **Step 4: Implement approved compact layout** + +Compose heritage header, current-genealogy paper slip, four equal shortcut entries with v2 assets, separate 我创建的 / 我加入的 groups, compact paper-slip rows, and the add button. Implement a distinct loading state and an empty paper/scroll state with 新建家谱 and 搜索并申请加入. Apply paper texture to the page and mountain/bamboo only to the lower content region. Add bottom content padding that clears the fixed Tabbar. + +- [x] **Step 5: Simplify GenealogyCard.vue** + +Use a seal-style surname block, title, short location/member metadata, identity label, and common/chevron-right-v2.png. Remove the legacy navy cover, motto, and active-member count. Ensure long copy uses min-width: 0, overflow: hidden, and text-overflow: ellipsis. + +- [x] **Step 6: Re-run the focused contract** + +Expected: PASS G-01 visual contract. + +## Task 4: Verify and update the project record + +**Files:** +- Modify: docs/design/G01_我的家谱_设计记录.md +- Modify: docs/规划.md +- Test: tests/g01-visual-contract.ps1 +- Test: tests/compile-audit.ps1 +- Test: tests/uni-scss-injection.ps1 + +- [x] **Step 1: Run the automated checks** + +Run: + + powershell -ExecutionPolicy Bypass -File C:\Users\Rain\Desktop\job\jiapuapp\tests\g01-visual-contract.ps1 + powershell -ExecutionPolicy Bypass -File C:\Users\Rain\Desktop\job\jiapuapp\tests\compile-audit.ps1 + powershell -ExecutionPolicy Bypass -File C:\Users\Rain\Desktop\job\jiapuapp\tests\uni-scss-injection.ps1 + +Expected: each command prints its PASS result. + +- [ ] **Step 2: Verify at Android reference sizes** + +Inspect 360 × 800 and 320 × 568. Confirm no overlap among Logo, title, and bell; notice dot only appears with unread entries; shortcut labels remain one line; list text truncates instead of overlaps; create action clears the Tabbar; all three Tab labels remain fully visible above system navigation. + +- [ ] **Step 3: Update only verified design state** + +In the G-01 record, tick only conditions backed by Tasks 1–2 and the two viewport checks. In the overall planning document, leave G-01 unchecked if even one state, asset, or viewport condition remains incomplete; otherwise record visual shell implemented and verified. + +- [ ] **Step 4: Commit only when Git becomes available** + +If a Git worktree exists, commit changed visual-shell files with message: feat: build G01 genealogy visual shell. If Git remains unavailable, report that no commit was created and do not initialize a repository. + +## Plan Self-Review + +- Task 1 covers local assets and transparency checks. +- Task 2 covers the Logo, conditional notification dot, and safe Tabbar. +- Task 3 covers G-01 normal, loading, and empty states plus approved compact layout. +- Task 4 requires automated and small-screen verification before any completion status changes. diff --git a/docs/superpowers/specs/2026-07-11-real-api-core-flow-design.md b/docs/superpowers/specs/2026-07-11-real-api-core-flow-design.md new file mode 100644 index 0000000..f0c3f94 --- /dev/null +++ b/docs/superpowers/specs/2026-07-11-real-api-core-flow-design.md @@ -0,0 +1,29 @@ +# 真实接口核心流程设计 + +## 目标 + +把现有静态界面升级为可在 Mock 和远端接口之间明确切换的核心流程:登录后进入我的家谱,按当前家谱 ID 查看详情、世系树和成员,并完成创建家谱后录入首代人物。 + +## 方案选择 + +- 采用显式 `mode: 'mock' | 'remote'` 配置;远端请求失败时显示错误,不自动切回 Mock。 +- 认证支持密码登录和短信登录。密码登录用于已有测试账号;短信入口按 OpenAPI 请求验证码和登录。 +- API 适配层统一解包 OpenAPI 的 `{ code, msg, data }` 响应,统一保存/清除 token,并在 401/403 时提示重新登录。 +- 当前家谱 ID 以页面参数为主、持久化上下文为辅。详情、树、成员、审核、家族动态不得再写死 `1001`。 + +## 范围 + +本阶段完成认证、会话、家谱上下文、创建家谱、录入首代、详情、世系树、成员档案的真实数据链路。 + +本阶段不实现谱文、相册、祭祀、VIP、帮助、反馈等内容模块;这些入口继续明确提示“后续开放”。 + +## 验收 + +1. Mock 模式下可完成:登录、创建家谱、录入首代、进入对应世系树、打开对应成员档案。 +2. Remote 模式下所有请求携带 `clientid` 与已保存 token,并按接口响应的 `data` 字段消费。 +3. 远端登录/接口失败时不会跳转成功、不会静默返回 Mock 数据,并能给出可理解提示。 +4. 页面跳转不再依赖硬编码家谱 ID 或成员 ID。 + +## 已知外部限制 + +当前远端密码登录探测返回 HTTP 500,前端会保留远端模式和错误提示,但无法在服务端恢复前完成真实账号的端到端验收。 diff --git a/docs/superpowers/specs/2026-07-12-g01-reference-typography-design.md b/docs/superpowers/specs/2026-07-12-g01-reference-typography-design.md new file mode 100644 index 0000000..1b6d8e3 --- /dev/null +++ b/docs/superpowers/specs/2026-07-12-g01-reference-typography-design.md @@ -0,0 +1,62 @@ +# G01 参考稿信息层级校正设计 + +## 已确认的目标 + +- 以 `docs/design/screens/G01-我的家谱-紧凑版设计稿-v5-Tabbar安全区.png` 为唯一视觉基准;不再以当前浏览器页为准缩放设计。 +- 本轮只校正用户箭头指出的内容区:当前家谱题签的信息层级、四个快捷入口、分隔线之后的两条列表和“新建家谱”按钮。 +- 保留已确认的朱砂页头、宣纸底纹、淡墨山水和底部 Tabbar;不接入接口、不改路由;仅为现有展示用 `data/mock.js` 家谱条目补充参考稿需要的 `updatedAt` 日期字段。 +- 预览阶段的展示字段必须与参考稿一致:当前家谱为“汤氏家谱 / 河南·洛阳 / 158 位成员 / 管理员”,已加入家谱为“汤氏宗谱 / 山东·济宁 / 286 位成员 / 成员”。视觉验收期间不得保留四川、达州、刘氏等旧演示字段。 + +## 方案比较与选择 + +1. 仅增大现有 CSS 字号和图标容器:改动少,但仍缺地点/成员/管理员图标和更新时间层级,不能还原参考稿。 +2. 同时压缩所有内容区:会牺牲旧安卓小屏可读性,也无法解决信息结构错误。 +3. **按参考稿重建四个内容区的信息栅格**:补齐独立 PNG 元信息图标,放大可见图标和标题字号,使用两行列表元信息与右侧角色列。选此方案。 + +## 页面规格 + +### 当前家谱题签 + +- 保持纸签框资产和透明四角;名称为最高层级,使用楷体回退链。 +- 左侧“家谱”不是普通红色圆角块:改为独立的竖式朱砂谱印框 PNG,包含参考稿的双层金白描边与红印底;谱印固定显示“家谱”,家谱名称和数值仍由页面数据渲染,不嵌死在图片中。 +- 当前家谱谱印比列表谱印更高;两者分别使用对应尺寸的 PNG 框,保持参考稿的层级,不能共用一个拉伸框。 +- 元信息改为三组:地点、成员数、管理员;每组由 24dp 的透明 PNG 图标与文字构成,不能再只用文字串联。 +- 三组在可用宽度内均匀排列;320px 小屏可换行但不重叠。 +- 名称与三组元信息之间保留参考稿中的细金线分隔;在 430px 验收宽度三组必须同一行。 + +### 快捷入口与分隔线 + +- 快捷图标的显示框放大,使实际图形接近参考稿的视觉面积;标签同步提升,四项保持等宽。 +- 快捷区与金线云纹分隔线保留明确留白,分区标题不得贴线。 + +### 家谱列表 + +- 每条维持纸签框和透明四角;标题提升为主要信息。 +- 左侧使用较小的竖式朱砂谱印框 PNG;已加入家谱可保持低饱和底色,但边框、比例与“我创建的”谱印一致。 +- 次行固定为“地点 + 成员数”;右侧固定为“角色 + 箭头”,并在宽屏下补充“更新于日期”。 +- 小屏降级时优先保留标题、地点、成员数和角色;更新时间可隐藏,禁止文字压到箭头。 +- 角色文字与右箭头使用同一水平基线;日期是文本信息,不增加参考稿中没有的日历图标。 +- 列表谱印固定显示竖排“家谱”,不显示动态姓氏;已加入列表使用低饱和谱印状态。 + +### 新建按钮 + +- 保留独立 PNG 加号;放大文字和图标实际显示尺寸。 +- 补齐参考稿的左右云纹装饰 PNG,不用 CSS 或文字模拟装饰。 + +## 资产与兼容性 + +- 新增地点、成员、管理员、更新时间和按钮云纹均为项目内 RGBA PNG;图标画布为 96px,并检查四角透明。 +- 不用 `clip-path`、蒙版或其他旧 Android WebView 风险较高的裁切方案。 +- 所有布局继续使用 rpx、弹性布局、单行省略和 `max-width: 340px` 小屏规则。 + +## 验收与验证 + +1. 自动契约先失败:要求新元信息图标、两行列表结构、放大的快捷图标和新建按钮云纹存在;旧的纯文字元信息实现必须不再通过。 +2. 完成最小代码与 PNG 资产改动后,运行 G01 契约、编译审计、SCSS 注入审计和 PNG 透明角检查。 +3. 使用 HBuilderX 在同一设备尺寸重新截图,与参考稿并排比对:重点确认箭头所指的字号、间距、图标面积、列表行高与按钮装饰。 + +## 自检 + +- 无占位项、无接口或路由扩展。 +- 唯一视觉来源是已确认的 G01 v5 参考稿;本轮没有重设颜色、背景或页面功能。 +- 若 320px 宽度装不下,按本文件定义隐藏更新时间,而不是压缩全部文字。 diff --git a/docs/交接记录.md b/docs/交接记录.md new file mode 100644 index 0000000..6e3b312 --- /dev/null +++ b/docs/交接记录.md @@ -0,0 +1,105 @@ +# 家谱 APP 交接记录 + +> 更新时间:2026-07-13 +> 用途:更换电脑或更换 GPT 后,先读本文件即可恢复当前工作上下文。 +> 保密说明:账号、密码、令牌和其他敏感信息不记录在本文件。 + +## 1. 新接手者先做什么 + +按以下顺序阅读,不要跳过: + +1. 根目录 `AGENTS.md`:项目工作约束,要求先确认依据、最小修改、修改后验证。 +2. `docs/规划.md`:全项目范围、完成状态与推进顺序。 +3. `docs/design/D1_安卓视觉规范与页面壳.md`:Android 视觉、兼容性、PNG 资产与背景规则。 +4. `docs/design/G01_我的家谱_设计记录.md`:G01 已完成的施工与尚未验收项。 +5. `docs/superpowers/specs/2026-07-12-g01-reference-typography-design.md` 与 `docs/superpowers/plans/2026-07-12-g01-information-hierarchy.md`:G01 的已确认规格与执行记录。 + +视觉唯一基准: + +- `docs/design/screens/G01-我的家谱-紧凑版设计稿-v5-Tabbar安全区.png` + +不要把“红色中国风”当作完成标准;G01 需要按此图逐区、逐字段、逐比例比对。 + +## 2. 项目与范围 + +- 项目:uni-app,目标为 Android,使用 HBuilderX 打包。 +- 当前阶段:先完成全部页面视觉设计和小屏验收;**暂不恢复接口联调、真实账号联调或 Android 打包**。 +- 当前正在处理:`G-01 我的家谱`。 +- 当前不做:iOS、PC 管理端、官网,以及新增业务接口。 +- 本地展示数据的唯一来源:`data/mock.js`;G01 当前不调用远程 API。 +- 本目录当前不是 Git 仓库;不要擅自初始化仓库、重置文件或删除既有用户文件。 + +## 3. 用户已确认的视觉规则 + +- 风格是“家祠卷轴”:朱砂页头、暖宣纸、古金细线、墨褐文字、淡墨山水/竹影;禁止绿色页面背景。 +- 需要使用的图标、谱印框与云纹必须是项目内的透明 PNG;不能用文字、emoji、CSS 图形或网络图片替代可见图标。 +- 参照图中的布局、字号、字段、图标可见面积和留白需要尽量一比一还原;不要只做“差不多”的国风页面。 +- 要兼容老款 Android:用 rpx、Flex、边距与基础圆角;避免 CSS Grid、`flex gap`、`clip-path`、复杂滤镜和大面积动画。 +- 每次完成一个可验收子项,更新 `docs/规划.md` 和对应设计记录;没有 HBuilderX 同尺寸截图确认时,不能勾选整个页面完成。 + +## 4. G01 当前实际状态 + +### 已施工并通过静态检查 + +- 朱砂顶部、项目 Logo、条件式通知红点、宣纸底纹、淡墨底图、底部 Tabbar。 +- 当前家谱题签、四个快捷入口、分隔金线、创建/加入列表、新建按钮。 +- 透明 PNG 资产已接入:快捷入口、Tab、通知、箭头、元信息图标、谱印框和新建云纹。 +- 当前演示字段已统一为参考稿: + - 当前家谱:`汤氏家谱 / 河南·洛阳 / 158 位成员 / 管理员` + - 已加入家谱:`汤氏宗谱 / 山东·济宁 / 286 位成员 / 成员` +- 当前题签有标题/元信息分隔线;列表右侧角色和箭头应为同一水平基线;日期为“更新于”文字,不显示参考稿中没有的日历图标。 + +### 必须继续做的事 + +1. 用 HBuilderX 刷新 G01,并使用与参考稿相同的手机预览尺寸截屏。 +2. 将新截图与 v5 参考稿并排比对,重点检查: + - 顶部家谱题签的字体、字段、分隔线和三组元信息是否同一行; + - 四个快捷图标的实际可见面积与文字大小; + - 两条列表的谱印、标题、地点/成员、日期、右侧角色和箭头基线; + - 新建按钮的云纹、文字、底部山水和 Tabbar 安全区。 +3. 有任何差异时,只改对应 G01 组件并重新截图;不要提前勾选 `G-01`。 +4. 最终还要按 `320 × 568` 和 `360 × 800` 做小屏检查,确认无重叠、无裁切、无底部遮挡。 + +## 5. G01 关键文件 + +| 作用 | 文件 | +| --- | --- | +| G01 页面与当前题签/快捷入口/新建按钮 | `pages/genealogy/index.vue` | +| G01 列表项 | `components/GenealogyCard.vue` | +| 顶部标题栏/Logo/通知点 | `components/PageHeader.vue` | +| 底部导航 | `components/AppTabbar.vue` | +| 展示数据 | `data/mock.js` | +| 视觉变量 | `styles/tokens.scss`、`styles/global.scss` | +| G01 图标 | `static/assets/icons/` | +| G01 背景 | `static/assets/backgrounds/` | +| G01 契约检查 | `tests/g01-visual-contract.ps1` | +| 新 PNG 透明检查 | `tests/g01-asset-alpha-audit.ps1` | + +## 6. 已知技术注意项 + +- `tests/g01-visual-contract.ps1` 用 UTF-8 Base64 形式检查中文展示字段。这是为了避免 Windows PowerShell 5.1 将无 BOM UTF-8 脚本中的中文字符串误读为乱码;不要把该段直接改回裸中文字面量。 +- `calendar-v1.png` 已因为参考稿没有该图标而删除;不要再次接入日期图标。 +- G01 的背景资产应继续使用 `footer-mountain-bamboo.png`,不要换回实心灰山的 `footer-mountain-bamboo-v2.png`。 +- 题签透明角已经过检查;若再次出现白角,优先检查题签容器是否重新加上不透明的矩形底色。 +- 所有新 PNG 在接入前都要检查:RGBA、四角透明、主体没有大量空白、显示尺寸符合 24dp/设计稿。 + +## 7. 复核命令 + +在项目根目录的 PowerShell 中运行: + +```powershell +powershell -ExecutionPolicy Bypass -File tests\g01-visual-contract.ps1 +powershell -ExecutionPolicy Bypass -File tests\g01-asset-alpha-audit.ps1 +powershell -ExecutionPolicy Bypass -File tests\compile-audit.ps1 +powershell -ExecutionPolicy Bypass -File tests\uni-scss-injection.ps1 +powershell -ExecutionPolicy Bypass -File tests\vue3-entry.ps1 +``` + +最近一次结果:五项均为 `PASS`。这只证明代码和资产契约通过,**不替代 HBuilderX 视觉验收**。 + +## 8. 换电脑操作 + +1. 完整复制整个 `jiapuapp` 项目文件夹,保留 `docs/`、`static/`、`tests/`、`data/` 和所有 Vue/SCSS 文件。 +2. 新电脑安装 HBuilderX 后,直接“打开目录”选择复制后的项目根目录。 +3. 将本文件和新的 HBuilderX 截图一起发给新的 GPT,并说明:“先读 `docs/交接记录.md` 与 `AGENTS.md`,继续 G01 的视觉验收,不要改接口。” +4. 新 GPT 修改后,先运行第 7 节命令,再由用户在 HBuilderX 提供同尺寸截图复核。 diff --git a/docs/规划.md b/docs/规划.md new file mode 100644 index 0000000..47874d1 --- /dev/null +++ b/docs/规划.md @@ -0,0 +1,207 @@ +# 规划 + +> 电脑或 GPT 更换时,先阅读:[项目交接记录](交接记录.md)。 + +> 状态:执行中 +> 建立日期:2026-07-11 +> 唯一适用端:Android `uni-app`(HBuilderX 打包) +> 执行原则:**先完成全部页面设计,再开始逐页实现;每完成一项,立即在本文件勾选。** + +## 1. 本轮边界 + +- 只做手机 Android 用户端;不做 iOS、H5、PC 管理端、后台管理端、官网。 +- 范围覆盖思维导图中的 Android 用户端:登录、家谱、家族、消息、我的,以及必要的空白、加载、异常、权限状态。 +- 现有 uni-app 页面与接口代码保留为临时功能骨架,但**不计入任何页面设计完成项**,也不再决定最终视觉样式。 +- 在“设计验收”完成前,暂停新增业务接口、真实账号联调和打包工作。 +- 接口暂未提供的视频、邀请码、多管理员分级等功能:本轮可完成其页面视觉和无数据状态;真实功能接入留到接口阶段。 + +## 2. 视觉方向(已确定) + +### 2.1 风格名称 + +**家祠卷轴**:喜庆而庄重。以宣纸的温度承载家族记忆,以朱砂表达礼序和重要操作,以古金表达传承;避免网红化、过度卡片化和大面积高饱和红色。 + +### 2.2 颜色与材质 + +| 用途 | 色彩 | 规则 | +| --- | --- | --- | +| 页面底色 | 宣纸暖白 `#F6F0E5` | 不使用绿色背景。 | +| 主操作 / 选中 | 朱砂 `#A33B2B` | 仅用于主按钮、当前状态、关键提醒。 | +| 标题 / 主要文字 | 墨褐 `#342A24` | 不使用偏绿的深色。 | +| 细分隔 / 装饰 | 古金 `#B58A4B` | 只做细线、印记、等级,不做大色块。 | +| 容器 | 纸白 `#FFF9EE` | 用轻边线或极浅阴影分层。 | +| 次级文字 | 暖灰褐 `#7A6958` | 保持正文可读性。 | + +### 2.3 固定组件规则 + +- 顶部为简洁的家祠题签式标题栏;可回退页面保留清晰返回区,不能让装饰挤压标题。 +- 底部导航固定为“家谱 / 家族 / 我的”,通知作为右上角入口,不单独占 Tab。 +- 家谱树中的人物使用竖式人物牌位;姓名、字辈、关系与在世状态层次清楚,不能用装饰遮挡信息。 +- 所有功能图标均使用透明背景 PNG,统一由 `static/icons/` 管理;不用网络图标字体,不混用不同画风。 +- 图片内容优先使用用户上传的真实照片;没有照片时使用统一的纸纹占位图,不使用 AI 人像。 + +## 3. Android 老机型与小屏兼容(必须验收) + +### 3.1 尺寸与排版 + +- 以 `320 × 568`、`360 × 640` 为关键小屏;`360 × 800`、`412 × 915` 为常规屏进行核对。 +- 布局使用流式纵向滚动;不以单一固定页面高度承载内容,不让底部按钮压住表单。 +- 一行中可能出现长姓名、长家谱名、长地址时必须截断或换行,不允许文字重叠。 +- 关键正文不小于 `24rpx`,主要按钮高度不小于 `88rpx`,所有可点击区域不小于约 `44dp`。 +- 双列内容在 `320px` 宽度下自动折为单列;人物树、照片墙等横向内容提供明确的横向滚动区域与边缘提示。 +- 顶部、底部均预留系统状态栏和 Android 三键/手势导航空间;无安全区能力的设备也要有保底内边距。 + +### 3.2 性能与技术限制 + +- 不使用全屏大尺寸背景图、视频背景、复杂滤镜、毛玻璃和持续动画。 +- 不依赖 `flex gap`、复杂 CSS Grid 或只在新 WebView 支持的视觉效果;以 Flex、边距和基础圆角为主。 +- 首屏图标为小尺寸透明 PNG;列表图片按缩略图加载,避免一次性渲染大量高清图。 +- 家谱树按层级或视区呈现,不在低端机一次渲染无边界的全部成员节点。 +- 表单、弹窗、图片预览都要可关闭、可返回,并在键盘弹起时保持提交按钮可见。 + +### 3.3 兼容验收方式 + +- 每个页面设计完成后,先按 `320 × 568` 检查:标题、长文案、表单、底部操作、横向内容五项均不得重叠。 +- 全部页面实现后,以 Android 真机或模拟器覆盖上述四组尺寸,记录在本文件“最终验收”中。 +- 这里的“兼容”指页面尺寸、性能和交互可用性;具体最低 Android 系统版本在最终 HBuilderX 打包配置阶段按实际 SDK 再确认。 + +## 4. 页面设计的完成标准 + +一页只有同时满足以下四项,才能标记为“设计完成”: + +1. 有明确的正常态布局、字体层级、颜色、图标、间距与操作层级。 +2. 有该页需要的空数据、加载、失败、无权限或审核中状态。 +3. 标明每个主要点击入口的去向、返回路径和确认操作。 +4. 已按 `320 × 568` 小屏规则检查,无重叠、无被底部导航遮挡的内容。 + +## 5. 全量页面清单与完成状态 + +### 5.1 设计基础与通用状态 + +- [x] P-00 锁定 Android 端范围、家祠卷轴视觉方向与透明 PNG 图标规则。 +- [x] P-01 锁定老机型 / 小屏适配原则与验收尺寸。 +- [x] P-02 设计系统:颜色、字号、间距、圆角、按钮、标签、列表、表单、弹窗、空状态。见 [D1 安卓视觉规范与页面壳](design/D1_安卓视觉规范与页面壳.md)。 +- [x] P-03 公共页面壳:顶部题签、返回栏、三 Tab、右上角通知入口、安全区与底部操作栏。见 [D1 安卓视觉规范与页面壳](design/D1_安卓视觉规范与页面壳.md)。 +- [x] P-04 通用状态:首次加载、列表加载、网络失败、空数据、无权限、审核中、删除确认、操作成功提示。见 [D1 安卓视觉规范与页面壳](design/D1_安卓视觉规范与页面壳.md)。 +- [ ] P-05 生成并验收项目 Logo、导航、通知与公共操作的透明 PNG 图标资产。见 [D1 安卓视觉规范与页面壳](design/D1_安卓视觉规范与页面壳.md)。 +- [ ] P-06 生成并验收祠堂红头、宣纸纸纹、山水 / 竹影等项目内背景资产。见 [D1 安卓视觉规范与页面壳](design/D1_安卓视觉规范与页面壳.md)。 + +### 5.2 账户与首次使用 + +- [ ] A-01 启动 / 登录引导页。 +- [ ] A-02 账号密码登录页。 +- [ ] A-03 手机验证码登录页。 +- [ ] A-04 注册页与服务协议确认。 +- [ ] A-05 忘记密码 / 重设密码页。 +- [ ] A-06 账号受限、登录失败与未完成注册状态。 + +### 5.3 家谱:创建、加入与管理入口 + +- [x] G-01 信息层级与谱印施工:元信息图标、谱印框、快捷入口、列表双层信息和新建云纹已实现并通过资产/编译审计;待 HBuilderX 同尺寸截图验收,故完整 G-01 仍未勾选。 +- [ ] G-01 我的家谱列表(已创建、已加入、搜索入口、通知入口)。 +- [ ] G-02 无家谱空状态(创建家谱 / 搜索加入)。 +- [ ] G-03 创建家谱表单(名称、地域、简介、公开范围)。 +- [ ] G-04 创建成功后的始祖录入页。 +- [ ] G-05 家谱总览(名称、编号、地域、成员数、管理员、公开状态、快捷入口)。 +- [ ] G-06 公开家谱搜索与筛选页。 +- [ ] G-07 家谱搜索结果与家谱简介页。 +- [ ] G-08 申请加入表单、提交成功与审核中页。 +- [ ] G-09 我的申请记录页。 +- [ ] G-10 管理员申请审核列表与审核确认页。 +- [ ] G-11 家谱设置、公开范围与成员访问说明页。 +- [ ] G-12 字辈诗列表、详情与管理员维护页。 + +### 5.4 世系树、成员与亲属关系 + +- [ ] T-01 世系树总览(缩放、横向移动、分支切换、当前人物定位)。 +- [ ] T-02 世系树小屏提示与无成员 / 数据加载失败状态。 +- [ ] T-03 成员档案详情(基本资料、代际、关系、照片、人生记录入口)。 +- [ ] T-04 新增直系亲属页(父母、配偶、子女的不同上下文)。 +- [ ] T-05 编辑成员资料页。 +- [ ] T-06 编辑亲属关系页与关系冲突提示。 +- [ ] T-07 成员目录与搜索页。 +- [ ] T-08 成员去世、隐私隐藏、无编辑权限等特殊状态。 + +### 5.5 家族:动态、谱文、相册与影像 + +- [ ] F-01 家族首页 / 家族动态流。 +- [ ] F-02 发布动态页(文字、图片、可见范围)。 +- [ ] F-03 动态详情、评论、点赞与删除确认页。 +- [ ] F-04 谱文分类与文章列表页。 +- [ ] F-05 谱文详情页。 +- [ ] F-06 新建 / 编辑谱文页。 +- [ ] F-07 相册列表页。 +- [ ] F-08 相册详情与照片墙页。 +- [ ] F-09 图片预览、上传照片与上传失败状态。 +- [ ] F-10 视频列表、详情、发布入口与“接口尚未开放”状态。 + +### 5.6 家族:人物、礼仪与档案 + +- [ ] R-01 人物录列表页。 +- [ ] R-02 人物录详情与新增 / 编辑页。 +- [ ] R-03 贺礼列表页。 +- [ ] R-04 新增贺礼、贺礼详情与删除确认页。 +- [ ] R-05 礼仪活动列表(婚礼、升学、生日、其他)。 +- [ ] R-06 礼仪详情页。 +- [ ] R-07 新建 / 编辑礼仪活动页。 +- [ ] R-08 成长日志列表、详情与新增 / 编辑页。 +- [ ] R-09 人生事列表、详情与新增 / 编辑页。 +- [ ] R-10 备忘录列表、详情与新增 / 编辑页。 +- [ ] R-11 功德记录列表、详情与新增 / 编辑页。 + +### 5.7 消息与个人中心 + +- [ ] N-01 消息中心(生日、贺礼、礼仪、应用通知、点赞评论、推广反馈分类)。 +- [ ] N-02 消息详情、已读状态与空消息状态。 +- [ ] M-01 我的首页(头像、身份、所属家谱、快捷入口)。 +- [ ] M-02 个人资料查看 / 编辑页。 +- [ ] M-03 安全设置页。 +- [ ] M-04 修改密码页。 +- [ ] M-05 修改手机号页。 +- [ ] M-06 帮助中心与搜索页。 +- [ ] M-07 意见反馈页(文字、图片、联系方式)。 +- [ ] M-08 应用推广页。 +- [ ] M-09 VIP 权益、套餐与订单状态页。 +- [ ] M-10 关于我们、服务协议、隐私政策与退出登录确认页。 + +## 6. 设计推进顺序(开发前必须全部完成) + +| 阶段 | 交付内容 | 状态 | +| --- | --- | --- | +| D1 | P-02 至 P-06:统一设计系统、Android 页面壳、公共图标与背景资产 | 进行中(P-02 至 P-04 已完成;P-05、P-06 资产生成中) | +| D2 | A-01 至 A-06:账户与首次使用全套页面 | 未开始 | +| D3 | G-01 至 G-12:家谱创建、加入、总览与管理全套页面 | 进行中(G-01 视觉壳已施工,待 HBuilderX 小屏预览验收;其余页面未开始) | +| D4 | T-01 至 T-08:世系树、成员、关系编辑全套页面 | 未开始 | +| D5 | F-01 至 F-10、R-01 至 R-11:家族内容全套页面 | 未开始 | +| D6 | N-01 至 N-02、M-01 至 M-10:消息与个人中心全套页面 | 未开始 | +| D7 | 全量小屏复核、视觉一致性复核、页面流程复核 | 未开始 | +| D8 | 逐页实现 uni-app、接入接口、Android 打包验证 | 未开始(D7 完成后才可开始) | + +## 7. 页面流转主线(设计时必须保持一致) + +1. 登录 → 我的家谱为空 → 创建家谱 → 录入始祖 → 家谱总览 → 世系树 → 成员档案 / 新增亲属。 +2. 登录 → 搜索公开家谱 → 查看简介 → 申请加入 → 审核中 → 管理员审核 → 进入家谱总览。 +3. 家族 Tab → 动态 / 谱文 / 相册 / 人物录 / 礼仪 / 档案 → 详情 → 发布或编辑(取决于权限)。 +4. 任一页面的通知入口 → 消息中心 → 相应业务详情。 +5. 我的 → 个人资料 / 安全 / 帮助 / 反馈 / VIP / 关于与协议。 + +## 8. 本轮执行纪律 + +- 每次只推进一个设计阶段;阶段内的每个页面完成后,更新本文件对应复选框。 +- 未有高保真设计和小屏检查的页面,不得开始其业务开发。 +- 已确认的视觉规范是代码还原依据;若实现与设计不一致,以设计为准修正实现。 +- 参考图是视觉锚点;核心材质、层级、比例、选中效果必须逐项一比一核对,不能只保留“红色中国风”的笼统印象。 +- 设计稿不得保留无业务意义的横线、破折号或模拟字符;颜色差异必须有可见且明确的业务含义。 +- 后续每一个页面新增的功能图标,必须同步生成、保存并验收透明 PNG 实体资产;未生成资产的页面不得标记为“设计完成”。 +- 功能图标必须遵循线上成熟标准的 24dp 语义、留白、触控与选中规则,并导出为透明 PNG;项目可在此基础上保留已确认的古金双线、轻云纹收口等家祠风格。当前从大图裁切的试验资产不得引用,需按单图标标准重新导出后验收。 +- 大部分按钮、顶部操作和快捷入口图标采用已确认的古金双线、轻云纹收口风格;底部 Tab 使用简洁同色系版本。每一页必须指定并使用已生成的背景资产组合,未完成背景设计的页面不得标记为“设计完成”。 +- 全页 AI 生成图可作为页面的美术效果锚点,但不能单独作为布局验收依据;页面必须同时按固定 Android 栅格、真实数据、真实 PNG 资产制作。已生成的“我的家谱”效果图保留其朱砂、宣纸、题签、山水和庄重层级,留白、Logo、占位文案与图标标准问题按设计栅格修正后才可计入完成项。 +- 新增需求先写入本文件,再决定是否纳入本轮,避免在页面开发中临时扩张范围。 + +## 9. 最终验收(暂未开始) + +- [ ] 所有 P / A / G / T / F / R / N / M 页面均有设计完成标记。 +- [ ] 全部设计在 `320 × 568` 下无内容重叠、无遮挡、无不可点操作。 +- [ ] 所有图标均为透明背景 PNG,且无绿色页面背景。 +- [ ] 页面风格与“家祠卷轴”设计一致,代码页面与确认设计逐屏比对通过。 +- [ ] 全量页面设计确认后,才解锁 uni-app 实现、接口联调和 Android 打包。 diff --git a/index.html b/index.html new file mode 100644 index 0000000..2483001 --- /dev/null +++ b/index.html @@ -0,0 +1,12 @@ + + + + + + + + + +
+ + diff --git a/main.js b/main.js new file mode 100644 index 0000000..70b8fd0 --- /dev/null +++ b/main.js @@ -0,0 +1,8 @@ +import App from './App.vue' + +import { createSSRApp } from 'vue' + +export function createApp() { + const app = createSSRApp(App) + return { app } +} diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..0691a0c --- /dev/null +++ b/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "家谱", + "appid": "__UNI__JIAPUAPP", + "description": "家祠卷轴风格的家谱共建应用", + "versionName": "1.0.0", + "versionCode": 100, + "transformPx": false, + "app-plus": { + "usingComponents": true, + "nvueStyleCompiler": "uni-app", + "compilerVersion": 3, + "splashscreen": { + "alwaysShowBeforeRender": true, + "waiting": true, + "autoclose": true, + "delay": 0 + }, + "distribute": { + "android": { + "permissions": [ + "", + "", + "" + ] + }, + "ios": { + "dSYMs": false + } + } + }, + "mp-weixin": { + "usingComponents": true + }, + "vueVersion": "3" +} diff --git a/pages.json b/pages.json new file mode 100644 index 0000000..3082bc9 --- /dev/null +++ b/pages.json @@ -0,0 +1,66 @@ +{ + "pages": [ + { + "path": "pages/auth/login", + "style": { "navigationStyle": "custom", "enablePullDownRefresh": false } + }, + { + "path": "pages/genealogy/index", + "style": { "navigationStyle": "custom", "enablePullDownRefresh": false } + }, + { + "path": "pages/genealogy/create", + "style": { "navigationStyle": "custom" } + }, + { + "path": "pages/genealogy/detail", + "style": { "navigationStyle": "custom" } + }, + { + "path": "pages/genealogy/search", + "style": { "navigationStyle": "custom" } + }, + { + "path": "pages/genealogy/applications", + "style": { "navigationStyle": "custom" } + }, + { + "path": "pages/lineage/first-person", + "style": { "navigationStyle": "custom" } + }, + { + "path": "pages/content/list", + "style": { "navigationStyle": "custom" } + }, + { + "path": "pages/content/editor", + "style": { "navigationStyle": "custom" } + }, + { + "path": "pages/tree/index", + "style": { "navigationStyle": "custom", "disableScroll": true } + }, + { + "path": "pages/member/detail", + "style": { "navigationStyle": "custom" } + }, + { + "path": "pages/family/index", + "style": { "navigationStyle": "custom" } + }, + { + "path": "pages/profile/index", + "style": { "navigationStyle": "custom" } + }, + { + "path": "pages/notification/index", + "style": { "navigationStyle": "custom" } + } + ], + "globalStyle": { + "navigationBarTextStyle": "black", + "navigationBarTitleText": "家谱", + "navigationBarBackgroundColor": "#F6F0E5", + "backgroundColor": "#F6F0E5" + } +} diff --git a/pages/auth/login.vue b/pages/auth/login.vue new file mode 100644 index 0000000..6e90236 --- /dev/null +++ b/pages/auth/login.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/pages/content/editor.vue b/pages/content/editor.vue new file mode 100644 index 0000000..f69535e --- /dev/null +++ b/pages/content/editor.vue @@ -0,0 +1,35 @@ +