Browse Source

Merge branch 'hurx'

hurx 1 day ago
parent
commit
4cc2bcc116

+ 12 - 0
src/api/customer/customerFile/customerInfo/types.ts

@@ -138,6 +138,12 @@ export interface CustomerInfoVO {
    */
   remark: string;
 
+  salesPersonId?: string | number;
+
+  serviceStaffId?: string | number;
+
+  belongingDepartmentId?: string | number;
+
   salesPersonName: string;
 
   serviceStaffName: string;
@@ -296,6 +302,12 @@ export interface CustomerInfoForm extends BaseEntity {
    */
   remark?: string;
 
+  salesPersonId?: string | number;
+
+  serviceStaffId?: string | number;
+
+  belongingDepartmentId?: string | number;
+
   /**
    * 工商信息
    */

+ 18 - 2
src/views/customer/customerFile/customerInfo/edit.vue

@@ -16,11 +16,18 @@
         <el-menu-item index="contactInfo">联系人</el-menu-item>
         <el-menu-item index="shippingAddress">收货地址</el-menu-item>
         <el-menu-item index="contractManagement">合同管理</el-menu-item>
+        <el-menu-item index="erpSaleInfo">ERP销售信息</el-menu-item>
         <!-- <el-menu-item index="procurementProfile">采购画像</el-menu-item>
         <el-menu-item index="operationLog">日志管理</el-menu-item> -->
       </el-menu>
       <!-- 动态组件显示区域 -->
-      <component :is="currentComponent" :customer-id="customerId" :customer-no="customerNo" :customer-name="customerName" />
+      <component
+        :is="currentComponent"
+        :customer-id="customerId"
+        :customer-no="customerNo"
+        :customer-name="customerName"
+        :is-view-mode="isViewMode"
+      />
     </el-card>
   </div>
 </template>
@@ -33,6 +40,7 @@ const activeMenu = ref('baseInfo');
 const customerId = ref<string>('');
 const customerNo = ref<string>('');
 const customerName = ref<string>('');
+const isViewMode = ref(false); // 查看模式标志
 
 // 异步加载子组件
 const BaseInfo = defineAsyncComponent(() => import('@/views/customer/customerFile/customerInfo/overview/baseInfo.vue'));
@@ -40,6 +48,7 @@ const OrgStructure = defineAsyncComponent(() => import('@/views/customer/custome
 const ContactInfo = defineAsyncComponent(() => import('@/views/customer/customerFile/customerInfo/overview/contactInfo.vue'));
 const ShippingAddress = defineAsyncComponent(() => import('@/views/customer/customerFile/customerInfo/overview/shippingAddress.vue'));
 const ContractManagement = defineAsyncComponent(() => import('@/views/customer/customerFile/customerInfo/overview/contractManagement.vue'));
+const ErpSaleInfo = defineAsyncComponent(() => import('@/views/customer/customerFile/customerInfo/overview/erpSaleInfo.vue'));
 // const ProcurementProfile = defineAsyncComponent(() => import('@/views/customer/customerFile/customerInfo/overview/procurementProfile.vue'));
 // const OperationLog = defineAsyncComponent(() => import('@/views/customer/customerFile/customerInfo/overview/operationLog.vue'));
 
@@ -49,7 +58,8 @@ const componentMap: Record<string, any> = {
   orgStructure: OrgStructure,
   contactInfo: ContactInfo,
   shippingAddress: ShippingAddress,
-  contractManagement: ContractManagement
+  contractManagement: ContractManagement,
+  erpSaleInfo: ErpSaleInfo
   // procurementProfile: ProcurementProfile,
   // operationLog: OperationLog
 };
@@ -77,6 +87,12 @@ onMounted(async () => {
     activeMenu.value = tab as string;
     currentComponent.value = componentMap[tab as string];
   }
+
+  // 判断是否为查看模式
+  const status = route.query.status;
+  if (status === 'view') {
+    isViewMode.value = true;
+  }
 });
 
 // 加载客户编号

+ 10 - 1
src/views/customer/customerFile/customerInfo/index.vue

@@ -170,7 +170,7 @@
         </el-table-column>
         <el-table-column label="操作" align="center" width="150" fixed="right">
           <template #default="scope">
-            <el-button link type="primary" @click="handleUpdate(scope.row)" v-hasPermi="['customer:customerInfo:edit']">查看</el-button>
+            <el-button link type="primary" @click="handleView(scope.row)" v-hasPermi="['customer:customerInfo:edit']">查看</el-button>
             <el-button link type="primary" @click="handleUpdate(scope.row)" v-hasPermi="['customer:customerInfo:edit']">编辑</el-button>
             <el-button link type="primary" v-if="scope.row.status == '0'" @click="handleCheck(scope.row)" v-hasPermi="['customer:customerInfo:edit']"
               >审核</el-button
@@ -571,6 +571,15 @@ const handleAdd = () => {
   });
 };
 
+/** 查看按钮操作 */
+const handleView = async (row?: CustomerInfoVO) => {
+  const _id = row?.id || ids.value[0];
+  router.push({
+    path: '/customer/customer-overview',
+    query: { id: _id, status: 'view' }
+  });
+};
+
 /** 修改按钮操作 */
 const handleUpdate = async (row?: CustomerInfoVO) => {
   const _id = row?.id || ids.value[0];

+ 185 - 395
src/views/customer/customerFile/customerInfo/overview/baseInfo.vue

@@ -5,7 +5,7 @@
       <template #header>
         <div class="flex justify-between items-center">
           <span class="font-medium">企业基本信息 </span>
-          <el-button type="primary" style="float: right" @click="handleSave">保存</el-button>
+          <el-button v-if="!isViewMode" type="primary" style="float: right" @click="handleSave">保存</el-button>
           <!-- <span class="font-medium"
             >企业基本信息 / <span style="color: #ff0033">客户编号:{{ customerNumber }}</span></span
           > -->
@@ -15,19 +15,26 @@
         <el-row :gutter="20">
           <el-col :span="8">
             <el-form-item label="所属公司" prop="belongCompanyId">
-              <el-select v-model="form.belongCompanyId" placeholder="请选择所属公司" class="w-full" filterable @change="handCompanyChange">
+              <el-select
+                v-model="form.belongCompanyId"
+                placeholder="请选择所属公司"
+                class="w-full"
+                filterable
+                @change="handCompanyChange"
+                :disabled="isViewMode"
+              >
                 <el-option v-for="item in companyList" :key="item.id" :label="`${item.companyCode} , ${item.companyName}`" :value="item.id" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="客户名称" prop="customerName">
-              <el-input v-model="form.customerName" placeholder="请输入客户名称"> </el-input>
+              <el-input v-model="form.customerName" placeholder="请输入客户名称" :disabled="isViewMode"> </el-input>
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="工商名称" prop="businessCustomerName">
-              <el-input v-model="form.businessCustomerName" placeholder="请输入工商名称" @blur="selectBusinessBtn"> </el-input>
+              <el-input v-model="form.businessCustomerName" placeholder="请输入工商名称" @blur="selectBusinessBtn" :disabled="isViewMode"> </el-input>
             </el-form-item>
           </el-col>
         </el-row>
@@ -35,12 +42,12 @@
         <el-row :gutter="20">
           <el-col :span="8">
             <el-form-item label="企业简称" prop="shortName">
-              <el-input v-model="form.shortName" placeholder="请输入企业简称" />
+              <el-input v-model="form.shortName" placeholder="请输入企业简称" :disabled="isViewMode" />
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="开票类型" prop="invoiceTypeId">
-              <el-select v-model="form.invoiceTypeId" placeholder="请选择开票类型" class="w-full">
+              <el-select v-model="form.invoiceTypeId" placeholder="请选择开票类型" class="w-full" :disabled="isViewMode">
                 <el-option
                   v-for="item in invoiceTypeList"
                   :key="item.id"
@@ -52,7 +59,7 @@
           </el-col>
           <el-col :span="8">
             <el-form-item label="企业规模" prop="enterpriseScaleId">
-              <el-select v-model="form.enterpriseScaleId" placeholder="请选择企业规模" class="w-full" filterable>
+              <el-select v-model="form.enterpriseScaleId" placeholder="请选择企业规模" class="w-full" filterable :disabled="isViewMode">
                 <el-option
                   v-for="item in enterpriseScaleList"
                   :key="item.id"
@@ -67,14 +74,14 @@
         <el-row :gutter="20">
           <el-col :span="8">
             <el-form-item label="客户类别" prop="customerTypeId">
-              <el-select v-model="form.customerTypeId" placeholder="请选择客户类别" class="w-full" filterable>
+              <el-select v-model="form.customerTypeId" placeholder="请选择客户类别" class="w-full" filterable :disabled="isViewMode">
                 <el-option v-for="item in customerTypeList" :key="item.id" :label="`${item.typeCode} , ${item.typeName}`" :value="item.id" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="行业类别" prop="industryCategoryId">
-              <el-select v-model="form.industryCategoryId" placeholder="请选择行业类别" class="w-full" filterable>
+              <el-select v-model="form.industryCategoryId" placeholder="请选择行业类别" class="w-full" filterable :disabled="isViewMode">
                 <el-option
                   v-for="item in industryCategoryList"
                   :key="item.id"
@@ -86,7 +93,7 @@
           </el-col>
           <el-col :span="8">
             <el-form-item label="客户等级" prop="customerLevelId">
-              <el-select v-model="form.customerLevelId" placeholder="请选择客户等级" class="w-full" filterable>
+              <el-select v-model="form.customerLevelId" placeholder="请选择客户等级" class="w-full" filterable :disabled="isViewMode">
                 <el-option v-for="item in customerLevelList" :key="item.id" :label="`${item.levelCode} , ${item.levelName}`" :value="item.id" />
               </el-select>
             </el-form-item>
@@ -96,17 +103,17 @@
         <el-row :gutter="20">
           <el-col :span="8">
             <el-form-item label="固定电话" prop="landline">
-              <el-input v-model="form.landline" placeholder="请输入固定电话" />
+              <el-input v-model="form.landline" placeholder="请输入固定电话" :disabled="isViewMode" />
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="传真" prop="fax">
-              <el-input v-model="form.fax" placeholder="请输入传真" />
+              <el-input v-model="form.fax" placeholder="请输入传真" :disabled="isViewMode" />
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="网址" prop="url">
-              <el-input v-model="form.url" placeholder="请输入网址" />
+              <el-input v-model="form.url" placeholder="请输入网址" :disabled="isViewMode" />
             </el-form-item>
           </el-col>
         </el-row>
@@ -114,7 +121,7 @@
         <el-row :gutter="20">
           <el-col :span="8">
             <el-form-item label="邮政编码" prop="postCode">
-              <el-input v-model="form.postCode" placeholder="请输入邮政编码" />
+              <el-input v-model="form.postCode" placeholder="请输入邮政编码" :disabled="isViewMode" />
             </el-form-item>
           </el-col>
           <el-col :span="8">
@@ -126,6 +133,7 @@
                 class="w-full"
                 value-format="YYYY-MM-DD"
                 style="width: 100%"
+                :disabled="isViewMode"
               />
             </el-form-item>
           </el-col>
@@ -139,6 +147,7 @@
                 value-format="YYYY-MM-DD"
                 style="width: 100%"
                 :disabled-date="(time) => form.validityFromDate && time.getTime() < new Date(form.validityFromDate).getTime()"
+                :disabled="isViewMode"
               />
             </el-form-item>
           </el-col>
@@ -158,12 +167,13 @@
                 placeholder="请选择"
                 @change="handleChange"
                 style="width: 100%"
+                :disabled="isViewMode"
               ></el-cascader>
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label-width="0">
-              <el-input v-model="form.address" placeholder="请输入详细地址" />
+              <el-input v-model="form.address" placeholder="请输入详细地址" :disabled="isViewMode" />
             </el-form-item>
           </el-col>
         </el-row>
@@ -175,7 +185,6 @@
       <template #header>
         <div class="flex justify-between items-center">
           <span class="font-medium">工商信息</span>
-          <el-button type="primary" @click="handleUpdate">更新</el-button>
         </div>
       </template>
 
@@ -294,7 +303,7 @@
       <template #header>
         <div class="flex justify-between items-center">
           <span class="font-medium">企业开票信息</span>
-          <el-button type="primary" @click="handleAddInvoice">新增</el-button>
+          <el-button v-if="!isViewMode" type="primary" @click="handleAddInvoice">新增</el-button>
         </div>
       </template>
       <el-table :data="invoiceList" border>
@@ -306,7 +315,7 @@
         </el-table-column>
         <el-table-column label="开户行名称" align="center" prop="bankName" min-width="180" />
         <el-table-column label="银行账户" align="center" prop="bankAccount" min-width="180" />
-        <el-table-column label="操作" align="center" width="150" fixed="right">
+        <el-table-column v-if="!isViewMode" label="操作" align="center" width="150" fixed="right">
           <template #default="{ row, $index }">
             <el-button link type="primary" @click="handleEditInvoice(row, $index)">编辑</el-button>
             <el-button link type="danger" @click="removeInvoice(row)">删除</el-button>
@@ -314,27 +323,31 @@
         </el-table-column>
       </el-table>
     </el-card>
-
-    <!-- 销售信息 --改为 ERP数据-->
     <el-card shadow="never" class="mb-4">
       <template #header>
-        <div class="flex justify-between items-center">
-          <span class="font-medium">ERP销售信息</span>
-          <!-- <el-button type="primary" @click="handleSave">保存</el-button> -->
-        </div>
+        <el-row :gutter="10" class="mb8" type="flex" justify="space-between" align="middle">
+          <span style="font-size: 16px; font-weight: 500">销售信息</span>
+        </el-row>
       </template>
-      <el-form ref="salesFormRef" :model="salesForm" :rules="salesRules" label-width="140px">
+      <el-form ref="salesFormRef" :model="form" label-width="140px">
         <el-row :gutter="20">
           <el-col :span="8">
-            <el-form-item label="业务人员" prop="salesPersonId" required>
-              <el-select v-model="salesForm.salesPersonId" placeholder="请选择业务人员" class="w-full" filterable @change="handleSalesPersonChange">
+            <el-form-item label="业务人员" prop="salesPersonId">
+              <el-select
+                v-model="form.salesPersonId"
+                placeholder="请选择业务人员"
+                class="w-full"
+                filterable
+                @change="handleSalesPersonChange"
+                :disabled="isViewMode"
+              >
                 <el-option v-for="item in comStaffList" :key="item.staffId" :label="`${item.staffCode} , ${item.staffName}`" :value="item.staffId" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="8">
-            <el-form-item label="客服人员" prop="serviceStaffId" required>
-              <el-select v-model="salesForm.serviceStaffId" placeholder="请选择客服人员" class="w-full" filterable>
+            <el-form-item label="客服人员" prop="serviceStaffId">
+              <el-select v-model="form.serviceStaffId" placeholder="请选择客服人员" class="w-full" filterable :disabled="isViewMode">
                 <el-option v-for="item in comStaffList" :key="item.staffId" :label="`${item.staffCode} , ${item.staffName}`" :value="item.staffId" />
               </el-select>
             </el-form-item>
@@ -344,131 +357,8 @@
               <el-input v-model="deptName" placeholder="请选择所属部门" class="w-full" disabled />
             </el-form-item>
           </el-col>
-        </el-row>
-
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="信用等级" prop="creditManagementId">
-              <el-select v-model="salesForm.creditManagementId" placeholder="请选择信用等级" class="w-full" filterable>
-                <el-option
-                  v-for="item in creditLevelList"
-                  :key="item.id"
-                  :label="`${item.creditLevelNo} , ${item.creditLevelName}`"
-                  :value="item.id"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="信用额度" prop="creditAmount">
-              <el-input v-model="salesForm.creditAmount" :controls="false" class="w-full" placeholder="请输入信用额度" style="width: 100%" disabled />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="可用额度" prop="remainingQuota">
-              <el-input
-                v-model="salesForm.remainingQuota"
-                :controls="false"
-                class="w-full"
-                placeholder="请输入可用额度"
-                style="width: 100%"
-                disabled
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="订单审核" prop="orderAudit">
-              <el-select v-model="salesForm.orderAudit" placeholder="请选择" class="w-full" filterable>
-                <el-option v-for="dict in order_check_way" :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="creditPaymentPassword">
-              <el-input v-model="salesForm.creditPaymentPassword" type="password" placeholder="请输入支付密码" show-password />
-            </el-form-item>
-          </el-col>
-          <!-- <el-col :span="8">
-            <el-form-item label="收款条件" prop="accountPeriod">
-              <el-select v-model="salesForm.accountPeriod" placeholder="请选择收款条件" class="w-full" filterable>
-                <el-option v-for="item in settlementMethodList" :key="item.id" :label="item.settlementName" :value="item.id" />
-              </el-select>
-            </el-form-item>
-          </el-col> -->
-        </el-row>
-
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="结算方式" prop="settlementMethod">
-              <el-select v-model="salesForm.settlementMethod" placeholder="请选择结算方式" class="w-full" filterable>
-                <el-option v-for="item in settlementMethodList" :key="item.id" :label="item.settlementName" :value="item.id" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="客户来源" prop="payDays">
-              <el-select v-model="salesForm.customerSource" class="w-full" filterable>
-                <el-option v-for="dict in customer_source" :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="payDays">
-              <el-select v-model="salesForm.sellChannel" class="w-full" filterable>
-                <el-option v-for="dict in sell_channel" :key="dict.value" :label="dict.label" :value="dict.value" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="税码" prop="rateId">
-              <el-select v-model="salesForm.rateId" placeholder="税码" class="w-full" filterable>
-                <el-option v-for="item in taxrateList" :key="item.id" :label="item.taxrateNo" :value="item.id" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="交易币别" prop="dealCurrencyId">
-              <el-select v-model="salesForm.dealCurrencyId" placeholder="请选择交易币别" class="w-full" filterable>
-                <el-option v-for="item in currencyList" :key="item.id" :label="item.currencyName" :value="item.id" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="账款归属" prop="payDays">
-              <el-input v-model="form.customerNo" disabled />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="单价含税" prop="payDays">
-              <el-select v-model="salesForm.unitPrice" placeholder="单价含税" class="w-full" filterable>
-                <el-option v-for="item in unitPriceArr" :key="item.value" :label="item.label" :value="item.value" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="账款额度超限" prop="creditLimit">
-              <el-select v-model="salesForm.creditLimit" placeholder="请选择账款额度超限" class="w-full" filterable>
-                <el-option v-for="dict in erp_is_enabled" :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="creditTimeLimit">
-              <el-select v-model="salesForm.creditTimeLimit" placeholder="请选择账款超期" class="w-full" filterable>
-                <el-option v-for="dict in erp_is_enabled" :key="dict.value" :label="dict.label" :value="dict.value" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-      </el-form>
-    </el-card>
+        </el-row> </el-form
+    ></el-card>
 
     <!-- 添加/编辑开票信息对话框 -->
     <add-invoice-dialog v-model="invoiceDialogVisible" :edit-data="currentInvoice" @confirm="handleInvoiceConfirm" />
@@ -489,7 +379,6 @@
 import { getCustomerInfo, updateCustomerInfo } from '@/api/customer/customerFile/customerInfo';
 import type { CustomerInfoForm } from '@/api/customer/customerFile/customerInfo/types';
 import type { BusinessInfoForm } from '@/api/customer/customerFile/businessInfo/types';
-import type { SalesInfoForm } from '@/api/customer/customerFile/salesInfo/types';
 import type { InvoiceInfoForm } from '@/api/customer/customerFile/invoiceInfo/types';
 import { listInvoiceInfo, getInvoiceInfo, addInvoiceInfo, updateInvoiceInfo, delInvoiceInfo } from '@/api/customer/customerFile/invoiceInfo';
 import { listSettlementMethod } from '@/api/customer/settlementMethod';
@@ -536,6 +425,9 @@ const props = defineProps<{
 
 const route = useRoute();
 const router = useRouter();
+
+// 查看模式
+const isViewMode = computed(() => route.query.status === 'view');
 const unitPriceArr = ref([
   { label: '含税', value: 'True' },
   { label: '不含税', value: 'False' }
@@ -610,7 +502,10 @@ const form = reactive<CustomerInfoForm>({
   regCountyNo: '',
   provincialCityCounty: '',
   status: '0',
-  remark: ''
+  remark: '',
+  salesPersonId: undefined,
+  serviceStaffId: undefined,
+  belongingDepartmentId: undefined
 });
 
 // 工商信息(只读)
@@ -629,28 +524,6 @@ const businessInfo = reactive<BusinessInfoForm>({
   status: '0'
 });
 
-// 销售信息
-const salesForm = reactive<SalesInfoForm>({
-  salesPersonId: undefined,
-  serviceStaffId: undefined,
-  belongingDepartmentId: undefined,
-  creditManagementId: undefined,
-  creditAmount: undefined,
-  remainingQuota: undefined,
-  orderAudit: undefined,
-  creditPaymentPassword: '',
-  accountPeriod: '',
-  payDays: undefined,
-  customerSource: '1',
-  unitPrice: 'True',
-  sellChannel: '1',
-  creditLimit: '1',
-  creditTimeLimit: '1',
-  dealCurrencyId: undefined,
-  settlementMethod: undefined,
-  status: '0'
-});
-
 // 开票信息列表
 const invoiceList = ref<InvoiceInfoForm[]>([]);
 const invoiceDialogVisible = ref(false);
@@ -666,6 +539,105 @@ const uploadHeaders = ref({
   Authorization: 'Bearer ' + localStorage.getItem('token')
 });
 
+// 打开添加开票信息对话框
+const handleAddInvoice = () => {
+  currentInvoice.value = {};
+  currentInvoice.value.taxId = businessInfo.socialCreditCode;
+  currentInvoice.value.address = businessInfo.businessAddress;
+  currentInvoiceIndex.value = -1;
+  invoiceDialogVisible.value = true;
+};
+
+// 更新工商信息
+const handleUpdate = () => {
+  // 触发上传
+  uploadRef.value?.$el.querySelector('input[type="file"]')?.click();
+};
+
+// 上传前验证
+const beforeUpload = (file: File) => {
+  const isImage = file.type.startsWith('image/');
+  const isPDF = file.type === 'application/pdf';
+  const isLt10M = file.size / 1024 / 1024 < 10;
+
+  if (!isImage && !isPDF) {
+    ElMessage.error('只能上传图片或PDF文件!');
+    return false;
+  }
+  if (!isLt10M) {
+    ElMessage.error('文件大小不能超过 10MB!');
+    return false;
+  }
+  uploadLoading.value = true;
+  return true;
+};
+
+// 处理业务人员选择变化
+const handleSalesPersonChange = async (staffId: any) => {
+  // 根据选中的业务人员ID,找到对应的部门ID
+  const selectedStaff = comStaffList.value.find((staff) => staff.staffId === staffId);
+  if (selectedStaff && selectedStaff.deptId) {
+    // 确保 deptId 的类型一致
+    form.belongingDepartmentId = String(selectedStaff.deptId);
+
+    // 如果部门不在列表中,从API获取
+    const deptExists = comDeptList.value.find((d) => String(d.deptId) === String(selectedStaff.deptId));
+    if (!deptExists) {
+      try {
+        const res = await getDept(selectedStaff.deptId);
+        if (res.data) {
+          comDeptList.value.push(res.data as any);
+        }
+      } catch (error) {
+        console.error('获取部门信息失败:', error);
+      }
+    }
+  }
+};
+
+// 上传成功回调
+const handleUploadSuccess = (response: any) => {
+  uploadLoading.value = false;
+  if (response.code === 200) {
+    businessInfo.businessLicense = response.data.url || response.data.fileName;
+    ElMessage.success('上传成功');
+
+    // TODO: 这里可以调用OCR识别接口,自动填充工商信息
+    // 如果后端提供了OCR识别接口,可以在这里调用
+    // recognizeBusinessLicense(response.data.url);
+  } else {
+    ElMessage.error(response.msg || '上传失败');
+  }
+};
+
+// 上传失败回调
+const handleUploadError = () => {
+  uploadLoading.value = false;
+  ElMessage.error('上传失败,请重试');
+};
+
+// 预览营业执照
+const previewLicense = () => {
+  if (businessInfo.businessLicense) {
+    window.open(businessInfo.businessLicense, '_blank');
+  }
+};
+
+// 营业执照选择处理
+const handleBusinessLicenseSelected = (files: any[]) => {
+  if (files && files.length > 0) {
+    const file = files[0]; // 取第一个文件
+    if (file && (file.url || file.path)) {
+      businessInfo.businessLicense = file.url || file.path;
+      ElMessage.success('营业执照选择成功');
+    } else {
+      ElMessage.error('请选择有效的图片文件');
+    }
+  } else {
+    ElMessage.error('请选择有效的图片文件');
+  }
+};
+
 // 表单验证规则
 const rules = {
   belongCompanyId: [{ required: true, message: '请选择所属公司', trigger: 'change' }],
@@ -687,39 +659,8 @@ const rules = {
   industryCategoryId: [{ required: true, message: '请选择行业类别', trigger: 'change' }],
   customerLevelId: [{ required: true, message: '请选择客户等级', trigger: 'change' }],
   address: [{ required: true, message: '请输入详细地址', trigger: 'blur' }]
-};
-
-// 销售信息表单验证规则
-const salesRules = {
-  salesPersonId: [{ required: true, message: '请选择业务人员', trigger: 'change' }],
-  serviceStaffId: [{ required: true, message: '请选择客服人员', trigger: 'change' }]
-};
-
-// 加载币种列表
-const loadCurrencyList = async () => {
-  try {
-    const res = await listComCurrency({
-      isShow: '0',
-      pageNum: 1,
-      pageSize: 1000
-    });
-    currencyList.value = res.rows || [];
-  } catch (error) {
-    console.error('加载币种列表失败:', error);
-    currencyList.value = [];
-  }
-};
-
-// 加载税码列表
-const loadTaxrateList = async () => {
-  try {
-    const res = await listTaxrate({
-      isShow: '0',
-      pageNum: 1,
-      pageSize: 1000
-    });
-    taxrateList.value = res.rows || [];
-  } catch (error) {}
+  // salesPersonId: [{ required: true, message: '请选择业务人员', trigger: 'change' }],
+  // serviceStaffId: [{ required: true, message: '请选择客服人员', trigger: 'change' }]
 };
 
 // 初始化
@@ -735,8 +676,6 @@ onMounted(async () => {
   await loadCustomerTypeList();
   await loadComStaffList();
   await loadComDeptList();
-  await loadCurrencyList();
-  await loadTaxrateList();
 
   // 优先使用props传递的customerId,否则从路由获取
   const id = props.customerId || route.query.id;
@@ -881,7 +820,7 @@ const loadCustomerTypeList = async () => {
 const loadComStaffList = async () => {
   try {
     const query: any = {};
-    const res = await listErpStaff(query);
+    const res = await listComStaff(query);
     comStaffList.value = res.rows || [];
   } catch (error) {
     console.error('加载员工列表失败:', error);
@@ -891,7 +830,7 @@ const loadComStaffList = async () => {
 // 加载部门列表
 const loadComDeptList = async () => {
   try {
-    const res = await listErpDept();
+    const res = await listDept();
     // 处理可能的不同返回结构
     comDeptList.value = res.rows || res.data || [];
   } catch (error) {
@@ -940,26 +879,6 @@ const loadCustomerData = async (id: any) => {
       codeArr.value = [data.regProvincialNo, data.regCityNo, data.regCountyNo] as any;
     }
 
-    // 填充销售信息
-    if (data.customerSalesInfoVo) {
-      Object.assign(salesForm, data.customerSalesInfoVo);
-
-      // 如果有部门ID,且部门不在列表中,从API获取
-      if (salesForm.belongingDepartmentId) {
-        const deptExists = comDeptList.value.find((d) => String(d.deptId) === String(salesForm.belongingDepartmentId));
-        if (!deptExists) {
-          try {
-            const deptRes = await getErpDept(salesForm.belongingDepartmentId);
-            if (deptRes.data) {
-              comDeptList.value.push(deptRes.data);
-            }
-          } catch (error) {
-            console.error('获取部门信息失败:', error);
-          }
-        }
-      }
-    }
-
     // 填充开票信息列表
     loadInvoiceList(id);
   } catch (error) {
@@ -1000,37 +919,6 @@ const getCustomerLevelName = (id: string | number | undefined) => {
 // 部门名称(响应式)
 const deptName = ref('');
 
-// 监听部门ID变化,自动加载部门名称
-watch(
-  () => salesForm.belongingDepartmentId,
-  async (newDeptId) => {
-    if (!newDeptId) {
-      deptName.value = '';
-      return;
-    }
-
-    // 先从列表中查找
-    const dept = comDeptList.value.find((d) => String(d.deptId) === String(newDeptId));
-    if (dept) {
-      deptName.value = dept.deptName;
-      return;
-    }
-
-    // 如果列表中没有,从API获取
-    try {
-      const res = await getDept(newDeptId);
-      if (res.data) {
-        deptName.value = res.data.deptName;
-        comDeptList.value.push(res.data as any);
-      }
-    } catch (error) {
-      console.error('获取部门信息失败:', error);
-      deptName.value = String(newDeptId);
-    }
-  },
-  { immediate: true }
-);
-
 // 处理区域选择变化
 const handleChange = (val: string[]) => {
   // 保存编码
@@ -1065,105 +953,6 @@ const handleChange = (val: string[]) => {
   form.provincialCityCounty = names.join('/');
 };
 
-// 处理业务人员选择变化
-const handleSalesPersonChange = async (staffId: any) => {
-  // 根据选中的业务人员ID,找到对应的部门ID
-  const selectedStaff = comStaffList.value.find((staff) => staff.staffId === staffId);
-  if (selectedStaff && selectedStaff.deptId) {
-    // 确保 deptId 的类型一致
-    salesForm.belongingDepartmentId = String(selectedStaff.deptId);
-
-    // 如果部门不在列表中,从API获取
-    const deptExists = comDeptList.value.find((d) => String(d.deptId) === String(selectedStaff.deptId));
-    if (!deptExists) {
-      try {
-        const res = await getDept(selectedStaff.deptId);
-        if (res.data) {
-          comDeptList.value.push(res.data as any);
-        }
-      } catch (error) {
-        console.error('获取部门信息失败:', error);
-      }
-    }
-  }
-};
-
-// 打开添加开票信息对话框
-const handleAddInvoice = () => {
-  currentInvoice.value = {};
-  currentInvoice.value.taxId = businessInfo.socialCreditCode;
-  currentInvoice.value.address = businessInfo.businessAddress;
-  currentInvoiceIndex.value = -1;
-  invoiceDialogVisible.value = true;
-};
-
-//更新工商信息
-const handleUpdate = () => {
-  // 触发上传
-  uploadRef.value?.$el.querySelector('input[type="file"]')?.click();
-};
-
-// 上传前验证
-const beforeUpload = (file: File) => {
-  const isImage = file.type.startsWith('image/');
-  const isPDF = file.type === 'application/pdf';
-  const isLt10M = file.size / 1024 / 1024 < 10;
-
-  if (!isImage && !isPDF) {
-    ElMessage.error('只能上传图片或PDF文件!');
-    return false;
-  }
-  if (!isLt10M) {
-    ElMessage.error('文件大小不能超过 10MB!');
-    return false;
-  }
-  uploadLoading.value = true;
-  return true;
-};
-
-// 上传成功回调
-const handleUploadSuccess = (response: any) => {
-  uploadLoading.value = false;
-  if (response.code === 200) {
-    businessInfo.businessLicense = response.data.url || response.data.fileName;
-    ElMessage.success('上传成功');
-
-    // TODO: 这里可以调用OCR识别接口,自动填充工商信息
-    // 如果后端提供了OCR识别接口,可以在这里调用
-    // recognizeBusinessLicense(response.data.url);
-  } else {
-    ElMessage.error(response.msg || '上传失败');
-  }
-};
-
-// 上传失败回调
-const handleUploadError = () => {
-  uploadLoading.value = false;
-  ElMessage.error('上传失败,请重试');
-};
-
-// 预览营业执照
-const previewLicense = () => {
-  if (businessInfo.businessLicense) {
-    window.open(businessInfo.businessLicense, '_blank');
-  }
-};
-
-// 营业执照选择处理
-const handleBusinessLicenseSelected = (files: any[]) => {
-  if (files && files.length > 0) {
-    const file = files[0]; // 取第一个文件
-    if (file && (file.url || file.path)) {
-      businessInfo.businessLicense = file.url || file.path;
-      ElMessage.success('营业执照选择成功');
-    } else {
-      ElMessage.error('请选择有效的图片文件');
-    }
-  } else {
-    ElMessage.error('请选择有效的图片文件');
-  }
-};
-
 // 编辑开票信息
 const handleEditInvoice = (row: InvoiceInfoForm, index: number) => {
   currentInvoice.value = { ...row };
@@ -1225,32 +1014,13 @@ const removeInvoice = (data: any) => {
 
 // 保存按钮
 const handleSave = async () => {
-  // 1. 先检查 ref 是否存在,避免静默失败
-  if (!formRef.value || !salesFormRef.value) {
-    ElMessage.error('表单组件未加载,请刷新页面');
-    return;
-  }
-
   try {
-    if (!salesForm.salesPersonId) {
-      ElMessage.warning('请选择业务人员!');
-      return;
-    }
-    if (!salesForm.serviceStaffId) {
-      ElMessage.warning('请选择客服人员!');
-      return;
-    }
-    // 2. 串行验证,任何一步失败都会抛出异常,进入 catch
-    // 注意:ElementPlus 的 validate 失败时会 reject 一个包含错误信息的对象
     await formRef.value.validate();
-    await salesFormRef.value.validate();
-
     submitLoading.value = true;
 
     const submitData: CustomerInfoForm = {
       ...form,
       customerBusinessBo: businessInfo,
-      customerSalesInfoBo: salesForm,
       customerInvoiceInfoBoList: invoiceList.value
     };
 
@@ -1260,30 +1030,50 @@ const handleSave = async () => {
 
     // 重新加载数据
     await loadCustomerData(custId.value);
-
-    // 可选:保存成功后重置表单或关闭弹窗
-    // emit('update:visible', false);
   } catch (error) {
-    // 3. 关键优化:区分验证错误和系统错误
-
-    // ElementPlus 的 validate 失败时,error 通常是一个包含 fields 信息的对象
-    // 或者你可以判断 error 是否包含特定的验证失败标记
     const isValidationError = error && typeof error === 'object' && 'fields' in error;
-    // 有些版本可能是 error instanceof Error 且 message 包含特定字样,具体视 EP 版本而定
-    // 最简单的判断:如果是因为 validate 抛出的,通常不需要报全局错误,因为表单上已经红字提示了
 
     if (isValidationError) {
       console.warn('表单验证未通过', error);
-      // 让用户专注于表单上的红色提示,不要弹全局 Toast 干扰用户
       return;
     }
 
-    // 如果是真正的系统错误(如网络断开、后端报错)
     ElMessage.error('保存失败,请稍后重试或联系管理员');
   } finally {
     submitLoading.value = false;
   }
 };
+
+// 监听部门ID变化,自动加载部门名称
+watch(
+  () => form.belongingDepartmentId,
+  async (newDeptId) => {
+    if (!newDeptId) {
+      deptName.value = '';
+      return;
+    }
+
+    // 先从列表中查找
+    const dept = comDeptList.value.find((d) => String(d.deptId) === String(newDeptId));
+    if (dept) {
+      deptName.value = dept.deptName;
+      return;
+    }
+
+    // 如果列表中没有,从API获取
+    try {
+      const res = await getDept(newDeptId);
+      if (res.data) {
+        deptName.value = res.data.deptName;
+        comDeptList.value.push(res.data as any);
+      }
+    } catch (error) {
+      console.error('获取部门信息失败:', error);
+      deptName.value = String(newDeptId);
+    }
+  },
+  { immediate: true }
+);
 </script>
 <style scoped>
 .upload-box:hover {

+ 60 - 22
src/views/customer/customerFile/customerInfo/overview/contactInfo.vue

@@ -2,16 +2,13 @@
   <div class="p-2">
     <el-card shadow="never">
       <template #header>
-        <el-row :gutter="10" class="mb8">
-          <el-col :span="20">
-            <span>联系人信息列表</span>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="primary" plain icon="Plus" @click="handleAdd">添加联系人</el-button>
-          </el-col>
+        <el-row :gutter="10" class="mb8" type="flex" justify="space-between" align="middle">
+          <span style="font-size: 16px; font-weight: 500">联系人信息列表</span>
+          <div style="display: flex; flex-wrap: nowrap; gap: 10px">
+            <el-button v-if="!isViewMode" type="primary" plain icon="Plus" @click="handleAdd">添加联系人</el-button>
+          </div>
         </el-row>
       </template>
-
       <el-table v-loading="loading" border :data="customerContactList" @selection-change="handleSelectionChange">
         <el-table-column type="selection" width="55" align="center" />
         <el-table-column label="用户ID" align="center" prop="contactNo" />
@@ -32,10 +29,16 @@
         </el-table-column>
         <el-table-column label="主联系人" align="center" prop="isPrimary">
           <template #default="scope">
-            <el-switch v-model="scope.row.isPrimary" active-value="0" inactive-value="1" @change="handlePrimaryChange(scope.row)"></el-switch>
+            <el-switch
+              v-model="scope.row.isPrimary"
+              active-value="0"
+              inactive-value="1"
+              @change="handlePrimaryChange(scope.row)"
+              :disabled="isViewMode"
+            ></el-switch>
           </template>
         </el-table-column>
-        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <el-table-column v-if="!isViewMode" label="操作" align="center" class-name="small-padding fixed-width">
           <template #default="scope">
             <el-button link type="primary" @click="handleUpdate(scope.row)">编辑</el-button>
             <el-button link type="primary" @click="handleDelete(scope.row)">删除</el-button>
@@ -51,24 +54,24 @@
         <el-row :gutter="20">
           <el-col :span="12">
             <el-form-item label="联系人姓名" prop="contactName">
-              <el-input v-model="form.contactName" placeholder="请输入联系人姓名" />
+              <el-input v-model="form.contactName" placeholder="请输入联系人姓名" :disabled="isViewMode" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
             <el-form-item label="手机号码" prop="phone">
-              <el-input v-model="form.phone" placeholder="请输入手机号码" />
+              <el-input v-model="form.phone" placeholder="请输入手机号码" :disabled="isViewMode" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
             <el-form-item label="办公电话" prop="officePhone">
-              <el-input v-model="form.officePhone" placeholder="请输入办公电话" />
+              <el-input v-model="form.officePhone" placeholder="请输入办公电话" :disabled="isViewMode" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
             <el-form-item label="自定义登录名" prop="customLoginName">
-              <el-input v-model="form.customLoginName" placeholder="请输入自定义登录名" />
+              <el-input v-model="form.customLoginName" placeholder="请输入自定义登录名" :disabled="isViewMode" />
             </el-form-item>
           </el-col>
         </el-row>
@@ -86,57 +89,88 @@
                 @change="handleDeptChange"
                 filterable
                 style="width: 100%"
+                :disabled="isViewMode"
               />
             </el-form-item>
           </el-col>
           <el-col :span="12">
             <el-form-item label="邮箱" prop="email">
-              <el-input v-model="form.email" placeholder="请输入邮箱" />
+              <el-input v-model="form.email" placeholder="请输入邮箱" :disabled="isViewMode" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
             <el-form-item label="采购角色" prop="roleId">
-              <el-select v-model="form.roleId" placeholder="请选择采购角色" clearable filterable style="width: 100%" @change="handleRoleChange">
+              <el-select
+                v-model="form.roleId"
+                placeholder="请选择采购角色"
+                clearable
+                filterable
+                style="width: 100%"
+                @change="handleRoleChange"
+                :disabled="isViewMode"
+              >
                 <el-option v-for="role in roleOptions" :key="role.roleId" :label="role.roleName" :value="role.roleId" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
             <el-form-item label="生日" prop="birthday">
-              <el-date-picker v-model="form.birthday" type="date" placeholder="请选择" class="w-full" value-format="YYYY-MM-DD" style="width: 100%" />
+              <el-date-picker
+                v-model="form.birthday"
+                type="date"
+                placeholder="请选择"
+                class="w-full"
+                value-format="YYYY-MM-DD"
+                style="width: 100%"
+                :disabled="isViewMode"
+              />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="12">
             <el-form-item label="性别" prop="gender">
-              <el-radio-group v-model="form.gender">
+              <el-radio-group v-model="form.gender" :disabled="isViewMode">
                 <el-radio v-for="dict in sys_user_sex" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
               </el-radio-group>
             </el-form-item>
           </el-col>
           <el-col :span="12">
             <el-form-item label="启用状态" prop="status">
-              <el-switch v-model="form.status" active-value="0" inactive-value="1" />
+              <el-switch v-model="form.status" active-value="0" inactive-value="1" :disabled="isViewMode" />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="20">
           <el-col :span="24">
             <el-form-item label="详细地址" prop="codeArr">
-              <el-cascader v-model="codeArr" :options="regionOptions" placeholder="请选择" @change="handleChange" style="width: 100%"></el-cascader>
+              <el-cascader
+                v-model="codeArr"
+                :options="regionOptions"
+                placeholder="请选择"
+                @change="handleChange"
+                style="width: 100%"
+                :disabled="isViewMode"
+              ></el-cascader>
             </el-form-item>
             <el-form-item prop="addressDetail">
-              <el-input v-model="form.addressDetail" type="textarea" :rows="3" placeholder="请输入详细地址" style="width: 100%" />
+              <el-input
+                v-model="form.addressDetail"
+                type="textarea"
+                :rows="3"
+                placeholder="请输入详细地址"
+                style="width: 100%"
+                :disabled="isViewMode"
+              />
             </el-form-item>
           </el-col>
         </el-row>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
-          <el-button type="primary" :loading="buttonLoading" @click="submitForm">确认</el-button>
+          <el-button v-if="!isViewMode" type="primary" :loading="buttonLoading" @click="submitForm">确认</el-button>
           <el-button @click="cancel">取消</el-button>
         </div>
       </template>
@@ -165,12 +199,16 @@ const props = defineProps<{
   customerNo?: string;
 }>();
 
+const route = useRoute();
 const regionOptions = regionData as any;
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const { sys_platform_yes_no, sys_user_sex, sys_normal_disable } = toRefs<any>(
   proxy?.useDict('sys_platform_yes_no', 'sys_user_sex', 'sys_normal_disable')
 );
 
+// 查看模式
+const isViewMode = computed(() => route.query.status === 'view');
+
 const customerContactList = ref<CustomerContactVO[]>([]);
 const customerDeptList = ref<CustomerDeptVO[]>([]);
 const buttonLoading = ref(false);

+ 13 - 14
src/views/customer/customerFile/customerInfo/overview/contractManagement.vue

@@ -31,13 +31,13 @@
 
     <el-card shadow="never">
       <template #header>
-        <el-row :gutter="10" class="mb8">
-          <el-col :span="20">
-            <span>合同管理信息列表</span>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['customer:contract:add']">新增合同</el-button>
-          </el-col>
+        <el-row :gutter="10" class="mb8" type="flex" justify="space-between" align="middle">
+          <span style="font-size: 16px; font-weight: 500">合同管理信息列表</span>
+          <div style="display: flex; flex-wrap: nowrap; gap: 10px">
+            <el-button v-if="!isViewMode" type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['customer:contract:add']"
+              >新增合同</el-button
+            >
+          </div>
         </el-row>
       </template>
 
@@ -71,7 +71,7 @@
         </el-table-column>
 
         <el-table-column label="附件管理" align="center" prop="annex" />
-        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <el-table-column v-if="!isViewMode" label="操作" align="center" class-name="small-padding fixed-width">
           <template #default="scope">
             <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['customer:contract:edit']">编辑</el-button>
             <el-button link type="primary" icon="Edit" @click="handleReview(scope.row)" v-hasPermi="['customer:contract:edit']">查看</el-button>
@@ -191,9 +191,14 @@ const props = defineProps<{
   customerNo?: string;
   customerName?: string;
 }>();
+
+const route = useRoute();
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const { contract_type, contract_status } = toRefs<any>(proxy?.useDict('contract_type', 'contract_status'));
 
+// 查看模式
+const isViewMode = computed(() => route.query.status === 'view');
+
 const contractList = ref<ContractVO[]>([]);
 const buttonLoading = ref(false);
 const loading = ref(true);
@@ -211,9 +216,6 @@ const dialog = reactive<DialogOption>({
   title: ''
 });
 
-// 是否为查看模式
-const isViewMode = ref(false);
-
 const initFormData: ContractForm = {
   id: undefined,
   customerNo: undefined,
@@ -326,7 +328,6 @@ const handleSelectionChange = (selection: ContractVO[]) => {
 /** 新增按钮操作 */
 const handleAdd = () => {
   reset();
-  isViewMode.value = false; // 取消查看模式
   // 将props中的客户信息赋值给form
   if (props.customerId) {
     form.value.customerId = props.customerId;
@@ -344,7 +345,6 @@ const handleAdd = () => {
 /** 修改按钮操作 */
 const handleUpdate = async (row?: ContractVO) => {
   reset();
-  isViewMode.value = false; // 取消查看模式
   const _id = row?.id || ids.value[0];
   const res = await getContract(_id);
   Object.assign(form.value, res.data);
@@ -354,7 +354,6 @@ const handleUpdate = async (row?: ContractVO) => {
 /** 查看按钮操作 */
 const handleReview = async (row?: ContractVO) => {
   reset();
-  isViewMode.value = true; // 设置为查看模式
   const _id = row?.id || ids.value[0];
   const res = await getContract(_id);
   Object.assign(form.value, res.data);

+ 464 - 0
src/views/customer/customerFile/customerInfo/overview/erpSaleInfo.vue

@@ -0,0 +1,464 @@
+<template>
+  <div class="p-4">
+    <!-- ERP销售信息 -->
+    <el-card shadow="never" class="mb-4">
+      <template #header>
+        <el-row :gutter="10" class="mb8" type="flex" justify="space-between" align="middle">
+          <span style="font-size: 16px; font-weight: 500">ERP销售信息</span>
+          <div style="display: flex; flex-wrap: nowrap; gap: 10px">
+            <el-button v-if="!isViewMode" type="primary" plain icon="Plus" :loading="submitLoading" @click="handleSave">保存</el-button>
+          </div>
+        </el-row>
+      </template>
+      <el-form ref="salesFormRef" :model="salesForm" :rules="salesRules" label-width="140px">
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="业务人员" prop="salesPersonId" required>
+              <el-select
+                v-model="salesForm.salesPersonId"
+                placeholder="请选择业务人员"
+                class="w-full"
+                filterable
+                @change="handleSalesPersonChange"
+                :disabled="isViewMode"
+              >
+                <el-option v-for="item in comStaffList" :key="item.staffId" :label="`${item.staffCode} , ${item.staffName}`" :value="item.staffId" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="客服人员" prop="serviceStaffId" required>
+              <el-select v-model="salesForm.serviceStaffId" placeholder="请选择客服人员" class="w-full" filterable :disabled="isViewMode">
+                <el-option v-for="item in comStaffList" :key="item.staffId" :label="`${item.staffCode} , ${item.staffName}`" :value="item.staffId" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="所属部门" prop="belongingDepartmentId">
+              <el-input v-model="deptName" placeholder="请选择所属部门" class="w-full" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="信用等级" prop="creditManagementId">
+              <el-select v-model="salesForm.creditManagementId" placeholder="请选择信用等级" class="w-full" filterable :disabled="isViewMode">
+                <el-option
+                  v-for="item in creditLevelList"
+                  :key="item.id"
+                  :label="`${item.creditLevelNo} , ${item.creditLevelName}`"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="信用额度" prop="creditAmount">
+              <el-input v-model="salesForm.creditAmount" :controls="false" class="w-full" placeholder="请输入信用额度" style="width: 100%" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="可用额度" prop="remainingQuota">
+              <el-input
+                v-model="salesForm.remainingQuota"
+                :controls="false"
+                class="w-full"
+                placeholder="请输入可用额度"
+                style="width: 100%"
+                disabled
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="订单审核" prop="orderAudit">
+              <el-select v-model="salesForm.orderAudit" placeholder="请选择" class="w-full" filterable :disabled="isViewMode">
+                <el-option v-for="dict in order_check_way" :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="creditPaymentPassword">
+              <el-input v-model="salesForm.creditPaymentPassword" type="password" placeholder="请输入支付密码" show-password :disabled="isViewMode" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="结算方式" prop="settlementMethod">
+              <el-select v-model="salesForm.settlementMethod" placeholder="请选择结算方式" class="w-full" filterable :disabled="isViewMode">
+                <el-option v-for="item in settlementMethodList" :key="item.id" :label="item.settlementName" :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="客户来源" prop="customerSource">
+              <el-select v-model="salesForm.customerSource" class="w-full" filterable :disabled="isViewMode">
+                <el-option v-for="dict in customer_source" :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="sellChannel">
+              <el-select v-model="salesForm.sellChannel" class="w-full" filterable :disabled="isViewMode">
+                <el-option v-for="dict in sell_channel" :key="dict.value" :label="dict.label" :value="dict.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="税码" prop="rateId">
+              <el-select v-model="salesForm.rateId" placeholder="税码" class="w-full" filterable :disabled="isViewMode">
+                <el-option v-for="item in taxrateList" :key="item.id" :label="item.taxrateNo" :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="交易币别" prop="dealCurrencyId">
+              <el-select v-model="salesForm.dealCurrencyId" placeholder="请选择交易币别" class="w-full" filterable :disabled="isViewMode">
+                <el-option v-for="item in currencyList" :key="item.id" :label="item.currencyName" :value="item.id" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="账款归属" prop="customerNo">
+              <el-input :model-value="props.customerNo || ''" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="单价含税" prop="unitPrice">
+              <el-select v-model="salesForm.unitPrice" placeholder="单价含税" class="w-full" filterable :disabled="isViewMode">
+                <el-option v-for="item in unitPriceArr" :key="item.value" :label="item.label" :value="item.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="账款额度超限" prop="creditLimit">
+              <el-select v-model="salesForm.creditLimit" placeholder="请选择账款额度超限" class="w-full" filterable :disabled="isViewMode">
+                <el-option v-for="dict in erp_is_enabled" :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="creditTimeLimit">
+              <el-select v-model="salesForm.creditTimeLimit" placeholder="请选择账款超期" class="w-full" filterable :disabled="isViewMode">
+                <el-option v-for="dict in erp_is_enabled" :key="dict.value" :label="dict.label" :value="dict.value" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-card>
+  </div>
+</template>
+
+<script setup lang="ts" name="ErpSaleInfo">
+import { getCustomerInfo, updateCustomerInfo } from '@/api/customer/customerFile/customerInfo';
+import type { SalesInfoForm } from '@/api/customer/customerFile/salesInfo/types';
+import type { CustomerInfoForm } from '@/api/customer/customerFile/customerInfo/types';
+import { listSettlementMethod } from '@/api/customer/settlementMethod';
+import { SettlementMethodVO } from '@/api/customer/settlementMethod/types';
+import { listCreditLevel } from '@/api/customer/creditLevel';
+import { CreditLevelVO, CreditLevelQuery } from '@/api/customer/creditLevel/types';
+import { listComStaff } from '@/api/company/comStaff';
+import { listErpStaff } from '@/api/erpData/erpStaff';
+import { listErpDept, getErpDept } from '@/api/erpData/erpDept';
+import { listComCurrency } from '@/api/company/comCurrency';
+import { listTaxrate } from '@/api/company/taxrate';
+import { ComCurrencyVO } from '@/api/company/comCurrency/types';
+import { ErpStaffVO } from '@/api/erpData/erpStaff/types';
+import { ErpDeptVO } from '@/api/erpData/erpDept/types';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { order_check_way, customer_source, sell_channel, erp_is_enabled } = toRefs<any>(
+  proxy?.useDict('order_check_way', 'customer_source', 'sell_channel', 'erp_is_enabled')
+);
+
+// 接收父组件传递的props
+const props = defineProps<{
+  customerId?: string | number;
+  customerNo?: string;
+}>();
+
+const route = useRoute();
+const router = useRouter();
+
+// 查看模式
+const isViewMode = computed(() => route.query.status === 'view');
+
+const unitPriceArr = ref([
+  { label: '含税', value: 'True' },
+  { label: '不含税', value: 'False' }
+]);
+
+const salesFormRef = ref<any>(null);
+const custId = ref<string | number>('');
+const customerNumber = ref('');
+const submitLoading = ref(false);
+
+// 下拉框数据列表
+const settlementMethodList = ref<SettlementMethodVO[]>([]);
+const creditLevelList = ref<CreditLevelVO[]>([]);
+const comStaffList = ref<ErpStaffVO[]>([]);
+const comDeptList = ref<ErpDeptVO[]>([]);
+const currencyList = ref<ComCurrencyVO[]>([]);
+const taxrateList = ref<any[]>([]);
+
+// 销售信息
+const salesForm = reactive<SalesInfoForm>({
+  salesPersonId: undefined,
+  serviceStaffId: undefined,
+  belongingDepartmentId: undefined,
+  creditManagementId: undefined,
+  creditAmount: undefined,
+  remainingQuota: undefined,
+  orderAudit: undefined,
+  creditPaymentPassword: '',
+  accountPeriod: '',
+  payDays: undefined,
+  customerSource: '1',
+  unitPrice: 'True',
+  sellChannel: '1',
+  creditLimit: '1',
+  creditTimeLimit: '1',
+  dealCurrencyId: undefined,
+  settlementMethod: undefined,
+  status: '0'
+});
+
+// 销售信息表单验证规则
+const salesRules = {
+  salesPersonId: [{ required: true, message: '请选择业务人员', trigger: 'change' }],
+  serviceStaffId: [{ required: true, message: '请选择客服人员', trigger: 'change' }]
+};
+
+// 部门名称(响应式)
+const deptName = ref('');
+
+// 加载币种列表
+const loadCurrencyList = async () => {
+  try {
+    const res = await listComCurrency({
+      isShow: '0',
+      pageNum: 1,
+      pageSize: 1000
+    });
+    currencyList.value = res.rows || [];
+    if (res.rows && res.rows.length > 0) {
+      salesForm.dealCurrencyId = res.rows[0].id;
+    }
+  } catch (error) {
+    console.error('加载币种列表失败:', error);
+    currencyList.value = [];
+  }
+};
+
+// 加载税码列表
+const loadTaxrateList = async () => {
+  try {
+    const res = await listTaxrate({
+      isShow: '0',
+      pageNum: 1,
+      pageSize: 1000
+    });
+    taxrateList.value = res.rows || [];
+  } catch (error) {}
+};
+
+// 初始化
+onMounted(async () => {
+  // 加载下拉框数据
+  await loadSettlementMethodList();
+  await loadCreditLevelList();
+  await loadComStaffList();
+  await loadComDeptList();
+  await loadCurrencyList();
+  await loadTaxrateList();
+
+  // 优先使用props传递的customerId,否则从路由获取
+  const id = props.customerId || route.query.id;
+  if (id) {
+    custId.value = id as string;
+    await loadCustomerData(id as any);
+  }
+});
+
+// 加载结算方式列表
+const loadSettlementMethodList = async () => {
+  try {
+    const query: any = { isShow: '0' };
+    const res = await listSettlementMethod(query);
+    settlementMethodList.value = res.rows || [];
+  } catch (error) {
+    console.error('加载结算方式列表失败:', error);
+  }
+};
+
+// 加载信用等级列表
+const loadCreditLevelList = async () => {
+  try {
+    const query: any = { dataSource: 'A10' };
+    const res = await listCreditLevel(query);
+    creditLevelList.value = res.rows || [];
+  } catch (error) {
+    console.error('加载信用等级列表失败:', error);
+  }
+};
+
+// 加载员工列表
+const loadComStaffList = async () => {
+  try {
+    const query: any = {};
+    const res = await listErpStaff(query);
+    comStaffList.value = res.rows || [];
+  } catch (error) {
+    console.error('加载员工列表失败:', error);
+  }
+};
+
+// 加载部门列表
+const loadComDeptList = async () => {
+  try {
+    const res = await listErpDept();
+    // 处理可能的不同返回结构
+    comDeptList.value = res.rows || res.data || [];
+  } catch (error) {
+    console.error('加载部门列表失败:', error);
+  }
+};
+
+// 加载客户数据
+const loadCustomerData = async (id: any) => {
+  try {
+    const res = await getCustomerInfo(id);
+    const data = res.data;
+
+    // 填充销售信息
+    if (data.customerSalesInfoVo) {
+      Object.assign(salesForm, data.customerSalesInfoVo);
+
+      // 如果有部门ID,且部门不在列表中,从API获取
+      if (salesForm.belongingDepartmentId) {
+        const deptExists = comDeptList.value.find((d) => String(d.deptId) === String(salesForm.belongingDepartmentId));
+        if (!deptExists) {
+          try {
+            const deptRes = await getErpDept(salesForm.belongingDepartmentId);
+            if (deptRes.data) {
+              comDeptList.value.push(deptRes.data);
+            }
+          } catch (error) {
+            console.error('获取部门信息失败:', error);
+          }
+        }
+      }
+    }
+  } catch (error) {
+    console.error('加载客户数据失败:', error);
+    ElMessage.error('加载客户数据失败');
+  }
+};
+
+// 监听props变化
+watch(
+  () => props.customerId,
+  (newId) => {
+    if (newId) {
+      custId.value = newId;
+      loadCustomerData(newId);
+    }
+  }
+);
+
+// 监听部门ID变化,自动加载部门名称
+watch(
+  () => salesForm.belongingDepartmentId,
+  async (newDeptId) => {
+    if (!newDeptId) {
+      deptName.value = '';
+      return;
+    }
+
+    // 先从列表中查找
+    const dept = comDeptList.value.find((d) => String(d.deptId) === String(newDeptId));
+    if (dept) {
+      deptName.value = dept.deptName;
+      return;
+    }
+
+    // 如果列表中没有,从API获取
+    try {
+      const res = await getErpDept(newDeptId);
+      if (res.data) {
+        deptName.value = res.data.deptName;
+        comDeptList.value.push(res.data as any);
+      }
+    } catch (error) {
+      console.error('获取部门信息失败:', error);
+      deptName.value = String(newDeptId);
+    }
+  },
+  { immediate: true }
+);
+
+// 处理业务人员选择变化
+const handleSalesPersonChange = async (staffId: any) => {
+  // 根据选中的业务人员ID,找到对应的部门ID
+  const selectedStaff = comStaffList.value.find((staff) => staff.staffId === staffId);
+  if (selectedStaff && selectedStaff.deptId) {
+    // 确保 deptId 的类型一致
+    salesForm.belongingDepartmentId = String(selectedStaff.deptId);
+
+    // 如果部门不在列表中,从API获取
+    const deptExists = comDeptList.value.find((d) => String(d.deptId) === String(selectedStaff.deptId));
+    if (!deptExists) {
+      try {
+        const res = await getErpDept(selectedStaff.deptId);
+        if (res.data) {
+          comDeptList.value.push(res.data as any);
+        }
+      } catch (error) {
+        console.error('获取部门信息失败:', error);
+      }
+    }
+  }
+};
+
+// 保存按钮
+const handleSave = async () => {
+  try {
+    await salesFormRef.value.validate();
+    submitLoading.value = true;
+
+    // 准备提交数据,包含销售信息
+    const submitData: CustomerInfoForm = {
+      id: custId.value,
+      customerSalesInfoBo: { ...salesForm }
+    };
+
+    await updateCustomerInfo(submitData);
+
+    ElMessage.success('保存成功');
+
+    // 重新加载数据
+    await loadCustomerData(custId.value);
+  } catch (error) {
+    const isValidationError = error && typeof error === 'object' && 'fields' in error;
+
+    if (isValidationError) {
+      console.warn('表单验证未通过', error);
+      return;
+    }
+
+    ElMessage.error('保存失败,请稍后重试或联系管理员');
+  } finally {
+    submitLoading.value = false;
+  }
+};
+</script>

+ 21 - 18
src/views/customer/customerFile/customerInfo/overview/orgStructure.vue

@@ -2,13 +2,11 @@
   <div class="p-2">
     <el-card shadow="never">
       <template #header>
-        <el-row :gutter="10" class="mb8">
-          <el-col :span="22">
-            <span>企业组织结构信息列表</span>
-          </el-col>
-          <el-col :span="2" style="text-align: right">
-            <el-button type="primary" plain icon="Plus" @click="handleAdd()">新增部门</el-button>
-          </el-col>
+        <el-row :gutter="10" class="mb8" type="flex" justify="space-between" align="middle">
+          <span style="font-size: 16px; font-weight: 500">企业组织结构信息列表</span>
+          <div style="display: flex; flex-wrap: nowrap; gap: 10px">
+            <el-button v-if="!isViewMode" type="primary" plain icon="Plus" @click="handleAdd()">新增部门</el-button>
+          </div>
         </el-row>
       </template>
 
@@ -24,7 +22,7 @@
             <el-tag v-else type="info">停用</el-tag>
           </template>
         </el-table-column>
-        <el-table-column label="操作" align="center" width="200">
+        <el-table-column v-if="!isViewMode" label="操作" align="center" width="200">
           <template #default="scope">
             <el-button link type="primary" @click="handleUpdate(scope.row)">编辑</el-button>
             <el-button link type="primary" @click="handleAdd(scope.row)">新增</el-button>
@@ -47,27 +45,28 @@
             check-strictly
             :render-after-expand="false"
             style="width: 240px"
+            :disabled="isViewMode"
           />
         </el-form-item>
         <el-form-item label="部门名称" prop="deptName">
-          <el-input v-model="form.deptName" placeholder="请输入部门名称" style="width: 240px" />
+          <el-input v-model="form.deptName" placeholder="请输入部门名称" style="width: 240px" :disabled="isViewMode" />
         </el-form-item>
         <el-form-item label="部门主管" prop="deptManage">
-          <el-select v-model="form.deptManage" placeholder="请选择" clearable style="width: 240px">
+          <el-select v-model="form.deptManage" placeholder="请选择" clearable style="width: 240px" :disabled="isViewMode">
             <el-option v-for="manage in customerContactList" :key="manage.id" :label="manage.contactName" :value="manage.id" />
           </el-select>
         </el-form-item>
         <el-row>
           <el-col :span="12">
             <el-form-item label="是否启用部门">
-              <el-radio-group v-model="form.status">
+              <el-radio-group v-model="form.status" :disabled="isViewMode">
                 <el-radio v-for="dict in sys_platform_yes_no" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
               </el-radio-group>
             </el-form-item>
           </el-col>
           <el-col :span="12">
             <el-form-item label="是否额度控制">
-              <el-radio-group v-model="form.isLimit">
+              <el-radio-group v-model="form.isLimit" :disabled="isViewMode">
                 <el-radio v-for="dict in sys_platform_yes_no" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
               </el-radio-group>
             </el-form-item>
@@ -80,14 +79,14 @@
             placeholder="请选择年度"
             value-format="YYYY"
             style="width: 240px"
-            :disabled="form.isLimit == '1'"
+            :disabled="form.isLimit == '1' || isViewMode"
           />
         </el-form-item>
         <div style="color: #999; font-size: 12px; margin-left: 120px; margin-bottom: 18px">
           只能对当期年度进行额度设置,往期年度,显示最后一日数据,无法充值额度。
         </div>
         <el-form-item v-if="form.isLimit === '0'" label="分项费用类型" prop="expenseTypeId">
-          <el-select v-model="form.expenseTypeId" placeholder="请选择" style="width: 240px" @change="expenseTypeChange">
+          <el-select v-model="form.expenseTypeId" placeholder="请选择" style="width: 240px" @change="expenseTypeChange" :disabled="isViewMode">
             <el-option v-for="item in expenseTypeList" :key="item.id" :label="item.expenseName" :value="item.id" />
           </el-select>
           <!-- <el-button type="primary" link style="margin-left: 12px">查询其他分项费用情况</el-button> -->
@@ -102,13 +101,13 @@
           <el-input v-model="form.residueYearlyBudget" style="width: 240px" disabled />
         </el-form-item>
         <el-form-item v-if="form.isLimit === '0'" label="充值额度" prop="recharge">
-          <el-input v-model="form.recharge" style="width: 240px" />
+          <el-input v-model="form.recharge" style="width: 240px" :disabled="isViewMode" />
         </el-form-item>
         <el-form-item label="绑定状态">
-          <el-switch v-model="form.bindStatus" :active-value="'0'" :inactive-value="'1'" />
+          <el-switch v-model="form.bindStatus" :active-value="'0'" :inactive-value="'1'" :disabled="isViewMode" />
         </el-form-item>
         <el-form-item v-if="form.bindStatus === '0'" label="绑定地址" prop="bindAddress">
-          <el-select v-model="form.bindAddress" placeholder="请选择" clearable style="width: 100%">
+          <el-select v-model="form.bindAddress" placeholder="请选择" clearable style="width: 100%" :disabled="isViewMode">
             <el-option
               v-for="addr in shippingAddressList"
               :key="addr.id"
@@ -128,7 +127,7 @@
       </el-form>
       <template #footer>
         <div class="dialog-footer">
-          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
+          <el-button v-if="!isViewMode" :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
           <el-button @click="cancel">取 消</el-button>
         </div>
       </template>
@@ -159,8 +158,12 @@ const props = defineProps<{
   customerName?: string;
 }>();
 
+const route = useRoute();
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 
+// 查看模式
+const isViewMode = computed(() => route.query.status === 'view');
+
 const { sys_platform_yes_no } = toRefs<any>(proxy?.useDict('sys_platform_yes_no'));
 
 const customerDeptList = ref<CustomerDeptVO[]>([]);

+ 25 - 14
src/views/customer/customerFile/customerInfo/overview/shippingAddress.vue

@@ -2,13 +2,13 @@
   <div class="p-2">
     <el-card shadow="never">
       <template #header>
-        <el-row :gutter="10" class="mb8">
-          <el-col :span="20">
-            <span>收货地址信息列表</span>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['customer:shippingAddress:add']">添加地址</el-button>
-          </el-col>
+        <el-row :gutter="10" class="mb8" type="flex" justify="space-between" align="middle">
+          <span style="font-size: 16px; font-weight: 500">收货地址信息列表</span>
+          <div style="display: flex; flex-wrap: nowrap; gap: 10px">
+            <el-button v-if="!isViewMode" type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['customer:shippingAddress:add']"
+              >添加地址</el-button
+            >
+          </div>
         </el-row>
       </template>
       <el-table v-loading="loading" border :data="shippingAddressList" @selection-change="handleSelectionChange">
@@ -27,7 +27,7 @@
             ></el-switch>
           </template>
         </el-table-column>
-        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <el-table-column v-if="!isViewMode" label="操作" align="center" class-name="small-padding fixed-width">
           <template #default="scope">
             <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['customer:shippingAddress:edit']"
               >编辑</el-button
@@ -45,27 +45,34 @@
     <el-dialog :title="dialog.title" v-model="dialog.visible" width="650px" append-to-body>
       <el-form ref="shippingAddressFormRef" :model="form" :rules="rules" label-width="110px">
         <el-form-item label="收货人" prop="consignee">
-          <el-input v-model="form.consignee" placeholder="请输入收货人姓名" />
+          <el-input v-model="form.consignee" placeholder="请输入收货人姓名" :disabled="isViewMode" />
         </el-form-item>
         <!-- <el-form-item label="部门名称" prop="deptName">
           <el-input v-model="form.deptName" placeholder="请输入部门名称" />
         </el-form-item> -->
         <el-form-item label="手机号码" prop="phone">
-          <el-input v-model="form.phone" placeholder="请输入联系电话" />
+          <el-input v-model="form.phone" placeholder="请输入联系电话" :disabled="isViewMode" />
         </el-form-item>
         <el-form-item label="邮政编码" prop="postal">
-          <el-input v-model="form.postal" placeholder="请输入邮政编码" />
+          <el-input v-model="form.postal" placeholder="请输入邮政编码" :disabled="isViewMode" />
         </el-form-item>
         <el-form-item label="详细地址" prop="provincialCityCountry">
-          <el-cascader v-model="codeArr" :options="regionData as any" placeholder="请选择" @change="handleChange" style="width: 100%"></el-cascader>
+          <el-cascader
+            v-model="codeArr"
+            :options="regionData as any"
+            placeholder="请选择"
+            @change="handleChange"
+            style="width: 100%"
+            :disabled="isViewMode"
+          ></el-cascader>
         </el-form-item>
         <el-form-item prop="address">
-          <el-input v-model="form.address" type="textarea" placeholder="请输入内容" />
+          <el-input v-model="form.address" type="textarea" placeholder="请输入内容" :disabled="isViewMode" />
         </el-form-item>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
-          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
+          <el-button v-if="!isViewMode" :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
           <el-button @click="cancel">取 消</el-button>
         </div>
       </template>
@@ -93,7 +100,11 @@ const props = defineProps<{
   customerNo?: string;
 }>();
 
+const route = useRoute();
 const shippingAddressList = ref<ShippingAddressVO[]>([]);
+
+// 查看模式
+const isViewMode = computed(() => route.query.status === 'view');
 const buttonLoading = ref(false);
 const loading = ref(true);
 const showSearch = ref(true);

+ 7 - 20
src/views/order/saleOrder/index.vue

@@ -46,50 +46,37 @@
 
     <el-card shadow="never">
       <template #header>
-        <el-row :gutter="10" class="mb8">
-          <el-col :span="13"> 销售订单信息列表 </el-col>
-          <el-col :span="1.5">
+        <el-row :gutter="10" class="mb8" type="flex" justify="space-between" align="middle">
+          <!-- 左侧标题 -->
+          <span style="font-size: 16px; font-weight: 500">销售订单信息列表</span>
+
+          <div style="display: flex; flex-wrap: nowrap; gap: 10px">
             <el-button type="primary" @click="handleCloseOrder()" :disabled="!ids.length" plain>关闭订单</el-button>
-          </el-col>
-          <el-col :span="1.5">
             <el-button type="primary" @click="handleDelete()" :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="queryParams.orderStatus === undefined ? 'primary' : ''"
               :plain="queryParams.orderStatus !== undefined"
               @click="handleQuery()"
               >全部订单{{ orderStatusStats.totalCount }}</el-button
             >
-          </el-col>
-          <el-col :span="1.5">
+
             <el-button :type="queryParams.orderStatus === '0' ? 'primary' : ''" :plain="queryParams.orderStatus !== '0'" @click="handleQuery('0')"
               >待付款{{ orderStatusStats.pendingPaymentCount }}</el-button
             >
-          </el-col>
-          <el-col :span="1.5">
             <el-button :type="queryParams.orderStatus === '2' ? 'primary' : ''" :plain="queryParams.orderStatus !== '2'" @click="handleQuery('2')"
               >待发货{{ orderStatusStats.pendingShipmentCount }}</el-button
             >
-          </el-col>
-          <el-col :span="1.5">
             <el-button :type="queryParams.orderStatus === '4' ? 'primary' : ''" :plain="queryParams.orderStatus !== '4'" @click="handleQuery('4')"
               >已发货{{ orderStatusStats.shippedCount }}</el-button
             >
-          </el-col>
-          <el-col :span="1.5">
             <el-button :type="queryParams.orderStatus === '5' ? 'primary' : ''" :plain="queryParams.orderStatus !== '5'" @click="handleQuery('5')"
               >已完成{{ orderStatusStats.completedCount }}</el-button
             >
-          </el-col>
-          <el-col :span="1.5">
             <el-button :type="queryParams.orderStatus === '6' ? 'primary' : ''" :plain="queryParams.orderStatus !== '6'" @click="handleQuery('6')"
               >已关闭{{ orderStatusStats.closedCount }}</el-button
             >
-          </el-col>
+          </div>
         </el-row>
       </template>