# 西宁市党建联盟社区共享自习室 · 微信小程序（一期）

> 一期范围：**找自习室（地图＋列表）· 自习室详情 · 我的 · 我的收藏 · 信息纠错 · 实名认证**
> 视觉：**党建红色系**（党旗红 #C1272D / 深党旗红 #9E1B24 / 高原金 #C9A227）
> **不包含**：选座预约、到馆签到、自习时长统计、党建联盟 Tab、阵地活动报名、积分、评价（均为二期）

---

## 一、快速运行

1. 打开 **微信开发者工具** → 导入项目 → 目录选到本文件夹（`XnzxsProject`）。
2. `project.config.json` 里的 `appid` 目前是 `touristappid`（游客模式）。正式开发请替换为西宁党建小程序的 AppID。
3. 首次运行需在开发者工具中授予**位置权限**（详情 → 本地设置 → 勾选"使用真实位置"或在模拟器中设定西宁市坐标，如 `36.6171, 101.7782`）。
   - 未授权也能正常使用：地图以市中心为中心，列表显示"距离未知"，不会白屏。
4. 建议基础库版本 **2.20.0 以上**（地图聚合 `enable-cluster` 需要）。
5. 编译即可看到首页。底部两个 Tab：**找自习室 / 我的**。

---

## 二、目录结构

```
XnzxsProject/
├── app.js                  # 全局数据（自习室、四区边界、设施字典）
├── app.json                # 页面注册、窗口样式、tabBar、位置权限声明
├── app.wxss                # 全局主题令牌 + 通用组件（卡片/标签/徽章/按钮/键值行/空态）
├── project.config.json     # 开发者工具项目配置
├── sitemap.json
├── assets/                 # 图标与占位图（全部本地，无外链）
│   ├── tab-home.png / tab-home-on.png / tab-mine.png / tab-mine-on.png
│   ├── marker-room.png / marker-alliance.png / blank.png   # 普通标点 / 示范点 / 区名标注占位
│   ├── room-1.jpg ... room-6.jpg                           # 实景图占位（需替换）
│   ├── avatar.png / empty.png
├── data/
│   └── rooms.js            # 14 间演示自习室 + 四区边界 + 设施字典
├── utils/
│   ├── util.js             # 距离计算、距离格式化、手机号脱敏、状态映射、导航、拨号、防抖
│   ├── store.js            # 收藏 / 纠错 / 实名认证 本地存储封装
│   └── icons.js            # 矢量 SVG 图标库（data URI 注入颜色，零位图、零外链）
└── pages/
    ├── index/              # 首页 · 找自习室（地图＋列表＋搜索＋筛选＋排序）
    ├── detail/             # 自习室详情
    ├── mine/               # 我的
    ├── favorites/          # 我的收藏
    ├── correct/            # 信息纠错
    └── verify/             # 实名认证
```

---

## 三、需求对照（逐条落地）

### 1. 首页顶部地图，展示城中区、城西区、城北区、城东区并标点

| 要求 | 实现 |
|---|---|
| 四区地图 | `<map>` + `<polygon>` 四区着色描边（城中红 / 城西蓝 / 城北绿 / 城东金），左上有四区图例；区名用 `callout` 常显标注 |
| 标点显示自习室 | `markers` 标点：普通自习室党旗红水滴，**党建联盟示范点加高原金圆环**；同屏超 12 个自动聚合（`enable-cluster`） |
| 点标交互 | 点击标点 → 底部浮出气泡卡（名称/县区/社区/距我/状态），卡上直接带【导航】【详情】 |
| 地图↔列表联动 | ① 上滑列表，地图自动居中当前卡片；② 拖动/缩放地图后，列表自动过滤为可视范围内；③ 右侧浮动按钮"我的位置""全览四区" |
| 定位授权 | 拒绝授权自动降级为市中心中心点，不出现空白地图 |

### 2. 地图下方列表，8 个字段齐全

| 需求字段 | 卡片中的位置 |
|---|---|
| 自习室名称 | 卡片标题 ＋ 状态徽章（开放中/已满/暂停开放） |
| 所在县区 | 红色标签（区）＋ 灰色标签（社区） |
| 位置信息 | 详细地址 ＋ "距我 1.2km"；**点击即唤起微信地图导航** |
| 推荐理由 | 金色左边框高亮块，最多 2 行，超出省略 |
| 配套措施 | 蓝色标签最多显示 4 个 ＋ "等 N 项" |
| 联系人 | 姓名 ＋ 职务 |
| 联系方式 | 脱敏显示 `138****8801`，**点击确认后拨号** |
| 自习室图片 | 左侧主图 ＋ 右下角"N 张"角标 |

**点击卡片** → 详情页；**点击位置** → 地图导航；**点击电话** → 拨号（用 `catchtap` 阻止冒泡，互不干扰）。

**排序**：智能推荐（联盟示范点优先→距离近优先）／距离最近。
**筛选**：按区（全部/城中/城西/城北/城东）、按配套（10 项多选）、仅看开放中。
**异常兜底**：无结果→空态图＋"重置筛选"；未定位→"距离未知"；地图失败→列表仍可独立使用。

### 3. 详情页

图册轮播（可点击看大图、右下角"N/M 张"）→ 标题区（区/社区/状态/联盟示范点金标）→ **推荐理由高亮卡** → 基础信息（地址可导航、开放时间、座位总数、联系电话、所属党组织、信息更新时间）→ 配套设施栅格（10 项，有则亮无则灰）→ 推荐理由详情 → 联系人（头像＋职务＋拨号）→ 底部固定操作条【导航前往｜拨号｜收藏｜分享】。

