From 3961d6324ac9b7757c6bfb8ecea6cb1b3caca6ee Mon Sep 17 00:00:00 2001
From: zjk <852185829@qq.com>
Date: 星期三, 14 十月 2026 11:44:21 +0800
Subject: [PATCH] feat(member-center): 新增会员中心全业务功能模块

---
 hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountWarehouseMapper.xml                     |   13 
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountWarehouseMapper.java               |   22 
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/PurchaseOrderVo.java                   |  130 +
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/AccountSalesRecord.java                   |  186 ++
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/AccountPurchaseOrder.java                 |  186 ++
 hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountWarehouseRecordMapper.xml               |   63 
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/SalesMonthSummaryVo.java               |   63 
 hugray-user-miniapp/pages.json                                                                                       |    7 
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/SalesTrendItemVo.java                  |   58 
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/MemberWarehouseVo.java                 |   89 +
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/WarehouseRecordVo.java                 |  117 +
 hugray-server/sql/hugray_account_member_center_20261014.sql                                                          |   96 +
 doc/design/用户端_会员中心_20261014.md                                                                                      |  475 ++++++
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/ProductSalesRatioVo.java               |   35 
 hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountSalesRecordMapper.xml                   |   77 +
 hugray-user-miniapp/pages/profile/index.vue                                                                          |    5 
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/MemberSalesStatisticsVo.java           |  144 +
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountSalesRecordMapper.java             |   72 
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/dto/MemberPurchaseDto.java                |   54 
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountWarehouseRecordMapper.java         |   29 
 hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountPurchaseOrderMapper.xml                 |   76 +
 hugray-user-miniapp/api/index.js                                                                                     |   43 
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/enums/WarehouseChangeTypeEnum.java               |   70 
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/controller/AccountMemberController.java          |  110 +
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/AccountWarehouseRecord.java               |  163 ++
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/enums/PurchaseOrderStatusEnum.java               |   66 
 hugray-user-miniapp/pages/member/index.vue                                                                           | 1394 ++++++++++++++++++
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountPurchaseOrderMapper.java           |   42 
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/service/IAccountMemberCenterService.java         |   59 
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/SalesUserRankingVo.java                |   63 
 hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/service/impl/AccountMemberCenterServiceImpl.java |  387 +++++
 31 files changed, 4,394 insertions(+), 0 deletions(-)

