# Minecraft_Shop

Minecraft_Shop 是一个基于 Paper 1.21.1 的 Minecraft 服务器商业系统雏形。当前阶段已经完成了游戏内插件、数据库业务表、若依后台基础页面、登录注册、Firebase 邮箱验证、玩家冻结门禁、金币/点券、开店申请、商户领地/商铺/仓库/库存上架和购买等基础链路。

后续计划会从单一商城插件扩展为更完整的 Minecraft 服务器管理系统。当前已经下载 RuoYi-Vue，后续后台和网站应逐步迁移到若依框架。

## 当前状态

- Minecraft 服务端：Paper 1.21.1
- 插件：MineShopLite
- Java 规范：Java 21
- 数据库：使用项目内便携 MySQL `minecraft_shop`，后续由若依后台管理
- 缓存：使用项目内便携 Redis，供若依登录令牌、验证码和缓存使用
- 正式网页服务：若依前端，端口 `http://localhost:8081`
- 若依后台：已接入玩家、商品、订单、开店申请审核、领地、商铺、仓库、库存和物流监控等基础页面
- 插件内置网页：默认关闭，仅保留为历史过渡代码
- Firebase：默认开启，用于邮箱注册和邮箱验证
- 游戏内登录门禁：未注册/未登录玩家不能移动、转视角、交互、破坏、放置、打开背包操作或执行普通命令
- 当前可演示商户链路：玩家花费 100 点券申请领地并由系统自动建立 -> 地主花费 500 金币申请成为商户 -> 若依后台 24 小时内通过或拒绝，超时自动通过 -> 玩家获得商铺拥有者权限 -> 创建虚拟商铺 -> 每个领地区块可绑定虚拟或实体仓库节点 -> 仓库记录实际库存 -> 在 GUI 中按实际库存上限设置价格和数量后上架商品 -> 其他玩家直接购买并选择收货仓库/中转站，或发布订购单等待商户自动成交
- 当前可演示物流链路：玩家市场购买会从商户仓库扣货，按照自动最短中转站路径生成物流任务；系统商城仍直接发放到玩家背包。物流支持慢速/标准/快速三档速度和按物品数量、距离计算的两位小数运费；等待时间写入数据库真实时间戳，后台每 10 秒检查到达或超时。

## 快速启动

解压项目后，双击根目录的：

```bat
scripts\start.bat
```

它会先停止当前项目已经启动的旧进程，然后自动补全并启动项目内便携 Maven、MySQL、Redis、Node.js、Paper 1.21.1、若依后端、若依前端和 Minecraft 测试服。若依后端会先完成构建和健康检查，`http://localhost:8080/site/summary` 返回正常后才会继续启动前端，避免前端过早打开时报“系统接口请求超时”。

`scripts\start.bat` 默认使用增量构建：只有插件源码、若依后端源码或相关 `pom.xml` 比已有 jar 更新时，才会重新执行 Maven 打包。需要强制重新构建所有后端产物时，可以双击：

```bat
scripts\rebuild.bat
```

也可以在命令行运行：

```bat
scripts\start.bat rebuild
```

停止所有由项目拉起的服务，双击根目录的：

```bat
scripts\stop.bat
```

`scripts\stop.bat` 会关闭 MySQL、Redis、若依后端、若依前端、Paper 服务端，以及一键启动拉起的后台 PowerShell / cmd 进程。

新机器首次使用时不需要单独运行初始化脚本，`scripts\start.bat` 会自动执行：

- 下载便携 Maven、MySQL、Redis、Node.js 到 `tools/`
- 下载 `paper-server/paper-1.21.1.jar`
- 初始化 `tools/mysql-data`
- 导入若依基础 SQL、Quartz SQL、Minecraft 商城业务 SQL 和若依商城后台菜单 SQL
- 构建并部署 `MineShopLite.jar`

如果下载 GitHub、Node.js、MySQL、Paper 或访问 Firebase 较慢，启动脚本会在未手动设置代理时自动检测 `http://127.0.0.1:7897`。也可以在 PowerShell 中先手动指定代理再启动，手动设置会优先生效：

```powershell
$env:HTTP_PROXY="http://127.0.0.1:7897"
$env:HTTPS_PROXY="http://127.0.0.1:7897"
$env:MINECRAFT_SHOP_PROXY="http://127.0.0.1:7897"
.\scripts\start.bat
```

Paper 服务端 jar 文件为：

```text
paper-server/paper-1.21.1.jar
```

该文件较大，协作时通常不要提交到 Git。如果缺失，`scripts\start.bat` 会通过 `scripts/setup-paper-server.ps1` 自动下载 Paper `1.21.1 build 133`。

启动要求：

- 本机需要安装 Java 21 或更高版本
- `java` 最好已经加入系统 `PATH`
- Firebase 开启时，服务器需要能访问 `identitytoolkit.googleapis.com`

进入服务器后，玩家必须先完成注册和登录：

```text
/register <密码> <确认密码> <邮箱> <确认邮箱>
/login <密码>
```

Firebase 开启时，注册会发送邮箱验证邮件。邮件验证有效期为 10 分钟，过期未验证需要重新输入邮箱注册。邮箱验证完成后，`/login <密码>` 才会放行玩家。

## 目录说明

```text
Minecraft_Shop/
├─ src/                         插件源码
├─ sql/                         当前数据库初始化 SQL
├─ paper-server/              可直接运行的 Paper 1.21.1 测试服务器
├─ frameworks/RuoYi-Vue/        若依前后端分离框架源码
├─ docs/                        设计文档和代码细节说明
├─ dist/                        打包后的协作压缩包
├─ scripts/                     启动、停止、下载、初始化和构建脚本
├─ pom.xml                      Maven 构建配置
├─ 分工以及具体开发语言、程序.md  原始需求/分工说明文档
└─ README.md                    当前协作文档
```

当前协作时主要看这些目录：

- `src/main/java/com/mineshop/lite`
- `src/main/resources`
- `paper-server/plugins/MineShopLite`
- `sql`
- `frameworks/RuoYi-Vue`
- `tools/mysql-8.0.46-winx64`
- `tools/redis-5.0.14.1`

这些目录/文件属于历史参考、开发工具或生成产物，通常不要作为当前功能入口：