**隐私规则**：联系方式在列表脱敏，详情页需**点击一次才展示完整号码**，第二次点击才拨出。

### 4. 党建红色系（验收标准）

- 色板集中在 `app.wxss` 的 `page { --djh / --dj2 / --gyj / --qhh / --qkl ... }`，**全站只允许出现这套色值**，红色只有"党旗红/深党旗红"两支。
- 红色只用于**顶部导航、主按钮、重点数据、选中态**（导航栏 `#9E1B24`、tabBar 选中 `#C1272D`、主按钮红金渐变），大面积留白用米白底 `#F7F5F1`，红色占比远低于 30%。
- 图标**全部为矢量 SVG**（`utils/icons.js`，data URI 注入颜色），**无 emoji、无位图图标、无外链**。
- 金色只用于荣誉类（联盟示范点、推荐理由高亮、收藏）。

---

## 四、上线前必须替换（3 项）

1. **经纬度**：`data/rooms.js` 中的 `latitude / longitude` 现为演示坐标，**必须到店门口实地采集**。
   严禁用地址地理编码批量生成——西宁老城区误差可达数百米，会出现"导航送到对面小区"。
2. **四区边界**：`polygons` 为示意矩形，需替换为实际行政区划 GeoJSON 边界。
3. **基础台账**：地址、开放时间、座位总数、联系人、联系电话、配套措施、推荐理由，以**社区填报 → 区委组织部审核**后的台账为准；`assets/room-*.jpg` 需替换为实拍图。

---

## 五、接入后端

演示数据与收藏/纠错/认证都走本地（`data/rooms.js`、`utils/store.js`）。接后端时：

| 位置 | 改法 |
|---|---|
| `data/rooms.js` 的 `rooms` | 改为请求 `/api/rooms`，字段名保持不变，页面无需改动 |
| `utils/store.js` 的 `getFavorites / toggleFavorite` | 改为调用收藏接口 |
| `utils/store.js` 的 `addCorrect` | 改为 POST 到纠错工单接口 |
| `utils/store.js` 的 `getVerify / setVerify` | 改为调用实名认证接口 |

页面只依赖这几个函数签名，替换实现即可，**不需要动 wxml**。

---

## 六、验收清单对照

| 验收项 | 本代码实现 |
|---|---|
| 地图完整显示城中/城西/城北/城东四区 | ✅ `polygons` 四色分区 ＋ 图例 ＋ 区名标注 |
| 标点准确、误差 < 50m | ⚠️ 代码支持，**需实地采集坐标后替换演示数据** |
| 列表 8 个字段齐全 | ✅ 见上表逐条对照 |
| 点击位置唤起微信地图导航 | ✅ `wx.openLocation`（无需地图权限） |
| 点击电话确认后拨出 | ✅ `wx.makePhoneCall`，列表脱敏 |
| 点卡片进详情，返回不丢列表位置 | ✅ `navigateTo` 返回，页面不销毁，滚动与筛选状态保留 |
| 地图与列表双向联动 | ✅ 列表滑动→地图跟随；地图拖动→列表过滤 |
| 拒绝定位有降级方案、不白屏 | ✅ 降级为市中心，距离显示"距离未知" |
| 弱网/无数据/失败有提示与重试 | ✅ 空态图 ＋ "重置筛选" |
| 底部操作条无预约类按钮 | ✅ 【导航｜拨号｜收藏｜分享】 |
| 全站无预约/选座/凭证/签到/时长 | ✅ 全局搜索无相关代码与入口 |
| 党建红色系、红色 ≤30%、色板唯一 | ✅ 色板集中在 `app.wxss` |
| 图标矢量 SVG、无 emoji、无外链 | ✅ `utils/icons.js`，已脚本校验无 emoji |
| 无占位文字（TODO/待补充） | ✅ 已脚本校验 |
| 专有名词加中文引号 | ✅ "党建联盟""书香里"等 |

---

## 七、常用改动指引

- **加一间自习室**：在 `data/rooms.js` 的 `rooms` 数组追加一条，字段照抄现有记录（19 个字段）。
- **加一个配套设施**：在 `data/rooms.js` 的 `facilities` 增加 `{key, name, icon}`；若图标库里没有，在 `utils/icons.js` 的 `PATHS` 加一条 24×24 的 path。详情页栅格按 5 列自适应。
- **改主题色**：只改 `app.wxss` 顶部 `page {}` 里的色值即可，全站生效。
- **改展示范围到湟中/大通/湟源**：在 `districts` 与 `polygons` 追加即可，首页筛选 chips 自动跟随。

---

## 八、已知限制（如实说明）

1. 演示数据中 14 间自习室为**虚构名称＋示意坐标**，仅用于跑通功能，不代表真实台账。
2. `assets/room-*.jpg` 是**程序生成的占位图**（带"图片占位·请替换为实拍图"字样），必须替换。
3. 四区边界为示意矩形，非实际区划。
4. 收藏／纠错／实名认证保存在本机 `wx.setStorageSync`，换设备不同步，正式版需后端。
5. 地图聚合 `enable-cluster` 需基础库 ≥ 2.20.0；低版本会自动退化为不聚合，不影响功能。
6. 本机无微信开发者工具，因此**未做真机／模拟器运行验证**；已完成的验证为：JSON/JS 语法检查、WXML 标签闭合、WXSS 花括号平衡、class 全覆盖、图片路径存在性、字段完整性与坐标范围、emoji 检查，以及首页筛选/排序/距离逻辑的 Node 运行测试（全部通过）。
