소스 검색

伙伴商订单分配

hurx 1 개월 전
부모
커밋
8b151e2498
3개의 변경된 파일1129개의 추가작업 그리고 0개의 파일을 삭제
  1. 181 0
      src/views/order/orderAssignment/assignmentDialog.vue
  2. 324 0
      src/views/order/orderAssignment/index.vue
  3. 624 0
      src/views/order/orderAssignment/splitAssignDialog.vue

+ 181 - 0
src/views/order/orderAssignment/assignmentDialog.vue

@@ -0,0 +1,181 @@
+<template>
+  <el-drawer v-model="drawer.visible" :title="drawer.title" size="500px" direction="rtl" :before-close="handleClose">
+    <div class="drawer-content">
+      <el-form ref="orderAssignmentFormRef" :model="form" :rules="rules" label-width="120px">
+        <el-form-item label="订单编号" v-if="form.orderNo">
+          <span class="form-value">{{ form.orderNo }}</span>
+        </el-form-item>
+
+        <el-form-item label="订单数量" v-if="orderCount > 1">
+          <span class="form-value">{{ orderCount }} 个订单</span>
+        </el-form-item>
+
+        <el-divider v-if="form.platformCode" />
+
+        <el-form-item label="当前平台" v-if="form.platformCode">
+          <dict-tag :options="sys_platform_code" :value="form.platformCode" />
+        </el-form-item>
+
+        <el-form-item label="分配后平台" prop="platformAfter">
+          <el-select v-model="form.platformAfter" placeholder="请选择平台" style="width: 100%" filterable clearable>
+            <el-option v-for="dict in sys_platform_code" :key="dict.value" :label="dict.label" :value="dict.value" />
+          </el-select>
+        </el-form-item>
+
+        <el-divider content-position="left">分配原因</el-divider>
+
+        <el-form-item label-width="0" prop="remark">
+          <el-input v-model="form.remark" type="textarea" :rows="6" placeholder="请输入分配原因(选填)" maxlength="500" show-word-limit />
+        </el-form-item>
+      </el-form>
+    </div>
+
+    <template #footer>
+      <div class="drawer-footer">
+        <el-button @click="cancel">取 消</el-button>
+        <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
+      </div>
+    </template>
+  </el-drawer>
+</template>
+
+<style scoped lang="scss">
+.drawer-content {
+  padding: 0 20px 20px;
+  height: calc(100% - 60px);
+  overflow-y: auto;
+}
+
+.drawer-footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: 10px;
+  padding: 10px 20px;
+  border-top: 1px solid #e4e7ed;
+}
+
+.form-value {
+  font-weight: 500;
+  color: #303133;
+  font-size: 14px;
+}
+
+:deep(.el-divider__text) {
+  font-weight: 600;
+  font-size: 14px;
+}
+
+:deep(.el-form-item__label) {
+  font-weight: 500;
+}
+</style>
+<script setup name="OrderAssignmentDialog" lang="ts">
+import { getOrderAssignment, addOrderAssignment, updateOrderAssignment } from '@/api/order/orderAssignmentLog';
+import { OrderAssignmentForm } from '@/api/order/orderAssignmentLog/types';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { sys_platform_code } = toRefs<any>(proxy?.useDict('sys_platform_code'));
+
+const emit = defineEmits(['success']);
+
+const buttonLoading = ref(false);
+const orderAssignmentFormRef = ref<ElFormInstance>();
+const orderCount = ref(0); // 订单数量
+
+const drawer = reactive<DialogOption>({
+  visible: false,
+  title: ''
+});
+
+const initFormData: OrderAssignmentForm = {
+  id: undefined,
+  orderId: undefined,
+  orderIds: undefined,
+  orderNo: undefined,
+  platformBefore: undefined,
+  platformAfter: undefined,
+  assignedBy: undefined,
+  assignTime: undefined,
+  assignType: '0',
+  status: undefined,
+  remark: undefined
+};
+
+const data = reactive<PageData<OrderAssignmentForm, any>>({
+  form: { ...initFormData },
+  queryParams: {},
+  rules: {
+    platformAfter: [{ required: true, message: '分配后平台不能为空', trigger: 'blur' }]
+  }
+});
+
+const { form, rules } = toRefs(data);
+
+/** 打开对话框 */
+const open = async (orderIds: Array<string | number>, orderNo?: string, platformCode?: string) => {
+  reset();
+  drawer.visible = true;
+  drawer.title = orderIds.length > 1 ? '批量整单分配' : '整单分配';
+
+  form.value.orderNo = orderNo;
+  form.value.platformCode = platformCode;
+  orderCount.value = orderIds.length;
+
+  // 如果是单个订单,可以查询已有的分配信息
+  if (orderIds.length === 1) {
+    try {
+      form.value.orderIds = orderIds[0] as string;
+    } catch (error) {}
+  } else {
+    // 批量分配
+    form.value.orderIds = orderIds.join(',');
+  }
+};
+
+/** 表单重置 */
+const reset = () => {
+  form.value = { ...initFormData };
+  orderAssignmentFormRef.value?.resetFields();
+};
+
+/** 取消按钮 */
+const cancel = () => {
+  drawer.visible = false;
+  reset();
+};
+
+/** 关闭前的回调 */
+const handleClose = (done: () => void) => {
+  if (buttonLoading.value) {
+    return;
+  }
+  done();
+  reset();
+};
+
+/** 提交按钮 */
+const submitForm = () => {
+  orderAssignmentFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      try {
+        if (form.value.id) {
+          await updateOrderAssignment(form.value);
+          proxy?.$modal.msgSuccess('修改成功');
+        } else {
+          await addOrderAssignment(form.value);
+          proxy?.$modal.msgSuccess('分配成功');
+        }
+        drawer.visible = false;
+        emit('success');
+      } finally {
+        buttonLoading.value = false;
+      }
+    }
+  });
+};
+
+defineExpose({
+  open
+});
+</script>