- `shopping_app_extracted`
- `shopping_app（包含工程文件、数据库）.zip`
- `mineshop_web`
- `target`
- `.git`

## 插件源码结构

```text
src/main/java/com/mineshop/lite/
├─ MineShopLitePlugin.java      插件入口，初始化数据库、网页服务、GUI、命令和监听器
├─ auth/                        登录注册、Firebase、未登录玩家门禁
├─ command/                     游戏内命令
├─ database/                    数据库连接、建表、角色权限、购买逻辑
├─ gui/                         游戏内商店 GUI
├─ hud/                         右侧玩家信息显示
├─ model/                       数据模型
└─ web/                         历史过渡网页代码，默认不启动
```

核心类：

- `MineShopLitePlugin`：插件主入口。
- `MineShopDatabase`：数据库建表、默认数据、金币点券、商品、订单、角色权限、商户领地/商铺/仓库/库存逻辑。
- `AuthGateListener`：未登录玩家冻结与命令限制。
- `FirebaseAuthService`：通过 Firebase Auth REST API 进行邮箱注册、发送验证邮件、登录验证。
- `WebServerService`：历史过渡网页服务，当前默认关闭。
- `ShopGui`：游戏内 `/shop` 商店 GUI。
- `PlayerHudService`：游戏右侧信息面板。

## 数据库

当前目标配置使用项目内便携 MySQL：

```yaml
database:
  type: mysql
  host: localhost
  port: 3306
  name: minecraft_shop
  username: root
  password: "123456"
```

若依数据源也指向同一个库：

```text
frameworks/RuoYi-Vue/ruoyi-admin/src/main/resources/application-druid.yml
```

业务 SQL：

```text
sql/shop_core.sql
sql/shop_admin_menu.sql
```

当前 `scripts/init-db.ps1` 初始化顺序：

1. `frameworks/RuoYi-Vue/sql/ruoyi_base_init.sql`
2. `frameworks/RuoYi-Vue/sql/quartz.sql`
3. `sql/shop_core.sql`
4. `sql/shop_admin_menu.sql`

当前不再保留旧版 `schema.sql`、`init_data.sql` 或一体化业务 SQL；数据库结构以 `sql/shop_core.sql` 为准，若依菜单以 `sql/shop_admin_menu.sql` 为准。

便携组件位置：

```text
tools/mysql-8.0.46-winx64
tools/mysql-data
tools/redis-5.0.14.1
tools/redis-data
```

当前数据库初始化后会包含若依基础表和 Minecraft 业务表。核心业务表包括：

```text
users
roles
permissions
user_roles
role_permissions
wallets
lands
land_quotas
land_members
land_chunks
shops
products
warehouses
warehouse_managers
warehouse_stocks
merchant_applications
orders
buy_orders
pending_deliveries
logistics_shipments
transfer_stations
transfer_station_items
daily_purchase_limits
audit_logs
system_settings
```

历史 H2 文件只作为开发期数据，不再作为后续后台系统的目标数据库。

## 已实现功能

### 登录注册

- `/register <密码> <确认密码> <邮箱> <确认邮箱>`
- `/login <密码>`
- Firebase 邮箱验证默认开启
- 邮箱验证邮件 10 分钟内有效，过期未验证需要重新注册邮箱
- 注册成功不会自动登录
- 登录成功后状态保持一天
- 未登录玩家被冻结，只允许注册和登录命令

### 商店

- `/shop` 打开游戏内 GUI
- `/shop web` 发送网页商城链接
- `/shop status` 展示当前玩家自己的商户状态、领地、商铺、仓库、库存种类和上架数
- 网页链接携带一次性 token
- token 只用于换取 HttpOnly cookie，随后网页不再依赖 URL token

### 领地系统

- `/land claim <name>` 由普通玩家认领当前所在 Minecraft chunk；系统会扣除 100 点券，立即自动建立领地数据库记录，并授予 `LAND_OWNER`
- 领地边界按 chunk 坐标计算，X/Z 为当前 chunk 的 16x16 范围，Y 为 Minecraft 1.21.1 的 `-64..319`
- 单个玩家最多拥有 100 个 active 领地区块；创建领地时会锁定该玩家的 `land_quotas` 行，防止并发申请突破额度
- 领地按当前 chunk 写入 `land_chunks`，同一个世界同一个 chunk 只能有一个 active 领地；并发申请冲突时数据库唯一键会让后提交的事务回滚
- 中转站区块不是玩家领地。已有中转站的 chunk 不能再用 `/land claim` 申明为玩家领地，已有 active 玩家领地的 chunk 也不能创建中转站。
- 领地内默认只有领地拥有者、被授权成员和 `SERVER_OWNER` 可以破坏、放置、右键交互、打开容器或操作实体；领地拥有者可用 `/land trust <玩家>` 主动授权，用 `/land untrust <玩家>` 移除授权
- 若依后台 `Land Overview` 可视化 active/deleted 领地、世界、坐标边界、成员数和关联商铺/仓库数量
- 若依后台支持删除单个领地、批量删除领地、删除某个玩家全部 active 领地，也支持 restore 单个/批量/某玩家全部 deleted 领地；删除会暂时取消该 chunk 的 owner/member/trust 权限并冻结对应仓库节点，释放交互保护，但该 chunk 会保留为 deleted 状态，不能被任何玩家重新 claim，直到管理员 restore；restore 会恢复原 owner 和此前被 trust 的成员权限

### 开店审核和商铺

