Parcourir la source

feat(supplier): 移除供应商信息页面中的地址对话框和品牌对话框组件

- 删除了 AddressDialog.vue 组件文件
- 删除了 BrandDialog.vue 组件文件
- 删除了 ContactDialog.vue 组件文件
- 更新 AddressTab.vue 组件以适配新的事件处理方式
- 修改 BasicInfoTab.vue 组件以支持编辑模式和状态显示
- 调整表单布局和样式,优化用户体验
- 添加营业执照和法人身份证照片上传功能
- 实现编辑取消功能的数据恢复机制
Lijingyang il y a 1 mois
Parent
commit
4bc0376844

+ 1 - 1
src/api/supplier/area/index.ts

@@ -10,7 +10,7 @@ import { AreaVO, AreaForm, AreaQuery } from '@/api/supplier/area/types';
 
 export const listArea = (query?: AreaQuery): AxiosPromise<AreaVO[]> => {
   return request({
-    url: '/customer/area/srm/list',
+    url: '/customer/area/list',
     method: 'get',
     params: query
   });

+ 1 - 1
src/api/supplier/businessInfo/index.ts

@@ -1,6 +1,6 @@
 import request from '@/utils/request';
 import { AxiosPromise } from 'axios';
-import { BusinessInfoVO, BusinessInfoForm, BusinessInfoQuery } from '@/api/suuplier/businessInfo/types';
+import { BusinessInfoVO, BusinessInfoForm, BusinessInfoQuery } from '@/api/supplier/businessInfo/types';
 
 /**
  * 查询供应商工商注册信息列表

+ 8 - 0
src/api/supplier/info/index.ts

@@ -66,6 +66,14 @@ export const updateInfo = (data: InfoForm) => {
   });
 };
 
+export const scmEditInfo = (data: InfoForm) => {
+  return request({
+    url: '/customer/info/edit',
+    method: 'put',
+    data: data
+  });
+};
+
 /**
  * 删除供应商信息
  * @param id

+ 51 - 16
src/components/ImageUpload/index.vue

@@ -3,6 +3,7 @@
     <el-upload
       ref="imageUploadRef"
       multiple
+      :disabled="disabled"
       :action="uploadImgUrl"
       list-type="picture-card"
       :on-success="handleUploadSuccess"
@@ -52,6 +53,10 @@ const props = defineProps({
     type: [String, Object, Array],
     default: () => []
   },
+  disabled: {
+    type: Boolean,
+    default: false
+  },
   // 图片数量限制
   limit: propTypes.number.def(5),
   // 大小限制(MB)
@@ -93,36 +98,62 @@ const fileAccept = computed(() => props.fileType.map((type) => `.${type}`).join(
 
 watch(
   () => props.modelValue,
-  async (val: string) => {
+  async (val: any) => {
     if (val) {
       // 首先将值转为数组
-      let list: OssVO[] = [];
+      let list: any[] = [];
       if (Array.isArray(val)) {
-        list = val as OssVO[];
-      } else {
-        const res = await listByIds(val);
-        list = res.data;
+        list = val;
+      } else if (typeof val === 'string') {
+        // 判断是否为路径模式 (包含 / 或 http)
+        if (val.includes('/') || val.includes('http')) {
+          list = val.split(',').map((url) => ({ url: url.trim(), name: url.trim() }));
+        } else {
+          try {
+            const res = await listByIds(val);
+            list = res.data || [];
+          } catch (e) {
+            console.error('Failed to list image by IDs:', val);
+            list = [];
+          }
+        }
       }
+
       // 然后将数组转为对象数组
       fileList.value = list.map((item) => {
-        // 字符串回显处理 如果此处存的是url可直接回显 如果存的是id需要调用接口查出来
         let itemData;
         if (typeof item === 'string') {
-          itemData = { name: item, url: item };
+          itemData = { name: item, url: formatUrl(item) };
         } else {
-          // 此处name使用ossId 防止删除出现重名
-          itemData = { name: item.ossId, url: item.url, ossId: item.ossId };
+          const name = item.ossId || item.url || 'image';
+          itemData = { name: name, url: formatUrl(item.url), ossId: item.ossId };
         }
         return itemData;
       });
     } else {
       fileList.value = [];
-      return [];
     }
   },
   { deep: true, immediate: true }
 );
 
+// 辅助函数:确保 URL 是正确的格式
+function formatUrl(url: string) {
+  if (!url) return '';
+  // 如果是 full URL (http/https 或 blob) 直接返回
+  if (url.startsWith('http') || url.startsWith('blob:')) {
+    return url;
+  }
+  // 如果是相对路径,补全 baseUrl (如果是 /profile 等路径,ruoyi 通常会自动处理,但此处手动防误)
+  // 注意:如果后端返回的是带 / 的路径且没有域名,这里需要根据实际情况补全
+  if (url.startsWith('/')) {
+    // 如果 baseUrl 结尾没有 /,且 url 开头有 /,需要处理
+    const base = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
+    return base + url;
+  }
+  return url;
+}
+
 /** 上传前loading加载 */
 const handleBeforeUpload = (file: any) => {
   let isImg = false;
@@ -187,10 +218,14 @@ const handleUploadSuccess = (res: any, file: UploadFile) => {
 
 // 删除图片
 const handleDelete = (file: UploadFile): boolean => {
-  const findex = fileList.value.map((f) => f.name).indexOf(file.name);
+  const findex = fileList.value.findIndex((f) => f.name === file.name || f.url === file.url);
   if (findex > -1 && uploadList.value.length === number.value) {
-    const ossId = fileList.value[findex].ossId;
-    delOss(ossId);
+    const item = fileList.value[findex];
+    if (item.ossId) {
+      delOss(item.ossId).catch(() => {
+        console.warn('Physical delete failed, but removing from UI.');
+      });
+    }
     fileList.value.splice(findex, 1);
     emit('update:modelValue', listToString(fileList.value));
     return false;
@@ -226,8 +261,8 @@ const listToString = (list: any[], separator?: string) => {
   let strs = '';
   separator = separator || ',';
   for (const i in list) {
-    if (undefined !== list[i].ossId && list[i].url.indexOf('blob:') !== 0) {
-      strs += list[i].ossId + separator;
+    if (undefined !== list[i].url && list[i].url.indexOf('blob:') !== 0) {
+      strs += list[i].url + separator;
     }
   }
   return strs != '' ? strs.substring(0, strs.length - 1) : '';

+ 13 - 0
src/router/index.ts

@@ -101,6 +101,19 @@ export const constantRoutes: RouteRecordRaw[] = [
         meta: { title: '新增产品线授权', activeMenu: '/supplier/author' }
       }
     ]
+  },
+  {
+    path: '/supplier/author/detail',
+    component: Layout,
+    hidden: true,
+    children: [
+      {
+        path: '',
+        component: () => import('@/views/supplier/author/detail.vue'),
+        name: 'AuthorDetail',
+        meta: { title: '查看授权详情', activeMenu: '/supplier/author' }
+      }
+    ]
   }
 ];
 

+ 13 - 0
src/views/supplier/address/index.vue

@@ -177,11 +177,16 @@ import { listAddress, getAddress, delAddress, addAddress, updateAddress } from '
 import { AddressVO, AddressQuery, AddressForm } from '@/api/supplier/address/types';
 import { listNameInfo } from '@/api/supplier/info';
 import { regionData, codeToText } from 'element-china-area-data';
+import { useRoute } from 'vue-router';
+import { useUserStore } from '@/store/modules/user';
 
 const regionOptions = ref(regionData);
 const selectedAddressRegion = ref<string[]>([]);
 const supplierOptions = ref<any[]>([]);
 
+const route = useRoute();
+const userStore = useUserStore();
+
 const getSupplierNameList = async () => {
   const res = await listNameInfo();
   supplierOptions.value = res.data || res.rows || [];
@@ -266,6 +271,14 @@ const { queryParams, form, rules } = toRefs(data);
 /** 查询供应商地址列表 */
 const getList = async () => {
   loading.value = true;
+  if (!userStore.supplierId) {
+    await userStore.getSupplierInfo();
+  }
+  queryParams.value.supplierId = (userStore.supplierId ?? route.query?.supplierId ?? route.query?.id ?? route.params?.supplierId ?? route.params?.id) as any;
+  if (!queryParams.value.supplierId) {
+    loading.value = false;
+    return;
+  }
   const res = await listAddress(queryParams.value);
   addressList.value = res.rows;
   total.value = res.total;

+ 7 - 0
src/views/supplier/author/edit.vue

@@ -399,6 +399,7 @@ const categoryDisplayNames = ref({
 // 表单数据
 const formData = ref({
   brandId: '',
+  brandNo: '',
   brandName: '',
   brandLogo: '', // 品牌LOGO
   brandRegistrant: '', // 商标注册人
@@ -564,6 +565,7 @@ const loadDetailData = async () => {
     console.log('详情数据:', data);
     
     // 回显基本信息
+    formData.value.brandNo = (data as any).brandNo || '';
     formData.value.brandName = data.brandName || '';
     formData.value.brandLogo = data.brandLogo || '';
     formData.value.brandRegistrant = data.brandRegistrant || (data as any).registrationCertificate || '';
@@ -723,6 +725,7 @@ const loadDetailData = async () => {
 
 const handleBrandClear = () => {
   formData.value.brandId = '';
+  formData.value.brandNo = '';
   formData.value.brandName = '';
   formData.value.brandLogo = '';
   formData.value.brandRegistrant = '';
@@ -782,6 +785,7 @@ const handleAuthorizeTypeChange = (id: string | number) => {
 const handleBrandChange = (brandName: string) => {
   if (!brandName) {
     formData.value.brandId = '';
+    formData.value.brandNo = '';
     formData.value.brandName = '';
     formData.value.brandLogo = '';
     formData.value.brandRegistrant = '';
@@ -790,11 +794,13 @@ const handleBrandChange = (brandName: string) => {
   const selectedBrand = brandList.value.find(b => b.brandName === brandName);
   if (selectedBrand) {
     formData.value.brandId = selectedBrand.id;
+    formData.value.brandNo = selectedBrand.brandNo || '';
     formData.value.brandName = selectedBrand.brandName;
     formData.value.brandLogo = selectedBrand.brandLogo || ''; // 保存品牌LOGO
     formData.value.brandRegistrant = selectedBrand.registrationCertificate || selectedBrand.brandRegistrant || '';
     console.log('选择品牌:', { 
       brandId: formData.value.brandId, 
+      brandNo: formData.value.brandNo,
       brandName: formData.value.brandName,
       brandLogo: formData.value.brandLogo,
       brandRegistrant: formData.value.brandRegistrant
@@ -1462,6 +1468,7 @@ const handleSubmit = async () => {
       supplierId: userStore.supplierId,
       supplierNo: userStore.supplierNo,
       brandId: formData.value.brandId,
+      brandNo: formData.value.brandNo,
       brandName: formData.value.brandName,
       brandLogo: formData.value.brandLogo,
       brandRegistrant: formData.value.brandRegistrant,

+ 13 - 5
src/views/supplier/author/index.vue

@@ -76,7 +76,7 @@
       </template>
 
       <!-- 授权详情信息列表 -->
-      <el-table v-loading="loading" :data="authorizationList" border style="width: 100%">
+      <el-table v-loading="loading" :data="authorizationList" border style="width: 100%" @row-dblclick="handleRowDblClick">
         <el-table-column prop="brandName" label="品牌名称" align="center" />
         <el-table-column label="一级类目" align="center">
           <template #default="scope">
@@ -127,7 +127,7 @@
         </el-table-column>
         <el-table-column label="操作" align="center" width="120">
           <template #default="scope">
-            <el-button link type="primary" @click="handleView(scope.row)">编辑</el-button>
+            <el-button link type="primary" @click="handleEdit(scope.row)">编辑</el-button>
           </template>
         </el-table-column>
       </el-table>
@@ -501,9 +501,17 @@ const handleAdd = () => {
   router.push('/supplier/author/edit');
 };
 
-/** 查看/编辑 */
-const handleView = (row: any) => {
-  console.log('查看/编辑:', row);
+/** 行双击查看 */
+const handleRowDblClick = (row: any) => {
+  router.push({
+    path: '/supplier/author/detail',
+    query: { id: row.id }
+  });
+};
+
+/** 编辑 */
+const handleEdit = (row: any) => {
+  console.log('编辑:', row);
   router.push({
     path: '/supplier/author/edit',
     query: { id: row.id }

+ 0 - 119
src/views/supplier/info/components/AddressDialog.vue

@@ -1,119 +0,0 @@
-<template>
-  <el-dialog
-    :model-value="modelValue"
-    :title="title"
-    width="650px"
-    :close-on-click-modal="false"
-    @update:model-value="(v) => emit('update:modelValue', v)"
-  >
-    <el-form
-      ref="formRef"
-      :model="model"
-      :rules="rules"
-      label-width="120px"
-      :disabled="readonly"
-    >
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="供应商编号:">
-            <el-input v-model="model.supplierNo" disabled />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="收货人:" prop="shipperName" required>
-            <el-input v-model="model.shipperName" placeholder="请输入收货人" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="手机号码:" prop="shipperPhone" required>
-            <el-input v-model="model.shipperPhone" placeholder="请输入手机号码" />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="邮政编码:" prop="shippingPostCode">
-            <el-input v-model="model.shippingPostCode" placeholder="请输入邮政编码" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-
-      <el-row :gutter="20">
-        <el-col :span="24">
-          <el-form-item label="地址:" prop="shippingProvincial" required>
-            <el-cascader
-              :model-value="selectedAddressRegion"
-              :options="regionOptions"
-              :props="regionCascaderProps"
-              placeholder="请选择"
-              clearable
-              filterable
-              style="width: 100%;"
-              @update:model-value="handleUpdateAddressRegion"
-            />
-          </el-form-item>
-        </el-col>
-      </el-row>
-
-      <el-row :gutter="20">
-        <el-col :span="24">
-          <el-form-item label="详细地址:" prop="shippingAddress">
-            <el-input v-model="model.shippingAddress" type="textarea" :rows="3" placeholder="请输入详细地址" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="默认地址:">
-            <el-switch v-model="model.isSelf" :active-value="1" :inactive-value="0" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-    </el-form>
-
-    <template #footer>
-      <div class="dialog-footer">
-        <el-button @click="emit('update:modelValue', false)">取消</el-button>
-        <el-button v-if="!readonly" type="primary" @click="onSubmit" :loading="submitLoading">确定</el-button>
-      </div>
-    </template>
-  </el-dialog>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue';
-
-type Props = {
-  modelValue: boolean;
-  title: string;
-  readonly: boolean;
-  submitLoading: boolean;
-  model: any;
-  rules: any;
-  selectedAddressRegion: string[];
-  regionOptions: any[];
-  regionCascaderProps: any;
-  onAddressRegionChange: (value: string[]) => void;
-  onSubmit: () => void;
-};
-
-const props = defineProps<Props>();
-
-const emit = defineEmits<{
-  (e: 'update:modelValue', value: boolean): void;
-  (e: 'update:selectedAddressRegion', value: string[]): void;
-}>();
-
-const formRef = ref();
-
-defineExpose({
-  formRef
-});
-
-const handleUpdateAddressRegion = (value: string[]) => {
-  emit('update:selectedAddressRegion', value);
-  props.onAddressRegionChange(value);
-};
-</script>

+ 42 - 38
src/views/supplier/info/components/AddressTab.vue

@@ -1,47 +1,51 @@
 <template>
-  <div class="info-section">
-    <div class="section-title">地址信息列表</div>
-    <el-button icon="Plus" type="primary" @click="onAddAddress">添加地址</el-button>
-    <el-table :data="addressList" border style="width: 100%">
-      <el-table-column prop="supplierNo" label="供应商编号" align="center" />
-      <el-table-column prop="addressNo" label="地址编号" align="center" />
-      <el-table-column prop="shipperName" label="姓名" align="center" />
-      <el-table-column prop="shipperPhone" label="手机号码" align="center" />
-      <el-table-column prop="shippingProvincial" label="省份" align="center" />
-      <el-table-column prop="shippingCity" label="市" align="center" />
-      <el-table-column prop="shippingCounty" label="区县" align="center" />
-      <el-table-column label="详细地址" align="center">
-        <template #default="scope">
-          <span>{{ scope.row.shippingAddress || '-' }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column prop="shippingPostCode" label="邮政编码" align="center" />
-      <el-table-column prop="isSelf" label="默认地址" align="center">
-        <template #default="scope">
-          <span>{{ scope.row.isSelf === 1 || scope.row.isSelf === '1' ? '是' : '否' }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="操作" align="center" width="150">
-        <template #default="scope">
-          <el-button link type="primary" @click="onEditAddress(scope.row)">编辑</el-button>
-          <el-button link type="danger" @click="onDeleteAddress(scope.row)">删除</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-
-    <div v-if="addressList.length === 0" style="text-align: center; padding: 40px; color: #999;">
-      暂无地址信息
+  <div class="tab-content">
+    <div class="info-section">
+      <div class="section-title-row">
+        <div class="section-title-left">
+          <span class="section-title-text">地址信息列表</span>
+        </div>
+        <el-button v-if="!isViewMode" icon="Plus" type="primary" @click="emit('add')">添加地址</el-button>
+      </div>
+      <el-table :data="addressList" border style="width: 100%">
+        <el-table-column prop="supplierNo" label="供应商编号" align="center" />
+        <el-table-column prop="addressNo" label="地址编号" align="center" />
+        <el-table-column prop="shipperName" label="姓名" align="center" />
+        <el-table-column prop="shipperPhone" label="手机号码" align="center" />
+        <el-table-column prop="shippingProvincial" label="省份" align="center" />
+        <el-table-column prop="shippingCity" label="市" align="center" />
+        <el-table-column prop="shippingCounty" label="区县" align="center" />
+        <el-table-column label="详细地址" align="center">
+          <template #default="scope">
+            <span>{{ scope.row.shippingAddress || '-' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="shippingPostCode" label="邮政编码" align="center" />
+        <el-table-column prop="isSelf" label="默认地址" align="center">
+          <template #default="scope">
+            <span>{{ scope.row.isSelf === 1 || scope.row.isSelf === '1' ? '是' : '否' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="center" width="150">
+          <template #default="scope">
+            <el-button v-if="!isViewMode" link type="primary" @click="emit('edit', scope.row)">编辑</el-button>
+            <el-button v-if="!isViewMode" link type="danger" @click="emit('delete', scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
     </div>
   </div>
 </template>
 
 <script setup lang="ts">
-type Props = {
+defineProps<{
   addressList: any[];
-  onAddAddress: () => void;
-  onEditAddress: (row: any) => void;
-  onDeleteAddress: (row: any) => void;
-};
+  isViewMode: boolean;
+}>();
 
-defineProps<Props>();
+const emit = defineEmits<{
+  (e: 'add'): void;
+  (e: 'edit', row: any): void;
+  (e: 'delete', row: any): void;
+}>();
 </script>

+ 364 - 118
src/views/supplier/info/components/BasicInfoTab.vue

@@ -1,183 +1,175 @@
 <template>
-  <div>
+  <div class="tab-content">
     <div class="info-section">
       <div class="section-title-row">
         <div class="section-title-left">
           <span class="section-title-text">企业基本信息</span>
           <span class="section-title-divider">/</span>
           <span class="supplier-no">供应商编码:{{ detailData.supplierNo }}</span>
+          <el-tag 
+            v-if="detailData?.supplyStatus !== undefined && detailData?.supplyStatus !== null" 
+            :type="getStatusConfig(detailData.supplyStatus).type" 
+            effect="light" 
+            style="margin-left: 8px;"
+          >
+            {{ getStatusConfig(detailData.supplyStatus).text }}
+          </el-tag>
+        </div>
+        <div v-if="!isViewMode" class="section-title-actions">
+          <el-button type="primary" :icon="isEditing ? 'Document' : 'Edit'" @click="onPrimaryAction">
+            {{ isEditing ? '保存' : '编辑' }}
+          </el-button>
+          <el-button v-if="isEditing" @click="onCancelEdit">取消</el-button>
         </div>
-        <el-button type="primary" icon="Document" @click="onSave">保存</el-button>
       </div>
 
-      <el-form :model="detailData" label-width="100px" class="detail-form">
-        <el-row :gutter="40" class="form-row">
+      <el-form :model="detailData" label-width="120px" class="detail-form">
+        <el-row :gutter="12" class="form-row">
           <el-col :span="8">
             <el-form-item label="所属公司:" required>
-              <el-select v-model="detailData.ownedCompany" placeholder="请选择" clearable filterable style="width: 100%;" disabled>
-                <el-option
-                  v-for="company in companyOptions"
-                  :key="company.id"
-                  :label="company.companyName"
-                  :value="company.id"
-                />
+              <el-select v-model="detailData.ownedCompany" placeholder="请选择" clearable filterable style="width: 100%;" :disabled="!isAddMode || !isEditing">
+                <el-option v-for="company in companyOptions" :key="company.id" :label="company.companyName" :value="company.id" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="企业名称:" required>
-              <el-input v-model="detailData.enterpriseName" placeholder="请输入企业名称" disabled>
-                <template #append v-if="isAddMode && !isBasicInfoSaved">
-                  <el-button
-                    type="primary"
-                    @click="onGetBusinessInfo"
-                    :loading="businessInfoLoading"
-                    :icon="businessInfoLoading ? '' : 'Search'"
-                  >
-                    {{ businessInfoLoading ? '获取中...' : '获取工商信息' }}
-                  </el-button>
-                </template>
-              </el-input>
+              <el-input v-model="detailData.enterpriseName" placeholder="请输入企业名称" :disabled="!isAddMode || !isEditing" />
             </el-form-item>
           </el-col>
           <el-col :span="8">
-            <el-form-item label="工商名称:">
-              <el-input v-model="detailData.businessName" placeholder="请输入工商名称" disabled />
+            <el-form-item label="工商名称:" required>
+              <el-input
+                v-model="detailData.businessName"
+                placeholder="请输入工商名称"
+                :disabled="!isEditing"
+              />
             </el-form-item>
           </el-col>
         </el-row>
 
-        <el-row :gutter="40" class="form-row">
+        <el-row :gutter="12" class="form-row">
           <el-col :span="8">
             <el-form-item label="企业简称:" required>
-              <el-input v-model="detailData.shortName" placeholder="请输入企业简称" />
+              <el-input v-model="detailData.shortName" placeholder="请输入企业简称" :disabled="!isEditing" />
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="供应商等级:" required>
-              <el-select v-model="detailData.cooperateLevel" placeholder="请选择" clearable filterable style="width: 100%;" disabled>
-                <el-option
-                  v-for="level in supplierLevelOptions"
-                  :key="level.id"
-                  :label="level.supplierLevelName"
-                  :value="String(level.id)"
-                />
+              <el-select v-model="detailData.cooperateLevel" placeholder="请选择" clearable filterable style="width: 100%;" :disabled="!isAddMode || !isEditing">
+                <el-option v-for="level in supplierLevelOptions" :key="level.id" :label="level.supplierLevelName" :value="String(level.id)" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="企业规模:" required>
-              <el-select v-model="detailData.membershipSize" placeholder="请选择" clearable filterable style="width: 100%;" disabled>
-                <el-option
-                  v-for="scale in enterpriseScaleOptions"
-                  :key="scale.id"
-                  :label="scale.enterpriseScaleName"
-                  :value="scale.id"
-                />
+              <el-select v-model="detailData.membershipSize" placeholder="请选择" clearable filterable style="width: 100%;" :disabled="!isEditing">
+                <el-option v-for="scale in enterpriseScaleOptions" :key="scale.id" :label="scale.enterpriseScaleName" :value="scale.id" />
               </el-select>
             </el-form-item>
           </el-col>
         </el-row>
 
-        <el-row :gutter="40" class="form-row">
+        <el-row :gutter="12" class="form-row">
           <el-col :span="8">
             <el-form-item label="行业类别:" required>
-              <el-select v-model="detailData.industrCategory" placeholder="请选择" clearable filterable style="width: 100%;" disabled>
-                <el-option
-                  v-for="industry in industryCategoryOptions"
-                  :key="industry.id"
-                  :label="industry.industryCategoryName"
-                  :value="industry.id"
-                />
+              <el-select v-model="detailData.industrCategory" placeholder="请选择" clearable filterable style="width: 100%;" :disabled="!isAddMode || !isEditing">
+                <el-option v-for="industry in industryCategoryOptions" :key="industry.id" :label="industry.industryCategoryName" :value="industry.id" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="供应商类型:" required>
-              <el-select v-model="detailData.supplierType" placeholder="请选择" clearable filterable style="width: 100%;" disabled>
-                <el-option
-                  v-for="type in supplierTypeOptions"
-                  :key="type.id"
-                  :label="type.supplierTypeName"
-                  :value="type.id"
-                />
+              <el-select v-model="detailData.supplierType" placeholder="请选择" clearable filterable style="width: 100%;" :disabled="!isAddMode || !isEditing">
+                <el-option v-for="type in supplierTypeOptions" :key="type.id" :label="type.supplierTypeName" :value="type.id" />
               </el-select>
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="固定电话:">
-              <el-input v-model="detailData.fixedPhone" placeholder="请输入固定电话" disabled />
+              <el-input
+                v-model="detailData.fixedPhone"
+                placeholder="请输入固定电话"
+                type="tel"
+                @input="onFixedPhoneInput"
+                :disabled="!isEditing"
+              />
             </el-form-item>
           </el-col>
         </el-row>
 
-        <el-row :gutter="40" class="form-row">
+        <el-row :gutter="12" class="form-row">
           <el-col :span="8">
             <el-form-item label="传真:">
-              <el-input v-model="detailData.fax" placeholder="请输入传真" disabled />
+              <el-input v-model="detailData.fax" placeholder="请输入传真" :disabled="!isEditing" />
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="企业邮箱:">
-              <el-input v-model="detailData.mailbox" placeholder="请输入企业邮箱" disabled />
+              <el-input v-model="detailData.mailbox" placeholder="请输入企业邮箱" :disabled="!isEditing" />
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="开始时间:">
-              <el-date-picker
-                v-model="detailData.validityFromDate"
-                type="date"
-                placeholder="请选择"
-                style="width: 100%;"
-                disabled
-              />
+              <el-date-picker v-model="detailData.validityFromDate" type="date" placeholder="请选择" style="width: 100%;" :disabled="!isAddMode || !isEditing" />
             </el-form-item>
           </el-col>
         </el-row>
 
-        <el-row :gutter="40" class="form-row">
+        <el-row :gutter="12" class="form-row">
           <el-col :span="8">
             <el-form-item label="结束时间:">
-              <el-date-picker
-                v-model="detailData.validityToDate"
-                type="date"
-                placeholder="请选择"
-                style="width: 100%;"
-                disabled
-              />
+              <el-date-picker v-model="detailData.validityToDate" type="date" placeholder="请选择" style="width: 100%;" :disabled="!isAddMode || !isEditing" />
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="邮政编码:">
-              <el-input v-model="detailData.postCode" placeholder="请输入邮政编码" disabled />
+              <el-input v-model="detailData.postCode" placeholder="请输入邮政编码" :disabled="!isEditing" />
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="网址:">
-              <el-input v-model="detailData.url" placeholder="请输入网址" disabled />
+              <el-input v-model="detailData.url" placeholder="请输入网址" :disabled="!isEditing" />
             </el-form-item>
           </el-col>
         </el-row>
 
-        <el-row :gutter="40" class="form-row">
+        <el-row :gutter="12" class="form-row">
           <el-col :span="8">
             <el-form-item label="详细地址:" required>
-              <el-cascader
-                :model-value="selectedOfficeRegion"
-                :options="regionOptions"
-                :props="regionCascaderProps"
-                placeholder="请选择省市区"
-                clearable
-                filterable
-                style="width: 100%;"
-                @update:model-value="onOfficeRegionChange"
-                disabled
-              />
+              <el-cascader v-model="selectedOfficeRegionProxy" :options="regionOptions" placeholder="请选择省市区" clearable filterable style="width: 100%;" @change="onOfficeRegionChange" :disabled="!isEditing" />
             </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label=" " label-width="0">
-              <el-input v-model="detailData.officeAddress" placeholder="请输入详细地址" disabled />
+              <el-input v-model="detailData.officeAddress" placeholder="请输入详细地址" :disabled="!isEditing" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="12" class="form-row">
+          <el-col :span="8">
+            <el-form-item label="营业执照:">
+              <ImageUpload
+                v-model="detailData.businessLicense"
+                :limit="1"
+                :disabled="isViewMode || !isEditing"
+                :file-size="5"
+                :file-type="['png', 'jpg', 'jpeg']"
+                :is-show-tip="false"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="法人身份证照片:">
+              <ImageUpload
+                v-model="detailData.personImage"
+                :limit="1"
+                :disabled="isViewMode || !isEditing"
+                :file-size="5"
+                :file-type="['png', 'jpg', 'jpeg']"
+                :is-show-tip="false"
+              />
             </el-form-item>
           </el-col>
         </el-row>
@@ -187,109 +179,363 @@
     <div class="info-section">
       <div class="section-title">工商信息</div>
 
-      <el-row :gutter="40" class="form-row">
+      <el-row :gutter="12" class="form-row">
         <el-col :span="8">
           <div class="form-item">
             <span class="label">企业工商名称:</span>
-            <span class="value">{{ businessInfo.businessName || detailData.businessName || '' }}</span>
+            <span class="value">{{ businessInfo?.businessName || detailData.businessName || '' }}</span>
           </div>
         </el-col>
         <el-col :span="8">
           <div class="form-item">
             <span class="label">登记机关:</span>
-            <span class="value">{{ businessInfo.registrationAuthority || '' }}</span>
+            <span class="value">{{ businessInfo?.registrationAuthority || '' }}</span>
           </div>
         </el-col>
         <el-col :span="8">
           <div class="form-item">
             <span class="label">成立日期:</span>
-            <span class="value">{{ formatDate(businessInfo.establishmentDate) || '' }}</span>
+            <span class="value">{{ formatDate(businessInfo?.establishmentDate) || '' }}</span>
           </div>
         </el-col>
       </el-row>
 
-      <el-row :gutter="40" class="form-row">
+      <el-row :gutter="12" class="form-row">
         <el-col :span="8">
           <div class="form-item">
             <span class="label">登记状态:</span>
-            <span class="value">{{ businessInfo.registrationStatus || '' }}</span>
+            <span class="value">{{ businessInfo?.registrationStatus || '' }}</span>
           </div>
         </el-col>
         <el-col :span="8">
           <div class="form-item">
             <span class="label">实缴资本:</span>
-            <span class="value">{{ businessInfo.paidInCapital || '' }}</span>
+            <span class="value">{{ businessInfo?.paidInCapital || '' }}</span>
           </div>
         </el-col>
         <el-col :span="8">
           <div class="form-item">
             <span class="label">社会信用代码:</span>
-            <span class="value">{{ businessInfo.socialCreditCode || detailData.socialCreditCode || '' }}</span>
+            <span class="value">{{ businessInfo?.socialCreditCode || detailData.socialCreditCode || '' }}</span>
           </div>
         </el-col>
       </el-row>
 
-      <el-row :gutter="40" class="form-row">
+      <el-row :gutter="12" class="form-row">
         <el-col :span="8">
           <div class="form-item">
             <span class="label">法人姓名:</span>
-            <span class="value">{{ businessInfo.legalPersonName || '' }}</span>
+            <span class="value">{{ businessInfo?.legalPersonName || '' }}</span>
           </div>
         </el-col>
         <el-col :span="8">
           <div class="form-item">
             <span class="label">注册资本:</span>
-            <span class="value">{{ businessInfo.registeredCapital || '' }}</span>
+            <span class="value">{{ businessInfo?.registeredCapital || '' }}</span>
           </div>
         </el-col>
       </el-row>
 
-      <el-row :gutter="40" class="form-row">
+      <el-row :gutter="12" class="form-row">
         <el-col :span="24">
           <div class="form-item">
             <span class="label">工商地址:</span>
-            <el-input v-model="businessInfo.businessAddress" placeholder="工商地址" style="width: 70%;" />
+            <el-input v-model="businessInfo.businessAddress" placeholder="工商地址" style="width: 70%;" :disabled="!isEditing" />
           </div>
         </el-col>
       </el-row>
+
     </div>
 
     <div class="info-section">
-      <div class="section-title">付款信息</div>
+      <div class="section-title-row">
+        <div class="section-title-left">
+          <span class="section-title-text">付款信息</span>
+        </div>
+      </div>
       <el-table :data="paymentInfoList" border style="width: 100%">
-        <el-table-column prop="num" label="是否主账号" align="center">
+        <el-table-column prop="isture" label="是否主账号" align="center">
           <template #default="scope">
-            <span>{{ scope.row.num === 1 ? '是' : '否' }}</span>
+            <span>{{ Number(scope.row.isture) === 1 ? '是' : '否' }}</span>
           </template>
         </el-table-column>
         <el-table-column prop="bankName" label="开户银行" align="center" />
         <el-table-column prop="bankNo" label="银行账户" align="center" />
       </el-table>
+
+
     </div>
   </div>
 </template>
 
 <script setup lang="ts">
-type Props = {
+import ImageUpload from '@/components/ImageUpload/index.vue';
+import { scmEditInfo } from '@/api/supplier/info';
+import { ref, computed, watch } from 'vue';
+import { useRoute } from 'vue-router';
+
+const props = defineProps<{
   detailData: any;
   companyOptions: any[];
-  supplierLevelOptions: any[];
   enterpriseScaleOptions: any[];
   industryCategoryOptions: any[];
+  supplierLevelOptions: any[];
   supplierTypeOptions: any[];
-  selectedOfficeRegion: any;
-  regionOptions: any[];
-  regionCascaderProps: any;
   isAddMode: boolean;
+  isViewMode: boolean;
   isBasicInfoSaved: boolean;
-  businessInfo: any;
-  businessInfoLoading: boolean;
+  businessInfo?: any;
+  businessInfoLoading?: boolean;
+  regionOptions: any[];
+  selectedOfficeRegion: string[];
   paymentInfoList: any[];
-  formatDate: (date: string | Date) => string;
-  onOfficeRegionChange: (value: string[]) => void;
-  onGetBusinessInfo: () => void;
-  onSave: () => void;
+  formatDate: (date: any) => string;
+}>();
+
+const emit = defineEmits<{
+  (e: 'save'): void;
+  (e: 'officeRegionChange', value: string[]): void;
+  (e: 'update:selectedOfficeRegion', value: string[]): void;
+  (e: 'addPayment'): void;
+  (e: 'viewPayment', row: any): void;
+  (e: 'editPayment', row: any): void;
+}>();
+
+const selectedOfficeRegionProxy = computed({
+  get: () => props.selectedOfficeRegion,
+  set: (value) => emit('update:selectedOfficeRegion', value)
+});
+
+const onOfficeRegionChange = (val: unknown) => {
+  emit('officeRegionChange', (val || []) as string[]);
+};
+
+const onFixedPhoneInput = (val: string) => {
+  const next = (val || '').replace(/\D+/g, '');
+  if (next !== props.detailData.fixedPhone) {
+    props.detailData.fixedPhone = next;
+  }
+};
+
+const safeFormatDate = (date: any) => {
+  return typeof props.formatDate === 'function' ? props.formatDate(date) : '';
 };
 
-defineProps<Props>();
+const isEditing = ref(false);
+
+const getStatusConfig = (status: string | number) => {
+  const s = String(status);
+  const map: Record<string, { text: string; type: 'success' | 'info' | 'warning' | 'primary' | 'danger' }> = {
+    '0': { text: '待审核', type: 'warning' },
+    '1': { text: '生效', type: 'success' },
+    '2': { text: '停止合作', type: 'danger' },
+    '3': { text: '审核不通过', type: 'danger' },
+    '4': { text: '待修改审核', type: 'warning' }
+  };
+  return map[s] || { text: '未知状态', type: 'info' };
+};
+
+const route = useRoute();
+const saveLoading = ref(false);
+const backupDetailData = ref<any>(null);
+const backupOfficeRegion = ref<string[] | null>(null);
+const backupBusinessAddress = ref<string | null>(null);
+const originDetailData = ref<any>(null);
+
+const makeSnapshot = (data: any) => {
+  try {
+    return JSON.parse(JSON.stringify(data ?? {}));
+  } catch (e) {
+    return data;
+  }
+};
+
+const getChangedFields = (origin: any, current: any) => {
+  const o = origin ?? {};
+  const c = current ?? {};
+  const changed: any = {};
+  Object.keys(c).forEach((k) => {
+    const ov = (o as any)[k];
+    const cv = (c as any)[k];
+    try {
+      if (JSON.stringify(ov) !== JSON.stringify(cv)) {
+        changed[k] = cv;
+      }
+    } catch (e) {
+      if (ov !== cv) {
+        changed[k] = cv;
+      }
+    }
+  });
+  return changed;
+};
+
+watch(
+  () => (props.detailData as any)?.id,
+  () => {
+    originDetailData.value = makeSnapshot(props.detailData);
+  },
+  { immediate: true }
+);
+
+const applySnapshot = (target: any, snapshot: any) => {
+  if (!target || !snapshot || typeof target !== 'object') return;
+  Object.keys(target).forEach((k) => {
+    delete target[k];
+  });
+  Object.assign(target, makeSnapshot(snapshot));
+};
+
+const onPrimaryAction = () => {
+  if (!isEditing.value) {
+    backupDetailData.value = makeSnapshot(props.detailData);
+    backupOfficeRegion.value = makeSnapshot(props.selectedOfficeRegion);
+    backupBusinessAddress.value = props.businessInfo?.businessAddress ?? null;
+    isEditing.value = true;
+    return;
+  }
+  if (saveLoading.value) return;
+  saveLoading.value = true;
+  const id = (route.query.id as string) || (props.detailData as any)?.id;
+  const changed = getChangedFields(originDetailData.value, props.detailData);
+  scmEditInfo({
+    ...changed,
+    id
+  } as any)
+    .then(() => {
+      originDetailData.value = makeSnapshot(props.detailData);
+      emit('save');
+      isEditing.value = false;
+    })
+    .finally(() => {
+      saveLoading.value = false;
+    });
+};
+
+const onCancelEdit = () => {
+  if (!isEditing.value) return;
+  applySnapshot(props.detailData, backupDetailData.value);
+  if (backupOfficeRegion.value) {
+    emit('update:selectedOfficeRegion', makeSnapshot(backupOfficeRegion.value));
+    emit('officeRegionChange', makeSnapshot(backupOfficeRegion.value));
+  }
+  if (props.businessInfo && backupBusinessAddress.value !== null) {
+    props.businessInfo.businessAddress = backupBusinessAddress.value;
+  }
+  isEditing.value = false;
+};
 </script>
+
+<style scoped>
+.tab-content {
+  --el-component-size: 24px;
+  padding: 16px;
+}
+
+.detail-form :deep(.el-form-item__label) {
+  white-space: nowrap;
+}
+
+.detail-form :deep(.form-row) {
+  margin-bottom: 2px;
+}
+
+.detail-form :deep(.el-form-item) {
+  margin-bottom: 8px;
+}
+
+.tab-content :deep(.form-row) {
+  margin-bottom: 2px;
+}
+
+.tab-content :deep(.el-form-item) {
+  margin-bottom: 8px;
+}
+
+.tab-content :deep(.info-section) {
+  margin-bottom: 20px;
+}
+
+.tab-content :deep(.section-title),
+.tab-content :deep(.section-title-row) {
+  margin-bottom: 12px;
+  padding-bottom: 8px;
+}
+
+.tab-content :deep(.section-title-text) {
+  font-size: 14px;
+}
+
+.tab-content :deep(.section-title-actions) {
+  display: flex;
+  gap: 8px;
+}
+
+.tab-content :deep(.supplier-no) {
+  font-size: 13px;
+}
+
+.tab-content :deep(.el-form-item__label) {
+  font-size: 13px;
+  height: var(--el-component-size);
+  line-height: var(--el-component-size);
+  padding-top: 0;
+  padding-bottom: 0;
+}
+
+.tab-content :deep(.form-item) {
+  line-height: 24px;
+  font-size: 13px;
+}
+
+.detail-form :deep(.el-input),
+.detail-form :deep(.el-select),
+.detail-form :deep(.el-date-editor),
+.detail-form :deep(.el-cascader) {
+  width: 100%;
+}
+
+.detail-form :deep(.el-input__wrapper),
+.detail-form :deep(.el-select__wrapper),
+.detail-form :deep(.el-date-editor),
+.detail-form :deep(.el-cascader) {
+  min-height: var(--el-component-size);
+}
+
+.detail-form :deep(.el-input__inner) {
+  height: var(--el-component-size);
+  line-height: var(--el-component-size);
+}
+
+.detail-form :deep(.el-form-item__content) {
+  align-items: center;
+  min-height: var(--el-component-size);
+}
+
+.detail-form :deep(.el-input__wrapper),
+.detail-form :deep(.el-select__wrapper),
+.detail-form :deep(.el-date-editor),
+.detail-form :deep(.el-cascader) {
+  height: var(--el-component-size);
+  align-items: center;
+  padding-top: 0;
+  padding-bottom: 0;
+}
+
+.detail-form :deep(.el-select__selected-item),
+.detail-form :deep(.el-select__input),
+.detail-form :deep(.el-range-input) {
+  line-height: var(--el-component-size);
+}
+
+:deep(.component-upload-image .el-upload--picture-card),
+:deep(.component-upload-image .el-upload-list--picture-card .el-upload-list__item) {
+  width: 64px;
+  height: 64px;
+}
+
+:deep(.component-upload-image .el-upload-list--picture-card .el-upload-list__item-thumbnail) {
+  width: 64px;
+  height: 64px;
+}
+</style>

+ 0 - 88
src/views/supplier/info/components/BrandDialog.vue

@@ -1,88 +0,0 @@
-<template>
-  <el-dialog
-    :model-value="modelValue"
-    title="添加品牌"
-    width="600px"
-    :close-on-click-modal="false"
-    @update:model-value="(v) => emit('update:modelValue', v)"
-  >
-    <div style="margin-bottom: 20px;">
-      <el-form :inline="true" @submit.prevent>
-        <el-form-item label="品牌名称:">
-          <el-input
-            :model-value="keyword"
-            placeholder="请输入品牌名称"
-            style="width: 200px;"
-            @update:model-value="(v) => emit('update:keyword', v)"
-            @keyup.enter="onSearch"
-          />
-        </el-form-item>
-        <el-form-item>
-          <el-button type="primary" @click="onSearch" :loading="searchLoading">搜索</el-button>
-          <el-button type="primary" @click="onAddManual">添加</el-button>
-        </el-form-item>
-      </el-form>
-    </div>
-
-    <div v-if="searchResults.length > 0" class="brand-search-results">
-      <div class="search-results-title">搜索结果:</div>
-      <div
-        class="brand-result-item"
-        v-for="brand in searchResults"
-        :key="brand.id"
-        @click="onAdd(brand)"
-      >
-        <span class="brand-result-name">{{ brand.brandName }}</span>
-        <span class="brand-result-no">编号: {{ brand.brandNo }}</span>
-      </div>
-    </div>
-
-    <div class="selected-brands-section">
-      <div class="section-label">已选择品牌:</div>
-      <div class="brand-tags-container">
-        <el-tag
-          v-for="brand in tempSelectedBrands"
-          :key="brand.id"
-          closable
-          @close="onRemoveTemp(brand)"
-          type="info"
-          style="margin-right: 10px; margin-bottom: 10px;"
-        >
-          {{ brand.brandName }}
-        </el-tag>
-        <span v-if="tempSelectedBrands.length === 0" style="color: #999; font-size: 14px;">暂无已选择品牌</span>
-      </div>
-    </div>
-
-    <template #footer>
-      <div class="dialog-footer">
-        <el-button @click="onClose">取消</el-button>
-        <el-button type="primary" @click="onSubmit" :loading="submitLoading">保存</el-button>
-      </div>
-    </template>
-  </el-dialog>
-</template>
-
-<script setup lang="ts">
-type Props = {
-  modelValue: boolean;
-  keyword: string;
-  searchResults: any[];
-  searchLoading: boolean;
-  tempSelectedBrands: any[];
-  submitLoading: boolean;
-  onSearch: () => void;
-  onAdd: (brand: any) => void;
-  onAddManual: () => void;
-  onRemoveTemp: (brand: any) => void;
-  onClose: () => void;
-  onSubmit: () => void;
-};
-
-defineProps<Props>();
-
-const emit = defineEmits<{
-  (e: 'update:modelValue', value: boolean): void;
-  (e: 'update:keyword', value: string): void;
-}>();
-</script>

+ 0 - 122
src/views/supplier/info/components/ContactDialog.vue

@@ -1,122 +0,0 @@
-<template>
-  <el-dialog
-    :model-value="modelValue"
-    :title="title"
-    width="900px"
-    :close-on-click-modal="false"
-    @update:model-value="(v) => emit('update:modelValue', v)"
-  >
-    <el-form
-      ref="formRef"
-      :model="model"
-      :rules="rules"
-      label-width="140px"
-      :disabled="readonly"
-    >
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="员工姓名:" prop="userName">
-            <el-input v-model="model.userName" placeholder="请输入员工姓名" />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="手机号:" prop="phone">
-            <el-input v-model="model.phone" placeholder="请输入手机号" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="部门:" prop="departmentNo">
-            <el-input v-model="model.departmentNo" placeholder="请输入部门" />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="职位:" prop="position">
-            <el-input v-model="model.position" placeholder="请输入职位" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="角色:" prop="roleNo">
-            <el-input v-model="model.roleNo" placeholder="请输入角色" />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="邮箱:" prop="email">
-            <el-input v-model="model.email" placeholder="请输入邮箱" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="主要联系人:" prop="isPrimaryContact">
-            <el-select v-model="model.isPrimaryContact" placeholder="请选择" style="width: 100%;">
-              <el-option label="是" value="1" />
-              <el-option label="否" value="0" />
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="允许登录供应商端:" prop="isRegister">
-            <el-select v-model="model.isRegister" placeholder="请选择" style="width: 100%;">
-              <el-option label="是" value="1" />
-              <el-option label="否" value="0" />
-            </el-select>
-          </el-form-item>
-        </el-col>
-      </el-row>
-
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="传真:" prop="fax">
-            <el-input v-model="model.fax" placeholder="请输入传真" />
-          </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="model.remark" type="textarea" :rows="3" placeholder="请输入备注" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-    </el-form>
-
-    <template #footer>
-      <div class="dialog-footer">
-        <el-button @click="emit('update:modelValue', false)">取消</el-button>
-        <el-button v-if="!readonly" type="primary" @click="onSubmit" :loading="submitLoading">确定</el-button>
-      </div>
-    </template>
-  </el-dialog>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue';
-
-type Props = {
-  modelValue: boolean;
-  title: string;
-  readonly: boolean;
-  submitLoading: boolean;
-  model: any;
-  rules: any;
-  onSubmit: () => void;
-};
-
-defineProps<Props>();
-
-const emit = defineEmits<{ (e: 'update:modelValue', value: boolean): void }>();
-
-const formRef = ref();
-
-defineExpose({
-  formRef
-});
-</script>

+ 45 - 38
src/views/supplier/info/components/ContactTab.vue

@@ -1,49 +1,56 @@
 <template>
-  <div class="info-section">
-    <div class="section-title-row">
-      <div class="section-title-left">
-        <span class="section-title-text">业务联系人</span>
+  <div class="tab-content">
+    <div class="info-section">
+      <div class="section-title-row">
+        <div class="section-title-left">
+          <span class="section-title-text">业务联系人</span>
+        </div>
+        <el-button v-if="!isViewMode" type="primary" icon="Plus" @click="emit('add')">新增联系人</el-button>
       </div>
-      <el-button type="primary" icon="Plus" @click="onAddContact">新增联系人</el-button>
-    </div>
 
-    <el-table v-loading="contactLoading" :data="contactList" border style="width: 100%">
-      <el-table-column prop="supplierName" label="所属供应商" align="center" />
-      <el-table-column prop="userNo" label="用户ID" align="center" />
-      <el-table-column prop="abutment_no" label="A10标识号" align="center" />
-      <el-table-column prop="userName" label="员工姓名" align="center" />
-      <el-table-column prop="phone" label="手机号" align="center" />
-      <el-table-column prop="roleNo" label="角色" align="center" />
-      <el-table-column prop="departmentNo" label="部门" align="center" />
-      <el-table-column prop="position" label="职位" align="center" />
-      <el-table-column prop="isPrimaryContact" label="主要联系人" align="center">
-        <template #default="scope">
-          <span>{{ scope.row.isPrimaryContact === '1' ? '是' : '否' }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column prop="isRegister" label="允许登录供应商端" align="center">
-        <template #default="scope">
-          <span>{{ scope.row.isRegister === '1' ? '是' : '否' }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="操作" align="center">
-        <template #default="scope">
-          <el-button link type="primary" @click="onViewContact(scope.row)">查看</el-button>
-          <el-button link type="primary" @click="onEditContact(scope.row)">编辑</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
+      <el-table v-loading="contactLoading" :data="contactList" border style="width: 100%">
+        
+        <el-table-column prop="userNo" label="用户ID" align="center" />
+        
+        <el-table-column prop="userName" label="员工姓名" align="center" />
+        <el-table-column prop="phone" label="手机号" align="center" />
+        <el-table-column prop="roleNo" label="角色" align="center" />
+        <el-table-column prop="departmentNo" label="部门" align="center" />
+        <el-table-column prop="position" label="职位" align="center" />
+        <el-table-column prop="isPrimaryContact" label="主要联系人" align="center">
+          <template #default="scope">
+            <span>{{ scope.row.isPrimaryContact === '1' ? '是' : '否' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="isRegister" label="允许登录供应商端" align="center">
+          <template #default="scope">
+            <span>{{ scope.row.isRegister === '1' ? '是' : '否' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="center">
+          <template #default="scope">
+            <el-button v-if="!isViewMode" link type="primary" @click="emit('edit', scope.row)">编辑</el-button>
+            <el-button v-if="!isViewMode" link type="primary" @click="emit('resetPassword', scope.row)">重置密码</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
   </div>
 </template>
 
 <script setup lang="ts">
-type Props = {
+defineProps<{
+  contactSearchParams: { userNo: string; userName: string };
   contactList: any[];
   contactLoading: boolean;
-  onAddContact: () => void;
-  onViewContact: (row: any) => void;
-  onEditContact: (row: any) => void;
-};
+  isViewMode: boolean;
+}>();
 
-defineProps<Props>();
+const emit = defineEmits<{
+  (e: 'search'): void;
+  (e: 'reset'): void;
+  (e: 'add'): void;
+  (e: 'edit', row: any): void;
+  (e: 'resetPassword', row: any): void;
+}>();
 </script>

+ 0 - 161
src/views/supplier/info/components/ContractDialog.vue

@@ -1,161 +0,0 @@
-<template>
-  <el-dialog
-    :model-value="modelValue"
-    :title="title"
-    width="900px"
-    :close-on-click-modal="false"
-    @update:model-value="(v) => emit('update:modelValue', v)"
-  >
-    <el-form
-      ref="formRef"
-      :model="model"
-      :rules="rules"
-      label-width="140px"
-      :disabled="readonly"
-    >
-      <el-row :gutter="20">
-        <el-col :span="24">
-          <el-form-item label="合同名称:" prop="contractName">
-            <el-input v-model="model.contractName" placeholder="请输入合同名称" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="合同类型:" prop="contractType">
-            <el-select v-model="model.contractType" placeholder="请选择" style="width: 100%;">
-              <el-option
-                v-for="item in contractTypeDict"
-                :key="item.dictValue"
-                :label="item.dictLabel"
-                :value="item.dictValue"
-              />
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="提醒时间:" prop="demandReminderTime">
-            <el-input-number v-model="model.demandReminderTime" :min="1" :max="365" style="width: 150px;" />
-            <span style="margin-left: 10px;">天</span>
-          </el-form-item>
-        </el-col>
-      </el-row>
-
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="开始时间:" prop="contractStartTime">
-            <el-date-picker v-model="model.contractStartTime" type="date" placeholder="请选择" style="width: 100%;" />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="截止时间:" prop="contractEndTime">
-            <el-date-picker v-model="model.contractEndTime" type="date" placeholder="请选择" style="width: 100%;" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="开票类型:" prop="invoiceType">
-            <el-select v-model="model.invoiceType" placeholder="请选择" style="width: 100%;">
-              <el-option
-                v-for="item in invoiceTypeList"
-                :key="item.id"
-                :label="item.invoiceTypeName"
-                :value="item.id"
-              />
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="合同金额:" prop="contractAmount">
-            <el-input v-model="model.contractAmount" placeholder="请输入">
-              <template #append>万元</template>
-            </el-input>
-          </el-form-item>
-        </el-col>
-      </el-row>
-
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-form-item label="税率:" prop="taxRate">
-            <el-select v-model="model.taxRate" placeholder="请选择" style="width: 100%;">
-              <el-option v-for="item in taxRateList" :key="item.id" :label="item.taxrateName" :value="item.id" />
-            </el-select>
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="结算方式:" prop="settlementMethod">
-            <el-select v-model="model.settlementMethod" placeholder="请选择" style="width: 100%;">
-              <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="24">
-          <el-form-item label="合同附件:" prop="contractAttachment">
-            <FileUpload
-              v-model="model.contractAttachment"
-              :limit="10"
-              :file-size="50"
-              :file-type="['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'pdf']"
-              :disabled="readonly"
-            />
-          </el-form-item>
-        </el-col>
-      </el-row>
-
-      <el-row :gutter="20">
-        <el-col :span="24">
-          <el-form-item label="合同说明:" prop="contractDescription">
-            <el-input v-model="model.contractDescription" type="textarea" :rows="4" placeholder="请输入合同说明" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-    </el-form>
-
-    <template #footer>
-      <div class="dialog-footer">
-        <el-button @click="emit('update:modelValue', false)">取消</el-button>
-        <el-button v-if="!readonly" type="primary" @click="onSubmit" :loading="submitLoading">确定</el-button>
-      </div>
-    </template>
-  </el-dialog>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue';
-import FileUpload from '@/components/FileUpload/index.vue';
-
-type Props = {
-  modelValue: boolean;
-  title: string;
-  readonly: boolean;
-  submitLoading: boolean;
-  model: any;
-  rules: any;
-  contractTypeDict: any[];
-  taxRateList: any[];
-  settlementMethodList: any[];
-  invoiceTypeList: any[];
-  onSubmit: () => void;
-};
-
-defineProps<Props>();
-
-const emit = defineEmits<{ (e: 'update:modelValue', value: boolean): void }>();
-
-const formRef = ref();
-
-defineExpose({
-  formRef
-});
-</script>

+ 106 - 89
src/views/supplier/info/components/ContractTab.vue

@@ -1,103 +1,120 @@
 <template>
-  <div class="info-section">
-    <el-form :model="contractSearchParams" :inline="true" style="margin-bottom: 20px;">
-      <el-form-item label="合同编号">
-        <el-input v-model="contractSearchParams.contractNo" placeholder="请输入合同编号" clearable style="width: 200px;" />
-      </el-form-item>
-      <el-form-item label="合同名称">
-        <el-input v-model="contractSearchParams.contractName" placeholder="请输入合同名称" clearable style="width: 200px;" />
-      </el-form-item>
-      <el-form-item label="合同类型">
-        <el-select v-model="contractSearchParams.contractType" placeholder="请选择" clearable filterable style="width: 150px;">
-          <el-option label="年度合作" value="0" />
-          <el-option label="项目采购" value="1" />
-          <el-option label="其他合作" value="2" />
-        </el-select>
-      </el-form-item>
+  <div class="tab-content">
+    <div class="info-section">
+      <el-form :model="contractSearchParams" label-width="70px" style="margin-bottom: 20px;">
+        <el-row :gutter="16">
+          <el-col :span="6">
+            <el-form-item label="合同编号">
+              <el-input v-model="contractSearchParams.contractNo" placeholder="请输入合同编号" clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="合同名称">
+              <el-input v-model="contractSearchParams.contractName" placeholder="请输入合同名称" clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="合同类型">
+              <el-select v-model="contractSearchParams.contractType" placeholder="请选择" clearable filterable style="width: 100%;">
+                <el-option v-for="item in contractTypeDict" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-form-item label-width="0">
+              <el-button type="primary" icon="Search" @click="emit('search')">搜索</el-button>
+              <el-button icon="Refresh" @click="emit('reset')">重置</el-button>
+            </el-form-item>
+          
+        </el-row>
 
-      <el-form-item>
-        <el-button type="primary" icon="Search" @click="onContractSearch">搜索</el-button>
-        <el-button icon="Refresh" @click="onContractReset">重置</el-button>
-      </el-form-item>
-    </el-form>
+        
+      </el-form>
 
-    <div class="section-title">合同信息列表</div>
+      <div class="section-title">合同信息列表</div>
 
-    <el-table :data="contractList" border style="width: 100%">
-      <el-table-column prop="contractNo" label="合同编号" align="center" />
-      <el-table-column prop="contractName" label="合同名称" align="center" />
-      <el-table-column prop="contractType" label="合同类型" align="center">
-        <template #default="scope">
-          <span>{{ getContractTypeText(scope.row.contractType) }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column prop="contractAmount" label="金额(万)" align="center">
-        <template #default="scope">
-          <span>{{ scope.row.contractAmount || '-' }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column prop="contractStartTime" label="起始时间" align="center">
-        <template #default="scope">
-          <span>{{ scope.row.contractStartTime ? formatDate(scope.row.contractStartTime) : '-' }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column prop="contractEndTime" label="截止时间" align="center">
-        <template #default="scope">
-          <span>{{ scope.row.contractEndTime ? formatDate(scope.row.contractEndTime) : '-' }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column prop="createTime" label="上传时间" align="center">
-        <template #default="scope">
-          <span>{{ scope.row.createTime ? formatDate(scope.row.createTime) : '-' }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column prop="contractAttachment" label="附件管理" align="center">
-        <template #default="scope">
-          <el-button v-if="scope.row.contractAttachment" link type="primary" @click="onViewAttachment(scope.row)">查看附件</el-button>
-          <span v-else>-</span>
-        </template>
-      </el-table-column>
-      <el-table-column prop="contractStatus" label="状态" align="center">
-        <template #default="scope">
-          <span>{{ getContractStatusText(scope.row.contractStatus) }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="操作" align="center" width="80">
-        <template #default="scope">
-          <el-button link type="primary" @click="onViewContract(scope.row)">查看</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
+      <el-table :data="contractList" border style="width: 100%">
+        <el-table-column prop="contractNo" label="合同编号" align="center" />
+        <el-table-column prop="contractName" label="合同名称" align="center" />
+        <el-table-column prop="contractType" label="合同类型" align="center">
+          <template #default="scope">
+            <span>{{ getContractTypeText(scope.row.contractType) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="contractAmount" label="金额(万)" align="center">
+          <template #default="scope">
+            <span>{{ scope.row.contractAmount || '-' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="contractStartTime" label="起始时间" align="center">
+          <template #default="scope">
+            <span>{{ scope.row.contractStartTime ? formatDate(scope.row.contractStartTime) : '-' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="contractEndTime" label="截止时间" align="center">
+          <template #default="scope">
+            <span>{{ scope.row.contractEndTime ? formatDate(scope.row.contractEndTime) : '-' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="createTime" label="上传时间" align="center">
+          <template #default="scope">
+            <span>{{ scope.row.createTime ? formatDate(scope.row.createTime) : '-' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="contractAttachment" label="附件管理" align="center">
+          <template #default="scope">
+            <el-button v-if="scope.row.contractAttachment" link type="primary" @click="emit('viewAttachment', scope.row)">查看附件</el-button>
+            <span v-else>-</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="contractStatus" label="状态" align="center">
+          <template #default="scope">
+            <span>{{ getContractStatusText(scope.row.contractStatus) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="center" width="120">
+          <template #default="scope">
+            <el-button link type="primary" @click="emit('view', scope.row)">查看</el-button>
+           <!--  <el-button v-if="!isViewMode" link type="primary" @click="emit('edit', scope.row)">编辑</el-button> -->
+          </template>
+        </el-table-column>
+      </el-table>
 
-    <div style="margin-top: 20px; display: flex; justify-content: flex-end;">
-      <el-pagination
-        v-model:current-page="contractPagination.pageNum"
-        v-model:page-size="contractPagination.pageSize"
-        :page-sizes="[10, 20, 50, 100]"
-        :total="contractPagination.total"
-        layout="total, sizes, prev, pager, next, jumper"
-        @size-change="onContractSizeChange"
-        @current-change="onContractCurrentChange"
-      />
+      <div style="margin-top: 20px; display: flex; justify-content: flex-end;">
+        <el-pagination
+          v-model:current-page="contractPagination.pageNum"
+          v-model:page-size="contractPagination.pageSize"
+          :page-sizes="[10, 20, 50, 100]"
+          :total="contractPagination.total"
+          layout="total, sizes, prev, pager, next, jumper"
+          @size-change="emit('sizeChange', $event)"
+          @current-change="emit('currentChange', $event)"
+        />
+      </div>
     </div>
   </div>
 </template>
 
 <script setup lang="ts">
-type Props = {
+defineProps<{
   contractSearchParams: any;
-  onContractSearch: () => void;
-  onContractReset: () => void;
   contractList: any[];
-  contractPagination: any;
-  onContractSizeChange: (size: number) => void;
-  onContractCurrentChange: (page: number) => void;
-  getContractTypeText: (type: string | number) => string;
-  getContractStatusText: (status: number) => string;
-  formatDate: (date: string | Date) => string;
-  onViewAttachment: (row: any) => void;
-  onViewContract: (row: any) => void;
-};
+  contractPagination: { pageNum: number; pageSize: number; total: number };
+  isViewMode: boolean;
+  contractTypeDict: any[];
+  contractStatusDict: any[];
+  formatDate: (date: any) => string;
+  getContractTypeText: (type: any) => string;
+  getContractStatusText: (status: any) => string;
+}>();
 
-defineProps<Props>();
+const emit = defineEmits<{
+  (e: 'search'): void;
+  (e: 'reset'): void;
+  (e: 'add'): void;
+  (e: 'viewAttachment', row: any): void;
+  (e: 'view', row: any): void;
+  (e: 'edit', row: any): void;
+  (e: 'sizeChange', size: number): void;
+  (e: 'currentChange', page: number): void;
+}>();
 </script>

+ 0 - 115
src/views/supplier/info/components/PaymentDialog.vue

@@ -1,115 +0,0 @@
-<template>
-  <el-dialog
-    :model-value="modelValue"
-    :title="title"
-    width="1000px"
-    :close-on-click-modal="false"
-    @update:model-value="(v) => emit('update:modelValue', v)"
-  >
-    <el-form
-      ref="formRef"
-      :model="model"
-      :rules="rules"
-      label-width="140px"
-      :disabled="readonly"
-    >
-      <el-form-item label="开票类型:" prop="invoiceTypeNo">
-        <el-select
-          v-model="model.invoiceTypeNo"
-          placeholder="请选择"
-          style="width: 100%;"
-          @change="onInvoiceTypeChange"
-        >
-          <el-option
-            v-for="item in invoiceTypeList"
-            :key="item.id"
-            :label="item.invoiceTypeName"
-            :value="item.id"
-          />
-        </el-select>
-      </el-form-item>
-
-      <el-form-item label="发票抬头:" prop="businessName">
-        <el-input v-model="model.businessName" placeholder="企业工商名称" disabled />
-      </el-form-item>
-
-      <el-form-item label="纳税人识别号:" prop="circlesName">
-        <el-input v-model="model.circlesName" placeholder="请输入纳税人识别号" disabled />
-      </el-form-item>
-
-      <el-form-item label="开户行行号:" prop="bankNum">
-        <el-input v-model="model.bankNum" placeholder="请输入开户行行号" />
-      </el-form-item>
-
-      <el-form-item label="开户行名称:" prop="bankInfoNo">
-        <el-select
-          v-model="model.bankInfoNo"
-          placeholder="请选择"
-          style="width: 100%;"
-          @change="onBankChange"
-        >
-          <el-option
-            v-for="item in systemBankList"
-            :key="item.id"
-            :label="item.bnName"
-            :value="item.id"
-          />
-        </el-select>
-      </el-form-item>
-
-      <el-form-item label="银行账户:" prop="bankNo">
-        <el-input v-model="model.bankNo" placeholder="请输入银行账户" />
-      </el-form-item>
-
-      <el-form-item label="固定电话:" prop="phone">
-        <el-input v-model="model.phone" placeholder="请输入固定电话" />
-      </el-form-item>
-
-      <el-form-item label="地址:" prop="businessAddress">
-        <el-input v-model="model.businessAddress" placeholder="工商地址" disabled />
-      </el-form-item>
-
-      <el-form-item label="是否主账号:" prop="num">
-        <el-radio-group v-model="model.num">
-          <el-radio :label="1">是</el-radio>
-          <el-radio :label="0">否</el-radio>
-        </el-radio-group>
-      </el-form-item>
-    </el-form>
-
-    <template #footer>
-      <div class="dialog-footer">
-        <el-button @click="emit('update:modelValue', false)">取消</el-button>
-        <el-button v-if="!readonly" type="primary" @click="onSubmit" :loading="submitLoading">确定</el-button>
-      </div>
-    </template>
-  </el-dialog>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue';
-
-type Props = {
-  modelValue: boolean;
-  title: string;
-  readonly: boolean;
-  submitLoading: boolean;
-  model: any;
-  rules: any;
-  invoiceTypeList: any[];
-  systemBankList: any[];
-  onInvoiceTypeChange: (value: string | number) => void;
-  onBankChange: (value: string | number) => void;
-  onSubmit: () => void;
-};
-
-defineProps<Props>();
-
-const emit = defineEmits<{ (e: 'update:modelValue', value: boolean): void }>();
-
-const formRef = ref();
-
-defineExpose({
-  formRef
-});
-</script>

+ 41 - 53
src/views/supplier/info/components/PurchaseInfoTab.vue

@@ -1,65 +1,53 @@
 <template>
-  <div class="info-section">
-    <div class="section-title">采购信息</div>
+  <div class="tab-content">
+    <div class="info-section">
+      <div class="section-title" style="display: flex; align-items: center; justify-content: space-between;">
+        <span class="purchase-title">采购信息</span>
+      </div>
 
-    <el-row :gutter="40" class="form-row">
-      <el-col :span="12">
-        <div class="form-item">
-          <span class="label">产品经理:</span>
-          <el-select
-            :model-value="selectedProductManager"
-            placeholder="请选择产品经理"
-            filterable
-            clearable
-            style="width: 300px;"
-            @update:model-value="onUpdateProductManager"
-          >
-            <el-option
-              v-for="item in staffOptions"
-              :key="item.staffId"
-              :label="item.displayText"
-              :value="item.staffId"
-            />
-          </el-select>
-        </div>
-      </el-col>
-      <el-col :span="12">
-        <div class="form-item">
-          <span class="label">采购员:</span>
-          <el-select
-            :model-value="selectedBuyer"
-            placeholder="请选择采购员"
-            filterable
-            clearable
-            style="width: 300px;"
-            @update:model-value="onUpdateBuyer"
-          >
-            <el-option
-              v-for="item in staffOptions"
-              :key="item.staffId"
-              :label="item.displayText"
-              :value="item.staffId"
-            />
-          </el-select>
-        </div>
-      </el-col>
-    </el-row>
-
-    <div style="margin-top: 20px;">
-      <el-button type="primary" icon="Document" @click="onSavePurchaseInfo">保存</el-button>
+      <el-row :gutter="40" class="form-row">
+        <el-col :span="12">
+          <div class="form-item">
+            <span class="label">产品经理:</span>
+            <span>{{ productManagerName }}</span>
+          </div>
+        </el-col>
+        <el-col :span="12">
+          <div class="form-item">
+            <span class="label">采购员:</span>
+            <span>{{ buyerName }}</span>
+          </div>
+        </el-col>
+      </el-row>
     </div>
   </div>
 </template>
 
 <script setup lang="ts">
-type Props = {
+import { computed } from 'vue';
+
+const props = defineProps<{
   staffOptions: any[];
   selectedProductManager: number | null;
   selectedBuyer: number | null;
-  onUpdateProductManager: (value: number | null) => void;
-  onUpdateBuyer: (value: number | null) => void;
-  onSavePurchaseInfo: () => void;
-};
+  isViewMode: boolean;
+}>();
 
-defineProps<Props>();
+const productManagerName = computed(() => {
+  const id = props.selectedProductManager;
+  const item = props.staffOptions?.find((x: any) => x?.staffId === id);
+  return item?.displayText || '';
+});
+
+const buyerName = computed(() => {
+  const id = props.selectedBuyer;
+  const item = props.staffOptions?.find((x: any) => x?.staffId === id);
+  return item?.displayText || '';
+});
 </script>
+
+<style scoped>
+.purchase-title {
+  color: #409eff;
+}
+</style>

+ 0 - 47
src/views/supplier/info/components/SupplyAreaDialog.vue

@@ -1,47 +0,0 @@
-<template>
-  <el-dialog
-    :model-value="modelValue"
-    title="编辑供货区域"
-    width="700px"
-    :close-on-click-modal="false"
-    @update:model-value="(v) => emit('update:modelValue', v)"
-  >
-    <el-cascader
-      :model-value="selectedSupplyAreas"
-      :options="supplyAreaOptions"
-      :props="cascaderProps"
-      placeholder="请选择供货区域"
-      clearable
-      filterable
-      collapse-tags
-      collapse-tags-tooltip
-      style="width: 100%;"
-      @update:model-value="(v) => emit('update:selectedSupplyAreas', v)"
-    />
-
-    <template #footer>
-      <div class="dialog-footer">
-        <el-button @click="emit('update:modelValue', false)">取消</el-button>
-        <el-button type="primary" @click="onSubmit" :loading="submitLoading">确定</el-button>
-      </div>
-    </template>
-  </el-dialog>
-</template>
-
-<script setup lang="ts">
-type Props = {
-  modelValue: boolean;
-  submitLoading: boolean;
-  selectedSupplyAreas: any[];
-  supplyAreaOptions: any[];
-  cascaderProps: any;
-  onSubmit: () => void;
-};
-
-defineProps<Props>();
-
-const emit = defineEmits<{
-  (e: 'update:modelValue', value: boolean): void;
-  (e: 'update:selectedSupplyAreas', value: any[]): void;
-}>();
-</script>

+ 0 - 143
src/views/supplier/info/components/SupplyTab.vue

@@ -1,143 +0,0 @@
-<template>
-  <div>
-    <div class="info-section">
-      <div class="section-title-row">
-        <div class="section-title-left">
-          <span class="section-title-text">供货类目</span>
-        </div>
-        <el-button type="primary" icon="Document" @click="onSaveCategories">保存</el-button>
-      </div>
-
-      <el-checkbox-group v-model="selectedCategoriesModel" class="category-group">
-        <el-checkbox
-          v-for="category in productCategoryList"
-          :key="category.id"
-          :label="String(category.id)"
-        >
-          {{ category.categoryName }}
-        </el-checkbox>
-      </el-checkbox-group>
-    </div>
-
-    <div class="info-section">
-      <div class="section-title-row">
-        <div class="section-title-left">
-          <span class="section-title-text">供货品牌</span>
-        </div>
-        <div>
-          <el-button type="primary" icon="Plus" @click="onEditBrands">编辑</el-button>
-        </div>
-      </div>
-      <div class="brand-display-wrapper">
-        <el-tag
-          v-for="brand in selectedBrands"
-          :key="brand.id"
-          closable
-          @close="onRemoveBrand(brand)"
-          style="margin-right: 10px; margin-bottom: 10px;"
-        >
-          {{ brand.brandName }}
-        </el-tag>
-        <span v-if="selectedBrands.length === 0" style="color: #999;">暂无品牌信息</span>
-      </div>
-    </div>
-
-    <div class="info-section">
-      <div class="section-title-row">
-        <div class="section-title-left">
-          <span class="section-title-text">供货区域</span>
-        </div>
-        <el-button type="primary" icon="Edit" @click="onEditSupplyArea">编辑</el-button>
-      </div>
-      <el-table :data="supplyAreaList" border style="width: 100%">
-        <el-table-column type="index" label="序号" align="center" width="80" />
-        <el-table-column prop="province" label="供货区域(省)" align="center">
-          <template #default="scope">
-            <span>{{ scope.row.province || '' }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column prop="city" label="供货区域(市)" align="center">
-          <template #default="scope">
-            <span>{{ scope.row.city || '' }}</span>
-          </template>
-        </el-table-column>
-      </el-table>
-    </div>
-
-    <div class="info-section">
-      <div class="section-title">授权详情信息列表</div>
-      <el-table :data="authorizationList" border style="width: 100%">
-        <el-table-column prop="supplierName" label="供应商名称" align="center" />
-        <el-table-column prop="brandName" label="品牌名称" align="center" />
-        <el-table-column label="一级类目" align="center">
-          <template #default="scope">
-            <span>{{ scope.row.categorysMap?.oneLevelName || '-' }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="二级类目" align="center">
-          <template #default="scope">
-            <span>{{ scope.row.categorysMap?.twoLevelName || '-' }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column label="三级类目" align="center">
-          <template #default="scope">
-            <span>{{ scope.row.categorysMap?.threeLevelName || '-' }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column prop="authorizationEndTime" label="禁止时间" align="center">
-          <template #default="scope">
-            <span>{{ scope.row.authorizationEndTime ? formatDate(scope.row.authorizationEndTime) : '-' }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column prop="province" label="授权区域(省)" align="center" />
-        <el-table-column prop="city" label="授权区域(市)" align="center" />
-        <el-table-column prop="authorizedStatus" label="状态" align="center">
-          <template #default="scope">
-            <span>{{ getAuthorizedStatusText(scope.row.authorizedStatus) }}</span>
-          </template>
-        </el-table-column>
-      </el-table>
-      <div style="margin-top: 20px; display: flex; justify-content: flex-end;">
-        <el-pagination
-          :current-page="authorizationPagination.pageNum"
-          :page-size="authorizationPagination.pageSize"
-          :page-sizes="[10, 20, 50, 100]"
-          :total="authorizationPagination.total"
-          layout="total, sizes, prev, pager, next, jumper"
-          @size-change="onAuthorizationSizeChange"
-          @current-change="onAuthorizationCurrentChange"
-        />
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { computed } from 'vue';
-
-type Props = {
-  productCategoryList: any[];
-  selectedCategories: string[];
-  onSaveCategories: () => void;
-  selectedBrands: any[];
-  onEditBrands: () => void;
-  onRemoveBrand: (brand: any) => void;
-  onEditSupplyArea: () => void;
-  supplyAreaList: any[];
-  authorizationList: any[];
-  authorizationPagination: any;
-  onAuthorizationSizeChange: (size: number) => void;
-  onAuthorizationCurrentChange: (page: number) => void;
-  formatDate: (date: string | Date) => string;
-  getAuthorizedStatusText: (status: string) => string;
-};
-
-const props = defineProps<Props>();
-
-const emit = defineEmits<{ (e: 'update:selectedCategories', value: string[]): void }>();
-
-const selectedCategoriesModel = computed({
-  get: () => props.selectedCategories,
-  set: (value: string[]) => emit('update:selectedCategories', value)
-});
-</script>

Fichier diff supprimé car celui-ci est trop grand
+ 698 - 218
src/views/supplier/info/index.vue


Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff