diff --git a/.DS_Store b/.DS_Store index 4d49c113..9ae2a6c8 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.cursor/scripts/README-gitea-sync.md b/.cursor/scripts/README-gitea-sync.md new file mode 100644 index 00000000..5e05cdb9 --- /dev/null +++ b/.cursor/scripts/README-gitea-sync.md @@ -0,0 +1,55 @@ +# 与 Gitea(192.168.1.201)同步 + +## 远程 + +- **gitea-local**:`http://192.168.1.201:3000/fnvtk/soul-yongping.git`(拉取 + 推送) + +## 手动同步 + +```bash +./.cursor/scripts/gitea-sync.sh +``` + +## 每 10 分钟自动同步(macOS launchd) + +- 已安装:`~/Library/LaunchAgents/com.soul.yongping.gitea-sync.plist` +- 每 10 分钟执行一次,登录后自动加载 + +**启用:** + +```bash +launchctl load ~/Library/LaunchAgents/com.soul.yongping.gitea-sync.plist +``` + +**停用:** + +```bash +launchctl unload ~/Library/LaunchAgents/com.soul.yongping.gitea-sync.plist +``` + +**查看是否在跑:** + +```bash +launchctl list | grep com.soul.yongping.gitea-sync +``` + +## 认证(192.168.1.201 需登录时) + +若 push/pull 需要账号密码,定时任务无法弹窗,请把凭证写进 remote URL(勿提交到仓库): + +```bash +git remote set-url gitea-local 'http://用户名:token或密码@192.168.1.201:3000/fnvtk/soul-yongping.git' +``` + +或用系统钥匙串: + +```bash +git config --global credential.helper osxkeychain +# 然后手动执行一次 gitea-sync.sh,输入一次账号密码,之后由钥匙串记住 +``` + +## 日志 + +- 脚本内部:`.cursor/scripts/gitea-sync.log` +- launchd 标准输出:`.cursor/scripts/gitea-sync-launchd.log` +- launchd 错误:`.cursor/scripts/gitea-sync-launchd.err.log` diff --git a/.cursor/scripts/gitea-sync-launchd.err.log b/.cursor/scripts/gitea-sync-launchd.err.log new file mode 100644 index 00000000..7455b655 --- /dev/null +++ b/.cursor/scripts/gitea-sync-launchd.err.log @@ -0,0 +1 @@ +/bin/bash: /Users/karuo/Documents/开发/3、自营项目/一场soul的创业实验-永平/.cursor/scripts/gitea-sync.sh: Operation not permitted diff --git a/.cursor/scripts/gitea-sync-launchd.log b/.cursor/scripts/gitea-sync-launchd.log new file mode 100644 index 00000000..e69de29b diff --git a/.cursor/scripts/gitea-sync.log b/.cursor/scripts/gitea-sync.log new file mode 100644 index 00000000..00b9df88 --- /dev/null +++ b/.cursor/scripts/gitea-sync.log @@ -0,0 +1,6 @@ +[2026-03-19 14:54:01] --- sync start (branch=devlop, remote=gitea-local) --- +From http://192.168.1.201:3000/fnvtk/soul-yongping + * [new branch] devlop -> gitea-local/devlop + * [new branch] main -> gitea-local/main +error: cannot pull with rebase: You have unstaged changes. +error: Please commit or stash them. diff --git a/.cursor/scripts/gitea-sync.sh b/.cursor/scripts/gitea-sync.sh new file mode 100755 index 00000000..418c4316 --- /dev/null +++ b/.cursor/scripts/gitea-sync.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# 与 Gitea(192.168.1.201)双向同步:先拉取,有本地变更则提交并推送 +# 可手动执行,也可由 launchd 每 10 分钟执行 + +set -e +REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)" +REMOTE="gitea-local" +LOG_FILE="$REPO_ROOT/.cursor/scripts/gitea-sync.log" + +cd "$REPO_ROOT" +BRANCH=$(git rev-parse --abbrev-ref HEAD) + +log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"; } + +log "--- sync start (branch=$BRANCH, remote=$REMOTE) ---" + +# 1. 拉取远程更新(若远程无此分支则仅 fetch) +git fetch "$REMOTE" 2>&1 | tee -a "$LOG_FILE" || true +if git ls-remote --exit-code --heads "$REMOTE" "$BRANCH" &>/dev/null; then + git pull "$REMOTE" "$BRANCH" --no-edit 2>&1 | tee -a "$LOG_FILE" || log "pull 失败或冲突,继续尝试推送本地变更" +else + log "远程无 $REMOTE/$BRANCH,仅 fetch" +fi + +# 2. 若有本地未提交变更,则提交并推送 +STATUS=$(git status -s) +if [ -n "$STATUS" ]; then + git add -A + git commit -m "sync: $(date '+%Y-%m-%d %H:%M')" 2>&1 | tee -a "$LOG_FILE" || log "commit failed (nothing to commit or conflict)" + git push "$REMOTE" "$BRANCH" 2>&1 | tee -a "$LOG_FILE" || log "push failed" +else + # 若有已提交但未推送的提交,也推送(仅当远程有此分支且本地比远程多提交时) + if git ls-remote --exit-code --heads "$REMOTE" "$BRANCH" &>/dev/null; then + AHEAD=$(git rev-list "refs/remotes/${REMOTE}/${BRANCH}"..HEAD --count 2>/dev/null || echo 0) + if [ "${AHEAD:-0}" -gt 0 ]; then + git push "$REMOTE" "$BRANCH" 2>&1 | tee -a "$LOG_FILE" || log "push failed" + fi + else + git push -u "$REMOTE" "$BRANCH" 2>&1 | tee -a "$LOG_FILE" || log "push (new branch) failed" + fi +fi + +log "--- sync end ---" diff --git a/project.config.json b/project.config.json new file mode 100644 index 00000000..fcf0d817 --- /dev/null +++ b/project.config.json @@ -0,0 +1,59 @@ +{ + "compileType": "miniprogram", + "miniprogramRoot": "miniprogram/", + "description": "Soul创业派对 - 来自派对房的真实商业故事", + "appid": "wxb8bbb2b10dec74aa", + "setting": { + "urlCheck": false, + "es6": true, + "enhance": true, + "postcss": true, + "preloadBackgroundData": false, + "minified": true, + "newFeature": true, + "coverView": true, + "nodeModules": false, + "autoAudits": false, + "showShadowRootInWxmlPanel": true, + "scopeDataCheck": false, + "uglifyFileName": false, + "checkInvalidKey": true, + "checkSiteMap": true, + "uploadWithSourceMap": true, + "compileHotReLoad": true, + "lazyloadPlaceholderEnable": false, + "useMultiFrameRuntime": true, + "babelSetting": { + "ignore": [], + "disablePlugins": [], + "outputPath": "" + }, + "enableEngineNative": false, + "useIsolateContext": true, + "userConfirmedBundleSwitch": false, + "packNpmManually": false, + "packNpmRelationList": [], + "minifyWXSS": true, + "disableUseStrict": false, + "minifyWXML": true, + "showES6CompileOption": false, + "useCompilerPlugins": false, + "ignoreUploadUnusedFiles": true, + "compileWorklet": false, + "localPlugins": false, + "condition": false, + "swc": false, + "disableSWC": true + }, + "condition": {}, + "editorSetting": { + "tabIndent": "insertSpaces", + "tabSize": 2 + }, + "simulatorPluginLibVersion": {}, + "packOptions": { + "ignore": [], + "include": [] + } +} + diff --git a/开发文档/1、需求/文章详情-阅读页线框图.md b/开发文档/1、需求/文章详情-阅读页线框图.md deleted file mode 100644 index c8c5563b..00000000 --- a/开发文档/1、需求/文章详情-阅读页线框图.md +++ /dev/null @@ -1,158 +0,0 @@ -# 文章详情(阅读页)线框图 - -> Soul 创业派对 - 小程序 `pages/read/read` 界面结构 - ---- - -## 一、完整内容态(免费/已购买) - -``` -┌─────────────────────────────────────────┐ -│ ████████████░░░░░░░░░░ 阅读进度 60% │ ← 顶部固定进度条 -├─────────────────────────────────────────┤ -│ ← 第 4 章 真实的行业 │ ← 导航栏 -├─────────────────────────────────────────┤ -│ [4] [免费] │ ← 章节元信息 -│ 4.1 旅游号:30天10万粉的真实逻辑 │ ← 章节标题(可长按复制) -├─────────────────────────────────────────┤ -│ │ -│ 这是一段正文内容,文中包含 @卡若 和 │ -│ #创业资源 可以点击。支持长按复制文字。 │ ← @ 高亮可点,# 金色可点 -│ │ -│ 第二段纯文本,无特殊标记。 │ -│ │ -│ ┌─────────────────────────────────┐ │ ← 图片(可点击全屏预览) -│ │ [ 插图 ] │ │ -│ └─────────────────────────────────┘ │ -│ │ -├─────────────────────────────────────────┤ -│ ┌──────────────┐ ┌──────────────────┐│ -│ │ 上一篇 │ │ 下一篇 ││ ← 章节导航 -│ │ 3.5 桶装水 │ │ 4.2 美业整合 → ││ -│ └──────────────┘ └──────────────────┘│ -│ │ -│ [ 📣 分享到朋友圈 ] [ 🖼️ 生成海报 ] │ ← 操作区 -└─────────────────────────────────────────┘ -``` - ---- - -## 二、付费墙态(未登录) - -``` -┌─────────────────────────────────────────┐ -│ ← 第 4 章 真实的行业 │ -├─────────────────────────────────────────┤ -│ 这是一段预览内容,显示前 50%... │ -│ 第二段预览... │ -│ │ -│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ ← 渐变遮罩 -│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │ -├─────────────────────────────────────────┤ -│ 🔒 │ -│ 登录后继续阅读 │ -│ 已阅读50%,登录后查看完整内容 │ -│ │ -│ [ 立即登录 ] │ -├─────────────────────────────────────────┤ -│ [ 上一篇 ] [ 下一篇 → ] │ -└─────────────────────────────────────────┘ -``` - ---- - -## 三、付费墙态(已登录未购买) - -``` -┌─────────────────────────────────────────┐ -│ (同上:预览内容 + 渐变遮罩) │ -├─────────────────────────────────────────┤ -│ 🔒 │ -│ 解锁完整内容 │ -│ 已阅读50%,购买后继续阅读 │ -│ │ -│ [ 购买本章 ¥1.0 ] │ -│ [ ✨ 解锁全部 62 章 ¥9.9 省82% ] │ ← 购买≥3章才显示 -│ │ -│ 分享给好友一起学习,还能赚取佣金 │ -├─────────────────────────────────────────┤ -│ [ 上一篇 ] [ 下一篇 → ] │ -└─────────────────────────────────────────┘ -``` - ---- - -## 四、交互说明 - -| 元素 | 交互 | -|------|------| -| **@卡若** | 点击 → 确认弹窗「是否添加 @卡若?」→ 调 CKB 留资加好友 | -| **#创业资源** | 点击 → 按类型:内链跳转 / 外链复制 / 小程序唤醒 / CKB 加好友 | -| **正文/标题** | 长按 → 选中复制(user-select) | -| **图片** | 点击 → 全屏预览;长按 → 保存菜单 | -| **上一篇/下一篇** | 点击 → 切换章节 | - ---- - -## 五、@ / # 三端数据流线框图 - -```mermaid -flowchart TB - subgraph 管理端["管理端 soul-admin"] - A1[链接人与事 Person] - A2[链接标签 LinkTag] - A3[RichEditor 编辑] - A4[autoLinkContent 转换] - A1 --> A3 - A2 --> A3 - A3 --> A4 - A4 --> |"content HTML"| DB - end - - subgraph 后端["后端 soul-api"] - DB[(chapters.content)] - API[GET /api/miniprogram/book/chapter] - CKB[POST /api/miniprogram/ckb/lead] - CFG[GET /api/miniprogram/config] - DB --> API - end - - subgraph 小程序["小程序 miniprogram"] - B1[contentParser 解析] - B2[contentSegments 渲染] - B3[onMentionTap] - B4[onLinkTagTap] - API --> B1 - B1 --> B2 - B2 --> B3 - B2 --> B4 - B3 --> CKB - B4 --> |"内链"| Nav[wx.navigateTo] - B4 --> |"外链"| Clip[复制剪贴板] - B4 --> |"miniprogram"| MP[wx.navigateToMiniProgram] - CFG --> B4 - end -``` - ---- - -## 六、数据流文字说明 - -``` -管理端 ContentPage - → 编辑插入 @[名称](token) / #标签 - → 保存 content(TipTap HTML) - -后端 chapters.content - → 原样存储、原样返回 - -小程序 contentParser - → 解析 → contentSegments - → WXML 渲染 text / mention / linkTag / image - -用户点击 @ - → onMentionTap → POST /api/miniprogram/ckb/lead - -用户点击 # - → onLinkTagTap → 按 tagType 分支处理 -``` diff --git a/开发文档/1、需求/链接人与事-所有同步需求.md b/开发文档/1、需求/链接人与事-所有同步需求.md deleted file mode 100644 index d7285b20..00000000 --- a/开发文档/1、需求/链接人与事-所有同步需求.md +++ /dev/null @@ -1,82 +0,0 @@ -# 链接人与事 — 所有同步需求汇总 - -> 整合自:链接人与事-存客宝同步-需求规划、实现方案、2026-03-16 文章编辑自动创建 - ---- - -## 一、同步场景总览 - -| 场景 | 触发 | 同步动作 | 状态 | -|------|------|----------|------| -| **创建 Person** | 管理端添加 / 文章 @某人 不存在时自动创建 | 调存客宝创建获客计划 → 落库 ckb_plan_id、ckb_api_key | ✅ 已实现 | -| **编辑 Person** | 管理端编辑弹窗保存 | 调存客宝更新计划 | 待实现 | -| **删除 Person** | 管理端删除 | 调存客宝删除计划 → 再删本地 | ✅ 已实现 | -| **文章 @某人 不存在** | 编辑文章输入 @新人物 并保存 | ensureMentionsAndTags → POST persons → 自动创建 + 同步存客宝 | ✅ 已实现 | - ---- - -## 二、已实现同步 - -### 2.1 创建 Person 时同步存客宝 - -- **触发**:POST /api/db/persons(仅传 name 或完整表单) -- **流程**:生成 token → 调 ckbOpenCreatePlan(deviceGroups 未传时默认选名为 soul 的设备)→ 落库 person_id、token、name、ckb_api_key、ckb_plan_id -- **实现**:`soul-api/internal/handler/db_person.go`、`ckb_open.go` - -### 2.2 删除 Person 时同步删存客宝 - -- **触发**:DELETE /api/db/persons?personId=xxx -- **流程**:若有 ckb_plan_id → 调 ckbOpenDeletePlan → 再删本地 -- **实现**:`db_person.go` DBPersonDelete - -### 2.3 文章 @某人 自动创建并同步 - -- **触发**:管理端保存文章,content 含 @新人物(persons 中不存在) -- **流程**:ensureMentionsAndTags 提取 @name → POST /api/db/persons {name} → 创建 Person + 存客宝计划 -- **实现**:`soul-admin` ContentPage ensureMentionsAndTags;`db_person.go` 按 name 查找/创建 - ---- - -## 三、待实现同步 - -### 3.1 编辑 Person 时同步存客宝 - -- **触发**:管理端编辑 Person 后保存(PUT 逻辑,personId 已存在) -- **流程**:更新本地 persons → 若有 ckb_plan_id,调存客宝 PUT /v1/plan/update 同步 name、greeting、tips 等 -- **参考**:`链接人与事-存客宝同步-需求规划.md` 4.2、7.1 - ---- - -## 四、配置与前置 - -| 配置 | 说明 | -|------|------| -| CKB_OPEN_API_KEY | 存客宝开放 API 密钥 | -| CKB_OPEN_ACCOUNT | 存客宝账号(鉴权) | -| 设备 | 创建计划时 deviceGroups 必填;未传时默认选 memo/nickname 含 "soul" 的设备 | - -### 创建计划必填参数(2026-03-16) - -| 参数 | 值 | 说明 | -|------|-----|------| -| planType | 1 | 必填 | -| sceneId | 9 | 必填 | -| scenario | 9 | 与 sceneId 一致 | -| status | 1 | 必填 | - ---- - -## 五、mention 存储格式(2026-03-16) - -| 规则 | 说明 | -|------|------| -| **data-label 必填** | TipTap Mention 仅从 `data-label` 解析显示名,缺则回退显示 `data-id`(token) | -| **ParseAutoLinkContent** | 输出 `data-type="mention"` 的 span 必须含 `data-label` | -| **已损坏内容** | span 内为 token 时,用 token 查 persons 取真实名字补回 data-label | - -## 六、相关文档 - -- `链接人与事-存客宝同步-需求规划.md` — 原始需求与 API 约定 -- `链接人与事-实现方案.md` — 实现清单 -- `临时需求池/2026-03-16-文章编辑自动创建@和#.md` — 自动创建需求 -- `开发文档/存客宝对接逻辑图.md` — 对接逻辑与参数约定 diff --git a/开发文档/全站测试报告_20260315.md b/开发文档/全站测试报告_20260315.md deleted file mode 100644 index ff6ccc5e..00000000 --- a/开发文档/全站测试报告_20260315.md +++ /dev/null @@ -1,236 +0,0 @@ -# Soul 创业派对 · 全站测试报告 - -**测试日期**:2026-03-15 -**测试范围**:管理端前端(20+ 页面) + 后端 API(35 端点) + 小程序代码审查(25 页面) + 数据库(25 张表) -**测试原则**:只检测不修改,不做任何部署 - ---- - -## 一、测试覆盖总览 - -| 测试维度 | 覆盖量 | 通过 | 问题 | -|---------|-------|------|------| -| 管理端页面(浏览器截图) | 20+ 页面/子Tab | 18 | 2 | -| API 端点测试 | 35 端点 | 29 | 6 | -| 小程序代码审查 | 25 页面 + 8 工具文件 | 核心流程完整 | 32 | -| 数据库检查 | 25 张表 | 数据一致 | 2 | -| **合计** | **全站** | — | **42 个问题** | - ---- - -## 二、问题清单(按严重程度排序) - -### 🔴 严重(Critical)— 必须修复 · 共 11 个 - -| # | 模块 | 问题 | 文件/位置 | 解决方案 | -|---|------|------|----------|---------| -| C1 | API/安全 | **OSS accessKeySecret 明文返回前端** | `db.go` AdminSettingsGet | 后端返回 ossConfig 时脱敏处理,accessKeySecret 返回 `****` | -| C2 | 小程序 | **payment.js API 路径全部错误**:使用不存在的 `app.globalData.apiBase` 和 `/payment/create` 等非标准路径 | `utils/payment.js` 全文件 | 若已不使用应删除;若要用需改为 `baseUrl` + `/api/miniprogram/*` | -| C3 | 小程序 | **payment.js 调用不存在的 `app.getUserInfo()`** | `utils/payment.js:188,201` | 改为 `app.globalData.userInfo` | -| C4 | 小程序 | **找伙伴跳转路径错误**:`pages/catalog/catalog` 不存在 | `pages/match/match.js:311` | 改为 `pages/chapters/chapters` | -| C5 | 小程序 | **`wx.getUserProfile()` 已废弃**(2022年后不可用) | `pages/settings/settings.js:251` | 改用 `