- `/merchant apply` 由地主提交成为商户的申请；没有有效领地时会自动写入拒绝记录并返回失败提示；提交申请会扣除 500 金币开店申请费
- 申请会写入 `merchant_applications`
- 若依后台可在 24 小时内通过或拒绝开店申请；超过 24 小时未审核且玩家仍有 active 领地时，系统自动通过
- 审核通过后同时授予 `SHOP_OWNER` 和 `MERCHANT`；当且仅当玩家同时拥有这两个 active 角色时，才是可以交易和上架的商户
- 后台冻结商户资格时只冻结 `SHOP_OWNER`，保留 `MERCHANT` 作为冻结标记；只有 `MERCHANT` 表示该玩家不能交易、不能上架、不能重新申请商户，只能由管理员 restore
- 数据库 trigger 会保证玩家没有任何 active 领地时自动移除 `LAND_OWNER`；`SHOP_OWNER` 和 `MERCHANT` 只由商户审核或后台角色管理改变
- 已审核商户可使用 `/merchant shop <name>` 创建自己的唯一虚拟商铺或修改商铺展示名称，命令会返回商铺 ID；不带名称时返回已有店铺名称和 ID，没有店铺则报错
- 若依后台 `Shop Overview` 可查看虚拟商铺状态、所属玩家、领地/仓库节点数、商品数、商城上架库存和实际库存；有商户管理权限时可对商店执行 Delete/Restore。Delete 只冻结店主 `SHOP_OWNER`，保留 `MERCHANT` 防止玩家重新申请；Restore 补回 `SHOP_OWNER`

### 仓库和库存

- 仓库和商铺分离；玩家必须先拥有 active 领地区块才能拥有仓库，没有地就没有仓库。仓库分为虚拟仓库和实体箱子仓库，都绑定到领地区块
- 创建或重命名商铺时会复用该玩家 active 领地区块上已有的仓库节点；如果玩家在开店前已经绑定过实体箱子，开店后不会新建覆盖仓库，而是把原仓库挂到新商铺
- 虚拟仓库记录在 `warehouse_stocks` 中；实体仓库通过 `/warehouse tools binder` 和 `/warehouse tools unbinder` 绑定/解绑自己领地区块内的箱子，`/warehouse view` 只负责查看：先选择领地区块，再分页显示该区块的虚拟仓库和实体容器库存
- `/warehouse tools compass` 可获得 MineShop Compass。手持该指南针右键会打开 GUI 目标选择器，玩家可以搜索自己的仓库，或搜索当前所在 chunk 被普通中转站信号范围覆盖时可见的中转站；也可用 `/warehouse compass <关键词>` 直接打开搜索后的目标 GUI。搜索入口使用铁砧重命名栏，选择后指南针会指向该目标
- 玩家手持或查看原版已填充地图时，地图会标记同世界、当前地图范围内的 `[自己仓库]` 和 `[中转站]`
- `/merchant gui` 打开当前区块仓库节点 GUI；仓库页可分页查看虚拟/实体库存，点击玩家背包中的普通可堆叠物品可存入当前区块虚拟仓库，左键仓库物品可从虚拟仓库取出 1 个，Shift+左键取出一组；右键仓库物品会打开上架二级菜单，玩家在菜单中设置金币/点券单价和上架数量后确认，上架会先扣虚拟仓库，不足时再扣实体箱子里的普通可上架物品
- `/merchant shelf` 打开货架 GUI，用于查看 active 上架商品；在货架中右键商品会打开下架确认菜单，确认后下架返还时先写回当前区块虚拟仓库，再尝试写回实体箱子，仍然放不下的部分会直接返还到玩家背包，背包满则掉落在当前位置
- 手持物品直接入库和手持物品直接上架快捷路径已禁用，避免 Minecraft 物品读取异常导致 AIR 入库或上架；商户库存维护应通过仓库 GUI 背包点击入库、绑定箱子和货架 GUI 完成
- 商铺拥有者可用 `/merchant stock` 查看实际库存和可用库存，用 `/merchant shelf` 查看 active 上架商品并下架
- 商户上下架维护优先通过 `/merchant gui` 和 `/merchant shelf` 的 GUI 操作完成
- 若依后台 `Warehouse Overview` 可按领地区块查看商铺仓库节点、容量、实际库存、锁定库存、可用库存，并对照商品上架库存和差值
- 商户商品不会因为后台删除领地而下架或隐藏；市场查询和购买锁定只要求商户仍有 active 店铺且同时拥有 active `SHOP_OWNER` 和 `MERCHANT`。删除领地区块只冻结该区块对应的实际仓库库存，不直接改写商品状态

### 订单、订购和物流

- 订单表记录商品快照、买家、卖家商品来源、支付金额、订单状态、执行结果和失败原因
- 商户商品订单支持 `paid_not_shipped`、`shipped`、`completed` 等处理状态，商户只能处理自己商品产生的订单
- 商铺拥有者可用 `/merchant orders` 查看自己商品的最近订单，用 `/merchant ship <订单ID>` 发货，用 `/merchant complete <订单ID>` 完成订单
- 若依后台 `Order Admin` 可查看和处理订单，`Logistics Monitor` 可按订单、玩家、商品、公开/商铺商品和配送状态筛选
- 直接购买系统商城商品时不走物流，系统会直接发放到玩家背包，背包满则自然掉落
- 直接购买玩家市场商品时，买家在 `/shop` 的购买确认后选择收货仓库或可取货中转站；系统从商户仓库扣货，写入 `logistics_shipments`，到达后再写入目标仓库或中转站个人库存
- 物流速度分为三档，默认慢速 5 格/秒、标准 15 格/秒、快速 30 格/秒；速度和三档价格可在 `config.yml` 的 `logistics.*` 中设置。默认费用按 1/2/3 金币每 3200 格每件物品计算并向下取整到分，允许运费为 `0.00`
- 物流等待使用真实时间戳：待选速度物流写入 `choice_expires_at = 当前时间 + 5 分钟`，运输中物流写入 `available_at = 当前时间 + ETA 秒`；服务器重启后会按数据库时间继续处理已超时或已到达物流
- 玩家市场交易平台手续费为 3%，商户收到成交额的 97%
- 订购单记录在 `buy_orders`：买家在 `/shop` 的玩家市场中选择物品后，可切换到 Buy Orders 并创建订购单。订购单只使用金币，创建时先扣除订购金额作为托管资金
- 创建订购单时，系统会立即尝试匹配当前满足条件的商户在售单；商户之后上架同类商品时，如果上架单价不高于订购单出价，也会自动成交
- 订购单自动成交后，金额流向商户钱包，商品进入物流任务。买家在线时 5 分钟内可选择速度并支付运费；买家不在线或超时未选择时，系统默认慢速并从买家账户扣款，余额允许扣成负数
- 物流到达仓库前会再次检查目标仓库、领地和路线中转站是否仍为 active；如果目标领地/仓库被删除，或路线/目标中转站被取消，货物会原路退回发货仓库，物流单标记 `returned`，对应订单结束为 `returned`，并向买家提示退回原因。正常到达仓库后先写入虚拟库存，虚拟库存满时尝试写入绑定实体箱子，仍放不下的剩余数量会原路退回发货仓库
- 未完全成交的订购单保持 open，买家可在 `/shop -> My Buy Orders` 中查看并取消；取消时按系统规则退回未成交托管金额

