- Added a new feature for sharing profile cards, including special handling for forwarding to friends and displaying a canvas cover with user information. - Updated the mini program's profile-edit page to generate a shareable card with a structured layout, including user avatar, nickname, and additional information. - Improved the documentation to reflect the new sharing capabilities and updated the last modified date for relevant entries.
119 lines
8.6 KiB
Markdown
119 lines
8.6 KiB
Markdown
---
|
||
name: soul-miniprogram-dev
|
||
description: Soul 创业派对小程序开发规范。在 miniprogram/ 下编辑时必遵循。WXML/WXSS/JS、app.request、/api/miniprogram/*、scene、支付、权限。Use when editing miniprogram, 小程序, 微信原生.
|
||
---
|
||
# Soul 创业派对 - 小程序开发 Skill
|
||
|
||
当你在 **miniprogram/** 目录下新增、优化或编辑代码时,必须遵循本 Skill。本 Skill 与 soul-api、soul-admin 的边界约束见项目 Rules,防止与 API/管理端逻辑互窜。
|
||
|
||
---
|
||
|
||
## 1. 项目定位与边界
|
||
|
||
- **miniprogram**:微信原生小程序(WXML/WXSS/JS),面向 C 端用户。
|
||
- **唯一后端**:业务接口只请求 **soul-api**(Go),通过 `app.globalData.baseUrl` 配置。
|
||
- **禁止**:不得在 miniprogram 内实现或依赖 next-project 的 API 路由;不得调用 `/api/admin/*`、`/api/db/*` 等管理端路径。
|
||
|
||
---
|
||
|
||
## 2. API 调用规范(防互窜)
|
||
|
||
- **路径前缀**:所有请求**必须**使用 `/api/miniprogram/...`,与 soul-api 的 `miniprogram` 路由组一致。
|
||
- **发起方式**:统一通过 `getApp().request(url, options)`,禁止在页面里直接 `wx.request` 写死 baseUrl。
|
||
- **示例**:
|
||
- 正确:`app.request('/api/miniprogram/book/all-chapters')`、`app.request('/api/miniprogram/login', { method: 'POST', data: { code } })`
|
||
- 错误:`app.request('/api/book/all-chapters')`、`app.request('/api/admin/xxx')`、`/api/vip/status`(若 soul-api 未提供 miniprogram 下等价接口则视为错误,需统一走 miniprogram 组)。
|
||
- **静默请求**:不弹窗的请求(如推荐访问、统计)传 `silent: true`:`app.request(url, { ..., silent: true })`。
|
||
- **错误处理**:`request` 已统一处理 200 且 `success: false`、401、4xx/5xx 与网络错误;页面只需 `try/catch` 或 `.then/.catch`,用 `_getApiErrorMsg` 的文案即可,勿重复造轮子。
|
||
|
||
---
|
||
|
||
## 3. 代码风格与结构
|
||
|
||
- **入口**:`app.js` 内维护 `globalData`(baseUrl、userInfo、openId、bookData、purchasedSections、theme、推荐相关等),页面通过 `getApp().globalData` 读取。
|
||
- **页面**:每个页面一个目录,含 `*.js`、`*.wxml`、`*.wxss`、`*.json`;页面逻辑用 `Page({ data: {...}, onLoad, onShow, ... })`,数据用 `this.setData()` 更新。
|
||
- **工具**:公共方法放在 `utils/`(如 `util.js`、`scene.js`、`chapterAccessManager.js`、`readingTracker.js`、`payment.js`);使用 `module.exports` 导出,页面内 `require`。
|
||
- **命名**:文件名小写短横线(如 `withdraw-records`);JS 内变量/函数小驼峰;常量可全大写下划线。
|
||
- **注释**:文件头注明「Soul创业派对 - 模块名」及重要逻辑说明(如 scene 编解码、权限状态机)。
|
||
|
||
---
|
||
|
||
## 4. 业务逻辑约定(与 soul-api 对齐)
|
||
|
||
- **登录**:微信登录走 `POST /api/miniprogram/login`(code);手机号用 `POST /api/miniprogram/phone-login` 或 `/api/miniprogram/phone`;token 存 `wx.setStorageSync('token', ...)`,请求头由 `app.request` 统一带 `Authorization: Bearer <token>`。
|
||
- **推荐码**:扫码/分享带 `ref` 或 scene 中 `ref`,由 `app.handleReferralCode` 统一处理;绑定调 `POST /api/miniprogram/referral/bind`,访问记录调 `POST /api/miniprogram/referral/visit`(可用 silent)。
|
||
- **书籍/章节**:目录与内容来自 `GET /api/miniprogram/book/all-chapters`、`/api/miniprogram/book/chapter/by-mid/:mid` 等;权限与购买状态用 `GET /api/miniprogram/user/purchase-status`,勿在端内臆造权限规则。
|
||
- **阅读进度**:使用 `utils/readingTracker.js` 与 `chapterAccessManager.js`;进度上报 `POST /api/miniprogram/user/reading-progress`。
|
||
- **支付**:下单/查单走 `POST/GET /api/miniprogram/pay`、回调由 soul-api 处理;支付前必须已有 openId(通过登录或 getOpenId 获得)。
|
||
- **提现**:申请/记录/确认等走 `/api/miniprogram/withdraw/*`;订阅消息模板 ID 在 `app.globalData.withdrawSubscribeTmplId`。
|
||
- **scene 编解码**:海报与扫码统一用 `utils/scene.js` 的 `buildScene`/`parseScene`,支持 mid、id、ref,分隔符与后端生成一致(如 `_`)。
|
||
|
||
---
|
||
|
||
## 5. 与 soul-api 的对接要点
|
||
|
||
- **响应格式**:成功为 `{ success: true, data: ... }` 或带 `message`;失败为 `{ success: false, error: "..." }` 或 `message`;`app.request` 已据此解析并 reject。
|
||
- **鉴权**:需登录的接口由 soul-api 校验 token;401 时 app 会清登录态并提示重新登录。
|
||
- **新增需求**:若 soul-api 尚未提供某能力,应在 soul-api 的 `miniprogram` 组下新增接口,小程序再调 `/api/miniprogram/...`,不得在 miniprogram 内写管理端路径或臆造接口。
|
||
|
||
---
|
||
|
||
## 6. 表单与输入框
|
||
|
||
- **input / textarea 边距**:**必须**用 `<view>` 包裹,padding/边距一律写在 view 上;内部 `<input>` 仅设 `width: 100%` 和字体样式。禁止在 input/textarea 自身上设 padding,否则会光标截断、布局异常。
|
||
- **口诀**:外边包 view,内部 input width 100%。
|
||
- **正确写法**:
|
||
- input:`<view class="form-input"><input class="form-input-inner" ... /></view>`,`.form-input { padding: 16rpx 24rpx; background: #1F2937; }`,`.form-input-inner { width: 100%; font-size: 28rpx; background: transparent; }`
|
||
- textarea:`<view class="form-textarea-wrap"><textarea class="form-textarea-inner" ... /></view>`,`.form-textarea-wrap { padding: 16rpx 24rpx; background: #1F2937; }`,`.form-textarea-inner { width: 100%; font-size: 28rpx; background: transparent; min-height: 160rpx; }`
|
||
|
||
---
|
||
|
||
## 7. 布局与边距(个人中心/设置类页面)
|
||
|
||
- **卡片区左右边距**:宜紧凑,**推荐 16rpx**,避免内容区过窄。
|
||
- **卡片**:内边距 32rpx,卡片间距 24rpx。
|
||
- **适用**:`pages/my/`、设置页等个人中心类页面。
|
||
|
||
---
|
||
|
||
## 8. 平台合规与能力检测(2025 起)
|
||
|
||
- **隐私按需授权**:涉及用户信息的接口(登录、手机号、位置等)必须在用户**实际触发功能时**再请求授权,禁止在 `app.onLaunch` 中集中请求。需配置《小程序用户隐私保护指引》,使用 `<button open-type="agreePrivacyAuthorization">` 获取同意。
|
||
- **能力检测**:使用新 API 前用 `wx.canIUse('api.xxx')` 检测,低版本做降级。
|
||
- **Skyline(可选)**:性能敏感页面可在 `page.json` 中配置 `"renderer": "skyline"`,仍使用 WXML/WXSS。
|
||
|
||
---
|
||
|
||
## 9. 文本可选与复制(阅读类内容)
|
||
|
||
- **长按选中复制**:需支持长按选中的文本用 `<text user-select>...</text>`(基础库 2.12.1+,`selectable` 已废弃)。
|
||
- **适用**:章节标题、正文段落、@ 提及、# 链接标签、预览内容等。
|
||
- **注意**:`user-select` 会使 text 显示为 inline-block,若布局异常可回退 `selectable`;iOS 原生选中失效时可用 `bindlongpress` + `wx.setClipboardData` 做整段复制兜底。
|
||
|
||
---
|
||
|
||
## 10. 分享名片(编辑资料页)
|
||
|
||
- **场景**:编辑资料页转发/朋友圈做特殊处理,直接变成分享名片。
|
||
- **标题**:`昵称+为您分享名片`(如「少年梦想家为您分享名片」)。
|
||
- **封面**:Canvas 绘制 5:4 封面图,布局:左头像(圆形)+ 右昵称 +「个人名片」副标题 + 分隔线 + 四栏信息(地区、MBTI、行业、职位)。
|
||
- **路径**:`member-detail?id=userId`,好友打开即见名片详情。
|
||
- **预生成**:资料加载完成后、头像更新后调用 `generateShareCard()`,将 `shareCardPath` 存入 data;`onShareAppMessage`/`onShareTimeline` 返回 `imageUrl: shareCardPath`。
|
||
- **朋友圈重定向**:分享带 `id` 时,`profile-edit` 的 `onLoad` 检测 `options.id` 即 `redirectTo` 到 `member-detail`。
|
||
- **头像**:网络头像需 `wx.downloadFile`,域名须配置 downloadFile 合法域名;失败时用昵称首字母占位。
|
||
|
||
---
|
||
|
||
## 11. 何时使用本 Skill
|
||
|
||
- 在 **miniprogram/** 下新增或修改页面、组件、utils 时。
|
||
- 在小程序内新增或修改任何网络请求路径时(必须保持 `/api/miniprogram/...`)。
|
||
- 做阅读、支付、推荐、提现等与 soul-api 对接的功能时。
|
||
- 做登录、手机号、推荐码等涉及用户信息的授权时(遵循 §8 隐私按需授权)。
|
||
- 做表单、input/textarea 样式时(遵循 §6,用 view 包裹,padding 写在 view 上)。
|
||
- 做个人中心、设置页布局时(遵循 §7,卡片区边距 16rpx)。
|
||
- 做阅读、文章等需长按复制的文本时(遵循 §9,text 加 user-select)。
|
||
- 做编辑资料页分享名片时(遵循 §10)。
|
||
|
||
遵循本 Skill 可保证小程序只与 soul-api 的 miniprogram 路由组对接,避免与管理端或 next-project 接口混用。
|