# 村社名片换肤等功能需增加接口 > 本文档仅供后端参阅,仅列出接口名称和输入输出参数,不涉及数据库设计。本文档的接口URL为建议值,实际实现时可根据情况调整。 --- ## 功能界面参考 ![image](https://server.imengyu.top/uploads/media/A6RCfcbXkkPm.jpg) ![image](https://server.imengyu.top/uploads/media/MjihNKtTirSn.jpg) ![image](https://server.imengyu.top/uploads/media/n3zJsKD7nJXF.jpg) ![image](https://server.imengyu.top/uploads/media/MinsPZNi8nG5.jpg) ## 一、皮肤模块 > **提示**:皮肤需要能在后台管理系统中进行增删改查(含皮肤图片上传、主题JSON配置等)。 ### 1.1 获取皮肤列表(皮肤中心) **用途**:分页获取所有可购买的皮肤列表(皮肤中心页面)。 | 项目 | 说明 | |------|------| | **方法** | `POST` | | **路径** | `/village/skin/list` | **输入参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | page | int | 否 | 页码,默认1 | | pageSize | int | 否 | 每页数量,默认20 | **输出**: ```json { "total": 10, "list": [ { "id": 1, "title": "默认皮肤", "desc": "默认的村社名片", "image": "https://xxx/thumb.jpg", "images": [ ... ], "price": 0 } ] } ``` | 字段 | 类型 | 说明 | |------|------|------| | total | int | 总数 | | list[].id | int | 皮肤ID | | list[].title | string | 标题 | | list[].desc | string | 描述 | | list[].image | string | 封面缩略图URL | | list[].images | string[] | 皮肤预览图列表(多张可左右滑动) | | list[].price | int | 价格(乡源果),0=免费 | --- ### 1.2 获取推荐/热门皮肤 **用途**:主页换肤页顶部"热门皮肤"展示,仅展示少量推荐皮肤。 | 项目 | 说明 | |------|------| | **方法** | `POST` | | **路径** | `/village/skin/recommend` | **输入参数**:无 **输出**: ```json { "list": [ { "id": 1, "title": "默认皮肤", "desc": "默认的村社名片", "price": 99, "image": "https://xxx/thumb.jpg", "images": [ ... ] } ] } ``` | 字段 | 类型 | 说明 | |------|------|------| | list[].id | int | 皮肤ID | | list[].title | string | 标题 | | list[].desc | string | 描述 | | list[].image | string | 封面缩略图URL | | list[].images | string[] | 皮肤预览图列表(多张可左右滑动) | --- ### 1.3 获取皮肤详情 **用途**:皮肤详情页,展示皮肤预览图和购买/使用按钮。需判断当前用户是否已购买。 | 项目 | 说明 | |------|------| | **方法** | `POST` | | **路径** | `/village/skin/detail` | **输入参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | id | int | 是 | 皮肤ID | | villageId | int | 是 | 村社ID(用于判断是否已购买) | **输出**: ```json { "id": 1, "title": "默认皮肤", "desc": "默认的村社名片", "image": "https://xxx/thumb.jpg", "images": [ "https://xxx/preview1.jpg", "https://xxx/preview2.jpg" ], "price": 99, "isBought": false } ``` | 字段 | 类型 | 说明 | |------|------|------| | id | int | 皮肤ID | | title | string | 标题 | | desc | string | 描述 | | image | string | 封面缩略图URL | | images | string[] | 皮肤预览图列表(多张可左右滑动) | | price | int | 价格(乡源果) | | isBought | bool | 当前用户在当前村社是否已购买该皮肤 | --- ### 1.4 购买皮肤 **用途**:下单购买皮肤,返回订单信息和微信支付参数。 | 项目 | 说明 | |------|------| | **方法** | `POST` | | **路径** | `/village/skin/buy` | **输入参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | skinId | int | 是 | 皮肤ID | | villageId | int | 是 | 村社ID | **输出**: ```json { "order": { "id": 100, "orderNo": "SK202501010001", "skinId": 1, "villageId": 10, "price": 99, "status": 0, "createtime": "2025-01-01 12:00:00" }, "pay": { "appId": "wxXXX", "timeStamp": "1704096000", "nonceStr": "abc123", "package": "prepay_id=xxx", "signType": "MD5", "paySign": "signature" } } ``` | 字段 | 类型 | 说明 | |------|------|------| | order.id | int | 订单ID | | order.orderNo | string | 订单号 | | order.price | int | 支付金额 | | order.status | int | 状态:0=待支付,1=已支付 | | pay | object | 微信支付参数(若price=0则为null,直接购买成功) | --- ### 1.5 使用皮肤 **用途**:将已购买的皮肤应用到指定村社。 | 项目 | 说明 | |------|------| | **方法** | `POST` | | **路径** | `/village/skin/apply` | **输入参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | skinId | int | 是 | 皮肤ID | | villageId | int | 是 | 村社ID | **输出**:无特殊数据。 --- ### 1.6 获取我的已购皮肤 **用途**:获取当前用户在指定村社下已购买的皮肤列表。 | 项目 | 说明 | |------|------| | **方法** | `POST` | | **路径** | `/village/skin/myPurchased` | **输入参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | villageId | int | 是 | 村社ID | **输出**: ```json { "list": [ { "id": 1, "title": "默认皮肤", "desc": "默认的村社名片", "image": "https://xxx/thumb.jpg", "price": 0 } ] } ``` --- ### 1.7 获取皮肤订单列表 **用途**:分页获取皮肤购买订单记录。 | 项目 | 说明 | |------|------| | **方法** | `POST` | | **路径** | `/village/skin/orderList` | **输入参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | page | int | 否 | 页码,默认1 | | pageSize | int | 否 | 每页数量,默认20 | | villageId | int | 否 | 村社ID(筛选) | | userId | int | 否 | 用户ID(筛选) | **输出**: ```json { "total": 5, "list": [ { "id": 100, "skinTitle": "古风主题", "villageName": "大庆村", "price": 99, "status": 1, "statusText": "已支付", "createtime": "2025-01-01 12:00:00" } ] } ``` | 字段 | 类型 | 说明 | |------|------|------| | total | int | 总数 | | list[].id | int | 订单ID | | list[].skinTitle | string | 皮肤标题 | | list[].villageName | string | 村社名称 | | list[].price | int | 金额 | | list[].status | int | 状态 | | list[].statusText | string | 状态文本 | | list[].createtime | string | 创建时间 | --- ### 1.8 获取村社当前皮肤数据 **用途**:获取村社当前使用的名片主题/皮肤完整数据(JSON 结构)。 > 该接口在进入村社名片主页时调用。 | 项目 | 说明 | |------|------| | **方法** | `POST` | | **路径** | `/village/skin/current` | **输入参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | villageId | int | 是 | 村社ID | **输出**:返回一个 DynamicXPage JSON 对象,结构参考 `src/pages/home/village/introd/data/DefaultCard.json`。该 JSON 描述名片页面的布局、组件类型、颜色、按钮行为等。示例如下: ```json { "name": "VILLAGE", "type": "page", "props": {}, "nodes": [ { "name": "VILLAGE:CONTENT", "type": "flex", "props": { "direction": "column", "padding": [30, 30, 0, 30], "gap": "gap.lg" }, "nodes": [ { "type": "BackgroundBox", "props": { "color1": "#eecaa0", "color2": "white", "color2Position": "85%", "radius": "radius.lg", "direction": "column", "padding": [35, 30], "gap": "gap.lg" }, "nodes": [ { "type": "Card:Basic" }, { "type": "Card:Level" }, { "type": "Card:Gallery" }, { "type": "Card:AddressAndMap" }, { "type": "flex", "props": { "direction": "row", "justify": "center", "gap": "gap.md" }, "nodes": [ { "type": "button", "props": { "text": "村社相册" }, "events": { "click": "globalContext.handleGoGallery()" } }, { "type": "button", "props": { "text": "编辑简介" }, "events": { "click": "globalContext.handleGoEdit()" } }, { "type": "button", "props": { "text": "主页换肤" }, "events": { "click": "globalContext.handleGoSkin()" } } ] }, { "type": "Card:Static" } ] }, { "type": "Block:Rank", "props": { "title": "排行榜" } }, { "type": "Block:Collect", "props": { "title": "魅力乡源" } }, { "type": "Block:Games", "props": { "title": "活力乡源", "items": [...] } }, { "type": "Block:Official", "props": { "title": "文脉乡源" } } ] } ] } ``` > 每个皮肤需要存储一份这样的 JSON,村社使用某皮肤时即返回该皮肤对应的 JSON。后台管理系统创建/编辑皮肤时需要能编辑此 JSON 配置。 --- ## 二、管理主页栏目显示与顺序 ### 2.1 获取村社栏目配置 **用途**:获取村社名片主页的栏目配置(栏目显示/隐藏、排列顺序)。 | 项目 | 说明 | |------|------| | **方法** | `POST` | | **路径** | `/village/column/getConfig` | **输入参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | villageId | int | 是 | 村社ID | **输出**:返回栏目配置 JSON。具体结构由前端确定,每项包含栏目标识,栏目数据和顺序,后端只需要保存JSON即可。 **与采集栏目关联**:待后端 采集栏目 相关接口设计完成后,此处下方 Block:Collect 与后端 采集栏目 管理并合并成最终列表。 ```json { "columns": [ { "type": "Card:Basic", "visible": true, "sort": 1 }, { "type": "Card:Level", "visible": true, "sort": 2 }, { "type": "Card:Gallery", "visible": true, "sort": 3 }, { "type": "Block:Rank", "visible": true, "sort": 4 }, { "type": "Block:Collect", "visible": true, "sort": 5, "props": { "title": "文脉乡源", "items": [ ... ] } }, { "type": "Block:Games", "visible": true, "sort": 6, "props": { "title": "魅力乡源" , "items": [ ... ] } }, { "type": "Block:Official", "visible": true, "sort": 7, "props": { "title": "文脉乡源" } } ] } ``` | 字段 | 类型 | 说明 | |------|------|------| | * | ? | 由前端确定 | --- ### 2.2 保存村社栏目配置 **用途**:保存编辑后的村社名片栏目配置。 | 项目 | 说明 | |------|------| | **方法** | `POST` | | **路径** | `/village/column/saveConfig` | **输入参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | villageId | int | 是 | 村社ID | | data | json | 是 | 栏目配置 JSON,结构同 2.1 输出 | **输出**:无特殊数据。 --- ## 三、管理贴图话题列表 ### 3.1 获取村社话题列表 **用途**:获取村社贴图话题列表(用于话题标签展示和管理)。若未配置则使用默认话题。 | 项目 | 说明 | |------|------| | **方法** | `POST` | | **路径** | `/village/topic/getTopicTags` | **输入参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | villageId | int | 是 | 村社ID | **输出**: ```json { "tags": [ { "title": "广场", "icon": "", "disabled": false, "sort": 1 }, { "title": "美食", "icon": "", "disabled": false, "sort": 2 }, { "title": "美景", "icon": "", "disabled": false, "sort": 3 } ] } ``` | 字段 | 类型 | 说明 | |------|------|------| | tags[].title | string | 话题名称 | | tags[].icon | string | 话题图标URL(可空) | | tags[].disabled | bool | 是否禁用 | | tags[].sort | int | 排序序号 | > 若村社未配置话题,返回空数组,前端将使用默认话题列表:`['广场', '美食', '美景', '故事', '老技艺', '老物件']` --- ### 3.2 保存村社话题列表 **用途**:保存编辑后的村社贴图话题列表(含排序和新增/删除)。 | 项目 | 说明 | |------|------| | **方法** | `POST` | | **路径** | `/village/topic/saveTopicTags` | **输入参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | villageId | int | 是 | 村社ID | | tags | array | 是 | 话题标签数组,结构同 3.1 输出 | **输出**:无特殊数据。 --- ## 四、接口汇总清单 | 序号 | 模块 | 接口名称 | 方法 | 路径 | |------|------|----------|------|------| | 1.1 | 皮肤 | 获取皮肤列表 | POST | `/village/skin/list` | | 1.2 | 皮肤 | 获取推荐皮肤 | POST | `/village/skin/recommend` | | 1.3 | 皮肤 | 获取皮肤详情 | POST | `/village/skin/detail` | | 1.4 | 皮肤 | 购买皮肤 | POST | `/village/skin/buy` | | 1.5 | 皮肤 | 使用皮肤 | POST | `/village/skin/apply` | | 1.6 | 皮肤 | 获取已购皮肤 | POST | `/village/skin/myPurchased` | | 1.7 | 皮肤 | 获取皮肤订单 | POST | `/village/skin/orderList` | | 1.8 | 皮肤 | 获取村社当前皮肤 | POST | `/village/skin/current` | | 2.1 | 栏目 | 获取栏目配置 | POST | `/village/column/getConfig` | | 2.2 | 栏目 | 保存栏目配置 | POST | `/village/column/saveConfig` | | 3.1 | 话题 | 获取话题列表 | POST | `/village/topic/getTopicTags` | | 3.2 | 话题 | 保存话题列表 | POST | `/village/topic/saveTopicTags` | --- ## 五、前端 TODO 对照说明 | 文件 | TODO 标记 | 对应接口 | |------|-----------|----------| | `card.vue:709` | `//TODO: 加载村社主题` | **1.8** 获取村社当前皮肤 | | `card.vue:713` | `//TODO: 加载村社话题` | **3.1** 获取话题列表 | | `config.vue:62-76` | `recommendLoader` 静态数据 | **1.2** 获取推荐皮肤 | | `skin/skin.vue:42` | `//TODO: 缺少接口` | **1.1** 获取皮肤列表 | | `skin/details.vue:57` | `//TODO: 缺少接口` | **1.3** 获取皮肤详情 | | `skin/details.vue:74` | `//TODO` (handleBuy) | **1.4** 购买皮肤 | | `skin/details.vue:78` | `//TODO` (handleUse) | **1.5** 使用皮肤 | | `skin/buied.vue:29` | `//TODO: 缺少接口` | **1.6** 获取已购皮肤 | | `skin/orders.vue:73` | `//TODO: 更换为获取皮肤订单接口` | **1.7** 获取皮肤订单 | | `config/config-tags.vue:79` | `//TODO: saveTags()` | **3.2** 保存话题列表 | | `config/config-tags.vue:87` | `//TODO: getTags()` | **3.1** 获取话题列表 |