### 中转站

- 服务器会为每个世界自动创建基础中转站 `BASE-<world>`，默认位于 `0,0` chunk，范围视为无限远。基础站只作为物流兜底网络，不作为玩家取货点，也不能绑定箱子、取消或放入玩家库存。
- 商户可购买自己的中转站：大型 `10240` 点券，覆盖半径 1024 chunk；中型 `2560` 点券，覆盖半径 128 chunk；小型 `640` 点券，覆盖半径 16 chunk。管理员创建不扣费。
- 中转站归属为开设者。物流费用按当前速度价格与距离计算边权；如果路线的第一个发出中转站是玩家中转站，该玩家获得该笔物流费的 100%；如果从基础/系统中转站发出，则物流费用归系统保留
- 中转站名称只允许自定义当前层级名称，最终显示名继承父级路径：大型为 `L-名称`，大型范围内的中型为 `M-大-中`，中型范围内的小型为 `S-大-中-小`；没有父级覆盖时只显示自身层级和名称。
- 中转站区块和玩家领地互斥：创建中转站时必须站在未被玩家领地占用的 chunk；玩家也不能把已有中转站 chunk 申明为领地。
- 物流寻路优先使用普通中转网络：小/中站在父级覆盖范围内连通，大型站之间可跨无限距离连通；没有普通路径时才通过基础中转站兜底。
- 中转站可绑定单个箱子或桶作为取货入口。绑定箱子不能是大箱子，已绑定的中转站箱子也不能再与旁边箱子合并。
- 中转站 chunk 内的普通方块按领地保护口径处理，只有 `SERVER_OWNER` 可以破坏、放置或任意交互；已绑定的中转站核心箱子不能被普通玩家破坏，但登录玩家可以右键打开取货，看到的是当前玩家自己的个人取货库存。到货后系统会提示玩家，物品超过 7 天未取会被系统回收。

### 货币

- 金币：`coins`
- 点券：`points`
- 普通商品、商户商品、订单和求购单的买卖单位都是金币
- 点券可以通过 `/points exchange <数量>` 单向置换为金币
- 金币不能置换为点券
- 玩家可用 `/coins` 查看自己的金币，用 `/points` 查看自己的点券
- 服主可修改玩家金币和点券

### 角色权限

当前已有角色：

- `PLAYER`
- `SHOP_OWNER`
- `MERCHANT`
- `LAND_OWNER`
- `WAREHOUSE_OWNER`
- `ADMIN_OWNER`
- `SERVER_OWNER`

普通玩家不拥有商品上架权限。普通玩家可以先花费 100 点券申请自己的领地，领地由系统自动建立，不需要后台审核；只有地主可以申请成为商户，申请时扣除 500 金币开店申请费。开店申请在后台通过，或超过 24 小时未审核时自动通过，玩家同时获得 `SHOP_OWNER` 和 `MERCHANT`，之后才能创建虚拟商铺和商品。`LAND_OWNER` 与 active 领地状态绑定：玩家失去最后一个 active 领地时，数据库触发器会移除 `LAND_OWNER`。`SHOP_OWNER` 和 `MERCHANT` 与玩家商户资格绑定，不会因为领地删除自动消失；只有 `MERCHANT` 而没有 `SHOP_OWNER` 表示商户资格被冻结，不能交易、不能上架、不能再次申请，只能由后台管理员恢复。仓库依赖领地而非商铺，虚拟仓库和实体箱子仓库都必须绑定领地区块。`SERVER_OWNER` 是唯一服主，可授予/撤销角色，并可像领地主一样交互任意领地和中转站；首个自动成为服主的玩家也会获得 `ADMIN_OWNER`。`ADMIN_OWNER` 可使用 `/owner status/info/coins/points` 和通用 `/coins`、`/points` 管理命令，但不能使用 `/owner role`，也不能绕过领地或中转站保护。

### 网页商城

正式网页入口迁移到若依前端：

```text
http://localhost:8081
```

插件内置网页服务已经默认关闭。游戏内 `/shop web` 继续生成带 token 的链接，但链接目标改为若依前端。若依后台当前已有商城管理页面；普通玩家网页商城和 token 自动登录仍需要继续实现。

### 若依后台

- 后端接口位于 `frameworks/RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/mineshop`
- 前端页面位于 `frameworks/RuoYi-Vue/ruoyi-ui/src/views/shop`
- 已有菜单和权限初始化：`sql/shop_admin_menu.sql`
- 后台定位是服主监管后台，不是普通玩家商城，也不是商户经营后台
- 已有页面：服主控制台、玩家列表、商品监管、订单列表、开店申请审核、领地总览、商铺总览、仓库总览、物流监控、中转站总览
- 后台可以处理高风险运营动作：唯一服主设置、钱包调整、角色授予/撤销、商户冻结/恢复、商品强制下架/恢复、异常物流处理、异常取货记录回收、中转站取消/恢复/标记异常、向玩家中转站库存放入测试物品
- 当前后台只审核开店申请，不审核商户自己上架的商品；商户商品库存由游戏内仓库、订单和物流链路维护，后台不直接改商户库存，只做状态监管和异常处理

### 若依模块说明

MineShop 在若依中使用一个独立的 `Shop Admin` 菜单组，菜单初始化 SQL 为 `sql/shop_admin_menu.sql`。后台模块只负责服主运营监管和可视化，不直接替代 Paper 插件里的游戏内 GUI 或命令；插件负责玩家进入服务器、登录注册、领地保护、商户 GUI、购买成交、仓库扣货和物流推进，若依负责后台页面、管理 API、权限校验和审计入口。

