|
|
@@ -1,202 +1,323 @@
|
|
|
<template>
|
|
|
- <el-drawer v-model="drawer.visible" :title="drawer.title" size="70%" direction="rtl" :before-close="handleClose">
|
|
|
- <div class="drawer-content">
|
|
|
- <!-- 分配方式选择 -->
|
|
|
- <div class="assign-type-selector">
|
|
|
- <el-radio-group v-model="assignType" @change="handleAssignTypeChange">
|
|
|
- <el-radio-button value="whole">整单分配</el-radio-button>
|
|
|
- <el-radio-button value="split">拆单分配</el-radio-button>
|
|
|
- </el-radio-group>
|
|
|
+ <!-- 订单分配详情抽屉 -->
|
|
|
+ <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>
|
|
|
|
|
|
- <el-divider />
|
|
|
-
|
|
|
- <!-- 整单分配表单 -->
|
|
|
- <div v-show="assignType === 'whole'" class="whole-assign-form">
|
|
|
- <el-form ref="wholeAssignFormRef" :model="wholeForm" :rules="wholeRules" label-width="120px">
|
|
|
- <el-form-item label="订单编号" v-if="orderInfo.orderNo">
|
|
|
- <span class="form-value">{{ orderInfo.orderNo }}</span>
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <el-form-item label="当前平台" v-if="orderInfo.platformCode">
|
|
|
- <dict-tag :options="sys_platform_code" :value="orderInfo.platformCode" />
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <el-form-item label="分配后平台" prop="platformAfter">
|
|
|
- <el-select v-model="wholeForm.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>
|
|
|
+ <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-divider content-position="left">分配原因</el-divider>
|
|
|
+ <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="400"
|
|
|
+ @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="400">
|
|
|
+ <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="150" align="center" fixed="right">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-button link type="warning" size="small" @click="handleReassign(scope.row)">转分配</el-button>
|
|
|
+ <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="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="assignTime" align="center" />
|
|
|
+ <el-table-column label="分配人" prop="assignedBy" align="center" />
|
|
|
+ <el-table-column label="分配目标" prop="assignTarget" align="center" />
|
|
|
+ <el-table-column label="商品数量" prop="productCount" align="center" />
|
|
|
+ <el-table-column label="备注" prop="remark" min-width="200" show-overflow-tooltip />
|
|
|
+ </el-table>
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ </div>
|
|
|
+ </el-drawer>
|
|
|
|
|
|
- <el-form-item label-width="0" prop="remark">
|
|
|
- <el-input v-model="wholeForm.remark" type="textarea" :rows="6" placeholder="请输入分配原因(选填)" maxlength="500" show-word-limit />
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
+ <!-- 分配对话框 -->
|
|
|
+ <el-dialog v-model="assignDialog.visible" title="分配" width="60%" :close-on-click-modal="false">
|
|
|
+ <div class="assign-dialog-content">
|
|
|
+ <!-- 提示信息 -->
|
|
|
+ <!-- <el-alert
|
|
|
+ title="说明:根据是自营还是伙伴商去进行展示分配给供应商还是伙伴商"
|
|
|
+ type="warning"
|
|
|
+ :closable="false"
|
|
|
+ show-icon
|
|
|
+ style="margin-bottom: 20px"
|
|
|
+ /> -->
|
|
|
+
|
|
|
+ <!-- 分配目标选择 -->
|
|
|
+ <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">{{ assignForm.targetType === 'srm' ? '供应商:' : '伙伴商:' }}</span>
|
|
|
+ <el-select
|
|
|
+ v-model="assignForm.targetId"
|
|
|
+ :placeholder="assignForm.targetType === 'srm' ? '请选择供应商' : '请选择伙伴商'"
|
|
|
+ clearable
|
|
|
+ filterable
|
|
|
+ style="flex: 1"
|
|
|
+ :disabled="!assignForm.targetType"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in assignForm.targetType === 'srm' ? supplierList : partnerList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.id"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 拆单分配表单 -->
|
|
|
- <div v-show="assignType === 'split'" class="split-assign-form">
|
|
|
- <el-form ref="splitAssignFormRef" :model="form" label-width="100px">
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="订单编号">
|
|
|
- <span class="form-value">{{ orderInfo.orderNo }}</span>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="12">
|
|
|
- <el-form-item label="当前平台">
|
|
|
- <dict-tag :options="sys_platform_code" :value="orderInfo.platformCode" />
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
-
|
|
|
- <el-divider content-position="left">商品列表</el-divider>
|
|
|
-
|
|
|
- <el-form-item label-width="0">
|
|
|
- <el-table :data="form.productList" border style="width: 100%" max-height="500">
|
|
|
- <el-table-column type="index" label="序号" width="60" align="center" />
|
|
|
- <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" show-overflow-tooltip />
|
|
|
- <el-table-column label="数量" prop="orderQuantity" width="100" align="center" />
|
|
|
- <el-table-column label="单价" prop="orderPrice" width="120" align="center">
|
|
|
- <template #default="scope">
|
|
|
- <span>¥{{ scope.row.orderPrice }}</span>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="小计" width="120" align="center">
|
|
|
- <template #default="scope">
|
|
|
- <span>¥{{ (scope.row.orderPrice * scope.row.orderQuantity).toFixed(2) }}</span>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="分配平台" align="center" fixed="right">
|
|
|
- <template #default="scope">
|
|
|
- <el-select v-model="scope.row.targetPlatform" placeholder="请选择平台" style="width: 100%">
|
|
|
- <el-option v-for="dict in sys_platform_code" :key="dict.value" :label="dict.label" :value="dict.value" />
|
|
|
- </el-select>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- </el-table>
|
|
|
- </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="4" placeholder="请输入分配原因(选填)" maxlength="500" show-word-limit />
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
+ <!-- 商品列表 -->
|
|
|
+ <div class="product-list-section">
|
|
|
+ <el-table
|
|
|
+ ref="assignProductTableRef"
|
|
|
+ :data="assignForm.productList"
|
|
|
+ border
|
|
|
+ style="width: 100%"
|
|
|
+ max-height="400"
|
|
|
+ @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="cancel">取 消</el-button>
|
|
|
- <el-button v-if="assignType === 'whole'" :loading="buttonLoading" type="primary" @click="submitWholeForm">确 定</el-button>
|
|
|
- <el-button v-else :loading="buttonLoading" type="primary" @click="submitSplitForm">确 定</el-button>
|
|
|
- </div>
|
|
|
+ <el-button @click="assignDialog.visible = false">取 消</el-button>
|
|
|
+ <el-button :loading="buttonLoading" type="primary" @click="submitAssign">确定分配</el-button>
|
|
|
</template>
|
|
|
- </el-drawer>
|
|
|
+ </el-dialog>
|
|
|
</template>
|
|
|
|
|
|
-<style scoped lang="scss">
|
|
|
-.drawer-content {
|
|
|
- padding: 0 20px 20px;
|
|
|
- height: calc(100% - 60px);
|
|
|
- overflow-y: auto;
|
|
|
-}
|
|
|
-
|
|
|
-.assign-type-selector {
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- padding: 10px 0;
|
|
|
-
|
|
|
- :deep(.el-radio-button__inner) {
|
|
|
- padding: 12px 30px;
|
|
|
- font-size: 14px;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.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;
|
|
|
-}
|
|
|
-
|
|
|
-:deep(.el-divider__text) {
|
|
|
- font-weight: 600;
|
|
|
- font-size: 14px;
|
|
|
-}
|
|
|
-</style>
|
|
|
-
|
|
|
<script setup name="SplitAssignDialog" lang="ts">
|
|
|
import { getOrderMain } from '@/api/order/orderMain';
|
|
|
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 } = toRefs<any>(proxy?.useDict('sys_platform_code'));
|
|
|
+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 splitAssignFormRef = ref<ElFormInstance>();
|
|
|
-const wholeAssignFormRef = ref<ElFormInstance>();
|
|
|
-
|
|
|
-// 分配类型:whole-整单分配,split-拆单分配
|
|
|
-const assignType = ref<'whole' | 'split'>('whole');
|
|
|
+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: ''
|
|
|
+ platformCode: '',
|
|
|
+ customerName: '',
|
|
|
+ businessStaff: '',
|
|
|
+ productQuantity: 0,
|
|
|
+ pendingCount: 0,
|
|
|
+ assignedCount: 0,
|
|
|
+ productTotal: 0,
|
|
|
+ assigned: 0,
|
|
|
+ unassigned: 0
|
|
|
});
|
|
|
|
|
|
-// 拆单分配表单
|
|
|
-const form = reactive({
|
|
|
- productList: [] as any[],
|
|
|
- remark: ''
|
|
|
+// 分配表单
|
|
|
+const assignForm = reactive({
|
|
|
+ targetType: '', // 分配对象类型:srm-供应商,bp-伙伴商
|
|
|
+ targetId: '', // 分配目标ID
|
|
|
+ productList: [] as any[]
|
|
|
});
|
|
|
|
|
|
-// 整单分配表单
|
|
|
-const wholeForm = reactive({
|
|
|
- platformAfter: '',
|
|
|
- remark: ''
|
|
|
-});
|
|
|
+// 供应商列表
|
|
|
+const supplierList = ref<any[]>([
|
|
|
+ { id: '1', name: '供应商A' },
|
|
|
+ { id: '2', name: '供应商B' },
|
|
|
+ { id: '3', name: '供应商C' }
|
|
|
+]);
|
|
|
|
|
|
-const wholeRules = {
|
|
|
- platformAfter: [{ required: true, message: '分配后平台不能为空', trigger: 'blur' }]
|
|
|
-};
|
|
|
+// 伙伴商列表
|
|
|
+const partnerList = ref<any[]>([
|
|
|
+ { id: '1', name: '伙伴商A' },
|
|
|
+ { id: '2', name: '伙伴商B' },
|
|
|
+ { id: '3', name: '伙伴商C' }
|
|
|
+]);
|
|
|
|
|
|
-/** 打开对话框 */
|
|
|
+// 标签页
|
|
|
+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;
|
|
|
- assignType.value = 'whole'; // 默认显示整单分配
|
|
|
|
|
|
try {
|
|
|
// 获取订单详情
|
|
|
@@ -204,56 +325,73 @@ const open = async (orderId: string | number) => {
|
|
|
orderInfo.value = {
|
|
|
orderNo: res.data.orderNo,
|
|
|
id: res.data.id,
|
|
|
- platformCode: res.data.platformCode
|
|
|
+ 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) {
|
|
|
- form.productList = res.data.orderProductList.map((item: any) => ({
|
|
|
+ const productList = res.data.orderProductList.map((item: any) => ({
|
|
|
...item,
|
|
|
- itemId: item.id, // 商品行ID
|
|
|
- targetPlatform: '' // 初始化分配平台为空
|
|
|
+ itemId: item.id,
|
|
|
+ assignQuantity: item.orderQuantity
|
|
|
}));
|
|
|
+
|
|
|
+ // 模拟待分配和已分配商品
|
|
|
+ pendingProducts.value = productList.slice(0, 8);
|
|
|
+ assignedProducts.value = productList.slice(8);
|
|
|
}
|
|
|
+
|
|
|
+ // 模拟分配记录
|
|
|
+ assignRecords.value = [
|
|
|
+ {
|
|
|
+ assignTime: '2024-01-14 10:30:00',
|
|
|
+ assignedBy: '张三',
|
|
|
+ assignTarget: '供应商A',
|
|
|
+ productCount: 2,
|
|
|
+ remark: '紧急订单优先处理'
|
|
|
+ }
|
|
|
+ ];
|
|
|
} catch (error) {
|
|
|
proxy?.$modal.msgError('获取订单信息失败');
|
|
|
drawer.visible = false;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-/** 分配类型切换 */
|
|
|
-const handleAssignTypeChange = (value: 'whole' | 'split') => {
|
|
|
- // 切换时可以做一些清理工作
|
|
|
- if (value === 'split' && form.productList.length === 0) {
|
|
|
- proxy?.$modal.msgWarning('该订单没有商品信息,无法进行拆单分配');
|
|
|
- assignType.value = 'whole';
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
/** 表单重置 */
|
|
|
const reset = () => {
|
|
|
- form.productList = [];
|
|
|
- form.remark = '';
|
|
|
- wholeForm.platformAfter = '';
|
|
|
- wholeForm.remark = '';
|
|
|
- assignType.value = 'whole';
|
|
|
+ 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: ''
|
|
|
+ platformCode: '',
|
|
|
+ customerName: '',
|
|
|
+ businessStaff: '',
|
|
|
+ productQuantity: 0,
|
|
|
+ pendingCount: 0,
|
|
|
+ assignedCount: 0,
|
|
|
+ productTotal: 0,
|
|
|
+ assigned: 0,
|
|
|
+ unassigned: 0
|
|
|
};
|
|
|
- splitAssignFormRef.value?.resetFields();
|
|
|
- wholeAssignFormRef.value?.resetFields();
|
|
|
-};
|
|
|
-
|
|
|
-/** 取消按钮 */
|
|
|
-const cancel = () => {
|
|
|
- drawer.visible = false;
|
|
|
- reset();
|
|
|
};
|
|
|
|
|
|
-/** 关闭前的回调 */
|
|
|
-const handleClose = (done: () => void) => {
|
|
|
+/** 关闭抽屉前的回调 */
|
|
|
+const handleDrawerClose = (done: () => void) => {
|
|
|
if (buttonLoading.value) {
|
|
|
return;
|
|
|
}
|
|
|
@@ -261,68 +399,213 @@ const handleClose = (done: () => void) => {
|
|
|
reset();
|
|
|
};
|
|
|
|
|
|
-/** 提交整单分配 */
|
|
|
-const submitWholeForm = async () => {
|
|
|
- wholeAssignFormRef.value?.validate(async (valid: boolean) => {
|
|
|
- if (valid) {
|
|
|
- buttonLoading.value = true;
|
|
|
- try {
|
|
|
- const submitData: OrderAssignmentForm = {
|
|
|
- orderIds: orderInfo.value.id,
|
|
|
- platformAfter: wholeForm.platformAfter,
|
|
|
- assignType: '0', // 整单分配
|
|
|
- remark: wholeForm.remark
|
|
|
- };
|
|
|
-
|
|
|
- await addOrderAssignment(submitData);
|
|
|
- proxy?.$modal.msgSuccess('整单分配成功');
|
|
|
- drawer.visible = false;
|
|
|
- emit('success');
|
|
|
- } catch (error) {
|
|
|
- proxy?.$modal.msgError('整单分配失败');
|
|
|
- } finally {
|
|
|
- buttonLoading.value = false;
|
|
|
- }
|
|
|
- }
|
|
|
+/** 待分配商品选择变化 */
|
|
|
+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 submitSplitForm = async () => {
|
|
|
- // 验证每个商品都选择了平台
|
|
|
- const unassignedProducts = form.productList.filter((item) => !item.targetPlatform);
|
|
|
- if (unassignedProducts.length > 0) {
|
|
|
- proxy?.$modal.msgWarning('请为所有商品选择分配平台');
|
|
|
+/** 分配单个商品 */
|
|
|
+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,
|
|
|
- itemRules: form.productList.map(
|
|
|
+ orderId: orderInfo.value.id, // 父订单ID
|
|
|
+ itemRules: selectedAssignProducts.value.map(
|
|
|
(product): OrderProductAssignRule => ({
|
|
|
- itemId: product.itemId,
|
|
|
- targetPlatform: product.targetPlatform
|
|
|
+ itemId: product.itemId, // 商品行ID
|
|
|
+ assigneeId: assignForm.targetId, // 供应商ID 或 伙伴商ID
|
|
|
+ assigneeType: assignForm.targetType // "srm" 或 "bp"
|
|
|
})
|
|
|
),
|
|
|
- remark: form.remark
|
|
|
+ remark: '' // 分配备注(可选)
|
|
|
};
|
|
|
|
|
|
// 调用拆单分配接口
|
|
|
await addOrderSplitAssign(submitData);
|
|
|
- proxy?.$modal.msgSuccess('拆单分配成功');
|
|
|
- drawer.visible = false;
|
|
|
+ proxy?.$modal.msgSuccess('分配成功');
|
|
|
+ assignDialog.visible = false;
|
|
|
+
|
|
|
+ // 清空选中状态
|
|
|
+ selectedAssignProducts.value = [];
|
|
|
+
|
|
|
+ // 刷新抽屉数据
|
|
|
+ await open(orderInfo.value.id);
|
|
|
emit('success');
|
|
|
} catch (error) {
|
|
|
- proxy?.$modal.msgError('拆单分配失败');
|
|
|
+ console.error('分配失败:', error);
|
|
|
+ proxy?.$modal.msgError('分配失败');
|
|
|
} finally {
|
|
|
buttonLoading.value = false;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+/** 分配对象类型变化 */
|
|
|
+const handleTargetTypeChange = () => {
|
|
|
+ // 切换类型时清空已选择的目标
|
|
|
+ assignForm.targetId = '';
|
|
|
+};
|
|
|
+
|
|
|
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-dialog-content {
|
|
|
+ padding: 0 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.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;
|
|
|
+}
|
|
|
+
|
|
|
+.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>
|