# BUFF 选品接口业务思路
## 一、系统架构概述
### 1.1 技术栈与调用链路
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ 前端 (client-tauri) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ BuffSelectionView.vue │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │ │
│ │ │ 检索条件表单 │ │ 选品条件表单 │ │ 开始选品 / 开始扫货 │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────┬───────────┘ │ │
│ │ │ │ │
│ │ ┌────────────────────────────────────────────────────▼───────────┐ │ │
│ │ │ secureApiClient.startBuffSelection() │ │ │
│ │ │ (secureApiClient.ts) │ │ │
│ │ └────────────────────────────────────────────────────┬───────────┘ │ │
│ └───────────────────────────────────────────────────────┼─────────────┘ │
│ │ │
└────────────────────────────────────────────────────────┼──────────────────┘
│ invoke()
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ Tauri 后端 (Rust) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Rust Commands (src-tauri) │ │
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
│ │ │ secure_buff_selection_start() │ │ │
│ │ │ - 调用 FastAPI POST /buff/secure/selection-start │ │ │
│ │ │ - AES+RSA 加密通信 │ │ │
│ │ └─────────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼ HTTP
┌─────────────────────────────────────────────────────────────────────────────┐
│ Python 后端 (backend-client) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ FastAPI Router (app/api/v1/router.py) │ │
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
│ │ │ POST /buff/secure/selection-start │ │ │
│ │ │ (安全端点,带加密解密) │ │ │
│ │ │ │ │ │
│ │ │ 1. 校验 session + machine_code + 用户过期 │ │ │
│ │ │ 2. 检查每日选品次数/条数限制 │ │ │
│ │ │ 3. 创建 BuffSelectionRequest (pending) │ │ │
│ │ │ 4. BackgroundTasks 执行 run_selection_task │ │ │
│ │ └─────────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ BuffSelectionService (app/services/) │ │
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
│ │ │ run_selection_task() │ │ │
│ │ │ │ │ │
│ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │
│ │ │ │ 第一步筛选 │ -> │ 第二步筛选 │ │ │ │
│ │ │ │ step1_candidate_ │ │ 利润判断与落库 │ │ │ │
│ │ │ │ ids() │ │ │ │ │ │
│ │ │ └─────────────────┘ └─────────────────┘ │ │ │
│ │ │ │ │ │ │ │
│ │ │ ▼ ▼ │ │ │
│ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │
│ │ │ │ buff_goods_filtered_view │ │ │ │
│ │ │ │ (BUFF 饰品数据视图) │ │ │ │
│ │ │ └─────────────────────────────────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 数据库表 │ │
│ │ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ │
│ │ │buff_selection_ │ │buff_selection_ │ │buff_selection_ │ │ │
│ │ │request │ │request_item │ │request_log │ │ │
│ │ │(选品请求单) │ │(选品明细) │ │(选品日志) │ │ │
│ │ └──────────────────┘ └──────────────────┘ └──────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### 1.2 核心数据表
| 表名 | 用途 | 关键字段 |
|------|------|----------|
| `buff_selection_request` | 选品请求单 | id, user_id, config_id, status, cancel_requested |
| `buff_selection_request_item` | 选品明细(选中的饰品) | goods_id, goods_name, price_cny, price_usd, wear_range |
| `buff_selection_request_log` | 选品过程日志 | request_id, goods_id, result, message, sequence_no |
| `buff_selection_config` | 用户选品配置 | config_json (包含所有检索和选品条件) |
| `buff_goods_filtered_view` | BUFF饰品数据视图 | 分类编码, 品质, 价格, 磨损区间等 |
---
## 二、前端调用流程
### 2.1 界面组件 (BuffSelectionView.vue)
**界面分为6个区域**:
1. **BUFF饰品检索条件**:步枪、手枪、微型冲锋枪、霰弹枪、机枪、品质、类别、外观、收藏品
2. **排除/指定饰品ID**:排除不想扫描的饰品,或指定必须扫描的饰品
3. **选品/扫货条件设置**:
- Steam 卡价比例
- 利润率 (%)
- BUFF 价格区间 (元)
- BUFF 在售数量
- 智能选品助手 (低/标准/高)
- 每天自动选品时间
- 选品数量
- 智能扫货助手 (低/标准/高)
- 扫货进程数
4. **按钮区域**:保存配置、开始选品、停止选品、开始扫货、停止扫货
5. **选品数据展示**:选中的饰品列表
6. **扫货成功数据展示**:扫货成功购买的饰品
### 2.2 开始选品按钮触发流程
```typescript
// 1. 点击「开始选品」按钮
开始选品
// 2. handleStart 函数
async function handleStart(source: 'manual' | 'auto' = 'manual') {
// 前置校验
if (form.steamCardRatio == null) {
message.warning('请先填写 Steam 卡价比例')
return
}
if (form.profitRate == null) {
message.warning('请先填写利润率')
return
}
// 清理之前的选品/扫货任务
await prepareBuffEnvironmentBeforeStart('selection', { manualHint: true })
// 调用后端API开始选品
running.value = true
secureApiClient.startBuffSelection(sessionId, machineCode)
.then((res) => {
if (res.code !== 200) {
message.warning(res.msg || '选品启动失败')
running.value = false
return
}
// 启动轮询获取选品结果
fetchSelectionResult(false).then(({ status }) => {
if (status === 'pending' || status === 'running') {
// 每秒轮询一次
selectionListPollTimer.value = setInterval(() => {
fetchSelectionResult(false).then(({ status }) => {
if (status !== 'pending' && status !== 'running') {
stopSelectionListPoll()
running.value = false
if (status === 'completed') {
// 选品完成,可能触发自动扫货
handleStartSweep(true, startedRequestId)
}
}
})
}, 1000)
}
})
})
}
// 3. 清理前置环境
async function prepareBuffEnvironmentBeforeStart(forWhat: 'selection' | 'sweep') {
// 1. 调用后端停止当前选品
await secureApiClient.stopBuffSelection(sessionId, machineCode)
// 2. 调用后端停止当前扫货
await secureApiClient.stopBuffSweep(sessionId, machineCode)
// 3. 停止前端轮询
stopSelectionListPoll()
stopSweepPoll()
// 4. 重置状态
running.value = false
sweepRunning.value = false
}
```
### 2.3 选品结果轮询
```typescript
// 获取选品结果
async function fetchSelectionResult(showLoading = false) {
const res = await secureApiClient.getBuffSelectionResult(sessionId, machineCode)
if (res.code === 200 && res.data) {
// 更新选品列表
selectionList.value = res.data.items
return { status: res.data.status, requestId: res.data.request_id }
}
return { status: null, requestId: null }
}
```
---
## 三、后端处理流程
### 3.1 API 端点 (router.py)
```python
@router.post("/buff/secure/selection-start")
@secure_endpoint(require_login=True, require_machine_code=True)
async def post_buff_selection_start_secure(
decrypted_params: dict, request: Request, db: Session, session=None, user=None
):
"""
开始选品(安全端点)
1. 校验会话、机器码、用户过期
2. 检查每日选品次数限制
3. 检查每日选品条数限制
4. 创建选品请求单 (pending)
5. 后台执行 run_selection_task
"""
```
### 3.2 选品请求单创建
```python
# 创建选品请求单
req = BuffSelectionRequest(
user_id=user_id,
config_id=config_id, # 使用默认配置或指定配置
status="pending",
)
db.add(req)
db.commit()
db.refresh(req)
# 后台异步执行选品任务
background_tasks.add_task(run_selection_task, req.id, user_id, config_id)
return {"code": 200, "msg": "选品已开始", "data": {"request_id": req.id}}
```
### 3.3 选品任务执行 (buff_selection_service.py)
```python
def run_selection_task(request_id: int, user_id: int, config_id: Optional[int]) -> None:
"""
后台选品任务执行流程:
1. 更新状态为 running
2. 加载用户配置
3. 执行第一步:筛选候选饰品ID
4. 执行第二步:逐个判断利润并落库
5. 更新状态为 completed/failed/cancelled
"""
```
---
## 四、核心选品逻辑
### 4.1 第一步:根据基础条件筛选候选饰品
**函数**: `step1_candidate_ids(db, config)`
**输入**: 用户配置的检索条件
**处理逻辑**:
```
┌─────────────────────────────────────────────────────────────────────────┐
│ buff_goods_filtered_view │
│ (BUFF 饰品数据视图) │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ WHERE 条件构建 │
├─────────────────────────────────────────────────────────────────────────┤
│ 条件块1: 枪械选择 (步枪/手枪/SMG/霰弹枪/机枪) │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ - 都没选: 1=1 (不限制) │ │
│ │ - 有选: 分类编码 IN ('weapon_ak47', 'weapon_awp', ...) │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ AND │
│ 条件块2: 品质 │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ - 未选: 1=1 │ │
│ │ - 已选: 品质 IN ('违禁', '隐秘', '保密', ...) │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ AND │
│ 条件块3: 类别 (普通/StatTrak™) │
│ 条件块4: 外观 (崭新出厂/略有磨损/久经沙场) │
│ 条件块5: 收藏品 │
│ 条件块6: BUFF 价格区间 (当前在售最低价格) │
│ 条件块7: BUFF 在售数量 │
│ 条件块8: 排除的饰品ID │
│ AND │
│ 条件块9: 指定饰品ID (UNION,不参与WHERE) │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 饰品 ID 列表 (已乱序) │
│ [id_104, id_892, id_567, id_231, id_789, ...] │
└─────────────────────────────────────────────────────────────────────────┘
```
**SQL 示例**:
```sql
SELECT DISTINCT `BUFF饰品ID`
FROM buff_goods_filtered_view
WHERE 1=1
AND `分类编码` IN (:gun_0, :gun_1, :gun_2)
AND `品质` IN (:quality_0, :quality_1)
AND `当前在售最低价格` >= :buff_price_min
AND `当前在售最低价格` <= :buff_price_max
AND `在售数量` >= :buff_sales_min
AND `在售数量` <= :buff_sales_max
AND `BUFF饰品ID` NOT IN (:exclude_0, :exclude_1)
```
**输出**: 候选饰品ID列表(与指定ID合并后乱序)
---
### 4.2 第二步:逐个判断利润并落库
**函数**: 在 `run_selection_task` 中循环调用
**流程图**:
```
┌─────────────────────────────────────────────────────────────────────────┐
│ 遍历候选饰品 ID 列表 (已乱序) │
│ [id_104, id_892, id_567, ...] │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 饰品 ID: {goods_id} │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 1. 获取当前在售最低价格 │ │
│ │ SELECT MIN(`当前在售最低价格`) FROM buff_goods_filtered_view │ │
│ │ WHERE `BUFF饰品ID` = :goods_id │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 2. BUFF 价格区间兜底复核 │ │
│ │ - 最低价 < buffPriceMin → 不入选 │ │
│ │ - 最低价 > buffPriceMax → 不入选 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 3. 智能选品助手判断 (assistantLevel) │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ low: 不做均价判断,直接通过 │ │ │
│ │ │ standard: 7天均价需在 [最低价*0.7, 最低价*1.3] 范围内 │ │ │
│ │ │ high: 30天均价需在 [最低价*0.5, 最低价*1.4] 范围内 │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 4. 获取磨损区间列表 (按最小磨损值升序) │ │
│ │ SELECT `最小磨损值`, `最大磨损值`, `区间底价` │ │
│ │ FROM buff_goods_filtered_view │ │
│ │ WHERE `BUFF饰品ID` = :goods_id │ │
│ │ ORDER BY `最小磨损值` ASC │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 5. 筛选「正常磨损区间」 │ │
│ │ 要求: 随最小磨损值增大,区间底价必须单调不升 │ │
│ │ 一旦某区间底价 > 前一个区间底价,该区间及之后全部舍弃 │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ 0.00-0.01: 215 ✓ │ │ │
│ │ │ 0.01-0.02: 210 ✓ (215→210 下降) │ │ │
│ │ │ 0.02-0.03: 178 ✓ (210→178 下降) │ │ │
│ │ │ 0.03-0.04: 200 ✗ (178→200 上升,异常) │ │ │
│ │ │ 0.04-0.05: 130 ✗ (被截断) │ │ │
│ │ │ 正常区间: [0.00-0.01, 0.01-0.02, 0.02-0.03] │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 6. 计算「满足利润的区间」 │ │
│ │ 比较价 = 当前在售最低价格 × (1 + 用户利润率) │ │
│ │ 例: 最低价=175, 利润率=10% → 比较价=175×1.1=192.5 │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ 正常区间底价 vs 比较价(192.5): │ │ │
│ │ │ 215 > 192.5 → 保留 ✓ │ │ │
│ │ │ 210 > 192.5 → 保留 ✓ │ │ │
│ │ │ 178 < 192.5 → 不保留,后续截断 │ │ │
│ │ │ 满足利润区间: [0.00-0.01, 0.01-0.02] │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ 有满足利润的区间? │ │
│ └────────┬─────────┘ │
│ 是 (入选) │ 否 (不入选) │
│ ┌───────────┴───────────┐ │
│ ▼ ▼ │
│ ┌─────────────────────────────────┐ ┌─────────────────────────┐ │
│ │ 7. 写入 buff_selection_ │ │ 写入选品日志 │ │
│ │ request_item │ │ result='not_selected' │ │
│ │ ┌───────────────────────────┐ │ │ message='无满足利润...' │ │
│ │ │ goods_id: xxx │ │ └─────────────────────────┘ │
│ │ │ goods_name: xxx │ │ │
│ │ │ price_cny: 比较价×扫货系数 │ │ │
│ │ │ price_usd: price_cny/汇率 │ │ │
│ │ │ wear_range: 0.00-0.02 │ │ │
│ │ └───────────────────────────┘ │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
```
### 4.3 选品结束条件
```
┌─────────────────────────────────────────────────────────────────────────┐
│ 选品结束条件 │
├─────────────────────────────────────────────────────────────────────────┤
│ 条件1: 用户配置的「选品数量」达标 │
│ 已入选饰品数 = selectionQuantity │
│ │
│ 条件2: 候选饰品ID全部处理完毕 │
│ 所有ID已遍历但未达到选品数量 │
│ │
│ 条件3: 当日选品条数达上限 │
│ 今日累计入选饰品数 >= system_config:buff_selection_daily_ │
│ items_limit_per_user (默认900) │
│ │
│ 条件4: 用户主动停止 │
│ cancel_requested = True │
└─────────────────────────────────────────────────────────────────────────┘
```
---
## 五、价格计算逻辑
### 5.1 目标价格计算
```
┌─────────────────────────────────────────────────────────────────────────┐
│ 价格计算公式 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. 比较价 = 当前在售最低价格 × (1 + 用户利润率) │
│ │
│ 例: 当前在售最低价 = 175元, 利润率 = 10% │
│ 比较价 = 175 × (1 + 0.10) = 192.5元 │
│ │
│ 2. 价格(人民币) = 比较价 × (1 + 扫货价格系数) │
│ │
│ 扫货价格系数来自 system_config: │
│ - 低: buff_sweep_price_factor_min (如 0.03) │
│ - 标准: buff_sweep_price_factor_mid (如 0.05) │
│ - 高: buff_sweep_price_factor_max (如 0.08) │
│ │
│ 例: 智能扫货助手=低, 系数=0.03 │
│ 价格(人民币) = 192.5 × (1 + 0.03) = 198.275元 │
│ │
│ 3. 价格(美元) = 价格(人民币) ÷ Steam卡价汇率 + 0.01 │
│ │
│ 例: Steam卡价比例 = 7.2 │
│ 价格(美元) = 198.275 / 7.2 + 0.01 = $27.55 │
│ │
└─────────────────────────────────────────────────────────────────────────┘
```
### 5.2 智能选品助手等级
| 等级 | 均价来源 | 价格波动范围 | 配置项 |
|------|----------|--------------|--------|
| low | 不判断 | 无限制 | - |
| standard | 7天在售最低价格平均价 | [-50%, +30%] | buff_ai_standard_range_max_increase_ratio
buff_ai_standard_range_max_decrease_ratio |
| high | 30天在售最低价格平均价 | [-50%, +40%] | buff_ai_high_range_max_increase_ratio
buff_ai_high_range_max_decrease_ratio |
---
## 六、选品日志
### 6.1 日志写入时机
每判断完一个饰品(无论是否入选),立即插入一条日志到 `buff_selection_request_log`。
### 6.2 日志内容
```sql
INSERT INTO buff_selection_request_log (
request_id, user_id, goods_id, goods_name,
sequence_no, result, message, wear_range,
price_cny, price_usd, created_at
) VALUES (
:request_id, :user_id, :goods_id, :goods_name,
:sequence_no, :result, :message, :wear_range,
:price_cny, :price_usd, :created_at
);
```
### 6.3 result 值说明
| result | 含义 | message 示例 |
|--------|------|-------------|
| `selected` | 已入选 | "已入选" |
| `not_selected` | 未入选 | "无满足利润的磨损区间"
"7天均价不在智能选品标准范围"
"当前在售最低价低于设置下限" |
| `stage` | 阶段日志 | "检索阶段:完成,共检索到 xxx 个候选饰品"
"计算阶段:结束,共入选 xxx 个饰品" |
---
## 七、前端轮询机制
### 7.1 选品状态轮询
```
┌─────────────────────────────────────────────────────────────────────────┐
│ 前端轮询获取选品结果 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 点击「开始选品」 │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 调用 secureApiClient.startBuffSelection() │ │
│ │ 返回 request_id │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 立即调用 fetchSelectionResult() 一次 │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 判断返回的 status: │ │
│ │ - pending/running: 启动 setInterval,每秒轮询 │ │
│ │ - completed/failed/cancelled: 停止轮询 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 选品完成后: │ │
│ │ 1. 更新 selectionList 显示入选饰品 │ │
│ │ 2. 如果配置了「选品数量」,自动触发扫货 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
```
### 7.2 自动选品定时器
```typescript
// 配置了「每天自动选品时间」后,启动定时器
function startAutoSelectionScheduler() {
autoSelectionTimer.value = setInterval(() => {
if (shouldRunAutoSelectionNow(dayjs())) {
handleStart('auto') // 自动触发选品
}
}, 20 * 1000) // 每20秒检查一次
}
```
---
## 八、系统限制
### 8.1 system_config 配置项
| config_key | 默认值 | 说明 |
|------------|--------|------|
| `buff_selection_daily_times_limit_per_user` | 3 | 每用户每天最多发起选品次数 |
| `buff_selection_daily_items_limit_per_user` | 900 | 每用户每天累计入选饰品条数上限 |
| `buff_ai_standard_range_max_increase_ratio` | 0.3 | 标准模式价格涨幅上限 |
| `buff_ai_standard_range_max_decrease_ratio` | 0.5 | 标准模式价格跌幅上限 |
| `buff_ai_high_range_max_increase_ratio` | 0.4 | 高模式价格涨幅上限 |
| `buff_ai_high_range_max_decrease_ratio` | 0.5 | 高模式价格跌幅上限 |
| `buff_sweep_price_factor_min` | 0.03 | 低扫货价格系数 |
| `buff_sweep_price_factor_mid` | 0.05 | 标准扫货价格系数 |
| `buff_sweep_price_factor_max` | 0.08 | 高扫货价格系数 |
### 8.2 限制检查时机
```
开始选品前检查:
│
├─→ 每日选品次数限制 (当日请求单数 < times_limit)
│
└─→ 每日选品条数限制 (当日累计入选数 < items_limit)
选品过程中检查:
│
└─→ 每日选品条数限制 (当本单处理时再次检查,超过则停止)
```
---
## 九、接口汇总
| 接口 | 用途 | 调用时机 |
|------|------|----------|
| `startBuffSelection` | 开始选品 | 点击「开始选品」 |
| `getBuffSelectionResult` | 获取选品结果 | 轮询获取状态和入选饰品 |
| `getBuffSelectionLog` | 获取选品日志 | 查看选品日志弹窗 |
| `stopBuffSelection` | 停止选品 | 点击「停止选品」 |
| `deleteBuffSelectionItem` | 删除选品数据 | 移除某个入选饰品 |
| `getBuffSelectionConfig` | 获取选品配置 | 页面加载时 |
| `saveBuffSelectionConfig` | 保存选品配置 | 点击「保存配置」 |
---
## 十、业务流程总结
```
┌─────────────────────────────────────────────────────────────────────────┐
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────────┐ │
│ │ 用户配置 │ -> │ 点击开始选品 │ -> │ 创建选品请求单 (pending) │ │
│ │ 检索+选品条件 │ │ │ │ │ │
│ └──────────────┘ └──────────────┘ └───────────┬──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ 后台执行选品任务 │ │
│ │ ┌───────────────────────┐ ┌───────────────────────────────┐ │ │
│ │ │ 第一步: 基础条件筛选 │ -> │ 第二步: 逐个利润判断 │ │ │
│ │ │ - 枪械/品质/类别... │ │ - 智能选品助手判断 │ │ │
│ │ │ - 价格区间/在售数量 │ │ - 磨损区间分析 │ │ │
│ │ │ - 排除/指定ID │ │ - 利润计算与落库 │ │ │
│ │ └───────────────────────┘ └───────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ 选品结果 │ │
│ │ ┌────────────────┐ ┌────────────────┐ ┌────────────────────┐ │ │
│ │ │ 选品请求单状态 │ │ 入选饰品列表 │ │ 选品过程日志 │ │ │
│ │ │ completed/... │ │ buff_sel_ │ │ 每个饰品的判断 │ │ │
│ │ │ │ │ request_item │ │ 结果 │ │ │
│ │ └────────────────┘ └────────────────┘ └────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ 前端展示 │ │
│ │ - 选品数据表格: 显示入选饰品 (可删除) │ │
│ │ - 选品日志弹窗: 实时查看判断过程 │ │
│ │ - 自动扫货: 选品完成后自动触发 (可选) │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
```