diff --git a/design-qa.md b/design-qa.md new file mode 100644 index 0000000..094479f --- /dev/null +++ b/design-qa.md @@ -0,0 +1,103 @@ +# M09 VIP 与订单:设计核验 + +## 对比对象 + +- Source visual truth: `C:\Users\Administrator\.codex\generated_images\019fa647-03b4-7901-9b6a-175d07d56512\exec-f3e0331f-59c3-4f01-a48f-d069bdab2d58.png` +- 同状态真机截图:`tmp/vip-redesign-audit/20-uniform-footer-cards.png` +- 下单面板真机截图:`tmp/vip-redesign-audit/21-uniform-footer-sheet.png` +- 并排对比:`tmp/vip-redesign-audit/22-uniform-main-reference-and-implementation.png` +- 设备:MuMu Android 基座,720 × 1280(360 × 640 CSS px,device scale factor 2)。参考图裁去底部已露出的面板后,按同一高度归一化进行并排检查。 + +## 视觉验收 + +- 顶部:水墨山景、竹影、留白与居中的标题层级已落地;新增背景资产为 `static/assets/modules/profile/opaque/m09-vip-hero-landscape.png`。 +- 套餐:基础版、宗族版、永久纪念版使用同一主推卡片规格,均有同样的朱砂描边、庭院水墨资产、底部价格/期限栏与圆角“立即开通”按钮。 +- 卡片资产:使用 `static/assets/modules/profile/opaque/m09-featured-courtyard.png`,在三张卡上保持统一的透明度和裁切方式,文字与按钮在真实窄屏上保持可读。 +- 下单:原居中装饰弹窗替换为底部确认单;套餐、有效期、应付金额、微信支付方式和取消入口均清晰可见。 + +## 交互验收 + +- MuMu 真机已点击“立即开通”,成功打开“确认下单”底部面板。 +- 已点击“暂不购买”安全关闭面板;关闭后确认页面仍保留 3 个“立即开通”入口,未由这次视觉验收新增订单。 +- 套餐和订单数据仍由现有接口读取;本次只改页面结构、样式与图片资产,不改接口字段或订单创建逻辑。 + +## 已知合同边界 + +- 当前 OpenAPI 未提供第三方支付调起参数或支付结果回调,因此主操作保持“创建订单”,不虚假宣称已完成微信支付。 + +## 结果 + +final result: passed + +--- + +# T01 世系谱:设计核验 + +## 对比对象 + +- Source visual truth:用户在本次会话提供的 `Jiapu-App` 世系谱截图(408 × 936 px),并已核对参考源码 `C:\Users\Administrator\Desktop\job\Jiapu-App\pages\index\tree\index.vue`。 +- Implementation screenshot:`tmp/t01-pedigree-paged-order-final2.png`(720 × 1280 px,MuMu Android;360 × 640 CSS px,density 2)。 +- 当前真实数据状态:已授权的“真机联调10159371”仅有 1 位成员;页面已显示一列始祖资料与右侧世代切换,不能据此核验多人横向滚动。 + +## Findings + +- [P1] 当前授权家谱只有一位成员,无法以真实数据复核参考图的“多位同世成员横向展开”状态。 + - 影响:实际单列、世代切换和纵向文字已验证,但多人列宽、横向滚动和同代排序仍缺少真机证据。 + - 修复:使用至少 5 位同世成员的测试家谱再次打开 T01;不应以本地伪造数据替代真实家谱数据。 + +## 已完成的源码核验 + +- T01 使用现有 `appApi.getTree` 单一数据 owner,按 `generation` 分组后每 5 人补齐空列并使用 `swiper` 横向分页;不引入参考项目的旧 `getGenealogyUserByParentsId` 接口。 +- 列结构为关系、姓名、资料三段纵向阅读;同世人员位于横向滚动容器,右侧切换上一世/下一世。 +- 静态合同、关系布局合同、人物操作合同和树接口运行时 smoke 均已通过。 + +final result: blocked + +--- + +# T01 树状图与 T02 世系谱:真机回归 + +## 对比对象 + +- Source visual truth:本次会话中用户提供的参考项目“世系谱”截图(408 × 936 px)及 `C:\Users\Administrator\Desktop\job\Jiapu-App\pages\index\tree\index.vue` 的交互实现。 +- Implementation captures:`C:\Users\Administrator\AppData\Local\Temp\t01-entry-verify.png`、`C:\Users\Administrator\AppData\Local\Temp\t02-entry-verify.png`、`C:\Users\Administrator\AppData\Local\Temp\t02-swipe-verify.png`、`C:\Users\Administrator\AppData\Local\Temp\t02-return-after-fix.png`。 +- Device/state:Android 模拟器 720 × 1280 px;真实家谱“界面大数据回归谱0726”;T01 树状图、T02 第 1/2 世。 + +## 真机交互验收 + +- T01 右上角“世系谱”可进入独立 T02 表格页;T02 右上角“树状图”可返回 T01 图谱页。 +- T02 从第 1 世直接左滑可切换到第 2 世,未使用点击箭头替代横向手势。 +- 点击姓名打开“成员档案”;点击下方生平文字读取人物详情并打开“人物生平”弹窗,两个命中区域和结果不同。 +- 返回失败的路由根因已修复:可选 `selectedId` 为空时不再传入 `undefined`,以符合导航参数必须为非空字符串的校验。 + +## 视觉核验状态 + +- 字体与排版、列格、纵向文字、朱红页头、右侧世代标识和背景纹理已在真机截图中检查。 +- 当前会话里的参考截图没有可供本地重新打开的原始文件路径,因此无法按同一画布把参考图与实现图合成后做逐像素并排对比;不对像素级一致性作虚假通过结论。 + +## Implementation Checklist + +- [x] 树状图与世系谱拆分为两个路由。 +- [x] 双向页头跳转与原生横向滑动。 +- [x] 姓名资料页与生平弹窗的分离点击行为。 +- [x] HBuilderX 页面诊断、静态路由合约和 Android 真机回归。 + +final result: blocked + +--- + +# T01 树状图与 T02 世系谱:设计核验 + +## 对比对象 + +- Source visual truth:用户本次会话提供的参考项目“世系谱”截图,以及 `C:\Users\Administrator\Desktop\job\Jiapu-App\pages\index\tree\index.vue` 的 `swiper` 实现。 +- Implementation capture:未生成。当前 HBuilderX CLI 未识别已连接模拟器作为可部署设备,无法取得包含新 T01/T02 路由的截图。 +- 目标状态:从“世系图”进入 T01 树状图;T01 顶部进入 T02 世系谱;T02 顶部返回 T01。 + +## 阻塞项 + +- [P0] 无法取得新版本的真机或浏览器实现截图,因此不能与参考截图进行同视口视觉比较,也不能把直接左右滑动标为已验收。 + - 已完成代码核验:T01 恢复横向树状图;T02 使用原生 `swiper` 和页内纵向 `scroll-view`,每页五位成员。 + - 需要:让 HBuilderX 识别任一已连接模拟器,或提供可运行的 H5 预览,以捕获两页入口和横滑状态。 + +final result: blocked diff --git a/genealogy-app-openapi.yaml b/genealogy-app-openapi.yaml new file mode 100644 index 0000000..af7c050 --- /dev/null +++ b/genealogy-app-openapi.yaml @@ -0,0 +1,4565 @@ +openapi: 3.0.3 +info: + title: Genealogy APP API + version: 1.0.0 + description: | + 家谱业务 APP/PC 用户侧接口文档,用于 Apifox 导入。 + + 导入方式:Apifox -> 导入 API 数据 -> OpenAPI/Swagger -> 选择本文件。 + + 约定: + - APP 路径前缀为 `/genealogy/app` + - PC/H5 路径前缀为 `/genealogy/pc` + - 后台管理接口不包含在本文件内 + - 登录后接口需要携带 token,且请求 Header 需携带 `clientid` +servers: + - url: http://127.0.0.1:8080 + description: Local Java backend + - url: http://127.0.0.1:9527/dev-api + description: Local frontend proxy +tags: + - name: 验证中心 + description: 统一验证码、天爱行为验证码和系统图形验证码 + - name: 认证登录 + description: APP/PC 登录注册与账号资料 + - name: 文件上传 + description: APP/PC 统一文件上传与业务引用绑定 + - name: 行政区划 + description: 行政区划 + - name: 家谱 + description: 家谱主体、加入申请与概览 + - name: 家谱成员 + description: 家谱成员 + - name: 字辈谱 + description: 字辈谱 + - name: 世系人物 + description: 世系人物与世系树 + - name: 家族圈 + description: 家族圈动态、点赞、评论 + - name: 内容文章 + description: 谱文、官网文章、帮助、推广 + - name: 相册 + description: 相册与照片 + - name: 视频 + description: 家谱视频 + - name: 祭祀 + description: 祭祀与献礼 + - name: 族务记录 + description: 成长、备忘、亲友、功德等记录 + - name: VIP + description: VIP 套餐与订单 + - name: 消息通知 + description: 消息通知 + - name: 意见反馈 + description: 意见反馈 +security: + - SaToken: [] +paths: + /genealogy/app/auth/verification/{operationCode}/require: + get: + tags: [验证中心] + summary: 查询 APP 认证动作是否需要验证 + description: 服务端按 operationCode 对应 APP 路由的当前激活绑定解析验证场景,前端不得提交 sceneCode。 + security: [] + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - name: operationCode + description: APP 认证业务动作 + in: path + required: true + schema: + type: string + enum: [password-login, sms-login, register, forgot-password, phone-change, account-deactivate] + - name: tenantId + description: 租户ID,用于区分不同租户的数据和验证策略 + in: query + required: true + schema: + type: string + example: "000000" + - name: subject + description: 验证主体,通常为手机号、用户ID或登录账号 + in: query + schema: + type: string + example: "13800000000" + responses: + '200': + $ref: '#/components/responses/VerificationRequireResult' + /genealogy/app/auth/verification/{operationCode}/challenge: + post: + tags: [验证中心] + summary: 生成 APP 认证动作验证挑战 + description: 服务端按 operationCode 的激活绑定解析场景。tenantId、subject 必须完整提交;clientid 仅从 Header 读取,前端不得提交 clientId 或 sceneCode。 + security: [] + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - name: operationCode + description: APP 认证业务动作 + in: path + required: true + schema: + type: string + enum: [password-login, sms-login, register, forgot-password, phone-change, account-deactivate] + requestBody: + $ref: '#/components/requestBodies/VerificationChallenge' + responses: + '200': + $ref: '#/components/responses/VerificationChallengeResult' + /genealogy/app/auth/verification/{operationCode}/verify: + post: + tags: [验证中心] + summary: 校验 APP 认证动作验证结果并换取 validToken + description: 必须使用生成挑战时相同的 operationCode、tenantId、subject 和 challengeId。clientid 仅从 Header 读取;服务端重新解析同一路由的激活场景,前端不得提交 clientId 或 sceneCode。 + security: [] + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - name: operationCode + description: APP 认证业务动作 + in: path + required: true + schema: + type: string + enum: [password-login, sms-login, register, forgot-password, phone-change, account-deactivate] + requestBody: + $ref: '#/components/requestBodies/VerificationCheck' + responses: + '200': + $ref: '#/components/responses/VerificationCheckResult' + /genealogy/app/auth/register: + post: + tags: [认证登录] + summary: APP 用户注册 + security: [] + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + requestBody: + $ref: '#/components/requestBodies/PasswordRegister' + responses: + '200': + $ref: '#/components/responses/LoginResult' + '400': + description: 短信验证码必须为 4 位数字;验证码错误、过期、重复使用,或租户、客户端、场景不匹配时拒绝;携带 validToken、code、uuid、供应商配置等旧字段返回 HTTP 400。 + content: + application/json: + schema: + $ref: '#/components/schemas/RVoid' + /genealogy/app/auth/login: + post: + tags: [认证登录] + summary: APP 密码登录 + security: [] + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + requestBody: + $ref: '#/components/requestBodies/PasswordLogin' + responses: + '200': + $ref: '#/components/responses/LoginResult' + '400': + description: 后端按 APP_PASSWORD_LOGIN 路由的当前激活绑定解析场景;该场景策略要求验证时必须提交匹配的 validToken,不要求验证时 validToken 可为空;请求携带已废弃的 sceneCode 或其他未知字段返回 HTTP 400。 + content: + application/json: + schema: + $ref: '#/components/schemas/RVoid' + /genealogy/app/auth/login/sms: + post: + tags: [认证登录] + summary: APP 短信登录 + security: [] + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + requestBody: + $ref: '#/components/requestBodies/SmsLogin' + responses: + '200': + $ref: '#/components/responses/LoginResult' + '400': + description: 短信验证码必须为 4 位数字;验证码错误、过期、重复使用,或租户、客户端、场景不匹配时拒绝;携带 validToken、code、uuid、供应商配置等旧字段返回 HTTP 400。 + content: + application/json: + schema: + $ref: '#/components/schemas/RVoid' + /genealogy/app/auth/sms/{operationCode}/code: + post: + tags: [认证登录] + summary: APP 发送短信验证码 + description: operationCode 决定短信业务动作,服务端按对应 APP 路由的激活绑定解析验证场景。策略开启时需提交 validToken,关闭时可为空;前端不得提交 sceneCode 或短信供应商配置 ID。 + security: [] + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - name: operationCode + description: 支持发送短信验证码的 APP 认证业务动作 + in: path + required: true + schema: + type: string + enum: [sms-login, register, forgot-password, phone-change, account-deactivate] + requestBody: + $ref: '#/components/requestBodies/SmsCode' + responses: + '200': + $ref: '#/components/responses/VoidResult' + '400': + description: 拒绝原因:票据缺失;票据与租户不匹配(错租户);票据与客户端不匹配(错客户端);票据与场景不匹配(错场景);票据过期;票据已被使用(重复使用);手机号主体不匹配;请求携带供应商配置或历史字段。 + content: + application/json: + schema: + $ref: '#/components/schemas/RVoid' + /genealogy/app/auth/profile: + get: + tags: [认证登录] + summary: APP 当前用户资料 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + put: + tags: [认证登录] + summary: APP 修改用户资料 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + requestBody: + $ref: '#/components/requestBodies/ProfileUpdate' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/auth/password: + put: + tags: [认证登录] + summary: APP 修改密码 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + requestBody: + $ref: '#/components/requestBodies/PasswordChange' + responses: + '200': + $ref: '#/components/responses/VoidResult' + /genealogy/app/auth/password/reset: + put: + tags: [认证登录] + summary: APP 找回密码 + security: [] + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + requestBody: + $ref: '#/components/requestBodies/PasswordReset' + responses: + '200': + $ref: '#/components/responses/VoidResult' + '400': + description: 短信验证码必须为 4 位数字;验证码错误、过期、重复使用,或租户、客户端、场景不匹配时拒绝;携带 validToken、code、uuid、供应商配置等旧字段返回 HTTP 400。 + content: + application/json: + schema: + $ref: '#/components/schemas/RVoid' + /genealogy/app/auth/phone: + put: + tags: [认证登录] + summary: APP 换绑手机号 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + requestBody: + $ref: '#/components/requestBodies/PhoneChange' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + '400': + description: 短信验证码必须为 4 位数字;验证码错误、过期、重复使用,或租户、客户端、场景不匹配时拒绝;携带 validToken、code、uuid、供应商配置等旧字段返回 HTTP 400。 + content: + application/json: + schema: + $ref: '#/components/schemas/RVoid' + /genealogy/app/auth/account/deactivate: + post: + tags: [认证登录] + summary: APP 注销账号 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + requestBody: + $ref: '#/components/requestBodies/AccountDeactivate' + responses: + '200': + $ref: '#/components/responses/VoidResult' + '400': + description: 短信验证码必须为 4 位数字;验证码错误、过期、重复使用,或租户、客户端、场景不匹配时拒绝;携带 validToken、code、uuid、供应商配置等旧字段返回 HTTP 400。 + content: + application/json: + schema: + $ref: '#/components/schemas/RVoid' + /genealogy/app/auth/logout: + delete: + tags: [认证登录] + summary: APP 退出登录 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + responses: + '200': + $ref: '#/components/responses/VoidResult' + + /genealogy/app/files/resumable/init: + post: + tags: [文件上传] + summary: APP 分片上传初始化 + description: 所有文件统一使用分片上传;普通小文件可设置为一个分片。返回 instant=true 时直接使用返回的 OSS 信息,跳过分片上传和合并。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + requestBody: + $ref: '#/components/requestBodies/ResumableInit' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/files/resumable/chunk: + post: + tags: [文件上传] + summary: APP 上传分片 + description: uploadId 已绑定初始化契约。除最后一片外,分片实际大小必须等于 chunkSize;最后一片必须等于剩余字节数。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + requestBody: + $ref: '#/components/requestBodies/ChunkUpload' + responses: + '200': + $ref: '#/components/responses/VoidResult' + /genealogy/app/files/resumable/complete: + post: + tags: [文件上传] + summary: APP 完成分片上传 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + requestBody: + $ref: '#/components/requestBodies/ResumableComplete' + responses: + '200': + $ref: '#/components/responses/FileUploadResult' + /genealogy/app/region/children: + get: + tags: [行政区划] + summary: 查询下级行政区划 + security: [] + parameters: + - name: parentCode + description: 父级行政区划编码,不传或传0查省级 + in: query + required: false + schema: + type: string + example: "51" + responses: + '200': + $ref: '#/components/responses/ListResult' + /genealogy/app/region/path/{regionCode}: + get: + tags: [行政区划] + summary: 查询行政区划路径 + security: [] + parameters: + - $ref: '#/components/parameters/RegionCode' + responses: + '200': + $ref: '#/components/responses/ListResult' + /genealogy/app/region/search: + get: + tags: [行政区划] + summary: 搜索行政区划 + security: [] + parameters: + - name: keyword + description: 搜索关键词,支持地区名称或编码模糊查询 + in: query + required: true + schema: + type: string + example: 北京 + - name: level + description: 行政区划级别,1省、2市、3区县、4乡镇街道、5村社区 + in: query + required: false + schema: + type: integer + example: 3 + - name: limit + description: 返回数量上限 + in: query + required: false + schema: + type: integer + example: 20 + responses: + '200': + $ref: '#/components/responses/ListResult' + /genealogy/app/region/{regionCode}: + get: + tags: [行政区划] + summary: 查询行政区划详情 + security: [] + parameters: + - $ref: '#/components/parameters/RegionCode' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/site/articles: + get: + tags: [官网内容] + summary: APP 查询官网文章 + security: [] + parameters: + - name: articleType + description: 文章类型,不传则查询全部已发布文章 + in: query + required: false + schema: { type: string } + - name: limit + description: 返回数量上限 + in: query + required: false + schema: { type: integer } + responses: + '200': { $ref: '#/components/responses/ListResult' } + /genealogy/app/site/pages/{pageKey}: + get: + tags: [官网内容] + summary: APP 查询官网单页 + security: [] + parameters: + - name: pageKey + description: 单页唯一标识 + in: path + required: true + schema: { type: string } + responses: + '200': { $ref: '#/components/responses/ObjectResult' } + + /genealogy/app/genealogies: + post: + tags: [家谱] + summary: APP 创建家谱 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + requestBody: + $ref: '#/components/requestBodies/GenealogyCreate' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/genealogies/mine: + get: + tags: [家谱] + summary: APP 我的家谱 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + responses: + '200': + $ref: '#/components/responses/ListResult' + /genealogy/app/genealogies/quota: + get: + tags: [家谱] + summary: APP 查询当前用户家谱配额 + description: 查询已创建和已加入的家谱数量、上限、剩余额度及是否还能继续操作。加入总数包含自己创建的家谱;limit 和 remaining 为 -1 时表示不限。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + responses: + '200': + $ref: '#/components/responses/GenealogyQuotaResult' + /genealogy/app/genealogies/public: + get: + tags: [家谱] + summary: APP 公开家谱 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + responses: + '200': + $ref: '#/components/responses/ListResult' + /genealogy/app/genealogies/options: + get: + tags: [家谱] + summary: APP 家谱下拉选项 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + responses: + '200': + $ref: '#/components/responses/ListResult' + /genealogy/app/genealogies/{genealogyId}: + get: + tags: [家谱] + summary: APP 家谱详情 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + put: + tags: [家谱] + summary: APP 修改家谱 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + requestBody: + $ref: '#/components/requestBodies/GenealogyUpdate' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/genealogies/{genealogyId}/overview: + get: + tags: [家谱] + summary: APP 家谱概览 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/genealogies/{genealogyId}/join-applies: + post: + tags: [家谱] + summary: APP 申请加入家谱 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + requestBody: + $ref: '#/components/requestBodies/GenealogyJoinApply' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/genealogies/join-applies/mine: + get: + tags: [家谱] + summary: APP 我的加入申请 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + responses: + '200': + $ref: '#/components/responses/ListResult' + /genealogy/app/genealogies/{genealogyId}/join-applies/pending: + get: + tags: [家谱] + summary: APP 待审核加入申请 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/ListResult' + /genealogy/app/genealogies/{genealogyId}/join-applies/{applyId}/audit: + put: + tags: [家谱] + summary: APP 审核加入申请 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: applyId + description: 加入家谱申请ID + in: path + required: true + schema: + type: integer + format: int64 + requestBody: + $ref: '#/components/requestBodies/GenealogyJoinAudit' + responses: + '200': + $ref: '#/components/responses/VoidResult' + /genealogy/app/genealogies/join-applies/{applyId}: + delete: + tags: [家谱] + summary: APP 撤销加入申请 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - name: applyId + description: 加入家谱申请ID + in: path + required: true + schema: + type: integer + format: int64 + responses: + '200': + $ref: '#/components/responses/VoidResult' + + /genealogy/app/genealogies/{genealogyId}/members: + get: + tags: [家谱成员] + summary: APP 家谱成员列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/ListResult' + /genealogy/app/genealogies/{genealogyId}/members/options: + get: + tags: [家谱成员] + summary: APP 家谱成员选项 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/ListResult' + /genealogy/app/genealogies/{genealogyId}/members/{memberId}: + put: + tags: [家谱成员] + summary: APP 修改成员 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/MemberId' + requestBody: + $ref: '#/components/requestBodies/GenealogyMemberUpdate' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + delete: + tags: [家谱成员] + summary: APP 移除成员 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/MemberId' + responses: + '200': + $ref: '#/components/responses/VoidResult' + /genealogy/app/genealogies/{genealogyId}/members/me: + delete: + tags: [家谱成员] + summary: APP 退出家谱 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/VoidResult' + /genealogy/app/genealogies/{genealogyId}/members/owner-transfer: + put: + tags: [家谱成员] + summary: APP 转让家谱所有者 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + requestBody: + $ref: '#/components/requestBodies/GenealogyOwnerTransfer' + responses: + '200': + $ref: '#/components/responses/VoidResult' + + /genealogy/app/genealogies/{genealogyId}/generation-poems: + get: + tags: [字辈谱] + summary: APP 查询正常字辈谱 + description: 对可查看家谱的业务用户开放;仅返回正常状态字辈,供世系人物录入和展示使用。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/GenerationPoemListResult' + post: + tags: [字辈谱] + summary: APP 新增字辈 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + requestBody: + $ref: '#/components/requestBodies/GenerationPoem' + responses: + '200': + $ref: '#/components/responses/GenerationPoemResult' + /genealogy/app/genealogies/{genealogyId}/generation-poems/management: + get: + tags: [字辈谱] + summary: APP 查询字辈维护列表 + description: 仅家谱内容编辑者可访问,返回正常和停用字辈,用于恢复、纠错和排序调整。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/GenerationPoemListResult' + /genealogy/app/genealogies/{genealogyId}/generation-poems/batch/preview: + post: + tags: [字辈谱] + summary: APP 批量字辈预览 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + requestBody: + $ref: '#/components/requestBodies/GenerationPoemBatch' + responses: + '200': + $ref: '#/components/responses/GenerationPoemBatchPreviewResult' + /genealogy/app/genealogies/{genealogyId}/generation-poems/batch/save: + post: + tags: [字辈谱] + summary: APP 批量保存字辈 + description: 保存时会重新按当前数据生成差异;停用不删除历史字辈记录。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + requestBody: + $ref: '#/components/requestBodies/GenerationPoemBatch' + responses: + '200': + $ref: '#/components/responses/VoidResult' + /genealogy/app/genealogies/{genealogyId}/generation-poems/{poemId}: + put: + tags: [字辈谱] + summary: APP 修改、停用或恢复字辈 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: poemId + description: 字辈记录ID + in: path + required: true + schema: + type: integer + format: int64 + requestBody: + $ref: '#/components/requestBodies/GenerationPoem' + responses: + '200': + $ref: '#/components/responses/GenerationPoemResult' + + /genealogy/app/genealogies/{genealogyId}/lineage/persons: + get: + tags: [世系人物] + summary: APP 世系人物列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/LineagePersonListResult' + post: + tags: [世系人物] + summary: APP 新增世系人物 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + requestBody: + $ref: '#/components/requestBodies/LineagePerson' + responses: + '200': + $ref: '#/components/responses/LineagePersonResult' + /genealogy/app/genealogies/{genealogyId}/lineage/persons/page: + get: + tags: [世系人物] + summary: APP 世系人物分页 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/PageNum' + - $ref: '#/components/parameters/PageSize' + - name: keyword + description: 姓名、别名或人物编号关键词 + in: query + required: false + schema: + type: string + - name: generation + description: 世代序号 + in: query + required: false + schema: + type: integer + format: int64 + - name: personStatus + description: "字典 gen_lineage_person_status:0=健在,1=已故,2=未知" + in: query + required: false + schema: + type: string + enum: ["0", "1", "2"] + example: "0" + x-dict-type: gen_lineage_person_status + responses: + '200': + $ref: '#/components/responses/LineagePersonPageResult' + /genealogy/app/genealogies/{genealogyId}/lineage/persons/options: + get: + tags: [世系人物] + summary: APP 世系人物选项 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: keyword + description: 姓名、别名或人物编号关键词 + in: query + required: false + schema: + type: string + responses: + '200': + $ref: '#/components/responses/LineagePersonListResult' + /genealogy/app/genealogies/{genealogyId}/lineage/tree: + get: + tags: [世系人物] + summary: APP 世系树 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/LineagePersonTreeResult' + /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}: + get: + tags: [世系人物] + summary: APP 世系人物详情 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/PersonId' + responses: + '200': + $ref: '#/components/responses/LineagePersonResult' + put: + tags: [世系人物] + summary: APP 修改世系人物 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/PersonId' + requestBody: + $ref: '#/components/requestBodies/LineagePerson' + responses: + '200': + $ref: '#/components/responses/LineagePersonResult' + delete: + tags: [世系人物] + summary: APP 停用世系人物 + description: 逻辑停用人物,不执行物理删除;存在正常子女时拒绝停用。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/PersonId' + responses: + '200': + $ref: '#/components/responses/VoidResult' + /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/children: + post: + tags: [世系人物] + summary: APP 给人物添加子女 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/PersonId' + requestBody: + $ref: '#/components/requestBodies/LineagePerson' + responses: + '200': + $ref: '#/components/responses/LineagePersonResult' + /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/parents: + post: + tags: [世系人物] + summary: APP 给人物添加父母 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/PersonId' + requestBody: + $ref: '#/components/requestBodies/LineagePerson' + responses: + '200': + $ref: '#/components/responses/LineagePersonResult' + /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/siblings: + post: + tags: [世系人物] + summary: APP 给人物添加兄弟姐妹 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/PersonId' + requestBody: + $ref: '#/components/requestBodies/LineagePerson' + responses: + '200': + $ref: '#/components/responses/LineagePersonResult' + /genealogy/app/genealogies/{genealogyId}/lineage/persons/{personId}/spouses: + post: + tags: [世系人物] + summary: APP 给人物添加配偶 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/PersonId' + requestBody: + $ref: '#/components/requestBodies/LineagePerson' + responses: + '200': + $ref: '#/components/responses/LineagePersonResult' + + /genealogy/app/genealogies/{genealogyId}/feeds: + get: + tags: [家族圈] + summary: APP 家族圈动态列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/FamilyFeedListResult' + post: + tags: [家族圈] + summary: APP 发布家族圈动态 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + requestBody: + $ref: '#/components/requestBodies/FamilyFeed' + responses: + '200': + $ref: '#/components/responses/FamilyFeedResult' + /genealogy/app/genealogies/{genealogyId}/feeds/page: + get: + tags: [家族圈] + summary: APP 家族圈动态分页 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/PageNum' + - $ref: '#/components/parameters/PageSize' + responses: + '200': + $ref: '#/components/responses/FamilyFeedPageResult' + /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}: + get: + tags: [家族圈] + summary: APP 家族圈动态详情 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/FeedId' + responses: + '200': + $ref: '#/components/responses/FamilyFeedResult' + put: + tags: [家族圈] + summary: APP 修改家族圈动态 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/FeedId' + requestBody: + $ref: '#/components/requestBodies/FamilyFeed' + responses: + '200': + $ref: '#/components/responses/FamilyFeedResult' + delete: + tags: [家族圈] + summary: APP 删除家族圈动态 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/FeedId' + responses: + '200': + $ref: '#/components/responses/VoidResult' + /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/likes: + post: + tags: [家族圈] + summary: APP 点赞动态 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/FeedId' + responses: + '200': + $ref: '#/components/responses/VoidResult' + delete: + tags: [家族圈] + summary: APP 取消点赞动态 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/FeedId' + responses: + '200': + $ref: '#/components/responses/VoidResult' + /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments: + get: + tags: [家族圈] + summary: APP 动态一级评论列表 + description: 仅返回正常展示的一级评论;每条评论的 replyCount 为正常展示的直接回复数量。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/FeedId' + responses: + '200': + $ref: '#/components/responses/FamilyFeedCommentListResult' + post: + tags: [家族圈] + summary: APP 评论动态 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/FeedId' + requestBody: + $ref: '#/components/requestBodies/FamilyFeedComment' + responses: + '200': + $ref: '#/components/responses/FamilyFeedCommentResult' + /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments/page: + get: + tags: [家族圈] + summary: APP 动态一级评论分页 + description: 仅返回正常展示的一级评论;展开回复时请调用 replies 接口。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/FeedId' + - $ref: '#/components/parameters/PageNum' + - $ref: '#/components/parameters/PageSize' + responses: + '200': + $ref: '#/components/responses/FamilyFeedCommentPageResult' + /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments/{commentId}/replies: + get: + tags: [家族圈] + summary: APP 获取评论的直接回复列表 + description: 仅返回指定正常评论的正常展示直接回复;回复的 replyCount 可用于继续按需展开下一层。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/FeedId' + - name: commentId + description: 父评论 ID + in: path + required: true + schema: + type: integer + format: int64 + responses: + '200': + $ref: '#/components/responses/FamilyFeedCommentListResult' + /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments/{commentId}/replies/page: + get: + tags: [家族圈] + summary: APP 分页获取评论的直接回复 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/FeedId' + - name: commentId + description: 父评论 ID + in: path + required: true + schema: + type: integer + format: int64 + - $ref: '#/components/parameters/PageNum' + - $ref: '#/components/parameters/PageSize' + responses: + '200': + $ref: '#/components/responses/FamilyFeedCommentPageResult' + /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments/{commentId}: + delete: + tags: [家族圈] + summary: APP 删除本人动态评论;有回复时保留删除占位 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - $ref: '#/components/parameters/FeedId' + - name: commentId + description: 评论ID + in: path + required: true + schema: + type: integer + format: int64 + responses: + '200': + $ref: '#/components/responses/VoidResult' + + /genealogy/app/genealogies/{genealogyId}/article-categories: + get: + tags: [内容文章] + summary: APP 谱文分类 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/ListResult' + /genealogy/app/genealogies/{genealogyId}/articles: + get: + tags: [内容文章] + summary: APP 谱文列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/ListResult' + post: + tags: [内容文章] + summary: APP 新增谱文 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + requestBody: + $ref: '#/components/requestBodies/Article' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/genealogies/{genealogyId}/articles/{articleId}: + get: + tags: [内容文章] + summary: APP 谱文详情 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: articleId + description: 谱文/官网文章ID + in: path + required: true + schema: + type: integer + format: int64 + responses: + '200': + $ref: '#/components/responses/ObjectResult' + put: + tags: [内容文章] + summary: APP 修改谱文 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: articleId + description: 谱文/官网文章ID + in: path + required: true + schema: + type: integer + format: int64 + requestBody: + $ref: '#/components/requestBodies/Article' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + delete: + tags: [内容文章] + summary: APP 删除谱文 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: articleId + description: 要删除的谱文ID + in: path + required: true + schema: { type: integer, format: int64 } + responses: + '200': { $ref: '#/components/responses/VoidResult' } + /genealogy/app/help-articles: + get: + tags: [内容文章] + summary: APP 帮助文章列表 + security: [] + responses: + '200': + $ref: '#/components/responses/ListResult' + /genealogy/app/help-articles/{helpId}: + get: + tags: [内容文章] + summary: APP 帮助文章详情 + security: [] + parameters: + - name: helpId + description: 帮助文章ID + in: path + required: true + schema: + type: integer + format: int64 + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/promotions: + get: + tags: [内容文章] + summary: APP 应用推广列表 + security: [] + responses: + '200': + $ref: '#/components/responses/ListResult' + + /genealogy/app/genealogies/{genealogyId}/albums: + get: + tags: [相册] + summary: APP 相册列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/ListResult' + post: + tags: [相册] + summary: APP 创建相册 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + requestBody: + $ref: '#/components/requestBodies/Album' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/genealogies/{genealogyId}/albums/{albumId}: + put: + tags: [相册] + summary: APP 修改相册 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: albumId + description: 相册ID + in: path + required: true + schema: + type: integer + format: int64 + requestBody: + $ref: '#/components/requestBodies/Album' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + delete: + tags: [相册] + summary: APP 删除相册 + description: 逻辑删除相册及其照片,并释放封面和照片文件引用。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: albumId + description: 要删除的相册ID + in: path + required: true + schema: { type: integer, format: int64 } + responses: + '200': { $ref: '#/components/responses/VoidResult' } + /genealogy/app/genealogies/{genealogyId}/albums/{albumId}/photos: + get: + tags: [相册] + summary: APP 相册图片列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: albumId + description: 相册ID + in: path + required: true + schema: + type: integer + format: int64 + responses: + '200': + $ref: '#/components/responses/ListResult' + post: + tags: [相册] + summary: APP 上传相册图片记录 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: albumId + description: 相册ID + in: path + required: true + schema: + type: integer + format: int64 + requestBody: + $ref: '#/components/requestBodies/AlbumPhoto' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/genealogies/{genealogyId}/albums/{albumId}/photos/{photoId}: + delete: + tags: [相册] + summary: APP 删除单张相册图片 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: albumId + description: 相册ID + in: path + required: true + schema: { type: integer, format: int64 } + - name: photoId + description: 要删除的相册图片ID + in: path + required: true + schema: { type: integer, format: int64 } + responses: + '200': { $ref: '#/components/responses/VoidResult' } + + /genealogy/app/genealogies/{genealogyId}/videos: + get: + tags: [视频] + summary: APP 视频列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': { $ref: '#/components/responses/ListResult' } + post: + tags: [视频] + summary: APP 新增视频 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + requestBody: + $ref: '#/components/requestBodies/Video' + responses: + '200': { $ref: '#/components/responses/ObjectResult' } + /genealogy/app/genealogies/{genealogyId}/videos/{videoId}: + get: + tags: [视频] + summary: APP 视频详情 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: videoId + description: 视频ID + in: path + required: true + schema: { type: integer, format: int64 } + responses: + '200': { $ref: '#/components/responses/ObjectResult' } + put: + tags: [视频] + summary: APP 修改视频 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: videoId + description: 视频ID + in: path + required: true + schema: { type: integer, format: int64 } + requestBody: + $ref: '#/components/requestBodies/Video' + responses: + '200': { $ref: '#/components/responses/ObjectResult' } + delete: + tags: [视频] + summary: APP 删除视频 + description: 逻辑删除视频,并释放视频文件和封面文件引用。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: videoId + description: 要删除的视频ID + in: path + required: true + schema: { type: integer, format: int64 } + responses: + '200': { $ref: '#/components/responses/VoidResult' } + + /genealogy/app/genealogies/{genealogyId}/ceremonies: + get: + tags: [祭祀] + summary: APP 祭祀列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/ListResult' + post: + tags: [祭祀] + summary: APP 创建祭祀 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + requestBody: + $ref: '#/components/requestBodies/Ceremony' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}: + get: + tags: [祭祀] + summary: APP 祭祀详情 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: ceremonyId + description: 祭祀/活动ID + in: path + required: true + schema: + type: integer + format: int64 + responses: + '200': + $ref: '#/components/responses/ObjectResult' + delete: + tags: [祭祀] + summary: APP 删除祭祀活动 + description: 逻辑删除祭祀活动及其祭品,并释放活动封面文件引用。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: ceremonyId + description: 要删除的祭祀活动ID + in: path + required: true + schema: { type: integer, format: int64 } + responses: + '200': { $ref: '#/components/responses/VoidResult' } + put: + tags: [祭祀] + summary: APP 修改祭祀 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: ceremonyId + description: 祭祀/活动ID + in: path + required: true + schema: + type: integer + format: int64 + requestBody: + $ref: '#/components/requestBodies/Ceremony' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}/gifts: + get: + tags: [祭祀] + summary: APP 祭祀献礼列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: ceremonyId + description: 祭祀/活动ID + in: path + required: true + schema: + type: integer + format: int64 + responses: + '200': + $ref: '#/components/responses/ListResult' + post: + tags: [祭祀] + summary: APP 新增祭祀献礼 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: ceremonyId + description: 祭祀/活动ID + in: path + required: true + schema: + type: integer + format: int64 + requestBody: + $ref: '#/components/requestBodies/CeremonyGift' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}/gifts/{giftId}: + delete: + tags: [祭祀] + summary: APP 删除单条祭品 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: ceremonyId + description: 祭祀活动ID + in: path + required: true + schema: { type: integer, format: int64 } + - name: giftId + description: 要删除的祭品ID + in: path + required: true + schema: { type: integer, format: int64 } + responses: + '200': { $ref: '#/components/responses/VoidResult' } + + /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}/invitees: + put: + tags: [贺礼邀约] + summary: APP 替换活动受邀人 + description: 使用完整名单替换当前待响应受邀人;仅家谱内容管理员可操作,受邀人必须是同一家谱的正常成员。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - { name: ceremonyId, description: 贺礼活动ID, in: path, required: true, schema: { type: integer, format: int64 } } + requestBody: + $ref: '#/components/requestBodies/CeremonyInvitees' + responses: + '200': { $ref: '#/components/responses/CeremonyInvitationListResult' } + /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}/invitations: + get: + tags: [贺礼邀约] + summary: APP 查询活动邀请名单 + description: 查询受邀人及其待响应、接受、拒绝或取消状态,仅家谱内容管理员可见。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - { name: ceremonyId, description: 贺礼活动ID, in: path, required: true, schema: { type: integer, format: int64 } } + responses: + '200': { $ref: '#/components/responses/CeremonyInvitationListResult' } + /genealogy/app/genealogies/{genealogyId}/ceremonies/{ceremonyId}/invitations/me: + put: + tags: [贺礼邀约] + summary: APP 响应当前用户的活动邀请 + description: 当前登录用户接受或拒绝自己的待响应邀请,不能代替其他用户操作。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - { name: ceremonyId, description: 贺礼活动ID, in: path, required: true, schema: { type: integer, format: int64 } } + requestBody: + $ref: '#/components/requestBodies/CeremonyInvitationResponse' + responses: + '200': { $ref: '#/components/responses/CeremonyInvitationResult' } + /genealogy/app/genealogies/ceremony-invitations/mine: + get: + tags: [贺礼邀约] + summary: APP 查询我的活动邀请 + description: 查询当前租户下发给当前业务用户且活动仍正常的邀请。 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + responses: + '200': { $ref: '#/components/responses/CeremonyInvitationListResult' } + + /genealogy/app/genealogies/{genealogyId}/growth-records: + get: + tags: [族务记录] + summary: APP 成长记录列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/ListResult' + post: + tags: [族务记录] + summary: APP 新增成长记录 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + requestBody: + $ref: '#/components/requestBodies/GrowthRecord' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/genealogies/{genealogyId}/growth-records/{recordId}: + get: + tags: [族务记录] + summary: APP 成长记录详情 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: recordId + description: 记录ID + in: path + required: true + schema: + type: integer + format: int64 + responses: + '200': + $ref: '#/components/responses/ObjectResult' + delete: + tags: [族务记录] + summary: APP 删除成长记录 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: recordId + description: 要删除的成长记录ID + in: path + required: true + schema: { type: integer, format: int64 } + responses: + '200': { $ref: '#/components/responses/VoidResult' } + put: + tags: [族务记录] + summary: APP 修改成长记录 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: recordId + description: 记录ID + in: path + required: true + schema: + type: integer + format: int64 + requestBody: + $ref: '#/components/requestBodies/GrowthRecord' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/genealogies/{genealogyId}/memos: + get: + tags: [族务记录] + summary: APP 备忘录列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/ListResult' + post: + tags: [族务记录] + summary: APP 新增备忘录 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + requestBody: + $ref: '#/components/requestBodies/Memo' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/genealogies/{genealogyId}/memos/{memoId}: + get: + tags: [族务记录] + summary: APP 备忘录详情 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: memoId + in: path + required: true + schema: + type: integer + format: int64 + responses: + '200': + $ref: '#/components/responses/ObjectResult' + delete: + tags: [族务记录] + summary: APP 删除备忘录 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: memoId + description: 要删除的备忘录ID + in: path + required: true + schema: { type: integer, format: int64 } + responses: + '200': { $ref: '#/components/responses/VoidResult' } + put: + tags: [族务记录] + summary: APP 修改备忘录 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: memoId + in: path + required: true + schema: + type: integer + format: int64 + requestBody: + $ref: '#/components/requestBodies/Memo' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + + /genealogy/app/genealogies/{genealogyId}/relative-records: + get: + tags: [族务记录] + summary: APP 亲友记录列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': { $ref: '#/components/responses/ListResult' } + post: + tags: [族务记录] + summary: APP 新增亲友记录 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + requestBody: + $ref: '#/components/requestBodies/RelativeRecord' + responses: + '200': { $ref: '#/components/responses/ObjectResult' } + /genealogy/app/genealogies/{genealogyId}/relative-records/{relativeId}: + get: + tags: [族务记录] + summary: APP 亲友记录详情 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - { name: relativeId, description: 亲友记录ID, in: path, required: true, schema: { type: integer, format: int64 } } + responses: + '200': { $ref: '#/components/responses/ObjectResult' } + put: + tags: [族务记录] + summary: APP 修改亲友记录 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - { name: relativeId, description: 亲友记录ID, in: path, required: true, schema: { type: integer, format: int64 } } + requestBody: + $ref: '#/components/requestBodies/RelativeRecord' + responses: + '200': { $ref: '#/components/responses/ObjectResult' } + delete: + tags: [族务记录] + summary: APP 删除亲友记录 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: relativeId + description: 要删除的亲友记录ID + in: path + required: true + schema: { type: integer, format: int64 } + responses: + '200': { $ref: '#/components/responses/VoidResult' } + /genealogy/app/genealogies/{genealogyId}/merit-records: + get: + tags: [族务记录] + summary: APP 功德记录列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + responses: + '200': + $ref: '#/components/responses/ListResult' + post: + tags: [族务记录] + summary: APP 新增功德记录 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + requestBody: + $ref: '#/components/requestBodies/MeritRecord' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + /genealogy/app/genealogies/{genealogyId}/merit-records/{meritId}: + get: + tags: [族务记录] + summary: APP 功德记录详情 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: meritId + description: 功德记录ID + in: path + required: true + schema: { type: integer, format: int64 } + responses: + '200': { $ref: '#/components/responses/ObjectResult' } + put: + tags: [族务记录] + summary: APP 修改功德记录 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: meritId + description: 功德记录ID + in: path + required: true + schema: { type: integer, format: int64 } + requestBody: + $ref: '#/components/requestBodies/MeritRecord' + responses: + '200': { $ref: '#/components/responses/ObjectResult' } + delete: + tags: [族务记录] + summary: APP 删除功德记录 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - $ref: '#/components/parameters/GenealogyId' + - name: meritId + description: 要删除的功德记录ID + in: path + required: true + schema: { type: integer, format: int64 } + responses: + '200': { $ref: '#/components/responses/VoidResult' } + + /genealogy/app/notifications: + get: + tags: [消息通知] + summary: APP 消息通知列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - name: readStatus + description: "字典 gen_notification_read_status:0=未读,1=已读;不传则查询全部" + in: query + required: false + schema: + type: string + enum: ['0', '1'] + example: "0" + x-dict-type: gen_notification_read_status + responses: + '200': + $ref: '#/components/responses/ListResult' + /genealogy/app/notifications/{notificationId}: + get: + tags: [消息通知] + summary: APP 消息通知详情 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - name: notificationId + description: 通知ID + in: path + required: true + schema: + type: integer + format: int64 + responses: + '200': + $ref: '#/components/responses/NotificationResult' + /genealogy/app/notifications/{notificationId}/read: + post: + tags: [消息通知] + summary: APP 标记通知已读 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + - name: notificationId + description: 通知ID + in: path + required: true + schema: + type: integer + format: int64 + responses: + '200': + $ref: '#/components/responses/VoidResult' + /genealogy/app/notifications/unread-count: + get: + tags: [消息通知] + summary: APP 查询未读通知数量 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + responses: + '200': + $ref: '#/components/responses/LongResult' + /genealogy/app/notifications/read-all: + post: + tags: [消息通知] + summary: APP 全部标记已读 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + responses: + '200': + $ref: '#/components/responses/VoidResult' + /genealogy/app/feedback: + get: + tags: [意见反馈] + summary: APP 我的反馈列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + responses: + '200': + $ref: '#/components/responses/ListResult' + post: + tags: [意见反馈] + summary: APP 提交反馈 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + requestBody: + $ref: '#/components/requestBodies/Feedback' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + + /genealogy/app/vip/packages: + get: + tags: [VIP] + summary: APP VIP 套餐列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + responses: + '200': + $ref: '#/components/responses/ListResult' + /genealogy/app/vip/orders: + get: + tags: [VIP] + summary: APP VIP 订单列表 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + responses: + '200': + $ref: '#/components/responses/ListResult' + post: + tags: [VIP] + summary: APP 创建 VIP 订单 + parameters: + - $ref: '#/components/parameters/ClientIdHeader' + requestBody: + $ref: '#/components/requestBodies/VipOrder' + responses: + '200': + $ref: '#/components/responses/ObjectResult' + +components: + securitySchemes: + SaToken: + type: apiKey + in: header + name: Authorization + description: 登录后返回的 token。若本地配置使用 sa-token 名称,请按项目实际 token-name 调整。 + parameters: + ClientIdHeader: + name: clientid + description: APP 认证业务请求的 clientid Header 必填;是业务客户端唯一来源;请求体不得提交 clientId,且客户端 clientKey 必须为 app 并与 APP 路由一致。 + in: header + required: true + schema: + type: string + example: 428a8310cd442757ae699df5d894f051 + PageNum: + name: pageNum + description: 页码,从1开始 + in: query + required: false + schema: + type: integer + default: 1 + PageSize: + name: pageSize + description: 每页条数 + in: query + required: false + schema: + type: integer + default: 10 + GenealogyId: + name: genealogyId + description: 家谱ID + in: path + required: true + schema: + type: integer + format: int64 + example: 900001001 + MemberId: + name: memberId + description: 家谱成员ID + in: path + required: true + schema: + type: integer + format: int64 + PersonId: + name: personId + description: 世系人物ID + in: path + required: true + schema: + type: integer + format: int64 + FeedId: + name: feedId + description: 家族动态ID + in: path + required: true + schema: + type: integer + format: int64 + RegionCode: + name: regionCode + description: 行政区划编码 + in: path + required: true + schema: + type: string + example: "510000" + requestBodies: + JsonObject: + required: true + content: + application/json: + schema: + type: object + additionalProperties: true + PasswordRegister: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordRegisterBody' + example: + grantType: "password" + tenantId: "000000" + phone: "13800000000" + password: "e10adc3949ba59abbe56e057f20f883e" + nickName: "测试用户" + registerSource: "app" + smsCode: "1234" + PasswordLogin: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordLoginBody' + example: + grantType: "password" + tenantId: "000000" + phone: "13800000000" + password: "e10adc3949ba59abbe56e057f20f883e" + validToken: "valid-token-from-captcha-verify" + SmsLogin: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SmsLoginBody' + example: + grantType: "sms" + tenantId: "000000" + phone: "13800000000" + smsCode: "1234" + SmsCode: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SmsCodeBody' + example: + tenantId: "000000" + phone: "13800000000" + grantType: "sms" + validToken: "captcha-ticket" + ProfileUpdate: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileUpdateBody' + example: + nickName: "张三" + realName: "张三" + avatar: 2060000000000000001 + sex: "0" + birthday: "1990-01-01" + email: "zhangsan@example.com" + PasswordChange: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordChangeBody' + example: + oldPassword: "e10adc3949ba59abbe56e057f20f883e" + newPassword: "25d55ad283aa400af464c76d713c07ad" + PasswordReset: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordResetBody' + example: + grantType: "password" + tenantId: "000000" + phone: "13800000000" + smsCode: "1234" + newPassword: "25d55ad283aa400af464c76d713c07ad" + PhoneChange: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PhoneChangeBody' + example: + phone: "13900000000" + smsCode: "1234" + AccountDeactivate: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AccountDeactivateBody' + example: + smsCode: "1234" + ChunkUpload: + required: true + content: + multipart/form-data: + schema: + type: object + required: [uploadId, chunkIndex, chunkMd5, file] + properties: + uploadId: + type: string + chunkIndex: + type: integer + example: 0 + chunkMd5: + type: string + example: d41d8cd98f00b204e9800998ecf8427e + file: + type: string + format: binary + ResumableInit: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ResumableInitBody' + example: + uploadId: "UPLOAD202607090001" + fileName: "cover.jpg" + fileMd5: "d41d8cd98f00b204e9800998ecf8427e" + totalSize: 9532 + totalChunks: 1 + chunkSize: 4194304 + contentType: "image/jpeg" + ResumableComplete: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ResumableCompleteBody' + example: + uploadId: "UPLOAD202607090001" + fileName: "cover.jpg" + fileMd5: "d41d8cd98f00b204e9800998ecf8427e" + totalSize: 9532 + totalChunks: 1 + GenerationPoemBatch: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/GenerationPoemBatchBody' + example: + poemText: "德承家亦\n忠厚传芳" + disableMissing: false + LineagePerson: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/LineagePersonBody' + example: + bindingMode: NONE + personNo: "P202607090001" + name: "彭德明" + aliasName: "德明" + sex: "0" + generation: 1 + generationName: "德" + avatarOssId: "2060000000000000001" + birthDate: "1950-01-01" + birthLunar: "0" + birthPlace: "江西吉安" + personStatus: "0" + biography: "第一世人物简介" + sortOrder: 1 + FamilyFeed: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/FamilyFeedBody' + example: + feedType: "text" + feedContent: "今天上传一张老照片。" + mediaOssIds: "2060000000000000001,2060000000000000002" + sortOrder: 0 + status: "0" + FamilyFeedComment: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/FamilyFeedCommentBody' + example: + parentCommentId: null + commentContent: "这张照片很有年代感。" + GenealogyCreate: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/GenealogyCreateBody' + example: + genealogyName: "彭氏家谱" + surname: "彭" + ancestralHall: "陇西堂" + originPlace: "江西吉安" + regionCode: "360800" + addressDetail: "江西省吉安市" + coverOssId: "2060000000000000001" + intro: "彭氏家谱简介" + visibility: "1" + joinMode: "1" + GenealogyUpdate: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/GenealogyUpdateBody' + example: + genealogyName: "彭氏家谱" + surname: "彭" + ancestralHall: "陇西堂" + originPlace: "江西吉安" + regionCode: "360800" + addressDetail: "江西省吉安市" + coverOssId: "2060000000000000001" + intro: "更新后的家谱简介" + visibility: "1" + joinMode: "1" + GenealogyJoinApply: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/GenealogyJoinApplyBody' + example: + applicantName: "彭小明" + phone: "13800000000" + relationDesc: "本族成员" + applyReason: "申请加入家谱维护" + inviterUserId: 900000001 + GenealogyJoinAudit: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/GenealogyJoinAuditBody' + example: + status: "1" + auditRemark: "信息核验通过" + GenealogyMemberUpdate: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/GenealogyMemberUpdateBody' + example: + memberName: "彭小明" + relationName: "族亲" + roleType: "member" + lineagePersonId: 900020001 + GenealogyOwnerTransfer: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/GenealogyOwnerTransferBody' + example: + targetMemberId: 900010002 + GenerationPoem: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/GenerationPoemBody' + example: + generationNo: 5 + generationText: "忠" + description: "fifth generation poem" + sortOrder: 5 + status: "0" + Article: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ArticleBody' + example: + categoryId: 900040001 + articleTitle: "族谱源流" + articleSummary: "介绍本支源流" + coverOssId: "2060000000000000001" + articleContent: "