diff --git "a/doc/design/\347\224\250\346\210\267\347\253\257_\344\274\232\345\221\230\344\270\255\345\277\203_20261014.md" "b/doc/design/\347\224\250\346\210\267\347\253\257_\344\274\232\345\221\230\344\270\255\345\277\203_20261014.md"
new file mode 100644
index 0000000..3424287
--- /dev/null
+++ "b/doc/design/\347\224\250\346\210\267\347\253\257_\344\274\232\345\221\230\344\270\255\345\277\203_20261014.md"
@@ -0,0 +1,475 @@
+# 用户端小程序 个人中心-会员中心 接口 开发设计文档
+
+- 模块:ruoyi-user(会员业务)
+- 日期:2026-10-14
+- 需求来源:“这是个人中心-会员中心的原型,根据 pen 源文件的设计风格设计 UI 然后实现页面和后端的业务功能”
+- 关联前端:`hugray-user-miniapp`(新增 `pages/member/index.vue`)
+- 关联文档:`doc/design/用户端_个人中心_20261013.md`(会员等级 / 收益 / 登录取数范式)、`doc/design/用户端_收货地址_20261014.md`(C 端接口范式)
+- 数据权威源:`192.168.110.111:3306/hugray-account`(实际表结构优先于本文档)
+- 设计风格源:`doc/琥歌瑞0928.pen`(深蓝渐变卡 `#003E7E→#1E5EBC`、白玻璃卡、草绿主按钮 `#82C236→#639C1F`)
+
+---
+
+## 一、功能概述
+
+会员中心页(原型图一「会员中心」/ 图二「我的会员」)为 L1~L4 会员专属页面,包含两个 Tab:
+
+| Tab | 原型位置 | 展示内容 |
+| --- | --- | --- |
+| 销售统计 | 图一 | 深蓝卡(脱敏手机号 + 当前等级 + 等级详情);当月销售额 / 当月进货额 / 当月利润;当月利润额大数 + 环比;销售额折线图(按日 1~20 号);商品销售额比例饼图;销售用户排行列表 |
+| 我的仓库 | 图二 | 深蓝卡(同上);商品列表(商品图占位 + 名称 + 当前库存 + 最低需求库存 + 进货 / 仓库记录按钮);低库存警示(`当前库存` 红字 + 蓝色提示条) |
+
+展示规则(沿用已确认业务约定):`isRestrictedView = !isLoggedIn || memberLevel === 'C'`。**未登录或 C 普通用户**不展示会员中心入口;接口虽不校验等级,但前端受限态不进入该页。会员身份取自网关注入的登录态,天然防水平越权。
+
+**本期新增 5 个 C 端接口**(对应前端新增的会员中心接口):
+
+| # | 接口 | 用途 |
+| --- | --- | --- |
+| 1 | `GET /miniapp/account/user/member/sales-statistics` | 销售统计(三栏 + 趋势 + 比例 + 排行) |
+| 2 | `GET /miniapp/account/user/member/warehouses` | 我的仓库列表(含低库存标记) |
+| 3 | `POST /miniapp/account/user/member/purchase` | 进货(生成进货单 + 增库存 + 记流水) |
+| 4 | `GET /miniapp/account/user/member/warehouse-records` | 仓库变动记录(进货/库存流水) |
+| 5 | `GET /miniapp/account/user/member/purchase-orders` | 进货订单列表 |
+
+---
+
+## 二、现状与关键约束
+
+### 2.1 表结构现状
+
+| 表 | 现状 | 本次是否新增 |
+| --- | --- | --- |
+| `account_user` | 已有 `system_level`(会员等级);9 个业务统计列(`sell_amount_total` 等)为“待回填”占位,无写入方 | 否(只读) |
+| `account_warehouse` | 已有:`user_id`/`product_name`/`stock_qty`/`min_stock_qty`/`del_flag` 等,配套实体 + Mapper + XML 齐备 | 否(只读 + 更新库存) |
+| 会员销售流水 | **无** | 是 → `account_sales_record` |
+| 会员进货单 | **无** | 是 → `account_purchase_order` |
+| 云仓变动流水 | **无** | 是 → `account_warehouse_record` |
+
+### 2.2 已有接口缺口
+
+`ruoyi-user` 现有 C 端控制器 `AccountProfileController`(`/user`)仅覆盖个人中心 / 认证 / 邀请 / 收获地址;**无仓库、进货、销售统计相关接口**。`AccountWarehouseMapper` 已有 `selectWarehouseByUserId` / `insertWarehouse` / `updateWarehouse`,但**缺 Service 层与 C 端查询接口**。
+
+### 2.3 销售数据来源(已确认决策)
+
+后端无任何订单 / 交易模块(`ruoyi-product` 仅启动类,`hugray-order` 零表),故:
+
+- **销售统计采用“新建简化销售流水模型”**:`account_sales_record` 一条流水 = 一次销售事件(销售额 + 利润),本月三栏与趋势 / 比例 / 排行均由流水实时聚合。
+- **进货采用“真实进货”**:`POST .../purchase` 生成一条 `account_purchase_order`,同时增加 `account_warehouse.stock_qty` 并追加一条 `account_warehouse_record`;当月进货额由进货单实时聚合。
+- `account_user` 的 9 个“待回填”统计列**本期不回填**(避免双写口径不一致),页面数据一律由流水表实时聚合。
+
+### 2.4 金额单位约定
+
+沿用用户规范与既有约定:接口金额一律 **分(long)** 返回,前端 `formatYuan(fen, withThousands)` 格式化为元(两位小数,可带千分位)。
+
+### 2.5 当月利润口径
+
+`利润 = 销售额 − 进货成本`(按销售流水 `profit_amount` 字段逐条落库,聚合时 `SUM(profit_amount)`)。**说明**:销售流水写入方(订单模块)尚未就绪,本期利润随销售流水数据而来;无流水时为 0。
+
+---
+
+## 三、接口设计
+
+统一响应体:`R<T>`(`code=200` 成功)。前端 `utils/request.js` 按 `successCode=200` / `unauthorizedCode=401` 解包,调用方取 `res.data`。
+
+> 规范说明:用户规则中的“`Result<T>`、`code=0 成功`”为通用模板;本工程实际框架为 RuoYi `R`(200 成功)+ `@RestControllerAdvice` 全局异常。按“与现有工程保持一致”优先,采用框架既有约定。
+
+### 3.1 查询销售统计
+
+- **外部路径**:`GET /miniapp/account/user/member/sales-statistics`(网关 `StripPrefix=2` → 服务内 `/user/member/sales-statistics`)
+- **鉴权**:需登录(不在白名单,未登录由 `AuthFilter` 返回 401)
+- **入参**:无(会员身份取自网关注入的 `user_id` 头)
+- **出参**:`R<MemberSalesStatisticsVo>`
+
+```json
+{
+  "code": 200,
+  "msg": "操作成功",
+  "data": {
+    "phone": "136****6666",
+    "memberLevel": "L2",
+    "monthSalesAmount": 19210000,
+    "monthPurchaseAmount": 19210000,
+    "monthProfitAmount": 192100,
+    "monthSalesCount": 86,
+    "profitGrowthRate": 14,
+    "salesTrend": [
+      { "day": "1号", "amount": 300000 },
+      { "day": "5号", "amount": 420000 }
+    ],
+    "productSalesRatio": [
+      { "productName": "G&METS-V", "amount": 1245100 },
+      { "productName": "G&METS-II", "amount": 1245100 }
+    ],
+    "salesUserRanking": [
+      { "rank": 1, "nickname": "张三", "phone": "138****4561", "amount": 1645200 }
+    ]
+  }
+}
+```
+
+| 字段 | 类型 | 说明 |
+| --- | --- | --- |
+| phone | String | 当前会员手机号(**脱敏**) |
+| memberLevel | String | 会员等级 `C`/`L1~L4`(兜底 `C`) |
+| monthSalesAmount | Long | 当月销售额(分)= `SUM(account_sales_record.amount)` |
+| monthPurchaseAmount | Long | 当月进货额(分)= `SUM(account_purchase_order.total_amount)` |
+| monthProfitAmount | Long | 当月利润额(分)= `SUM(account_sales_record.profit_amount)`,可为负 |
+| monthSalesCount | Integer | 当月销售单数 = `COUNT(account_sales_record)` |
+| profitGrowthRate | Integer | 当月利润环比上月提升百分比(`Math.round`,无上月数据时返回 0) |
+| salesTrend[].day | String | 日标签(`1号`~`31号`),当月无销售当日补 0 |
+| salesTrend[].amount | Long | 当日销售额(分) |
+| productSalesRatio[].productName | String | 商品名称 |
+| productSalesRatio[].amount | Long | 该商品当月销售额(分) |
+| salesUserRanking[].rank | Integer | 名次(从 1 开始) |
+| salesUserRanking[].nickname | String | 购买人昵称(可空,前端回退脱敏手机号) |
+| salesUserRanking[].phone | String | 购买人手机号(**脱敏**) |
+| salesUserRanking[].amount | Long | 该用户当月购买额(分) |
+
+- **错误提示**:`获取销售统计失败`(会员不存在或查询异常)
+
+### 3.2 查询我的仓库列表
+
+- **外部路径**:`GET /miniapp/account/user/member/warehouses`
+- **鉴权**:需登录
+- **入参**:无
+- **出参**:`R<List<MemberWarehouseVo>>`
+
+```json
+{
+  "code": 200,
+  "msg": "操作成功",
+  "data": [
+    {
+      "warehouseId": 100,
+      "productName": "G&METS-II 超分子基团复合肽",
+      "productImage": null,
+      "stockQty": 100,
+      "minStockQty": 100,
+      "lowStock": false
+    }
+  ]
+}
+```
+
+| 字段 | 类型 | 说明 |
+| --- | --- | --- |
+| warehouseId | Long | 云仓行主键(进货时回传) |
+| productName | String | 商品名称 |
+| productImage | String | 商品图片(`account_warehouse` 无此列,本期恒为 null,前端用占位图) |
+| stockQty | Long | 当前库存 |
+| minStockQty | Long | 最低需求库存 |
+| lowStock | Boolean | 低库存标记:`stockQty < minStockQty` 时为 true(前端标红 + 蓝色提示条) |
+
+### 3.3 进货(生成进货单 + 增加库存)
+
+- **外部路径**:`POST /miniapp/account/user/member/purchase`
+- **鉴权**:需登录
+- **入参**(`MemberPurchaseDto`):
+
+```json
+{ "warehouseId": 100, "qty": 5 }
+```
+
+| 字段 | 类型 | 必填 | 说明 |
+| --- | --- | --- | --- |
+| warehouseId | Long | 是 | 云仓行主键(须属于当前会员) |
+| qty | Long | 是 | 进货数量(正整数) |
+
+- **出参**:`R<Void>`
+- **事务**:同一事务内 ① 校验归属 → ② 落进货单 → ③ `stock_qty = stock_qty + qty` → ④ 追加仓库变动流水。
+- **幂等**:进货单 `order_no` 由服务端生成(`PG + yyyyMMddHHmmss + 4 位随机`),`UNIQUE KEY` 兜底。
+- **错误提示**:`商品不存在或不属于当前会员`、`进货数量必须大于 0`、`进货失败,请稍后重试`。
+
+### 3.4 查询仓库变动记录
+
+- **外部路径**:`GET /miniapp/account/user/member/warehouse-records`
+- **鉴权**:需登录
+- **入参**:`pageNum`(默认 1)、`pageSize`(默认 10)
+- **出参**:`TableDataInfo`(顶层 `rows` / `total`)
+
+```json
+{
+  "code": 200,
+  "msg": "查询成功",
+  "rows": [
+    {
+      "recordId": 1,
+      "productName": "G&METS-II 超分子基团复合肽",
+      "changeType": "1",
+      "changeTypeName": "进货入库",
+      "changeQty": 5,
+      "afterQty": 105,
+      "remark": "进货单 PG20261014xxxx",
+      "createTime": "2026-10-14 10:00:00"
+    }
+  ],
+  "total": 1
+}
+```
+
+| 字段 | 类型 | 说明 |
+| --- | --- | --- |
+| recordId | Long | 流水主键 |
+| productName | String | 商品名称(变动时快照) |
+| changeType | String | 变动类型 `1` 进货入库 / `2` 销售出库 / `3` 库存调整 |
+| changeTypeName | String | 变动类型中文名(由枚举下发) |
+| changeQty | Long | 变动数量(入库为正,出库为负) |
+| afterQty | Long | 变动后库存 |
+| remark | String | 备注(进货单号等) |
+| createTime | String | 变动时间(`yyyy-MM-dd HH:mm:ss`) |
+
+### 3.5 查询进货订单列表
+
+- **外部路径**:`GET /miniapp/account/user/member/purchase-orders`
+- **鉴权**:需登录
+- **入参**:`pageNum`(默认 1)、`pageSize`(默认 10)
+- **出参**:`TableDataInfo`(顶层 `rows` / `total`)
+
+```json
+{
+  "code": 200,
+  "msg": "查询成功",
+  "rows": [
+    {
+      "orderId": 1,
+      "orderNo": "PG2026101410301234",
+      "productName": "G&METS-II 超分子基团复合肽",
+      "qty": 5,
+      "unitPrice": 20000,
+      "totalAmount": 100000,
+      "status": "1",
+      "statusName": "已入库",
+      "createTime": "2026-10-14 10:30:12"
+    }
+  ],
+  "total": 1
+}
+```
+
+| 字段 | 类型 | 说明 |
+| --- | --- | --- |
+| orderId | Long | 进货单主键 |
+| orderNo | String | 进货单号 |
+| productName | String | 商品名称 |
+| qty | Long | 进货数量 |
+| unitPrice | Long | 进货单价(分);`account_warehouse` 无单价列,本期由前端进货弹窗按商品默认单价传入或取 0 |
+| totalAmount | Long | 进货金额(分)= `qty × unitPrice` |
+| status | String | 状态 `1` 已入库 |
+| statusName | String | 状态中文名 |
+| createTime | String | 下单时间 |
+
+---
+
+## 四、数据库设计
+
+库:`hugray-account`(权威库 `192.168.110.111:3306`)。脚本:`sql/hugray_account_member_center_20261014.sql`(与代码同一次提交,含变更 + 回滚)。
+
+### 4.1 新增会员销售流水表 `account_sales_record`
+
+```sql
+CREATE TABLE IF NOT EXISTS `account_sales_record` (
+  `record_id`     bigint(20)   NOT NULL AUTO_INCREMENT COMMENT '销售流水ID',
+  `seller_id`     bigint(20)   NOT NULL                COMMENT '销售会员ID(account_user.user_id)',
+  `buyer_id`      bigint(20)   DEFAULT NULL            COMMENT '购买会员ID(account_user.user_id,散客为空)',
+  `buyer_name`    varchar(64)  DEFAULT NULL            COMMENT '购买人昵称(销售排行展示用)',
+  `buyer_phone`   varchar(20)  DEFAULT NULL            COMMENT '购买人手机号(下发脱敏)',
+  `product_name`  varchar(128) DEFAULT NULL            COMMENT '商品名称(比例图/排行展示用)',
+  `qty`           bigint(20)   NOT NULL DEFAULT 0      COMMENT '销售数量',
+  `amount`        bigint(20)   NOT NULL DEFAULT 0      COMMENT '销售额(单位:分)',
+  `profit_amount` bigint(20)   NOT NULL DEFAULT 0      COMMENT '利润额(单位:分,可为负)',
+  `sale_time`     datetime     DEFAULT NULL            COMMENT '销售时间(聚合口径)',
+  `del_flag`      char(1)      DEFAULT '0'             COMMENT '删除标志(0存在 2删除)',
+  `create_by`     varchar(64)  DEFAULT ''              COMMENT '创建者',
+  `create_time`   datetime     DEFAULT NULL            COMMENT '创建时间',
+  `update_by`     varchar(64)  DEFAULT ''              COMMENT '更新者',
+  `update_time`   datetime     DEFAULT NULL            COMMENT '更新时间',
+  `remark`        varchar(500) DEFAULT NULL            COMMENT '备注',
+  PRIMARY KEY (`record_id`),
+  KEY `idx_sales_seller_time` (`seller_id`, `sale_time`)
+) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COMMENT='会员销售流水表';
+```
+
+### 4.2 新增会员进货单表 `account_purchase_order`
+
+```sql
+CREATE TABLE IF NOT EXISTS `account_purchase_order` (
+  `order_id`      bigint(20)   NOT NULL AUTO_INCREMENT COMMENT '进货单ID',
+  `order_no`      varchar(64)  NOT NULL                COMMENT '进货单号(幂等唯一)',
+  `user_id`       bigint(20)   NOT NULL                COMMENT '进货会员ID(account_user.user_id)',
+  `warehouse_id`  bigint(20)   DEFAULT NULL            COMMENT '云仓行ID(account_warehouse.id,快照)',
+  `product_name`  varchar(128) DEFAULT NULL            COMMENT '商品名称(快照)',
+  `qty`           bigint(20)   NOT NULL DEFAULT 0      COMMENT '进货数量',
+  `unit_price`    bigint(20)   NOT NULL DEFAULT 0      COMMENT '进货单价(单位:分)',
+  `total_amount`  bigint(20)   NOT NULL DEFAULT 0      COMMENT '进货金额(单位:分)= qty × unit_price',
+  `status`        char(1)      DEFAULT '1'             COMMENT '状态(1已入库)',
+  `purchase_time` datetime     DEFAULT NULL            COMMENT '进货时间(聚合口径)',
+  `del_flag`      char(1)      DEFAULT '0'             COMMENT '删除标志(0存在 2删除)',
+  `create_by`     varchar(64)  DEFAULT ''              COMMENT '创建者',
+  `create_time`   datetime     DEFAULT NULL            COMMENT '创建时间',
+  `update_by`     varchar(64)  DEFAULT ''              COMMENT '更新者',
+  `update_time`   datetime     DEFAULT NULL            COMMENT '更新时间',
+  `remark`        varchar(500) DEFAULT NULL            COMMENT '备注',
+  PRIMARY KEY (`order_id`),
+  UNIQUE KEY `uk_purchase_order_no` (`order_no`),
+  KEY `idx_purchase_user_time` (`user_id`, `purchase_time`)
+) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COMMENT='会员进货单表';
+```
+
+### 4.3 新增云仓变动流水表 `account_warehouse_record`
+
+```sql
+CREATE TABLE IF NOT EXISTS `account_warehouse_record` (
+  `record_id`     bigint(20)   NOT NULL AUTO_INCREMENT COMMENT '流水ID',
+  `user_id`       bigint(20)   NOT NULL                COMMENT '会员ID(account_user.user_id)',
+  `warehouse_id`  bigint(20)   DEFAULT NULL            COMMENT '云仓行ID(account_warehouse.id)',
+  `product_name`  varchar(128) DEFAULT NULL            COMMENT '商品名称(快照)',
+  `change_type`   char(1)      NOT NULL                COMMENT '变动类型(1进货入库 2销售出库 3库存调整)',
+  `change_qty`    bigint(20)   NOT NULL DEFAULT 0      COMMENT '变动数量(入库为正,出库为负)',
+  `after_qty`     bigint(20)   NOT NULL DEFAULT 0      COMMENT '变动后库存',
+  `biz_no`        varchar(64)  DEFAULT NULL            COMMENT '业务单号(关联进货单等)',
+  `del_flag`      char(1)      DEFAULT '0'             COMMENT '删除标志(0存在 2删除)',
+  `create_by`     varchar(64)  DEFAULT ''              COMMENT '创建者',
+  `create_time`   datetime     DEFAULT NULL            COMMENT '变动时间',
+  `update_by`     varchar(64)  DEFAULT ''              COMMENT '更新者',
+  `update_time`   datetime     DEFAULT NULL            COMMENT '更新时间',
+  `remark`        varchar(500) DEFAULT NULL            COMMENT '备注',
+  PRIMARY KEY (`record_id`),
+  KEY `idx_whrecord_user_time` (`user_id`, `create_time`),
+  KEY `idx_whrecord_warehouse` (`warehouse_id`)
+) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COMMENT='会员云仓变动流水表';
+```
+
+**回滚**:
+
+```sql
+DROP TABLE IF EXISTS `account_warehouse_record`;
+DROP TABLE IF EXISTS `account_purchase_order`;
+DROP TABLE IF EXISTS `account_sales_record`;
+```
+
+---
+
+## 五、流程设计
+
+### 5.1 查询销售统计(`MemberCenterServiceImpl.getSalesStatistics`)
+
+```
+STEP 1: 校验 userId 非空,为空抛「获取销售统计失败」
+STEP 2: 查 account_user,取 phone(脱敏)与 system_level(normalize 兜底 C);不存在抛异常
+STEP 3: 聚合三栏(单条 SQL,本月口径):销售额 / 利润额 / 销售单数
+STEP 4: 聚合并月进货额(account_purchase_order 本月 SUM(total_amount))
+STEP 5: 计算利润环比:上月利润额为 0 时环比返回 0,否则 round((本月-上月)/上月 × 100)
+STEP 6: 查当月销售额趋势(按 DAY(sale_time) 分组)→ 补全当月 1~N 号缺省日(amount=0)
+STEP 7: 查当月商品销售额比例(按 product_name 分组 SUM(amount),降序)
+STEP 8: 查当月销售用户排行(按 buyer 分组 SUM(amount),降序取前 10,手机号脱敏)
+STEP 9: 组装并返回 MemberSalesStatisticsVo
+```
+
+### 5.2 进货(`MemberCenterServiceImpl.purchase`,`@Transactional`)
+
+```
+STEP 1: 校验 userId / warehouseId / qty(qty 必须 > 0)
+STEP 2: 按 warehouseId 查 account_warehouse(del_flag='0');为空或 user_id != 当前会员 → 抛「商品不存在或不属于当前会员」(防水平越权)
+STEP 3: 生成唯一进货单号 order_no(PG + 时间戳 + 随机)
+STEP 4: 落进货单(status='1' 已入库,purchase_time=sysdate)
+STEP 5: 更新库存 stock_qty = stock_qty + qty(SQL 内自增,避免读改写竞态)
+STEP 6: 追加云仓变动流水(change_type='1',change_qty=+qty,after_qty=自增后库存,biz_no=order_no)
+STEP 7: 提交事务
+```
+
+### 5.3 仓库列表 / 变动记录 / 进货订单
+
+均为只读查询,按当前会员过滤(`user_id = 当前会员`),记录 / 订单按时间倒序分页;列表接口低库存标记在 Service 组装(`stockQty < minStockQty`)。
+
+---
+
+## 六、枚举与状态
+
+| 名称 | 取值 | 说明 |
+| --- | --- | --- |
+| 会员等级 `memberLevel`(源 `system_level`) | `C` / `L1` / `L2` / `L3` / `L4` | 复用 `MemberLevelEnum` |
+| 云仓变动类型 `changeType` | `1` 进货入库 / `2` 销售出库 / `3` 库存调整 | 新增 `WarehouseChangeTypeEnum`(`code` + `desc` + `getByCode`) |
+| 进货单状态 `status` | `1` 已入库 | 新增 `PurchaseOrderStatusEnum`(`code` + `desc` + `getByCode`) |
+| 删除标志 `delFlag` | `0` 存在 / `2` 删除 | 复用现有语义 |
+
+---
+
+## 七、影响范围与文件清单
+
+### 新增(ruoyi-user)
+
+| 文件 | 说明 |
+| --- | --- |
+| `domain/AccountSalesRecord.java` | 销售流水实体 |
+| `domain/AccountPurchaseOrder.java` | 进货单实体 |
+| `domain/AccountWarehouseRecord.java` | 云仓变动流水实体 |
+| `domain/dto/MemberPurchaseDto.java` | 进货入参 |
+| `domain/vo/MemberSalesStatisticsVo.java` | 销售统计聚合出参 |
+| `domain/vo/SalesTrendItemVo.java` | 销售额趋势项 |
+| `domain/vo/ProductSalesRatioVo.java` | 商品销售额比例项 |
+| `domain/vo/SalesUserRankingVo.java` | 销售用户排行项 |
+| `domain/vo/MemberWarehouseVo.java` | 云仓列表项(含低库存标记) |
+| `domain/vo/WarehouseRecordVo.java` | 云仓变动记录项 |
+| `domain/vo/PurchaseOrderVo.java` | 进货订单项 |
+| `enums/WarehouseChangeTypeEnum.java` | 云仓变动类型枚举 |
+| `enums/PurchaseOrderStatusEnum.java` | 进货单状态枚举 |
+| `mapper/AccountSalesRecordMapper.java` + XML | 销售流水聚合查询 |
+| `mapper/AccountPurchaseOrderMapper.java` + XML | 进货单落库 + 聚合 + 分页 |
+| `mapper/AccountWarehouseRecordMapper.java` + XML | 变动流水落库 + 分页 |
+| `service/IAccountMemberCenterService.java` + `service/impl/AccountMemberCenterServiceImpl.java` | 会员中心业务 |
+| `controller/AccountMemberCenterController.java` | C 端 5 个接口 |
+
+### 修改
+
+| 文件 | 改动 |
+| --- | --- |
+| `mapper/AccountWarehouseMapper.java` + XML | 新增 `selectWarehouseById`(按主键查,含 `del_flag='0'`)与 `increaseStockQty`(`stock_qty = stock_qty + #{qty}` 原子自增) |
+| `sql/hugray_account_member_center_20261014.sql` | 新增三张表 DDL(变更 + 回滚) |
+| 前端 `hugray-user-miniapp/api/index.js` | 新增 5 个会员中心接口方法 |
+| 前端 `hugray-user-miniapp/pages.json` | 注册 `pages/member/index` 路由(custom 导航) |
+| 前端 `hugray-user-miniapp/pages/profile/index.vue` | 菜单 `member` 由「敬请期待」改为跳转会员中心页 |
+| 前端 `hugray-user-miniapp/pages/member/index.vue` | 新增会员中心页(销售统计 / 我的仓库) |
+
+> 网关无需改动:`/miniapp/account/**` → `ruoyi-user` 路由已存在。
+
+---
+
+## 八、边界与异常清单
+
+| # | 场景 | 处理 |
+| --- | --- | --- |
+| 1 | 未登录访问 | 网关 `AuthFilter` 返回 401,前端跳登录页;后端不做分支 |
+| 2 | `user_id` 头缺失/为空 | 服务内兜底判空,抛业务异常(不 NPE) |
+| 3 | 会员不存在 / 已逻辑删除 | 抛业务异常 |
+| 4 | 进货 `warehouseId` 不属于当前会员 | 抛「商品不存在或不属于当前会员」(防水平越权) |
+| 5 | 进货 `qty` ≤ 0 | 抛「进货数量必须大于 0」 |
+| 6 | 当月无销售流水 | 三栏为 0,趋势全为 0,比例/排行为空数组 |
+| 7 | 上月利润为 0 | 环比返回 0(不抛除零) |
+| 8 | 排行购买人手机号 | 下发**脱敏**值(`138****4561`) |
+| 9 | 进货并发 | 库存用 SQL 原子自增 `stock_qty = stock_qty + #{qty}`,避免读改写竞态 |
+| 10 | 进货单号重复 | `uk_purchase_order_no` 唯一索引兜底,生成时已带随机段 |
+
+---
+
+## 九、规范符合性说明
+
+- 分层:Controller 只取身份 + 转发;业务在 Service;SQL 在 Mapper;Controller 不直接调 Mapper。
+- 命名:`getSalesStatistics` / `purchase` / `increaseStockQty` 等见名知意;Entity / DTO / VO 分离。
+- 注释:实体类字段注释(取值与单位)、Javadoc、核心流程 `// STEP x:` 注释。
+- 魔法值:变动类型、进货单状态收口枚举;云仓变动 `change_qty` 正负语义在 Service 注释说明。
+- 异常:统一 `ServiceException` + 全局处理器;不散落 try-catch。
+- 数据库:字段显式长度 + COMMENT;聚合列有索引;无 `SELECT *`;无 `${}` 拼接;无循环查库。
+- 幂等:进货单 `order_no` 唯一索引;库存原子自增。
+- 单测:`getSalesStatistics`(无流水 / 有流水 / 上月为 0)、`purchase`(正常 / 非本人 / qty≤0)补单测,Mockito Mock Mapper。
+- 说明(与现有工程一致优先):`account_*` 系列主键沿用自增(与同库既有表一致),未采用雪花 ID,作为已知项记录。
+
+---
+
+## 十、已确认决策
+
+1. **销售统计数据来源**:**已定** —— 新建简化销售流水模型 `account_sales_record`,本月三栏 / 趋势 / 比例 / 排行实时聚合。
+2. **进货业务口径**:**已定** —— 真实进货:生成进货单 `account_purchase_order` + 增加 `account_warehouse.stock_qty` + 追加变动流水 `account_warehouse_record`。
+3. **金额单位**:**已定** —— 接口返回分(`long`),前端格式化两位小数。
+4. **`account_user` 统计列**:**已定** —— 本期不回填,页面数据一律由流水表实时聚合(避免双写口径不一致)。
+5. **当月利润口径**:**已定** —— `SUM(account_sales_record.profit_amount)`;写入方(订单模块)就绪前无流水时为 0。
+6. **等级详情**:本期为前端本地展示(等级说明),不新增后端接口。
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/controller/AccountMemberController.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/controller/AccountMemberController.java
new file mode 100644
index 0000000..4ef0cc9
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/controller/AccountMemberController.java
@@ -0,0 +1,110 @@
+package com.ruoyi.user.controller;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.web.controller.BaseController;
+import com.ruoyi.common.core.web.page.TableDataInfo;
+import com.ruoyi.common.security.utils.SecurityUtils;
+import com.ruoyi.user.domain.dto.MemberPurchaseDto;
+import com.ruoyi.user.domain.vo.MemberSalesStatisticsVo;
+import com.ruoyi.user.domain.vo.MemberWarehouseVo;
+import com.ruoyi.user.domain.vo.PurchaseOrderVo;
+import com.ruoyi.user.domain.vo.WarehouseRecordVo;
+import com.ruoyi.user.service.IAccountMemberCenterService;
+
+/**
+ * C端会员 个人中心-会员中心接口
+ *
+ * 网关前缀 /miniapp/account 由 StripPrefix=2 剥掉,故此处映射为 /user/member,
+ * 外部实际路径为 /miniapp/account/user/member/**。
+ *
+ * 会员身份取自网关注入的登录态(SecurityUtils.getUserId),不接受前端传 userId,
+ * 天然防止水平越权;未登录请求由网关直接以 401 拦截,故此处不处理未登录分支。
+ *
+ * @author hugray
+ */
+@RestController
+@RequestMapping("/user/member")
+public class AccountMemberController extends BaseController
+{
+    @Autowired
+    private IAccountMemberCenterService accountMemberCenterService;
+
+    /**
+     * 查询当前登录会员的销售统计
+     *
+     * 返回当月销售额 / 进货额 / 利润(单位分)、利润环比、销售额趋势、商品销售额比例与销售用户排行。
+     *
+     * @return 销售统计聚合对象
+     */
+    @GetMapping("/sales-statistics")
+    public R<MemberSalesStatisticsVo> salesStatistics()
+    {
+        return R.ok(accountMemberCenterService.getSalesStatistics(SecurityUtils.getUserId()));
+    }
+
+    /**
+     * 查询当前登录会员的云仓列表
+     *
+     * 含当前库存、最低需求库存与低库存标记;商品图片本期为空,由前端使用占位图。
+     *
+     * @return 云仓列表
+     */
+    @GetMapping("/warehouses")
+    public R<List<MemberWarehouseVo>> warehouses()
+    {
+        return R.ok(accountMemberCenterService.getWarehouseList(SecurityUtils.getUserId()));
+    }
+
+    /**
+     * 进货:生成进货单并增加对应云仓库存
+     *
+     * 云仓归属由服务端校验(非本会员商品拒绝),库存原子自增,同一事务内追加变动流水。
+     *
+     * @param dto 进货入参(warehouseId、qty 必填)
+     * @return 操作结果
+     */
+    @PostMapping("/purchase")
+    public R<Void> purchase(@Validated @RequestBody MemberPurchaseDto dto)
+    {
+        accountMemberCenterService.purchase(SecurityUtils.getUserId(), dto);
+        return R.ok();
+    }
+
+    /**
+     * 分页查询当前登录会员的云仓变动记录
+     *
+     * 分页参数 pageNum 默认 1、pageSize 默认 10,按变动时间倒序。
+     *
+     * @return 分页数据(rows 为变动记录,total 为总数)
+     */
+    @GetMapping("/warehouse-records")
+    public TableDataInfo warehouseRecords()
+    {
+        startPage();
+        List<WarehouseRecordVo> list = accountMemberCenterService.getWarehouseRecordList(SecurityUtils.getUserId());
+        return getDataTable(list);
+    }
+
+    /**
+     * 分页查询当前登录会员的进货订单
+     *
+     * 分页参数 pageNum 默认 1、pageSize 默认 10,按下单时间倒序。
+     *
+     * @return 分页数据(rows 为进货订单,total 为总数)
+     */
+    @GetMapping("/purchase-orders")
+    public TableDataInfo purchaseOrders()
+    {
+        startPage();
+        List<PurchaseOrderVo> list = accountMemberCenterService.getPurchaseOrderList(SecurityUtils.getUserId());
+        return getDataTable(list);
+    }
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/AccountPurchaseOrder.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/AccountPurchaseOrder.java
new file mode 100644
index 0000000..13f39df
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/AccountPurchaseOrder.java
@@ -0,0 +1,186 @@
+package com.ruoyi.user.domain;
+
+import java.util.Date;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.common.core.web.domain.BaseEntity;
+
+/**
+ * 会员进货单 account_purchase_order
+ *
+ * 一条进货单 = 一次进货入库;落单同时增加 account_warehouse.stock_qty 并追加云仓变动流水。
+ * 当月进货额由本表按 purchase_time 实时聚合。
+ *
+ * @author hugray
+ */
+public class AccountPurchaseOrder extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 进货单ID */
+    private Long orderId;
+
+    /** 进货单号(幂等唯一,服务端生成) */
+    private String orderNo;
+
+    /** 进货会员ID(account_user.user_id) */
+    private Long userId;
+
+    /** 云仓行ID(account_warehouse.id,快照) */
+    private Long warehouseId;
+
+    /** 商品名称(快照) */
+    private String productName;
+
+    /** 进货数量 */
+    private Long qty;
+
+    /** 进货单价(单位:分) */
+    private Long unitPrice;
+
+    /** 进货金额(单位:分)= qty × unitPrice */
+    private Long totalAmount;
+
+    /** 状态(1已入库,见 PurchaseOrderStatusEnum) */
+    private String status;
+
+    /** 进货时间(聚合口径) */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date purchaseTime;
+
+    /** 删除标志(0存在 2删除) */
+    private String delFlag;
+
+    public Long getOrderId()
+    {
+        return orderId;
+    }
+
+    public void setOrderId(Long orderId)
+    {
+        this.orderId = orderId;
+    }
+
+    public String getOrderNo()
+    {
+        return orderNo;
+    }
+
+    public void setOrderNo(String orderNo)
+    {
+        this.orderNo = orderNo;
+    }
+
+    public Long getUserId()
+    {
+        return userId;
+    }
+
+    public void setUserId(Long userId)
+    {
+        this.userId = userId;
+    }
+
+    public Long getWarehouseId()
+    {
+        return warehouseId;
+    }
+
+    public void setWarehouseId(Long warehouseId)
+    {
+        this.warehouseId = warehouseId;
+    }
+
+    public String getProductName()
+    {
+        return productName;
+    }
+
+    public void setProductName(String productName)
+    {
+        this.productName = productName;
+    }
+
+    public Long getQty()
+    {
+        return qty;
+    }
+
+    public void setQty(Long qty)
+    {
+        this.qty = qty;
+    }
+
+    public Long getUnitPrice()
+    {
+        return unitPrice;
+    }
+
+    public void setUnitPrice(Long unitPrice)
+    {
+        this.unitPrice = unitPrice;
+    }
+
+    public Long getTotalAmount()
+    {
+        return totalAmount;
+    }
+
+    public void setTotalAmount(Long totalAmount)
+    {
+        this.totalAmount = totalAmount;
+    }
+
+    public String getStatus()
+    {
+        return status;
+    }
+
+    public void setStatus(String status)
+    {
+        this.status = status;
+    }
+
+    public Date getPurchaseTime()
+    {
+        return purchaseTime;
+    }
+
+    public void setPurchaseTime(Date purchaseTime)
+    {
+        this.purchaseTime = purchaseTime;
+    }
+
+    public String getDelFlag()
+    {
+        return delFlag;
+    }
+
+    public void setDelFlag(String delFlag)
+    {
+        this.delFlag = delFlag;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+            .append("orderId", getOrderId())
+            .append("orderNo", getOrderNo())
+            .append("userId", getUserId())
+            .append("warehouseId", getWarehouseId())
+            .append("productName", getProductName())
+            .append("qty", getQty())
+            .append("unitPrice", getUnitPrice())
+            .append("totalAmount", getTotalAmount())
+            .append("status", getStatus())
+            .append("purchaseTime", getPurchaseTime())
+            .append("delFlag", getDelFlag())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("remark", getRemark())
+            .toString();
+    }
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/AccountSalesRecord.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/AccountSalesRecord.java
new file mode 100644
index 0000000..80850d7
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/AccountSalesRecord.java
@@ -0,0 +1,186 @@
+package com.ruoyi.user.domain;
+
+import java.util.Date;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.common.core.web.domain.BaseEntity;
+
+/**
+ * 会员销售流水 account_sales_record
+ *
+ * 一条流水 = 一次销售事件。当月销售额 / 利润额 / 销售单数、销售额趋势、商品销售额比例、
+ * 销售用户排行均由本表按 sale_time 实时聚合。
+ *
+ * @author hugray
+ */
+public class AccountSalesRecord extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 销售流水ID */
+    private Long recordId;
+
+    /** 销售会员ID(account_user.user_id) */
+    private Long sellerId;
+
+    /** 购买会员ID(account_user.user_id,散客为空) */
+    private Long buyerId;
+
+    /** 购买人昵称(销售排行展示用) */
+    private String buyerName;
+
+    /** 购买人手机号(下发前脱敏) */
+    private String buyerPhone;
+
+    /** 商品名称(比例图 / 排行展示用) */
+    private String productName;
+
+    /** 销售数量 */
+    private Long qty;
+
+    /** 销售额(单位:分) */
+    private Long amount;
+
+    /** 利润额(单位:分,可为负) */
+    private Long profitAmount;
+
+    /** 销售时间(聚合口径) */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date saleTime;
+
+    /** 删除标志(0存在 2删除) */
+    private String delFlag;
+
+    public Long getRecordId()
+    {
+        return recordId;
+    }
+
+    public void setRecordId(Long recordId)
+    {
+        this.recordId = recordId;
+    }
+
+    public Long getSellerId()
+    {
+        return sellerId;
+    }
+
+    public void setSellerId(Long sellerId)
+    {
+        this.sellerId = sellerId;
+    }
+
+    public Long getBuyerId()
+    {
+        return buyerId;
+    }
+
+    public void setBuyerId(Long buyerId)
+    {
+        this.buyerId = buyerId;
+    }
+
+    public String getBuyerName()
+    {
+        return buyerName;
+    }
+
+    public void setBuyerName(String buyerName)
+    {
+        this.buyerName = buyerName;
+    }
+
+    public String getBuyerPhone()
+    {
+        return buyerPhone;
+    }
+
+    public void setBuyerPhone(String buyerPhone)
+    {
+        this.buyerPhone = buyerPhone;
+    }
+
+    public String getProductName()
+    {
+        return productName;
+    }
+
+    public void setProductName(String productName)
+    {
+        this.productName = productName;
+    }
+
+    public Long getQty()
+    {
+        return qty;
+    }
+
+    public void setQty(Long qty)
+    {
+        this.qty = qty;
+    }
+
+    public Long getAmount()
+    {
+        return amount;
+    }
+
+    public void setAmount(Long amount)
+    {
+        this.amount = amount;
+    }
+
+    public Long getProfitAmount()
+    {
+        return profitAmount;
+    }
+
+    public void setProfitAmount(Long profitAmount)
+    {
+        this.profitAmount = profitAmount;
+    }
+
+    public Date getSaleTime()
+    {
+        return saleTime;
+    }
+
+    public void setSaleTime(Date saleTime)
+    {
+        this.saleTime = saleTime;
+    }
+
+    public String getDelFlag()
+    {
+        return delFlag;
+    }
+
+    public void setDelFlag(String delFlag)
+    {
+        this.delFlag = delFlag;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+            .append("recordId", getRecordId())
+            .append("sellerId", getSellerId())
+            .append("buyerId", getBuyerId())
+            .append("buyerName", getBuyerName())
+            .append("buyerPhone", getBuyerPhone())
+            .append("productName", getProductName())
+            .append("qty", getQty())
+            .append("amount", getAmount())
+            .append("profitAmount", getProfitAmount())
+            .append("saleTime", getSaleTime())
+            .append("delFlag", getDelFlag())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("remark", getRemark())
+            .toString();
+    }
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/AccountWarehouseRecord.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/AccountWarehouseRecord.java
new file mode 100644
index 0000000..8a54102
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/AccountWarehouseRecord.java
@@ -0,0 +1,163 @@
+package com.ruoyi.user.domain;
+
+import java.util.Date;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.core.web.domain.BaseEntity;
+
+/**
+ * 会员云仓变动流水 account_warehouse_record
+ *
+ * 每次库存变动(进货入库 / 销售出库 / 库存调整)追加一条流水,供「仓库记录」倒序展示。
+ *
+ * @author hugray
+ */
+public class AccountWarehouseRecord extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 流水ID */
+    private Long recordId;
+
+    /** 会员ID(account_user.user_id) */
+    private Long userId;
+
+    /** 云仓行ID(account_warehouse.id) */
+    private Long warehouseId;
+
+    /** 商品名称(快照) */
+    private String productName;
+
+    /** 变动类型(1进货入库 2销售出库 3库存调整,见 WarehouseChangeTypeEnum) */
+    private String changeType;
+
+    /** 变动数量(入库为正,出库为负) */
+    private Long changeQty;
+
+    /** 变动后库存 */
+    private Long afterQty;
+
+    /** 业务单号(关联进货单等,便于溯源) */
+    private String bizNo;
+
+    /** 删除标志(0存在 2删除) */
+    private String delFlag;
+
+    public Long getRecordId()
+    {
+        return recordId;
+    }
+
+    public void setRecordId(Long recordId)
+    {
+        this.recordId = recordId;
+    }
+
+    public Long getUserId()
+    {
+        return userId;
+    }
+
+    public void setUserId(Long userId)
+    {
+        this.userId = userId;
+    }
+
+    public Long getWarehouseId()
+    {
+        return warehouseId;
+    }
+
+    public void setWarehouseId(Long warehouseId)
+    {
+        this.warehouseId = warehouseId;
+    }
+
+    public String getProductName()
+    {
+        return productName;
+    }
+
+    public void setProductName(String productName)
+    {
+        this.productName = productName;
+    }
+
+    public String getChangeType()
+    {
+        return changeType;
+    }
+
+    public void setChangeType(String changeType)
+    {
+        this.changeType = changeType;
+    }
+
+    public Long getChangeQty()
+    {
+        return changeQty;
+    }
+
+    public void setChangeQty(Long changeQty)
+    {
+        this.changeQty = changeQty;
+    }
+
+    public Long getAfterQty()
+    {
+        return afterQty;
+    }
+
+    public void setAfterQty(Long afterQty)
+    {
+        this.afterQty = afterQty;
+    }
+
+    public String getBizNo()
+    {
+        return bizNo;
+    }
+
+    public void setBizNo(String bizNo)
+    {
+        this.bizNo = bizNo;
+    }
+
+    public String getDelFlag()
+    {
+        return delFlag;
+    }
+
+    public void setDelFlag(String delFlag)
+    {
+        this.delFlag = delFlag;
+    }
+
+    /**
+     * 变动时间:直接复用父类 createTime(流水创建即变动发生),此处仅做展示别名。
+     */
+    public Date getChangeTime()
+    {
+        return getCreateTime();
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+            .append("recordId", getRecordId())
+            .append("userId", getUserId())
+            .append("warehouseId", getWarehouseId())
+            .append("productName", getProductName())
+            .append("changeType", getChangeType())
+            .append("changeQty", getChangeQty())
+            .append("afterQty", getAfterQty())
+            .append("bizNo", getBizNo())
+            .append("delFlag", getDelFlag())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("remark", getRemark())
+            .toString();
+    }
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/dto/MemberPurchaseDto.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/dto/MemberPurchaseDto.java
new file mode 100644
index 0000000..896a8e8
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/dto/MemberPurchaseDto.java
@@ -0,0 +1,54 @@
+package com.ruoyi.user.domain.dto;
+
+import jakarta.validation.constraints.NotNull;
+
+/**
+ * 会员进货入参
+ *
+ * 会员身份取自登录态,不接受前端传入 userId;warehouseId 须属于当前会员(服务端校验归属)。
+ *
+ * @author hugray
+ */
+public class MemberPurchaseDto
+{
+    /** 云仓行ID(account_warehouse.id,须属于当前会员) */
+    @NotNull(message = "进货商品不能为空")
+    private Long warehouseId;
+
+    /** 进货数量(正整数) */
+    @NotNull(message = "进货数量不能为空")
+    private Long qty;
+
+    /** 进货单价(单位:分;可选,缺省按 0 计) */
+    private Long unitPrice;
+
+    public Long getWarehouseId()
+    {
+        return warehouseId;
+    }
+
+    public void setWarehouseId(Long warehouseId)
+    {
+        this.warehouseId = warehouseId;
+    }
+
+    public Long getQty()
+    {
+        return qty;
+    }
+
+    public void setQty(Long qty)
+    {
+        this.qty = qty;
+    }
+
+    public Long getUnitPrice()
+    {
+        return unitPrice;
+    }
+
+    public void setUnitPrice(Long unitPrice)
+    {
+        this.unitPrice = unitPrice;
+    }
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/MemberSalesStatisticsVo.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/MemberSalesStatisticsVo.java
new file mode 100644
index 0000000..e74a6c5
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/MemberSalesStatisticsVo.java
@@ -0,0 +1,144 @@
+package com.ruoyi.user.domain.vo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 会员销售统计 VO(会员中心「销售统计」Tab 聚合出参)
+ *
+ * 金额单位一律「分」;无销售流水时三栏为 0、趋势全为 0、比例与排行为空数组。
+ *
+ * @author hugray
+ */
+public class MemberSalesStatisticsVo
+{
+    /** 当前会员手机号(脱敏,形如 136****6666) */
+    private String phone;
+
+    /** 会员等级(C / L1~L4) */
+    private String memberLevel;
+
+    /** 当月销售额(分)= SUM(account_sales_record.amount) */
+    private Long monthSalesAmount;
+
+    /** 当月进货额(分)= SUM(account_purchase_order.total_amount) */
+    private Long monthPurchaseAmount;
+
+    /** 当月利润额(分)= SUM(account_sales_record.profit_amount),可为负 */
+    private Long monthProfitAmount;
+
+    /** 当月销售单数 = COUNT(account_sales_record) */
+    private Integer monthSalesCount;
+
+    /** 当月利润环比上月提升百分比(无上月数据时为 0) */
+    private Integer profitGrowthRate;
+
+    /** 当月销售额趋势(按日补零,1 号到当日) */
+    private List<SalesTrendItemVo> salesTrend = new ArrayList<>();
+
+    /** 当月商品销售额比例 */
+    private List<ProductSalesRatioVo> productSalesRatio = new ArrayList<>();
+
+    /** 当月销售用户排行(Top 10) */
+    private List<SalesUserRankingVo> salesUserRanking = new ArrayList<>();
+
+    public String getPhone()
+    {
+        return phone;
+    }
+
+    public void setPhone(String phone)
+    {
+        this.phone = phone;
+    }
+
+    public String getMemberLevel()
+    {
+        return memberLevel;
+    }
+
+    public void setMemberLevel(String memberLevel)
+    {
+        this.memberLevel = memberLevel;
+    }
+
+    public Long getMonthSalesAmount()
+    {
+        return monthSalesAmount;
+    }
+
+    public void setMonthSalesAmount(Long monthSalesAmount)
+    {
+        this.monthSalesAmount = monthSalesAmount;
+    }
+
+    public Long getMonthPurchaseAmount()
+    {
+        return monthPurchaseAmount;
+    }
+
+    public void setMonthPurchaseAmount(Long monthPurchaseAmount)
+    {
+        this.monthPurchaseAmount = monthPurchaseAmount;
+    }
+
+    public Long getMonthProfitAmount()
+    {
+        return monthProfitAmount;
+    }
+
+    public void setMonthProfitAmount(Long monthProfitAmount)
+    {
+        this.monthProfitAmount = monthProfitAmount;
+    }
+
+    public Integer getMonthSalesCount()
+    {
+        return monthSalesCount;
+    }
+
+    public void setMonthSalesCount(Integer monthSalesCount)
+    {
+        this.monthSalesCount = monthSalesCount;
+    }
+
+    public Integer getProfitGrowthRate()
+    {
+        return profitGrowthRate;
+    }
+
+    public void setProfitGrowthRate(Integer profitGrowthRate)
+    {
+        this.profitGrowthRate = profitGrowthRate;
+    }
+
+    public List<SalesTrendItemVo> getSalesTrend()
+    {
+        return salesTrend;
+    }
+
+    public void setSalesTrend(List<SalesTrendItemVo> salesTrend)
+    {
+        this.salesTrend = salesTrend;
+    }
+
+    public List<ProductSalesRatioVo> getProductSalesRatio()
+    {
+        return productSalesRatio;
+    }
+
+    public void setProductSalesRatio(List<ProductSalesRatioVo> productSalesRatio)
+    {
+        this.productSalesRatio = productSalesRatio;
+    }
+
+    public List<SalesUserRankingVo> getSalesUserRanking()
+    {
+        return salesUserRanking;
+    }
+
+    public void setSalesUserRanking(List<SalesUserRankingVo> salesUserRanking)
+    {
+        this.salesUserRanking = salesUserRanking;
+    }
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/MemberWarehouseVo.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/MemberWarehouseVo.java
new file mode 100644
index 0000000..23df1ce
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/MemberWarehouseVo.java
@@ -0,0 +1,89 @@
+package com.ruoyi.user.domain.vo;
+
+/**
+ * 我的仓库列表项 VO(会员中心「我的仓库」Tab)
+ *
+ * 商品图片列在 account_warehouse 不存在,本期恒为 null,由前端使用占位图。
+ *
+ * @author hugray
+ */
+public class MemberWarehouseVo
+{
+    /** 云仓行主键(进货时回传) */
+    private Long warehouseId;
+
+    /** 商品名称 */
+    private String productName;
+
+    /** 商品图片(本期恒为 null,前端用占位图) */
+    private String productImage;
+
+    /** 当前库存 */
+    private Long stockQty;
+
+    /** 最低需求库存 */
+    private Long minStockQty;
+
+    /** 低库存标记:stockQty < minStockQty 时为 true(前端标红 + 提示条) */
+    private Boolean lowStock;
+
+    public Long getWarehouseId()
+    {
+        return warehouseId;
+    }
+
+    public void setWarehouseId(Long warehouseId)
+    {
+        this.warehouseId = warehouseId;
+    }
+
+    public String getProductName()
+    {
+        return productName;
+    }
+
+    public void setProductName(String productName)
+    {
+        this.productName = productName;
+    }
+
+    public String getProductImage()
+    {
+        return productImage;
+    }
+
+    public void setProductImage(String productImage)
+    {
+        this.productImage = productImage;
+    }
+
+    public Long getStockQty()
+    {
+        return stockQty;
+    }
+
+    public void setStockQty(Long stockQty)
+    {
+        this.stockQty = stockQty;
+    }
+
+    public Long getMinStockQty()
+    {
+        return minStockQty;
+    }
+
+    public void setMinStockQty(Long minStockQty)
+    {
+        this.minStockQty = minStockQty;
+    }
+
+    public Boolean getLowStock()
+    {
+        return lowStock;
+    }
+
+    public void setLowStock(Boolean lowStock)
+    {
+        this.lowStock = lowStock;
+    }
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/ProductSalesRatioVo.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/ProductSalesRatioVo.java
new file mode 100644
index 0000000..8ab2a64
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/ProductSalesRatioVo.java
@@ -0,0 +1,35 @@
+package com.ruoyi.user.domain.vo;
+
+/**
+ * 商品销售额比例项 VO(销售统计饼图数据点)
+ *
+ * @author hugray
+ */
+public class ProductSalesRatioVo
+{
+    /** 商品名称 */
+    private String productName;
+
+    /** 该商品当月销售额(分) */
+    private Long amount;
+
+    public String getProductName()
+    {
+        return productName;
+    }
+
+    public void setProductName(String productName)
+    {
+        this.productName = productName;
+    }
+
+    public Long getAmount()
+    {
+        return amount;
+    }
+
+    public void setAmount(Long amount)
+    {
+        this.amount = amount;
+    }
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/PurchaseOrderVo.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/PurchaseOrderVo.java
new file mode 100644
index 0000000..33c6c16
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/PurchaseOrderVo.java
@@ -0,0 +1,130 @@
+package com.ruoyi.user.domain.vo;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 进货订单项 VO(「进货订单」列表)
+ *
+ * @author hugray
+ */
+public class PurchaseOrderVo
+{
+    /** 进货单主键 */
+    private Long orderId;
+
+    /** 进货单号 */
+    private String orderNo;
+
+    /** 商品名称 */
+    private String productName;
+
+    /** 进货数量 */
+    private Long qty;
+
+    /** 进货单价(分) */
+    private Long unitPrice;
+
+    /** 进货金额(分)= qty × unitPrice */
+    private Long totalAmount;
+
+    /** 状态(1已入库) */
+    private String status;
+
+    /** 状态中文名 */
+    private String statusName;
+
+    /** 下单时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    public Long getOrderId()
+    {
+        return orderId;
+    }
+
+    public void setOrderId(Long orderId)
+    {
+        this.orderId = orderId;
+    }
+
+    public String getOrderNo()
+    {
+        return orderNo;
+    }
+
+    public void setOrderNo(String orderNo)
+    {
+        this.orderNo = orderNo;
+    }
+
+    public String getProductName()
+    {
+        return productName;
+    }
+
+    public void setProductName(String productName)
+    {
+        this.productName = productName;
+    }
+
+    public Long getQty()
+    {
+        return qty;
+    }
+
+    public void setQty(Long qty)
+    {
+        this.qty = qty;
+    }
+
+    public Long getUnitPrice()
+    {
+        return unitPrice;
+    }
+
+    public void setUnitPrice(Long unitPrice)
+    {
+        this.unitPrice = unitPrice;
+    }
+
+    public Long getTotalAmount()
+    {
+        return totalAmount;
+    }
+
+    public void setTotalAmount(Long totalAmount)
+    {
+        this.totalAmount = totalAmount;
+    }
+
+    public String getStatus()
+    {
+        return status;
+    }
+
+    public void setStatus(String status)
+    {
+        this.status = status;
+    }
+
+    public String getStatusName()
+    {
+        return statusName;
+    }
+
+    public void setStatusName(String statusName)
+    {
+        this.statusName = statusName;
+    }
+
+    public Date getCreateTime()
+    {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime)
+    {
+        this.createTime = createTime;
+    }
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/SalesMonthSummaryVo.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/SalesMonthSummaryVo.java
new file mode 100644
index 0000000..fb6ada8
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/SalesMonthSummaryVo.java
@@ -0,0 +1,63 @@
+package com.ruoyi.user.domain.vo;
+
+/**
+ * 销售月汇总 VO(服务端内部聚合载体,不直接对外返回)
+ *
+ * 单条 SQL 同时聚合本月销售额 / 利润额 / 单数与上月利润额,避免多次数据库往返。
+ *
+ * @author hugray
+ */
+public class SalesMonthSummaryVo
+{
+    /** 本月销售额(分) */
+    private Long salesAmount;
+
+    /** 本月利润额(分,可为负) */
+    private Long profitAmount;
+
+    /** 本月销售单数 */
+    private Integer salesCount;
+
+    /** 上月利润额(分,用于环比计算) */
+    private Long prevMonthProfit;
+
+    public Long getSalesAmount()
+    {
+        return salesAmount;
+    }
+
+    public void setSalesAmount(Long salesAmount)
+    {
+        this.salesAmount = salesAmount;
+    }
+
+    public Long getProfitAmount()
+    {
+        return profitAmount;
+    }
+
+    public void setProfitAmount(Long profitAmount)
+    {
+        this.profitAmount = profitAmount;
+    }
+
+    public Integer getSalesCount()
+    {
+        return salesCount;
+    }
+
+    public void setSalesCount(Integer salesCount)
+    {
+        this.salesCount = salesCount;
+    }
+
+    public Long getPrevMonthProfit()
+    {
+        return prevMonthProfit;
+    }
+
+    public void setPrevMonthProfit(Long prevMonthProfit)
+    {
+        this.prevMonthProfit = prevMonthProfit;
+    }
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/SalesTrendItemVo.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/SalesTrendItemVo.java
new file mode 100644
index 0000000..26a7bcd
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/SalesTrendItemVo.java
@@ -0,0 +1,58 @@
+package com.ruoyi.user.domain.vo;
+
+/**
+ * 销售额趋势项 VO(销售统计折线图数据点)
+ *
+ * @author hugray
+ */
+public class SalesTrendItemVo
+{
+    /** 日标签(对外展示,形如 1号 / 5号) */
+    private String day;
+
+    /** 月内第几天(1~31,仅用于服务端补零对齐,不对外使用) */
+    private Integer dayOfMonth;
+
+    /** 当日销售额(分) */
+    private Long amount;
+
+    public SalesTrendItemVo()
+    {
+    }
+
+    public SalesTrendItemVo(String day, Long amount)
+    {
+        this.day = day;
+        this.amount = amount;
+    }
+
+    public String getDay()
+    {
+        return day;
+    }
+
+    public void setDay(String day)
+    {
+        this.day = day;
+    }
+
+    public Integer getDayOfMonth()
+    {
+        return dayOfMonth;
+    }
+
+    public void setDayOfMonth(Integer dayOfMonth)
+    {
+        this.dayOfMonth = dayOfMonth;
+    }
+
+    public Long getAmount()
+    {
+        return amount;
+    }
+
+    public void setAmount(Long amount)
+    {
+        this.amount = amount;
+    }
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/SalesUserRankingVo.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/SalesUserRankingVo.java
new file mode 100644
index 0000000..8499d36
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/SalesUserRankingVo.java
@@ -0,0 +1,63 @@
+package com.ruoyi.user.domain.vo;
+
+/**
+ * 销售用户排行项 VO(销售统计排行列表)
+ *
+ * 手机号下发前已脱敏;昵称可为空,前端回退展示脱敏手机号。
+ *
+ * @author hugray
+ */
+public class SalesUserRankingVo
+{
+    /** 名次(从 1 开始) */
+    private Integer rank;
+
+    /** 购买人昵称(可为空) */
+    private String nickname;
+
+    /** 购买人手机号(脱敏,形如 138****4561) */
+    private String phone;
+
+    /** 该用户当月购买额(分) */
+    private Long amount;
+
+    public Integer getRank()
+    {
+        return rank;
+    }
+
+    public void setRank(Integer rank)
+    {
+        this.rank = rank;
+    }
+
+    public String getNickname()
+    {
+        return nickname;
+    }
+
+    public void setNickname(String nickname)
+    {
+        this.nickname = nickname;
+    }
+
+    public String getPhone()
+    {
+        return phone;
+    }
+
+    public void setPhone(String phone)
+    {
+        this.phone = phone;
+    }
+
+    public Long getAmount()
+    {
+        return amount;
+    }
+
+    public void setAmount(Long amount)
+    {
+        this.amount = amount;
+    }
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/WarehouseRecordVo.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/WarehouseRecordVo.java
new file mode 100644
index 0000000..ab26840
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/domain/vo/WarehouseRecordVo.java
@@ -0,0 +1,117 @@
+package com.ruoyi.user.domain.vo;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 云仓变动记录项 VO(「仓库记录」弹层列表)
+ *
+ * @author hugray
+ */
+public class WarehouseRecordVo
+{
+    /** 流水主键 */
+    private Long recordId;
+
+    /** 商品名称(变动时快照) */
+    private String productName;
+
+    /** 变动类型(1进货入库 2销售出库 3库存调整) */
+    private String changeType;
+
+    /** 变动类型中文名(由枚举下发) */
+    private String changeTypeName;
+
+    /** 变动数量(入库为正,出库为负) */
+    private Long changeQty;
+
+    /** 变动后库存 */
+    private Long afterQty;
+
+    /** 备注(进货单号等) */
+    private String remark;
+
+    /** 变动时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    public Long getRecordId()
+    {
+        return recordId;
+    }
+
+    public void setRecordId(Long recordId)
+    {
+        this.recordId = recordId;
+    }
+
+    public String getProductName()
+    {
+        return productName;
+    }
+
+    public void setProductName(String productName)
+    {
+        this.productName = productName;
+    }
+
+    public String getChangeType()
+    {
+        return changeType;
+    }
+
+    public void setChangeType(String changeType)
+    {
+        this.changeType = changeType;
+    }
+
+    public String getChangeTypeName()
+    {
+        return changeTypeName;
+    }
+
+    public void setChangeTypeName(String changeTypeName)
+    {
+        this.changeTypeName = changeTypeName;
+    }
+
+    public Long getChangeQty()
+    {
+        return changeQty;
+    }
+
+    public void setChangeQty(Long changeQty)
+    {
+        this.changeQty = changeQty;
+    }
+
+    public Long getAfterQty()
+    {
+        return afterQty;
+    }
+
+    public void setAfterQty(Long afterQty)
+    {
+        this.afterQty = afterQty;
+    }
+
+    public String getRemark()
+    {
+        return remark;
+    }
+
+    public void setRemark(String remark)
+    {
+        this.remark = remark;
+    }
+
+    public Date getCreateTime()
+    {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime)
+    {
+        this.createTime = createTime;
+    }
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/enums/PurchaseOrderStatusEnum.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/enums/PurchaseOrderStatusEnum.java
new file mode 100644
index 0000000..340bd35
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/enums/PurchaseOrderStatusEnum.java
@@ -0,0 +1,66 @@
+package com.ruoyi.user.enums;
+
+/**
+ * 进货单状态枚举
+ *
+ * 与 account_purchase_order.status 字段一一对应。本期进货即入库,仅一种终态。
+ *
+ * @author hugray
+ */
+public enum PurchaseOrderStatusEnum
+{
+    /** 已入库 */
+    STOCKED("1", "已入库");
+
+    /** 状态编码(落库值) */
+    private final String code;
+
+    /** 状态描述 */
+    private final String desc;
+
+    PurchaseOrderStatusEnum(String code, String desc)
+    {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public String getCode()
+    {
+        return code;
+    }
+
+    public String getDesc()
+    {
+        return desc;
+    }
+
+    /**
+     * 按编码获取枚举
+     *
+     * @param code 状态编码
+     * @return 命中返回枚举;未命中返回 null
+     */
+    public static PurchaseOrderStatusEnum getByCode(String code)
+    {
+        for (PurchaseOrderStatusEnum status : values())
+        {
+            if (status.code.equals(code))
+            {
+                return status;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 按编码取描述,未命中返回空字符串,避免前端展示 null
+     *
+     * @param code 状态编码
+     * @return 状态描述
+     */
+    public static String descOf(String code)
+    {
+        PurchaseOrderStatusEnum status = getByCode(code);
+        return status == null ? "" : status.getDesc();
+    }
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/enums/WarehouseChangeTypeEnum.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/enums/WarehouseChangeTypeEnum.java
new file mode 100644
index 0000000..740af6c
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/enums/WarehouseChangeTypeEnum.java
@@ -0,0 +1,70 @@
+package com.ruoyi.user.enums;
+
+/**
+ * 云仓变动类型枚举
+ *
+ * 与 account_warehouse_record.change_type 字段一一对应。
+ *
+ * @author hugray
+ */
+public enum WarehouseChangeTypeEnum
+{
+    /** 进货入库(数量为正) */
+    PURCHASE_IN("1", "进货入库"),
+    /** 销售出库(数量为负) */
+    SALE_OUT("2", "销售出库"),
+    /** 库存调整(可正可负) */
+    ADJUST("3", "库存调整");
+
+    /** 类型编码(落库值) */
+    private final String code;
+
+    /** 类型描述 */
+    private final String desc;
+
+    WarehouseChangeTypeEnum(String code, String desc)
+    {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public String getCode()
+    {
+        return code;
+    }
+
+    public String getDesc()
+    {
+        return desc;
+    }
+
+    /**
+     * 按编码获取枚举
+     *
+     * @param code 类型编码
+     * @return 命中返回枚举;未命中返回 null
+     */
+    public static WarehouseChangeTypeEnum getByCode(String code)
+    {
+        for (WarehouseChangeTypeEnum type : values())
+        {
+            if (type.code.equals(code))
+            {
+                return type;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 按编码取描述,未命中返回空字符串,避免前端展示 null
+     *
+     * @param code 类型编码
+     * @return 类型描述
+     */
+    public static String descOf(String code)
+    {
+        WarehouseChangeTypeEnum type = getByCode(code);
+        return type == null ? "" : type.getDesc();
+    }
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountPurchaseOrderMapper.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountPurchaseOrderMapper.java
new file mode 100644
index 0000000..0d658bf
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountPurchaseOrderMapper.java
@@ -0,0 +1,42 @@
+package com.ruoyi.user.mapper;
+
+import java.util.Date;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import com.ruoyi.user.domain.AccountPurchaseOrder;
+
+/**
+ * 会员进货单 数据层
+ *
+ * @author hugray
+ */
+public interface AccountPurchaseOrderMapper
+{
+    /**
+     * 新增进货单(落单即入库,order_no 唯一索引兜底幂等)
+     *
+     * @param accountPurchaseOrder 进货单
+     * @return 影响行数
+     */
+    public int insertPurchaseOrder(AccountPurchaseOrder accountPurchaseOrder);
+
+    /**
+     * 聚合本月进货额
+     *
+     * @param userId         会员ID
+     * @param monthStart     本月起始(含)
+     * @param nextMonthStart 次月起始(不含)
+     * @return 本月进货额(单位:分;无进货时为 0)
+     */
+    public Long selectMonthPurchaseAmount(@Param("userId") Long userId,
+                                          @Param("monthStart") Date monthStart,
+                                          @Param("nextMonthStart") Date nextMonthStart);
+
+    /**
+     * 查询指定会员的进货单列表(按进货时间倒序,配合 startPage 分页)
+     *
+     * @param userId 会员ID
+     * @return 进货单列表
+     */
+    public List<AccountPurchaseOrder> selectPurchaseOrderList(@Param("userId") Long userId);
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountSalesRecordMapper.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountSalesRecordMapper.java
new file mode 100644
index 0000000..e6fd7c2
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountSalesRecordMapper.java
@@ -0,0 +1,72 @@
+package com.ruoyi.user.mapper;
+
+import java.util.Date;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import com.ruoyi.user.domain.vo.ProductSalesRatioVo;
+import com.ruoyi.user.domain.vo.SalesMonthSummaryVo;
+import com.ruoyi.user.domain.vo.SalesTrendItemVo;
+import com.ruoyi.user.domain.vo.SalesUserRankingVo;
+
+/**
+ * 会员销售流水 数据层
+ *
+ * 全部为聚合查询,命中 idx_sales_seller_time(seller_id, sale_time)联合索引;
+ * 时间区间由 Service 传入月初 / 次月初 / 上月初,避免 SQL 内做日期方言运算。
+ *
+ * @author hugray
+ */
+public interface AccountSalesRecordMapper
+{
+    /**
+     * 聚合本月销售额 / 利润额 / 单数与上月利润额(单条 SQL 取回,避免多次数据库往返)
+     *
+     * @param sellerId       销售会员ID
+     * @param monthStart     本月起始(含)
+     * @param nextMonthStart 次月起始(不含,用于划定本月上界)
+     * @param prevMonthStart 上月起始(含,用于上月利润环比口径)
+     * @return 月汇总(单位:分;无流水时各栏为 0)
+     */
+    public SalesMonthSummaryVo selectMonthSummary(@Param("sellerId") Long sellerId,
+                                                  @Param("monthStart") Date monthStart,
+                                                  @Param("nextMonthStart") Date nextMonthStart,
+                                                  @Param("prevMonthStart") Date prevMonthStart);
+
+    /**
+     * 按日聚合本月销售额(趋势折线图原始数据,缺省日由 Service 补零)
+     *
+     * @param sellerId       销售会员ID
+     * @param monthStart     本月起始(含)
+     * @param nextMonthStart 次月起始(不含)
+     * @return 按日升序的趋势行(仅含当月有销售的日期)
+     */
+    public List<SalesTrendItemVo> selectDailyTrend(@Param("sellerId") Long sellerId,
+                                                   @Param("monthStart") Date monthStart,
+                                                   @Param("nextMonthStart") Date nextMonthStart);
+
+    /**
+     * 按商品聚合本月销售额(比例饼图数据,降序)
+     *
+     * @param sellerId       销售会员ID
+     * @param monthStart     本月起始(含)
+     * @param nextMonthStart 次月起始(不含)
+     * @return 商品销售额列表(降序)
+     */
+    public List<ProductSalesRatioVo> selectProductSalesRatio(@Param("sellerId") Long sellerId,
+                                                             @Param("monthStart") Date monthStart,
+                                                             @Param("nextMonthStart") Date nextMonthStart);
+
+    /**
+     * 按购买人聚合本月购买额(销售排行,降序取前 10)
+     *
+     * 手机号在 Service 下发前脱敏;由 SQL 侧 LIMIT 控制取数规模。
+     *
+     * @param sellerId       销售会员ID
+     * @param monthStart     本月起始(含)
+     * @param nextMonthStart 次月起始(不含)
+     * @return 排行列表(降序,最多 10 条;rank 由 Service 填充)
+     */
+    public List<SalesUserRankingVo> selectSalesUserRanking(@Param("sellerId") Long sellerId,
+                                                           @Param("monthStart") Date monthStart,
+                                                           @Param("nextMonthStart") Date nextMonthStart);
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountWarehouseMapper.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountWarehouseMapper.java
index ccbf199..d1369c4 100644
--- a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountWarehouseMapper.java
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountWarehouseMapper.java
@@ -1,6 +1,7 @@
 package com.ruoyi.user.mapper;
 
 import java.util.List;
+import org.apache.ibatis.annotations.Param;
 import com.ruoyi.user.domain.AccountWarehouse;
 
 /**
@@ -16,6 +17,27 @@
     public List<AccountWarehouse> selectWarehouseByUserId(Long userId);
 
     /**
+     * 按主键查询云仓库存(仅未删除行)
+     *
+     * 供进货前校验归属使用:取回行的 userId 与当前会员比对,防范水平越权。
+     *
+     * @param id 云仓行主键
+     * @return 云仓库存(不存在或已删除返回 null)
+     */
+    public AccountWarehouse selectWarehouseById(@Param("id") Long id);
+
+    /**
+     * 库存原子自增(进货入库)
+     *
+     * 用 SQL 内 `stock_qty = stock_qty + #{qty}` 自增,避免"读-改-写"竞态导致并发丢更新。
+     *
+     * @param id  云仓行主键
+     * @param qty 增加数量(正数)
+     * @return 影响行数
+     */
+    public int increaseStockQty(@Param("id") Long id, @Param("qty") Long qty);
+
+    /**
      * 新增云仓库存
      */
     public int insertWarehouse(AccountWarehouse accountWarehouse);
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountWarehouseRecordMapper.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountWarehouseRecordMapper.java
new file mode 100644
index 0000000..d89198c
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/mapper/AccountWarehouseRecordMapper.java
@@ -0,0 +1,29 @@
+package com.ruoyi.user.mapper;
+
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import com.ruoyi.user.domain.AccountWarehouseRecord;
+
+/**
+ * 会员云仓变动流水 数据层
+ *
+ * @author hugray
+ */
+public interface AccountWarehouseRecordMapper
+{
+    /**
+     * 新增云仓变动流水(进货入库 / 销售出库 / 库存调整)
+     *
+     * @param accountWarehouseRecord 变动流水
+     * @return 影响行数
+     */
+    public int insertWarehouseRecord(AccountWarehouseRecord accountWarehouseRecord);
+
+    /**
+     * 查询指定会员的云仓变动流水(按变动时间倒序,配合 startPage 分页)
+     *
+     * @param userId 会员ID
+     * @return 变动流水列表
+     */
+    public List<AccountWarehouseRecord> selectWarehouseRecordList(@Param("userId") Long userId);
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/service/IAccountMemberCenterService.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/service/IAccountMemberCenterService.java
new file mode 100644
index 0000000..cb9c5b4
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/service/IAccountMemberCenterService.java
@@ -0,0 +1,59 @@
+package com.ruoyi.user.service;
+
+import java.util.List;
+import com.ruoyi.user.domain.dto.MemberPurchaseDto;
+import com.ruoyi.user.domain.vo.MemberSalesStatisticsVo;
+import com.ruoyi.user.domain.vo.MemberWarehouseVo;
+import com.ruoyi.user.domain.vo.PurchaseOrderVo;
+import com.ruoyi.user.domain.vo.WarehouseRecordVo;
+
+/**
+ * 会员中心 业务层
+ *
+ * 覆盖「销售统计」与「我的仓库」两个 Tab:统计聚合、仓库列表、进货入库、变动记录、进货订单。
+ * 会员身份一律由调用方(Controller)从登录态解析后传入 userId,本层不接受前端直传。
+ *
+ * @author hugray
+ */
+public interface IAccountMemberCenterService
+{
+    /**
+     * 查询当前会员的销售统计(当月三栏 + 环比 + 趋势 + 比例 + 排行)
+     *
+     * @param userId 会员ID
+     * @return 销售统计聚合出参
+     */
+    public MemberSalesStatisticsVo getSalesStatistics(Long userId);
+
+    /**
+     * 查询当前会员的云仓列表(含低库存标记)
+     *
+     * @param userId 会员ID
+     * @return 云仓列表
+     */
+    public List<MemberWarehouseVo> getWarehouseList(Long userId);
+
+    /**
+     * 进货:生成进货单 + 增加库存 + 追加变动流水(同一事务)
+     *
+     * @param userId 会员ID
+     * @param dto    进货入参(warehouseId 须属于当前会员)
+     */
+    public void purchase(Long userId, MemberPurchaseDto dto);
+
+    /**
+     * 查询当前会员的云仓变动记录(按变动时间倒序,配合 startPage 分页)
+     *
+     * @param userId 会员ID
+     * @return 变动记录列表
+     */
+    public List<WarehouseRecordVo> getWarehouseRecordList(Long userId);
+
+    /**
+     * 查询当前会员的进货订单(按下单时间倒序,配合 startPage 分页)
+     *
+     * @param userId 会员ID
+     * @return 进货订单列表
+     */
+    public List<PurchaseOrderVo> getPurchaseOrderList(Long userId);
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/service/impl/AccountMemberCenterServiceImpl.java b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/service/impl/AccountMemberCenterServiceImpl.java
new file mode 100644
index 0000000..ca25661
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/java/com/ruoyi/user/service/impl/AccountMemberCenterServiceImpl.java
@@ -0,0 +1,387 @@
+package com.ruoyi.user.service.impl;
+
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ThreadLocalRandom;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import com.ruoyi.common.core.exception.ServiceException;
+import com.ruoyi.user.domain.AccountPurchaseOrder;
+import com.ruoyi.user.domain.AccountUser;
+import com.ruoyi.user.domain.AccountWarehouse;
+import com.ruoyi.user.domain.AccountWarehouseRecord;
+import com.ruoyi.user.domain.dto.MemberPurchaseDto;
+import com.ruoyi.user.domain.vo.MemberSalesStatisticsVo;
+import com.ruoyi.user.domain.vo.MemberWarehouseVo;
+import com.ruoyi.user.domain.vo.ProductSalesRatioVo;
+import com.ruoyi.user.domain.vo.PurchaseOrderVo;
+import com.ruoyi.user.domain.vo.SalesMonthSummaryVo;
+import com.ruoyi.user.domain.vo.SalesTrendItemVo;
+import com.ruoyi.user.domain.vo.SalesUserRankingVo;
+import com.ruoyi.user.domain.vo.WarehouseRecordVo;
+import com.ruoyi.user.enums.MemberLevelEnum;
+import com.ruoyi.user.enums.PurchaseOrderStatusEnum;
+import com.ruoyi.user.enums.WarehouseChangeTypeEnum;
+import com.ruoyi.user.mapper.AccountPurchaseOrderMapper;
+import com.ruoyi.user.mapper.AccountSalesRecordMapper;
+import com.ruoyi.user.mapper.AccountUserMapper;
+import com.ruoyi.user.mapper.AccountWarehouseMapper;
+import com.ruoyi.user.mapper.AccountWarehouseRecordMapper;
+import com.ruoyi.user.service.IAccountMemberCenterService;
+
+/**
+ * 会员中心 业务实现
+ *
+ * @author hugray
+ */
+@Service
+public class AccountMemberCenterServiceImpl implements IAccountMemberCenterService
+{
+    /** 进货单号前缀 */
+    private static final String PURCHASE_ORDER_PREFIX = "PG";
+
+    /** 进货单号随机段上界(4 位) */
+    private static final int ORDER_NO_RANDOM_BOUND = 10000;
+
+    /** 销售排行取前 N 名 */
+    private static final int RANKING_LIMIT = 10;
+
+    @Autowired
+    private AccountUserMapper accountUserMapper;
+
+    @Autowired
+    private AccountSalesRecordMapper accountSalesRecordMapper;
+
+    @Autowired
+    private AccountPurchaseOrderMapper accountPurchaseOrderMapper;
+
+    @Autowired
+    private AccountWarehouseMapper accountWarehouseMapper;
+
+    @Autowired
+    private AccountWarehouseRecordMapper accountWarehouseRecordMapper;
+
+    @Override
+    public MemberSalesStatisticsVo getSalesStatistics(Long userId)
+    {
+        // STEP 1: 校验会员身份(网关注入的登录态)
+        if (userId == null)
+        {
+            throw new ServiceException("获取销售统计失败");
+        }
+
+        // STEP 2: 取会员资料(手机号脱敏 + 等级归一化兜底)
+        AccountUser user = accountUserMapper.selectAccountUserById(userId);
+        if (user == null)
+        {
+            throw new ServiceException("获取销售统计失败");
+        }
+
+        // STEP 3: 计算本月 / 上月时间边界(在 Java 侧算好,避免 SQL 日期方言差异)
+        LocalDate today = LocalDate.now();
+        LocalDate monthStartDate = today.withDayOfMonth(1);
+        Date monthStart = toDate(monthStartDate);
+        Date nextMonthStart = toDate(monthStartDate.plusMonths(1));
+        Date prevMonthStart = toDate(monthStartDate.minusMonths(1));
+
+        // STEP 4: 聚合本月销售额 / 利润额 / 单数与上月利润
+        SalesMonthSummaryVo summary = accountSalesRecordMapper.selectMonthSummary(
+            userId, monthStart, nextMonthStart, prevMonthStart);
+        if (summary == null)
+        {
+            summary = new SalesMonthSummaryVo();
+        }
+
+        // STEP 5: 聚合本月进货额(来自进货单)
+        Long monthPurchaseAmount = accountPurchaseOrderMapper.selectMonthPurchaseAmount(
+            userId, monthStart, nextMonthStart);
+
+        // STEP 6: 组装出参
+        MemberSalesStatisticsVo vo = new MemberSalesStatisticsVo();
+        vo.setPhone(maskPhone(user.getPhone()));
+        vo.setMemberLevel(MemberLevelEnum.normalize(user.getSystemLevel()));
+        vo.setMonthSalesAmount(nullToZero(summary.getSalesAmount()));
+        vo.setMonthPurchaseAmount(nullToZero(monthPurchaseAmount));
+        vo.setMonthProfitAmount(nullToZero(summary.getProfitAmount()));
+        vo.setMonthSalesCount(summary.getSalesCount() == null ? 0 : summary.getSalesCount());
+        vo.setProfitGrowthRate(calcGrowthRate(summary.getProfitAmount(), summary.getPrevMonthProfit()));
+
+        // STEP 7: 趋势折线(当月 1 号到当日,缺省日补 0)
+        vo.setSalesTrend(buildSalesTrend(userId, monthStart, nextMonthStart, today));
+
+        // STEP 8: 商品销售额比例
+        List<ProductSalesRatioVo> ratioList = accountSalesRecordMapper.selectProductSalesRatio(
+            userId, monthStart, nextMonthStart);
+        vo.setProductSalesRatio(ratioList == null ? new ArrayList<>() : ratioList);
+
+        // STEP 9: 销售用户排行(脱敏 + 填名次)
+        vo.setSalesUserRanking(buildRanking(userId, monthStart, nextMonthStart));
+        return vo;
+    }
+
+    @Override
+    public List<MemberWarehouseVo> getWarehouseList(Long userId)
+    {
+        if (userId == null)
+        {
+            throw new ServiceException("获取仓库列表失败");
+        }
+        List<AccountWarehouse> warehouses = accountWarehouseMapper.selectWarehouseByUserId(userId);
+        List<MemberWarehouseVo> voList = new ArrayList<>();
+        if (warehouses == null)
+        {
+            return voList;
+        }
+        for (AccountWarehouse warehouse : warehouses)
+        {
+            MemberWarehouseVo vo = new MemberWarehouseVo();
+            vo.setWarehouseId(warehouse.getId());
+            vo.setProductName(warehouse.getProductName());
+            // 商品图片列在 account_warehouse 不存在,恒为 null,由前端使用占位图
+            vo.setProductImage(null);
+            vo.setStockQty(nullToZero(warehouse.getStockQty()));
+            vo.setMinStockQty(nullToZero(warehouse.getMinStockQty()));
+            vo.setLowStock(isLowStock(warehouse.getStockQty(), warehouse.getMinStockQty()));
+            voList.add(vo);
+        }
+        return voList;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void purchase(Long userId, MemberPurchaseDto dto)
+    {
+        // STEP 1: 基础校验
+        if (userId == null || dto == null || dto.getWarehouseId() == null)
+        {
+            throw new ServiceException("进货失败,请稍后重试");
+        }
+        if (dto.getQty() == null || dto.getQty() <= 0)
+        {
+            throw new ServiceException("进货数量必须大于 0");
+        }
+
+        // STEP 2: 校验云仓归属(防水平越权:非本会员商品直接拒绝)
+        AccountWarehouse warehouse = accountWarehouseMapper.selectWarehouseById(dto.getWarehouseId());
+        if (warehouse == null || !userId.equals(warehouse.getUserId()))
+        {
+            throw new ServiceException("商品不存在或不属于当前会员");
+        }
+
+        // STEP 3: 生成唯一进货单号(时间戳 + 随机段,UNIQUE KEY 兜底幂等)
+        String orderNo = generatePurchaseOrderNo();
+        Long qty = dto.getQty();
+        long unitPrice = dto.getUnitPrice() == null || dto.getUnitPrice() < 0 ? 0L : dto.getUnitPrice();
+
+        // STEP 4: 落进货单(status=已入库)
+        AccountPurchaseOrder order = new AccountPurchaseOrder();
+        order.setOrderNo(orderNo);
+        order.setUserId(userId);
+        order.setWarehouseId(warehouse.getId());
+        order.setProductName(warehouse.getProductName());
+        order.setQty(qty);
+        order.setUnitPrice(unitPrice);
+        order.setTotalAmount(qty * unitPrice);
+        order.setStatus(PurchaseOrderStatusEnum.STOCKED.getCode());
+        accountPurchaseOrderMapper.insertPurchaseOrder(order);
+
+        // STEP 5: 库存原子自增(SQL 内自增,避免并发读改写丢更新)
+        accountWarehouseMapper.increaseStockQty(warehouse.getId(), qty);
+
+        // STEP 6: 追加云仓变动流水(进货入库,数量为正)
+        long afterQty = nullToZero(warehouse.getStockQty()) + qty;
+        AccountWarehouseRecord record = new AccountWarehouseRecord();
+        record.setUserId(userId);
+        record.setWarehouseId(warehouse.getId());
+        record.setProductName(warehouse.getProductName());
+        record.setChangeType(WarehouseChangeTypeEnum.PURCHASE_IN.getCode());
+        record.setChangeQty(qty);
+        record.setAfterQty(afterQty);
+        record.setBizNo(orderNo);
+        record.setRemark("进货单 " + orderNo);
+        accountWarehouseRecordMapper.insertWarehouseRecord(record);
+        // STEP 7: 事务提交(由 Spring 统一提交)
+    }
+
+    @Override
+    public List<WarehouseRecordVo> getWarehouseRecordList(Long userId)
+    {
+        if (userId == null)
+        {
+            throw new ServiceException("获取仓库记录失败");
+        }
+        List<AccountWarehouseRecord> records = accountWarehouseRecordMapper.selectWarehouseRecordList(userId);
+        List<WarehouseRecordVo> voList = new ArrayList<>();
+        if (records == null)
+        {
+            return voList;
+        }
+        for (AccountWarehouseRecord record : records)
+        {
+            WarehouseRecordVo vo = new WarehouseRecordVo();
+            vo.setRecordId(record.getRecordId());
+            vo.setProductName(record.getProductName());
+            vo.setChangeType(record.getChangeType());
+            vo.setChangeTypeName(WarehouseChangeTypeEnum.descOf(record.getChangeType()));
+            vo.setChangeQty(nullToZero(record.getChangeQty()));
+            vo.setAfterQty(nullToZero(record.getAfterQty()));
+            vo.setRemark(record.getRemark());
+            vo.setCreateTime(record.getCreateTime());
+            voList.add(vo);
+        }
+        return voList;
+    }
+
+    @Override
+    public List<PurchaseOrderVo> getPurchaseOrderList(Long userId)
+    {
+        if (userId == null)
+        {
+            throw new ServiceException("获取进货订单失败");
+        }
+        List<AccountPurchaseOrder> orders = accountPurchaseOrderMapper.selectPurchaseOrderList(userId);
+        List<PurchaseOrderVo> voList = new ArrayList<>();
+        if (orders == null)
+        {
+            return voList;
+        }
+        for (AccountPurchaseOrder order : orders)
+        {
+            PurchaseOrderVo vo = new PurchaseOrderVo();
+            vo.setOrderId(order.getOrderId());
+            vo.setOrderNo(order.getOrderNo());
+            vo.setProductName(order.getProductName());
+            vo.setQty(nullToZero(order.getQty()));
+            vo.setUnitPrice(nullToZero(order.getUnitPrice()));
+            vo.setTotalAmount(nullToZero(order.getTotalAmount()));
+            vo.setStatus(order.getStatus());
+            vo.setStatusName(PurchaseOrderStatusEnum.descOf(order.getStatus()));
+            vo.setCreateTime(order.getCreateTime());
+            voList.add(vo);
+        }
+        return voList;
+    }
+
+    /**
+     * 组装销售额趋势:把「有销售的日期」铺满当月 1 号至当日,缺省日补 0
+     */
+    private List<SalesTrendItemVo> buildSalesTrend(Long userId, Date monthStart, Date nextMonthStart, LocalDate today)
+    {
+        List<SalesTrendItemVo> rawList = accountSalesRecordMapper.selectDailyTrend(userId, monthStart, nextMonthStart);
+        Map<Integer, Long> amountByDay = new HashMap<>();
+        if (rawList != null)
+        {
+            for (SalesTrendItemVo item : rawList)
+            {
+                amountByDay.put(item.getDayOfMonth(), nullToZero(item.getAmount()));
+            }
+        }
+        List<SalesTrendItemVo> result = new ArrayList<>();
+        int maxDay = today.getDayOfMonth();
+        for (int day = 1; day <= maxDay; day++)
+        {
+            Long amount = amountByDay.get(day);
+            result.add(new SalesTrendItemVo(day + "号", amount == null ? 0L : amount));
+        }
+        return result;
+    }
+
+    /**
+     * 组装销售用户排行:手机号脱敏 + 依次填名次
+     */
+    private List<SalesUserRankingVo> buildRanking(Long userId, Date monthStart, Date nextMonthStart)
+    {
+        List<SalesUserRankingVo> rankingList = accountSalesRecordMapper.selectSalesUserRanking(
+            userId, monthStart, nextMonthStart);
+        List<SalesUserRankingVo> result = new ArrayList<>();
+        if (rankingList == null)
+        {
+            return result;
+        }
+        int rank = 1;
+        for (SalesUserRankingVo item : rankingList)
+        {
+            if (rank > RANKING_LIMIT)
+            {
+                break;
+            }
+            item.setRank(rank);
+            item.setPhone(maskPhone(item.getPhone()));
+            item.setAmount(nullToZero(item.getAmount()));
+            result.add(item);
+            rank++;
+        }
+        return result;
+    }
+
+    /**
+     * 计算利润环比:上月利润为 0 时返回 0(不抛除零),否则四舍五入为整数百分比
+     */
+    private Integer calcGrowthRate(Long current, Long previous)
+    {
+        long prev = nullToZero(previous);
+        if (prev == 0L)
+        {
+            return 0;
+        }
+        long cur = nullToZero(current);
+        return (int) Math.round((cur - prev) * 100.0 / prev);
+    }
+
+    /**
+     * 低库存判定:库存存在且低于最低需求库存
+     */
+    private boolean isLowStock(Long stockQty, Long minStockQty)
+    {
+        if (stockQty == null || minStockQty == null)
+        {
+            return false;
+        }
+        return stockQty < minStockQty;
+    }
+
+    /**
+     * 手机号脱敏:长度不足 7 位原样返回,否则保留前 3 位与后 4 位
+     */
+    private String maskPhone(String phone)
+    {
+        if (phone == null || phone.length() < 7)
+        {
+            return phone;
+        }
+        return phone.substring(0, 3) + "****" + phone.substring(phone.length() - 4);
+    }
+
+    /**
+     * 生成进货单号:PG + yyyyMMddHHmmss + 4 位随机,唯一索引兜底
+     */
+    private String generatePurchaseOrderNo()
+    {
+        String time = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(java.time.LocalDateTime.now());
+        String random = String.format("%04d", ThreadLocalRandom.current().nextInt(ORDER_NO_RANDOM_BOUND));
+        return PURCHASE_ORDER_PREFIX + time + random;
+    }
+
+    /**
+     * LocalDate 转 java.util.Date(按系统时区当天零点)
+     */
+    private Date toDate(LocalDate date)
+    {
+        return Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
+    }
+
+    /**
+     * Long 空值归零
+     */
+    private long nullToZero(Long value)
+    {
+        return value == null ? 0L : value;
+    }
+}
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountPurchaseOrderMapper.xml b/hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountPurchaseOrderMapper.xml
new file mode 100644
index 0000000..50b5155
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountPurchaseOrderMapper.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.user.mapper.AccountPurchaseOrderMapper">
+
+    <resultMap type="com.ruoyi.user.domain.AccountPurchaseOrder" id="AccountPurchaseOrderResult">
+        <id     property="orderId"      column="order_id"      />
+        <result property="orderNo"      column="order_no"      />
+        <result property="userId"       column="user_id"       />
+        <result property="warehouseId"  column="warehouse_id"  />
+        <result property="productName"  column="product_name"  />
+        <result property="qty"          column="qty"           />
+        <result property="unitPrice"    column="unit_price"    />
+        <result property="totalAmount"  column="total_amount"  />
+        <result property="status"       column="status"        />
+        <result property="purchaseTime" column="purchase_time" />
+        <result property="delFlag"      column="del_flag"      />
+        <result property="createBy"     column="create_by"     />
+        <result property="createTime"   column="create_time"   />
+        <result property="updateBy"     column="update_by"     />
+        <result property="updateTime"   column="update_time"   />
+        <result property="remark"       column="remark"        />
+    </resultMap>
+
+    <sql id="selectPurchaseOrderVo">
+        select order_id, order_no, user_id, warehouse_id, product_name, qty, unit_price,
+               total_amount, status, purchase_time, del_flag,
+               create_by, create_time, update_by, update_time, remark
+        from account_purchase_order
+    </sql>
+
+    <!-- 落单即入库:purchase_time 即聚合口径时间,create_time 记录写入时间 -->
+    <insert id="insertPurchaseOrder" parameterType="com.ruoyi.user.domain.AccountPurchaseOrder" useGeneratedKeys="true" keyProperty="orderId">
+        insert into account_purchase_order(
+            order_no,
+            user_id,
+            <if test="warehouseId != null">warehouse_id,</if>
+            <if test="productName != null">product_name,</if>
+            qty,
+            unit_price,
+            total_amount,
+            status,
+            purchase_time,
+            del_flag,
+            create_time
+        )values(
+            #{orderNo},
+            #{userId},
+            <if test="warehouseId != null">#{warehouseId},</if>
+            <if test="productName != null">#{productName},</if>
+            #{qty},
+            #{unitPrice},
+            #{totalAmount},
+            #{status},
+            sysdate(),
+            '0',
+            sysdate()
+        )
+    </insert>
+
+    <!-- 本月进货额区间 [monthStart, nextMonthStart),命中 idx_purchase_user_time -->
+    <select id="selectMonthPurchaseAmount" resultType="java.lang.Long">
+        select ifnull(sum(total_amount), 0)
+        from account_purchase_order
+        where del_flag = '0' and user_id = #{userId}
+          and purchase_time &gt;= #{monthStart} and purchase_time &lt; #{nextMonthStart}
+    </select>
+
+    <select id="selectPurchaseOrderList" parameterType="Long" resultMap="AccountPurchaseOrderResult">
+        <include refid="selectPurchaseOrderVo"/>
+        where del_flag = '0' and user_id = #{userId}
+        order by order_id desc
+    </select>
+
+</mapper>
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountSalesRecordMapper.xml b/hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountSalesRecordMapper.xml
new file mode 100644
index 0000000..eda2339
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountSalesRecordMapper.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.user.mapper.AccountSalesRecordMapper">
+
+    <resultMap type="com.ruoyi.user.domain.vo.SalesMonthSummaryVo" id="SalesMonthSummaryResult">
+        <result property="salesAmount"     column="sales_amount"      />
+        <result property="profitAmount"    column="profit_amount"     />
+        <result property="salesCount"      column="sales_count"       />
+        <result property="prevMonthProfit" column="prev_month_profit" />
+    </resultMap>
+
+    <resultMap type="com.ruoyi.user.domain.vo.SalesTrendItemVo" id="SalesTrendResult">
+        <result property="dayOfMonth" column="day_of_month" />
+        <result property="amount"     column="amount"       />
+    </resultMap>
+
+    <resultMap type="com.ruoyi.user.domain.vo.ProductSalesRatioVo" id="ProductSalesRatioResult">
+        <result property="productName" column="product_name" />
+        <result property="amount"      column="amount"       />
+    </resultMap>
+
+    <resultMap type="com.ruoyi.user.domain.vo.SalesUserRankingVo" id="SalesUserRankingResult">
+        <result property="nickname" column="nickname" />
+        <result property="phone"    column="phone"    />
+        <result property="amount"   column="amount"   />
+    </resultMap>
+
+    <!-- 单条 SQL 聚合三栏 + 上月利润:本月区间 [monthStart, nextMonthStart),上月利润区间 [prevMonthStart, monthStart) -->
+    <select id="selectMonthSummary" resultMap="SalesMonthSummaryResult">
+        select
+            ifnull(sum(case when sale_time &gt;= #{monthStart} and sale_time &lt; #{nextMonthStart} then amount end), 0)        as sales_amount,
+            ifnull(sum(case when sale_time &gt;= #{monthStart} and sale_time &lt; #{nextMonthStart} then profit_amount end), 0) as profit_amount,
+            ifnull(sum(case when sale_time &gt;= #{monthStart} and sale_time &lt; #{nextMonthStart} then 1 else 0 end), 0)      as sales_count,
+            ifnull(sum(case when sale_time &gt;= #{prevMonthStart} and sale_time &lt; #{monthStart} then profit_amount end), 0)  as prev_month_profit
+        from account_sales_record
+        where del_flag = '0' and seller_id = #{sellerId}
+    </select>
+
+    <select id="selectDailyTrend" resultMap="SalesTrendResult">
+        select
+            day(sale_time)              as day_of_month,
+            ifnull(sum(amount), 0)      as amount
+        from account_sales_record
+        where del_flag = '0' and seller_id = #{sellerId}
+          and sale_time &gt;= #{monthStart} and sale_time &lt; #{nextMonthStart}
+        group by day(sale_time)
+        order by day_of_month asc
+    </select>
+
+    <select id="selectProductSalesRatio" resultMap="ProductSalesRatioResult">
+        select
+            ifnull(product_name, '')    as product_name,
+            ifnull(sum(amount), 0)      as amount
+        from account_sales_record
+        where del_flag = '0' and seller_id = #{sellerId}
+          and sale_time &gt;= #{monthStart} and sale_time &lt; #{nextMonthStart}
+        group by product_name
+        order by amount desc
+    </select>
+
+    <!-- 排行取前 10,控制单次返回规模 -->
+    <select id="selectSalesUserRanking" resultMap="SalesUserRankingResult">
+        select
+            buyer_name                  as nickname,
+            buyer_phone                 as phone,
+            ifnull(sum(amount), 0)      as amount
+        from account_sales_record
+        where del_flag = '0' and seller_id = #{sellerId}
+          and sale_time &gt;= #{monthStart} and sale_time &lt; #{nextMonthStart}
+        group by buyer_id, buyer_name, buyer_phone
+        order by amount desc
+        limit 10
+    </select>
+
+</mapper>
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountWarehouseMapper.xml b/hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountWarehouseMapper.xml
index a95689d..fa6cb16 100644
--- a/hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountWarehouseMapper.xml
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountWarehouseMapper.xml
@@ -30,6 +30,19 @@
         order by id asc
     </select>
 
+    <select id="selectWarehouseById" parameterType="Long" resultMap="AccountWarehouseResult">
+        <include refid="selectWarehouseVo"/>
+        where del_flag = '0' and id = #{id}
+    </select>
+
+    <!-- 库存原子自增:非空校验兜底,避免库存为 NULL 时自增结果为 NULL -->
+    <update id="increaseStockQty">
+        update account_warehouse
+        set stock_qty = ifnull(stock_qty, 0) + #{qty},
+            update_time = sysdate()
+        where id = #{id} and del_flag = '0'
+    </update>
+
     <insert id="insertWarehouse" parameterType="AccountWarehouse" useGeneratedKeys="true" keyProperty="id">
         insert into account_warehouse(
             <if test="userId != null">user_id,</if>
diff --git a/hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountWarehouseRecordMapper.xml b/hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountWarehouseRecordMapper.xml
new file mode 100644
index 0000000..8ebbc91
--- /dev/null
+++ b/hugray-server/ruoyi-modules/ruoyi-user/src/main/resources/mapper/user/AccountWarehouseRecordMapper.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.user.mapper.AccountWarehouseRecordMapper">
+
+    <resultMap type="com.ruoyi.user.domain.AccountWarehouseRecord" id="AccountWarehouseRecordResult">
+        <id     property="recordId"    column="record_id"    />
+        <result property="userId"      column="user_id"      />
+        <result property="warehouseId" column="warehouse_id" />
+        <result property="productName" column="product_name" />
+        <result property="changeType"  column="change_type"  />
+        <result property="changeQty"   column="change_qty"   />
+        <result property="afterQty"    column="after_qty"    />
+        <result property="bizNo"       column="biz_no"       />
+        <result property="delFlag"     column="del_flag"     />
+        <result property="createBy"    column="create_by"    />
+        <result property="createTime"  column="create_time"  />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateTime"  column="update_time"  />
+        <result property="remark"      column="remark"       />
+    </resultMap>
+
+    <sql id="selectWarehouseRecordVo">
+        select record_id, user_id, warehouse_id, product_name, change_type, change_qty,
+               after_qty, biz_no, del_flag, create_by, create_time, update_by, update_time, remark
+        from account_warehouse_record
+    </sql>
+
+    <!-- 变动时间即 create_time,入库时统一落 sysdate(),避免与业务时间口径漂移 -->
+    <insert id="insertWarehouseRecord" parameterType="com.ruoyi.user.domain.AccountWarehouseRecord" useGeneratedKeys="true" keyProperty="recordId">
+        insert into account_warehouse_record(
+            user_id,
+            <if test="warehouseId != null">warehouse_id,</if>
+            <if test="productName != null">product_name,</if>
+            change_type,
+            change_qty,
+            after_qty,
+            <if test="bizNo != null">biz_no,</if>
+            <if test="remark != null">remark,</if>
+            del_flag,
+            create_time
+        )values(
+            #{userId},
+            <if test="warehouseId != null">#{warehouseId},</if>
+            <if test="productName != null">#{productName},</if>
+            #{changeType},
+            #{changeQty},
+            #{afterQty},
+            <if test="bizNo != null">#{bizNo},</if>
+            <if test="remark != null">#{remark},</if>
+            '0',
+            sysdate()
+        )
+    </insert>
+
+    <select id="selectWarehouseRecordList" parameterType="Long" resultMap="AccountWarehouseRecordResult">
+        <include refid="selectWarehouseRecordVo"/>
+        where del_flag = '0' and user_id = #{userId}
+        order by record_id desc
+    </select>
+
+</mapper>
diff --git a/hugray-server/sql/hugray_account_member_center_20261014.sql b/hugray-server/sql/hugray_account_member_center_20261014.sql
new file mode 100644
index 0000000..65e614d
--- /dev/null
+++ b/hugray-server/sql/hugray_account_member_center_20261014.sql
@@ -0,0 +1,96 @@
+-- ----------------------------
+-- C 端会员 个人中心-会员中心 相关变更(ruoyi-user 用户服务)
+--
+-- 需求:个人中心「会员中心」页需展示「销售统计」(当月销售额/进货额/利润、销售额趋势、
+--       商品销售额比例、销售用户排行)与「我的仓库」(库存列表、低库存警示、进货、仓库记录)。
+-- 变更内容:
+--   1. 新增「会员销售流水表」account_sales_record,销售三栏/趋势/比例/排行由其按时间实时聚合;
+--   2. 新增「会员进货单表」account_purchase_order,进货入库留痕,当月进货额由其聚合;
+--   3. 新增「会员云仓变动流水表」account_warehouse_record,记录每次库存变动(进货入库等)。
+--
+-- 说明(按权威库 192.168.110.111 的既有结构对齐):
+--   account_warehouse 已有库存列,本脚本不改动该表;进货仅在其上做 stock_qty 原子自增。
+--   account_user 的 9 个业务统计列本期不回填,页面数据一律由流水表实时聚合,避免双写口径不一致。
+--
+-- 目标库 hugray-account 由使用方预先创建(utf8mb4)。
+-- 注意:库名含连字符,任何引用都必须用反引号。
+-- ----------------------------
+
+USE `hugray-account`;
+
+-- 变更 1:新增会员销售流水表(一条流水 = 一次销售事件,含销售额与利润额)
+CREATE TABLE IF NOT EXISTS `account_sales_record` (
+  `record_id`     bigint(20)   NOT NULL AUTO_INCREMENT COMMENT '销售流水ID',
+  `seller_id`     bigint(20)   NOT NULL                COMMENT '销售会员ID(account_user.user_id)',
+  `buyer_id`      bigint(20)   DEFAULT NULL            COMMENT '购买会员ID(account_user.user_id,散客为空)',
+  `buyer_name`    varchar(64)  DEFAULT NULL            COMMENT '购买人昵称(销售排行展示用)',
+  `buyer_phone`   varchar(20)  DEFAULT NULL            COMMENT '购买人手机号(下发脱敏)',
+  `product_name`  varchar(128) DEFAULT NULL            COMMENT '商品名称(比例图/排行展示用)',
+  `qty`           bigint(20)   NOT NULL DEFAULT 0      COMMENT '销售数量',
+  `amount`        bigint(20)   NOT NULL DEFAULT 0      COMMENT '销售额(单位:分)',
+  `profit_amount` bigint(20)   NOT NULL DEFAULT 0      COMMENT '利润额(单位:分,可为负)',
+  `sale_time`     datetime     DEFAULT NULL            COMMENT '销售时间(聚合口径)',
+  `del_flag`      char(1)      DEFAULT '0'             COMMENT '删除标志(0存在 2删除)',
+  `create_by`     varchar(64)  DEFAULT ''              COMMENT '创建者',
+  `create_time`   datetime     DEFAULT NULL            COMMENT '创建时间',
+  `update_by`     varchar(64)  DEFAULT ''              COMMENT '更新者',
+  `update_time`   datetime     DEFAULT NULL            COMMENT '更新时间',
+  `remark`        varchar(500) DEFAULT NULL            COMMENT '备注',
+  PRIMARY KEY (`record_id`),
+  -- 覆盖「按销售会员 + 时间区间」的聚合,避免全表扫描
+  KEY `idx_sales_seller_time` (`seller_id`, `sale_time`)
+) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COMMENT='会员销售流水表';
+
+-- 变更 2:新增会员进货单表(生成进货单即增加云仓库存,下单时间即聚合口径)
+CREATE TABLE IF NOT EXISTS `account_purchase_order` (
+  `order_id`      bigint(20)   NOT NULL AUTO_INCREMENT COMMENT '进货单ID',
+  `order_no`      varchar(64)  NOT NULL                COMMENT '进货单号(幂等唯一)',
+  `user_id`       bigint(20)   NOT NULL                COMMENT '进货会员ID(account_user.user_id)',
+  `warehouse_id`  bigint(20)   DEFAULT NULL            COMMENT '云仓行ID(account_warehouse.id,快照)',
+  `product_name`  varchar(128) DEFAULT NULL            COMMENT '商品名称(快照)',
+  `qty`           bigint(20)   NOT NULL DEFAULT 0      COMMENT '进货数量',
+  `unit_price`    bigint(20)   NOT NULL DEFAULT 0      COMMENT '进货单价(单位:分)',
+  `total_amount`  bigint(20)   NOT NULL DEFAULT 0      COMMENT '进货金额(单位:分)= qty × unit_price',
+  `status`        char(1)      DEFAULT '1'             COMMENT '状态(1已入库)',
+  `purchase_time` datetime     DEFAULT NULL            COMMENT '进货时间(聚合口径)',
+  `del_flag`      char(1)      DEFAULT '0'             COMMENT '删除标志(0存在 2删除)',
+  `create_by`     varchar(64)  DEFAULT ''              COMMENT '创建者',
+  `create_time`   datetime     DEFAULT NULL            COMMENT '创建时间',
+  `update_by`     varchar(64)  DEFAULT ''              COMMENT '更新者',
+  `update_time`   datetime     DEFAULT NULL            COMMENT '更新时间',
+  `remark`        varchar(500) DEFAULT NULL            COMMENT '备注',
+  PRIMARY KEY (`order_id`),
+  -- 业务幂等:进货单号全局唯一,重复入库被数据库兜底拦截
+  UNIQUE KEY `uk_purchase_order_no` (`order_no`),
+  -- 覆盖「按会员 + 时间区间」的进货额聚合
+  KEY `idx_purchase_user_time` (`user_id`, `purchase_time`)
+) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COMMENT='会员进货单表';
+
+-- 变更 3:新增会员云仓变动流水表(进货入库/销售出库等库存变动留痕)
+CREATE TABLE IF NOT EXISTS `account_warehouse_record` (
+  `record_id`     bigint(20)   NOT NULL AUTO_INCREMENT COMMENT '流水ID',
+  `user_id`       bigint(20)   NOT NULL                COMMENT '会员ID(account_user.user_id)',
+  `warehouse_id`  bigint(20)   DEFAULT NULL            COMMENT '云仓行ID(account_warehouse.id)',
+  `product_name`  varchar(128) DEFAULT NULL            COMMENT '商品名称(快照)',
+  `change_type`   char(1)      NOT NULL                COMMENT '变动类型(1进货入库 2销售出库 3库存调整)',
+  `change_qty`    bigint(20)   NOT NULL DEFAULT 0      COMMENT '变动数量(入库为正,出库为负)',
+  `after_qty`     bigint(20)   NOT NULL DEFAULT 0      COMMENT '变动后库存',
+  `biz_no`        varchar(64)  DEFAULT NULL            COMMENT '业务单号(关联进货单等)',
+  `del_flag`      char(1)      DEFAULT '0'             COMMENT '删除标志(0存在 2删除)',
+  `create_by`     varchar(64)  DEFAULT ''              COMMENT '创建者',
+  `create_time`   datetime     DEFAULT NULL            COMMENT '变动时间',
+  `update_by`     varchar(64)  DEFAULT ''              COMMENT '更新者',
+  `update_time`   datetime     DEFAULT NULL            COMMENT '更新时间',
+  `remark`        varchar(500) DEFAULT NULL            COMMENT '备注',
+  PRIMARY KEY (`record_id`),
+  -- 覆盖「按会员 + 时间倒序」的流水分页
+  KEY `idx_whrecord_user_time` (`user_id`, `create_time`),
+  KEY `idx_whrecord_warehouse` (`warehouse_id`)
+) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8mb4 COMMENT='会员云仓变动流水表';
+
+-- ----------------------------
+-- 回滚语句(如需回滚,按依赖倒序执行)
+-- ----------------------------
+-- DROP TABLE IF EXISTS `account_warehouse_record`;
+-- DROP TABLE IF EXISTS `account_purchase_order`;
+-- DROP TABLE IF EXISTS `account_sales_record`;
diff --git a/hugray-user-miniapp/api/index.js b/hugray-user-miniapp/api/index.js
index 8683ba6..45baca9 100644
--- a/hugray-user-miniapp/api/index.js
+++ b/hugray-user-miniapp/api/index.js
@@ -110,6 +110,49 @@
 }
 
 /**
+ * 查询当前会员的销售统计(会员中心「销售统计」Tab)
+ * 返回 data 含 phone / memberLevel、三栏金额(单位:分)、利润环比 profitGrowthRate(%)、
+ * 销售额趋势 salesTrend、商品销售额比例 productSalesRatio、销售用户排行 salesUserRanking
+ */
+export function getMemberSalesStatistics() {
+    return get('/miniapp/account/user/member/sales-statistics')
+}
+
+/**
+ * 查询当前会员的云仓列表(「我的仓库」Tab)
+ * 返回 data 为数组,元素含 warehouseId / productName / stockQty / minStockQty / lowStock
+ */
+export function getMemberWarehouses() {
+    return get('/miniapp/account/user/member/warehouses')
+}
+
+/**
+ * 会员进货(生成进货单并增加云仓库存,会员身份由网关注入)
+ * @param {Object} data { warehouseId, qty, unitPrice } unitPrice 单位为分,选填
+ */
+export function memberPurchase(data) {
+    return post('/miniapp/account/user/member/purchase', data)
+}
+
+/**
+ * 查询当前会员的云仓变动记录(「仓库记录」弹层)
+ * @param {Object} params { pageNum, pageSize }
+ * 说明:后端返回 TableDataInfo,数据在顶层 rows(非 data 包裹),总数为 total
+ */
+export function getMemberWarehouseRecords(params) {
+    return get('/miniapp/account/user/member/warehouse-records', params)
+}
+
+/**
+ * 查询当前会员的进货订单(「进货订单」Tab)
+ * @param {Object} params { pageNum, pageSize }
+ * 说明:后端返回 TableDataInfo,数据在顶层 rows(非 data 包裹),总数为 total
+ */
+export function getMemberPurchaseOrders(params) {
+    return get('/miniapp/account/user/member/purchase-orders', params)
+}
+
+/**
  * 上传头像文件到文件服务,返回 { data: { name, url } }
  * 说明:走网关 /file/** -> ruoyi-file,需登录态(网关白名单不含 /file/upload)
  * @param {String} filePath 本地临时文件路径(uni.chooseImage 返回)
diff --git a/hugray-user-miniapp/pages.json b/hugray-user-miniapp/pages.json
index a117e14..1d95863 100644
--- a/hugray-user-miniapp/pages.json
+++ b/hugray-user-miniapp/pages.json
@@ -58,6 +58,13 @@
 			}
 		},
 		{
+			"path": "pages/member/index",
+			// 顶部为深蓝会员卡 + 三段式 Tab,需自定义导航栏承载
+			"style": {
+				"navigationStyle": "custom"
+			}
+		},
+		{
 			"path": "pages/contact/index",
 			// 顶部为深蓝底品牌区,与白底原生导航冲突,故使用自定义导航栏
 			"style": {
diff --git a/hugray-user-miniapp/pages/member/index.vue b/hugray-user-miniapp/pages/member/index.vue
new file mode 100644
index 0000000..94b3b7d
--- /dev/null
+++ b/hugray-user-miniapp/pages/member/index.vue
@@ -0,0 +1,1394 @@
+<template>
+    <view class="page">
+        <!-- 自定义导航栏:状态栏留白由行内 paddingTop 撑开 -->
+        <view class="nav" :style="{ paddingTop: statusBarHeight + 'px' }">
+            <view class="nav-bar">
+                <view class="nav-back" @tap="handleBack">
+                    <view class="icon-back"></view>
+                </view>
+                <text class="nav-title">会员中心</text>
+            </view>
+        </view>
+
+        <scroll-view class="scroll" scroll-y>
+            <!-- 会员信息深蓝卡:脱敏手机号 + 当前等级 + 等级详情入口 -->
+            <view class="member-card">
+                <view class="member-left">
+                    <text class="member-phone">{{ memberPhone || '—' }}</text>
+                    <view class="member-level-line">
+                        <text class="member-level-label">当前等级</text>
+                        <text class="member-level-value">{{ memberLevel }}</text>
+                    </view>
+                </view>
+                <view class="level-detail-btn" @tap="handleLevelDetail">
+                    <text class="level-detail-text">等级详情</text>
+                </view>
+            </view>
+
+            <!-- 三段式 Tab:销售统计 / 我的仓库 / 进货订单 -->
+            <view class="tabs">
+                <view
+                    v-for="tab in TAB_LIST"
+                    :key="tab.key"
+                    class="tab-item"
+                    @tap="handleTabChange(tab.key)"
+                >
+                    <text class="tab-text" :class="{ 'tab-text--active': activeTab === tab.key }">
+                        {{ tab.label }}
+                    </text>
+                    <view v-if="activeTab === tab.key" class="tab-indicator"></view>
+                </view>
+            </view>
+
+            <!-- ==================== Tab1:销售统计 ==================== -->
+            <view v-if="activeTab === 'sales'" class="panel">
+                <!-- 当月数据汇总:三栏 + 利润环比 -->
+                <view class="stat-card">
+                    <view class="stat-head">
+                        <text class="stat-head-label">当月销售</text>
+                        <text class="stat-head-growth">{{ growthRateText }}</text>
+                    </view>
+                    <text class="stat-amount">¥{{ formatYuan(stats.monthSalesAmount, true) }}</text>
+                    <text class="stat-sub">当月利润 ¥{{ formatYuan(stats.monthProfitAmount, true) }}</text>
+                    <view class="stat-cols">
+                        <view class="stat-col">
+                            <text class="stat-col-label">当月销售额</text>
+                            <text class="stat-col-value">¥{{ formatYuan(stats.monthSalesAmount, true) }}</text>
+                        </view>
+                        <view class="stat-col">
+                            <text class="stat-col-label">当月进货额</text>
+                            <text class="stat-col-value">¥{{ formatYuan(stats.monthPurchaseAmount, true) }}</text>
+                        </view>
+                        <view class="stat-col">
+                            <text class="stat-col-label">销售单数</text>
+                            <text class="stat-col-value">{{ stats.monthSalesCount || 0 }}</text>
+                        </view>
+                    </view>
+                </view>
+
+                <!-- 销售额折线图(当月 1 号至当日) -->
+                <view class="chart-card">
+                    <text class="chart-title">销售额</text>
+                    <view class="chart-box">
+                        <qiun-data-charts
+                            v-if="hasTrend"
+                            type="line"
+                            :chartData="trendChartData"
+                            :opts="TREND_OPTS"
+                        />
+                        <view v-else class="chart-empty">
+                            <text class="chart-empty-text">暂无销售数据</text>
+                        </view>
+                    </view>
+                </view>
+
+                <!-- 商品销售额比例:环形图 + 图例 -->
+                <view class="chart-card">
+                    <text class="chart-title">商品销售额比例</text>
+                    <view v-if="ratioList.length > 0" class="ratio-wrap">
+                        <view class="ratio-chart">
+                            <qiun-data-charts type="ring" :chartData="ratioChartData" :opts="RATIO_OPTS" />
+                        </view>
+                        <view class="ratio-legend">
+                            <view
+                                v-for="(item, index) in ratioList"
+                                :key="item.productName"
+                                class="legend-row"
+                            >
+                                <view class="legend-dot" :style="{ backgroundColor: legendColor(index) }"></view>
+                                <text class="legend-name">{{ item.productName }}</text>
+                                <text class="legend-value">¥{{ formatYuan(item.amount, true) }}</text>
+                            </view>
+                        </view>
+                    </view>
+                    <view v-else class="chart-empty">
+                        <text class="chart-empty-text">暂无销售数据</text>
+                    </view>
+                </view>
+
+                <!-- 销售用户排行(Top 10) -->
+                <view class="chart-card">
+                    <text class="chart-title">销售用户排行</text>
+                    <view v-if="rankingList.length > 0" class="rank-list">
+                        <view v-for="item in rankingList" :key="item.rank" class="rank-row">
+                            <view class="rank-index">
+                                <text class="rank-index-text">{{ item.rank }}</text>
+                            </view>
+                            <text class="rank-name">{{ item.nickname || '会员' }}</text>
+                            <text class="rank-phone">{{ item.phone || '—' }}</text>
+                            <text class="rank-amount">¥{{ formatYuan(item.amount, true) }}</text>
+                        </view>
+                    </view>
+                    <view v-else class="chart-empty">
+                        <text class="chart-empty-text">暂无排行数据</text>
+                    </view>
+                </view>
+            </view>
+
+            <!-- ==================== Tab2:我的仓库 ==================== -->
+            <view v-else-if="activeTab === 'warehouse'" class="panel">
+                <view v-if="warehouseList.length > 0" class="warehouse-list">
+                    <view
+                        v-for="item in warehouseList"
+                        :key="item.warehouseId"
+                        class="warehouse-card"
+                    >
+                        <!-- 低库存警示条:低于最低需求库存时置顶展示 -->
+                        <view v-if="item.lowStock" class="low-stock-bar">
+                            <view class="low-stock-icon"></view>
+                            <text class="low-stock-bar-text">已低于最低需求库存,无法销售该商品,请及时补充</text>
+                        </view>
+                        <view class="warehouse-row">
+                            <!-- 商品图:后端暂未下发图片字段,回退占位图 -->
+                            <view class="product-thumb">
+                                <image
+                                    v-if="item.productImage"
+                                    class="product-thumb-img"
+                                    :src="item.productImage"
+                                    mode="aspectFill"
+                                />
+                                <view v-else class="icon icon-image"></view>
+                            </view>
+                            <view class="warehouse-main">
+                                <text class="product-name">{{ item.productName }}</text>
+                                <view class="warehouse-stock">
+                                    <text class="stock-label">当前库存:</text>
+                                    <text class="stock-value" :class="{ 'stock-value--low': item.lowStock }">
+                                        {{ item.stockQty }}
+                                    </text>
+                                    <text class="stock-label stock-label--gap">最低需求库存:</text>
+                                    <text class="stock-value">{{ item.minStockQty }}</text>
+                                </view>
+                                <view class="warehouse-actions">
+                                    <view class="btn-green" @tap="handleOpenPurchase(item)">
+                                        <text class="btn-green-text">进货</text>
+                                    </view>
+                                    <view class="btn-green" @tap="handleOpenRecords(item)">
+                                        <text class="btn-green-text">仓库记录</text>
+                                    </view>
+                                </view>
+                            </view>
+                        </view>
+                    </view>
+                </view>
+                <view v-else-if="!warehouseLoading" class="empty">
+                    <text class="empty-title">暂无云仓商品</text>
+                    <text class="empty-desc">开通云仓后可在此查看库存与进货</text>
+                </view>
+            </view>
+
+            <!-- ==================== Tab3:进货订单 ==================== -->
+            <view v-else class="panel">
+                <view v-if="orderList.length > 0" class="order-list">
+                    <view v-for="item in orderList" :key="item.orderId" class="order-card">
+                        <view class="order-head">
+                            <text class="order-no">单号:{{ item.orderNo }}</text>
+                            <text class="order-status">{{ item.statusName }}</text>
+                        </view>
+                        <text class="order-product">{{ item.productName }}</text>
+                        <view class="order-foot">
+                            <text class="order-qty">数量 ×{{ item.qty }}</text>
+                            <text class="order-amount">¥{{ formatYuan(item.totalAmount, true) }}</text>
+                        </view>
+                        <text class="order-time">{{ item.createTime }}</text>
+                    </view>
+                </view>
+                <view v-else-if="!orderLoading" class="empty">
+                    <text class="empty-title">暂无进货订单</text>
+                    <text class="empty-desc">在「我的仓库」进货后此处可查看</text>
+                </view>
+            </view>
+        </scroll-view>
+
+        <!-- ==================== 进货弹窗 ==================== -->
+        <view v-if="purchaseVisible" class="mask" @tap="closePurchase">
+            <view class="dialog" @tap.stop>
+                <text class="dialog-title">进货</text>
+                <text class="dialog-product">{{ purchaseTarget.productName }}</text>
+                <view class="form-row">
+                    <text class="form-label">进货数量</text>
+                    <input
+                        class="form-input"
+                        type="number"
+                        placeholder="请输入进货数量"
+                        placeholder-class="form-placeholder"
+                        v-model="purchaseQty"
+                    />
+                </view>
+                <view class="form-row">
+                    <text class="form-label">进货单价(元)</text>
+                    <input
+                        class="form-input"
+                        type="digit"
+                        placeholder="选填,默认 0"
+                        placeholder-class="form-placeholder"
+                        v-model="purchaseUnitPrice"
+                    />
+                </view>
+                <view class="dialog-actions">
+                    <view class="btn-plain" @tap="closePurchase">
+                        <text class="btn-plain-text">取消</text>
+                    </view>
+                    <view class="btn-green btn-green--fill" @tap="handleSubmitPurchase">
+                        <text class="btn-green-text">确认进货</text>
+                    </view>
+                </view>
+            </view>
+        </view>
+
+        <!-- ==================== 仓库记录弹窗 ==================== -->
+        <view v-if="recordsVisible" class="mask" @tap="closeRecords">
+            <view class="dialog dialog--records" @tap.stop>
+                <text class="dialog-title">仓库记录</text>
+                <text class="dialog-sub">{{ recordsProductName }}</text>
+                <scroll-view class="record-scroll" scroll-y>
+                    <view v-for="item in warehouseRecords" :key="item.recordId" class="record-row">
+                        <view class="record-line1">
+                            <text class="record-product">{{ item.productName }}</text>
+                            <text
+                                class="record-change"
+                                :class="item.changeQty < 0 ? 'record-change--out' : 'record-change--in'"
+                            >
+                                {{ item.changeQty > 0 ? '+' : '' }}{{ item.changeQty }}
+                            </text>
+                        </view>
+                        <view class="record-line2">
+                            <text class="record-type">{{ item.changeTypeName }}</text>
+                            <text class="record-after">结存 {{ item.afterQty }}</text>
+                            <text class="record-time">{{ item.createTime }}</text>
+                        </view>
+                    </view>
+                    <view v-if="warehouseRecords.length === 0" class="record-empty">
+                        <text class="record-empty-text">暂无记录</text>
+                    </view>
+                </scroll-view>
+                <view class="btn-green btn-green--fill" @tap="closeRecords">
+                    <text class="btn-green-text">关闭</text>
+                </view>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script setup>
+import { computed, ref } from 'vue'
+import { onLoad } from '@dcloudio/uni-app'
+import { ensureLogin } from '@/utils/request.js'
+import { formatYuan } from '@/utils/format.js'
+import {
+    getMemberSalesStatistics,
+    getMemberWarehouses,
+    memberPurchase,
+    getMemberWarehouseRecords,
+    getMemberPurchaseOrders
+} from '@/api/index.js'
+import qiunDataCharts from '@/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue'
+
+/** 状态栏高度:自定义导航栏下用于顶部留白 */
+const statusBarHeight = uni.getSystemInfoSync().statusBarHeight || 0
+
+/** 三段式 Tab 配置:key 仅前端切换用 */
+const TAB_LIST = [
+    { key: 'sales', label: '销售统计' },
+    { key: 'warehouse', label: '我的仓库' },
+    { key: 'orders', label: '进货订单' }
+]
+
+/** 图表/图例配色(与设计稿一致:蓝 / 青 / 草绿),按序循环使用 */
+const LEGEND_COLORS = ['#2F86E8', '#2FB5B8', '#7CC142']
+
+/** 折线图样式:隐藏图例、虚线网格、直线折线 */
+const TREND_OPTS = {
+    color: ['#1E5EBC'],
+    padding: [15, 10, 0, 5],
+    legend: { show: false },
+    // X 轴标签由 trendChartData 自行等间距抽稀,此处不再用 labelCount(避免 uCharts 强制补末尾标签造成相邻)
+    xAxis: { disableGrid: true, fontSize: 10, fontColor: '#94A3B8' },
+    yAxis: {
+        gridType: 'dash',
+        dashLength: 4,
+        splitNumber: 4,
+        gridColor: '#E2E8F0',
+        fontColor: '#94A3B8',
+        // axisLine:false 去掉左侧 Y 轴竖线,仅保留刻度文字
+        data: [{ min: 0, axisLine: false }]
+    },
+    extra: { line: { type: 'straight', width: 2, activeType: 'hollow' } }
+}
+
+/** 环形图样式:内部留空、不显示数据标签(图例由页面自绘) */
+const RATIO_OPTS = {
+    color: LEGEND_COLORS,
+    padding: [5, 5, 5, 5],
+    legend: { show: false },
+    dataLabel: false,
+    extra: { ring: { ringWidth: 36, activeOpacity: 0.5, activeRadius: 10 } }
+}
+
+/** 销售统计出参默认值:接口未返回时页面展示全零,避免 NaN */
+const DEFAULT_STATS = {
+    phone: '',
+    memberLevel: 'C',
+    monthSalesAmount: 0,
+    monthPurchaseAmount: 0,
+    monthProfitAmount: 0,
+    monthSalesCount: 0,
+    profitGrowthRate: 0,
+    salesTrend: [],
+    productSalesRatio: [],
+    salesUserRanking: []
+}
+
+/** 当前 Tab,默认「销售统计」 */
+const activeTab = ref('sales')
+
+/** 销售统计聚合数据 */
+const stats = ref({ ...DEFAULT_STATS })
+
+/** 会员脱敏手机号 */
+const memberPhone = computed(() => stats.value.phone)
+
+/** 会员等级:缺省兜底 C,与后端 MemberLevelEnum.normalize 保持一致 */
+const memberLevel = computed(() => stats.value.memberLevel || 'C')
+
+/** 商品销售额比例列表 */
+const ratioList = computed(() => stats.value.productSalesRatio || [])
+
+/** 销售用户排行列表 */
+const rankingList = computed(() => stats.value.salesUserRanking || [])
+
+/** 是否存在销售趋势数据(无数据时不渲染图表,改展示空态) */
+const hasTrend = computed(() => (stats.value.salesTrend || []).length > 0)
+
+/** 利润环比文案:正数为提升、负数为下降 */
+const growthRateText = computed(() => {
+    const rate = stats.value.profitGrowthRate || 0
+    return rate >= 0 ? `上月提升 ${rate}%` : `上月下降 ${Math.abs(rate)}%`
+})
+
+/** 折线图数据:分类为「N号」,金额由分转为元 */
+/** 折线图 X 轴最多显示的标签数 */
+const TREND_MAX_LABELS = 6
+
+const trendChartData = computed(() => {
+    const trend = stats.value.salesTrend || []
+    const total = trend.length
+    // 等间距抽稀:以最后一天为锚点向前按固定 step 取标签,保证间距一致且始终包含最新日期
+    const step = Math.max(1, Math.ceil((total - 1) / (TREND_MAX_LABELS - 1)))
+    return {
+        categories: trend.map((item, index) => ((total - 1 - index) % step === 0 ? item.day : '')),
+        series: [{ name: '销售额', data: trend.map((item) => Number(formatYuan(item.amount))) }]
+    }
+})
+
+/** 环形图数据:uCharts 单系列 data 数组承载各商品金额(元) */
+const ratioChartData = computed(() => ({
+    series: [
+        {
+            data: ratioList.value.map((item) => ({
+                name: item.productName,
+                value: Number(formatYuan(item.amount))
+            }))
+        }
+    ]
+}))
+
+/** 我的仓库列表 */
+const warehouseList = ref([])
+/** 我的仓库加载中标志 */
+const warehouseLoading = ref(false)
+
+/** 进货订单列表 */
+const orderList = ref([])
+/** 进货订单加载中标志 */
+const orderLoading = ref(false)
+
+/** 进货弹窗显隐 */
+const purchaseVisible = ref(false)
+/** 进货目标商品(含 warehouseId / productName) */
+const purchaseTarget = ref({})
+/** 进货数量输入值 */
+const purchaseQty = ref('')
+/** 进货单价输入值(元) */
+const purchaseUnitPrice = ref('')
+
+/** 仓库记录弹窗显隐 */
+const recordsVisible = ref(false)
+/** 仓库记录列表 */
+const warehouseRecords = ref([])
+/** 当前查看记录的商品名(弹窗副标题) */
+const recordsProductName = ref('')
+
+/** 图例色:按序循环取色,与环形图分段色保持一致 */
+const legendColor = (index) => LEGEND_COLORS[index % LEGEND_COLORS.length]
+
+/** 拉取销售统计(含手机号 / 等级 / 三栏金额 / 趋势 / 比例 / 排行) */
+const loadStatistics = async () => {
+    try {
+        const res = await getMemberSalesStatistics()
+        stats.value = { ...DEFAULT_STATS, ...(res.data || {}) }
+    } catch (error) {
+        console.error('[MEMBER] 获取销售统计失败', error)
+    }
+}
+
+/** 拉取云仓列表 */
+const loadWarehouses = async () => {
+    warehouseLoading.value = true
+    try {
+        const res = await getMemberWarehouses()
+        warehouseList.value = res.data || []
+    } catch (error) {
+        console.error('[MEMBER] 获取云仓列表失败', error)
+        warehouseList.value = []
+    } finally {
+        warehouseLoading.value = false
+    }
+}
+
+/** 拉取进货订单(分页接口,取前 20 条) */
+const loadOrders = async () => {
+    orderLoading.value = true
+    try {
+        const res = await getMemberPurchaseOrders({ pageNum: 1, pageSize: 20 })
+        // 分页接口返回 TableDataInfo:数据在顶层 rows(非 data 包裹)
+        orderList.value = res.rows || []
+    } catch (error) {
+        console.error('[MEMBER] 获取进货订单失败', error)
+        orderList.value = []
+    } finally {
+        orderLoading.value = false
+    }
+}
+
+/** Tab 切换:进入「我的仓库」「进货订单」时按需懒加载 */
+const handleTabChange = (key) => {
+    if (activeTab.value === key) return
+    activeTab.value = key
+    if (key === 'warehouse' && warehouseList.value.length === 0) {
+        loadWarehouses()
+    }
+    if (key === 'orders' && orderList.value.length === 0) {
+        loadOrders()
+    }
+}
+
+/** 打开进货弹窗:清空上一次输入 */
+const handleOpenPurchase = (item) => {
+    purchaseTarget.value = item
+    purchaseQty.value = ''
+    purchaseUnitPrice.value = ''
+    purchaseVisible.value = true
+}
+
+/** 关闭进货弹窗 */
+const closePurchase = () => {
+    purchaseVisible.value = false
+}
+
+/** 提交进货:校验数量后调用接口,成功后刷新云仓列表 */
+const handleSubmitPurchase = async () => {
+    const qty = Number(purchaseQty.value)
+    if (!Number.isInteger(qty) || qty <= 0) {
+        uni.showToast({ title: '请输入正确的进货数量', icon: 'none' })
+        return
+    }
+    // 单价选填:元 → 分,未填或非法则不传(后端按 0 计)
+    const unitPriceYuan = Number(purchaseUnitPrice.value)
+    const unitPrice =
+        Number.isFinite(unitPriceYuan) && unitPriceYuan > 0 ? Math.round(unitPriceYuan * 100) : undefined
+    try {
+        await memberPurchase({ warehouseId: purchaseTarget.value.warehouseId, qty, unitPrice })
+        uni.showToast({ title: '进货成功', icon: 'success' })
+        purchaseVisible.value = false
+        loadWarehouses()
+    } catch (error) {
+        console.error('[MEMBER] 进货失败', error)
+        uni.showToast({ title: error.message || '进货失败', icon: 'none' })
+    }
+}
+
+/** 打开仓库记录弹窗:拉取流水并按当前商品名筛选 */
+const handleOpenRecords = async (item) => {
+    recordsProductName.value = item.productName
+    warehouseRecords.value = []
+    recordsVisible.value = true
+    try {
+        const res = await getMemberWarehouseRecords({ pageNum: 1, pageSize: 50 })
+        const rows = res.rows || []
+        // 记录接口按会员维度下发,这里按商品名筛选,展示该商品的变动明细
+        warehouseRecords.value = rows.filter((record) => record.productName === item.productName)
+    } catch (error) {
+        console.error('[MEMBER] 获取仓库记录失败', error)
+    }
+}
+
+/** 关闭仓库记录弹窗 */
+const closeRecords = () => {
+    recordsVisible.value = false
+}
+
+/** 等级详情:后端暂未提供等级规则接口,先给出占位反馈 */
+const handleLevelDetail = () => {
+    uni.showToast({ title: '等级详情敬请期待', icon: 'none' })
+}
+
+/** 返回:优先返回上一页,无上一页时回个人中心(Tab 页) */
+const handleBack = () => {
+    const pages = getCurrentPages()
+    if (pages.length > 1) {
+        uni.navigateBack()
+        return
+    }
+    uni.switchTab({ url: '/pages/profile/index' })
+}
+
+/** 页面加载:校验登录态后拉取销售统计(仓库与订单按 Tab 懒加载) */
+onLoad(() => {
+    if (!ensureLogin()) return
+    loadStatistics()
+})
+</script>
+
+<style scoped lang="scss">
+.page {
+    height: 100vh;
+    display: flex;
+    flex-direction: column;
+    box-sizing: border-box;
+    background-color: #f8fafc;
+}
+
+/* ==================== 自定义导航栏 ==================== */
+
+.nav {
+    flex-shrink: 0;
+    background-color: #ffffff;
+}
+
+.nav-bar {
+    position: relative;
+    height: 88rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.nav-back {
+    position: absolute;
+    left: 16rpx;
+    top: 50%;
+    transform: translateY(-50%);
+    width: 64rpx;
+    height: 64rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+/* 纯 CSS 左向箭头:左 + 下边框旋转 45° */
+.icon-back {
+    width: 22rpx;
+    height: 22rpx;
+    border-left: 4rpx solid #0f172a;
+    border-bottom: 4rpx solid #0f172a;
+    transform: rotate(45deg);
+}
+
+.nav-title {
+    font-size: 34rpx;
+    font-weight: 700;
+    line-height: 1;
+    letter-spacing: 1rpx;
+    color: #0f172a;
+}
+
+.scroll {
+    flex: 1;
+    overflow: hidden;
+}
+
+/* ==================== 会员信息深蓝卡 ==================== */
+
+.member-card {
+    margin: 24rpx 32rpx 0;
+    padding: 40rpx 32rpx;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    box-sizing: border-box;
+    border-radius: 24rpx;
+    /* 深蓝渐变:与设计稿 #003E7E → #1E5EBC 一致 */
+    background: linear-gradient(135deg, #003e7e 0%, #1e5ebc 100%);
+    box-shadow: 0 12rpx 32rpx rgba(0, 62, 126, 0.24);
+}
+
+.member-left {
+    display: flex;
+    flex-direction: column;
+    gap: 20rpx;
+}
+
+.member-phone {
+    font-size: 28rpx;
+    line-height: 1;
+    letter-spacing: 1rpx;
+    color: rgba(255, 255, 255, 0.88);
+}
+
+.member-level-line {
+    display: flex;
+    align-items: baseline;
+    gap: 16rpx;
+}
+
+.member-level-label {
+    font-size: 28rpx;
+    font-weight: 500;
+    line-height: 1;
+    color: #ffffff;
+}
+
+.member-level-value {
+    font-size: 56rpx;
+    font-weight: 800;
+    line-height: 1;
+    letter-spacing: 2rpx;
+    color: #ffffff;
+}
+
+/* 草绿主按钮:等级详情 */
+.level-detail-btn {
+    flex-shrink: 0;
+    height: 64rpx;
+    display: flex;
+    align-items: center;
+    padding: 0 30rpx;
+    box-sizing: border-box;
+    border-radius: 12rpx;
+    background: linear-gradient(135deg, #82c236 0%, #639c1f 100%);
+    box-shadow: 0 6rpx 16rpx rgba(99, 156, 31, 0.32);
+}
+
+.level-detail-text {
+    font-size: 26rpx;
+    font-weight: 600;
+    line-height: 1;
+    color: #ffffff;
+}
+
+/* ==================== 三段式 Tab ==================== */
+
+.tabs {
+    margin-top: 24rpx;
+    display: flex;
+    align-items: center;
+    background-color: #ffffff;
+    border-bottom: 2rpx solid #e2e8f0;
+}
+
+.tab-item {
+    flex: 1;
+    height: 88rpx;
+    position: relative;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.tab-text {
+    font-size: 30rpx;
+    line-height: 1;
+    color: #64748b;
+}
+
+.tab-text--active {
+    font-weight: 600;
+    color: #639c1f;
+}
+
+/* 选中态底部指示条(草绿) */
+.tab-indicator {
+    position: absolute;
+    bottom: 0;
+    left: 50%;
+    transform: translateX(-50%);
+    width: 96rpx;
+    height: 6rpx;
+    border-radius: 6rpx;
+    background-color: #82c236;
+}
+
+.panel {
+    padding: 24rpx 32rpx 60rpx;
+    display: flex;
+    flex-direction: column;
+    gap: 24rpx;
+}
+
+/* ==================== 通用卡片 ==================== */
+
+.stat-card,
+.chart-card {
+    padding: 28rpx;
+    box-sizing: border-box;
+    border-radius: 20rpx;
+    background-color: #ffffff;
+    border: 2rpx solid #e2e8f0;
+    box-shadow: 0 6rpx 16rpx rgba(15, 23, 42, 0.05);
+}
+
+/* ==================== Tab1:销售统计 ==================== */
+
+.stat-head {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+}
+
+.stat-head-label {
+    font-size: 26rpx;
+    line-height: 1;
+    color: #64748b;
+}
+
+.stat-head-growth {
+    font-size: 24rpx;
+    line-height: 1;
+    color: #e11d48;
+}
+
+.stat-amount {
+    display: block;
+    margin-top: 20rpx;
+    font-size: 52rpx;
+    font-weight: 800;
+    line-height: 1;
+    color: #0f172a;
+}
+
+.stat-sub {
+    display: block;
+    margin-top: 14rpx;
+    font-size: 24rpx;
+    line-height: 1;
+    color: #94a3b8;
+}
+
+.stat-cols {
+    margin-top: 28rpx;
+    padding-top: 28rpx;
+    display: flex;
+    align-items: center;
+    border-top: 2rpx solid #f1f5f9;
+}
+
+.stat-col {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    gap: 12rpx;
+}
+
+.stat-col-label {
+    font-size: 24rpx;
+    line-height: 1;
+    color: #64748b;
+}
+
+.stat-col-value {
+    font-size: 30rpx;
+    font-weight: 700;
+    line-height: 1;
+    color: #0f172a;
+}
+
+.chart-title {
+    display: block;
+    font-size: 28rpx;
+    font-weight: 600;
+    line-height: 1;
+    color: #0f172a;
+    text-align: center;
+}
+
+.chart-box {
+    margin-top: 20rpx;
+    height: 400rpx;
+}
+
+/* 图表空态 */
+.chart-empty {
+    margin-top: 20rpx;
+    height: 200rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.chart-empty-text {
+    font-size: 26rpx;
+    line-height: 1;
+    color: #94a3b8;
+}
+
+/* 环形图 + 图例:左图右文 */
+.ratio-wrap {
+    margin-top: 20rpx;
+    display: flex;
+    align-items: center;
+}
+
+.ratio-chart {
+    width: 260rpx;
+    height: 260rpx;
+    flex-shrink: 0;
+}
+
+.ratio-legend {
+    flex: 1;
+    min-width: 0;
+    display: flex;
+    flex-direction: column;
+    gap: 20rpx;
+}
+
+.legend-row {
+    display: flex;
+    align-items: center;
+    gap: 12rpx;
+}
+
+.legend-dot {
+    flex-shrink: 0;
+    width: 16rpx;
+    height: 16rpx;
+    border-radius: 4rpx;
+}
+
+.legend-name {
+    flex: 1;
+    min-width: 0;
+    font-size: 24rpx;
+    line-height: 1;
+    color: #475569;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+}
+
+.legend-value {
+    flex-shrink: 0;
+    font-size: 24rpx;
+    font-weight: 600;
+    line-height: 1;
+    color: #0f172a;
+}
+
+/* 销售用户排行 */
+.rank-list {
+    margin-top: 12rpx;
+    display: flex;
+    flex-direction: column;
+}
+
+.rank-row {
+    height: 92rpx;
+    display: flex;
+    align-items: center;
+    gap: 20rpx;
+    border-bottom: 2rpx solid #f1f5f9;
+}
+
+.rank-row:last-child {
+    border-bottom: none;
+}
+
+.rank-index {
+    flex-shrink: 0;
+    width: 44rpx;
+    height: 44rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    border-radius: 50%;
+    background-color: #e8f1fc;
+}
+
+.rank-index-text {
+    font-size: 24rpx;
+    font-weight: 700;
+    line-height: 1;
+    color: #1e5ebc;
+}
+
+.rank-name {
+    flex-shrink: 0;
+    max-width: 160rpx;
+    font-size: 28rpx;
+    font-weight: 500;
+    line-height: 1;
+    color: #0f172a;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+}
+
+.rank-phone {
+    flex: 1;
+    min-width: 0;
+    font-size: 26rpx;
+    line-height: 1;
+    color: #94a3b8;
+}
+
+.rank-amount {
+    flex-shrink: 0;
+    font-size: 28rpx;
+    font-weight: 600;
+    line-height: 1;
+    color: #0f172a;
+}
+
+/* ==================== Tab2:我的仓库 ==================== */
+
+.warehouse-list {
+    display: flex;
+    flex-direction: column;
+    gap: 24rpx;
+}
+
+.warehouse-card {
+    border-radius: 20rpx;
+    overflow: hidden;
+    background-color: #ffffff;
+    border: 2rpx solid #e2e8f0;
+    box-shadow: 0 6rpx 16rpx rgba(15, 23, 42, 0.05);
+}
+
+/* 低库存警示条:蓝底白字 */
+.low-stock-bar {
+    display: flex;
+    align-items: center;
+    gap: 12rpx;
+    padding: 18rpx 24rpx;
+    background-color: #2f86e8;
+}
+
+.low-stock-icon {
+    flex-shrink: 0;
+    width: 32rpx;
+    height: 32rpx;
+    border-radius: 50%;
+    border: 3rpx solid #ffffff;
+    box-sizing: border-box;
+}
+
+.low-stock-bar-text {
+    flex: 1;
+    font-size: 24rpx;
+    line-height: 1.3;
+    color: #ffffff;
+}
+
+.warehouse-row {
+    padding: 24rpx;
+    display: flex;
+    align-items: flex-start;
+    gap: 24rpx;
+}
+
+/* 商品图占位(#F1F5F9 底 + 图片图标) */
+.product-thumb {
+    flex-shrink: 0;
+    width: 160rpx;
+    height: 160rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    border-radius: 12rpx;
+    overflow: hidden;
+    background-color: #f1f5f9;
+}
+
+.product-thumb-img {
+    width: 100%;
+    height: 100%;
+}
+
+.warehouse-main {
+    flex: 1;
+    min-width: 0;
+    display: flex;
+    flex-direction: column;
+    gap: 16rpx;
+}
+
+.product-name {
+    font-size: 28rpx;
+    font-weight: 600;
+    line-height: 1.35;
+    color: #0f172a;
+}
+
+.warehouse-stock {
+    display: flex;
+    align-items: center;
+    flex-wrap: wrap;
+}
+
+.stock-label {
+    font-size: 24rpx;
+    line-height: 1;
+    color: #64748b;
+}
+
+.stock-label--gap {
+    margin-left: 24rpx;
+}
+
+.stock-value {
+    margin-left: 6rpx;
+    font-size: 26rpx;
+    font-weight: 600;
+    line-height: 1;
+    color: #0f172a;
+}
+
+/* 低库存数值标红 */
+.stock-value--low {
+    color: #ef4444;
+}
+
+.warehouse-actions {
+    display: flex;
+    align-items: center;
+    gap: 20rpx;
+}
+
+/* 草绿按钮:进货 / 仓库记录 */
+.btn-green {
+    height: 64rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    padding: 0 36rpx;
+    box-sizing: border-box;
+    border-radius: 10rpx;
+    background: linear-gradient(135deg, #82c236 0%, #639c1f 100%);
+    box-shadow: 0 6rpx 16rpx rgba(99, 156, 31, 0.26);
+}
+
+.btn-green--fill {
+    flex: 1;
+}
+
+.btn-green-text {
+    font-size: 26rpx;
+    font-weight: 600;
+    line-height: 1;
+    color: #ffffff;
+}
+
+/* ==================== Tab3:进货订单 ==================== */
+
+.order-list {
+    display: flex;
+    flex-direction: column;
+    gap: 24rpx;
+}
+
+.order-card {
+    padding: 28rpx;
+    display: flex;
+    flex-direction: column;
+    gap: 16rpx;
+    border-radius: 20rpx;
+    background-color: #ffffff;
+    border: 2rpx solid #e2e8f0;
+    box-shadow: 0 6rpx 16rpx rgba(15, 23, 42, 0.05);
+}
+
+.order-head {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+}
+
+.order-no {
+    font-size: 24rpx;
+    line-height: 1;
+    color: #94a3b8;
+}
+
+.order-status {
+    font-size: 24rpx;
+    font-weight: 600;
+    line-height: 1;
+    color: #639c1f;
+}
+
+.order-product {
+    font-size: 28rpx;
+    font-weight: 600;
+    line-height: 1.35;
+    color: #0f172a;
+}
+
+.order-foot {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+}
+
+.order-qty {
+    font-size: 26rpx;
+    line-height: 1;
+    color: #64748b;
+}
+
+.order-amount {
+    font-size: 32rpx;
+    font-weight: 700;
+    line-height: 1;
+    color: #0f172a;
+}
+
+.order-time {
+    font-size: 22rpx;
+    line-height: 1;
+    color: #cbd5e1;
+}
+
+/* ==================== 空态 ==================== */
+
+.empty {
+    padding: 140rpx 0 0;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    gap: 16rpx;
+}
+
+.empty-title {
+    font-size: 30rpx;
+    font-weight: 600;
+    line-height: 1;
+    color: #475569;
+}
+
+.empty-desc {
+    font-size: 26rpx;
+    line-height: 1;
+    color: #94a3b8;
+}
+
+/* ==================== 弹窗(进货 / 仓库记录) ==================== */
+
+.mask {
+    position: fixed;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 100;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    padding: 0 60rpx;
+    box-sizing: border-box;
+    background-color: rgba(15, 23, 42, 0.45);
+}
+
+.dialog {
+    width: 100%;
+    padding: 40rpx 32rpx;
+    box-sizing: border-box;
+    border-radius: 24rpx;
+    background-color: #ffffff;
+    display: flex;
+    flex-direction: column;
+    gap: 24rpx;
+}
+
+.dialog-title {
+    font-size: 34rpx;
+    font-weight: 700;
+    line-height: 1;
+    color: #0f172a;
+    text-align: center;
+}
+
+.dialog-product {
+    font-size: 26rpx;
+    line-height: 1.3;
+    color: #64748b;
+    text-align: center;
+}
+
+.dialog-sub {
+    font-size: 24rpx;
+    line-height: 1;
+    color: #94a3b8;
+    text-align: center;
+}
+
+.form-row {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    gap: 24rpx;
+    height: 88rpx;
+    padding: 0 24rpx;
+    box-sizing: border-box;
+    border-radius: 12rpx;
+    background-color: #f8fafc;
+}
+
+.form-label {
+    flex-shrink: 0;
+    font-size: 28rpx;
+    line-height: 1;
+    color: #334155;
+}
+
+.form-input {
+    flex: 1;
+    height: 88rpx;
+    font-size: 28rpx;
+    line-height: 88rpx;
+    text-align: right;
+    color: #0f172a;
+}
+
+.form-placeholder {
+    color: #cbd5e1;
+}
+
+.dialog-actions {
+    margin-top: 8rpx;
+    display: flex;
+    align-items: center;
+    gap: 24rpx;
+}
+
+.btn-plain {
+    flex: 1;
+    height: 88rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    box-sizing: border-box;
+    border-radius: 44rpx;
+    background-color: #f1f5f9;
+}
+
+.btn-plain-text {
+    font-size: 28rpx;
+    font-weight: 600;
+    line-height: 1;
+    color: #475569;
+}
+
+/* 弹窗内草绿按钮:撑满、圆角胶囊 */
+.dialog-actions .btn-green,
+.dialog .btn-green--fill {
+    height: 88rpx;
+    border-radius: 44rpx;
+}
+
+/* 仓库记录弹窗:列表可滚动 */
+.dialog--records {
+    max-height: 76vh;
+}
+
+.record-scroll {
+    max-height: 640rpx;
+}
+
+.record-row {
+    padding: 20rpx 0;
+    display: flex;
+    flex-direction: column;
+    gap: 12rpx;
+    border-bottom: 2rpx solid #f1f5f9;
+}
+
+.record-line1,
+.record-line2 {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    gap: 16rpx;
+}
+
+.record-product {
+    flex: 1;
+    min-width: 0;
+    font-size: 26rpx;
+    font-weight: 600;
+    line-height: 1;
+    color: #0f172a;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+}
+
+.record-change {
+    flex-shrink: 0;
+    font-size: 28rpx;
+    font-weight: 700;
+    line-height: 1;
+}
+
+.record-change--in {
+    color: #639c1f;
+}
+
+.record-change--out {
+    color: #ef4444;
+}
+
+.record-type {
+    font-size: 24rpx;
+    line-height: 1;
+    color: #64748b;
+}
+
+.record-after,
+.record-time {
+    font-size: 22rpx;
+    line-height: 1;
+    color: #94a3b8;
+}
+
+.record-empty {
+    padding: 60rpx 0;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.record-empty-text {
+    font-size: 26rpx;
+    line-height: 1;
+    color: #94a3b8;
+}
+
+/* ==================== 图标(内联 base64 SVG) ==================== */
+
+.icon {
+    flex-shrink: 0;
+    background-repeat: no-repeat;
+    background-position: center center;
+    background-size: 100% 100%;
+}
+
+/* 商品图占位图标(#CBD5E1) */
+.icon-image {
+    width: 64rpx;
+    height: 64rpx;
+    background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjQ0JENUUxIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHJlY3Qgd2lkdGg9IjE4IiBoZWlnaHQ9IjE4IiB4PSIzIiB5PSIzIiByeD0iMiIgcnk9IjIiLz48Y2lyY2xlIGN4PSI5IiBjeT0iOSIgcj0iMiIvPjxwYXRoIGQ9Im0yMSAxNS0zLjA4Ni0zLjA4NmEyIDIgMCAwIDAtMi44MjggMEw2IDIxIi8+PC9zdmc+');
+}
+</style>
diff --git a/hugray-user-miniapp/pages/profile/index.vue b/hugray-user-miniapp/pages/profile/index.vue
index d41373d..0e26faf 100644
--- a/hugray-user-miniapp/pages/profile/index.vue
+++ b/hugray-user-miniapp/pages/profile/index.vue
@@ -169,6 +169,11 @@
         uni.navigateTo({ url: '/pages/profile/invite' })
         return
     }
+    // 会员中心:跳转会员中心页(销售统计 / 我的仓库 / 进货订单)
+    if (menu.key === 'member') {
+        uni.navigateTo({ url: '/pages/member/index' })
+        return
+    }
     uni.showToast({ title: '敬请期待', icon: 'none' })
 }
 

--
Gitblit v1.7.1