| 若依模块 | 前端页面 | 后端接口 | 权限码 | 功能 |
| --- | --- | --- | --- | --- |
| `Shop Admin` | 菜单组 | 无直接页面 | 无 | MineShop 后台根菜单，承载服主控制台、玩家、商品、订单、开店申请、领地、商铺、仓库、物流和中转站监管。 |
| `Owner Console` | `src/views/shop/owner/index.vue` | `/shop/admin/owner` | `shop:owner:panel`, `shop:owner:wallet`, `shop:owner:role` | 服主控制台：查看全局统计和玩家列表；按两位小数调整金币/点券；授予或撤销 MineShop 角色；设置 `SERVER_OWNER` 时会保持唯一服主。 |
| `Product Admin` | `src/views/shop/product/index.vue` | `/shop/admin/products` | `shop:product:list`, `shop:product:edit` | 商品监管：按商品名、公开/商户商品、卖家、货币、状态筛选；可强制下架/恢复异常商品。商户商品库存不能在后台直接修改，避免绕过仓库和物流链路。 |
| `Order Admin` | `src/views/shop/order/index.vue` | `/shop/admin/orders` | `shop:order:list`, `shop:order:ship` | 查看订单、筛选订单状态和来源；商户订单支持从待发货推进到已发货，再推进到已完成。 |
| `User Admin` | `src/views/shop/user/index.vue` | `/shop/admin/users` | `shop:user:list`, `shop:user:owner` | 查看 MineShop 用户、钱包、角色和商户相关统计；可设置唯一 `SERVER_OWNER`，也可冻结/恢复商户资格。冻结只撤销 `SHOP_OWNER`，保留 `MERCHANT` 作为冻结标记。 |
| `Merchant Applications` | `src/views/shop/merchant/index.vue` | `/shop/admin/merchants` | `shop:merchant:list`, `shop:merchant:audit` | 审核地主开店申请；管理员可通过或拒绝，超过 24 小时未审核且仍有 active 领地时自动通过。 |
| `Land Overview` | `src/views/shop/land/index.vue` | `/shop/admin/lands` | `shop:land:list`, `shop:land:delete` | 可视化领地所有者、世界、坐标边界、成员数、关联商铺/仓库数量；支持删除/恢复单个领地、批量删除/恢复领地、删除/恢复某玩家全部对应状态领地。 |
| `Shop Overview` | `src/views/shop/shop/index.vue` | `/shop/admin/shops` | `shop:shop:list`, `shop:user:owner` | 商店视图：查看玩家虚拟商铺、商户状态、仓库节点数、商品数和 Virtual Stock；有 `shop:user:owner` 权限时可 Delete/Restore 商户资格。 |
| `Warehouse Overview` | `src/views/shop/warehouse/index.vue` | `/shop/admin/warehouses` | `shop:warehouse:list` | 仓库视图：按领地区块查看仓库 ID、名称、商铺、拥有者、领地、世界、Virtual Stock、状态和创建时间。 |
| `Logistics Monitor` | `src/views/shop/logistics/index.vue` | `/shop/admin/logistics` | `shop:logistics:list`, `shop:logistics:manage` | 物流监管：查看订单物流、在途任务和 `pending_deliveries` 待领取记录；可退回未完成物流、标记异常物流、回收异常待领取记录。 |
| `Transfer Stations` | `src/views/shop/station/index.vue` | `/shop/admin/stations` | `shop:station:list`, `shop:station:manage` | 中转站监管：查看所有中转站、层级、半径、父级路径、绑定箱子、个人取货库存、在途数量和开设状态；可取消/恢复普通中转站、标记异常中转站、向指定玩家的站点库存放入测试物品。基础中转站不可取消，也不能作为玩家取货库存入口。 |

### 若依后台操作流程

启动完成后打开：

```text
http://localhost:8081/admin/login
```

默认后台账号：

```text
admin / admin123
```

登录后从左侧菜单进入 `Shop Admin`。推荐按下面顺序演示和操作：

| 操作目标 | 菜单路径 | 操作方式 | 结果 |
| --- | --- | --- | --- |
| 服主总览和高权限操作 | `Shop Admin -> Owner Console` | 查看统计卡片和玩家列表；选择玩家后调整金币/点券或授予/撤销角色。 | 钱包按 cents 存储，页面按两位小数显示；`SERVER_OWNER` 始终只保留一个，避免多个服主并存。 |
| 查看玩家、设置服主和冻结商户 | `Shop Admin -> User Admin` | 搜索玩家；在玩家行上使用服主开关、Freeze Merchant 或 Restore Merchant。 | 后台只保留一个 MineShop `SERVER_OWNER`。冻结商户会撤销 `SHOP_OWNER` 并冻结商铺和商户在售商品，但不改商户库存；恢复后重新允许交易。 |
| 审核开店申请 | `Shop Admin -> Merchant Applications` | 查看 `pending` 申请，点击通过或拒绝。 | 通过后玩家获得 `SHOP_OWNER` 和 `MERCHANT`；拒绝会记录审核备注。玩家没有 active 领地时系统会自动拒绝。 |
| 监管商品 | `Shop Admin -> Product Admin` | 按商品名、公开/商铺商品、卖家类型、货币、状态筛选；对异常商品执行 Remove 或 Restore。 | 商户商品库存不允许在后台直接编辑。Remove 会把商品置为 `admin_removed`，Restore 会根据剩余库存恢复为 `on_sale` 或 `sold_out`。 |
| 处理订单 | `Shop Admin -> Order Admin` | 按订单号、玩家、商品、状态或来源筛选；对商户订单点击 Ship 或 Complete。 | 商户订单状态从 `paid_not_shipped` 推进到 `shipped`，再推进到 `completed`；官方商品通常直接完成。 |
| 查看、删除和恢复领地 | `Shop Admin -> Land Overview` | 搜索领地、玩家、世界或状态；勾选多行批量删除/恢复，或在单行操作中处理；也可按玩家批量删除/恢复。 | 删除会释放游戏内交互保护、冻结对应仓库节点并阻止任何人重新 claim；restore 会恢复 owner 和原 trust 成员权限。删除领地不改变商户身份、商铺和商品状态；只要玩家仍有商户身份，其上架商品仍可展示和购买。 |
| 查看/冻结/恢复商铺 | `Shop Admin -> Shop Overview` | 按商铺名、玩家、领地或状态筛选；对 Active 商户点击 Delete，对 Frozen 商户点击 Restore。 | 商店视角对照每个商铺的 active 商品数、商城上架库存、实际库存和差值。Delete 只移除 `SHOP_OWNER`，保留 `MERCHANT`；Restore 补回 `SHOP_OWNER`。 |
| 查看仓库 | `Shop Admin -> Warehouse Overview` | 按仓库名、商铺、玩家或状态筛选。 | 仓库视角查看容量、实际库存、锁定库存、可用库存、上架库存和差值。 |
| 监控和处理物流 | `Shop Admin -> Logistics Monitor` | 在 Orders、Shipments 和 Pending deliveries 页签中筛选；对异常任务执行 Return、Mark abnormal 或 Recycle。 | Return 会把未完成物流退回原仓库；源仓库不可用时应改为异常处理。Recycle 会把长期异常待领取记录标记为系统回收。 |
| 管理中转站 | `Shop Admin -> Transfer Stations` | 按站点名、拥有者、世界、层级或状态筛选；对普通 active 中转站点击 Delete、Mark abnormal 或 Restore；也可以向指定玩家放入测试取货库存。 | 基础中转站只作为系统兜底网络，后台不可取消、不可标记异常、不可作为玩家取货入口。普通站恢复后会重新计算父级路径和自动显示名。 |
| 查看前台商城 | 顶部地址栏直接访问 `/market` | 打开 `http://localhost:8081/market`。 | 查看当前上架商品、价格、库存和材质图；材质由若依后端代理缓存，避免浏览器直接依赖外网材质站。 |