article content

" + authorName: "族谱管理员" + sortOrder: 1 + status: "0" + Album: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AlbumBody' + example: + albumName: "老照片" + albumDesc: "family old photos" + coverOssId: "2060000000000000001" + sortOrder: 1 + status: "0" + AlbumPhoto: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AlbumPhotoBody' + example: + ossId: "2060000000000000001" + photoTitle: "老宅合影" + photoDesc: "old house photo" + photographer: "彭小明" + shootTime: "2026-07-09 10:00:00" + sortOrder: 1 + status: "0" + Ceremony: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CeremonyBody' + example: + ceremonyType: "ancestor" + ceremonyTitle: "清明祭祖" + ceremonyDesc: "online ancestor ceremony" + ceremonyTime: "2026-04-04 09:00:00" + location: "祠堂" + locationAddress: "四川省成都市示例路1号" + longitude: 104.0665410 + latitude: 30.5722690 + coverOssId: "2060000000000000001" + sortOrder: 1 + status: "0" + CeremonyInvitees: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CeremonyInviteesBody' + example: + inviteeUserIds: [900000001, 900000002] + CeremonyInvitationResponse: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CeremonyInvitationResponseBody' + example: + inviteStatus: "ACCEPTED" + CeremonyGift: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CeremonyGiftBody' + example: + giverName: "彭小明" + giftAmount: 66.66 + giftMessage: "缅怀先祖" + GrowthRecord: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/GrowthRecordBody' + example: + lineagePersonId: 900020001 + recordType: "birth" + recordTitle: "出生记录" + recordContent: "birth record" + recordDate: "2026-07-09 10:00:00" + remindTime: "2027-07-09 10:00:00" + mediaOssIds: "2060000000000000001" + sortOrder: 1 + status: "0" + Memo: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/MemoBody' + example: + memoTitle: "修谱事项" + memoContent: "contact family members" + remindTime: "2026-08-01 09:00:00" + completed: "0" + mediaOssIds: "2060000000000000001" + sortOrder: 1 + status: "0" + RelativeRecord: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/RelativeRecordBody' + example: + relativeName: "张三" + relationName: "亲友" + eventName: "礼尚往来" + eventTime: "2026-07-16 10:00:00" + giftAmount: 100.00 + recordContent: "往来记录" + mediaOssIds: "2060000000000000001" + sortOrder: 1 + status: "0" + MeritRecord: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/MeritRecordBody' + example: + donorName: "彭小明" + meritType: "donation" + meritTitle: "修谱捐款" + meritContent: "support genealogy work" + amount: 100.0 + meritTime: "2026-07-09 10:00:00" + sortOrder: 1 + status: "0" + Video: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/VideoBody' + example: + videoTitle: "家族活动记录" + videoDesc: "2026 年清明祭祖活动" + coverOssId: "2060000000000000001" + videoOssId: "2060000000000000002" + durationSeconds: 180 + sortOrder: 1 + status: "0" + Feedback: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/FeedbackBody' + example: + feedbackType: "bug" + feedbackContent: "upload image failed" + contactInfo: "13800000000" + VipOrder: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/VipOrderBody' + example: + packageId: 900060001 + genealogyId: 900001001 + payType: "wechat" + VerificationChallenge: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/VerificationChallengeBody' + example: + tenantId: "000000" + subject: "13800000000" + VerificationCheck: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/VerificationCheckBody' + examples: + tianai_behavior: + summary: 天爱滑块/旋转/滑动还原/文字点选验证 + value: + tenantId: "000000" + subject: "13800000000" + challengeId: "CAPTCHA_CHALLENGE_ID" + providerCode: "tianai" + captchaType: "SLIDER" + payload: + track: + bgImageWidth: 340 + bgImageHeight: 180 + templateImageWidth: 50 + templateImageHeight: 50 + startTime: 1720000000000 + stopTime: 1720000001500 + left: 120 + top: 0 + trackList: + - x: 0 + y: 0 + t: 0 + type: down + - x: 120 + y: 0 + t: 650 + type: move + - x: 120 + y: 0 + t: 700 + type: up + system_image: + summary: 系统图形验证码 + value: + tenantId: "000000" + subject: "13800000000" + challengeId: "CAPTCHA_CHALLENGE_ID" + providerCode: "ruoyi_image" + captchaType: "math" + payload: + uuid: "captcha-uuid" + code: "6" + responses: + VoidResult: + description: 通用成功响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RVoid' + ObjectResult: + description: 通用对象响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RObject' + GenealogyQuotaResult: + description: 当前业务用户家谱配额响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RGenealogyQuota' + LongResult: + description: 长整型数据响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RLong' + ListResult: + description: 通用列表响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RList' + CeremonyInvitationResult: + description: 贺礼邀约详情响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RCeremonyInvitation' + CeremonyInvitationListResult: + description: 贺礼邀约列表响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RCeremonyInvitationList' + GenerationPoemResult: + description: 字辈详情响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RGenerationPoem' + GenerationPoemListResult: + description: 字辈列表响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RGenerationPoemList' + GenerationPoemBatchPreviewResult: + description: 字辈批量预览响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RGenerationPoemBatchPreview' + LineagePersonResult: + description: 世系人物详情响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RLineagePerson' + LineagePersonListResult: + description: 世系人物列表或选项响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RLineagePersonList' + LineagePersonTreeResult: + description: 世系树响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RLineagePersonTreeList' + LineagePersonPageResult: + description: 世系人物分页响应 + content: + application/json: + schema: + $ref: '#/components/schemas/LineagePersonPageResult' + 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' + FamilyFeedCommentResult: + description: 家族圈评论对象响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RFamilyFeedComment' + FamilyFeedCommentListResult: + description: 家族圈评论列表响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RFamilyFeedCommentList' + FamilyFeedCommentPageResult: + description: 家族圈评论分页响应 + content: + application/json: + schema: + $ref: '#/components/schemas/FamilyFeedCommentPageResult' + FamilyFeedResult: + description: 家族圈动态对象响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RFamilyFeed' + FamilyFeedListResult: + description: 家族圈动态列表响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RFamilyFeedList' + FamilyFeedPageResult: + description: 家族圈动态分页响应 + content: + application/json: + schema: + $ref: '#/components/schemas/FamilyFeedPageResult' + NotificationResult: + description: 消息通知详情响应 + content: + application/json: + schema: + $ref: '#/components/schemas/RNotification' + schemas: + RVoid: + type: object + properties: + code: + description: 系统图形验证码或响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + example: 操作成功 + data: + description: 响应数据主体 + nullable: true + GenealogyQuota: + type: object + required: [createUsed, createLimit, createRemaining, canCreate, joinUsed, joinLimit, joinRemaining, canJoin] + properties: + createUsed: { description: 当前用户已创建的家谱数量, type: integer, format: int64, minimum: 0, example: 1 } + createLimit: { description: 每用户可创建家谱上限,-1 表示不限,0 表示禁止,正数表示上限, type: integer, format: int64, minimum: -1, example: 3 } + createRemaining: { description: 还可创建的家谱数量,-1 表示不限, type: integer, format: int64, minimum: -1, example: 2 } + canCreate: { description: 当前用户是否还能创建家谱, type: boolean, example: true } + joinUsed: { description: 已加入的家谱总数,包含自己创建的家谱, type: integer, format: int64, minimum: 0, example: 2 } + joinLimit: { description: 每用户可加入家谱总数上限,-1 表示不限,0 表示禁止,正数表示上限, type: integer, format: int64, minimum: -1, example: 10 } + joinRemaining: { description: 还可加入的家谱数量,-1 表示不限, type: integer, format: int64, minimum: -1, example: 8 } + canJoin: { description: 当前用户是否还能加入其他家谱, type: boolean, example: true } + RGenealogyQuota: + type: object + properties: + code: { description: 响应状态码, type: integer, example: 200 } + msg: { description: 响应消息, type: string, example: 操作成功 } + data: { $ref: '#/components/schemas/GenealogyQuota' } + RObject: + type: object + properties: + code: + description: 系统图形验证码或响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + example: 操作成功 + data: + description: 响应数据主体 + type: object + additionalProperties: true + RLong: + type: object + properties: + code: { description: 响应状态码, type: integer, example: 200 } + msg: { description: 响应消息, type: string, example: 操作成功 } + data: { description: 当前业务用户未读通知数量, type: integer, format: int64, example: 3 } + RList: + type: object + properties: + code: + description: 系统图形验证码或响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + example: 操作成功 + data: + description: 响应数据主体 + type: array + items: + type: object + additionalProperties: true + PageResult: + type: object + properties: + code: + description: 系统图形验证码或响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + example: 操作成功 + rows: + description: 分页数据列表 + type: array + items: + type: object + additionalProperties: true + total: + type: integer + example: 0 + RLogin: + type: object + properties: + code: + description: 系统图形验证码或响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + example: 操作成功 + data: + description: 响应数据主体 + $ref: '#/components/schemas/LoginVo' + RFileUpload: + type: object + properties: + code: + description: 系统图形验证码或响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + example: 操作成功 + data: + description: 响应数据主体 + $ref: '#/components/schemas/FileUploadVo' + LoginVo: + type: object + properties: + token: + type: string + accessToken: + type: string + tokenValue: + type: string + userId: + type: integer + format: int64 + tenantId: + description: 租户ID,用于区分不同租户的数据和验证策略 + type: string + clientId: + description: 客户端ID,对应后台客户端管理中的APP/PC/小程序等终端 + type: string + clientKey: + type: string + FileUploadVo: + type: object + properties: + ossId: + description: OSS文件ID,表单内部使用,用户侧应通过上传组件获取 + type: string + pattern: '^[1-9][0-9]*$' + url: + type: string + thumbnailUrl: + type: string + nullable: true + fileName: + description: 原始文件名 + type: string + originalName: + type: string + PasswordRegisterBody: + type: object + additionalProperties: false + required: [grantType, tenantId, phone, password, smsCode] + properties: + grantType: + description: 授权类型,例如password、sms、wechat、apple + type: string + example: password + tenantId: + description: 租户ID,用于区分不同租户的数据和验证策略 + type: string + example: "000000" + phone: + description: 手机号 + type: string + example: "13800000000" + password: + type: string + description: 32 位 MD5 + example: e10adc3949ba59abbe56e057f20f883e + nickName: + description: 用户昵称 + type: string + registerSource: + description: 注册来源,例如APP、PC、H5、MINI_PROGRAM + type: string + smsCode: + description: 4 位短信验证码 + type: string + pattern: '^\d{4}$' + example: "1234" + PasswordLoginBody: + description: APP 用户密码登录请求;验证场景由后端按 APP_PASSWORD_LOGIN 路由的当前激活绑定解析,前端不得提交 sceneCode;validToken 是否需要由解析后场景的策略决定。 + type: object + additionalProperties: false + required: [grantType, tenantId, phone, password] + properties: + grantType: + description: 授权类型,例如password、sms、wechat、apple + type: string + example: password + tenantId: + description: 租户ID,用于区分不同租户的数据和验证策略 + type: string + example: "000000" + phone: + description: 登录手机号,也是行为验证票据绑定的验证主体。 + type: string + example: "13800000000" + password: + type: string + description: 32 位 MD5 + example: e10adc3949ba59abbe56e057f20f883e + validToken: + description: 验证中心通过后返回的一次性票据;后台验证策略关闭时可为空,开启时必须提交。 + type: string + SmsLoginBody: + type: object + additionalProperties: false + required: [grantType, tenantId, phone, smsCode] + properties: + grantType: + description: 授权类型,例如password、sms、wechat、apple + type: string + example: sms + tenantId: + description: 租户ID,用于区分不同租户的数据和验证策略 + type: string + example: "000000" + phone: + description: 手机号 + type: string + example: "13800000000" + smsCode: + description: 4 位短信验证码 + type: string + pattern: '^\d{4}$' + example: "1234" + SmsCodeBody: + type: object + additionalProperties: false + required: [grantType, tenantId, phone] + properties: + grantType: + description: 授权类型,例如password、sms、wechat、apple + type: string + example: sms + tenantId: + description: 租户ID,用于区分不同租户的数据和验证策略 + type: string + example: "000000" + phone: + description: 手机号 + type: string + example: "13800000000" + validToken: + description: 验证中心通过后返回的票据,仅用于发送短信验证码;后台验证策略关闭时可为空,开启时必填。 + type: string + ProfileUpdateBody: + type: object + additionalProperties: false + properties: + nickName: + description: 用户昵称 + type: string + maxLength: 30 + realName: + description: 真实姓名 + type: string + maxLength: 30 + avatar: + description: 头像文件OSS ID + type: integer + format: int64 + sex: + description: "字典 sys_user_sex:0=男,1=女,2=未知" + type: string + enum: ["0", "1", "2"] + example: "2" + x-dict-type: sys_user_sex + birthday: + description: 生日,格式 yyyy-MM-dd + type: string + format: date + email: + description: 邮箱 + type: string + format: email + maxLength: 100 + PasswordChangeBody: + type: object + required: [oldPassword, newPassword] + properties: + oldPassword: + type: string + description: 32 位 MD5 + newPassword: + type: string + description: 32 位 MD5 + PasswordResetBody: + type: object + additionalProperties: false + required: [grantType, tenantId, phone, smsCode, newPassword] + properties: + grantType: + description: 授权类型 + type: string + example: password + tenantId: + description: 租户ID,用于区分不同租户的数据和验证策略 + type: string + example: "000000" + phone: + description: 手机号 + type: string + smsCode: + description: 4 位短信验证码 + type: string + pattern: '^\d{4}$' + example: "1234" + newPassword: + type: string + description: 32 位 MD5 + PhoneChangeBody: + type: object + additionalProperties: false + required: [phone, smsCode] + properties: + phone: + description: 新手机号 + type: string + smsCode: + description: 4 位短信验证码 + type: string + pattern: '^\d{4}$' + example: "1234" + AccountDeactivateBody: + type: object + additionalProperties: false + required: [smsCode] + properties: + smsCode: + description: 4 位短信验证码 + type: string + pattern: '^\d{4}$' + example: "1234" + ResumableInitBody: + type: object + additionalProperties: false + required: [uploadId, fileName, fileMd5, totalSize, totalChunks, chunkSize] + properties: + uploadId: + description: 客户端生成并在整个上传过程保持不变的上传任务ID + type: string + fileName: + description: 原始文件名 + type: string + fileMd5: + description: 完整文件MD5,用于秒传和完整性校验 + type: string + pattern: '^[a-fA-F0-9]{32}$' + totalSize: + description: 完整文件大小,单位字节 + type: integer + format: int64 + minimum: 1 + totalChunks: + description: 总分片数 + type: integer + minimum: 1 + chunkSize: + description: 单个分片大小,单位字节;除最后一片外每片必须严格等于该值 + type: integer + format: int64 + minimum: 1 + example: 4194304 + contentType: + description: 文件MIME类型,例如 image/jpeg、video/mp4 + type: string + ResumableCompleteBody: + type: object + additionalProperties: false + required: [uploadId, fileName, fileMd5, totalSize, totalChunks] + properties: + uploadId: + description: 分片上传任务ID + type: string + fileName: + description: 原始文件名,必须与初始化请求一致 + type: string + fileMd5: + description: 完整文件MD5,用于秒传和完整性校验 + type: string + pattern: '^[a-fA-F0-9]{32}$' + totalSize: + description: 完整文件大小,单位字节 + type: integer + format: int64 + minimum: 1 + totalChunks: + description: 总分片数,必须与初始化请求一致 + type: integer + minimum: 1 + GenerationPoemView: + type: object + properties: + poemId: + description: 字辈记录ID + type: integer + format: int64 + genealogyId: + description: 所属家谱ID + type: integer + format: int64 + genealogyNo: + description: 家谱编号 + type: string + genealogyName: + description: 家谱名称 + type: string + generationNo: + description: 世代序号 + type: integer + format: int64 + generationText: + description: 字辈文字 + type: string + description: + description: 字辈说明 + type: string + sortOrder: + description: 排序值,数值越小越靠前 + type: integer + format: int64 + status: + description: "字典 sys_normal_disable:0=正常,1=停用" + type: string + enum: ["0", "1"] + example: "0" + x-dict-type: sys_normal_disable + GenerationPoemBatchItemView: + type: object + properties: + poemId: + description: 现有字辈记录ID;新增时为空 + type: integer + format: int64 + generationNo: + description: 世代序号 + type: integer + format: int64 + oldGenerationText: + description: 保存前字辈文字 + type: string + newGenerationText: + description: 保存后字辈文字 + type: string + oldStatus: + description: 保存前状态 + type: string + newStatus: + description: 保存后状态 + type: string + action: + description: 预览动作,create、update、keep 或 disable + type: string + warning: + description: 需要用户确认的变更提示 + type: string + GenerationPoemBatchPreviewView: + type: object + properties: + genealogyId: + description: 所属家谱ID + type: integer + format: int64 + genealogyNo: + description: 家谱编号 + type: string + genealogyName: + description: 家谱名称 + type: string + createCount: + description: 将新增的字辈数量 + type: integer + updateCount: + description: 将修改或恢复的字辈数量 + type: integer + keepCount: + description: 保持不变的字辈数量 + type: integer + disableCount: + description: 将停用的字辈数量 + type: integer + items: + description: 按世代排序的逐项变更预览 + type: array + items: + $ref: '#/components/schemas/GenerationPoemBatchItemView' + RGenerationPoem: + type: object + properties: + code: + description: 响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + data: + $ref: '#/components/schemas/GenerationPoemView' + RGenerationPoemList: + type: object + properties: + code: + description: 响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + data: + type: array + items: + $ref: '#/components/schemas/GenerationPoemView' + RGenerationPoemBatchPreview: + type: object + properties: + code: + description: 响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + data: + $ref: '#/components/schemas/GenerationPoemBatchPreviewView' + GenerationPoemBatchBody: + type: object + required: [poemText] + properties: + poemText: + description: 字辈文本。无分隔符时按单个字拆分;可用空格、逗号、分号、顿号、斜杠或竖线分隔多个字辈。单个字辈最多50个字符,一次最多500个世代。 + type: string + maxLength: 26000 + example: "德承家亦\n忠厚传芳" + disableMissing: + description: 保存时是否停用未出现在新文本中的后续世代;不会删除历史记录。 + type: boolean + example: false + LineagePersonBody: + type: object + additionalProperties: false + required: [bindingMode, name] + properties: + bindingMode: + description: "账号绑定方式:NONE=不绑定账号;SELF=绑定当前登录业务用户;SPECIFIED=由有管理权限的操作者指定 appUserId" + type: string + enum: [NONE, SELF, SPECIFIED] + example: NONE + appUserId: + description: 仅 bindingMode=SPECIFIED 时必填;NONE/SELF 时必须不传。指定用户必须属于当前租户、状态正常,且未绑定当前家谱的其他有效世系人物 + type: integer + format: int64 + personNo: + description: 人物编号;不传时由服务端生成 + type: string + name: + description: 姓名 + type: string + aliasName: + description: 别名或曾用名 + type: string + sex: + description: "字典 sys_user_sex:0=男,1=女,2=未知" + type: string + enum: ["0", "1", "2"] + example: "0" + x-dict-type: sys_user_sex + generation: + description: 世代序号 + type: integer + format: int64 + generationName: + description: 字辈或辈分 + type: string + fatherId: + description: 父亲人物ID,必须属于当前家谱 + type: integer + format: int64 + motherId: + description: 母亲人物ID,必须属于当前家谱 + type: integer + format: int64 + avatarOssId: + description: 头像文件OSS ID;用户界面应通过统一上传组件获得,不允许手工录入 + type: string + pattern: '^[1-9][0-9]*$' + nullable: true + birthDate: + type: string + format: date-time + nullable: true + birthLunar: + description: "字典 gen_number_yes_no:0=否,1=是" + type: string + enum: ["0", "1"] + example: "0" + x-dict-type: gen_number_yes_no + birthPlace: + description: 出生地 + type: string + deathDate: + type: string + format: date-time + nullable: true + deathLunar: + description: "字典 gen_number_yes_no:0=否,1=是" + type: string + enum: ["0", "1"] + example: "0" + x-dict-type: gen_number_yes_no + deathPlace: + description: 逝世地 + type: string + burialPlace: + description: 安葬地 + type: string + personStatus: + description: "字典 gen_lineage_person_status:0=健在,1=已故,2=未知" + type: string + enum: ["0", "1", "2"] + example: "0" + x-dict-type: gen_lineage_person_status + biography: + description: 人物简介 + type: string + sortOrder: + description: 排序值,数值越小越靠前 + type: integer + format: int64 + remark: + description: 备注 + type: string + relationName: + description: 通过添加配偶快捷接口提交时使用的关系显示名称 + type: string + LineagePersonView: + type: object + properties: + personId: { description: 人物ID, type: integer, format: int64 } + genealogyId: { description: 家谱ID, type: integer, format: int64 } + genealogyName: { description: 家谱名称, type: string } + genealogyNo: { description: 家谱编号, type: string } + appUserId: { description: 绑定业务用户ID, type: integer, format: int64, nullable: true } + appUserNickName: { description: 绑定业务用户昵称, type: string } + personNo: { description: 人物编号, type: string } + name: { description: 姓名, type: string } + aliasName: { description: 别名或曾用名, type: string } + sex: { description: "字典 sys_user_sex:0=男,1=女,2=未知", type: string, enum: ["0", "1", "2"], example: "2", x-dict-type: sys_user_sex } + generation: { description: 世代序号, type: integer, format: int64 } + generationName: { description: 字辈或辈分, type: string } + fatherId: { description: 父亲人物ID, type: integer, format: int64, nullable: true } + fatherName: { description: 父亲姓名, type: string } + motherId: { description: 母亲人物ID, type: integer, format: int64, nullable: true } + motherName: { description: 母亲姓名, type: string } + spouseNames: { description: 配偶姓名,多个使用顿号分隔, type: string } + avatarOssId: { description: 头像文件OSS ID, type: string, pattern: '^[1-9][0-9]*$', nullable: true } + birthDate: { description: 出生日期, type: string, format: date-time, nullable: true } + birthLunar: { description: "字典 gen_number_yes_no:0=否,1=是", type: string, enum: ["0", "1"], example: "0", x-dict-type: gen_number_yes_no } + birthPlace: { description: 出生地, type: string } + deathDate: { description: 逝世日期, type: string, format: date-time, nullable: true } + deathLunar: { description: "字典 gen_number_yes_no:0=否,1=是", type: string, enum: ["0", "1"], example: "0", x-dict-type: gen_number_yes_no } + deathPlace: { description: 逝世地, type: string } + burialPlace: { description: 安葬地, type: string } + personStatus: { description: "字典 gen_lineage_person_status:0=健在,1=已故,2=未知", type: string, enum: ["0", "1", "2"], example: "0", x-dict-type: gen_lineage_person_status } + biography: { description: 人物简介, type: string } + sortOrder: { description: 排序值, type: integer, format: int64 } + status: { description: "字典 sys_normal_disable:0=正常,1=停用", type: string, enum: ["0", "1"], example: "0", x-dict-type: sys_normal_disable } + remark: { description: 备注, type: string } + LineagePersonTreeView: + allOf: + - $ref: '#/components/schemas/LineagePersonView' + - type: object + properties: + relationType: { description: "字典 gen_lineage_relation_type:father=父亲,mother=母亲,spouse=配偶,child=子女,adoptive=收养", type: string, enum: [father, mother, spouse, child, adoptive], example: spouse, x-dict-type: gen_lineage_relation_type } + relationName: { description: 关系显示名称, type: string } + spouses: + description: 配偶节点 + type: array + items: { $ref: '#/components/schemas/LineagePersonTreeView' } + children: + description: 子女节点 + type: array + items: { $ref: '#/components/schemas/LineagePersonTreeView' } + RLineagePerson: + type: object + properties: + code: { description: 响应状态码, type: integer, example: 200 } + msg: { description: 响应消息, type: string, example: 操作成功 } + data: { $ref: '#/components/schemas/LineagePersonView' } + RLineagePersonList: + type: object + properties: + code: { description: 响应状态码, type: integer, example: 200 } + msg: { description: 响应消息, type: string, example: 操作成功 } + data: + type: array + items: { $ref: '#/components/schemas/LineagePersonView' } + RLineagePersonTreeList: + type: object + properties: + code: { description: 响应状态码, type: integer, example: 200 } + msg: { description: 响应消息, type: string, example: 操作成功 } + data: + type: array + items: { $ref: '#/components/schemas/LineagePersonTreeView' } + LineagePersonPageResult: + type: object + properties: + code: { description: 响应状态码, type: integer, example: 200 } + msg: { description: 响应消息, type: string, example: 操作成功 } + rows: + description: 当前页世系人物 + type: array + items: { $ref: '#/components/schemas/LineagePersonView' } + total: { description: 总记录数, type: integer, format: int64, example: 0 } + 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: "字典 sys_normal_disable:0=正常,1=停用;未传时默认为0" + type: string + enum: ["0", "1"] + example: "0" + x-dict-type: sys_normal_disable + FamilyFeedView: + type: object + properties: + feedId: { description: 动态ID, type: integer, format: int64 } + genealogyId: { description: 所属家谱ID, type: integer, format: int64 } + genealogyNo: { description: 家谱编号, type: string } + genealogyName: { description: 家谱名称, type: string } + publisherUserId: { description: 发布业务用户ID, type: integer, format: int64 } + publisherNickName: { description: 发布用户昵称, type: string } + publisherStatus: { description: 发布用户状态, type: string } + feedType: { description: 动态类型, type: string } + feedContent: { description: 动态内容, type: string } + mediaOssIds: { description: 媒体文件OSS ID列表,多个ID使用英文逗号分隔, type: string } + likedByMe: { description: 当前登录用户是否已点赞, type: boolean, example: false } + likeCount: { description: 点赞数量, type: integer, format: int64 } + commentCount: { description: 评论数量, type: integer, format: int64 } + pinned: { description: "字典 gen_number_yes_no:0=否,1=是", type: string, enum: ["0", "1"], example: "0", x-dict-type: gen_number_yes_no } + pinnedTime: { description: 置顶时间, type: string, format: date-time, nullable: true } + sortOrder: { description: 排序值, type: integer, format: int64 } + status: { description: "字典 sys_normal_disable:0=正常,1=停用", type: string, enum: ["0", "1"], example: "0", x-dict-type: sys_normal_disable } + remark: { description: 备注, type: string } + createTime: { description: 发布时间, type: string, format: date-time } + updateTime: { description: 更新时间, type: string, format: date-time } + RFamilyFeed: + type: object + properties: + code: { description: 响应状态码, type: integer, example: 200 } + msg: { description: 响应消息, type: string, example: 操作成功 } + data: { $ref: '#/components/schemas/FamilyFeedView' } + RFamilyFeedList: + type: object + properties: + code: { description: 响应状态码, type: integer, example: 200 } + msg: { description: 响应消息, type: string, example: 操作成功 } + data: + type: array + items: { $ref: '#/components/schemas/FamilyFeedView' } + FamilyFeedPageResult: + type: object + properties: + code: { description: 响应状态码, type: integer, example: 200 } + msg: { description: 响应消息, type: string, example: 操作成功 } + rows: + type: array + items: { $ref: '#/components/schemas/FamilyFeedView' } + total: { description: 总记录数, type: integer, format: int64, example: 0 } + NotificationView: + type: object + properties: + notificationId: { description: 通知ID, type: integer, format: int64 } + genealogyId: { description: 所属家谱ID, type: integer, format: int64, nullable: true } + genealogyNo: { description: 家谱编号, type: string } + genealogyName: { description: 家谱名称, type: string } + senderUserId: { description: 发送业务用户ID, type: integer, format: int64, nullable: true } + senderNickName: { description: 发送用户昵称, type: string } + senderPhone: { description: 脱敏后的发送用户手机号, type: string } + noticeType: { description: 通知类型, type: string } + noticeTitle: { description: 通知标题, type: string } + noticeContent: { description: 通知正文, type: string } + bizType: { description: 关联业务类型, type: string } + bizId: { description: 关联业务ID, type: integer, format: int64, nullable: true } + bizSummary: { description: 关联业务摘要, type: string } + publishTime: { description: 发布时间, type: string, format: date-time } + readStatus: { description: "字典 gen_notification_read_status:0=未读,1=已读", type: string, enum: ["0", "1"], example: "0", x-dict-type: gen_notification_read_status } + readTime: { description: 阅读时间, type: string, format: date-time, nullable: true } + status: { description: "字典 sys_normal_disable:0=正常,1=停用", type: string, enum: ["0", "1"], example: "0", x-dict-type: sys_normal_disable } + remark: { description: 备注, type: string } + RNotification: + type: object + properties: + code: { description: 响应状态码, type: integer, example: 200 } + msg: { description: 响应消息, type: string, example: 操作成功 } + data: { $ref: '#/components/schemas/NotificationView' } + FamilyFeedCommentBody: + type: object + required: [commentContent] + properties: + parentCommentId: + description: 父评论 ID;不传或传 null 表示发布一级评论 + type: integer + format: int64 + nullable: true + commentContent: + description: 评论内容,最多 1000 个字符 + type: string + FamilyFeedCommentView: + type: object + properties: + commentId: + description: 评论 ID + type: integer + format: int64 + genealogyId: + description: 所属家谱 ID + type: integer + format: int64 + feedId: + description: 所属动态 ID + type: integer + format: int64 + parentCommentId: + description: 父评论 ID;null 或 0 表示一级评论 + type: integer + format: int64 + nullable: true + appUserId: + description: 评论业务用户 ID + type: integer + format: int64 + appUserNickName: + description: 评论人昵称 + type: string + appUserAvatar: + description: 评论人头像文件 ID + type: integer + format: int64 + nullable: true + parentAppUserId: + description: 被直接回复的业务用户 ID + type: integer + format: int64 + nullable: true + parentAppUserNickName: + description: 被直接回复的用户昵称 + type: string + nullable: true + commentContent: + description: 评论内容;作者删除后为 null + type: string + nullable: true + userDeleted: + description: 作者删除状态,0 未删除,1 已删除并保留占位 + type: string + enum: ["0", "1"] + example: "0" + replyCount: + description: 正常展示的直接回复数量 + type: integer + format: int64 + commentLevel: + description: 评论层级,root 为一级评论,reply 为回复 + type: string + enum: [root, reply] + status: + description: "字典 sys_normal_disable:0=正常展示,1=停用;会员接口仅返回0" + type: string + enum: ["0", "1"] + example: "0" + x-dict-type: sys_normal_disable + createTime: + description: 评论发布时间 + type: string + format: date-time + RFamilyFeedComment: + type: object + properties: + code: + description: 响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + data: + $ref: '#/components/schemas/FamilyFeedCommentView' + RFamilyFeedCommentList: + type: object + properties: + code: + description: 响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + data: + type: array + items: + $ref: '#/components/schemas/FamilyFeedCommentView' + FamilyFeedCommentPageResult: + type: object + properties: + code: + description: 响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + rows: + description: 评论分页数据 + type: array + items: + $ref: '#/components/schemas/FamilyFeedCommentView' + total: + description: 评论总数 + type: integer + format: int64 + GenealogyCreateBody: + type: object + required: [genealogyName, surname, regionCode] + properties: + genealogyName: + description: 家谱名称 + type: string + surname: + description: 姓氏 + type: string + ancestralHall: + description: 堂号/祠堂名称 + type: string + originPlace: + description: 籍贯/起源地 + type: string + regionCode: + description: 行政区划编码 + type: string + addressDetail: + description: 详细地址 + type: string + coverOssId: + description: 封面图片OSS ID + type: string + pattern: '^[1-9][0-9]*$' + intro: + description: 简介 + type: string + visibility: + description: "字典 gen_genealogy_visibility:0=私密,1=公开,2=成员可见" + type: string + enum: ["0", "1", "2"] + example: "1" + x-dict-type: gen_genealogy_visibility + joinMode: + description: "字典 gen_genealogy_join_mode:0=关闭加入,1=申请审核,2=邀请码加入" + type: string + enum: ["0", "1", "2"] + example: "1" + x-dict-type: gen_genealogy_join_mode + example: + genealogyName: "彭氏家谱" + surname: "彭" + ancestralHall: "陇西堂" + originPlace: "江西吉安" + regionCode: "360800" + addressDetail: "江西省吉安市" + coverOssId: "2060000000000000001" + intro: "彭氏家谱简介" + visibility: "1" + joinMode: "1" + GenealogyUpdateBody: + type: object + properties: + genealogyName: + description: 家谱名称 + type: string + surname: + description: 姓氏 + type: string + ancestralHall: + description: 堂号/祠堂名称 + type: string + originPlace: + description: 籍贯/起源地 + type: string + regionCode: + description: 行政区划编码 + type: string + addressDetail: + description: 详细地址 + type: string + coverOssId: + description: 封面图片OSS ID + type: string + pattern: '^[1-9][0-9]*$' + intro: + description: 简介 + type: string + visibility: + description: "字典 gen_genealogy_visibility:0=私密,1=公开,2=成员可见" + type: string + enum: ["0", "1", "2"] + example: "1" + x-dict-type: gen_genealogy_visibility + joinMode: + description: "字典 gen_genealogy_join_mode:0=关闭加入,1=申请审核,2=邀请码加入" + type: string + enum: ["0", "1", "2"] + example: "1" + x-dict-type: gen_genealogy_join_mode + example: + genealogyName: "彭氏家谱" + surname: "彭" + ancestralHall: "陇西堂" + originPlace: "江西吉安" + regionCode: "360800" + addressDetail: "江西省吉安市" + coverOssId: "2060000000000000001" + intro: "更新后的家谱简介" + visibility: "1" + joinMode: "1" + GenealogyJoinApplyBody: + type: object + properties: + applicantName: + description: 申请人姓名 + type: string + phone: + description: 手机号 + type: string + relationDesc: + description: 与家谱/人物的关系说明 + type: string + applyReason: + description: 申请理由 + type: string + inviterUserId: + description: 邀请人业务用户ID + type: integer + format: int64 + example: + applicantName: "彭小明" + phone: "13800000000" + relationDesc: "本族成员" + applyReason: "申请加入家谱维护" + inviterUserId: 900000001 + GenealogyJoinAuditBody: + type: object + required: [status] + properties: + status: + description: "字典 gen_genealogy_join_apply_status:0=待审核,1=通过,2=拒绝,3=取消" + type: string + enum: ["0", "1", "2", "3"] + example: "1" + x-dict-type: gen_genealogy_join_apply_status + auditRemark: + description: 审核备注 + type: string + example: + status: "1" + auditRemark: "信息核验通过" + GenealogyMemberUpdateBody: + type: object + properties: + memberName: + description: 成员姓名 + type: string + relationName: + description: 成员关系名称 + type: string + roleType: + description: "字典 gen_genealogy_member_role:owner=谱主,admin=管理员,editor=编辑,member=成员,visitor=访客" + type: string + enum: [owner, admin, editor, member, visitor] + example: member + x-dict-type: gen_genealogy_member_role + lineagePersonId: + description: 绑定的世系人物ID + type: integer + format: int64 + example: + memberName: "彭小明" + relationName: "族亲" + roleType: "member" + lineagePersonId: 900020001 + GenealogyOwnerTransferBody: + type: object + required: [targetMemberId] + properties: + targetMemberId: + description: 目标成员ID + type: integer + format: int64 + example: + targetMemberId: 900010002 + GenerationPoemBody: + type: object + required: [generationNo, generationText] + properties: + generationNo: + description: 世代序号 + type: integer + format: int64 + minimum: 1 + maximum: 2147483647 + generationText: + description: 当前世代的字辈文字,最长50个字符 + type: string + maxLength: 50 + description: + description: 字辈说明,最长500个字符 + type: string + maxLength: 500 + sortOrder: + description: 排序值,数值越小越靠前 + type: integer + format: int64 + minimum: -2147483648 + maximum: 2147483647 + status: + description: "字典 sys_normal_disable:0=正常,1=停用" + type: string + enum: ["0", "1"] + example: "0" + x-dict-type: sys_normal_disable + example: + generationNo: 5 + generationText: "忠" + description: "fifth generation poem" + sortOrder: 5 + status: "0" + ArticleBody: + type: object + required: [articleTitle, articleContent] + properties: + categoryId: + description: 分类ID + type: integer + format: int64 + articleTitle: + description: 文章标题 + type: string + articleSummary: + description: 文章摘要 + type: string + coverOssId: + description: 封面图片OSS ID + type: string + pattern: '^[1-9][0-9]*$' + articleContent: + description: 文章内容 + type: string + authorName: + description: 作者名称 + type: string + sortOrder: + description: 排序值,数值越小越靠前 + type: integer + format: int64 + status: + description: "字典 sys_normal_disable:0=正常,1=停用" + type: string + enum: ["0", "1"] + example: "0" + x-dict-type: sys_normal_disable + example: + categoryId: 900040001 + articleTitle: "族谱源流" + articleSummary: "介绍本支源流" + coverOssId: "2060000000000000001" + articleContent: "

