diff --git a/.gitignore b/.gitignore index 2c45bba..6785f82 100755 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,6 @@ dge.gynhc.com_*.tar.gz # 本地目录,不纳入仓库(AGENTS.md 含账号密码,切勿入库) /AGENTS.md /fluniapp/ + +# 小程序端源码(uniapp/)内的本地凭据文件,同样切勿入库 +/uniapp/AGENTS.md diff --git a/README.md b/README.md index b37f04f..4ef8050 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,30 @@ FastAdmin是一款基于ThinkPHP+Bootstrap的极速后台开发框架。 +--- + +## 本项目结构(同城分类信息) + +| 目录 | 内容 | +| --- | --- | +| `application/` | 后端(FastAdmin + ThinkPHP 5.0):`api/controller/` 用户端 v1 接口、`admin/controller/fc/` 后台业务模块、`admin/command/FcInstall.php` 业务表安装器(`php think fc:install`) | +| `uniapp/` | **小程序端(用户端 uni-app · Vue3)源码**:13 页面 + 74 图标 + 3 轮播插画 + 本地 Mock 兜底 + 零依赖全链路用例;构建与上传说明见 `uniapp/README.md` | +| `docs/` | 后端实现规范(`05-后端实现规范.md`)、后台字段中文化规范(`06-后台字段中文化规范.md`) | +| `tools/` | 后端校验脚本:`verify-api.mjs`(线上接口端到端验证)、`check-admin-i18n.mjs`、`check-theme.mjs` | + +### 部署链路 + +``` +本地 git push origin main + ├─→ gitcode 镜像(ssh://git@gitcode.gynhc.com:2222/.../fenleixinxi.git) + └─→ 服务器裸仓库 /www/repos/fenleixinxi.git + └─ hooks/post-receive → git reset --hard → /www/wwwroot/fenleixinxi.gzyakj.com.cn +``` + +> `uniapp/` 入库的是**源码快照**(不含构建产物 `unpackage/`)。小程序端真正的「上线」仍需用微信开发者工具 +> `cli upload` 上传版本(命令见 `uniapp/README.md` §8.2);服务器与远程仓库里的 `uniapp/` 用于版本归档与协作。 + +--- + ## 主要特性 diff --git a/uniapp/.gitignore b/uniapp/.gitignore new file mode 100644 index 0000000..38ed8c5 --- /dev/null +++ b/uniapp/.gitignore @@ -0,0 +1,16 @@ +# 依赖 +node_modules/ + +# uni-app / HBuilderX 构建产物 +unpackage/ +dist/ + +# 编辑器与系统文件 +.DS_Store +.idea/ +.vscode/ +.hbuilderx/ +*.log + +# 微信开发者工具本地私有配置 +project.private.config.json diff --git a/uniapp/App.vue b/uniapp/App.vue new file mode 100644 index 0000000..7e18b45 --- /dev/null +++ b/uniapp/App.vue @@ -0,0 +1,209 @@ + + + diff --git a/uniapp/README.md b/uniapp/README.md new file mode 100644 index 0000000..1e15719 --- /dev/null +++ b/uniapp/README.md @@ -0,0 +1,336 @@ +# 同城分类信息小程序(fenleixinxi) + +春绿(Spring Green,品牌亮绿取自设计稿 `#00E070`)主题同城分类信息平台:**招聘 / 房产 / 二手 / 车辆 / 本地服务** 信息发布与检索。 +技术栈:uni-app(Vue 3)+ 统一请求层 + 本地 Mock 兜底 + 零依赖全链路测试。 + +--- + +## 一、交付物索引 + +| 交付物 | 文件 | 说明 | +| --- | --- | --- | +| **① 功能模块清单(PM)** | [`docs/01-产品功能模块清单.md`](docs/01-产品功能模块清单.md) | 用户端 + 后台管理端模块清单、优先级、业务规则、接口映射 | +| **② UI 设计规范(UI)** | [`docs/02-UI设计规范.md`](docs/02-UI设计规范.md) | 春绿设计令牌、排版、组件、动效规范 | +| **③ 接口文档(前后端)** | [`docs/03-接口文档.md`](docs/03-接口文档.md) | 52 个接口字段级契约 + Mock 兜底机制 + 联调清单 | +| **④ 全链路测试报告(QA)** | [`docs/04-全链路测试用例与报告.md`](docs/04-全链路测试用例与报告.md) | 139 条用例、15 步 E2E、14 个缺陷记录与修复 | + +## 二、目录结构 + +``` +fenleixinxi/ +├── App.vue # 全局主题样式(春绿 CSS 变量 + 原子类) +├── uni.scss # 设计令牌($fc-* 自动注入所有 scss) +├── pages.json # 13 个页面路由 +├── pages/ # 用户端页面 +│ ├── index/index.vue # 首页:定位/搜索/轮播/分类/会员条/筛选/信息流 +│ ├── search/index.vue # 智能搜索:历史 + 热门 +│ ├── post/list.vue # 分类列表:多维筛选 + 分页 +│ ├── post/create.vue # 发布:表单/发布方式(免费·单条·套餐)/草稿箱 +│ ├── post/mine.vue # 我的发布:审核状态筛选 + 驳回原因 + 删除(v1.0.7 新增) +│ ├── detail/detail.vue # 详情:图文/地图/付费查看/评价/海报 +│ ├── member/index.vue # 会员:权益/开通/资产 +│ ├── member/orders.vue # 订单管理 +│ ├── distribution/index.vue # 分销:佣金/邀请/团队/提现 +│ ├── message/index.vue # 消息中心 +│ ├── mine/index.vue # 我的 +│ └── auth/login.vue # 认证与登录(身份切换 + 资质) +├── components/ # fc-navbar / fc-tabbar / fc-post-card / fc-empty +├── common/ +│ ├── config/index.js # 网关地址、开关、常量 +│ ├── utils/request.js # 统一请求层(鉴权/解包/401/降级) +│ ├── utils/{storage,format,pay}.js +│ ├── api/ # auth/home/post/member/distribution/message/admin +│ ├── assets/ # 图标注册表(icons.js)+ 轮播取图与主题护栏(banners.js) +│ ├── mock/ # 52 条 mock 路由 + 数据集(离线可跑) +│ ├── constants/ui.js # 状态/图标映射 +│ └── store/index.js # 轻量全局状态 +├── static/ # 74 枚图标 + 3 张轮播插画(banners/)+ LOGO +├── docs/ # 4 份交付文档 +└── tests/ # 零依赖测试与结构校验 +``` + +## 三、快速开始 + +### 3.1 运行小程序(HBuilderX) + +1. 用 **HBuilderX** 打开本目录(项目名为 `fenleixinxi`)。 +2. 运行 → 运行到小程序模拟器 → 微信开发者工具(或运行到浏览器 H5)。 +3. `manifest.json` 中 `mp-weixin.appid` 已配置为本项目小程序账号 `wxbfcb778f3019cff8`, + 如需换成自己的小程序,请同步修改(并保证后端 `fa_fc_config.wx.appid` 一致,见 README 8.2)。 + +> 未联调后端时无需任何配置:请求层会在网络不可用时自动降级到本地 Mock,**首页、发布、详情、会员、分销、消息、我的全链路均可离线体验**。 + +### 3.2 切换真实后端 + +编辑 `common/config/index.js`: + +```js +forceMock: false, // 关闭强制 mock +enableMockFallback: false, // 生产建议关闭降级,暴露真实问题 +``` + +网关默认:`https://fenleixinxi.gzyakj.com.cn/api`(与后台同域)。 + +## 五、图标与 LOGO 与轮播配图(全部为图片,可后台自定义) + +### 5.1 图标体系(配图 v2 · 全图片,真实透明) + +- **不使用任何矢量线条图标 / emoji**:全站图标均为 `static/icons/` 下的 **填充插画 PNG**(74 个,192×192,**真实透明通道**)。 +- **插画造型**:纯填充色块,形体饱满、笔画厚重;`主色 + 第二色 + 纯白高光` 三档配方,画面干净统一。 +- **配图与文字一一对应**:招聘求职→公文包、房产租售→房子、二手闲置→立体包裹箱、车辆买卖→汽车、本地服务→八齿齿轮、教育培训→学士帽、家政保洁→三重闪光、同城交友→爱心。 +- **徽章底**:浅色**垂直渐变**圆角块(如 `#E9F7F2 → #D2EFE5`),圆角 31%,与插画形成质感层次。 +- **统一注册表**:`common/assets/icons.js` 定义每个图标的 `key / 中文名 / 默认文件`,分 8 组。 +- **解析优先级**:后端下发的自定义地址 > `static/icons/` 内置默认图 + - 纯函数层:`common/utils/icon.js`(`iconUrl / logoUrl / categoryIconUrl`) + - 响应式层:`common/store/ui.js`(模板里直接调用即为响应式,后台改完立即生效) +- **重新生成配图**:修改 `tools/icon-svg.mjs`(`ART` 图形 + `OUTPUTS` 配色/渐变)后执行 + ```bash + node tools/gen-icons.mjs # 白底/黑底两遍渲染 + alpha 反解 + 降采样 + node tools/preview-theme.mjs --render # 出预览图并扫描旧色残留(改主题后必跑) + ``` + > 品牌色只集中在 `tools/icon-svg.mjs` 的 `OUTPUTS` 与 `uni.scss` 两处:**改主题 = 改这两处 + 重跑上面两条命令**。 + +### 5.2 首页轮播配图(Banner v2 · 绿底 + 白色插画) + +首页轮播由 **1 层后台底色 + 4 层页面绘制的装饰/文字** 叠加而成,**不使用整幅位图 banner**: + +``` +① 后台渐变底色 color ② 光晕 + 叶脉斜纹 + 双层远山(仅用中性半透明色) +③ 双圆环 + 白色插画大徽章 ④ 左侧压暗罩(保白字对比度) ⑤ 文字浮层(标签/标题/CTA) +``` + +- **白色插画**:`static/banners/banner-art-{1,2,3}.png`(192×192,真实透明,合计 6.0KB),按轮播位置循环: + ① 立体包裹箱(二手)② 公文包(招聘)③ 屋顶 + 门的小家(本地服务/上门)。 +- **主题护栏**:`common/assets/banners.js` 的 `bannerBg(banner, i)` **只认结构完整的渐变**(`linear-gradient(...)` 且含≥2 个色标、以 `)` 收尾); + 后台若仍是历史暖色纯色(`#FF8A5B` 等)、空值、或被字段宽度截断的半截值,都会自动回落内置春绿渐变 —— 换主题时即使线上数据没同步, + 首页也不会再冒出旧配色(后端可执行 `php think fc:install` 幂等对齐线上库)。 +- **金只给价值**:`bannerHasValue()` 为真(「直降 / 免费」)时,圆环右上嵌一颗金色宝石点;平台服务类不带金色。 +- **白字对比度实测**:4.93:1(banner 1)、7.09:1(banner 2)、5.86:1(banner 3),均 ≥ WCAG AA 4.5:1。 +- **重新生成插画**(仅在调整插画造型/配色时需要): + ```bash + node tools/gen-banner-art.mjs # SVG → 白底/黑底两遍渲染 + alpha 反解 → 192×192 透明 PNG + ``` +- **后台换整幅位图**:在「轮播管理」填 `image` 后铺满卡面并自动隐藏装饰层(该条轮播无需再用内置插画)。 +- **数据库字段**:`fc_banner.color` 已由 `varchar(16)` 扩到 `varchar(255)`(渐变串约 70 字符,16 会被截断成半截值); + 老库在服务器执行 `php think fc:install` 会自动扩容并把内置 3 条轮播回填为春绿渐变(亮绿 `#00E070` → 深绿 `#046B3B`)。 + +### 5.3 LOGO + +`static/logo.png`(512×512,春绿渐变 `#00E070→#00A855→#046B3B` 圆角方块 + 白色定位针 + 金色分类列表三条),统一用于: +- 小程序**首页左上角**(60rpx) +- **登录页**品牌区(140rpx) +- 后台设置页预览 + +### 5.4 后台自定义(可替换任意配图与 LOGO) + +打开 **我的 → LOGO 与图标设置**(`pages/admin/setting.vue`),或直接访问 `pages/admin/setting`: + +| 能力 | 说明 | +| --- | --- | +| 更换 LOGO | 上传图片 → 预览 → 保存,用户端首页/登录页同步生效 | +| 逐个替换配图 | 按分组列出全部 74 个图标,每个可「替换 / 默认」,已改动的显示「已改」角标 | +| 修改小程序名称 | 同步用于登录页标题 | +| 一键恢复 | 单个恢复默认 / 全部恢复默认 | + +对应接口(详见 `docs/03-接口文档.md`): + +| 方法 | 路径 | 说明 | +| --- | --- | --- | +| GET | `/setting/ui` | 用户端读取 `{ siteName, logo, icons }` | +| GET | `/admin/setting/ui` | 后台读取(含 `updatedAt`) | +| POST | `/admin/setting/ui` | 后台保存 `{ siteName, logo, icons }` | +| POST | `/admin/setting/ui/reset` | 全部恢复默认 | +| POST | `/admin/upload` | 图片上传(multipart,返回 `{ url }`) | + +## 六、执行测试 + +```bash +sh tests/run.sh +# 等价于依次执行: +# 1) node tests/validate.mjs 项目结构校验(路由/.vue 标签/SCSS 括号/import 依赖) +# 2) node tools/check-scss.cjs 用 dart-sass 编译全部 SCSS +# 3) node tests/run.mjs 全链路接口测试(139 例) +``` + +## 七、设计主色调(春绿 · Spring Green) + +| Token | 色值 | 用途 | +| --- | --- | --- | +| 品牌亮绿(主色) | `#00E070` | **面**:主按钮底、徽章、胶囊、选中态、轮播底(= 后台登录页同一品牌色号) | +| 亮绿上的字 | `#04301E` | 亮绿面上的文字(**8.2:1**;白字压亮绿只有 1.8:1,故一律不用白字) | +| 白字安全绿 | `#04874A` | 白字区(头部 / Hero / 渐变收尾,**4.6:1**);也是白底绿字、描边按钮用色 | +| 主色渐变(亮绿面) | `#00E070 → #00C860 → #00B85C` | 主按钮、选中态、指示条(配墨绿字) | +| Hero 渐变(深绿面) | `#04874A → #046B3B → #023A21` | 首页头部、我的 / 会员 / 分销头部、渐变导航条(配白字) | +| 深绿 / 极深绿 | `#046B3B` / `#023A21` | 会员资产卡、白字区收尾 | +| 辅助色(金) | `#F5A623` | 会员、热度、价格(只给「值得关注」的信息) | +| 页面底色 | `#F2FEF7` | 薄荷白底 | +| 主文字 | `#04291C` | 墨绿黑(替代纯黑) | + +> 设计立意:**春绿立品牌、收获金点价值** —— 亮绿只做「面」(按钮 / 徽章 / 胶囊 / 轮播底)并统一配墨绿字, +> 白字只落在 `#04874A` 及更深的绿面上;「绿=平台与内容、金=价值与特权」仍是品牌记忆点。 +> 90 分钟可复核:`node tools/preview-theme.mjs --render` 出图 + `node tools/run.mjs` 的「亮绿面不得配白字」回归用例。 + +配色自检 / 预览出图(改配色后必跑): + +```bash +node tools/preview-theme.mjs --render # 首页仿真 + 全量令牌色板;并自动扫描旧色残留 +``` + +详见 [`docs/02-UI设计规范.md`](docs/02-UI设计规范.md)。 + +## 八、当前验证状态 + +``` +[1/3] 项目结构校验 : 错误 0,警告 0 +[2/3] SCSS 编译校验 : 通过 17 个,失败 0(dart-sass) +[3/3] 全链路接口测试 : 用例总数 139 通过 139 失败 0 (通过率 100%) + —— 含 配图完整性与后台自定义闭环 16 例 + 轮播配图与主题护栏 14 例 + —— 含 v1.0.7 新增:我的发布 / 发布配置与计费 / 后台置顶闭环 15 例 +``` + +| 视觉资源 | 状态 | +| --- | --- | +| 配图数量 | 74 / 74(192×192,真实透明,尺寸统一) | +| 轮播插画 | 3 / 3(192×192 白色插画,合计 6.0KB) | +| 静态资源体积 | `static/` 616K(`icons/` 492K + `banners/` 12K[实际 6.0KB] + LOGO) | +| 小程序包体积 | 约 1.3M(主包上限 2M,余量充足) | +| 字号体系 | 24 / 26 / 28 / 32 / 36 / 42rpx(六档,跨度 1.75×) | + +### 8.1 后端接口(线上真实环境) + +后端 v1 业务接口已实现并部署到 `https://fenleixinxi.gzyakj.com.cn/api/v1`, +与本前端 `common/api/*.js` 的 65 个端点**逐一对应**,契约见 `docs/03-接口文档.md`。 + +``` +后端接口端到端验证(tools/verify-api.mjs) +用例总数: 183 通过: 183 失败: 0 + —— 65 端点契约 + 12 条业务规则文案比对 + 8 步双端业务闭环 + (用户发布 → 后台待审 → 后台审核 → 前台可见 → 消息通知 → 操作留痕) +``` + +**后端种子数据与本前端 `common/mock/data.js` 逐字段对齐**,因此把 +`common/config/index.js` 的 `forceMock` 关闭后,页面数据与离线演示完全一致。 + +> 切真实后端:将 `common/config/index.js` 的 `enableMockFallback` 置为 `false` +> (生产建议关闭降级,以便暴露真实问题)。 + +### 8.2 小程序线上发布记录 + +| 项 | 值 | +| --- | --- | +| AppID(前端 `manifest.json`) | `wxbfcb778f3019cff8` | +| AppSecret(仅后端持有) | `fa_fc_config.wx.secret`(**不下发前端**,仅服务端 `jscode2session` 调用) | +| 上传包体积 | **788.0 KB**(v1.0.7 上传实测,CLI 输出 806,887 字节;本地 173 文件 `wc -c` 合计 751,376 字节;v1.0.4 738,797 字节;主包上限 2MB,余量充足) | +| 待上传 | **v1.0.9**(173 文件 / 755,921 字节)已本地构建完成,正在等待开发者工具登录(本轮上传时登录态过期,报 `code 10 需要重新登录`);v1.0.8 构建完成但未上传,其改动已全部包含在 1.0.9 中,随 1.0.9 一并上传 | +| 上传状态 | v1.0.7 已于 2026-10-15 上传成功(`✔ Using AppID: wxbfcb778f3019cff8` → `✔ upload`,TOTAL 788.0 KB / 806,887 字节);v1.0.6 同日上传成功:`✔ Using AppID: wxbfcb778f3019cff8` → `✔ upload`(待人工在 mp 平台设为体验版 / 提交审核,并确认请求合法域名 `https://fenleixinxi.gzyakj.com.cn`) | +| 构建方式 | 生产构建(`unpackage/dist/build/mp-weixin`,无 sourcemap) | +| 接口指向 | `https://fenleixinxi.gzyakj.com.cn/api`(线上真实后端) | +| 产物校验 | 13 页面(含 `pages/post/mine`)· 74 配图 + 3 轮播插画 + LOGO · 春绿令牌已编译(`--fc-primary:#00e070`、主按钮 `linear-gradient(135deg,#00e070,…)`、头部 `linear-gradient(150deg,#04874a,#046b3b 55%,#023a21)`)· appid 正确 | + +| 版本 | 时间 | 内容 | +| --- | --- | --- | +| **1.0.0** | 2026-10-15 | 首个完整版本:用户端 9 大模块 + 后台管理端 10 大模块 | +| **1.0.1** | 2026-10-15 | 修复「后台改完前端不变」:关闭 mock 静默降级、首页 `onShow` 强制刷新后台配置 | +| **1.0.2** | 2026-10-15 | 打通余额支付:详情页新增「余额支付/微信支付」选择器;默认支付方式可配置 | +| **1.0.3** | 2026-10-15 | 修复发布页分类图标:原先把图标地址当文本显示(8 条路径重叠),改为 `image` 正常渲染 | +| **1.0.4** | 2026-10-15 | 小程序账号同步:AppID 由 `wxf611d31accda42e8` 更新为 `wxbfcb778f3019cff8`;前端 `manifest.json` 与后端 `fa_fc_config.wx.appid/wx.secret` 双端一致 | +| **1.0.5** | 2026-10-15 | 生态绿主题收尾 · **首页轮播配图重做**:后台底色 + 光晕/叶脉/远山装饰 + 双圆环白色插画大徽章 + 左侧压暗罩 + 文字浮层五层结构;白字对比度实测 ≥ 4.93:1;前端新增 `bannerBg()` 主题护栏(旧暖色纯色自动回落生态绿),后端 `FcInstall::BANNERS` 统一种子并新增幂等底色升级;新增 14 条轮播自动化用例(总用例 116,全绿) | +| **1.0.6** | 2026-10-15 | **春绿主题 v4(全站换色)**:品牌主色改为设计稿亮绿 `#00E070`(只做「面」,面上统一墨绿字 `#04301E` 8.2:1);新增 `$fc-primary-ink` / `$fc-primary-text` / `$fc-gradient-hero` 三枚令牌,白字只保留在深绿 Hero 与深绿渐变上;**74 枚图标 + LOGO + 3 张轮播插画全量重配春绿**;轮播卡由「绿底白字」改为「亮绿底 + 墨绿字 + 右侧深绿白插画」(105deg),实测最差对比度 4.71:1;页面底色 `#F2FEF7`、正文 `#04291C`;新增 3 条主题回归用例(总用例 119,全绿) | +| **1.0.7** | 2026-10-15 | **发布侧三件事(缺陷 + 两个新功能)**:① **「我的发布」页上线**——原先「我的」页入口指向 `/pages/post/list`(分类信息列表,只显示别人审核通过的信息),用户发完**看不到自己的发布记录**,现新增 `GET /post/mine`(按 全部/待审核/已通过/已驳回/已下架 筛选 + 各类计数 + 驳回原因)与 `pages/post/mine.vue`,发布成功后直接跳转该页;② **后台手动置顶**——`fc_post.is_top` 正式接入用户端:后台「信息管理」新增「置顶/取消置顶」(工具栏批量 + 行内按钮 + 状态徽章,附站内消息通知),`Home::feed` 与 `/post/mine` 均按 `is_top desc` 排序,卡片显示「置顶」角标;③ **免费/付费发布开关**——后台新增「发布与费用配置」页(同城业务 → 基础数据):发布模式(免费发布 / 付费发布)+ 会员单条发布价格 + 按月(价格 + 含条数)+ 按年(价格 + 含条数),保存后同步会员套餐(月卡 M1 / 年卡 M12);`fc_user_ext` 新增发布额度 `post_quota_left`,开通月/年卡自动发放额度、额度内免费发布(付费模式下仍保留「每日免费条数」避免硬付费墙);④ **计费改为服务端定价**(BUG-012):原先发布金额由前端 `amount` 传入并被后端直接采信,客户端可改价(0.01 元发帖),现金额一律按后台配置在服务端计算;新增 15 条用例(总用例 134,全绿) | +| **1.0.8** | 2026-10-16 | **会员手机号真绑定 + 后台会员列表字段调整**:① **修复「手机号授权绑定」假实现**(BUG-013)——原先登录页点击绑定只在前端拼 `138 + 时间戳` 的假号、从不落库,导致微信注册会员 `fa_user.mobile` 恒为空、后台会员列表手机号大面积为空;现改为 `