若依后台操作的是 MySQL 中的业务数据；Paper 插件会读取同一套数据库。因此后台审核、设置 Owner、封禁商户、强制下架商品、删除/恢复领地、处理物流异常等操作会影响游戏内权限、商城商品、领地保护、物流和中转站取货。领地保护缓存每 10 秒自动刷新一次，后台删除/恢复后最多约 10 秒反映到游戏内。反过来，玩家在游戏内注册、申请领地、申请开店、创建商铺、上架商品、购买、订购、物流到达后，也会在若依后台对应页面显示。

如果后台菜单缺失、权限按钮不可见或触发器未生效，优先确认 `scripts/start.bat` 已重新启动若依后端；后端启动脚本会同步导入 `sql/shop_admin_menu.sql` 和 `sql/shop_runtime_rules.sql`。重新生成本地数据库也可以运行 `scripts/cleanup.bat` 后再运行 `scripts/start.bat`，但这会清空本机业务数据。

若依前台商城页面位于 `frameworks/RuoYi-Vue/ruoyi-ui/src/views/site`：

| 前台页面 | 路由 | 功能 |
| --- | --- | --- |
| `Home.vue` | `/` | 服务器商城首页，展示站点概要和入口。 |
| `Market.vue` | `/market` | 展示上架商品、价格、库存和 Minecraft 材质图；材质由若依后端 `/site/textures/{material}` 代理并缓存。 |
| `Forum.vue` | `/forum` | 论坛/公告展示入口，当前作为前台扩展页面。 |

若依仍保留部分框架自带系统管理能力，例如用户、角色、菜单、字典、日志和监控。MineShop 业务页面集中放在 `src/views/shop` 和 `src/views/site`，后续新增后台功能也应优先放入这两个目录，而不是继续扩展插件内置网页。

## 常用命令

当前插件实际注册的命令来自 `src/main/resources/plugin.yml`。未注册到 `plugin.yml` 的旧命令类不视为可用命令。

### 认证命令

| 命令 | 使用者 | 功能 |
| --- | --- | --- |
| `/register <密码> <确认密码> <邮箱> <确认邮箱>` | 未注册玩家 | 注册本服 MineShop 账号。Firebase 邮箱验证开启时必须填写邮箱并在 10 分钟内完成验证。 |
| `/register <密码> <确认密码>` | 未注册玩家 | 在 Firebase 邮箱验证关闭时注册账号。 |
| `/login <密码>` | 已注册玩家 | 登录账号。未登录玩家会被门禁限制移动、交互、破坏、放置、打开背包和执行普通命令。 |

### 商城命令

| 命令 | 使用者 | 功能 |
| --- | --- | --- |
| `/shop` | 已登录玩家 | 打开游戏内商城 GUI。可进入系统商城、玩家市场、我的订购单；玩家市场支持查看在售单、查看/创建订购单、购买商户商品并选择收货仓库。 |
| `/shop web` | 已登录玩家 | 生成带一次性 token 的网页商城入口，目标为若依前端 `http://localhost:8081`。 |
| `/shop status` | 已登录玩家 | 查看当前玩家自己的商户审批/领地/商铺/仓库/库存种类/上架数等状态。 |
| `/shop logistics` | 已登录玩家 | 查看自己的待选速度物流和运输中物流；待选速度物流可点击选择慢速/标准/快速，运输中物流只展示状态和预计到达时间。 |

### 金币命令

| 命令 | 使用者 | 功能 |
| --- | --- | --- |
| `/coins` | 已登录玩家 | 查看自己的金币余额。 |
| `/coins get [玩家]` | 玩家 / 管理者 | 不带玩家名时查看自己的金币；有管理权限时可查看指定玩家金币。 |
| `/coins add <玩家> <数量>` | SERVER_OWNER / ADMIN_OWNER / 有权限管理者 | 给指定玩家增加金币。 |
| `/coins set <玩家> <数量>` | SERVER_OWNER / ADMIN_OWNER / 有权限管理者 | 将指定玩家金币设置为给定数量。 |

### 点券命令

| 命令 | 使用者 | 功能 |
| --- | --- | --- |
| `/points` | 已登录玩家 | 查看自己的点券余额。 |
| `/points get [玩家]` | 玩家 / 管理者 | 不带玩家名时查看自己的点券；有管理权限时可查看指定玩家点券。 |
| `/points exchange <数量>` | 已登录玩家 | 将自己的点券按 1:1 单向置换为金币，金额支持小数输入。 |
| `/points add <玩家> <数量>` | SERVER_OWNER / ADMIN_OWNER / 有权限管理者 | 给指定玩家增加点券。 |
| `/points set <玩家> <数量>` | SERVER_OWNER / ADMIN_OWNER / 有权限管理者 | 将指定玩家点券设置为给定数量。 |

