# 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 │ │ 结果 │ │ │ │ │ └────────────────┘ └────────────────┘ └────────────────────┘ │ │ │ └──────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────────────────────────────────┐ │ │ │ 前端展示 │ │ │ │ - 选品数据表格: 显示入选饰品 (可删除) │ │ │ │ - 选品日志弹窗: 实时查看判断过程 │ │ │ │ - 自动扫货: 选品完成后自动触发 (可选) │ │ │ └──────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────┘ ```