+ 324 - 0
src/views/order/orderAssignment/index.vue

@@ -0,0 +1,324 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div v-show="showSearch" class="mb-[10px]">
+        <el-card shadow="hover">
+          <el-form ref="queryFormRef" :model="queryParams" :inline="true">
+            <el-form-item label="订单编号" prop="orderNo">
+              <el-input v-model="queryParams.orderNo" placeholder="请输入订单编号" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item label="客户编号" prop="customerCode">
+              <el-input v-model="queryParams.customerCode" placeholder="请输入客户编号" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item label="客户名称" prop="customerName">
+              <el-input v-model="queryParams.customerName" placeholder="请输入客户名称" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item label="订单来源" prop="orderSource">
+              <el-select v-model="queryParams.orderSource" placeholder="请选择订单来源" clearable>
+                <el-option v-for="dict in order_source" :key="dict.value" :label="dict.label" :value="dict.value" />
+              </el-select>
+            </el-form-item>
+            <!-- <el-form-item label="订单状态" prop="orderStatus">
+              <el-select v-model="queryParams.orderStatus" placeholder="请选择订单状态" clearable>
+                <el-option v-for="dict in order_status" :key="dict.value" :label="dict.label" :value="dict.value" />
+              </el-select>
+            </el-form-item> -->
+
+            <el-form-item label="订单时间" prop="dateRange">
+              <el-date-picker v-model="dateRange" type="daterange" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" />
+            </el-form-item>
+
+            <el-form-item>
+              <el-button type="primary" icon="Search" @click="handleQuery()">搜索</el-button>
+              <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+            </el-form-item>
+          </el-form>
+        </el-card>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="18"> 订单分配列表 </el-col>
+          <!-- <el-col :span="1.5">
+            <el-button type="primary" :disabled="!ids.length" plain @click="handleAssignment(null)">批量整单分配</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="primary" :disabled="!ids.length" plain>关闭订单</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="primary" :disabled="!ids.length" plain>删除订单</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="primary" :disabled="!ids.length" plain>导出订单</el-button>
+          </el-col> -->
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" border :data="orderMainList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" :resizable="false" />
+        <el-table-column label="订单时间" align="center" prop="orderTime" :resizable="false" />
+        <el-table-column label="订单编号" align="center" prop="orderNo" :resizable="false" />
+        <el-table-column label="客户编号" align="center" prop="customerCode" :resizable="false" />
+        <el-table-column label="订单总金额" align="center" prop="totalAmount" :resizable="false" />
+        <el-table-column label="支付方式" align="center" prop="payType" :resizable="false">
+          <template #default="scope">
+            <dict-tag :options="pay_method" :value="scope.row.payType" />
+          </template>
+        </el-table-column>
+        <!-- <el-table-column label="业务员" align="center" prop="businessStaff" :resizable="false" />
+        <el-table-column label="客服" align="center" prop="customerService" :resizable="false" /> -->
+        <el-table-column label="归属部门" align="center" prop="businessDept" :resizable="false" />
+        <el-table-column label="订单来源" align="center" prop="orderSource">
+          <template #default="scope">
+            <dict-tag :options="order_source" :value="scope.row.orderSource" />
+          </template>
+        </el-table-column>
+        <el-table-column label="分配状态" align="center" prop="assignmentStatus" :resizable="false">
+          <template #default="scope">
+            <dict-tag :options="order_assignment_status" :value="scope.row.assignmentStatus" />
+          </template>
+        </el-table-column>
+        <!-- <el-table-column label="当前平台" align="center" prop="platformCode">
+          <template #default="scope">
+            <dict-tag :options="sys_platform_code" :value="scope.row.platformCode" />
+          </template>
+        </el-table-column> -->
+
+        <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="180" :resizable="false">
+          <template #default="scope">
+            <el-button link type="primary" @click="handleReview(scope.row)">详情</el-button>
+            <el-button link type="primary" v-if="scope.row.assignmentStatus != '1'" @click="handleAssignment(scope.row)">分配</el-button>
+            <!-- <el-button link type="primary" v-if="scope.row.assignmentStatus == '1'" @click="handleAssignment(scope.row)">重新分配</el-button> -->
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+
+    <!-- 订单分配对话框 -->
+    <assignment-dialog ref="assignmentDialogRef" @success="getList" />
+    <!-- 拆单分配对话框 -->
+    <split-assign-dialog ref="splitAssignDialogRef" @success="getList" />
+  </div>
+</template>
+
+<script setup name="OrderAssignment" lang="ts">
+import { listOrderAssignment, getOrderMain, delOrderMain } from '@/api/order/orderMain';
+import { OrderMainVO, OrderMainQuery, OrderMainForm } from '@/api/order/orderMain/types';
+import AssignmentDialog from './assignmentDialog.vue';
+import SplitAssignDialog from './splitAssignDialog.vue';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { order_assignment_status, order_check_status, pay_method, order_source, sys_platform_code } = toRefs<any>(
+  proxy?.useDict('order_assignment_status', 'order_check_status', 'pay_method', 'order_source', 'sys_platform_code')
+);
+
+const orderMainList = ref<OrderMainVO[]>([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref<Array<string | number>>([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+const router = useRouter();
+const queryFormRef = ref<ElFormInstance>();
+const orderMainFormRef = ref<ElFormInstance>();
+const assignmentDialogRef = ref<InstanceType<typeof AssignmentDialog>>();
+const splitAssignDialogRef = ref<InstanceType<typeof SplitAssignDialog>>();
+
+const dateRange = ref<[DateModelType, DateModelType]>(['', '']);
+const dialog = reactive<DialogOption>({
+  visible: false,
+  title: ''
+});
+
+const initFormData: OrderMainForm = {
+  id: undefined,
+  orderNo: undefined,
+  shipmentNo: undefined,
+  subOrderNo: undefined,
+  companyId: undefined,
+  customerId: undefined,
+  customerCode: undefined,
+  userId: undefined,
+  shippingAddressId: undefined,
+  purchaseReason: undefined,
+  invoiceType: undefined,
+  payType: undefined,
+  warehouseId: undefined,
+  creditLimit: undefined,
+  expectedDeliveryTime: undefined,
+  businessStaff: undefined,
+  customerService: undefined,
+  businessDept: undefined,
+  userDept: undefined,
+  productQuantity: undefined,
+  shippingFee: undefined,
+  totalAmount: undefined,
+  payableAmount: undefined,
+  paymentStatus: undefined,
+  orderSource: undefined,
+  orderStatus: undefined,
+  orderTime: undefined,
+  confirmTime: undefined,
+  shippingTime: undefined,
+  receivingTime: undefined,
+  shippedQuantity: undefined,
+  unshippedQuantity: undefined,
+  packageCount: undefined,
+  signedQuantity: undefined,
+  afterSaleCompleted: undefined,
+  afterSalePending: undefined,
+  deliveryDesc: undefined,
+  pushStatus: undefined,
+  attachmentPath: undefined,
+  deliveryType: undefined,
+  orderCategory: undefined,
+  productCode: undefined,
+  cancelReason: undefined,
+  expenseType: undefined,
+  userNo: undefined,
+  status: undefined,
+  remark: undefined,
+  isSplitChild: undefined,
+  orderProductBos: [],
+  customerSalesInfoVo: {}
+};
+const data = reactive<PageData<OrderMainForm, OrderMainQuery>>({
+  form: { ...initFormData },
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    orderNo: undefined,
+    shipmentNo: undefined,
+    subOrderNo: undefined,
+    companyId: undefined,
+    customerCode: undefined,
+    customerId: undefined,
+    userId: undefined,
+    payType: undefined,
+    warehouseId: undefined,
+    expectedDeliveryTime: undefined,
+    businessStaff: undefined,
+    customerService: undefined,
+    businessDept: undefined,
+    productQuantity: undefined,
+    totalAmount: undefined,
+    payableAmount: undefined,
+    paymentStatus: undefined,
+    orderSource: undefined,
+    orderStatus: undefined,
+    orderTime: undefined,
+    confirmTime: undefined,
+    status: undefined,
+    isSplitChild: '1',
+    params: {}
+  },
+  rules: {}
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+/** 查询订单主信息列表 */
+const getList = async () => {
+  loading.value = true;
+  const res = await listOrderAssignment(proxy?.addDateRange(queryParams.value, dateRange.value));
+  orderMainList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
+};
+
+/** 取消按钮 */
+const cancel = () => {
+  reset();
+  dialog.visible = false;
+};
+
+/** 表单重置 */
+const reset = () => {
+  form.value = { ...initFormData };
+  orderMainFormRef.value?.resetFields();
+};
+
+/** 搜索按钮操作 */
+const handleQuery = (orderStatus?: string) => {
+  if (orderStatus) {
+    queryParams.value.orderStatus = orderStatus;
+  } else {
+    queryParams.value.orderStatus = undefined;
+  }
+  queryParams.value.pageNum = 1;
+  getList();
+};
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  dateRange.value = ['', ''];
+  queryFormRef.value?.resetFields();
+  handleQuery();
+};
+
+/** 多选框选中数据 */
+const handleSelectionChange = (selection: OrderMainVO[]) => {
+  ids.value = selection.map((item) => item.id);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+};
+
+const handleReview = (row?: OrderMainVO) => {
+  router.push({
+    path: '/order-manage/order-sendDetail',
+    query: { id: row.id }
+  });
+};
+
+/** 订单分配按钮操作 */
+const handleAssignment = async (row?: OrderMainVO | null) => {
+  let orderIds: Array<string | number>;
+
+  if (row) {
+    // 单个订单分配 - 直接打开统一的分配抽屉
+    splitAssignDialogRef.value?.open(row.id);
+  } else {
+    // 批量分配 - 只支持整单分配
+    if (!ids.value || ids.value.length === 0) {
+      proxy?.$modal.msgWarning('请选择要分配的订单');
+      return;
+    }
+    orderIds = ids.value;
+    assignmentDialogRef.value?.open(orderIds, undefined, undefined);
+  }
+};
+
+/** 删除按钮操作 */
+const handleDelete = async (row?: OrderMainVO) => {
+  const _ids = row?.id || ids.value;
+  await proxy?.$modal.confirm('是否确认删除订单主信息编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
+  await delOrderMain(_ids);
+  proxy?.$modal.msgSuccess('删除成功');
+  await getList();
+};
+
+/** 导出按钮操作 */
+const handleExport = () => {
+  proxy?.download(
+    'order/orderMain/export',
+    {
+      ...queryParams.value
+    },
+    `orderMain_${new Date().getTime()}.xlsx`
+  );
+};
+
+onMounted(() => {
+  getList();
+});
+
+onActivated(() => {
+  getList();
+});
+</script>

+ 624 - 0
src/views/order/orderAssignment/splitAssignDialog.vue

@@ -0,0 +1,624 @@
+<template>
+  <!-- 订单分配详情抽屉 -->
+  <el-drawer v-model="drawer.visible" size="65%" direction="rtl" :close-on-click-modal="true" :before-close="handleDrawerClose">
+    <template #header>
+      <div class="drawer-header">
+        <!-- <el-icon color="#f56c6c" :size="24"><WarningFilled /></el-icon> -->
+        <span class="order-title">订单分配 {{ orderInfo.orderNo }}</span>
+      </div>
+    </template>
+
+    <div class="drawer-content">
+      <div class="detail-header">
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <div class="info-item">
+              <span class="label">客户</span>
+              <span class="value">{{ orderInfo.customerName }}</span>
+            </div>
+          </el-col>
+          <el-col :span="6">
+            <div class="info-item">
+              <span class="label">负责人</span>
+              <span class="value">{{ orderInfo.businessStaff }}</span>
+            </div>
+          </el-col>
+          <el-col :span="4">
+            <div class="info-item">
+              <span class="label">商品总数</span>
+              <span class="value">{{ orderInfo.productTotal }}</span>
+            </div>
+          </el-col>
+          <el-col :span="4">
+            <div class="info-item">
+              <span class="label">待分配</span>
+              <span class="value">{{ orderInfo.unassigned }}</span>
+            </div>
+          </el-col>
+          <el-col :span="4">
+            <div class="info-item">
+              <span class="label">已分配</span>
+              <span class="value">{{ orderInfo.assigned }}</span>
+            </div>
+          </el-col>
+        </el-row>
+      </div>
+
+      <el-tabs v-model="activeTab" class="detail-tabs">
+        <el-tab-pane label="待分配" name="pending">
+          <div class="tab-actions">
+            <el-button type="primary" @click="handleBatchAssign">+ 批量分配</el-button>
+          </div>
+          <el-table
+            ref="pendingTableRef"
+            :data="pendingProducts"
+            border
+            style="width: 100%"
+            max-height="800"
+            @selection-change="handlePendingSelectionChange"
+          >
+            <el-table-column type="selection" width="55" align="center" />
+            <el-table-column label="序号" width="80" align="center">
+              <template #default="scope">{{ scope.$index + 1 }}</template>
+            </el-table-column>
+            <el-table-column label="商品图片" width="100" align="center">
+              <template #default="scope">
+                <el-image
+                  v-if="scope.row.productImage"
+                  :src="scope.row.productImage"
+                  style="width: 60px; height: 60px"
+                  fit="cover"
+                  :preview-src-list="[scope.row.productImage]"
+                />
+              </template>
+            </el-table-column>
+            <el-table-column label="商品编号" prop="productNo" align="center" />
+            <el-table-column label="商品名称" prop="productName" min-width="200" show-overflow-tooltip align="center" />
+            <el-table-column label="数量" prop="orderQuantity" align="center" />
+            <el-table-column label="单价" prop="orderPrice" align="center" />
+            <el-table-column label="小计" align="center">
+              <template #default="scope">{{ (scope.row.orderPrice * scope.row.orderQuantity).toFixed(2) }}</template>
+            </el-table-column>
+            <el-table-column label="状态" width="100" align="center">
+              <template #default="scope">
+                <dict-tag :options="order_assignment_status" :value="scope.row.assignmentStatus" />
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" width="120" align="center" fixed="right">
+              <template #default="scope">
+                <el-button link type="primary" size="small" @click="handleAssignProduct(scope.row)">分配</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+
+        <el-tab-pane label="已分配" name="assigned">
+          <el-table :data="assignedProducts" border style="width: 100%" max-height="800">
+            <el-table-column label="序号" width="80" align="center">
+              <template #default="scope">{{ scope.$index + 1 }}</template>
+            </el-table-column>
+            <el-table-column label="商品图片" width="100" align="center">
+              <template #default="scope">
+                <el-image
+                  v-if="scope.row.productImage"
+                  :src="scope.row.productImage"
+                  style="width: 60px; height: 60px"
+                  fit="cover"
+                  :preview-src-list="[scope.row.productImage]"
+                />
+              </template>
+            </el-table-column>
+            <el-table-column label="商品编号" prop="productNo" align="center" />
+            <el-table-column label="商品名称" prop="productName" min-width="200" show-overflow-tooltip align="center" />
+            <el-table-column label="数量" prop="orderQuantity" align="center" />
+            <el-table-column label="单价" prop="orderPrice" align="center" />
+            <el-table-column label="小计" align="center">
+              <template #default="scope">{{ (scope.row.orderPrice * scope.row.orderQuantity).toFixed(2) }}</template>
+            </el-table-column>
+            <el-table-column label="状态" width="100" align="center">
+              <template #default="scope">
+                <dict-tag :options="order_assignment_status" :value="scope.row.assignmentStatus" />
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+
+        <el-tab-pane label="记录" name="record">
+          <el-table :data="assignRecords" border style="width: 100%" max-height="400">
+            <el-table-column label="序号" type="index" width="80" align="center" />
+            <el-table-column label="分配时间" prop="createTime" align="center" />
+            <el-table-column label="分配人" prop="createName" align="center" />
+            <el-table-column label="分配目标" prop="assigneeName" align="center" />
+          </el-table>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+  </el-drawer>
+
+  <!-- 分配抽屉 -->
+  <el-drawer v-model="assignDialog.visible" title="分配" size="50%" direction="rtl" :close-on-click-modal="true">
+    <div class="assign-drawer-content">
+      <!-- 分配目标选择 -->
+      <div class="assign-target-section">
+        <el-row :gutter="20">
+          <!-- <el-col :span="12">
+            <div class="target-input-wrapper">
+              <span class="required-mark">*</span>
+              <span class="label">分配对象类型:</span>
+              <el-select v-model="assignForm.targetType" placeholder="请选择分配对象类型" clearable style="flex: 1" @change="handleTargetTypeChange">
+                <el-option label="SRM供应商" value="srm" />
+                <el-option label="BP伙伴商" value="bp" />
+              </el-select>
+            </div>
+          </el-col> -->
+          <el-col :span="12">
+            <div class="target-input-wrapper">
+              <span class="required-mark">*</span>
+              <span class="label">供应商: </span>
+              <el-select v-model="assignForm.targetId" :placeholder="'请选择伙伴商'" clearable filterable style="flex: 1">
+                <el-option v-for="item in partnerList" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+            </div>
+          </el-col>
+        </el-row>
+      </div>
+
+      <!-- 商品列表 -->
+      <div class="product-list-section">
+        <el-table
+          ref="assignProductTableRef"
+          :data="assignForm.productList"
+          border
+          style="width: 100%"
+          max-height="800"
+          @selection-change="handleAssignProductSelectionChange"
+        >
+          <el-table-column type="selection" width="55" align="center" />
+          <el-table-column label="序号" width="80" align="center">
+            <template #default="scope">{{ scope.$index + 1 }}</template>
+          </el-table-column>
+          <el-table-column label="商品图片" width="100" align="center">
+            <template #default="scope">
+              <el-image
+                v-if="scope.row.productImage"
+                :src="scope.row.productImage"
+                style="width: 60px; height: 60px"
+                fit="cover"
+                :preview-src-list="[scope.row.productImage]"
+              />
+              <span v-else style="color: #999">暂无图片</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="商品编号" prop="productNo" width="140" align="center" />
+          <el-table-column label="商品名称" prop="productName" min-width="200" show-overflow-tooltip />
+          <el-table-column label="分配数量" width="150" align="center" prop="orderQuantity">
+            <!-- <template #default="scope">
+              <el-input-number v-model="scope.row.assignQuantity" :min="1" :max="scope.row.orderQuantity" :controls="false" style="width: 100%" />
+            </template> -->
+          </el-table-column>
+          <el-table-column label="单价" prop="orderPrice" width="120" align="center" />
+          <el-table-column label="小计" width="120" align="center">
+            <template #default="scope">{{ (scope.row.orderPrice * scope.row.orderQuantity).toFixed(2) }}</template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </div>
+
+    <template #footer>
+      <div class="drawer-footer">
+        <el-button @click="assignDialog.visible = false">取 消</el-button>
+        <el-button :loading="buttonLoading" type="primary" @click="submitAssign">确定分配</el-button>
+      </div>
+    </template>
+  </el-drawer>
+</template>
+
+<script setup name="SplitAssignDialog" lang="ts">
+import { getOrderMain } from '@/api/order/orderMain';
+import { listOrderAssignment } from '@/api/order/orderAssignmentLog';
+// import { listInfo } from '@/api/supplier/info';
+import { addOrderSplitAssign, addOrderAssignment } from '@/api/order/orderAssignmentLog';
+import { OrderSplitAssignForm, OrderProductAssignRule, OrderAssignmentForm } from '@/api/order/orderAssignmentLog/types';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { sys_platform_code, order_assignment_status } = toRefs<any>(proxy?.useDict('sys_platform_code', 'order_assignment_status'));
+
+const emit = defineEmits(['success']);
+
+const buttonLoading = ref(false);
+const pendingTableRef = ref();
+const assignProductTableRef = ref();
+const selectedPendingProducts = ref<any[]>([]);
+const selectedAssignProducts = ref<any[]>([]); // 分配对话框中选中的商品
+
+// 订单分配详情抽屉
+const drawer = reactive<DialogOption>({
+  visible: false,
+  title: '订单分配'
+});
+
+// 分配对话框
+const assignDialog = reactive({
+  visible: false
+});
+
+const orderInfo = ref<any>({
+  orderNo: '',
+  id: undefined,
+  platformCode: '',
+  customerName: '',
+  businessStaff: '',
+  productQuantity: 0,
+  pendingCount: 0,
+  assignedCount: 0,
+  productTotal: 0,
+  assigned: 0,
+  unassigned: 0
+});
+
+// 分配表单
+const assignForm = reactive({
+  targetType: 'bp', // 分配对象类型:bp-伙伴商
+  targetId: '', // 分配目标ID
+  productList: [] as any[]
+});
+
+// 供应商列表
+const supplierList = ref<any[]>([]);
+// 缓存的供应商列表(打开抽屉时预先加载)
+const cachedPartnerList = ref<any[]>([]);
+
+// 伙伴商列表
+const partnerList = ref<any[]>([]);
+
+// 标签页
+const activeTab = ref('pending');
+
+// 待分配商品列表
+const pendingProducts = ref<any[]>([]);
+
+// 已分配商品列表
+const assignedProducts = ref<any[]>([]);
+
+// 分配记录
+const assignRecords = ref<any[]>([]);
+
+/** 打开订单分配详情抽屉 */
+const open = async (orderId: string | number) => {
+  reset();
+  drawer.visible = true;
+
+  try {
+    // 获取订单详情
+    const res = await getOrderMain(orderId);
+    orderInfo.value = {
+      orderNo: res.data.orderNo,
+      id: res.data.id,
+      platformCode: res.data.platformCode,
+      customerName: res.data.customerName || '--',
+      businessStaff: res.data.businessStaff || '--',
+      productQuantity: res.data.productQuantity || 0,
+
+      productTotal: res.data.productTotal || 0,
+      assigned: res.data.assigned || 0,
+      unassigned: res.data.unassigned || 0
+    };
+
+    // 加载订单商品列表
+    if (res.data.orderProductList && res.data.orderProductList.length > 0) {
+      const productList = res.data.orderProductList.map((item: any) => ({
+        ...item,
+        itemId: item.id,
+        assignQuantity: item.orderQuantity
+      }));
+
+      // 待分配/已分配商品(按 assignmentStatus 过滤:0-待分配,1-已分配)
+      pendingProducts.value = productList.filter((item: any) => item.assignmentStatus === '0');
+      assignedProducts.value = productList.filter((item: any) => item.assignmentStatus === '1');
+    }
+
+    // 加载分配记录
+    await loadAssignRecords(orderId);
+
+    // 预加载伙伴商数据以加快后续操作响应
+    loadrPartnerData();
+  } catch (error) {
+    proxy?.$modal.msgError('获取订单信息失败');
+    drawer.visible = false;
+  }
+};
+
+/** 预加载伙伴商数据 */
+const loadrPartnerData = async () => {
+  if (cachedPartnerList.value.length > 0) return;
+  try {
+    // const res: any = await listInfo({ pageNum: 1, pageSize: 1000 });
+    const res: any = null; // TODO: 替换为实际的伙伴商列表接口
+    const list = res.rows || res.data || [];
+    cachedPartnerList.value = list.map((item: any) => ({
+      ...item,
+      id: item.id,
+      name: item.partnerName
+    }));
+    partnerList.value = cachedPartnerList.value;
+  } catch (error) {
+    console.error('获取伙伴商列表失败', error);
+  }
+};
+
+/** 加载分配记录 */
+const loadAssignRecords = async (orderId: string | number) => {
+  try {
+    const res = await listOrderAssignment({
+      orderId: orderId,
+      pageNum: 1,
+      pageSize: 100
+    });
+    assignRecords.value = res.rows || [];
+  } catch (error) {
+    console.error('获取分配记录失败:', error);
+    assignRecords.value = [];
+  }
+};
+
+/** 表单重置 */
+const reset = () => {
+  assignForm.targetType = '';
+  assignForm.targetId = '';
+  assignForm.productList = [];
+  selectedPendingProducts.value = [];
+  selectedAssignProducts.value = [];
+  pendingProducts.value = [];
+  assignedProducts.value = [];
+  assignRecords.value = [];
+  activeTab.value = 'pending';
+  orderInfo.value = {
+    orderNo: '',
+    id: undefined,
+    platformCode: '',
+    customerName: '',
+    businessStaff: '',
+    productQuantity: 0,
+    pendingCount: 0,
+    assignedCount: 0,
+    productTotal: 0,
+    assigned: 0,
+    unassigned: 0
+  };
+};
+
+/** 关闭抽屉前的回调 */
+const handleDrawerClose = (done: () => void) => {
+  if (buttonLoading.value) {
+    return;
+  }
+  done();
+  reset();
+};
+
+/** 待分配商品选择变化 */
+const handlePendingSelectionChange = (selection: any[]) => {
+  selectedPendingProducts.value = selection;
+};
+
+/** 分配对话框中商品选择变化 */
+const handleAssignProductSelectionChange = (selection: any[]) => {
+  selectedAssignProducts.value = selection;
+};
+
+/** 批量分配 */
+const handleBatchAssign = () => {
+  // 验证是否选择了商品
+  if (selectedPendingProducts.value.length === 0) {
+    proxy?.$modal.msgWarning('请至少选择一个商品进行分配');
+    return;
+  }
+  // 打开分配对话框
+  assignForm.productList = [...selectedPendingProducts.value];
+  assignDialog.visible = true;
+
+  // 等待对话框渲染后,默认全选所有商品
+  nextTick(() => {
+    assignForm.productList.forEach((row) => {
+      assignProductTableRef.value?.toggleRowSelection(row, true);
+    });
+  });
+};
+
+/** 分配单个商品 */
+const handleAssignProduct = (row: any) => {
+  // 打开分配对话框,只包含当前商品
+  assignForm.productList = [row];
+  assignDialog.visible = true;
+
+  // 等待对话框渲染后,默认选中该商品
+  nextTick(() => {
+    assignProductTableRef.value?.toggleRowSelection(row, true);
+  });
+};
+
+/** 转分配 */
+const handleReassign = (row: any) => {
+  proxy?.$modal.confirm('确认要转分配该商品吗?').then(() => {
+    // 打开分配对话框
+    assignForm.productList = [row];
+    assignDialog.visible = true;
+
+    // 等待对话框渲染后,默认选中该商品
+    nextTick(() => {
+      assignProductTableRef.value?.toggleRowSelection(row, true);
+    });
+  });
+};
+
+/** 提交分配 */
+const submitAssign = async () => {
+  // 验证是否选择了商品
+  if (selectedAssignProducts.value.length === 0) {
+    proxy?.$modal.msgWarning('请至少勾选一个商品进行分配');
+    return;
+  }
+
+  // 验证分配对象类型
+  if (!assignForm.targetType) {
+    proxy?.$modal.msgWarning('请选择分配对象类型');
+    return;
+  }
+
+  // 验证分配目标
+  if (!assignForm.targetId) {
+    proxy?.$modal.msgWarning(`请选择${assignForm.targetType === 'srm' ? '供应商' : '伙伴商'}`);
+    return;
+  }
+
+  buttonLoading.value = true;
+  try {
+    // 组装提交数据,只提交勾选的商品
+    const submitData: OrderSplitAssignForm = {
+      orderId: orderInfo.value.id, // 父订单ID
+      itemRules: selectedAssignProducts.value.map(
+        (product): OrderProductAssignRule => ({
+          itemId: product.itemId, // 商品行ID
+          assigneeId: assignForm.targetId, // 供应商ID 或 伙伴商ID
+          assigneeType: assignForm.targetType // "srm" 或 "bp"
+        })
+      ),
+      remark: '' // 分配备注(可选)
+    };
+
+    // 调用拆单分配接口
+    await addOrderSplitAssign(submitData);
+    proxy?.$modal.msgSuccess('分配成功');
+    assignDialog.visible = false;
+
+    // 清空选中状态
+    selectedAssignProducts.value = [];
+
+    // 刷新抽屉数据
+    await open(orderInfo.value.id);
+    emit('success');
+  } catch (error) {
+    console.error('分配失败:', error);
+    proxy?.$modal.msgError('分配失败');
+  } finally {
+    buttonLoading.value = false;
+  }
+};
+
+// /** 分配对象类型变化 */
+// const handleTargetTypeChange = () => {
+//   // 切换类型时清空已选择的目标
+//   assignForm.targetId = '';
+
+//   if (assignForm.targetType === 'srm') {
+//     supplierList.value = cachedPartnerList.value;
+//   } else {
+//     // 处理伙伴商等其他情况(目前留空或使用别的缓存)
+//   }
+// };
+
+defineExpose({
+  open
+});
+</script>
+
+<style scoped lang="scss">
+.drawer-header {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+
+  .order-title {
+    font-size: 16px;
+    font-weight: 600;
+    color: #303133;
+  }
+}
+
+.drawer-content {
+  padding: 0 20px 20px;
+  height: calc(100% - 60px);
+  overflow-y: auto;
+}
+
+.assign-drawer-content {
+  padding: 0 20px 20px;
+  height: calc(100% - 80px);
+  overflow-y: auto;
+}
+
+.assign-target-section {
+  margin-bottom: 20px;
+
+  .target-input-wrapper {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+
+    .required-mark {
+      color: #f56c6c;
+      font-size: 14px;
+    }
+
+    .label {
+      font-size: 14px;
+      color: #606266;
+      white-space: nowrap;
+    }
+  }
+
+  .or-divider {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 14px;
+    color: #909399;
+  }
+}
+
+.product-list-section {
+  margin-top: 20px;
+}
+
+.drawer-footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: 10px;
+  padding: 10px 20px;
+  border-top: 1px solid #e4e7ed;
+}
+
+.detail-header {
+  padding: 15px 20px;
+  background-color: #f5f7fa;
+  border-radius: 4px;
+  margin-bottom: 20px;
+
+  .info-item {
+    display: flex;
+    flex-direction: column;
+    gap: 5px;
+
+    .label {
+      font-size: 12px;
+      color: #909399;
+    }
+
+    .value {
+      font-size: 14px;
+      color: #303133;
+      font-weight: 500;
+    }
+  }
+}
+
+.detail-tabs {
+  .tab-actions {
+    margin-bottom: 15px;
+  }
+}
+
+:deep(.el-alert__title) {
+  font-size: 13px;
+}
+</style>