### HUD 命令

| 命令 | 使用者 | 功能 |
| --- | --- | --- |
| `/hud refresh` | 已登录玩家 | 手动刷新游戏内“市场信息”侧边栏。 |
| `/hud hide` | 已登录玩家 | 隐藏游戏内“市场信息”侧边栏。 |
| `/hud show` | 已登录玩家 | 重新显示游戏内“市场信息”侧边栏。 |

### 领地命令

| 命令 | 使用者 | 功能 |
| --- | --- | --- |
| `/land claim <名称>` | 已登录玩家 | 花费 100 点券认领玩家当前所在 Minecraft chunk，系统自动写入 `lands`、`land_members`、`land_chunks`，并授予 `LAND_OWNER`。 |
| `/land trust <玩家>` | 领地拥有者 | 授权指定玩家使用自己的主领地，使其可以在领地内进行允许的交互。 |
| `/land untrust <玩家>` | 领地拥有者 | 移除指定玩家的领地使用权限。 |
| `/land members` | 领地拥有者 | 查看自己主领地的成员和角色。 |

领地边界按 chunk 坐标计算，X/Z 为当前 chunk 的 16x16 范围，Y 为 `-64..319`。单个玩家最多拥有 100 个 active 领地区块；同世界同 chunk 的 active 占用由 `land_chunks` 唯一键防冲突。

### 仓库命令

| 命令 | 使用者 | 功能 |
| --- | --- | --- |
| `/warehouse view` | 领地拥有者 | 打开只读仓库总览 GUI：先选择自己的领地区块，再查看该区块虚拟仓库和实体容器里的所有普通可堆叠物品。 |
| `/warehouse tools binder` | 领地拥有者 | 获取实体仓库绑定工具；手持右键自己领地区块内的单个箱子或桶即可绑定该区块实体仓库。 |
| `/warehouse tools unbinder` | 领地拥有者 | 获取实体仓库解绑工具；手持右键已绑定的实体仓库容器即可解绑。 |
| `/warehouse tools compass` | 领地拥有者 | 获取 MineShop Compass；手持右键打开 GUI 目标列表，选择自己的仓库或 active 中转站后指南针会指向该目标。 |
| `/warehouse compass <关键词>` | 已登录玩家 | 以给定关键词打开 MineShop Compass 目标 GUI；点击结果时需要手持 MineShop Compass。 |

MineShop Compass 的仓库目标不再按距离过滤，玩家可以搜索自己的已加载世界仓库；中转站目标复用购买时的可取货中转站搜索逻辑，只显示当前所在 chunk 被普通中转站信号范围覆盖时可见的站点。GUI 内的搜索入口使用铁砧重命名栏输入关键词，不再向聊天区刷列表。

### 中转站命令

| 命令 | 使用者 | 功能 |
| --- | --- | --- |
| `/station list` | 商户 / 中转站管理员 | 查看当前 active 中转站、层级、半径、所在 chunk 和绑定箱子坐标。 |
| `/station create <small|medium|large> [名称]` | 商户 / 中转站管理员 | 在当前未被领地占用的 chunk 创建中转站。商户按层级扣点券，管理员创建不扣费。 |
| `/station bind <中转站ID>` | 中转站拥有者 / 中转站管理员 | 看向 6 格内的单个箱子或桶，将其绑定为该中转站取货入口。 |
| `/station put <中转站ID> <玩家> <物品> <数量>` | 中转站管理员 | 测试接口：直接向指定玩家在指定中转站的个人库存放入物品。基础中转站不能放入玩家库存。 |
| `/station cancel <中转站ID>` | 中转站管理员 / 中转站拥有者 | 取消普通中转站。基础中转站不能取消。 |
| `/station restore <中转站ID>` | 中转站管理员 / 中转站拥有者 | 恢复 cancelled 普通中转站，并重新计算父级路径和自动显示名。基础中转站不需要恢复。 |

中转站 chunk 按领地保护同一口径处理：只有 `SERVER_OWNER` 可以破坏、放置或任意交互；核心箱子允许登录玩家右键打开取货，但仍不可被普通玩家破坏。`ADMIN_OWNER` 不会获得该绕过权限。

### 商户命令

| 命令 | 使用者 | 功能 |
| --- | --- | --- |
| `/merchant apply` | 地主 | 花费 500 金币提交商户申请并获得虚拟商铺资格审核。没有 active 领地时会自动拒绝；超过 24 小时未审核会自动通过。 |
| `/merchant status` | 已登录玩家 | 查看自己的商户状态、领地、商铺、仓库库存种类和 active 商品数。 |
| `/merchant shop [名称]` | 已审核商户 | 带名称时创建自己的唯一虚拟商铺或修改商铺展示名称并返回 ID；不带名称时返回已有名称和 ID，没有店铺则报错。 |
| `/merchant gui` | 已审核商户 | 站在自己的 active 领地区块内打开该区块仓库节点 GUI。仓库页可分页查看虚拟/实体库存；点击玩家背包中的普通可堆叠物品可存入当前区块虚拟仓库；左键从虚拟仓库取出 1 个、Shift+左键取出一组；右键库存物品打开上架二级菜单，可设置金币/点券单价和数量后确认。 |
| `/merchant shelf` | 已审核商户 | 打开货架 GUI，查看自己的 active 上架商品；右键商品打开下架确认菜单，确认后返还库存。 |
| `/merchant stock` | 已审核商户 | 查看自己商铺仓库的实际库存数量和可用数量。 |
| `/merchant orders` | 已审核商户 | 查看自己商品产生的最近 10 条订单，包括待发货、已发货、已完成状态。 |
| `/merchant ship <订单ID>` | 订单所属商户 | 将自己的待发货订单推进为已发货。只能处理自己商品产生的订单。 |
| `/merchant complete <订单ID>` | 订单所属商户 | 将自己的已发货订单推进为已完成。只能处理自己商品产生的订单。 |

商户上架只接受普通可堆叠物品；带自定义名称、lore、附魔、耐久损耗、自定义模型或持久化数据的物品不会被当作普通商品处理。

### 服主命令

