|
|
@@ -0,0 +1,904 @@
|
|
|
+<template>
|
|
|
+ <div class="p-2">
|
|
|
+ <!-- 订单流程 -->
|
|
|
+ <el-card shadow="never" class="mb-2">
|
|
|
+ <div class="order-steps">
|
|
|
+ <span class="step-title">A10订单流程</span>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 订单基本信息 -->
|
|
|
+ <el-card shadow="never" class="mb-2">
|
|
|
+ <template #header>
|
|
|
+ <div class="card-header">
|
|
|
+ <span>订单基本信息</span>
|
|
|
+ <span> 订单日期:<el-date-picker v-model="form.orderTime" type="date" value-format="YYYY-MM-DD" /></span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <el-form ref="orderMainFormRef" :model="form" :rules="rules" label-width="100px">
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <!-- 第一行 -->
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="归属公司" prop="companyId">
|
|
|
+ <el-select v-model="form.companyId" placeholder="请选择" style="width: 100%" filterable>
|
|
|
+ <el-option v-for="company in companyList" :key="company.id" :label="company.companyName" :value="company.id" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="客户名称" prop="customerId">
|
|
|
+ <el-select
|
|
|
+ v-model="form.customerId"
|
|
|
+ placeholder="请选择客户"
|
|
|
+ style="width: 100%"
|
|
|
+ filterable
|
|
|
+ :disabled="!form.companyId"
|
|
|
+ :loading="customerLoading"
|
|
|
+ @change="handleCustomerChange"
|
|
|
+ >
|
|
|
+ <el-option v-for="customer in customerList" :key="customer.id" :label="customer.customerName" :value="customer.id" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <!-- 第二行 -->
|
|
|
+ <el-col :span="8"> </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="信用额度" prop="creditLimit">
|
|
|
+ <el-input v-model="form.creditLimit" placeholder="0" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="剩余额度">
|
|
|
+ <el-input value="0" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <!-- 第三行 -->
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="业务人员" prop="businessStaff">
|
|
|
+ <el-input v-model="form.businessStaff" placeholder="请选择" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="客服人员" prop="customerService">
|
|
|
+ <el-input v-model="form.customerService" placeholder="请选择" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="业务部门" prop="businessDept">
|
|
|
+ <el-input v-model="form.businessDept" placeholder="请选择" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <!-- 第四行 -->
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="发票类型" prop="invoiceType">
|
|
|
+ <el-select v-model="form.invoiceType" placeholder="请选择" style="width: 100%" disabled>
|
|
|
+ <el-option label="普通发票" value="1" />
|
|
|
+ <el-option label="增值税发票" value="2" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="支付方式" prop="payType">
|
|
|
+ <el-select v-model="form.payType" placeholder="请选择" style="width: 100%">
|
|
|
+ <el-option v-for="dict in pay_method" :key="dict.value" :label="dict.label" :value="dict.value" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="预收货日" prop="expectedDeliveryTime">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="form.expectedDeliveryTime"
|
|
|
+ type="date"
|
|
|
+ placeholder="请选择"
|
|
|
+ value-format="YYYY-MM-DD"
|
|
|
+ style="width: 100%"
|
|
|
+ :disabled-date="disabledDeliveryDate"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <!-- 第五行 -->
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="发货仓库" prop="warehouseId">
|
|
|
+ <el-select v-model="form.warehouseId" placeholder="请选择" style="width: 100%" filterable>
|
|
|
+ <el-option
|
|
|
+ v-for="warehouse in warehouseList"
|
|
|
+ :key="warehouse.id"
|
|
|
+ :label="`${warehouse.warehouseCode},${warehouse.warehouseName}`"
|
|
|
+ :value="warehouse.id"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="费用类型" prop="expenseType">
|
|
|
+ <el-select v-model="form.expenseType" placeholder="请选择" style="width: 100%">
|
|
|
+ <el-option v-for="dict in fee_type" :key="dict.value" :label="dict.label" :value="dict.value" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="下单部门" prop="userDept">
|
|
|
+ <el-select v-model="form.userDept" placeholder="请选择" style="width: 100%" :disabled="!form.customerId">
|
|
|
+ <el-option v-for="dept in customerDeptList" :key="dept.id" :label="dept.deptName" :value="dept.id" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <!-- 第六行 -->
|
|
|
+ <el-col :span="24">
|
|
|
+ <el-form-item label="采购事由" prop="purchaseReason">
|
|
|
+ <el-input v-model="form.purchaseReason" placeholder="请输入采购事由" type="textarea" :rows="2" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <!-- 第七行 -->
|
|
|
+ <el-col :span="24">
|
|
|
+ <el-form-item label="订单备注" prop="remark">
|
|
|
+ <el-input v-model="form.remark" placeholder="请输入订单备注" type="textarea" :rows="2" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <!-- 第八行 -->
|
|
|
+ <el-col :span="24">
|
|
|
+ <el-form-item label="附件" prop="attachmentPath">
|
|
|
+ <el-upload class="upload-demo" action="#" :auto-upload="false">
|
|
|
+ <el-button type="primary" plain>上传附件</el-button>
|
|
|
+ </el-upload>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-form>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 收货地址 -->
|
|
|
+ <el-card shadow="never" class="mb-2">
|
|
|
+ <template #header>
|
|
|
+ <div class="card-header">
|
|
|
+ <span>收货地址</span>
|
|
|
+ <div>
|
|
|
+ <el-button type="primary" plain @click="addAddress">添加收货地址</el-button>
|
|
|
+ <el-button type="primary" plain @click="chooseAddress">选择收货地址</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <el-form :model="form" label-width="100px">
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="收货人姓名">
|
|
|
+ <el-input v-model="addressDisplay.receiverName" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="手机号码">
|
|
|
+ <el-input v-model="addressDisplay.receiverPhone" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="详细地址">
|
|
|
+ <el-input v-model="addressDisplay.receiverProvince" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item>
|
|
|
+ <el-input v-model="addressDisplay.addressDetail" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-form>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 商品明细 -->
|
|
|
+ <el-card shadow="never" class="mb-2">
|
|
|
+ <template #header>
|
|
|
+ <div class="card-header">
|
|
|
+ <span>商品明细</span>
|
|
|
+ <div>
|
|
|
+ <el-button type="primary" plain @click="handleAddProduct">添加商品</el-button>
|
|
|
+ <el-button type="primary" plain>导入</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <el-table :data="productList" border style="width: 100%">
|
|
|
+ <el-table-column prop="productCode" label="产品编码" width="130" align="center" />
|
|
|
+ <el-table-column label="商品图片" align="center">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-image v-if="scope.row.productImage" :src="scope.row.productImage" style="width: 60px; height: 60px" fit="cover" />
|
|
|
+ <span v-else>暂无图片</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="productName" label="产品信息" align="center" />
|
|
|
+ <el-table-column prop="taxRate" label="税率" align="center">
|
|
|
+ <template #default="scope"> 增值税{{ scope.row.taxRate }}% </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="unit" label="单位" align="center" />
|
|
|
+ <el-table-column prop="price" label="单价" align="center" />
|
|
|
+ <el-table-column prop="certificatePrice" label="最低售价" align="center" />
|
|
|
+ <el-table-column prop="minOrderQuantity" label="起订量" align="center" />
|
|
|
+ <el-table-column prop="unitPrice" label="含税单价" align="center">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-input-number
|
|
|
+ v-model="scope.row.unitPrice"
|
|
|
+ :min="scope.row.certificatePrice"
|
|
|
+ :precision="2"
|
|
|
+ :controls="false"
|
|
|
+ @blur="handleUnitPriceChange(scope.$index)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="quantity" label="数量" align="center">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-input-number
|
|
|
+ v-model="scope.row.quantity"
|
|
|
+ :min="scope.row.minOrderQuantity || 1"
|
|
|
+ :precision="0"
|
|
|
+ :controls="false"
|
|
|
+ @change="handleQuantityChange(scope.$index)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="amount" label="小计" align="center" />
|
|
|
+ <el-table-column label="操作" align="center">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-button link type="danger" size="small" @click="handleDeleteProduct(scope.$index)">删除</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <div class="mt-2 text-right">
|
|
|
+ <span>商品数:{{ totalQuantity }} 合计金额:¥ {{ totalAmount.toFixed(2) }}</span>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 信息汇总 -->
|
|
|
+ <el-card shadow="never" class="mb-2">
|
|
|
+ <template #header>
|
|
|
+ <div class="card-header">
|
|
|
+ <span>信息汇总</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <el-table :data="summaryData" border style="width: 100%">
|
|
|
+ <el-table-column prop="quantity" label="商品数量" align="center" />
|
|
|
+ <el-table-column prop="shippingFee" label="运费" align="center" />
|
|
|
+ <el-table-column prop="totalAmount" label="订单总金额" align="center" />
|
|
|
+ <el-table-column prop="payableAmount" label="应付款金额" align="center" />
|
|
|
+ </el-table>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 底部按钮 -->
|
|
|
+ <div class="text-center mt-4">
|
|
|
+ <el-button @click="cancel">取消</el-button>
|
|
|
+ <el-button type="primary" :loading="buttonLoading" @click="submitForm">确定</el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 选择地址对话框 -->
|
|
|
+ <ChooseAddress v-model="showAddressDialog" :customer-id="form.customerId" @confirm="handleAddressConfirm" />
|
|
|
+
|
|
|
+ <!-- 添加地址对话框 -->
|
|
|
+ <AddAddress v-model="showAddAddressDialog" :customer-id="form.customerId" @success="handleAddAddressSuccess" />
|
|
|
+
|
|
|
+ <!-- 选择商品对话框 -->
|
|
|
+ <ChooseProduct v-model="showProductDialog" @confirm="handleProductConfirm" />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup name="OrderMain" lang="ts">
|
|
|
+import { listOrderMain, getOrderMain, delOrderMain, addOrderMain, updateOrderMain } from '@/api/order/orderMain';
|
|
|
+import { OrderMainVO, OrderMainQuery, OrderMainForm } from '@/api/order/orderMain/types';
|
|
|
+import { listCompany } from '@/api/company/company';
|
|
|
+import { listCustomerDept } from '@/api/customer/customerFile/customerDept';
|
|
|
+import { CustomerDeptVO } from '@/api/customer/customerFile/customerDept/types';
|
|
|
+import { CompanyVO } from '@/api/company/company/types';
|
|
|
+import { listWarehouse, getWarehouse } from '@/api/company/warehouse';
|
|
|
+import { WarehouseVO, WarehouseQuery } from '@/api/company/warehouse/types';
|
|
|
+import { listCustomerInfo, getCustomerInfo } from '@/api/customer/customerFile/customerInfo';
|
|
|
+import { CustomerInfoVO, CustomerInfoQuery, CustomerInfoForm } from '@/api/customer/customerFile/customerInfo/types';
|
|
|
+import { ShippingAddressVO } from '@/api/customer/customerFile/shippingAddress/types';
|
|
|
+import ChooseAddress from './components/chooseAddress.vue';
|
|
|
+import AddAddress from './components/addressDialog.vue';
|
|
|
+import ChooseProduct from './components/chooseProduct.vue';
|
|
|
+import { BaseVO } from '@/api/product/base/types';
|
|
|
+
|
|
|
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
+const { order_status, fee_type, pay_method } = toRefs<any>(proxy?.useDict('order_status', 'fee_type', 'pay_method'));
|
|
|
+import { regionData } from 'element-china-area-data';
|
|
|
+const buttonLoading = ref(false);
|
|
|
+const loading = ref(true);
|
|
|
+const ids = ref<Array<string | number>>([]);
|
|
|
+const single = ref(true);
|
|
|
+const multiple = ref(true);
|
|
|
+const router = useRouter();
|
|
|
+const queryFormRef = ref<ElFormInstance>();
|
|
|
+const orderMainFormRef = ref<ElFormInstance>();
|
|
|
+
|
|
|
+const dialog = reactive<DialogOption>({
|
|
|
+ visible: false,
|
|
|
+ title: ''
|
|
|
+});
|
|
|
+
|
|
|
+// 商品列表数据
|
|
|
+const productList = ref([]);
|
|
|
+
|
|
|
+// 地址选择对话框
|
|
|
+const showAddressDialog = ref(false);
|
|
|
+
|
|
|
+// 添加地址对话框
|
|
|
+const showAddAddressDialog = ref(false);
|
|
|
+
|
|
|
+// 选择商品对话框
|
|
|
+const showProductDialog = ref(false);
|
|
|
+
|
|
|
+// 计算商品总数(所有商品的数量之和)
|
|
|
+const totalQuantity = computed(() => {
|
|
|
+ return productList.value.reduce((sum, item) => {
|
|
|
+ return sum + (Number(item.quantity) || 0);
|
|
|
+ }, 0);
|
|
|
+});
|
|
|
+
|
|
|
+// 计算商品总金额(所有商品的小计之和)
|
|
|
+const totalAmount = computed(() => {
|
|
|
+ return productList.value.reduce((sum, item) => {
|
|
|
+ return sum + (Number(item.amount) || 0);
|
|
|
+ }, 0);
|
|
|
+});
|
|
|
+
|
|
|
+// 计算应付款金额(订单总金额 + 运费)
|
|
|
+const payableAmount = computed(() => {
|
|
|
+ const shipping = Number(form.value.shippingFee) || 0;
|
|
|
+ return totalAmount.value + shipping;
|
|
|
+});
|
|
|
+
|
|
|
+// 汇总数据(用于表格显示)
|
|
|
+const summaryData = computed(() => {
|
|
|
+ return [
|
|
|
+ {
|
|
|
+ quantity: totalQuantity.value,
|
|
|
+ shippingFee: `¥${(Number(form.value.shippingFee) || 0).toFixed(2)}`,
|
|
|
+ totalAmount: `¥${totalAmount.value.toFixed(2)}`,
|
|
|
+ payableAmount: `¥${payableAmount.value.toFixed(2)}`
|
|
|
+ }
|
|
|
+ ];
|
|
|
+});
|
|
|
+
|
|
|
+// 公司列表
|
|
|
+const companyList = ref<CompanyVO[]>([]);
|
|
|
+
|
|
|
+// 仓库列表
|
|
|
+const warehouseList = ref<WarehouseVO[]>([]);
|
|
|
+
|
|
|
+// 客户列表
|
|
|
+const customerList = ref<CustomerInfoVO[]>([]);
|
|
|
+const customerLoading = ref(false);
|
|
|
+
|
|
|
+// 客户部门列表
|
|
|
+const customerDeptList = ref<CustomerDeptVO[]>([]);
|
|
|
+
|
|
|
+// 收货地址显示信息(仅用于显示,不提交)
|
|
|
+const addressDisplay = ref({
|
|
|
+ receiverName: '',
|
|
|
+ receiverPhone: '',
|
|
|
+ receiverProvince: '',
|
|
|
+ addressDetail: ''
|
|
|
+});
|
|
|
+
|
|
|
+// 禁用预收货日期的函数(只能选择订单日期之后的日期)
|
|
|
+const disabledDeliveryDate = (time: Date) => {
|
|
|
+ if (!form.value.orderTime) {
|
|
|
+ // 如果没有选择订单日期,禁用今天之前的日期
|
|
|
+ return time.getTime() < Date.now() - 8.64e7;
|
|
|
+ }
|
|
|
+ // 将订单日期转换为时间戳进行比较
|
|
|
+ const orderDate = new Date(form.value.orderTime);
|
|
|
+ orderDate.setHours(0, 0, 0, 0);
|
|
|
+ const compareTime = time.getTime();
|
|
|
+ const orderTime = orderDate.getTime();
|
|
|
+ // 禁用订单日期及之前的日期
|
|
|
+ return compareTime <= orderTime;
|
|
|
+};
|
|
|
+
|
|
|
+const initFormData: OrderMainForm = {
|
|
|
+ id: undefined,
|
|
|
+ orderNo: undefined,
|
|
|
+ shipmentNo: undefined,
|
|
|
+ subOrderNo: undefined,
|
|
|
+ companyId: undefined,
|
|
|
+ customerId: 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: '1',
|
|
|
+ orderStatus: undefined,
|
|
|
+ orderTime: new Date().toISOString().split('T')[0], // 默认今天,格式:YYYY-MM-DD
|
|
|
+ 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,
|
|
|
+ customerNo: undefined,
|
|
|
+ userNo: undefined,
|
|
|
+ status: undefined,
|
|
|
+ remark: undefined,
|
|
|
+ customerSalesInfoVo: {
|
|
|
+ salesPerson: '',
|
|
|
+ serviceStaff: '',
|
|
|
+ belongingDepartment: ''
|
|
|
+ }
|
|
|
+};
|
|
|
+const data = reactive<PageData<OrderMainForm, OrderMainQuery>>({
|
|
|
+ form: { ...initFormData },
|
|
|
+ queryParams: {
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ orderNo: undefined,
|
|
|
+ shipmentNo: undefined,
|
|
|
+ subOrderNo: undefined,
|
|
|
+ companyId: undefined,
|
|
|
+ customerId: undefined,
|
|
|
+ userId: undefined,
|
|
|
+ shippingAddressId: undefined,
|
|
|
+
|
|
|
+ params: {}
|
|
|
+ },
|
|
|
+ rules: {
|
|
|
+ companyId: [{ required: true, message: '归属公司不能为空', trigger: 'blur' }],
|
|
|
+ customerId: [{ required: true, message: '客户名称不能为空', trigger: 'blur' }],
|
|
|
+ payType: [{ required: true, message: '支付方式不能为空', trigger: 'change' }],
|
|
|
+ warehouseId: [{ required: true, message: '发货仓库不能为空', trigger: 'change' }],
|
|
|
+ expectedDeliveryTime: [{ required: true, message: '预计送达时间不能为空', trigger: 'blur' }],
|
|
|
+ shippingFee: [{ required: true, message: '运费不能为空', trigger: 'blur' }],
|
|
|
+ confirmTime: [{ required: true, message: '确认时间不能为空', trigger: 'blur' }],
|
|
|
+ shippingTime: [{ required: true, message: '发货时间不能为空', trigger: 'blur' }],
|
|
|
+ expenseType: [{ required: true, message: '费用类型不能为空', trigger: 'change' }],
|
|
|
+ purchaseReason: [{ required: true, message: '采购事由不能为空', trigger: 'change' }]
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+const { queryParams, form, rules } = toRefs(data);
|
|
|
+
|
|
|
+// 监听公司变化,加载该公司的客户列表
|
|
|
+watch(
|
|
|
+ () => form.value.companyId,
|
|
|
+ (newVal, oldVal) => {
|
|
|
+ if (newVal !== oldVal) {
|
|
|
+ // 清空客户选择和相关信息
|
|
|
+ form.value.customerId = undefined;
|
|
|
+ customerList.value = [];
|
|
|
+ customerDeptList.value = [];
|
|
|
+ form.value.creditLimit = undefined;
|
|
|
+ form.value.shippingAddressId = undefined;
|
|
|
+ form.value.userDept = undefined;
|
|
|
+ form.value.businessStaff = undefined;
|
|
|
+ form.value.customerService = undefined;
|
|
|
+ form.value.businessDept = undefined;
|
|
|
+ // 清空收货地址显示信息
|
|
|
+ addressDisplay.value = {
|
|
|
+ receiverName: '',
|
|
|
+ receiverPhone: '',
|
|
|
+ addressDetail: ''
|
|
|
+ } as any;
|
|
|
+
|
|
|
+ // 如果选择了公司,加载该公司的客户列表
|
|
|
+ if (newVal) {
|
|
|
+ loadCustomerListByCompany(newVal);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+/** 取消按钮 */
|
|
|
+const cancel = () => {
|
|
|
+ reset();
|
|
|
+ dialog.visible = false;
|
|
|
+};
|
|
|
+
|
|
|
+/** 表单重置 */
|
|
|
+const reset = () => {
|
|
|
+ form.value = { ...initFormData };
|
|
|
+ orderMainFormRef.value?.resetFields();
|
|
|
+};
|
|
|
+
|
|
|
+/** 搜索按钮操作 */
|
|
|
+const handleQuery = () => {
|
|
|
+ queryParams.value.pageNum = 1;
|
|
|
+};
|
|
|
+
|
|
|
+/** 重置按钮操作 */
|
|
|
+const resetQuery = () => {
|
|
|
+ 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 handleAdd = () => {
|
|
|
+ reset();
|
|
|
+ dialog.visible = true;
|
|
|
+ dialog.title = '添加订单主信息';
|
|
|
+};
|
|
|
+
|
|
|
+/** 修改按钮操作 */
|
|
|
+const handleUpdate = async (row?: OrderMainVO) => {
|
|
|
+ reset();
|
|
|
+ const _id = row?.id || ids.value[0];
|
|
|
+ const res = await getOrderMain(_id);
|
|
|
+ Object.assign(form.value, res.data);
|
|
|
+ dialog.visible = true;
|
|
|
+ dialog.title = '修改订单主信息';
|
|
|
+};
|
|
|
+
|
|
|
+/** 提交按钮 */
|
|
|
+const submitForm = () => {
|
|
|
+ orderMainFormRef.value?.validate(async (valid: boolean) => {
|
|
|
+ if (valid) {
|
|
|
+ // 验证是否有商品
|
|
|
+ if (!productList.value || productList.value.length === 0) {
|
|
|
+ proxy?.$modal.msgWarning('请至少添加一个商品');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ buttonLoading.value = true;
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 组装订单商品明细数据
|
|
|
+ const orderProductList = productList.value.map((product) => ({
|
|
|
+ productNo: product.productCode, // 产品编号
|
|
|
+ productName: product.productName, // 产品名称
|
|
|
+ productUnit: product.unit, // 产品单位
|
|
|
+ productImage: product.productImage, // 产品图片
|
|
|
+ platformPrice: product.price, // 平台价格(单价)
|
|
|
+ minOrderQuantity: product.minOrderQuantity, // 最小起订量
|
|
|
+ orderPrice: product.unitPrice, // 订单单价(含税单价)
|
|
|
+ orderQuantity: product.quantity, // 订购数量
|
|
|
+ subtotal: product.amount, // 行小计金额
|
|
|
+ minSellingPrice: product.certificatePrice, // 最低销售价
|
|
|
+ preDeliveryDate: form.value.expectedDeliveryTime, // 预计送达时间
|
|
|
+ status: '0' // 状态(0正常)
|
|
|
+ }));
|
|
|
+
|
|
|
+ // 组装提交数据
|
|
|
+ const submitData = {
|
|
|
+ ...form.value,
|
|
|
+ productQuantity: totalQuantity.value, // 商品总数量
|
|
|
+ totalAmount: totalAmount.value, // 订单总金额
|
|
|
+ payableAmount: payableAmount.value, // 应付金额
|
|
|
+ shippingFee: Number(form.value.shippingFee) || 0, // 运费
|
|
|
+ orderProductBos: orderProductList // 订单商品明细列表
|
|
|
+ };
|
|
|
+
|
|
|
+ if (form.value.id) {
|
|
|
+ await updateOrderMain(submitData);
|
|
|
+ } else {
|
|
|
+ await addOrderMain(submitData);
|
|
|
+ }
|
|
|
+
|
|
|
+ proxy?.$modal.msgSuccess('操作成功');
|
|
|
+ // 可以在这里添加跳转逻辑,比如返回列表页
|
|
|
+ router.push('/order-manage/order-list');
|
|
|
+ } catch (error) {
|
|
|
+ console.error('提交订单失败:', error);
|
|
|
+ proxy?.$modal.msgError('提交订单失败,请检查数据后重试');
|
|
|
+ } finally {
|
|
|
+ buttonLoading.value = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+/** 删除按钮操作 */
|
|
|
+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('删除成功');
|
|
|
+};
|
|
|
+
|
|
|
+/** 导出按钮操作 */
|
|
|
+const handleExport = () => {
|
|
|
+ proxy?.download(
|
|
|
+ 'system/orderMain/export',
|
|
|
+ {
|
|
|
+ ...queryParams.value
|
|
|
+ },
|
|
|
+ `orderMain_${new Date().getTime()}.xlsx`
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+/** 选择收货地址 */
|
|
|
+const chooseAddress = () => {
|
|
|
+ if (!form.value.customerId) {
|
|
|
+ proxy?.$modal.msgWarning('请先选择客户');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ showAddressDialog.value = true;
|
|
|
+};
|
|
|
+
|
|
|
+/** 添加收货地址 */
|
|
|
+const addAddress = () => {
|
|
|
+ if (!form.value.customerId) {
|
|
|
+ proxy?.$modal.msgWarning('请先选择客户');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ showAddAddressDialog.value = true;
|
|
|
+};
|
|
|
+
|
|
|
+/** 添加地址成功回调 */
|
|
|
+const handleAddAddressSuccess = () => {
|
|
|
+ proxy?.$modal.msgSuccess('添加地址成功');
|
|
|
+};
|
|
|
+
|
|
|
+/** 打开添加商品对话框 */
|
|
|
+const handleAddProduct = () => {
|
|
|
+ showProductDialog.value = true;
|
|
|
+};
|
|
|
+
|
|
|
+/** 确认选择商品 */
|
|
|
+const handleProductConfirm = (product: BaseVO) => {
|
|
|
+ // 将商品添加到商品列表,按照新的字段映射
|
|
|
+ const newProduct = {
|
|
|
+ productCode: product.productNo, // 产品编码
|
|
|
+ productImage: product.productImage, // 商品图片
|
|
|
+ productName: product.itemName, // 产品信息
|
|
|
+ taxRate: product.taxRate || 0, // 税率
|
|
|
+ unit: product.unitId, // 单位
|
|
|
+ price: product.standardPrice || 0, // 单价(使用平档价)
|
|
|
+ certificatePrice: product.certificatePrice || 0, // 最低售价
|
|
|
+ minOrderQuantity: product.minOrderQuantity || 1, // 起订量
|
|
|
+ unitPrice: product.certificatePrice || 0, // 含税单价(默认使用最低售价)
|
|
|
+ quantity: product.minOrderQuantity || 1, // 数量(默认使用起订量)
|
|
|
+ amount: ((product.certificatePrice || 0) * (product.minOrderQuantity || 1)).toFixed(2) // 小计 = 含税单价 × 数量
|
|
|
+ };
|
|
|
+ productList.value.push(newProduct);
|
|
|
+ proxy?.$modal.msgSuccess('添加商品成功');
|
|
|
+};
|
|
|
+
|
|
|
+/** 删除商品 */
|
|
|
+const handleDeleteProduct = (index: number) => {
|
|
|
+ productList.value.splice(index, 1);
|
|
|
+ proxy?.$modal.msgSuccess('删除成功');
|
|
|
+};
|
|
|
+
|
|
|
+/** 含税单价变化时验证最低售价 */
|
|
|
+const handleUnitPriceChange = (index: number) => {
|
|
|
+ const product = productList.value[index];
|
|
|
+ if (product) {
|
|
|
+ // 如果含税单价小于最低售价,自动设置为最低售价
|
|
|
+ if (Number(product.unitPrice) < Number(product.certificatePrice)) {
|
|
|
+ product.unitPrice = product.certificatePrice;
|
|
|
+ }
|
|
|
+ // 重新计算小计:小计 = 数量 × 含税单价
|
|
|
+ product.amount = (Number(product.quantity) * Number(product.unitPrice)).toFixed(2);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/** 数量变化时重新计算金额 */
|
|
|
+const handleQuantityChange = (index: number) => {
|
|
|
+ const product = productList.value[index];
|
|
|
+ if (product) {
|
|
|
+ // 小计 = 数量 × 含税单价
|
|
|
+ product.amount = (Number(product.quantity) * Number(product.unitPrice)).toFixed(2);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/** 确认选择地址 */
|
|
|
+const handleAddressConfirm = (address: ShippingAddressVO) => {
|
|
|
+ form.value.shippingAddressId = address.id;
|
|
|
+ // 更新地址显示信息
|
|
|
+ addressDisplay.value = {
|
|
|
+ receiverName: address.consignee,
|
|
|
+ receiverPhone: address.phone,
|
|
|
+ receiverProvince: address.provincialCityCountry,
|
|
|
+ addressDetail: address.address
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+/** 获取公司列表 */
|
|
|
+const getCompanyList = async () => {
|
|
|
+ try {
|
|
|
+ const res = await listCompany({
|
|
|
+ isShow: '0',
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 1000
|
|
|
+ });
|
|
|
+ companyList.value = res.rows || [];
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取公司列表失败:', error);
|
|
|
+ companyList.value = [];
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/** 获取仓库列表 */
|
|
|
+const getWarehouseList = async () => {
|
|
|
+ try {
|
|
|
+ const res = await listWarehouse({
|
|
|
+ isShow: '0',
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 1000
|
|
|
+ });
|
|
|
+ warehouseList.value = res.rows || [];
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取仓库列表失败:', error);
|
|
|
+ warehouseList.value = [];
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/** 根据公司ID加载客户列表 */
|
|
|
+const loadCustomerListByCompany = async (companyId: string | number) => {
|
|
|
+ customerLoading.value = true;
|
|
|
+ try {
|
|
|
+ const params: CustomerInfoQuery = {
|
|
|
+ belongCompanyId: companyId,
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 1000 // 加载所有客户
|
|
|
+ };
|
|
|
+ const res = await listCustomerInfo(params);
|
|
|
+ customerList.value = res.rows || [];
|
|
|
+ } catch (error) {
|
|
|
+ console.error('加载客户列表失败:', error);
|
|
|
+ customerList.value = [];
|
|
|
+ } finally {
|
|
|
+ customerLoading.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/** 客户变化时获取客户详情 */
|
|
|
+const handleCustomerChange = async (customerId: string | number) => {
|
|
|
+ if (!customerId) {
|
|
|
+ // 清空客户相关信息
|
|
|
+ form.value.creditLimit = undefined;
|
|
|
+ form.value.shippingAddressId = undefined;
|
|
|
+ form.value.userDept = undefined;
|
|
|
+ form.value.businessStaff = undefined;
|
|
|
+ form.value.customerService = undefined;
|
|
|
+ form.value.businessDept = undefined;
|
|
|
+ customerDeptList.value = [];
|
|
|
+ // 清空收货地址显示信息
|
|
|
+ addressDisplay.value = {
|
|
|
+ receiverName: '',
|
|
|
+ receiverPhone: '',
|
|
|
+ addressDetail: ''
|
|
|
+ } as any;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 获取客户详情
|
|
|
+ const res = await getCustomerInfo(customerId);
|
|
|
+ const customerInfo = res.data;
|
|
|
+
|
|
|
+ // 填充客户相关信息
|
|
|
+ if (customerInfo.customerSalesInfoVo) {
|
|
|
+ const salesInfo = customerInfo.customerSalesInfoVo;
|
|
|
+ form.value.creditLimit = salesInfo.remainingQuota || salesInfo.creditAmount;
|
|
|
+ // 填充业务人员、客服人员、业务部门
|
|
|
+ form.value.businessStaff = salesInfo.salesPerson;
|
|
|
+ form.value.customerService = salesInfo.serviceStaff;
|
|
|
+ form.value.businessDept = salesInfo.belongingDepartment;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取客户部门列表
|
|
|
+ await getCustomerDeptList(customerId);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取客户详情失败:', error);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/** 获取客户部门列表 */
|
|
|
+const getCustomerDeptList = async (customerId: string | number) => {
|
|
|
+ try {
|
|
|
+ const res = await listCustomerDept({
|
|
|
+ customerId: customerId
|
|
|
+ });
|
|
|
+ customerDeptList.value = res.rows || [];
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取客户部门列表失败:', error);
|
|
|
+ customerDeptList.value = [];
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ getCompanyList();
|
|
|
+ getWarehouseList();
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.order-steps {
|
|
|
+ padding: 10px 0;
|
|
|
+
|
|
|
+ .step-title {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #303133;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.card-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+
|
|
|
+.mb-2 {
|
|
|
+ margin-bottom: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+.mt-2 {
|
|
|
+ margin-top: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+.mt-4 {
|
|
|
+ margin-top: 32px;
|
|
|
+}
|
|
|
+
|
|
|
+.text-right {
|
|
|
+ text-align: right;
|
|
|
+}
|
|
|
+
|
|
|
+.text-center {
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.el-form-item__label) {
|
|
|
+ font-weight: normal;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.el-card__header) {
|
|
|
+ padding: 12px 20px;
|
|
|
+ background-color: #f5f7fa;
|
|
|
+}
|
|
|
+</style>
|