**问题理解**

* 创建/编辑对话框单列过长，影响填写与可读性。

* 产品、用户应支持选择（远程搜索）而非手填。

* 订单来源限定为：淘宝/拼多多/京东/线下；来源类型与文本重复，应仅保留类型并在后端映射文本。

**前端改造**

* 表单布局（左右分布）：

  * 在 `web/admin/src/views/operations/shipping-stats/index.vue` 的编辑对话框使用 `el-row/el-col` 两列布局，将字段按分组排布：

    * 左列：发货时间、产品选择、单价、发货数量、订单来源类型（下拉）。

    * 右列：用户选择、收件人、地址、快递公司、运单号、订单号。

  * 必填项：`shipped_at`、`product_id`、`user_id`、`shipped_qty`。

* 产品选择：

  * 远程搜索下拉 `el-select filterable remote` 调用 `GET 'admin/products'`（已有路由：`internal/router/router.go:120`）。

  * 选中后自动填充：`product_id`、`product_name`、`product_price_cents`。

* 用户选择：

  * 远程搜索下拉调用 `GET 'admin/users'`（已有路由：`internal/router/router.go:129`）。

  * 选中后自动填充：`user_id`、`user_name`；`user_address_text`仍支持手动输入。

* 订单来源：

  * 将 `order_source_type` 改为下拉选择：`{1: 淘宝, 2: 拼多多, 3: 京东, 4: 线下}`。

  * 移除前端表单中的 `order_source_text` 字段，仅展示文本列（由后端返回）。

* API 类型调整：

  * 在 `web/admin/src/api/shipping-stats.ts` 的 `CreateShippingStatRequest/UpdateShippingStatRequest` 中删除 `order_source_text` 字段。

  * 列表表格仅显示 `order_source_text`；不显示 `order_source_type` 列（现有实现只显示文本，无需调整）。

**后端改造**

* 文段位置：`internal/api/admin/shipping_stats_admin.go`。

* 文本映射策略：

  * 在创建与更新接口中，根据 `OrderSourceType` 自动映射 `OrderSourceText`：

    * `1→"淘宝"`、`2→"拼多多"`、`3→"京东"`、`4→"线下"`，其他值映射为`"未知"`。

  * 移除对 `order_source_text` 的前端输入依赖：

    * `CreateShippingStat()` 忽略请求体中的 `order_source_text`，统一用映射结果赋值。

    * `ModifyShippingStat()` 若 `OrderSourceType` 变更则同步更新映射文本。

* 其余字段逻辑不变；保留列表筛选条件与分页排序。

**交互与体验**

* 远程搜索均支持关键字匹配与节流，选项标签为 `名称 (ID)`，用户便于确认。

* 表单左右分布减少滚动，分组更清晰；金额与运单等非必填项可留空。

**验收标准**

* 新建/编辑对话框为两列布局，核心字段分组合理，必填校验生效。

* 产品与用户支持远程搜索选择，选中后自动填充相关字段。

* 订单来源仅以下拉类型选择，后端返回正确文本，前端只展示文本；不再出现“来源文本/来源类型重复”问题。

* 列表/详情/增改删功能在管理端登录后完整可用。

