shop-wx/doc/暂存柜功能文档.md

12 KiB
Raw Blame History

暂存柜功能文档

概述

storage-cells-summary 组件是智能柜管理系统中用于暂存柜(临时存储)功能的核心组件。该组件提供以下核心功能:

  1. 可用格口展示 - 显示当前店铺/区域的可用暂存柜格口,按格口类型(小格、中格、大格、超大格)分类统计
  2. 格口选择 - 允许用户选择特定类型的格口进行物品存入
  3. 物品存入流程 - 完整的存入物品流程:分配格口 → 生成密码 → 验证密码 → 打开格口
  4. 物品取出流程 - 通过密码验证取出已暂存的物品
  5. 状态管理 - 使用状态机模式管理弹窗流程,确保业务流程完整性

功能特性

1. 数据展示

  • 实时获取并显示可用格口数量
  • 按四种格口类型分类统计:小格(1)、中格(2)、大格(3)、超大格(4)
  • 显示每种类型的剩余可用数量
  • 支持刷新数据

2. 格口选择

  • 可视化格口类型卡片展示
  • 显示每种类型的SVG图标
  • 智能禁用无可用格口的类型
  • 选中状态视觉反馈

3. 存入流程

用户点击"物品暂存" → 分配选定类型格口 → 生成4位数字密码 →
显示密码给用户 → 用户确认已记住 → 输入密码验证 →
验证通过打开格口 → 刷新格口状态

4. 取出流程

用户点击"物品取出" → 输入4位密码 → 验证密码 →
验证通过打开格口 → 刷新格口状态

5. 用户交互

  • 加载状态提示
  • 错误状态处理与重试
  • 空状态提示
  • 弹窗式密码输入与验证
  • 数字键盘集成

组件结构

文件位置

src/components/storage-cells-summary/
├── index.vue              # 主组件文件
└── usePopupState.ts      # 弹窗状态管理hook

组件Props

属性名 类型 默认值 说明
shopId number 必填 店铺ID用于获取可用格口列表
autoLoad boolean true 是否自动加载数据
showButtons boolean true 是否显示操作按钮(存入/取出)

组件Emits

事件名 参数 说明
deposit 点击存入按钮时触发(向后兼容)
retrieve 点击取出按钮时触发(向后兼容)
refresh 数据刷新完成时触发
error Error 数据加载失败时触发
backToAddressSelect 点击"重选地址"按钮时触发

核心状态变量

变量名 类型 说明
loading Ref<boolean> 数据加载状态
error Ref<Error | null> 错误信息
cellsData Ref<AvailableStorageCellDTO[]> 格口数据列表
selectedCellType Ref<number> 当前选中的格口类型
depositLoading Ref<boolean> 存入操作加载状态
retrieveLoading Ref<boolean> 取出操作加载状态
generatedPassword Ref<string> 生成的密码(向后兼容)

计算属性

属性名 说明
availableCells 过滤出无密码的可用格口
cellTypeStats 按类型统计可用格口数量
hasAvailableCells 是否存在可用格口

业务流程

1. 数据初始化流程

graph TD
    A[组件挂载] --> B{autoLoad为true?};
    B -->|是| C[调用refresh函数];
    B -->|否| D[等待手动刷新];
    C --> E[调用availableStorageCells API];
    E --> F[更新cellsData];
    F --> G[触发refresh事件];

2. 物品存入流程

graph TD
    A[用户点击"物品暂存"] --> B[触发deposit事件];
    B --> C[调用handleDepositFlow];
    C --> D[调用storeItemApi分配格口];
    D --> E{是否获取到密码?};
    E -->|是| F[显示密码弹窗];
    E -->|否| G[显示错误提示];
    F --> H[用户点击"已记住"];
    H --> I[进入密码验证状态];
    I --> J[用户输入密码];
    J --> K[密码验证];
    K --> L{密码正确?};
    L -->|是| M[调用openByPassword打开格口];
    L -->|否| N[显示密码错误提示];
    M --> O[显示成功提示];
    O --> P[刷新格口数据];

3. 物品取出流程

graph TD
    A[用户点击"物品取出"] --> B[触发retrieve事件];
    B --> C[显示密码输入弹窗];
    C --> D[用户输入密码];
    D --> E[调用openByPassword打开格口];
    E --> F[显示成功提示];
    F --> G[刷新格口数据];

API接口

依赖的API模块

import {
  availableStorageCells,   // 获取可用格口列表
  storeItemApi,           // 存入物品分配格口
  openByPassword,         // 根据密码打开格口
  resetByPassword         // 重置格口状态(当前未使用)
} from '@/api/cabinet/index'

1. availableStorageCells

功能:获取指定店铺的可用暂存柜格口列表

请求参数

{
  shopId: number  // 店铺ID
}

响应数据结构AvailableStorageCellDTO[]

interface AvailableStorageCellDTO {
  cellId: number;          // 格口ID
  cabinetId: number;       // 柜机ID
  cabinetName: string;     // 柜子名称
  mainboardId: number;     // 主板ID
  cellNo: number;         // 格口号
  pinNo: number;          // 针脚序号
  stock: number;          // 库存数量
  cellPrice: number;      // 格口租用价格
  isRented: number;       // 是否已租用0-未租用1-已租用)
  cellType: number;       // 格口类型1-小格2-中格3-大格4-超大格)
  usageStatus: number;    // 使用状态1-空闲2-已占用)
  availableStatus: number;// 可用状态1-正常2-故障)
  hasPassword: boolean;   // 是否有密码true-有密码/已占用false-无密码/可用)
  goodsId: number;        // 商品ID
  goodsName: string;      // 商品名称
  price: number;         // 商品价格
  coverImg: string;      // 封面图URL
}

2. storeItemApi