| 命令 | 使用者 | 功能 |
| --- | --- | --- |
| `/owner status` | SERVER_OWNER / ADMIN_OWNER / 控制台权限入口 | 查看当前 MineShop 服主和管理员状态。 |
| `/owner info <玩家>` | SERVER_OWNER / ADMIN_OWNER / 控制台权限入口 | 查看指定玩家的账号、钱包和角色概要。 |
| `/owner coins add <玩家> <数量>` | SERVER_OWNER / ADMIN_OWNER / 控制台权限入口 | 给指定玩家增加金币。 |
| `/owner coins set <玩家> <数量>` | SERVER_OWNER / ADMIN_OWNER / 控制台权限入口 | 将指定玩家金币设置为给定数量。 |
| `/owner points add <玩家> <数量>` | SERVER_OWNER / ADMIN_OWNER / 控制台权限入口 | 给指定玩家增加点券。 |
| `/owner points set <玩家> <数量>` | SERVER_OWNER / ADMIN_OWNER / 控制台权限入口 | 将指定玩家点券设置为给定数量。 |
| `/owner role add <玩家> <角色>` | SERVER_OWNER / 控制台权限入口 | 给指定玩家授予角色，例如 `SHOP_OWNER`、`LAND_OWNER`、`ADMIN_OWNER`。 |
| `/owner role remove <玩家> <角色>` | SERVER_OWNER / 控制台权限入口 | 移除指定玩家的角色。 |

## 配置文件

源码默认配置：

```text
src/main/resources/config.yml
```

服务器实际运行配置：

```text
paper-server/plugins/MineShopLite/config.yml
```

关键配置：

```yaml
owner:
  name: Homeaster

web:
  enabled: false
  host: "127.0.0.1"
  port: 8088
  public_url: "http://localhost:8081"
  secure_cookies: false

auth:
  firebase:
    enabled: true
```

本地 HTTP 运行时 `secure_cookies` 保持 `false`。如果后续部署到 HTTPS 域名，应改为 `true`。

## 构建插件

项目使用 `tools/` 下的便携 Maven 构建：

```bat
tools\apache-maven-3.9.16\bin\mvn.cmd package
```

构建产物：

```text
target/MineShopLite.jar
```

如果要让测试服务器加载新插件，需要复制到：

```text
paper-server/plugins/MineShopLite.jar
```

当前服务器包里已经包含了最新插件。

## RuoYi 集成

若依源码位置：

```text
frameworks/RuoYi-Vue
```

集成设计文档：

```text
docs/design.md
docs/details.md
```

`docs/design.md` 描述业务角色、表结构和课程设计方案；`docs/details.md` 描述 Java、SQL、脚本和若依集成等代码层细节。后续管理后台应优先在若依中新增 Minecraft 模块，而不是继续扩展插件内置网页。插件负责游戏内逻辑和服务器通信，若依负责后台、网站、管理 API 和权限审计。

若依启动由一键脚本托管：

```bat
scripts\start.bat
```

默认启动会跳过未变化的 Maven 构建；`scripts\rebuild.bat` 会强制重新打包若依后端和插件。

若依默认后台账号：

```text
admin / admin123
```

`scripts/run-ruoyi-frontend.ps1` 会优先使用项目内便携 Node.js/npm；如果 `node_modules` 不存在，会自动执行 `npm install`。

前端执行生产构建时可能出现 `asset size limit` 或 `entrypoint size limit` 这类 bundle size warning。它表示打包后的部分 JS/CSS/图片超过 webpack 默认建议体积，例如 ElementUI、公共依赖包、登录背景图或后台页面代码较大。该提示不是构建失败，也不会影响 `scripts\start.bat` 启动或 `http://localhost:8081` 正常访问；当前课程设计和本地演示阶段可以忽略。后续如果要优化首次加载速度，再考虑图片压缩、路由分包和按需引入组件。

如果需要丢弃本机旧数据库并从 SQL 重新生成，可以单独运行：

```bat
scripts\cleanup.bat
```

该脚本会先停止本项目本地进程，再删除 `tools/mysql-data`。下一次运行 `scripts\start.bat` 时会重新初始化 MySQL 并导入当前 SQL。这个操作会清空本机玩家、商品、订单等数据库数据，不会在正常启动流程中自动执行。PowerShell 版本入口是 `scripts\cleanup.ps1`，主要供命令行或自动化使用。

## 协作注意事项

- 当前已迁移为 MySQL 目标配置。新机器直接运行 `scripts\start.bat`，脚本会自动下载便携工具并初始化本机数据目录。
- `tools` 下的二进制压缩包、解压目录、`node_modules`、`tools/mysql-data`、`tools/redis-data`、`paper-server/paper-1.21.1.jar` 都是本机运行依赖或生成数据，通常不要提交到 Git。协作者应通过脚本在自己的机器上生成。
- 若依后端依赖 Redis 缓存服务；MySQL 负责业务数据，Redis 负责登录令牌、验证码、缓存等运行状态。
- `scripts\start.bat` 会先调用 `scripts/stop-all.ps1` 停止当前项目旧进程。不要在同一份工作区里保留重要的手动调试 Java/Node 进程后再直接运行一键脚本。
- 不要同时保留多个 MineShop 插件 jar，避免 Paper 重复加载。
- 修改 `src/main/resources/config.yml` 只影响重新构建后的默认配置；服务器已生成的配置需要改 `paper-server/plugins/MineShopLite/config.yml`。
- Firebase 开启后，注册和登录都依赖外网访问 Firebase Auth REST API。
- 当前插件内置网页默认关闭，正式网站和后台应在若依前端中实现。
- 当前商城还不是完整业务系统，购物车、多商户合并结算、普通玩家网页账号自动登录和真正的客户端自定义搜索 GUI 等仍属于后续扩展；玩家市场物流、中转站、运费和到达处理已接入当前演示链路。

## 成员分工和后续开发方向

当前设计文档按真实业务角色分工，不按“只写前端/只写后端”分工：

- `fsj`：服务器 / 平台运营者，负责后台运营、审计、退款、物流路线和高风险操作。
- `lzh`：商户玩家，负责商铺拥有者、商品上架、领地、仓库、库存和发货。
- `wzh`：消费者玩家，负责浏览商品、下单购买、收货、个人订单和钱包体验。