article content

" + authorName: "族谱管理员" + sortOrder: 1 + status: "0" + AlbumBody: + type: object + required: [albumName] + properties: + albumName: + description: 相册名称 + type: string + albumDesc: + description: 相册说明 + type: string + coverOssId: + description: 封面图片OSS ID + type: string + pattern: '^[1-9][0-9]*$' + sortOrder: + description: 排序值,数值越小越靠前 + type: integer + format: int64 + status: + description: "字典 sys_normal_disable:0=正常,1=停用" + type: string + enum: ["0", "1"] + example: "0" + x-dict-type: sys_normal_disable + example: + albumName: "老照片" + albumDesc: "family old photos" + coverOssId: "2060000000000000001" + sortOrder: 1 + status: "0" + AlbumPhotoBody: + type: object + required: [ossId] + properties: + ossId: + description: OSS文件ID,表单内部使用,用户侧应通过上传组件获取 + type: string + pattern: '^[1-9][0-9]*$' + photoTitle: + description: 图片标题 + type: string + photoDesc: + description: 图片说明 + type: string + photographer: + description: 拍摄人 + type: string + shootTime: + description: 拍摄时间 + type: string + sortOrder: + description: 排序值,数值越小越靠前 + type: integer + format: int64 + status: + description: "字典 sys_normal_disable:0=正常,1=停用" + type: string + enum: ["0", "1"] + example: "0" + x-dict-type: sys_normal_disable + example: + ossId: "2060000000000000001" + photoTitle: "老宅合影" + photoDesc: "old house photo" + photographer: "彭小明" + shootTime: "2026-07-09 10:00:00" + sortOrder: 1 + status: "0" + CeremonyBody: + type: object + required: [ceremonyType, ceremonyTitle] + properties: + ceremonyType: + description: 祭祀/活动类型 + type: string + ceremonyTitle: + description: 祭祀/活动标题 + type: string + ceremonyDesc: + description: 祭祀/活动说明 + type: string + ceremonyTime: + description: 祭祀/活动时间 + type: string + location: + description: 地点名称,例如祠堂或酒店名称 + type: string + locationAddress: + description: 详细地址 + type: string + maxLength: 300 + longitude: + description: 经度,必须与纬度同时提供 + type: number + minimum: -180 + maximum: 180 + latitude: + description: 纬度,必须与经度同时提供 + type: number + minimum: -90 + maximum: 90 + coverOssId: + description: 封面图片OSS ID + type: string + pattern: '^[1-9][0-9]*$' + sortOrder: + description: 排序值,数值越小越靠前 + type: integer + format: int64 + status: + description: "字典 sys_normal_disable:0=正常,1=停用" + type: string + enum: ["0", "1"] + example: "0" + x-dict-type: sys_normal_disable + example: + ceremonyType: "ancestor" + ceremonyTitle: "清明祭祖" + ceremonyDesc: "online ancestor ceremony" + ceremonyTime: "2026-04-04 09:00:00" + location: "祠堂" + locationAddress: "四川省成都市示例路1号" + longitude: 104.0665410 + latitude: 30.5722690 + coverOssId: "2060000000000000001" + sortOrder: 1 + status: "0" + CeremonyInviteesBody: + type: object + required: [inviteeUserIds] + properties: + inviteeUserIds: + description: 完整受邀业务用户ID列表;空数组表示取消全部尚未响应的邀请 + type: array + uniqueItems: true + items: { type: integer, format: int64 } + example: + inviteeUserIds: [900000001, 900000002] + CeremonyInvitationResponseBody: + type: object + required: [inviteStatus] + properties: + inviteStatus: + description: 当前用户的邀约响应,只允许接受或拒绝 + type: string + enum: [ACCEPTED, DECLINED] + example: + inviteStatus: "ACCEPTED" + CeremonyInvitationVo: + type: object + properties: + invitationId: { description: 邀约ID, type: integer, format: int64 } + genealogyId: { description: 家谱ID, type: integer, format: int64 } + ceremonyId: { description: 贺礼活动ID, type: integer, format: int64 } + inviteeUserId: { description: 受邀业务用户ID, type: integer, format: int64 } + inviteStatus: { description: 邀约状态, type: string, enum: [PENDING, ACCEPTED, DECLINED, CANCELED] } + inviteVersion: { description: 邀请版本,取消后重新邀请时递增, type: integer } + deliveredTime: { description: 邀请投递时间, type: string, format: date-time } + readTime: { description: 邀请阅读时间, type: string, format: date-time } + responseTime: { description: 接受或拒绝时间, type: string, format: date-time } + ceremonyTitle: { description: 贺礼活动标题, type: string } + ceremonyTime: { description: 贺礼活动时间, type: string, format: date-time } + location: { description: 地点名称, type: string } + locationAddress: { description: 详细地址, type: string } + longitude: { description: 经度, type: number } + latitude: { description: 纬度, type: number } + RCeremonyInvitation: + type: object + properties: + code: { description: 响应状态码, type: integer, example: 200 } + msg: { description: 响应消息, type: string, example: 操作成功 } + data: + $ref: '#/components/schemas/CeremonyInvitationVo' + RCeremonyInvitationList: + type: object + properties: + code: { description: 响应状态码, type: integer, example: 200 } + msg: { description: 响应消息, type: string, example: 操作成功 } + data: + description: 贺礼邀约列表 + type: array + items: + $ref: '#/components/schemas/CeremonyInvitationVo' + CeremonyGiftBody: + type: object + required: [giftAmount] + properties: + giverName: + description: 赠送人/献礼人姓名 + type: string + giftAmount: + description: 礼物金额 + type: number + format: double + giftMessage: + description: 礼物留言 + type: string + example: + giverName: "彭小明" + giftAmount: 66.66 + giftMessage: "缅怀先祖" + GrowthRecordBody: + type: object + required: [recordTitle] + properties: + lineagePersonId: + description: 绑定的世系人物ID + type: integer + format: int64 + recordType: + description: 记录类型 + type: string + recordTitle: + description: 记录标题 + type: string + recordContent: + description: 记录内容 + type: string + recordDate: + description: 记录日期 + type: string + remindTime: + description: 提醒时间 + type: string + mediaOssIds: + description: 媒体文件 OSS ID 列表;多个正整数 ID 使用英文逗号分隔,禁止空项和其他字符 + type: string + pattern: '^$|^[1-9][0-9]*(,[1-9][0-9]*)*$' + sortOrder: + description: 排序值,数值越小越靠前 + type: integer + format: int64 + status: + description: "字典 sys_normal_disable:0=正常,1=停用" + type: string + enum: ["0", "1"] + example: "0" + x-dict-type: sys_normal_disable + example: + lineagePersonId: 900020001 + recordType: "birth" + recordTitle: "出生记录" + recordContent: "birth record" + recordDate: "2026-07-09 10:00:00" + remindTime: "2027-07-09 10:00:00" + mediaOssIds: "2060000000000000001" + sortOrder: 1 + status: "0" + MemoBody: + type: object + required: [memoTitle] + properties: + memoTitle: + description: 备忘标题 + type: string + memoContent: + description: 备忘内容 + type: string + remindTime: + description: 提醒时间 + type: string + completed: + description: 是否已完成 + type: string + mediaOssIds: + description: 媒体文件 OSS ID 列表;多个正整数 ID 使用英文逗号分隔,禁止空项和其他字符 + type: string + pattern: '^$|^[1-9][0-9]*(,[1-9][0-9]*)*$' + sortOrder: + description: 排序值,数值越小越靠前 + type: integer + format: int64 + status: + description: "字典 sys_normal_disable:0=正常,1=停用" + type: string + enum: ["0", "1"] + example: "0" + x-dict-type: sys_normal_disable + example: + memoTitle: "修谱事项" + memoContent: "contact family members" + remindTime: "2026-08-01 09:00:00" + completed: "0" + mediaOssIds: "2060000000000000001" + sortOrder: 1 + status: "0" + RelativeRecordBody: + type: object + required: [relativeName] + properties: + relativeName: { description: 亲友姓名, type: string } + relationName: { description: 关系名称, type: string } + eventName: { description: 事件名称, type: string } + eventTime: { description: 事件时间, type: string } + giftAmount: { description: 礼金金额, type: number } + recordContent: { description: 记录内容, type: string } + mediaOssIds: + description: 媒体文件 OSS ID 列表;多个正整数 ID 使用英文逗号分隔,禁止空项和其他字符 + type: string + pattern: '^$|^[1-9][0-9]*(,[1-9][0-9]*)*$' + sortOrder: { description: 排序值,数值越小越靠前, type: integer, format: int64 } + status: { description: "字典 sys_normal_disable:0=正常,1=停用", type: string, enum: ["0", "1"], example: "0", x-dict-type: sys_normal_disable } + MeritRecordBody: + type: object + required: [donorName, meritTitle] + properties: + donorName: + description: 功德人/捐赠人姓名 + type: string + meritType: + description: "字典 gen_merit_type:donation=捐赠,repair=修祠,public=公益,other=其他" + type: string + enum: [donation, repair, public, other] + example: donation + x-dict-type: gen_merit_type + meritTitle: + description: 功德标题 + type: string + meritContent: + description: 功德内容 + type: string + amount: + description: 金额 + type: number + format: double + meritTime: + description: 功德时间 + type: string + sortOrder: + description: 排序值,数值越小越靠前 + type: integer + format: int64 + status: + description: "字典 sys_normal_disable:0=正常,1=停用" + type: string + enum: ["0", "1"] + example: "0" + x-dict-type: sys_normal_disable + example: + donorName: "彭小明" + meritType: "donation" + meritTitle: "修谱捐款" + meritContent: "support genealogy work" + amount: 100.0 + meritTime: "2026-07-09 10:00:00" + sortOrder: 1 + status: "0" + VideoBody: + type: object + additionalProperties: false + required: [videoTitle, videoOssId] + properties: + videoTitle: + description: 视频标题 + type: string + videoDesc: + description: 视频说明 + type: string + coverOssId: + description: 视频封面文件 OSS ID + type: string + pattern: '^[1-9][0-9]*$' + videoOssId: + description: 视频文件 OSS ID + type: string + pattern: '^[1-9][0-9]*$' + durationSeconds: + description: 视频时长,单位秒 + type: integer + format: int64 + sortOrder: + description: 排序值,数值越小越靠前 + type: integer + format: int64 + status: + description: "字典 sys_normal_disable:0=正常,1=停用" + type: string + enum: ["0", "1"] + example: "0" + x-dict-type: sys_normal_disable + FeedbackBody: + type: object + required: [feedbackContent] + properties: + feedbackType: + description: "字典 gen_feedback_type:advice=建议,bug=故障,complaint=投诉,other=其他" + type: string + enum: [advice, bug, complaint, other] + example: bug + x-dict-type: gen_feedback_type + feedbackContent: + description: 反馈内容 + type: string + contactInfo: + description: 联系方式 + type: string + example: + feedbackType: "bug" + feedbackContent: "upload image failed" + contactInfo: "13800000000" + VipOrderBody: + type: object + required: [packageId] + properties: + packageId: + description: VIP套餐ID + type: integer + format: int64 + genealogyId: + description: 家谱ID + type: integer + format: int64 + payType: + description: 支付方式 + type: string + example: + packageId: 900060001 + genealogyId: 900001001 + payType: "wechat" + VerificationChallengeBody: + type: object + additionalProperties: false + required: [tenantId, subject] + properties: + tenantId: + type: string + description: 租户 ID + subject: + type: string + description: 验证主体,如手机号/用户名/IP + example: + tenantId: "000000" + subject: "13800000000" + VerificationCheckBody: + type: object + additionalProperties: false + required: [tenantId, subject, challengeId] + properties: + tenantId: + description: 租户ID,用于区分不同租户的数据和验证策略 + 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: + description: 验证结果载荷。天爱行为验证码提交 payload.track;系统图形验证码提交 payload.uuid 和 payload.code + oneOf: + - $ref: '#/components/schemas/TianaiVerificationPayload' + - $ref: '#/components/schemas/SystemImageVerificationPayload' + TianaiVerificationPayload: + type: object + description: 将天爱 1.5.5 前端验证回调中的 data 原样放入 track;回调 id 不放入 payload,挑战标识统一提交顶层 challengeId + required: [track] + properties: + track: + $ref: '#/components/schemas/TianaiCaptchaTrack' + TianaiCaptchaTrack: + type: object + required: [bgImageWidth, bgImageHeight, startTime, stopTime, trackList] + properties: + bgImageWidth: + type: integer + description: 验证码背景图片在前端实际显示的宽度,单位像素 + bgImageHeight: + type: integer + description: 验证码背景图片在前端实际显示的高度,单位像素 + templateImageWidth: + type: integer + description: 滑块或旋转模板图片在前端实际显示的宽度,单位像素 + templateImageHeight: + type: integer + description: 滑块或旋转模板图片在前端实际显示的高度,单位像素 + startTime: + type: integer + format: int64 + description: 用户开始操作的时间戳,单位毫秒 + stopTime: + type: integer + format: int64 + description: 用户结束操作的时间戳,单位毫秒 + left: + type: integer + description: 滑块最终水平偏移量,单位像素;由天爱前端控件生成 + top: + type: integer + description: 点选或模板最终垂直偏移量,单位像素;由天爱前端控件生成 + trackList: + type: array + minItems: 1 + description: 用户操作轨迹,不能为空,必须直接使用天爱前端控件产生的数据 + items: + $ref: '#/components/schemas/TianaiCaptchaTrackPoint' + data: + type: object + nullable: true + additionalProperties: true + description: 不同验证码类型附带的扩展数据,由天爱前端控件原样提交 + TianaiCaptchaTrackPoint: + type: object + required: [x, y, t, type] + properties: + x: + type: number + format: float + description: 当前轨迹点的水平坐标 + y: + type: number + format: float + description: 当前轨迹点的垂直坐标 + t: + type: number + format: float + description: 当前轨迹点相对操作开始时的时间,单位毫秒 + type: + type: string + description: 轨迹事件类型,例如 down、move、up + SystemImageVerificationPayload: + type: object + required: [uuid, code] + properties: + uuid: + type: string + description: 系统图形验证码接口返回的唯一标识 + code: + type: string + description: 用户填写的图形验证码答案 + VerificationRequireVo: + type: object + properties: + required: + description: 当前场景是否需要验证 + type: boolean + providerCode: + description: 第三方服务商编码 + type: string + captchaType: + description: 验证码类型,例如SLIDER、ROTATE、CONCAT、WORD_IMAGE_CLICK + type: string + sceneCode: + description: 服务端按当前业务动作和激活绑定解析出的实际验证场景编码 + type: string + ttlSeconds: + description: 验证或票据有效秒数 + type: integer + example: + required: true + providerCode: "tianai" + captchaType: "SLIDER" + sceneCode: "APP_LOGIN_ACTIVE_SCENE" + ttlSeconds: 300 + 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: 天爱验证码数据,包括背景图、模板图、尺寸等 + 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 + 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: "验证通过" + 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,..." + RVerificationRequire: + type: object + properties: + code: + description: 系统图形验证码或响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + example: "操作成功" + data: + description: 响应数据主体 + $ref: '#/components/schemas/VerificationRequireVo' + RVerificationChallenge: + type: object + properties: + code: + description: 系统图形验证码或响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + example: "操作成功" + data: + description: 响应数据主体 + $ref: '#/components/schemas/VerificationChallengeVo' + RVerificationCheck: + type: object + properties: + code: + description: 系统图形验证码或响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + example: "操作成功" + data: + description: 响应数据主体 + $ref: '#/components/schemas/VerificationCheckVo' + RLegacyCaptcha: + type: object + properties: + code: + description: 系统图形验证码或响应状态码 + type: integer + example: 200 + msg: + description: 响应消息 + type: string + example: "操作成功" + data: + description: 响应数据主体 + $ref: '#/components/schemas/LegacyCaptchaVo' diff --git a/manifest.json b/manifest.json index 878f367..e0e001e 100644 --- a/manifest.json +++ b/manifest.json @@ -1,40 +1,72 @@ { - "name": "家谱", - "appid": "__UNI__1997FFD", - "description": "家祠卷轴风格的家谱共建应用", - "versionName": "1.0.0", - "versionCode": 100, - "transformPx": false, - "app-plus": { - "usingComponents": true, - "nvueStyleCompiler": "uni-app", - "compilerVersion": 3, - "statusbar": { - "immersed": "supportedDevice", - "style": "light", - "background": "#B52E22" + "name" : "家谱", + "appid" : "__UNI__2E0520B", + "description" : "家祠卷轴风格的家谱共建应用", + "versionName" : "1.0.0", + "versionCode" : 100, + "transformPx" : false, + "app-plus" : { + "usingComponents" : true, + "nvueStyleCompiler" : "uni-app", + "compilerVersion" : 3, + "statusbar" : { + "immersed" : "supportedDevice", + "style" : "light", + "background" : "#B52E22" + }, + "splashscreen" : { + "alwaysShowBeforeRender" : true, + "waiting" : true, + "autoclose" : true, + "delay" : 0 + }, + "distribute" : { + "android" : { + "permissions" : [ + "", + "", + "" + ] + }, + "ios" : { + "dSYMs" : false + }, + "icons" : { + "android" : { + "hdpi" : "unpackage/res/icons/72x72.png", + "xhdpi" : "unpackage/res/icons/96x96.png", + "xxhdpi" : "unpackage/res/icons/144x144.png", + "xxxhdpi" : "unpackage/res/icons/192x192.png" + }, + "ios" : { + "appstore" : "unpackage/res/icons/1024x1024.png", + "ipad" : { + "app" : "unpackage/res/icons/76x76.png", + "app@2x" : "unpackage/res/icons/152x152.png", + "notification" : "unpackage/res/icons/20x20.png", + "notification@2x" : "unpackage/res/icons/40x40.png", + "proapp@2x" : "unpackage/res/icons/167x167.png", + "settings" : "unpackage/res/icons/29x29.png", + "settings@2x" : "unpackage/res/icons/58x58.png", + "spotlight" : "unpackage/res/icons/40x40.png", + "spotlight@2x" : "unpackage/res/icons/80x80.png" + }, + "iphone" : { + "app@2x" : "unpackage/res/icons/120x120.png", + "app@3x" : "unpackage/res/icons/180x180.png", + "notification@2x" : "unpackage/res/icons/40x40.png", + "notification@3x" : "unpackage/res/icons/60x60.png", + "settings@2x" : "unpackage/res/icons/58x58.png", + "settings@3x" : "unpackage/res/icons/87x87.png", + "spotlight@2x" : "unpackage/res/icons/80x80.png", + "spotlight@3x" : "unpackage/res/icons/120x120.png" + } + } + } + } }, - "splashscreen": { - "alwaysShowBeforeRender": true, - "waiting": true, - "autoclose": true, - "delay": 0 + "mp-weixin" : { + "usingComponents" : true }, - "distribute": { - "android": { - "permissions": [ - "", - "", - "" - ] - }, - "ios": { - "dSYMs": false - } - } - }, - "mp-weixin": { - "usingComponents": true - }, - "vueVersion": "3" + "vueVersion" : "3" } diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..e767f93 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,26 @@ +{ + "name": "jiapuapp", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "jiapuapp", + "devDependencies": { + "yaml": "^2.8.1" + } + }, + "node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..2f1a3e2 --- /dev/null +++ b/package.json @@ -0,0 +1,7 @@ +{ + "name": "jiapuapp", + "private": true, + "devDependencies": { + "yaml": "^2.8.1" + } +} diff --git a/pages.json b/pages.json index 787403e..410ef9f 100644 --- a/pages.json +++ b/pages.json @@ -81,6 +81,13 @@ "disableScroll": true } }, + { + "path": "pages/tree/t02-pedigree-overview", + "style": { + "navigationStyle": "custom", + "disableScroll": true + } + }, { "path": "pages/tree/t03-member-profile", "style": { diff --git a/pages/genealogy/g05-genealogy-overview.vue b/pages/genealogy/g05-genealogy-overview.vue index f728bc8..b694a52 100644 --- a/pages/genealogy/g05-genealogy-overview.vue +++ b/pages/genealogy/g05-genealogy-overview.vue @@ -18,18 +18,32 @@