功能:存入物品并分配格口,生成访问密码

请求参数StoreItemToCellCommand

interface StoreItemToCellCommand {
  shopId: number;    // 店铺ID
  cellType: number;  // 格口类型1-小格2-中格3-大格4-超大格)
}

响应数据结构CabinetCellEntity

interface CabinetCellEntity {
  cellId: number;          // 格口唯一ID
  cabinetId: number;       // 关联柜机ID
  mainboardId?: number;    // 主板ID
  cellNo: number;         // 格口号
  pinNo: number;          // 针脚序号
  stock: number;          // 库存数量
  cellPrice?: number;     // 格口价格
  isRented: number;       // 是否已租用0-未租用1-已租用
  cellType: number;       // 格口类型1小格 2中格 3大格 4超大格
  usageStatus: number;    // 使用状态1空闲 2已占用
  availableStatus: number;// 可用状态1正常 2故障
  goodsId?: number;       // 商品ID
  password?: string;      // 密码(暂存模式使用)
}

3. openByPassword

功能:根据密码打开对应的格口

请求参数OpenCellByPasswordCommand

interface OpenCellByPasswordCommand {
  shopId: number;     // 店铺ID
  password: string;   // 格口密码
}

响应无数据成功时HTTP状态码为200

状态管理usePopupState

状态机设计

弹窗流程采用状态机模式,确保业务流程的完整性和一致性:

状态类型 说明 显示内容
idle 空闲状态,无弹窗显示 无弹窗
password-show 显示生成的密码 密码显示弹窗
password-verify 验证用户输入的密码 密码输入框+验证按钮
retrieve-input 输入取出密码 密码输入框+确认按钮
processing 显示处理中的加载提示 加载动画+处理文本

状态转换图

graph LR
    A[idle] -->|存入流程开始| B[password-show];
    B -->|点击"已记住"| C[password-verify];
    C -->|密码验证通过| D[processing];
    C -->|密码验证失败| C;
    A -->|取出流程开始| E[retrieve-input];
    E -->|输入密码确认| D[processing];
    D -->|操作完成| A;
    B -->|取消| A;
    C -->|取消| A;
    E -->|取消| A;

Hook接口

interface UsePopupStateReturn {
  currentState: Ref<PopupState>;           // 当前弹窗状态
  popupInputValue: Ref<string>;           // 弹窗输入框的值
  passwordLength: number;                 // 密码长度固定为4
  popupVisible: ComputedRef<boolean>;     // 弹窗显示状态
  keyboardVisible: Ref<boolean>;          // 键盘显示状态
  popupTitle: ComputedRef<string>;        // 弹窗标题
  popupMessage: ComputedRef<string>;      // 弹窗消息内容
  popupConfirmText: ComputedRef<string>;  // 确认按钮文本
  showCancelButton: ComputedRef<boolean>; // 是否显示取消按钮
  transitionTo: (state: PopupState) => void; // 状态转换函数
  // ... 其他处理函数
}

使用方法

1. 基本使用

<template>
  <storage-cells-summary
    :shop-id="currentShopId"
    :auto-load="true"
    :show-buttons="true"
    @deposit="handleDeposit"
    @retrieve="handleRetrieve"
    @refresh="handleRefresh"
    @error="handleError"
    @back-to-address-select="handleBack"
  />
</template>

2. 仅展示模式

<template>
  <storage-cells-summary
    :shop-id="currentShopId"
    :show-buttons="false"
  />
</template>

3. 手动控制数据加载

<template>
  <storage-cells-summary
    ref="storageRef"
    :shop-id="currentShopId"
    :auto-load="false"
  />
</template>

<script setup>
import { ref, onMounted } from 'vue'

const storageRef = ref()

// 手动刷新数据
function refreshData() {
  storageRef.value?.refresh()
}
</script>

样式与UI组件

使用的UI组件

  • wd-popup - 弹窗容器
  • wd-password-input - 密码输入框(格子模式)
  • wd-keyboard - 数字键盘
  • wd-button - 按钮
  • wd-loading - 加载动画
  • wd-icon - 图标
  • wd-row / wd-col - 栅格布局

样式特点

  • 使用 rpx 单位适配不同屏幕
  • 响应式网格布局2列
  • 交互状态反馈(点击效果、选中状态)
  • 弹窗圆角设计border-top-left-radius: 24rpx
  • 安全区域适配safe-area-inset-bottom

注意事项

1. 密码安全

  • 密码为4位数字由系统自动生成
  • 密码仅在存入流程中显示一次,用户需要牢记
  • 密码验证失败会提示错误,但不会泄露正确密码

2. 格口状态同步

  • 每次成功操作(存入/取出)后会自动刷新格口数据
  • 可用格口数量实时更新
  • 已被占用的格口hasPassword: true不会显示在可用列表中

3. 错误处理

  • 网络请求失败会显示错误提示
  • 用户可点击"重试"按钮重新加载
  • 操作失败会回到初始状态,不会卡在中间状态

4. 向后兼容性

  • 保留了 depositretrieve 事件发射
  • 保留了 generatedPassword 状态变量
  • 新增的 handleDepositFlowhandleRetrieveFlow 函数与原有事件处理并行

5. 性能考虑

  • 按需加载数据autoLoad控制
  • 计算属性缓存统计结果
  • 避免不必要的重复请求

相关文件

  • src/components/storage-cells-summary/index.vue - 主组件实现
  • src/components/storage-cells-summary/usePopupState.ts - 弹窗状态管理
  • src/api/cabinet/index.ts - 柜机相关API
  • src/api/cabinet/types.ts - 数据类型定义
  • src/static/svg/ - 格口类型SVG图标

最后更新2025-12-22 组件版本:基于当前代码实现 维护者:项目开发团队