Quellcode durchsuchen

前端bug修改

沐梦. vor 11 Stunden
Ursprung
Commit
70fa06113d

+ 11 - 2
src/components/ImageUpload/index.vue

@@ -16,7 +16,8 @@
       :headers="headers"
       :file-list="fileList"
       :on-preview="handlePictureCardPreview"
-      :class="{ hide: fileList.length >= limit }"
+      :disabled="disabled"
+      :class="{ hide: fileList.length >= limit || disabled }"
     >
       <el-icon class="avatar-uploader-icon">
         <plus />
@@ -69,7 +70,12 @@ const props = defineProps({
     default: false
   },
   // 压缩目标大小,单位KB。默认300KB以上文件才压缩,并压缩至300KB以内
-  compressTargetSize: propTypes.number.def(300)
+  compressTargetSize: propTypes.number.def(300),
+  // 是否禁用
+  disabled: {
+    type: Boolean,
+    default: false
+  }
 });
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@@ -239,4 +245,7 @@ const listToString = (list: any[], separator?: string) => {
 :deep(.hide .el-upload--picture-card) {
   display: none;
 }
+:deep(.el-upload-list__item .el-icon--close), :deep(.el-upload-list__item .el-upload-list__item-delete) {
+  display: v-bind('props.disabled ? "none !important" : "inline-flex"');
+}
 </style>

+ 5 - 5
src/views/common/businessActivity.vue

@@ -33,13 +33,13 @@
               </div>
               <div class="user-ops">
                 <el-button 
-                  v-if="!( (computedDataType === 12 && (item.roleCode === '1' || item.roleCode === 'B0001' || item.roleCode === '3')) || ((computedDataType === 1 || computedDataType === 2) && (item.roleCode === '1' || item.roleCode === '3')) )" 
+                  v-if="!( (computedDataType === 12 && (item.roleCode === '1' || item.roleCode === 'B0001' || item.roleCode === '3')) || ((computedDataType === 1 || computedDataType === 2 || computedDataType === 3 || computedDataType === 4) && (item.roleCode === '1' || item.roleCode === '3')) || item.izManager === 1 || index === 0 )" 
                   link 
                   class="btn-edit" 
                   @click="handleEditMember(item)"
                 >编辑</el-button>
                 <el-button 
-                  v-if="!( (computedDataType === 12 && (item.roleCode === '1' || item.roleCode === 'B0001' || item.roleCode === '3')) || ((computedDataType === 1 || computedDataType === 2) && (item.roleCode === '1' || item.roleCode === '3')) )" 
+                  v-if="!( (computedDataType === 12 && (item.roleCode === '1' || item.roleCode === 'B0001' || item.roleCode === '3')) || ((computedDataType === 1 || computedDataType === 2 || computedDataType === 3 || computedDataType === 4) && (item.roleCode === '1' || item.roleCode === '3')) || item.izManager === 1 || index === 0 )" 
                   link 
                   class="btn-delete" 
                   @click="handleDeleteMember(item)"
@@ -399,7 +399,7 @@ const memberForm = reactive({
   userNo: '',
   realName: '',
   roleCode: '',
-  updateAccredit: 0,
+  updateAccredit: 1,
   izManager: 0,
   objectNo: ''
 });
@@ -431,7 +431,7 @@ watch(isReadOnly, (val) => {
   nextTick(() => {
     emit('update-readonly', val);
   });
-});
+}, { immediate: true });
 
 const filteredTeamRoleDict = computed(() => {
   if (!teamRoleDict.value) return [];
@@ -583,7 +583,7 @@ const handleAddMember = () => {
     userNo: '',
     realName: '',
     roleCode: '',
-    updateAccredit: 0,
+    updateAccredit: 1,
     izManager: 0,
     objectNo: computedObjectNo.value,
     dataType: computedDataType.value

+ 299 - 221
src/views/customer/contactPerson/edit.vue

@@ -1,222 +1,249 @@
 <template>
   <el-drawer
     v-model="visible"
-    title="编辑联系人"
+    :title="form.id ? '编辑联系人' : '新建联系人'"
     size="80%"
     :modal="false"
     @close="handleClose"
     destroy-on-close
+    class="contact-form-drawer"
+    :with-header="false"
   >
-    <div class="drawer-content">
-      <el-form ref="contactPersonRef" :model="form" :rules="rules" label-width="110px" v-loading="loading">
-        <div class="section-title">个人资料</div>
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="姓名" prop="contactName">
-              <el-input v-model="form.contactName" placeholder="请输入姓名" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="联系人类型" prop="type">
-              <el-radio-group v-model="form.type">
-                <el-radio :label="'1'">公司职员</el-radio>
-                <el-radio :label="'2'">关系资源人</el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="性别" prop="gender">
-              <el-radio-group v-model="form.gender">
-                <el-radio :label="'0'">男</el-radio>
-                <el-radio :label="'1'">女</el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="年龄" prop="age">
-              <el-input v-model="form.age" placeholder="请输入" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="籍贯" prop="nativePlace">
-              <el-input v-model="form.nativePlace" placeholder="请输入籍贯" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="生日" prop="birthday">
-              <el-date-picker clearable
-                v-model="form.birthday"
-                type="date"
-                value-format="YYYY-MM-DD"
-                placeholder="请选择生日"
-                style="width: 100%">
-              </el-date-picker>
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row :gutter="20">
-          <el-col :span="24">
-            <el-form-item label="描述" prop="remark">
-              <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" :rows="3" maxlength="200" show-word-limit />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <div class="section-title" style="margin-top: 10px;">职业信息</div>
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="在职状态" prop="jobStatus">
-              <el-radio-group v-model="form.jobStatus">
-                <el-radio :label="'1'">在职</el-radio>
-                <el-radio :label="'2'">离职</el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="手机号码" prop="phone">
-              <el-input v-model="form.phone" placeholder="请输入手机号码" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="部门" prop="deptName">
-              <el-input v-model="form.deptName" placeholder="请输入部门" />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="职位" prop="position">
-              <el-input v-model="form.position" placeholder="请输入职位" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="办公座机" prop="officePhone">
-              <el-input v-model="form.officePhone" placeholder="请输入办公座机" />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row :gutter="20">
-          <el-col :span="24">
-            <el-form-item label="办公地址" prop="addressDetail">
-              <div style="display: flex; gap: 10px; width: 100%">
-                <el-cascader
-                  v-model="form.region"
-                  ref="regionCascader"
-                  :options="areaOptions"
-                  :props="{ label: 'areaName', value: 'id', children: 'children' }"
-                  placeholder="请选择省/市/县"
-                  style="width: 250px"
-                  clearable
-                />
-                <el-input v-model="form.addressDetail" placeholder="请输入详细地址" style="flex: 1" />
-              </div>
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row :gutter="20">
-          <el-col :span="24">
-            <el-form-item label="工作内容" prop="jobContent">
-              <el-input v-model="form.jobContent" type="textarea" placeholder="请输入内容" :rows="2" maxlength="200" show-word-limit />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row :gutter="20">
-          <el-col :span="12">
-            <el-form-item label="项目角色" prop="projectRole">
-              <el-select v-model="form.projectRole" placeholder="请选择项目角色" style="width: 100%" clearable>
-                <el-option v-for="dict in projectRoleOptions" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="是否关键人" prop="isKeyPerson">
-              <el-select v-model="form.isKeyPerson" placeholder="请选择" style="width: 100%" clearable>
-                <el-option label="是" :value="1" />
-                <el-option label="否" :value="0" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
+    <div class="form-container" v-loading="loading">
+      <div class="form-toolbar">
+        <div class="toolbar-left">
+          <span class="breadcrumb" v-if="form.contactNo">个人资料 / <span class="highlight">人员编号: {{ form.contactNo }}</span></span>
+          <span class="breadcrumb" v-else>新建联系人</span>
+        </div>
+        <div class="toolbar-right">
+          <el-button type="primary" icon="Check" @click="submitForm">保存</el-button>
+          <el-button @click="handleClose">取消</el-button>
+        </div>
+      </div>
 
+      <el-form ref="contactPersonRef" :model="form" :rules="rules" label-width="120px" label-position="right" label-suffix=":">
+        <!-- 个人信息 -->
+        <div class="form-section">
+          <div class="section-title">个人信息</div>
+          <el-row :gutter="20">
+            <el-col :span="8">
+              <el-form-item label="人员编号">
+                <el-input :model-value="form.contactNo || ''" disabled />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="姓名" prop="contactName">
+                <el-input v-model="form.contactName" placeholder="请输入姓名" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="联系人类型" prop="type">
+                <el-select v-model="form.type" placeholder="请选择" class="w100">
+                  <el-option label="公司职员" value="1" />
+                  <el-option label="关系资源人" value="2" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row :gutter="20">
+            <el-col :span="8">
+              <el-form-item label="性别" prop="gender">
+                <el-select v-model="form.gender" placeholder="请选择" class="w100">
+                  <el-option label="男" value="0" />
+                  <el-option label="女" value="1" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="年龄" prop="age">
+                <el-input v-model="form.age" placeholder="请输入" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="籍贯" prop="nativePlace">
+                <el-input v-model="form.nativePlace" placeholder="请输入籍贯" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row :gutter="20">
+            <el-col :span="8">
+              <el-form-item label="生日" prop="birthday">
+                <el-date-picker clearable
+                  v-model="form.birthday"
+                  type="date"
+                  value-format="YYYY-MM-DD"
+                  placeholder="请选择生日"
+                  style="width: 100%">
+                </el-date-picker>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row :gutter="20">
+            <el-col :span="24">
+              <el-form-item label="描述" prop="remark">
+                <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" :rows="3" maxlength="200" show-word-limit />
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+        <div class="section-title" style="margin-top: 10px;">办公信息</div>
         <el-row :gutter="20">
-          <el-col :span="24">
-            <el-form-item label="公关情况" prop="prStatus">
-              <el-input v-model="form.prStatus" type="textarea" placeholder="请输入内容" :rows="3" maxlength="200" show-word-limit />
-            </el-form-item>
-          </el-col>
-        </el-row>
+            <el-col :span="8">
+              <el-form-item label="归属公司">
+                <el-input :model-value="form.companyName || '优易达科技集团有限公司'" disabled />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="客户名称">
+                <el-input :model-value="form.customerName || ''" disabled />
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row :gutter="20">
+            <el-col :span="8">
+              <el-form-item label="在职状态" prop="jobStatus">
+                <el-select v-model="form.jobStatus" placeholder="请选择" class="w100">
+                  <el-option label="在职" value="1" />
+                  <el-option label="离职" value="2" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="手机号码" prop="phone">
+                <el-input v-model="form.phone" placeholder="请输入手机号码" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="部门" prop="deptName">
+                <el-input v-model="form.deptName" placeholder="请输入部门" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row :gutter="20">
+            <el-col :span="8">
+              <el-form-item label="职位" prop="position">
+                <el-input v-model="form.position" placeholder="请输入职位" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="办公座机" prop="officePhone">
+                <el-input v-model="form.officePhone" placeholder="请输入办公座机" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="办公地址" prop="addressDetail">
+                <div style="display: flex; gap: 10px; width: 100%">
+                  <el-cascader
+                    v-model="form.region"
+                    ref="regionCascader"
+                    :options="areaOptions"
+                    :props="{ label: 'areaName', value: 'id', children: 'children' }"
+                    placeholder="请选择"
+                    style="width: 150px"
+                    clearable
+                  />
+                  <el-input v-model="form.addressDetail" placeholder="请输入详细地址" style="flex: 1" />
+                </div>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row :gutter="20">
+            <el-col :span="24">
+              <el-form-item label="工作内容" prop="jobContent">
+                <el-input v-model="form.jobContent" type="textarea" placeholder="请输入内容" :rows="2" maxlength="200" show-word-limit />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <el-form-item label="项目角色" prop="projectRole">
+                <el-select v-model="form.projectRole" placeholder="请选择项目角色" class="w100" clearable>
+                  <el-option v-for="dict in projectRoleOptions" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="是否关键人" prop="isKeyPerson">
+                <el-select v-model="form.isKeyPerson" placeholder="请选择" class="w100" clearable>
+                  <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="24">
+              <el-form-item label="公关情况" prop="prStatus">
+                <el-input v-model="form.prStatus" type="textarea" placeholder="请输入内容" :rows="2" maxlength="200" show-word-limit />
+              </el-form-item>
+            </el-col>
+          </el-row>
 
         <div class="section-title" style="margin-top: 10px;">家庭信息</div>
         <el-row :gutter="20">
-          <el-col :span="24">
-            <el-form-item label="家庭住址" prop="homeAddressDetail">
-              <div style="display: flex; gap: 10px; width: 100%">
-                <el-cascader
-                  v-model="form.homeRegion"
-                  :options="areaOptions"
-                  :props="{ label: 'areaName', value: 'id', children: 'children' }"
-                  placeholder="请选择省/市/县"
-                  style="width: 250px"
-                  clearable
-                />
-                <el-input v-model="form.homeAddressDetail" placeholder="请输入详细地址" style="flex: 1" />
-              </div>
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="家庭情况" prop="familyStatus">
-              <el-input v-model="form.familyStatus" placeholder="请输入内容" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="爱好" prop="hobby">
-              <el-input v-model="form.hobby" placeholder="请输入内容" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="性格特征" prop="characterTrait">
-              <el-input v-model="form.characterTrait" placeholder="请输入内容" />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="是否抽烟" prop="isSmoke">
-              <el-radio-group v-model="form.isSmoke">
-                <el-radio value="1">是</el-radio>
-                <el-radio value="0">否</el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="是否喝酒" prop="isDrink">
-              <el-radio-group v-model="form.isDrink">
-                <el-radio value="1">是</el-radio>
-                <el-radio value="0">否</el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
+            <el-col :span="16">
+              <el-form-item label="家庭住址" prop="homeAddressDetail">
+                <div style="display: flex; gap: 10px; width: 100%">
+                  <el-cascader
+                    v-model="form.homeRegion"
+                    :options="areaOptions"
+                    :props="{ label: 'areaName', value: 'id', children: 'children' }"
+                    placeholder="请选择"
+                    style="width: 200px"
+                    clearable
+                  />
+                  <el-input v-model="form.homeAddressDetail" placeholder="请输入详细地址" style="flex: 1" />
+                </div>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row :gutter="20">
+            <el-col :span="8">
+              <el-form-item label="家庭情况" prop="familyStatus">
+                <el-input v-model="form.familyStatus" placeholder="请输入家庭情况" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="爱好" prop="hobby">
+                <el-input v-model="form.hobby" placeholder="请输入爱好" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="性格特征" prop="characterTrait">
+                <el-input v-model="form.characterTrait" placeholder="请输入性格特征" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row :gutter="20">
+            <el-col :span="8">
+              <el-form-item label="是否抽烟" prop="isSmoke">
+                <el-radio-group v-model="form.isSmoke">
+                  <el-radio value="1">是</el-radio>
+                  <el-radio value="0">否</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="是否喝酒" prop="isDrink">
+                <el-radio-group v-model="form.isDrink">
+                  <el-radio value="1">是</el-radio>
+                  <el-radio value="0">否</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </div>
       </el-form>
     </div>
-    <template #footer>
-      <div class="drawer-footer">
-        <el-button type="primary" @click="submitForm">确 定</el-button>
-        <el-button @click="handleClose">取 消</el-button>
-      </div>
-    </template>
   </el-drawer>
 </template>
 
@@ -506,30 +533,81 @@ function handleClose() {
 defineExpose({ open });
 </script>
 
-<style scoped lang="scss">
-.drawer-content {
-  padding: 0;
+<style lang="scss" scoped>
+.contact-form-drawer {
+  :deep(.el-drawer__body) {
+    padding: 0;
+  }
+}
+
+.form-container {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  background-color: #fff;
 }
 
-.section-title {
-  font-size: 15px;
-  color: #409eff;
-  margin-bottom: 12px;
-  padding-bottom: 8px;
+.form-toolbar {
+  height: 56px;
+  padding: 0 24px;
+  background-color: #fff;
   border-bottom: 1px solid #ebeef5;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  flex-shrink: 0;
+
+  .toolbar-left {
+    .breadcrumb {
+      font-size: 14px;
+      color: #606266;
+      .highlight {
+        color: #409eff;
+        font-weight: 500;
+      }
+    }
+  }
 }
 
-:deep(.el-form-item) {
-  margin-bottom: 14px;
+.el-form {
+  flex: 1;
+  overflow-y: auto;
+  padding: 24px;
+  
+  /* 隐藏滚动条 */
+  &::-webkit-scrollbar {
+    width: 0 !important;
+    height: 0 !important;
+    display: none !important;
+  }
+  -ms-overflow-style: none !important;
+  scrollbar-width: none !important;
 }
-.drawer-footer {
-  padding: 20px;
-  text-align: right;
-  border-top: 1px solid #ebeef5;
+
+.form-section {
+  padding: 0;
+  margin-bottom: 0;
+
+  .section-title {
+    font-size: 16px;
+    font-weight: 600;
+    color: #303133;
+    margin-bottom: 24px;
+    display: flex;
+    align-items: center;
+
+    &::before {
+      content: '';
+      width: 4px;
+      height: 16px;
+      background-color: #409eff;
+      margin-right: 8px;
+      border-radius: 2px;
+    }
+  }
 }
 
-/* 强制所有字体不加粗 */
-:deep(*) {
-  font-weight: 400 !important;
+.w100 {
+  width: 100%;
 }
 </style>

+ 119 - 103
src/views/customer/highseas/edit.vue

@@ -22,25 +22,20 @@
         <div class="form-section">
           <div class="section-title">基本信息</div>
           <el-row :gutter="20">
-            <el-col :span="8">
-              <el-form-item label="所属公司" required prop="belongCompanyId">
-                <el-select v-model="form.belongCompanyId" placeholder="请选择" class="w100" clearable>
-                  <el-option v-for="item in companyOptions" :key="item.id" :label="item.companyName" :value="String(item.id)" />
-                </el-select>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="客户名称" required prop="customerName">
-                <el-input v-model="form.customerName" placeholder="请输入客户名称" class="w100" maxlength="100" show-word-limit />
+            <el-col :span="24">
+              <el-form-item label="工商名称">
+                <el-input :model-value="rawCustomerData.businessCustomerName || form.businessCustomerName || ''" disabled />
               </el-form-item>
             </el-col>
+          </el-row>
+          <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="工商名称" prop="businessCustomerName">
-                <el-input v-model="form.businessCustomerName" placeholder="请输入工商名称" class="w100" maxlength="100" show-word-limit />
+              <el-form-item label="归属公司">
+                <el-select :model-value="rawCustomerData.companyName || rawCustomerData.customerBusinessVo?.companyName || ''" class="w100" disabled>
+                  <el-option :label="rawCustomerData.companyName || rawCustomerData.customerBusinessVo?.companyName || ''" :value="rawCustomerData.companyName || rawCustomerData.customerBusinessVo?.companyName || ''" />
+                </el-select>
               </el-form-item>
             </el-col>
-          </el-row>
-          <el-row :gutter="20">
             <el-col :span="8">
               <el-form-item label="客户来源" prop="customerSourceId">
                 <el-select v-model="form.customerSourceId" placeholder="请选择" class="w100" clearable>
@@ -55,80 +50,67 @@
                 </el-select>
               </el-form-item>
             </el-col>
-            <el-col :span="8">
-              <el-form-item label="企业规模" prop="enterpriseScaleId">
-                <el-select v-model="form.enterpriseScaleId" placeholder="请选择" class="w100" clearable>
-                  <el-option v-for="item in scaleOptions" :key="String(item.id)" :label="item.enterpriseScaleName || item.enterpriseScale || item.label || item.name" :value="String(item.id)" />
-                </el-select>
-              </el-form-item>
-            </el-col>
           </el-row>
+
           <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="客户类别" prop="customerTypeId">
-                <el-select v-model="form.customerTypeId" placeholder="请选择" class="w100" clearable>
-                  <el-option v-for="item in categoryOptions" :key="String(item.id)" :label="item.customerTypeName || item.customerCategoryName || item.typeName || item.name" :value="String(item.id)" />
+              <el-form-item label="客户等级">
+                <el-select :model-value="rawCustomerData.customerLevelName || rawCustomerData.customerBusinessVo?.customerLevelName || ''" class="w100" disabled>
+                  <el-option :label="rawCustomerData.customerLevelName || rawCustomerData.customerBusinessVo?.customerLevelName || ''" :value="rawCustomerData.customerLevelName || rawCustomerData.customerBusinessVo?.customerLevelName || ''" />
                 </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="w100" clearable>
-                  <el-option v-for="item in industryOptions" :key="item.id" :label="item.industryCategoryName" :value="item.id" />
+              <el-form-item label="企业规模">
+                <el-select :model-value="rawCustomerData.enterpriseScale || ''" class="w100" disabled>
+                  <el-option :label="rawCustomerData.enterpriseScale || ''" :value="rawCustomerData.enterpriseScale || ''" />
                 </el-select>
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="客户等级" prop="customerLevelId">
-                <el-select v-model="form.customerLevelId" placeholder="请选择" class="w100" clearable>
-                  <el-option v-for="item in levelOptions" :key="item.id" :label="item.levelName" :value="String(item.id)" />
-                </el-select>
+              <el-form-item label="企业邮箱">
+                <el-input :model-value="rawCustomerData.email || ''" disabled />
               </el-form-item>
             </el-col>
           </el-row>
+
           <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="固定电话" prop="landline">
-                <el-input v-model="form.landline" placeholder="请输入固定电话" class="w100" maxlength="20" />
+              <el-form-item label="办公电话">
+                <el-input :model-value="rawCustomerData.landline || ''" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="传真" prop="fax">
-                <el-input v-model="form.fax" placeholder="请输入传真" class="w100" maxlength="20" />
+              <el-form-item label="行业">
+                <el-select :model-value="rawCustomerData.industryName || ''" class="w100" disabled>
+                  <el-option :label="rawCustomerData.industryName || ''" :value="rawCustomerData.industryName || ''" />
+                </el-select>
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="网址" prop="url">
-                <el-input v-model="form.url" placeholder="请输入网址" class="w100" maxlength="100" />
+              <el-form-item label="国家">
+                <el-input :model-value="'中国'" disabled />
               </el-form-item>
             </el-col>
           </el-row>
+
           <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="邮政编码" prop="postCode">
-                <el-input v-model="form.postCode" placeholder="请输入邮政编码" class="w100" maxlength="6" />
+              <el-form-item label="省份">
+                <el-input :model-value="rawCustomerData.regProvincialName || ''" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="邮箱" prop="email">
-                <el-input v-model="form.email" placeholder="请输入邮箱" class="w100" maxlength="50" />
+              <el-form-item label="城市">
+                <el-input :model-value="rawCustomerData.regCityName || ''" disabled />
               </el-form-item>
             </el-col>
           </el-row>
+
           <el-row :gutter="20">
-            <el-col :span="12">
-              <el-form-item label="详细地址" prop="areaArray">
-                <div class="address-group">
-                  <el-cascader
-                    v-model="form.areaArray"
-                    :options="areaOptions"
-                    :props="{ label: 'areaName', value: 'id', children: 'children' }"
-                    placeholder="请选择"
-                    class="flex1"
-                    @change="handleAreaChange"
-                  />
-                  <el-input v-model="form.address" placeholder="请输入详细地址" class="flex1" maxlength="200" show-word-limit />
-                </div>
+            <el-col :span="24">
+              <el-form-item label="办公地址">
+                <el-input :model-value="rawCustomerData.address || rawCustomerData.customerBusinessVo?.address || ''" disabled />
               </el-form-item>
             </el-col>
           </el-row>
@@ -138,79 +120,67 @@
         <div class="form-section">
           <div class="section-title">工商信息</div>
           <el-row :gutter="20">
-            <el-col :span="8">
-              <el-form-item label="企业工商名称" prop="businessCustomerName">
-                <el-input v-model="form.businessCustomerName" class="w100" maxlength="100" show-word-limit />
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="社会信用代码" prop="socialCreditCode">
-                <el-input v-model="form.socialCreditCode" class="w100" maxlength="18" />
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="法人姓名" prop="legalPersonName">
-                <el-input v-model="form.legalPersonName" class="w100" maxlength="50" />
+            <el-col :span="24">
+              <el-form-item label="工商名称">
+                <el-input :model-value="rawCustomerData.businessCustomerName || form.businessCustomerName || ''" disabled />
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="注册资本" prop="registeredCapital">
-                <el-input v-model="form.registeredCapital" class="w100" maxlength="50" />
+              <el-form-item label="社会信用代码">
+                <el-input :model-value="rawCustomerData.customerBusinessVo?.socialCreditCode || rawCustomerData.customerBusinessInfoVo?.socialCreditCode || ''" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="登记机关" prop="registrationAuthority">
-                <el-input v-model="form.registrationAuthority" class="w100" maxlength="100" />
+              <el-form-item label="法定代表人">
+                <el-input :model-value="rawCustomerData.customerBusinessVo?.legalPersonName || rawCustomerData.customerBusinessInfoVo?.legalPersonName || ''" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="成立日期">
-                <el-date-picker v-model="form.establishmentDate" type="date" value-format="YYYY-MM-DD" style="width: 100%" />
+              <el-form-item label="注册资本">
+                <el-input :model-value="rawCustomerData.customerBusinessVo?.registeredCapital || rawCustomerData.customerBusinessInfoVo?.registeredCapital || ''" disabled />
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="吊销日期">
-                <el-date-picker v-model="form.revocationDate" type="date" value-format="YYYY-MM-DD" style="width: 100%" />
+              <el-form-item label="成立日期">
+                <el-input :model-value="rawCustomerData.customerBusinessVo?.establishmentDate || rawCustomerData.customerBusinessInfoVo?.establishmentDate || ''" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="登记状态">
-                <el-select v-model="form.registrationStatus" placeholder="请选择" class="w100" clearable>
-                  <el-option v-for="item in dict.registration_status" :key="item.value" :label="item.label" :value="item.value" />
-                </el-select>
+              <el-form-item label="吊销日期">
+                <el-input :model-value="rawCustomerData.customerBusinessVo?.revocationDate || rawCustomerData.customerBusinessInfoVo?.revocationDate || ''" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="实缴资本" prop="paidInCapital">
-                <el-input v-model="form.paidInCapital" class="w100" maxlength="50" />
+              <el-form-item label="登记状态">
+                <el-input :model-value="rawCustomerData.customerBusinessVo?.registrationStatusName || rawCustomerData.customerBusinessInfoVo?.registrationStatus || ''" disabled />
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="20">
             <el-col :span="24">
-              <el-form-item label="详细地址" prop="businessAddress">
-                <el-input v-model="form.businessAddress" placeholder="请输入详细地址" class="w100" maxlength="200" show-word-limit />
+              <el-form-item label="注册地址">
+                <el-input :model-value="rawCustomerData.customerBusinessVo?.businessAddress || rawCustomerData.customerBusinessInfoVo?.businessAddress || ''" disabled />
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="20" class="mt-20">
             <el-col :span="8">
               <el-form-item label="营业执照">
-                <image-upload v-model="form.businessLicense" :limit="1" :is-show-tip="false" />
+                <image-upload v-model="form.businessLicense" :limit="1" :is-show-tip="false" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
               <el-form-item label="正面身份证">
-                <image-upload v-model="form.legalPersonCardFront" :limit="1" :is-show-tip="false" />
+                <image-upload v-model="form.legalPersonCardFront" :limit="1" :is-show-tip="false" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
               <el-form-item label="反面身份证">
-                <image-upload v-model="form.legalPersonCardBack" :limit="1" :is-show-tip="false" />
+                <image-upload v-model="form.legalPersonCardBack" :limit="1" :is-show-tip="false" disabled />
               </el-form-item>
             </el-col>
           </el-row>
@@ -221,33 +191,68 @@
           <div class="section-title">销售信息</div>
           <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="负责人">
-                <el-select v-model="form.salesPersonId" placeholder="请选择" class="w100" clearable>
-                  <el-option v-for="item in staffOptions" :key="item.staffId" :label="(item.staffCode ? '(' + item.staffCode + ') ' : '') + item.staffName" :value="String(item.staffId)" />
+              <el-form-item label="合作状况">
+                <el-select v-model="form.status" placeholder="请选择" class="w100" clearable>
+                  <el-option v-for="item in dict.cooperation_status" :key="item.value" :label="item.label" :value="item.value" />
                 </el-select>
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="客服支持">
-                <el-select v-model="form.serviceStaffId" placeholder="请选择" class="w100" clearable>
-                  <el-option v-for="item in staffOptions" :key="item.staffId" :label="(item.staffCode ? '(' + item.staffCode + ') ' : '') + item.staffName" :value="String(item.staffId)" />
+              <el-form-item label="开票类型">
+                <el-input :model-value="rawCustomerData.sellInvoiceType || ''" disabled />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="归属部门">
+                <el-input :model-value="rawCustomerData.belongingDepartmentName || rawCustomerData.deptName || ''" disabled />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20">
+            <el-col :span="8">
+              <el-form-item label="采购规模(万)">
+                <el-input v-model="form.annualProcurementScale" placeholder="请输入采购规模" class="w100"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="销售目标(万)">
+                <el-input v-model="form.salesTarget" placeholder="请输入销售目标" class="w100"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="采购方式">
+                <el-select v-model="form.procurementMethod" placeholder="请选择" class="w100" clearable multiple>
+                  <el-option v-for="item in dict.X0001" :key="item.value" :label="item.label" :value="item.value" />
                 </el-select>
               </el-form-item>
             </el-col>
+          </el-row>
+          <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="采购规模">
-                <el-input v-model="form.annualProcurementScale" placeholder="请输入采购规模" class="w100">
-                  <template #append>万</template>
-                </el-input>
+              <el-form-item label="信用等级">
+                <el-input :model-value="rawCustomerData.customerSalesInfoVo?.creditLevel || rawCustomerData.customerLevelName || ''" disabled />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="授信额度">
+                <el-input :model-value="rawCustomerData.customerSalesInfoVo?.creditAmount || '0.00'" disabled />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="应收账款">
+                <el-input :model-value="rawCustomerData.customerSalesInfoVo?.accountsReceivable || ''" disabled />
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="销售目标">
-                <el-input v-model="form.salesTarget" placeholder="请输入销售目标" class="w100">
-                  <template #append>万</template>
-                </el-input>
+              <el-form-item label="预收账款">
+                <el-input :model-value="rawCustomerData.customerSalesInfoVo?.prepaidAmount || rawCustomerData.deptCredit || ''" disabled />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="剩余额度">
+                <el-input :model-value="rawCustomerData.customerSalesInfoVo?.remainingQuota || '0.00'" disabled />
               </el-form-item>
             </el-col>
           </el-row>
@@ -271,13 +276,16 @@ const proxy = getCurrentInstance().proxy;
 const dict = reactive(proxy.useDict(
   'K0001', 
   'Q0001',
-  'registration_status'
+  'registration_status',
+  'cooperation_status',
+  'X0001'
 ));
 
 const visible = ref(false);
 const loading = ref(false);
 const submitting = ref(false);
 const formRef = ref(null);
+const rawCustomerData = ref({});
 
 const emit = defineEmits(['success']);
 
@@ -322,6 +330,8 @@ const form = reactive({
   serviceStaffId: undefined,
   annualProcurementScale: undefined,
   salesTarget: undefined,
+  status: undefined,
+  procurementMethod: undefined,
   contacts: []
 });
 
@@ -391,8 +401,10 @@ const reset = () => {
     establishmentDate: '', revocationDate: '', registrationStatus: '', registrationAuthority: '',
     businessAddress: '', businessLicense: '', legalPersonCardUrl: '',
     salesPersonId: undefined, serviceStaffId: undefined, annualProcurementScale: undefined, salesTarget: undefined,
+    status: undefined, procurementMethod: undefined,
     contacts: []
   });
+  rawCustomerData.value = {};
   if (formRef.value) formRef.value.resetFields();
 };
 
@@ -400,6 +412,7 @@ const loadData = (id) => {
   loading.value = true;
   getCustomerInfo(id).then(res => {
     const data = res.data;
+    rawCustomerData.value = data;
     const biz = data.customerBusinessInfoVo || {};
     const sales = data.customerSalesInfoVo || {};
 
@@ -465,8 +478,10 @@ const loadData = (id) => {
     }
     form.legalPersonCardUrl = biz.legalPersonCardUrl;
 
-    form.annualProcurementScale = data.annualProcurementScale;
-    form.salesTarget = data.salesTarget;
+    form.annualProcurementScale = data.annualProcurementScale || sales.procurementScale;
+    form.salesTarget = data.salesTarget || sales.salesTarget;
+    form.status = data.status || data.cooperationStatus;
+    form.procurementMethod = data.procurementMethod;
 
     loading.value = false;
   }).catch((err) => {
@@ -604,4 +619,5 @@ function handleTree(data, id, parentId, children) {
 .mt-10 { margin-top: 10px; }
 :deep(.el-form-item__label) { font-weight: normal; color: #64748b; white-space: nowrap; }
 :deep(.el-form-item) { margin-bottom: 22px; }
+.static-text { color: #333; font-size: 14px; }
 </style>

+ 120 - 112
src/views/customer/valid/edit.vue

@@ -26,26 +26,20 @@
         <div class="form-title">基本信息</div>
         <div class="form-section">
           <el-row :gutter="20">
-            <el-col :span="8">
-              <el-form-item label="所属公司" prop="belongCompanyId">
-                <el-select v-model="form.belongCompanyId" placeholder="请选择" class="w100">
-                  <el-option v-for="item in companyOptions" :key="item.id" :label="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="请输入客户名称" maxlength="100" show-word-limit />
+            <el-col :span="24">
+              <el-form-item label="工商名称">
+                <el-input :model-value="rawCustomerData.businessCustomerName || form.businessCustomerName || ''" disabled />
               </el-form-item>
             </el-col>
+          </el-row>
+          <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="工商名称" prop="businessCustomerName">
-                <el-input v-model="form.businessCustomerName" placeholder="请输入工商名称" maxlength="100" show-word-limit />
+              <el-form-item label="归属公司">
+                <el-select :model-value="rawCustomerData.companyName || rawCustomerData.customerBusinessVo?.companyName || ''" class="w100" disabled>
+                  <el-option :label="rawCustomerData.companyName || rawCustomerData.customerBusinessVo?.companyName || ''" :value="rawCustomerData.companyName || rawCustomerData.customerBusinessVo?.companyName || ''" />
+                </el-select>
               </el-form-item>
             </el-col>
-          </el-row>
-
-          <el-row :gutter="20">
             <el-col :span="8">
               <el-form-item label="客户来源" prop="customerSourceId">
                 <el-select v-model="form.customerSourceId" placeholder="请选择" class="w100">
@@ -60,85 +54,67 @@
                 </el-select>
               </el-form-item>
             </el-col>
-            <el-col :span="8">
-              <el-form-item label="企业规模" prop="enterpriseScaleId">
-                 <el-select v-model="form.enterpriseScaleId" placeholder="请选择" class="w100" clearable>
-                   <el-option v-for="item in scaleOptions" :key="String(item.id)" :label="item.enterpriseScaleName || item.enterpriseScale || item.label || item.name" :value="String(item.id)" />
-                 </el-select>
-              </el-form-item>
-            </el-col>
           </el-row>
 
           <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="客户类别" prop="customerTypeId">
-                  <el-select v-model="form.customerTypeId" placeholder="请选择" class="w100">
-                    <el-option v-for="item in categoryOptions" :key="String(item.id)" :label="item.customerTypeName || item.customerCategoryName || item.typeName || item.name" :value="String(item.id)" />
-                  </el-select>
+              <el-form-item label="客户等级">
+                <el-select :model-value="rawCustomerData.customerLevelName || rawCustomerData.customerBusinessVo?.customerLevelName || ''" class="w100" disabled>
+                  <el-option :label="rawCustomerData.customerLevelName || rawCustomerData.customerBusinessVo?.customerLevelName || ''" :value="rawCustomerData.customerLevelName || rawCustomerData.customerBusinessVo?.customerLevelName || ''" />
+                </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="w100">
-                  <el-option v-for="item in industryOptions" :key="item.id" :label="item.industryCategoryName" :value="item.id" />
+              <el-form-item label="企业规模">
+                <el-select :model-value="rawCustomerData.enterpriseScale || ''" class="w100" disabled>
+                  <el-option :label="rawCustomerData.enterpriseScale || ''" :value="rawCustomerData.enterpriseScale || ''" />
                 </el-select>
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="客户等级" prop="customerLevelId">
-                <el-select v-model="form.customerLevelId" placeholder="请选择" class="w100" clearable>
-                  <el-option v-for="item in levelOptions" :key="String(item.id)" :label="item.levelName || item.customerLevelName || item.label || item.name" :value="String(item.id)" />
-                </el-select>
+              <el-form-item label="企业邮箱">
+                <el-input :model-value="rawCustomerData.email || ''" disabled />
               </el-form-item>
             </el-col>
           </el-row>
 
           <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="固定电话" prop="landline">
-                <el-input v-model="form.landline" placeholder="请输入固定电话" maxlength="20" />
+              <el-form-item label="办公电话">
+                <el-input :model-value="rawCustomerData.landline || ''" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="传真" prop="fax">
-                <el-input v-model="form.fax" placeholder="请输入传真" maxlength="20" />
+              <el-form-item label="行业">
+                <el-select :model-value="rawCustomerData.industryName || ''" class="w100" disabled>
+                  <el-option :label="rawCustomerData.industryName || ''" :value="rawCustomerData.industryName || ''" />
+                </el-select>
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="网址" prop="url">
-                <el-input v-model="form.url" placeholder="请输入网址" maxlength="100" />
+              <el-form-item label="国家">
+                <el-input :model-value="'中国'" disabled />
               </el-form-item>
             </el-col>
           </el-row>
 
           <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="邮政编码" prop="postCode">
-                <el-input v-model="form.postCode" placeholder="请输入邮政编码" maxlength="6" />
+              <el-form-item label="省份">
+                <el-input :model-value="rawCustomerData.regProvincialName || ''" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="邮箱" prop="email">
-                <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
+              <el-form-item label="城市">
+                <el-input :model-value="rawCustomerData.regCityName || ''" disabled />
               </el-form-item>
             </el-col>
           </el-row>
 
           <el-row :gutter="20">
-            <el-col :span="16">
-              <el-form-item label="详细地址" prop="areaArray">
-                 <div style="display: flex; gap: 10px; width: 100%;">
-                    <el-cascader
-                      v-model="form.areaArray"
-                      :options="areaOptions"
-                      :props="{ label: 'areaName', value: 'id', children: 'children' }"
-                      placeholder="请选择省/市/县"
-                      style="flex: 1"
-                      clearable
-                      @change="handleAreaChange"
-                    />
-                    <el-input v-model="form.address" placeholder="请输入详细地址" style="flex: 1.5" maxlength="200" show-word-limit />
-                 </div>
+            <el-col :span="24">
+              <el-form-item label="办公地址">
+                <el-input :model-value="rawCustomerData.address || rawCustomerData.customerBusinessVo?.address || ''" disabled />
               </el-form-item>
             </el-col>
           </el-row>
@@ -146,118 +122,138 @@
 
         <div class="form-title">工商信息</div>
         <div class="form-section">
+          <el-row :gutter="20">
+            <el-col :span="24">
+              <el-form-item label="工商名称">
+                <el-input :model-value="rawCustomerData.businessCustomerName || form.businessCustomerName || ''" disabled />
+              </el-form-item>
+            </el-col>
+          </el-row>
           <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="企业工商名称" prop="customerBusinessBo.businessCustomerName">
-                <el-input v-model="form.customerBusinessBo.businessCustomerName" maxlength="100" show-word-limit />
+              <el-form-item label="社会信用代码">
+                <el-input :model-value="rawCustomerData.customerBusinessVo?.socialCreditCode || rawCustomerData.customerBusinessInfoVo?.socialCreditCode || ''" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="社会信用代码" prop="customerBusinessBo.socialCreditCode">
-                <el-input v-model="form.customerBusinessBo.socialCreditCode" maxlength="18" />
+              <el-form-item label="法定代表人">
+                <el-input :model-value="rawCustomerData.customerBusinessVo?.legalPersonName || rawCustomerData.customerBusinessInfoVo?.legalPersonName || ''" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="法人姓名" prop="customerBusinessBo.legalPersonName">
-                <el-input v-model="form.customerBusinessBo.legalPersonName" maxlength="50" />
+              <el-form-item label="注册资本">
+                <el-input :model-value="rawCustomerData.customerBusinessVo?.registeredCapital || rawCustomerData.customerBusinessInfoVo?.registeredCapital || ''" disabled />
               </el-form-item>
             </el-col>
           </el-row>
-
           <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="注册资本" prop="customerBusinessBo.registeredCapital">
-                <el-input v-model="form.customerBusinessBo.registeredCapital" maxlength="50" />
+              <el-form-item label="成立日期">
+                <el-input :model-value="rawCustomerData.customerBusinessVo?.establishmentDate || rawCustomerData.customerBusinessInfoVo?.establishmentDate || ''" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="登记机关" prop="customerBusinessBo.registrationAuthority">
-                <el-input v-model="form.customerBusinessBo.registrationAuthority" maxlength="100" />
+              <el-form-item label="吊销日期">
+                <el-input :model-value="rawCustomerData.customerBusinessVo?.revocationDate || rawCustomerData.customerBusinessInfoVo?.revocationDate || ''" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="成立日期">
-                <el-date-picker v-model="form.customerBusinessBo.establishmentDate" type="date" placeholder="选择日期" style="width: 100%" />
+              <el-form-item label="登记状态">
+                <el-input :model-value="rawCustomerData.customerBusinessVo?.registrationStatusName || rawCustomerData.customerBusinessInfoVo?.registrationStatus || ''" disabled />
               </el-form-item>
             </el-col>
           </el-row>
-
           <el-row :gutter="20">
+            <el-col :span="24">
+              <el-form-item label="注册地址">
+                <el-input :model-value="rawCustomerData.customerBusinessVo?.businessAddress || rawCustomerData.customerBusinessInfoVo?.businessAddress || ''" disabled />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="20" class="mt-20">
             <el-col :span="8">
-              <el-form-item label="吊销日期">
-                <el-date-picker v-model="form.customerBusinessBo.revocationDate" type="date" placeholder="选择日期" style="width: 100%" />
+              <el-form-item label="营业执照">
+                <image-upload v-model="form.businessLicense" :limit="1" :is-show-tip="false" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="登记状态" prop="customerBusinessBo.registrationStatus">
-                <el-input v-model="form.customerBusinessBo.registrationStatus" maxlength="50" />
+              <el-form-item label="正面身份证">
+                <image-upload v-model="form.legalPersonCardFront" :limit="1" :is-show-tip="false" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="实缴资本" prop="customerBusinessBo.paidInCapital">
-                <el-input v-model="form.customerBusinessBo.paidInCapital" maxlength="50" />
+              <el-form-item label="反面身份证">
+                <image-upload v-model="form.legalPersonCardBack" :limit="1" :is-show-tip="false" disabled />
               </el-form-item>
             </el-col>
           </el-row>
-
+        </div>
+        <div class="form-title">销售信息</div>
+        <div class="form-section">
           <el-row :gutter="20">
-            <el-col :span="24">
-              <el-form-item label="详细地址" prop="customerBusinessBo.businessAddress">
-                <el-input v-model="form.customerBusinessBo.businessAddress" placeholder="请输入详细地址" maxlength="200" show-word-limit />
+            <el-col :span="8">
+              <el-form-item label="合作状况">
+                <el-select v-model="form.status" placeholder="请选择" class="w100" clearable>
+                  <el-option v-for="item in cooperationOptions" :key="item.value" :label="item.label" :value="item.value" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="开票类型">
+                <el-input :model-value="rawCustomerData.sellInvoiceType || ''" disabled />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="归属部门">
+                <el-input :model-value="rawCustomerData.belongingDepartmentName || rawCustomerData.deptName || ''" disabled />
               </el-form-item>
             </el-col>
           </el-row>
-
           <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="营业执照">
-                <image-upload v-model="form.customerBusinessBo.businessLicense" :limit="1" :isShowTip="false" />
+              <el-form-item label="采购规模(万)">
+                <el-input v-model="form.annualProcurementScale" placeholder="请输入采购规模" class="w100"></el-input>
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="正面身份证">
-                <image-upload v-model="form.idCardFront" :limit="1" :isShowTip="false" />
+              <el-form-item label="销售目标(万)">
+                <el-input v-model="form.salesTarget" placeholder="请输入销售目标" class="w100"></el-input>
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="反面身份证">
-                <image-upload v-model="form.idCardBack" :limit="1" :isShowTip="false" />
+              <el-form-item label="采购方式">
+                <el-select v-model="form.procurementMethod" placeholder="请选择" class="w100" clearable multiple>
+                  <el-option v-for="item in purchaseWayOptions" :key="item.value" :label="item.label" :value="item.value" />
+                </el-select>
               </el-form-item>
             </el-col>
           </el-row>
-        </div>
-
-        <div class="form-title">销售信息</div>
-        <div class="form-section">
           <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="负责人">
-                 <el-select v-model="form.salesPersonId" placeholder="请选择" class="w100">
-                   <el-option v-for="item in staffOptions" :key="item.staffId" :label="(item.staffCode ? '(' + item.staffCode + ') ' : '') + item.staffName" :value="item.staffId" />
-                 </el-select>
+              <el-form-item label="信用等级">
+                <el-input :model-value="rawCustomerData.customerSalesInfoVo?.creditLevel || rawCustomerData.customerLevelName || ''" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="客服支持">
-                 <el-select v-model="form.serviceStaffId" placeholder="请选择" class="w100">
-                   <el-option v-for="item in staffOptions" :key="item.staffId" :label="(item.staffCode ? '(' + item.staffCode + ') ' : '') + item.staffName" :value="item.staffId" />
-                 </el-select>
+              <el-form-item label="授信额度">
+                <el-input :model-value="rawCustomerData.customerSalesInfoVo?.creditAmount || '0.00'" disabled />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="采购规模">
-                 <el-input v-model="form.customerSalesInfoBo.procurementScale" placeholder="请输入采购规模">
-                   <template #append>万</template>
-                 </el-input>
+              <el-form-item label="应收账款">
+                <el-input :model-value="rawCustomerData.customerSalesInfoVo?.accountsReceivable || ''" disabled />
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="销售目标">
-                 <el-input v-model="form.customerSalesInfoBo.salesTarget" placeholder="请输入销售目标">
-                   <template #append>万</template>
-                 </el-input>
+              <el-form-item label="预收账款">
+                <el-input :model-value="rawCustomerData.customerSalesInfoVo?.prepaidAmount || rawCustomerData.deptCredit || ''" disabled />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="剩余额度">
+                <el-input :model-value="rawCustomerData.customerSalesInfoVo?.remainingQuota || '0.00'" disabled />
               </el-form-item>
             </el-col>
           </el-row>
@@ -280,7 +276,7 @@ import { listProvinceWithCities } from "@/api/customer/addressArea";
 import { deptTreeSelect } from "@/api/system/dept";
 
 const proxy = getCurrentInstance().proxy;
-const { K0001: sourceOptions, Q0001: corpTypeOptions } = toRefs(reactive(proxy.useDict("K0001", "Q0001")));
+const { K0001: sourceOptions, Q0001: corpTypeOptions, cooperation_status: cooperationOptions, X0001: purchaseWayOptions } = toRefs(reactive(proxy.useDict("K0001", "Q0001", "cooperation_status", "X0001")));
 const route = useRoute();
 const router = useRouter();
 
@@ -288,7 +284,7 @@ const formRef = ref(null);
 const loading = ref(false);
 const visible = ref(false);
 const submitting = ref(false);
-
+const rawCustomerData = ref({});
 const form = reactive({
   id: undefined,
   customerNo: '',
@@ -323,7 +319,9 @@ const form = reactive({
     registrationAuthority: '', paidInCapital: '', revocationDate: '',
     businessAddress: '', businessLicense: '', legalPersonCardUrl: ''
   },
-  customerSalesInfoBo: { procurementScale: '', salesTarget: '' }
+  customerSalesInfoBo: { procurementScale: '', salesTarget: '' },
+  status: undefined,
+  procurementMethod: undefined
 });
 
 const rules = reactive({
@@ -406,6 +404,7 @@ const loadData = (id) => {
   getCustomerInfo(id).then(res => {
     const data = res.data;
     if (!data) return;
+    rawCustomerData.value = data;
     Object.assign(form, data);
     
     const biz = data.customerBusinessVo || data.customerBusinessInfoVo || {};
@@ -430,8 +429,16 @@ const loadData = (id) => {
       id: sales.id,
       customerId: data.id,
       procurementScale: sales.procurementScale || data.annualProcurementScale,
-      salesTarget: sales.salesTarget || data.salesTarget
+      salesTarget: sales.salesTarget || data.salesTarget,
+      creditLevel: sales.creditLevel,
+      creditAmount: sales.creditAmount,
+      accountsReceivable: sales.accountsReceivable,
+      prepaidAmount: sales.prepaidAmount || data.deptCredit,
+      remainingQuota: sales.remainingQuota
     };
+    
+    form.status = data.status || data.cooperationStatus;
+    form.procurementMethod = data.procurementMethod;
 
     // 解析身份证回显
     const cardUrls = biz.legalPersonCardUrl ? biz.legalPersonCardUrl.split(',') : [];
@@ -632,4 +639,5 @@ function handleTree(data, id, parentId, children) {
   gap: 8px; 
 }
 .w100 { width: 100%; }
+.static-text { color: #333; font-size: 14px; }
 </style>

+ 17 - 5
src/views/saleManage/leads/add.vue

@@ -55,7 +55,7 @@
           </el-row>
           <el-row :gutter="30">
             <el-col :span="12">
-              <el-form-item label="项目负责人" prop="leader">
+              <el-form-item label="业务负责人" prop="leader">
                 <el-select v-model="form.leader" placeholder="请选择" filterable style="width: 100%" @change="handleLeaderChange">
                   <el-option
                     v-for="item in userOptions"
@@ -204,8 +204,9 @@
              <el-table-column label="文件名称" prop="name" show-overflow-tooltip />
              <el-table-column label="文件类型" prop="type" width="120" align="center" />
              <el-table-column label="上传时间" prop="uploadTime" width="180" align="center" />
-             <el-table-column label="操作" width="100" align="center">
+             <el-table-column label="操作" width="140" align="center">
                 <template #default="scope">
+                  <el-button link type="primary" @click="handleDownload(scope.row)" style="margin-right: 10px;">下载</el-button>
                   <el-button link type="danger" @click="handleDeleteFile(scope.$index)">删除</el-button>
                 </template>
              </el-table-column>
@@ -259,7 +260,7 @@ const localCustomerOptions = ref([]);
 
 const form = reactive({
   izClue: 1,
-  status: '1',
+  status: '0',
   fileNo: '',
   productSupport: undefined,
   productSupportName: undefined
@@ -268,7 +269,7 @@ const form = reactive({
 const rules = reactive({
   companyNo: [{ required: true, message: '归属公司不能为空', trigger: 'change' }],
   customerNo: [{ required: true, message: '客户名称不能为空', trigger: 'change' }],
-  leader: [{ required: true, message: '项目负责人不能为空', trigger: 'change' }],
+  leader: [{ required: true, message: '业务负责人不能为空', trigger: 'change' }],
   projectName: [
     { required: true, message: '项目名称不能为空', trigger: 'blur' },
     { max: 200, message: '项目名称不能超过200个字符', trigger: 'blur' }
@@ -282,6 +283,7 @@ const rules = reactive({
   projectLevel: [{ required: true, message: '项目级别不能为空', trigger: 'change' }],
   projectArea: [
     { required: true, message: '项目区域不能为空', trigger: 'blur' },
+    { pattern: /^[\u4e00-\u9fa5]+$/, message: '项目区域只能输入中文,不能包含数字或其他字符', trigger: 'blur' },
     { max: 100, message: '项目区域不能超过100个字符', trigger: 'blur' }
   ],
   procurementMethod: [{ required: true, message: '采购方式不能为空', trigger: 'change' }],
@@ -339,7 +341,7 @@ const reset = () => {
     purchaseContent: undefined,
     projectDescription: undefined,
     competitor: undefined,
-    status: '1',
+    status: '0',
     fileNo: '',
     activityNo: undefined,
     profession: undefined,
@@ -388,6 +390,16 @@ const handleDeleteFile = (idx) => {
   form.fileNo = fileList.value.map(i => i.ossId).join(',');
 };
 
+const handleDownload = (row) => {
+  if (row.ossId) {
+    proxy.$download.oss(row.ossId);
+  } else if (row.url) {
+    window.open(row.url, '_blank');
+  } else {
+    proxy.$modal.msgError("下载地址不存在");
+  }
+};
+
 const submitForm = () => {
   formRef.value.validate(valid => {
     if (valid) {

+ 1 - 1
src/views/saleManage/leads/detail.vue

@@ -59,7 +59,7 @@
                 <div class="info-item"></div>
               </div>
               <div class="info-grid">
-                <div class="info-item"><span class="info-label">项目负责人</span><span class="info-value">{{ form.leaderName || findUserName(form.leader) }}</span></div>
+                <div class="info-item"><span class="info-label">业务负责人</span><span class="info-value">{{ form.leaderName || findUserName(form.leader) }}</span></div>
                 <div class="info-item"><span class="info-label">产品支持</span><span class="info-value">{{ form.productSupportName || findUserName(form.productSupport) }}</span></div>
                 <div class="info-item"></div>
               </div>

+ 78 - 134
src/views/saleManage/leads/edit.vue

@@ -18,128 +18,123 @@
         <div class="form-section">
           <div class="section-title"><span>基本信息</span></div>
           <el-row :gutter="30">
-            <el-col :span="12">
+            <el-col :span="24">
+              <el-form-item label="项目名称" prop="projectName">
+                <el-input v-model="form.projectName" placeholder="请输入" maxlength="200" show-word-limit />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="30">
+            <el-col :span="8">
               <el-form-item label="归属公司" prop="companyNo">
-                <el-select v-model="form.companyNo" placeholder="请选择" filterable style="width: 100%" clearable>
+                <el-select v-model="form.companyNo" placeholder="请选择" filterable style="width: 100%" clearable disabled>
                   <el-option v-for="item in computedCompanyOptions" :key="item.companyCode" :label="item.companyName" :value="String(item.companyCode)" />
                 </el-select>
               </el-form-item>
             </el-col>
-            <el-col :span="12">
+            <el-col :span="16">
               <el-form-item label="客户名称" prop="customerNo">
-                <el-select 
-                  v-model="form.customerNo" 
-                  placeholder="请输入关键字检索" 
-                  filterable 
-                  style="width: 100%" 
-                  @change="handleCustomerChange"
-                >
-                  <el-option v-for="item in localCustomerOptions" :key="item.customerNo" :label="item.customerName" :value="String(item.customerNo)" />
-                </el-select>
+                <el-input :model-value="form.customerName ? (form.customerNo + '、' + form.customerName) : ''" disabled />
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="30">
-            <el-col :span="12">
-              <el-form-item label="项目负责人" prop="leader">
-                <el-select v-model="form.leader" placeholder="请选择" filterable style="width: 100%" @change="handleLeaderChange">
-                  <el-option v-for="item in computedUserOptions" :key="item.staffId" :label="(item.staffCode ? '(' + item.staffCode + ') ' : '') + item.staffName" :value="String(item.staffId)" />
+            <el-col :span="8">
+              <el-form-item label="行业" prop="profession">
+                <el-select v-model="form.profession" placeholder="请选择" style="width: 100%" clearable filterable disabled>
+                  <el-option v-for="item in industryOptions" :key="item.id" :label="item.industryCategoryName" :value="String(item.id)" />
                 </el-select>
               </el-form-item>
             </el-col>
-            <el-col :span="12">
-              <el-form-item label="项目名称" prop="projectName">
-                <el-input v-model="form.projectName" placeholder="请输入" maxlength="200" show-word-limit />
+            <el-col :span="8">
+              <el-form-item label="部门" prop="deptName">
+                <el-input v-model="form.deptName" placeholder="无" disabled style="width: 100%" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="营销活动" prop="activityNo">
+                <el-select v-model="form.activityNo" placeholder="请选择" style="width: 100%" clearable filterable>
+                  <el-option v-for="item in marketingActivityOptions" :key="item.value" :label="item.label" :value="item.value" />
+                </el-select>
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="30">
-            <el-col :span="12">
+            <el-col :span="8">
               <el-form-item label="金额(万)" prop="projectBudget">
                 <el-input-number 
                   v-model="form.projectBudget" 
                   :precision="2" 
                   :step="1" 
                   :min="0" 
-                  placeholder="请输入金额" 
+                  placeholder="请输入" 
                   controls-position="right" 
                   style="width: 100%"
                 />
               </el-form-item>
             </el-col>
-            <el-col :span="12">
+            <el-col :span="8">
               <el-form-item label="赢单率(%)" prop="winRate">
-                <el-input v-model="form.winRate" placeholder="请输入" type="number" maxlength="6"><template #append>%</template></el-input>
+                <el-input v-model="form.winRate" placeholder="请输入" type="number" maxlength="6" />
               </el-form-item>
             </el-col>
-          </el-row>
-          <el-row :gutter="30">
-            <el-col :span="12">
+            <el-col :span="8">
               <el-form-item label="立项时间" prop="approvalDate">
                 <el-date-picker v-model="form.approvalDate" type="date" placeholder="请选择" value-format="YYYY-MM-DD" style="width: 100%" />
               </el-form-item>
             </el-col>
-            <el-col :span="12">
-              <el-form-item label="成单时间" prop="expectedCompletionTime">
-                <el-date-picker v-model="form.expectedCompletionTime" type="date" value-format="YYYY-MM-DD" style="width: 100%" />
-              </el-form-item>
-            </el-col>
           </el-row>
           <el-row :gutter="30">
-            <el-col :span="12">
-              <el-form-item label="营销活动" prop="activityNo">
-                <el-select v-model="form.activityNo" placeholder="请选择" style="width: 100%" clearable filterable>
-                  <el-option v-for="item in marketingActivityOptions" :key="item.value" :label="item.label" :value="item.value" />
-                </el-select>
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="行业" prop="profession">
-                <el-select v-model="form.profession" placeholder="请选择" style="width: 100%" clearable filterable>
-                  <el-option v-for="item in industryOptions" :key="item.id" :label="item.industryCategoryName" :value="String(item.id)" />
-                </el-select>
+            <el-col :span="8">
+              <el-form-item label="成单时间" prop="expectedCompletionTime">
+                <el-date-picker v-model="form.expectedCompletionTime" type="date" placeholder="请选择" value-format="YYYY-MM-DD" style="width: 100%" />
               </el-form-item>
             </el-col>
-          </el-row>
-          <el-row :gutter="30">
-            <el-col :span="12">
-              <el-form-item label="产品支持" prop="productSupport">
-                <el-select v-model="form.productSupport" placeholder="请选择" filterable style="width: 100%" clearable @change="handleProductSupportChange">
-                  <el-option v-for="item in computedProductSupportOptions" :key="item.staffId" :label="(item.staffCode ? '(' + item.staffCode + ') ' : '') + item.staffName" :value="String(item.staffId)" />
-                </el-select>
+            <el-col :span="8">
+              <el-form-item label="项目状态" prop="status">
+                <el-input :model-value="saleStatusOptions?.find(i => String(i.value) === String(form.status))?.label || form.statusName || form.status" disabled />
               </el-form-item>
             </el-col>
           </el-row>
         </div>
 
         <div class="form-section">
-          <div class="section-title"><span>项目信息</span></div>
+          <div class="section-title"><span>项目情况</span></div>
           <el-row :gutter="30">
-            <el-col :span="12">
+            <el-col :span="8">
+              <el-form-item label="信息来源" prop="infoSource">
+                <el-select v-model="form.infoSource" placeholder="请选择" style="width: 100%" clearable filterable disabled>
+                   <el-option v-for="item in infoSourceOptions" :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="projectLevel">
                 <el-select v-model="form.projectLevel" placeholder="请选择" style="width: 100%" clearable filterable>
                    <el-option v-for="item in projectLevelOptions" :key="item.value" :label="item.label" :value="item.value" />
                 </el-select>
               </el-form-item>
             </el-col>
-            <el-col :span="12">
+            <el-col :span="8">
               <el-form-item label="项目区域" prop="projectArea">
                 <el-input v-model="form.projectArea" placeholder="请输入" maxlength="100" />
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="30">
-            <el-col :span="12">
+            <el-col :span="16">
               <el-form-item label="采购方式" prop="procurementMethod">
-                <el-select v-model="form.procurementMethod" style="width: 100%" clearable filterable>
+                <el-select v-model="form.procurementMethod" placeholder="请选择" style="width: 100%" clearable filterable>
                    <el-option v-for="item in procurementMethodOptions" :key="item.value" :label="item.label" :value="item.value" />
                 </el-select>
               </el-form-item>
             </el-col>
-            <el-col :span="12">
-              <el-form-item label="信息来源" prop="infoSource">
-                <el-select v-model="form.infoSource" placeholder="请选择" style="width: 100%" clearable filterable>
-                   <el-option v-for="item in infoSourceOptions" :key="item.value" :label="item.label" :value="item.value" />
+          </el-row>
+          <el-row :gutter="30">
+            <el-col :span="16">
+              <el-form-item label="平台名称" prop="platformCode">
+                <el-select v-model="form.platformCode" placeholder="请选择" style="width: 100%" clearable filterable>
+                   <el-option v-for="item in platformOptions" :key="item.id" :label="item.platformName" :value="String(item.id)" />
                 </el-select>
               </el-form-item>
             </el-col>
@@ -167,25 +162,7 @@
           </el-row>
         </div>
 
-        <div class="form-section">
-          <div class="section-title attachment-header">
-            <span>附件</span>
-            <el-upload :action="uploadFileUrl" :headers="headers" :on-success="handleUploadSuccess" :show-file-list="false" multiple class="upload-btn">
-              <el-button link type="primary" icon="Upload">上传附件</el-button>
-            </el-upload>
-          </div>
-          <el-table :data="fileList" border class="at-table">
-             <el-table-column label="文件名称" prop="name" show-overflow-tooltip />
-             <el-table-column label="文件类型" prop="type" width="120" align="center" />
-             <el-table-column label="上传时间" prop="uploadTime" width="180" align="center" />
-             <el-table-column label="操作" width="140" align="center">
-                <template #default="scope">
-                  <el-button link type="primary" @click="handleDownload(scope.row)">下载</el-button>
-                  <el-button link type="danger" @click="handleDeleteFile(scope.$index)">删除</el-button>
-                </template>
-             </el-table-column>
-          </el-table>
-        </div>
+
       </el-form>
     </div>
     <template #footer>
@@ -200,10 +177,10 @@
 <script setup>
 import { ref, reactive, watch, computed, getCurrentInstance } from 'vue';
 import { getLeads, updateLeads } from '@/api/saleManage/leads/index';
+import { listPlatformSelection } from '@/api/saleManage/platformSelection/index';
 import { listCustomerInfo } from "@/api/customer/customerInfo/index";
-import { listByIds } from '@/api/system/oss/index';
 import { globalHeaders } from '@/utils/request';
-import { Close, Upload } from '@element-plus/icons-vue';
+import { Close } from '@element-plus/icons-vue';
 
 const props = defineProps({
   modelValue: Boolean,
@@ -225,9 +202,9 @@ const visible = ref(false);
 const loading = ref(false);
 const submitting = ref(false);
 const formRef = ref(null);
-const fileList = ref([]);
-const uploadFileUrl = import.meta.env.VITE_APP_BASE_API + '/resource/oss/upload';
-const headers = globalHeaders();
+const platformOptions = ref([]);
+
+const { J0001: saleStatusOptions } = toRefs(reactive(proxy.useDict('J0001')));
 
 const customerLoading = ref(false);
 const localCustomerOptions = ref([]);
@@ -283,7 +260,6 @@ const computedCompanyOptions = computed(() => {
 const rules = reactive({
   companyNo: [{ required: true, message: '必填', trigger: 'change' }],
   customerNo: [{ required: true, message: '必填', trigger: 'change' }],
-  leader: [{ required: true, message: '必填', trigger: 'change' }],
   projectName: [
     { required: true, message: '必填', trigger: 'blur' },
     { max: 200, message: '项目名称不能超过200个字符', trigger: 'blur' }
@@ -292,6 +268,7 @@ const rules = reactive({
     { pattern: /^(100|[1-9]?\d(\.\d+)?)$/, message: '请输入正确的赢单率(0-100)', trigger: 'blur' }
   ],
   projectArea: [
+    { pattern: /^[\u4e00-\u9fa5]+$/, message: '项目区域只能输入中文,不能包含数字或其他字符', trigger: 'blur' },
     { max: 100, message: '项目区域不能超过100个字符', trigger: 'blur' }
   ],
   purchaseContent: [
@@ -307,7 +284,12 @@ const rules = reactive({
 
 watch(() => props.modelValue, (val) => { 
   visible.value = val; 
-  if (val && props.id) loadDetail(props.id);
+  if (val) {
+    if (props.id) loadDetail(props.id);
+    listPlatformSelection({ pageNum: 1, pageSize: 500 }).then(res => {
+      platformOptions.value = res.data || res.rows || [];
+    });
+  }
 });
 watch(() => visible.value, (val) => { emit('update:modelValue', val); });
 
@@ -334,18 +316,6 @@ const loadDetail = (id) => {
     if (form.activityNo !== undefined && form.activityNo !== null) form.activityNo = String(form.activityNo);
     if (form.infoSource !== undefined && form.infoSource !== null) form.infoSource = String(form.infoSource);
     if (form.profession !== undefined && form.profession !== null) form.profession = String(form.profession);
-
-    if (form.fileNo) {
-      listByIds(form.fileNo).then(ossRes => {
-        fileList.value = ossRes.data.map(i => ({ 
-          name: i.originalName, 
-          url: i.url, 
-          ossId: i.ossId,
-          type: i.fileSuffix ? i.fileSuffix.toUpperCase() : (i.originalName.split('.').pop().toUpperCase()),
-          uploadTime: i.createTime || ''
-        }));
-      });
-    }
   }).finally(() => { loading.value = false; });
 };
 
@@ -390,37 +360,21 @@ const handleProductSupportChange = (id) => {
   }
 };
 
-const handleUploadSuccess = (res) => {
-  if (res.code === 200) {
-    fileList.value.push({ 
-      name: res.data.fileName, 
-      url: res.data.url, 
-      ossId: res.data.ossId,
-      type: res.data.fileName.split('.').pop().toUpperCase(),
-      uploadTime: proxy.parseTime(new Date())
-    });
-    form.fileNo = fileList.value.map(i => i.ossId).join(',');
-  }
-};
-
-const handleDownload = (row) => {
-  if (row.url) {
-    window.open(row.url);
-  } else {
-    proxy.$modal.msgError("下载地址不存在");
-  }
-};
-
-const handleDeleteFile = (idx) => {
-  fileList.value.splice(idx, 1);
-  form.fileNo = fileList.value.map(i => i.ossId).join(',');
-};
+const findCompanyName = (no) => computedCompanyOptions.value.find(i => String(i.companyCode) === String(no))?.companyName || no;
+const findIndustryName = (id) => props.industryOptions?.find(i => String(i.id) === String(id))?.industryCategoryName || id;
+const findStatusName = (status) => saleStatusOptions.value?.find(i => String(i.value) === String(status))?.label || status;
+const findInfoSourceName = (source) => props.infoSourceOptions?.find(i => String(i.value) === String(source))?.label || source;
 
 const submitForm = () => {
   formRef.value.validate(valid => {
     if (valid) {
       submitting.value = true;
-      updateLeads(form).then(() => {
+      const submitData = { ...form };
+      // 修复后端反序列化报错:如果 dealResult 是字符串(如 "赢单"),则将其剔除
+      if (typeof submitData.dealResult === 'string' && isNaN(Number(submitData.dealResult))) {
+        delete submitData.dealResult;
+      }
+      updateLeads(submitData).then(() => {
         proxy.$modal.msgSuccess("修改成功");
         visible.value = false;
         emit('success');
@@ -470,11 +424,6 @@ const submitForm = () => {
     margin-bottom: 15px;
   }
 }
-.attachment-header {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
 .drawer-footer {
   padding: 15px 25px;
   border-top: 1px solid #f0f0f0;
@@ -483,10 +432,5 @@ const submitForm = () => {
     font-weight: normal;
   }
 }
-.at-table {
-  :deep(th.el-table__cell) {
-    font-weight: normal;
-    color: #333;
-  }
-}
+.static-text { color: #333; font-size: 14px; }
 </style>

+ 7 - 20
src/views/saleManage/leads/index.vue

@@ -157,8 +157,8 @@
           </template>
         </el-table-column>
 
-        <!-- 10. 项目负责人 -->
-        <el-table-column label="项目负责人" align="center" prop="leaderName" width="110">
+        <!-- 10. 业务负责人 -->
+        <el-table-column label="业务负责人" align="center" prop="leaderName" width="110">
           <template #default="scope">
             <span>{{ scope.row.leaderName || findUserName(scope.row.leader) }}</span>
           </template>
@@ -274,7 +274,7 @@
     <!-- 认领对话框 -->
     <el-dialog v-model="claimOpen" title="您正在认领销售线索,请分配销售线索认领信息" width="500px" append-to-body>
       <el-form :model="claimForm" label-width="150px">
-        <el-form-item label="项目负责人" required>
+        <el-form-item label="业务负责人" required>
           <el-select v-model="claimForm.leader" filterable placeholder="请选择" style="width: 100%">
             <el-option v-for="item in computedClaimUserOptions" :key="item.staffId" :label="(item.staffCode ? '(' + item.staffCode + ') ' : '') + item.staffName" :value="item.staffId" />
           </el-select>
@@ -286,7 +286,7 @@
           </el-select>
         </el-form-item>
 
-        <el-form-item label="保留已有项目负责人" required>
+        <el-form-item label="保留已有业务负责人" required>
           <el-radio-group v-model="claimForm.keepOldManager">
             <el-radio :value="true">是</el-radio>
             <el-radio :value="false">否</el-radio>
@@ -334,7 +334,7 @@ const dateRange = ref([]);
 const queryParams = reactive({
   pageNum: 1,
   pageSize: 10,
-  status: '1',
+  status: '0',
   companyNo: undefined,
   projectName: undefined,
   customerName: undefined,
@@ -400,20 +400,7 @@ const computedClaimUserOptions = computed(() => {
   return options;
 });
 
-// 联动逻辑:当选择保留已有负责人时,自动切回原负责人 ID
-watch(() => claimForm.keepOldManager, (val) => {
-  if (val && claimForm.ids.length === 1) {
-    // 单个认领时,如果选“是”,则强制回显原负责人
-    const row = leadsList.value.find(i => i.id === claimForm.ids[0]);
-    if (row && row.leader) {
-      claimForm.leader = String(row.leader);
-      claimForm.currentLeaderName = row.leaderName || '';
-    }
-  } else if (!val) {
-    // 选“否”时不再默认设为自己
-    claimForm.leader = undefined;
-  }
-});
+
 
 onMounted(() => {
   getDicts();
@@ -523,7 +510,7 @@ const handleClaim = (row) => {
 
 const submitClaim = () => {
   if (!claimForm.leader) {
-    proxy.$modal.msgError("请选择项目负责人");
+    proxy.$modal.msgError("请选择业务负责人");
     return;
   }
   if (!claimForm.productSupport) {

+ 8 - 3
src/views/saleManage/opportunity/add.vue

@@ -48,7 +48,7 @@
             </el-row>
             <el-row :gutter="24">
               <el-col :span="12">
-                <el-form-item label="项目负责人" prop="managerId">
+                <el-form-item label="业务负责人" prop="managerId">
                     <el-select v-model="form.managerId" placeholder="请选择" style="width: 100%" clearable filterable @change="handleLeaderChange">
                       <el-option v-for="item in userOptions" :key="item.staffId || item.userId"
                         :label="(item.staffCode || item.userName ? '(' + (item.staffCode || item.userName) + ') ' : '') + (item.staffName || item.nickName)" :value="String(item.staffId || item.userId)" />
@@ -243,7 +243,7 @@ const remoteLoadCustomers = useDebounceFn((query) => {
 const rules = reactive({
   companyId: [{ required: true, message: '归属公司不能为空', trigger: 'change' }],
   customerNo: [{ required: true, message: '客户名称不能为空', trigger: 'change' }],
-  managerId: [{ required: true, message: '项目负责人不能为空', trigger: 'change' }],
+  managerId: [{ required: true, message: '业务负责人不能为空', trigger: 'change' }],
   projectName: [
     { required: true, message: '项目名称不能为空', trigger: 'blur' },
     { max: 200, message: '项目名称不能超过200个字符', trigger: 'blur' }
@@ -259,6 +259,7 @@ const rules = reactive({
   projectLevel: [{ required: true, message: '项目级别不能为空', trigger: 'change' }],
   projectArea: [
     { required: true, message: '项目区域不能为空', trigger: 'blur' },
+    { pattern: /^[\u4e00-\u9fa5]+$/, message: '项目区域只能输入中文,不能包含数字或其他字符', trigger: 'blur' },
     { max: 100, message: '项目区域不能超过100个字符', trigger: 'blur' }
   ],
   purchaseMethod: [{ required: true, message: '采购方式不能为空', trigger: 'change' }],
@@ -345,13 +346,17 @@ const handleUploadSuccess = (res) => {
 };
 
 const downloadFile = (row) => {
-  if (row.url) {
+  if (row.ossId) {
+    proxy.$download.oss(row.ossId);
+  } else if (row.url) {
     proxy.$modal.msgInfo("正在启动下载...");
     if (proxy.$download && proxy.$download.resource) {
       proxy.$download.resource(row.url);
     } else {
       window.open(row.url, '_blank');
     }
+  } else {
+    proxy.$modal.msgError("下载地址不存在");
   }
 };
 

+ 5 - 5
src/views/saleManage/opportunity/detail.vue

@@ -69,7 +69,7 @@
                   <el-descriptions-item label="营销活动:">{{ detailData.marketingActivityName || detailData.activityNo }}</el-descriptions-item>
                   <el-descriptions-item label=" "></el-descriptions-item>
 
-                  <el-descriptions-item label="项目负责人:">{{ detailData.leaderName || findUserName(detailData.leader) }}</el-descriptions-item>
+                  <el-descriptions-item label="业务负责人:">{{ detailData.leaderName || findUserName(detailData.leader) }}</el-descriptions-item>
                   <el-descriptions-item label="产品支持:">{{ detailData.productSupportName || findUserName(detailData.productSupport) }}</el-descriptions-item>
                   <el-descriptions-item label=" "></el-descriptions-item>
                 </el-descriptions>
@@ -883,7 +883,7 @@ const confirmAssociate = useDebounceFn(async () => {
         id: undefined, // 避免使用联系人ID作为关联表主键
         contactId: contact.id, // 记录原联系人ID
         platformCode: String(detailData.value.id),
-        customerId: detailData.value.realCustomerId || detailData.value.customerNo,
+        customerId: detailData.value.customerId || detailData.value.realCustomerId || contact.customerId,
         customerName: detailData.value.customerName,
         customerNo: detailData.value.customerNo,
         projectNo: detailData.value.projectNo
@@ -908,7 +908,7 @@ const handleNewProjectContact = () => {
   Object.assign(projectContactForm, {
     id: undefined, contactName: '', type: '1', gender: '0', age: '',
     jobStatus: '0', phone: '', deptName: '', position: '',
-    customerId: detailData.value.realCustomerId || detailData.value.customerNo,
+    customerId: detailData.value.customerId || detailData.value.realCustomerId || undefined,
     customerName: detailData.value.customerName,
     nativePlace: '', birthday: '', remark: '', officePhone: '', officeRegion: [], provincialCityCounty: '', addressDetail: '',
     jobContent: '', prStatus: '',
@@ -930,7 +930,7 @@ const handleEditContact = (row) => {
       type: String(data.type || '1'),
       gender: String(data.gender || '0'),
       age: data.age,
-      customerId: data.customerId || detailData.value.realCustomerId || detailData.value.customerNo,
+      customerId: data.customerId || detailData.value.customerId || detailData.value.realCustomerId || undefined,
       customerName: data.customerName || detailData.value.customerName,
       nativePlace: data.nativePlace,
       birthday: data.birthday,
@@ -976,7 +976,7 @@ const submitProjectContact = useDebounceFn(() => {
           ...projectContactForm,
           roleId: projectContactForm.type === '1' ? 1 : 2,
           // 关联客户信息
-          customerId: projectContactForm.customerId || detailData.value.realCustomerId || detailData.value.customerNo,
+          customerId: projectContactForm.customerId || detailData.value.customerId || detailData.value.realCustomerId || undefined,
           platformCode: String(detailData.value.id),
           customerName: projectContactForm.customerName || detailData.value.customerName || '',
           customerNo: detailData.value.customerNo || '',

+ 57 - 80
src/views/saleManage/opportunity/edit.vue

@@ -14,56 +14,48 @@
           <div class="section-block">
             <div class="section-title">基本信息</div>
             <el-row :gutter="24">
-              <el-col :span="12">
+              <el-col :span="24">
+                <el-form-item label="项目名称" prop="projectName">
+                  <el-input v-model="form.projectName" placeholder="请输入" maxlength="200" show-word-limit />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="24">
+              <el-col :span="8">
                 <el-form-item label="归属公司" prop="companyId">
-                  <el-select v-model="form.companyId" placeholder="请选择" style="width: 100%" clearable filterable>
+                  <el-select v-model="form.companyId" placeholder="请选择" style="width: 100%" clearable filterable disabled>
                     <el-option v-for="item in computedCompanyOptions" :key="item.companyCode || item.id"
                       :label="item.companyName" :value="String(item.companyCode || item.id)" />
                   </el-select>
                 </el-form-item>
               </el-col>
-              <el-col :span="12">
+              <el-col :span="16">
                 <el-form-item label="客户名称" prop="customerNo">
-                  <el-select 
-                    v-model="form.customerNo" 
-                    placeholder="请输入关键字搜索客户" 
-                    style="width: 100%" 
-                    clearable 
-                    filterable 
-                    @change="handleCustomerChange"
-                  >
-                    <el-option v-for="item in computedCustomerOptions" :key="item.id || item.customerNo"
-                      :label="item.customerName" :value="String(item.id || item.customerNo)" />
-                  </el-select>
+                  <el-input :model-value="form.customerName ? (form.customerNo + '、' + form.customerName) : ''" disabled />
                 </el-form-item>
               </el-col>
             </el-row>
             <el-row :gutter="24">
-              <el-col :span="12">
-                <el-form-item label="项目负责人" prop="managerId">
-                  <el-select v-model="form.managerId" placeholder="请选择" style="width: 100%" clearable filterable @change="handleLeaderChange">
-                    <el-option v-for="item in computedUserOptions" :key="item.staffId || item.userId"
-                      :label="(item.staffCode || item.userName ? '(' + (item.staffCode || item.userName) + ') ' : '') + (item.staffName || item.nickName)" :value="String(item.staffId || item.userId)" />
-                  </el-select>
+              <el-col :span="8">
+                <el-form-item label="行业" prop="industry">
+                  <el-input v-model="form.industry" placeholder="无" disabled style="width: 100%" />
                 </el-form-item>
               </el-col>
-              <el-col :span="12">
-                <el-form-item label="项目名称" prop="projectName">
-                  <el-input v-model="form.projectName" placeholder="请输入" maxlength="200" show-word-limit />
+              <el-col :span="8">
+                <el-form-item label="部门" prop="deptName">
+                  <el-input v-model="form.deptName" placeholder="无" disabled style="width: 100%" />
                 </el-form-item>
               </el-col>
-            </el-row>
-            <el-row :gutter="24">
               <el-col :span="8">
                 <el-form-item label="金额(万)" prop="amount">
                   <el-input-number v-model="form.amount" :precision="2" :step="1" :min="0" controls-position="right" style="width: 100%" />
                 </el-form-item>
               </el-col>
+            </el-row>
+            <el-row :gutter="24">
               <el-col :span="8">
                 <el-form-item label="赢单率(%)" prop="winRate">
-                  <el-input v-model="form.winRate" placeholder="请输入" type="number" maxlength="6">
-                    <template #append>%</template>
-                  </el-input>
+                  <el-input v-model="form.winRate" placeholder="请输入" type="number" maxlength="6" />
                 </el-form-item>
               </el-col>
               <el-col :span="8">
@@ -71,13 +63,18 @@
                   <el-date-picker v-model="form.setupTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择" style="width: 100%" />
                 </el-form-item>
               </el-col>
-            </el-row>
-            <el-row :gutter="24">
               <el-col :span="8">
                 <el-form-item label="截止时间" prop="deadline">
                   <el-date-picker v-model="form.deadline" type="date" value-format="YYYY-MM-DD" placeholder="请选择" style="width: 100%" />
                 </el-form-item>
               </el-col>
+            </el-row>
+            <el-row :gutter="24">
+              <el-col :span="8">
+                <el-form-item label="项目状态" prop="status">
+                  <el-input :model-value="saleStatusOptions?.find(i => String(i.value) === String(form.status))?.label || form.statusName || form.status" disabled style="width: 100%" />
+                </el-form-item>
+              </el-col>
               <el-col :span="16">
                 <el-form-item label="营销活动" prop="marketingActivity">
                   <el-select v-model="form.marketingActivity" placeholder="请选择" style="width: 100%" clearable filterable>
@@ -88,10 +85,18 @@
             </el-row>
           </div>
 
-          <!-- 项目信息 -->
+          <!-- 项目情况 -->
           <div class="section-block">
-            <div class="section-title">项目信息</div>
+            <div class="section-title">项目情况</div>
             <el-row :gutter="24">
+              <el-col :span="8">
+                <el-form-item label="商机来源" prop="source">
+                  <el-select v-model="form.source" placeholder="请选择" style="width: 100%" clearable filterable>
+                    <el-option v-for="item in infoSourceOptions" :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="projectLevel">
                   <el-select v-model="form.projectLevel" placeholder="请选择" style="width: 100%" clearable filterable>
@@ -105,7 +110,9 @@
                   <el-input v-model="form.projectArea" placeholder="请输入" maxlength="100" />
                 </el-form-item>
               </el-col>
-              <el-col :span="8">
+            </el-row>
+            <el-row :gutter="24">
+              <el-col :span="16">
                 <el-form-item label="采购方式" prop="purchaseMethod">
                   <el-select v-model="form.purchaseMethod" placeholder="请选择" style="width: 100%" clearable filterable>
                     <el-option v-for="item in procurementMethodOptions" :key="item.value"
@@ -115,54 +122,19 @@
               </el-col>
             </el-row>
             <el-row :gutter="24">
-              <el-col :span="8">
-                <el-form-item label="商机来源" prop="source">
-                  <el-select v-model="form.source" placeholder="请选择" style="width: 100%" clearable filterable>
-                    <el-option v-for="item in infoSourceOptions" :key="item.value"
-                      :label="item.label" :value="item.value" />
-                  </el-select>
+              <el-col :span="24">
+                <el-form-item label="项目描述" prop="description">
+                  <el-input v-model="form.description" type="textarea" :rows="3" placeholder="请输入项目描述" maxlength="500" show-word-limit />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="24">
+              <el-col :span="24">
+                <el-form-item label="竞争对手" prop="competitor">
+                  <el-input v-model="form.competitor" type="textarea" :rows="3" placeholder="请输入竞争对手" maxlength="500" show-word-limit />
                 </el-form-item>
               </el-col>
             </el-row>
-            <el-form-item label="项目描述" prop="description">
-              <el-input v-model="form.description" type="textarea" :rows="3" placeholder="请输入项目描述" maxlength="500" show-word-limit />
-            </el-form-item>
-            <el-form-item label="竞争对手" prop="competitor">
-              <el-input v-model="form.competitor" type="textarea" :rows="3" placeholder="请输入竞争对手" maxlength="500" show-word-limit />
-            </el-form-item>
-          </div>
-
-          <!-- 附件 -->
-          <div class="section-block no-border">
-            <div class="section-title attachment-header">
-              <span>附件</span>
-              <el-upload
-                :action="uploadFileUrl"
-                :headers="headers"
-                :on-success="handleUploadSuccess"
-                :show-file-list="false"
-                multiple
-                class="upload-btn"
-              >
-                <el-button link type="primary" icon="Upload">上传附件</el-button>
-              </el-upload>
-            </div>
-            <el-table :data="fileList" border stripe class="file-table">
-              <el-table-column label="文件名称" prop="name" show-overflow-tooltip>
-                <template #default="scope">
-                  <el-link type="primary" :underline="false" @click="downloadFile(scope.row)" class="file-link">
-                    <el-icon style="margin-right: 4px;"><Document /></el-icon>
-                    {{ scope.row.name }}
-                  </el-link>
-                </template>
-              </el-table-column>
-              <el-table-column label="操作" width="120" align="center">
-                 <template #default="scope">
-                   <el-button link type="primary" @click="downloadFile(scope.row)">下载</el-button>
-                   <el-button link type="danger" @click="handleDeleteFile(scope.$index)">删除</el-button>
-                 </template>
-              </el-table-column>
-            </el-table>
           </div>
         </el-form>
       </div>
@@ -225,7 +197,7 @@ const remoteLoadCustomers = useDebounceFn((query) => {
 const rules = reactive({
   companyId: [{ required: true, message: '归属公司不能为空', trigger: 'change' }],
   customerNo: [{ required: true, message: '客户名称不能为空', trigger: 'change' }],
-  managerId: [{ required: true, message: '项目负责人不能为空', trigger: 'change' }],
+  managerId: [{ required: true, message: '业务负责人不能为空', trigger: 'change' }],
   projectName: [
     { required: true, message: '项目名称不能为空', trigger: 'blur' },
     { max: 200, message: '项目名称不能超过200个字符', trigger: 'blur' }
@@ -239,6 +211,7 @@ const rules = reactive({
   ],
   setupTime: [{ required: true, message: '立项时间不能为空', trigger: 'change' }],
   projectArea: [
+    { pattern: /^[\u4e00-\u9fa5]+$/, message: '项目区域只能输入中文,不能包含数字或其他字符', trigger: 'blur' },
     { max: 100, message: '项目区域不能超过100个字符', trigger: 'blur' }
   ],
   description: [
@@ -349,13 +322,17 @@ const handleUploadSuccess = (res) => {
 };
 
 const downloadFile = (row) => {
-  if (row.url) {
+  if (row.ossId) {
+    proxy.$download.oss(row.ossId);
+  } else if (row.url) {
     proxy.$modal.msgInfo("正在启动下载...");
     if (proxy.$download && proxy.$download.resource) {
       proxy.$download.resource(row.url);
     } else {
       window.open(row.url, '_blank');
     }
+  } else {
+    proxy.$modal.msgError("下载地址不存在");
   }
 };
 

+ 7 - 7
src/views/saleManage/opportunity/index.vue

@@ -22,7 +22,7 @@
             </el-form-item>
           </el-col>
           <el-col :span="6">
-            <el-form-item label="项目负责人" prop="managerId">
+            <el-form-item label="业务负责人" prop="managerId">
               <el-select v-model="queryParams.managerId" placeholder="请选择" style="width: 100%" clearable>
                 <el-option v-for="item in userOptions" :key="item.staffId || item.userId"
                   :label="(item.staffCode || item.userName ? '(' + (item.staffCode || item.userName) + ') ' : '') + (item.staffName || item.nickName)" :value="item.staffId || item.userId" />
@@ -81,7 +81,7 @@
           </el-col>
           <el-col :span="8">
             <el-form-item label="时间范围" prop="dateRange">
-              <el-date-picker v-model="dateRange" type="daterange" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" style="width: 100%" />
+              <el-date-picker v-model="dateRange" type="daterange" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" style="width: 100%" value-format="YYYY-MM-DD" />
             </el-form-item>
           </el-col>
           <el-col :span="10">
@@ -150,7 +150,7 @@
             <span>{{ findProjectLevelName(row.projectLevel) }}</span>
           </template>
         </el-table-column>
-        <el-table-column label="项目负责人" align="center" prop="leader" min-width="100">
+        <el-table-column label="业务负责人" align="center" prop="leader" min-width="100">
           <template #default="{ row }">
             <span>{{ findUserName(row.leader) }}</span>
           </template>
@@ -201,16 +201,16 @@
     </el-card>
 
     <!-- 弹窗:转移他人 -->
-    <el-dialog title="是否将选中的项目商机转移其他负责人?" v-model="transferVisible" width="550px" append-to-body>
+    <el-dialog title="是否将选中的项目商机转移其他业务负责人?" v-model="transferVisible" width="550px" append-to-body>
       <el-form label-width="100px" style="padding: 20px 0;">
-        <el-form-item label="新负责人:" required>
+        <el-form-item label="新业务负责人:" required>
           <el-select v-model="transferOwner" placeholder="请选择" style="width: 100%">
             <el-option v-for="item in userOptions" :key="item.staffId || item.userId"
               :label="(item.staffCode || item.userName ? '(' + (item.staffCode || item.userName) + ') ' : '') + (item.staffName || item.nickName)" :value="String(item.staffId || item.userId)" />
           </el-select>
         </el-form-item>
         <el-form-item class="label-nowrap">
-          <el-checkbox v-model="keepAsMember">保留【负责人】为销售团队成员</el-checkbox>
+          <el-checkbox v-model="keepAsMember">保留【业务负责人】为销售团队成员</el-checkbox>
         </el-form-item>
       </el-form>
       <template #footer>
@@ -436,7 +436,7 @@ const handleTransfer = () => {
   transferOwner.value = ''; keepAsMember.value = true; transferVisible.value = true;
 };
 const confirmTransfer = async () => {
-  if (!transferOwner.value) return proxy.$modal.msgWarning('请选择新负责人');
+  if (!transferOwner.value) return proxy.$modal.msgWarning('请选择新业务负责人');
   const ids = multipleSelection.value.map(item => item.id);
   const ownerUser = userOptions.value.find(u => u.staffId == transferOwner.value || u.userId == transferOwner.value);
   try {

+ 11 - 0
src/views/saleManage/platformSelection/add.vue

@@ -232,6 +232,7 @@
             <el-table-column label="上传时间" prop="createTime" width="180" align="center" />
             <el-table-column label="操作" width="120" align="center">
               <template #default="scope">
+                <el-button link type="primary" @click="handleDownload(scope.row)">下载</el-button>
                 <el-button link type="danger" @click="handleFileDelete(scope.$index)">删除</el-button>
               </template>
             </el-table-column>
@@ -440,6 +441,16 @@ const handleBeforeUpload = (file) => {
 };
 
 const handleFileDelete = (index) => { drawerForm.value.fileList.splice(index, 1); };
+
+const handleDownload = (row) => {
+  if (row.ossId) {
+    proxy.$download.oss(row.ossId);
+  } else if (row.fileUrl) {
+    window.open(row.fileUrl, '_blank');
+  } else {
+    proxy.$modal.msgError("下载地址不存在");
+  }
+};
 </script>
 
 <style scoped lang="scss">

+ 3 - 2
src/views/saleManage/platformSelection/detail.vue

@@ -61,7 +61,7 @@
                     <el-descriptions-item label="项目状态">{{ getStatusLabel(drawerForm.projectStatus) }}</el-descriptions-item>
                     <el-descriptions-item label="项目级别">{{ displayProjectLevelName }}</el-descriptions-item>
                     <el-descriptions-item label="项目类型">{{ displayProjectTypeName }}</el-descriptions-item>
-                    <el-descriptions-item label="负责人">{{ drawerForm.leaderName || findUserName(drawerForm.leader) }}</el-descriptions-item>
+                    <el-descriptions-item label="业务负责人">{{ drawerForm.leaderName || findUserName(drawerForm.leader) }}</el-descriptions-item>
                     <el-descriptions-item label="产品支持">{{ drawerForm.productSupportName || findUserName(drawerForm.productSupport) }}</el-descriptions-item>
                     <el-descriptions-item label="平台名称" :span="2">{{ drawerForm.platformName }}</el-descriptions-item>
                     <el-descriptions-item label="平台链接" :span="3">{{ drawerForm.platformLink }}</el-descriptions-item>
@@ -249,6 +249,7 @@
               /* 显式传入负责人姓名,兼容多种字段名,避免回退到系统创建人 */
               leaderName: drawerForm.leaderName || drawerForm.managerName || drawerForm.staffName || ''
             }"
+            @update-readonly="val => isReadOnly = val"
           />
         </div>
       </div>
@@ -1043,7 +1044,7 @@ const openLink = (link) => {
 };
 
 const formatDate = (date) => date ? proxy.parseTime(date, '{y}-{m}-{d}') : '';
-const getStatusLabel = (s) => props.options.status?.find(o => String(o.value) === String(s))?.label || '';
+const getStatusLabel = (s) => props.options.status?.find(o => String(o.value) === String(s))?.label || (String(s) === '0' || String(s) === '1' ? '跟进中' : '');
 const getProjectRoleLabel = (val) => {
   return projectRoleOptions.value.find(o => String(o.value) === String(val))?.label || val || '';
 };

+ 138 - 126
src/views/saleManage/platformSelection/edit.vue

@@ -7,82 +7,70 @@
     :destroy-on-close="true"
   >
     <div class="edit-form-container" v-loading="loading">
-      <el-form :model="drawerForm" :rules="drawerRules" ref="drawerFormRef" label-width="140px" label-position="right">
+      <el-form :model="drawerForm" :rules="drawerRules" ref="drawerFormRef" label-width="140px" label-position="left">
         <div class="form-section">
           <div class="section-title">基本信息</div>
-          <el-row :gutter="20">
+          <el-row :gutter="24">
+            <el-col :span="24">
+              <el-form-item label="项目名称" prop="projectName">
+                <el-input v-model="drawerForm.projectName" placeholder="请输入项目名称" maxlength="200" show-word-limit />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="24">
             <el-col :span="8">
               <el-form-item label="归属公司" prop="companyNo">
-                <el-select v-model="drawerForm.companyNo" style="width:100%" placeholder="请选择" filterable>
+                <el-select v-model="drawerForm.companyNo" style="width:100%" placeholder="请选择" filterable disabled>
                   <el-option v-for="item in options.company" :key="item.companyCode" :label="item.companyName" :value="item.companyCode" />
                 </el-select>
               </el-form-item>
             </el-col>
-            <el-col :span="8">
+            <el-col :span="16">
               <el-form-item label="客户名称" prop="customName">
-                <el-select 
-                  v-model="drawerForm.customName" 
-                  style="width:100%" 
-                  placeholder="搜索客户" 
-                  filterable 
-                  clearable
-                >
-                  <el-option 
-                    v-for="item in computedCustomerOptions" 
-                    :key="item.id || item.customerNo" 
-                    :label="item.customerName || item.customName" 
-                    :value="item.customerName || item.customName" 
-                  />
-                </el-select>
+                <el-input :model-value="drawerForm.customName ? ((drawerForm.customNo || drawerForm.customerNo || drawerForm.id || '') + '、' + drawerForm.customName) : ''" disabled />
               </el-form-item>
             </el-col>
+          </el-row>
+          <el-row :gutter="24">
             <el-col :span="8">
-              <el-form-item label="项目级别" prop="projectLevel">
-                <el-select v-model="drawerForm.projectLevel" style="width:100%" placeholder="请选择">
-                  <el-option v-for="item in options.level" :key="item.value" :label="item.label" :value="item.value" />
-                </el-select>
+              <el-form-item label="行业" prop="industryName">
+                <el-input :model-value="displayIndustryName" placeholder="无" disabled style="width: 100%" />
               </el-form-item>
             </el-col>
-          </el-row>
-          <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="项目类型" prop="businessType">
-                <el-select v-model="drawerForm.businessType" style="width:100%" placeholder="请选择">
-                  <el-option v-for="item in options.type" :key="item.value" :label="item.label" :value="item.value" />
-                </el-select>
+              <el-form-item label="部门" prop="deptName">
+                <el-input :model-value="displayDeptName" placeholder="无" disabled style="width: 100%" />
               </el-form-item>
             </el-col>
+          </el-row>
+          <el-row :gutter="24">
             <el-col :span="8">
-              <el-form-item label="项目名称" prop="projectName">
-                <el-input v-model="drawerForm.projectName" placeholder="请输入项目名称" maxlength="200" show-word-limit />
+              <el-form-item label="项目状态" prop="statusName">
+                <el-input :model-value="saleStatusOptions?.find(i => String(i.value) === String(drawerForm.projectStatus))?.label || (String(drawerForm.projectStatus) === '0' || String(drawerForm.projectStatus) === '1' ? '跟进中' : (drawerForm.statusName || drawerForm.projectStatus || '无'))" disabled style="width: 100%" />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="项目负责人" prop="leader">
-                <el-select v-model="drawerForm.leader" style="width:100%" placeholder="请选择" filterable clearable>
-                  <el-option v-for="item in computedUserOptions" :key="item.userId || item.staffId" :label="(item.userName || item.staffCode ? '(' + (item.userName || item.staffCode) + ') ' : '') + (item.nickName || item.staffName)" :value="String(item.userId || item.staffId)" />
+              <el-form-item label="项目级别" prop="projectLevel">
+                <el-select v-model="drawerForm.projectLevel" style="width:100%" placeholder="请选择" clearable>
+                  <el-option v-for="item in options.level" :key="item.value" :label="item.label" :value="item.value" />
                 </el-select>
               </el-form-item>
             </el-col>
-          </el-row>
-          <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="平台名称" prop="platformName">
-                <el-input v-model="drawerForm.platformName" placeholder="请输入平台名称" maxlength="200" show-word-limit />
+              <el-form-item label="项目类型" prop="businessType">
+                <el-select v-model="drawerForm.businessType" style="width:100%" placeholder="请选择" clearable>
+                  <el-option v-for="item in options.type" :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="productSupport" label-for="productSupportSelect">
-                <el-select id="productSupportSelect" v-model="drawerForm.productSupport" style="width:100%" placeholder="请选择" filterable clearable @change="handleProductSupportChange">
-                  <template v-if="computedProductSupportOptions && computedProductSupportOptions.length">
-                    <el-option v-for="item in computedProductSupportOptions" :key="item.userId || item.staffId" :label="(item.userName || item.staffCode ? '(' + (item.userName || item.staffCode) + ') ' : '') + (item.nickName || item.staffName)" :value="String(item.userId || item.staffId)" />
-                  </template>
-                </el-select>
+              <el-form-item label="平台名称" prop="platformName">
+                <el-input v-model="drawerForm.platformName" placeholder="请输入平台名称" maxlength="200" show-word-limit />
               </el-form-item>
             </el-col>
           </el-row>
-          <el-row :gutter="20">
-            <el-col :span="24">
+          <el-row :gutter="24">
+            <el-col :span="16">
               <el-form-item label="平台链接" prop="platformLink">
                 <el-input v-model="drawerForm.platformLink" placeholder="请输入平台链接" maxlength="500" />
               </el-form-item>
@@ -92,31 +80,32 @@
 
         <div class="form-section">
           <div class="section-title">项目情况</div>
-          <el-row :gutter="20">
+          <el-row :gutter="24">
+            <el-col :span="8">
+              <el-form-item label="登记日期" prop="createTimeStr">
+                <el-input v-model="drawerForm.createTimeStr" placeholder="无" disabled style="width: 100%" />
+              </el-form-item>
+            </el-col>
             <el-col :span="8">
-              <el-form-item label="金额" prop="amount">
-                <el-input v-model="drawerForm.amount" placeholder="请输入金额" maxlength="15">
-                  <template #append>万</template>
-                </el-input>
+              <el-form-item label="金额(万)" prop="amount">
+                <el-input-number v-model="drawerForm.amount" :precision="2" :step="1" :min="0" controls-position="right" style="width: 100%" />
               </el-form-item>
             </el-col>
             <el-col :span="8">
               <el-form-item label="报名费" prop="entryFee">
-                <el-input v-model="drawerForm.entryFee" placeholder="请输入报名费" maxlength="15" />
+                <el-input-number v-model="drawerForm.entryFee" :precision="2" :step="1" :min="0" controls-position="right" style="width: 100%" />
               </el-form-item>
             </el-col>
+          </el-row>
+          <el-row :gutter="24">
             <el-col :span="8">
               <el-form-item label="投标保证金" prop="bidBond">
-                <el-input v-model="drawerForm.bidBond" placeholder="请输入投标保证金" maxlength="15" />
+                <el-input-number v-model="drawerForm.bidBond" :precision="2" :step="1" :min="0" controls-position="right" style="width: 100%" />
               </el-form-item>
             </el-col>
-          </el-row>
-          <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="赢单率" prop="winningRate">
-                <el-input v-model="drawerForm.winningRate" placeholder="请输入赢单率" maxlength="6">
-                  <template #append>%</template>
-                </el-input>
+              <el-form-item label="赢单率(%)" prop="winningRate">
+                <el-input v-model="drawerForm.winningRate" placeholder="请输入" type="number" maxlength="6" />
               </el-form-item>
             </el-col>
             <el-col :span="8">
@@ -124,54 +113,61 @@
                 <el-date-picker v-model="drawerForm.signUpDeadline" type="date" value-format="YYYY-MM-DD" style="width:100%" placeholder="请选择" />
               </el-form-item>
             </el-col>
+          </el-row>
+          <el-row :gutter="24">
             <el-col :span="8">
               <el-form-item label="投标截止时间" prop="tenderDeadline">
                 <el-date-picker v-model="drawerForm.tenderDeadline" type="date" value-format="YYYY-MM-DD" style="width:100%" placeholder="请选择" />
               </el-form-item>
             </el-col>
-          </el-row>
-          <el-row :gutter="20">
             <el-col :span="8">
-              <el-form-item label="服务期" prop="standardPeriod">
-                <el-input v-model="drawerForm.standardPeriod" placeholder="请输入服务期" maxlength="50">
-                  <template #append>年</template>
-                </el-input>
+              <el-form-item label="标书汇编完成时间" prop="compilationTime">
+                <el-date-picker v-model="drawerForm.compilationTime" type="date" value-format="YYYY-MM-DD" style="width:100%" placeholder="请选择" />
               </el-form-item>
             </el-col>
+            <el-col :span="8">
+              <el-form-item label="服务期(年)" prop="standardPeriod">
+                <el-input v-model="drawerForm.standardPeriod" placeholder="请输入" maxlength="50" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="24">
             <el-col :span="8">
               <el-form-item label="服务时间段" prop="serviceTime">
-                <el-input v-model="drawerForm.serviceTime" placeholder="请输入服务时间段" maxlength="100" />
+                <el-input v-model="drawerForm.serviceTime" placeholder="请输入" maxlength="100" />
               </el-form-item>
             </el-col>
             <el-col :span="8">
               <el-form-item label="入围类型" prop="shortlistedType">
-                <el-select v-model="drawerForm.shortlistedType" style="width:100%" placeholder="请选择">
+                <el-select v-model="drawerForm.shortlistedType" style="width:100%" placeholder="请选择" clearable>
                   <el-option v-for="item in options.shortlisted" :key="item.value" :label="item.label" :value="item.value" />
                 </el-select>
               </el-form-item>
             </el-col>
           </el-row>
-          <el-row :gutter="20">
-            <el-col :span="8">
+          <el-row :gutter="24">
+            <el-col :span="16">
               <el-form-item label="物资类目" prop="profession">
-                <el-select v-model="drawerForm.profession" style="width:100%" placeholder="请选择">
+                <el-select v-model="drawerForm.profession" style="width:100%" placeholder="请选择" clearable multiple>
                   <el-option v-for="item in options.material" :key="item.value" :label="item.label" :value="item.value" />
                 </el-select>
               </el-form-item>
             </el-col>
+          </el-row>
+          <el-row :gutter="24">
             <el-col :span="8">
               <el-form-item label="招标代理机构" prop="biddingAgency">
-                <el-input v-model="drawerForm.biddingAgency" placeholder="请输入代理机构" maxlength="100" />
+                <el-input v-model="drawerForm.biddingAgency" placeholder="请输入" maxlength="100" />
               </el-form-item>
             </el-col>
-            <el-col :span="8">
-              <el-form-item label="代理联系方式" prop="agencyContact">
-                <el-input v-model="drawerForm.agencyContact" placeholder="请输入联系方式" maxlength="50" />
+            <el-col :span="16">
+              <el-form-item label="代理机构联系方式" prop="agencyContact">
+                <el-input v-model="drawerForm.agencyContact" placeholder="请输入" maxlength="50" />
               </el-form-item>
             </el-col>
           </el-row>
-          <el-row :gutter="20">
-            <el-col :span="24">
+          <el-row :gutter="24">
+            <el-col :span="8">
               <el-form-item label="标期类型" prop="bidPeriodType">
                 <el-radio-group v-model="drawerForm.bidPeriodType">
                   <el-radio :value="1">单项目入围</el-radio>
@@ -179,29 +175,26 @@
                 </el-radio-group>
               </el-form-item>
             </el-col>
+            <el-col :span="8" v-if="drawerForm.bidPeriodType === 2">
+              <el-form-item label="预计下次投标时间" prop="nextBiddingTime">
+                <el-date-picker v-model="drawerForm.nextBiddingTime" type="date" value-format="YYYY-MM-DD" style="width:100%" placeholder="请选择" />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8" v-if="drawerForm.bidPeriodType === 2">
+              <el-form-item label="提前提醒天数" prop="noticeAdvanceDays">
+                <el-input v-model="drawerForm.noticeAdvanceDays" placeholder="请输入" maxlength="5" />
+              </el-form-item>
+            </el-col>
           </el-row>
-          <template v-if="drawerForm.bidPeriodType === 2">
-            <el-row :gutter="20">
-              <el-col :span="8">
-                <el-form-item label="预计下次投标时间" prop="nextBiddingTime">
-                  <el-date-picker v-model="drawerForm.nextBiddingTime" type="date" value-format="YYYY-MM-DD" style="width:100%" placeholder="请选择" />
-                </el-form-item>
-              </el-col>
-              <el-col :span="8">
-                <el-form-item label="提前提醒天数" prop="noticeAdvanceDays">
-                  <el-input v-model="drawerForm.noticeAdvanceDays" placeholder="请输入提醒天数" maxlength="5" />
-                </el-form-item>
-              </el-col>
-            </el-row>
-          </template>
-          <el-row :gutter="20">
+
+          <el-row :gutter="24">
             <el-col :span="24">
               <el-form-item label="入围要求" prop="shortlistedRequirement">
                 <el-input v-model="drawerForm.shortlistedRequirement" type="textarea" :rows="3" placeholder="请输入入围要求" maxlength="500" show-word-limit />
               </el-form-item>
             </el-col>
           </el-row>
-          <el-row :gutter="20">
+          <el-row :gutter="24">
             <el-col :span="24">
               <el-form-item label="项目描述" prop="projectDesc">
                 <el-input v-model="drawerForm.projectDesc" type="textarea" :rows="3" placeholder="请输入项目描述" maxlength="500" show-word-limit />
@@ -209,36 +202,6 @@
             </el-col>
           </el-row>
         </div>
-
-        <div class="form-section">
-          <div class="section-header">
-            <div class="section-title">附件</div>
-            <el-upload
-              :action="uploadFileUrl"
-              :headers="uploadHeaders"
-              :on-success="handleUploadSuccess"
-              :show-file-list="false"
-              :before-upload="handleBeforeUpload"
-            >
-              <el-button type="primary" link><el-icon><Upload /></el-icon> 上传附件</el-button>
-            </el-upload>
-          </div>
-          <el-table :data="drawerForm.fileList" border class="custom-table">
-            <el-table-column label="文件名称" prop="fileName" align="center" show-overflow-tooltip />
-            <el-table-column label="文件类型" width="100" align="center">
-              <template #default="scope">
-                <el-tag size="small" type="info">{{ scope.row.fileName ? scope.row.fileName.split('.').pop().toUpperCase() : '' }}</el-tag>
-              </template>
-            </el-table-column>
-            <el-table-column label="上传时间" prop="createTime" width="180" align="center" />
-            <el-table-column label="操作" width="120" align="center">
-              <template #default="scope">
-                <el-button link type="primary" @click="handleDownload(scope.row)">下载</el-button>
-                <el-button link type="danger" @click="handleFileDelete(scope.$index)">删除</el-button>
-              </template>
-            </el-table-column>
-          </el-table>
-        </div>
       </el-form>
     </div>
     <template #footer>
@@ -251,13 +214,14 @@
 </template>
 
 <script setup>
-import { ref, reactive, computed, watch, onMounted, getCurrentInstance } from 'vue';
+import { ref, reactive, computed, watch, onMounted, getCurrentInstance, toRefs } from 'vue';
 import { getPlatformSelection, updatePlatformSelection } from '@/api/saleManage/platformSelection/index';
 import { listCustomerInfo } from "@/api/customer/customerInfo/index";
 import { getToken } from "@/utils/auth";
 import { Upload } from '@element-plus/icons-vue';
 
 const proxy = getCurrentInstance().proxy;
+const { J0001: saleStatusOptions } = toRefs(reactive(proxy.useDict('J0001')));
 
 const props = defineProps({
   modelValue: Boolean,
@@ -329,6 +293,41 @@ const computedProductSupportOptions = computed(() => {
   return list;
 });
 
+const flatten = (list) => {
+  let res = [];
+  list.forEach(i => {
+    res.push(i);
+    if (i.children) res = res.concat(flatten(i.children));
+  });
+  return res;
+};
+
+const displayIndustryName = computed(() => {
+  if (drawerForm.value.industryName && isNaN(Number(drawerForm.value.industryName))) return drawerForm.value.industryName;
+  if (drawerForm.value.industryCategoryName && isNaN(Number(drawerForm.value.industryCategoryName))) return drawerForm.value.industryCategoryName;
+  if (drawerForm.value.industry && isNaN(Number(drawerForm.value.industry))) return drawerForm.value.industry;
+  
+  const professionId = drawerForm.value.profession || drawerForm.value.industry;
+  if (professionId && props.options.industryList) {
+    const flatList = flatten(props.options.industryList);
+    const found = flatList.find(i => String(i.id) === String(professionId))?.industryCategoryName || '';
+    if (found) return found;
+  }
+  return '';
+});
+
+const displayDeptName = computed(() => {
+  const name = drawerForm.value.deptName || drawerForm.value.createDeptName || '';
+  if (name && isNaN(Number(name))) return name;
+
+  const deptId = drawerForm.value.deptNo || drawerForm.value.deptId;
+  if (deptId && props.options.dept) {
+    const found = flatten(props.options.dept).find(d => String(d.id) === String(deptId));
+    if (found) return found.label || found.deptName || '';
+  }
+  return '';
+});
+
 const remoteSearchCustomer = async (query) => {
   customerLoading.value = true;
   try {
@@ -443,7 +442,14 @@ const loadData = async () => {
       leaderName: data.leaderName || data.staffName,
       productSupport: data.productSupport ? String(data.productSupport) : '',
       shortlistedRequirement: data.shortlistedRequirement || data.condition || data.requirement,
-      finalizationType: data.finalizationType || data.shortlistedType
+      finalizationType: data.finalizationType || data.shortlistedType,
+      companyNo: data.companyNo ? String(data.companyNo) : '',
+      projectLevel: data.projectLevel ? String(data.projectLevel) : '',
+      businessType: data.businessType ? String(data.businessType) : '',
+      shortlistedType: data.shortlistedType ? String(data.shortlistedType) : '',
+      profession: data.profession ? String(data.profession).split(',') : [],
+      projectStatus: (data.projectStatus ?? data.status) != null ? String(data.projectStatus ?? data.status) : '',
+      createTimeStr: data.createTimeStr || proxy.parseTime(data.createTime, '{y}-{m}-{d}')
     };
 
     // 补全 productSupportName
@@ -497,7 +503,8 @@ const handleSubmit = async () => {
           condition: drawerForm.value.shortlistedRequirement,
           requirement: drawerForm.value.shortlistedRequirement,
           fileNo: drawerForm.value.fileList.map(f => f.ossId).filter(Boolean).join(','),
-          finalizationType: drawerForm.value.shortlistedType // 双向映射,兼容后端字段不统一
+          finalizationType: drawerForm.value.shortlistedType, // 双向映射,兼容后端字段不统一
+          profession: Array.isArray(drawerForm.value.profession) ? drawerForm.value.profession.join(',') : drawerForm.value.profession
         };
         await updatePlatformSelection(postData);
         proxy.$modal.msgSuccess("修改成功");
@@ -511,8 +518,13 @@ const handleSubmit = async () => {
 };
 
 const handleDownload = (row) => {
-  if (!row.fileUrl) return proxy.$modal.msgError("文件地址不存在");
-  window.open(import.meta.env.VITE_APP_BASE_API + row.fileUrl, '_blank');
+  if (row.ossId) {
+    proxy.$download.oss(row.ossId);
+  } else if (row.fileUrl) {
+    window.open(row.fileUrl, '_blank');
+  } else {
+    proxy.$modal.msgError("下载地址不存在");
+  }
 };
 
 const handleUploadSuccess = (res, file) => {

+ 1 - 1
src/views/saleManage/platformSelection/index.vue

@@ -174,7 +174,7 @@
           </template>
         </el-table-column>
         <el-table-column label="部门" align="center" prop="deptName" width="120" />
-        <el-table-column label="负责人" align="center" prop="leaderName" width="100">
+        <el-table-column label="业务负责人" align="center" prop="leaderName" width="100">
           <template #default="scope">
             {{ scope.row.leaderName || scope.row.managerName || userOptions.find(u => String(u.staffId || u.userId) === String(scope.row.leader))?.staffName || '' }}
           </template>

+ 22 - 7
src/views/saleManage/projectSelection/add.vue

@@ -12,6 +12,9 @@
           <!-- 基本信息 -->
           <div class="section-block">
             <div class="section-title">基本信息</div>
+            <el-form-item label="项目名称" prop="projectName">
+              <el-input v-model="form.projectName" placeholder="请输入项目名称" maxlength="200" show-word-limit />
+            </el-form-item>
             <el-row :gutter="24">
               <el-col :span="8">
                 <el-form-item label="归属公司" prop="companyNo">
@@ -71,9 +74,6 @@
                 </el-form-item>
               </el-col>
             </el-row>
-            <el-form-item label="项目名称" prop="projectName">
-              <el-input v-model="form.projectName" placeholder="请输入项目名称" maxlength="200" show-word-limit />
-            </el-form-item>
           </div>
 
           <!-- 项目情况 -->
@@ -189,8 +189,9 @@
               <el-table-column label="文件名称" prop="name" show-overflow-tooltip />
               <el-table-column label="文件类型" prop="type" width="120" align="center" />
               <el-table-column label="上传时间" prop="uploadTime" width="180" align="center" />
-              <el-table-column label="操作" width="100" align="center">
+              <el-table-column label="操作" width="140" align="center">
                  <template #default="scope">
+                   <el-button link type="primary" @click="handleDownload(scope.row)" style="margin-right: 10px;">下载</el-button>
                    <el-button link type="danger" @click="handleDeleteFile(scope.$index)">删除</el-button>
                  </template>
               </el-table-column>
@@ -208,7 +209,7 @@
 </template>
 
 <script setup>
-import { ref, reactive, watch, getCurrentInstance } from 'vue';
+import { ref, reactive, watch, getCurrentInstance, onMounted } from 'vue';
 import { addProjectSelection } from '@/api/saleManage/projectSelection/index';
 import { listCustomerInfo } from "@/api/customer/customerInfo/index";
 import { globalHeaders } from '@/utils/request';
@@ -221,7 +222,8 @@ const props = defineProps({
   projectLevelOptions: Array,
   projectTypeOptions: Array,
   shortlistedTypeOptions: Array,
-  professionOptions: Array
+  professionOptions: Array,
+  industryOptions: Array
 });
 
 const emit = defineEmits(['update:modelValue', 'success']);
@@ -286,7 +288,10 @@ const rules = reactive({
 
 watch(() => props.modelValue, (val) => {
   visible.value = val;
-  if (val) reset();
+  if (val) {
+    reset();
+    remoteLoadCustomers('');
+  }
 });
 watch(() => visible.value, (val) => { emit('update:modelValue', val); });
 
@@ -388,6 +393,16 @@ const handleDeleteFile = (index) => {
   form.fileNo = fileList.value.map(f => f.ossId).join(',');
 };
 
+const handleDownload = (row) => {
+  if (row.ossId) {
+    proxy.$download.oss(row.ossId);
+  } else if (row.url) {
+    window.open(row.url, '_blank');
+  } else {
+    proxy.$modal.msgError("下载地址不存在");
+  }
+};
+
 const submitForm = () => {
   formRef.value.validate(valid => {
     if (valid) {

+ 5 - 4
src/views/saleManage/projectSelection/detail.vue

@@ -57,7 +57,7 @@
                   
                   <el-descriptions-item label="行业">{{ findIndustryLabel() }}</el-descriptions-item>
                   <el-descriptions-item label="部门">{{ findLeaderDeptName(detailData.leader) }}</el-descriptions-item>
-                  <el-descriptions-item label="负责人">{{ detailData.leaderName || detailData.leader }}</el-descriptions-item>
+                  <el-descriptions-item label="业务负责人">{{ detailData.leaderName || detailData.leader }}</el-descriptions-item>
                   
                   <el-descriptions-item label="项目状态">{{ getStatusLabel(detailData.projectStatus) }}</el-descriptions-item>
                   <el-descriptions-item label="项目级别">{{ getLevelLabel(detailData.projectLevel) }}</el-descriptions-item>
@@ -461,6 +461,7 @@ const props = defineProps({
   shortlistedTypeOptions: Array,
   statusOptions: Array,
   professionOptions: Array,
+  industryOptions: Array,
   deptOptions: Array
 });
 
@@ -535,7 +536,7 @@ const open = async (row) => {
         getCustomerInfo(detailData.value.customNo || detailData.value.customerNo).then(cRes => {
           const cData = cRes.data || cRes;
           const industryId = cData.industryCategoryId || cData.industryId;
-          const industryName = cData.industryName || props.professionOptions?.find(o => String(o.id) === String(industryId))?.industryCategoryName;
+          const industryName = cData.industryName || props.industryOptions?.find(o => String(o.id) === String(industryId))?.industryCategoryName;
           if (industryName) {
             detailData.value = { ...detailData.value, industryName: industryName };
           }
@@ -884,7 +885,7 @@ const handleStepClick = async (index) => {
   }
 };
 
-const getStatusLabel = (val) => props.statusOptions?.find(o => String(o.value) === String(val))?.label || val;
+const getStatusLabel = (val) => props.statusOptions?.find(o => String(o.value) === String(val))?.label || (String(val) === '2' ? '进行中' : (String(val) === '0' || String(val) === '1' ? '跟进中' : val));
 const getLevelLabel = (val) => props.projectLevelOptions?.find(o => String(o.value) === String(val))?.label || val;
 const getTypeLabel = (val) => props.projectTypeOptions?.find(o => String(o.value) === String(val))?.label || val;
 const getShortlistedLabel = (val) => props.shortlistedTypeOptions?.find(o => String(o.value) === String(val))?.label || val;
@@ -894,7 +895,7 @@ const findProfessionLabel = (val) => {
 };
 const findIndustryLabel = () => {
   return detailData.value.industryName || 
-         props.professionOptions?.find(o => String(o.id) === String(detailData.value.industryId || detailData.value.industry || detailData.value.profession))?.industryCategoryName || 
+         props.industryOptions?.find(o => String(o.id) === String(detailData.value.industryId || detailData.value.industry || detailData.value.profession))?.industryCategoryName || 
          '';
 };
 const findLeaderDeptName = (val) => {

+ 170 - 96
src/views/saleManage/projectSelection/edit.vue

@@ -9,78 +9,76 @@
   >
     <template #default>
       <div class="drawer-body" v-loading="loading">
-        <el-form ref="formRef" :model="form" :rules="rules" label-width="110px" class="selection-form" label-position="left">
+        <el-form ref="formRef" :model="form" :rules="rules" label-width="140px" class="selection-form" label-position="left">
           <!-- 基本信息 -->
           <div class="section-block">
             <div class="section-title">基本信息</div>
+            <el-row :gutter="24">
+              <el-col :span="24">
+                <el-form-item label="项目名称" prop="projectName">
+                  <el-input v-model="form.projectName" placeholder="请输入项目名称" maxlength="200" show-word-limit />
+                </el-form-item>
+              </el-col>
+            </el-row>
             <el-row :gutter="24">
               <el-col :span="8">
                 <el-form-item label="归属公司" prop="companyNo">
-                  <el-select v-model="form.companyNo" placeholder="请选择" style="width: 100%" clearable filterable>
+                  <el-select v-model="form.companyNo" placeholder="请选择" style="width: 100%" clearable filterable disabled>
                     <el-option v-for="item in computedCompanyOptions" :key="item.companyCode || item.id"
                       :label="item.companyName" :value="String(item.companyCode || item.id)" />
                   </el-select>
                 </el-form-item>
               </el-col>
+              <el-col :span="16">
+                <el-form-item label="客户名称" prop="customName">
+                  <el-input :model-value="form.customName ? ((form.customNo || form.customerNo) + '、' + form.customName) : ''" disabled />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="24">
               <el-col :span="8">
-                <el-form-item label="客户名称" prop="customerName">
-                  <el-select 
-                    v-model="form.customNo" 
-                    placeholder="搜索客户" 
-                    style="width: 100%" 
-                    filterable 
-                    clearable
-                    @change="handleCustomerChange"
-                  >
-                    <el-option 
-                      v-for="item in computedCustomerOptions" 
-                      :key="item.id || item.customerNo" 
-                      :label="item.customerName || item.customName" 
-                      :value="String(item.customerNo || item.id)" 
-                    />
-                  </el-select>
+                <el-form-item label="行业" prop="industryName">
+                  <el-input v-model="form.industryName" placeholder="无" disabled style="width: 100%" />
                 </el-form-item>
               </el-col>
               <el-col :span="8">
-                <el-form-item label="项目类型" prop="businessType">
-                  <el-select v-model="form.businessType" placeholder="请选择" style="width: 100%" clearable>
-                    <el-option v-for="item in projectTypeOptions" :key="item.value" :label="item.label" :value="String(item.value)" />
-                  </el-select>
+                <el-form-item label="部门" prop="deptName">
+                  <el-input v-model="form.deptName" placeholder="无" disabled style="width: 100%" />
                 </el-form-item>
               </el-col>
             </el-row>
             <el-row :gutter="24">
               <el-col :span="8">
-                <el-form-item label="项目类别" prop="projectLevel">
-                  <el-select v-model="form.projectLevel" placeholder="请选择" style="width: 100%" clearable>
-                    <el-option v-for="item in projectLevelOptions" :key="item.value" :label="item.label" :value="String(item.value)" />
-                  </el-select>
+                <el-form-item label="项目状态" prop="projectStatus">
+                  <el-input :model-value="saleStatusOptions?.find(i => String(i.value) === String(form.projectStatus))?.label || (String(form.projectStatus) === '2' ? '进行中' : (String(form.projectStatus) === '0' || String(form.projectStatus) === '1' ? '跟进中' : (form.statusName || form.projectStatus || '无')))" disabled style="width: 100%" />
                 </el-form-item>
               </el-col>
               <el-col :span="8">
-                <el-form-item label="项目负责人" prop="leader">
-                    <el-select v-model="form.leader" placeholder="请选择" style="width: 100%" clearable filterable @change="handleLeaderChange">
-                      <el-option v-for="item in computedUserOptions" :key="item.staffId || item.userId" :label="(item.staffCode || item.userName ? '(' + (item.staffCode || item.userName) + ') ' : '') + (item.staffName || item.nickName)" :value="String(item.staffId || item.userId)" />
-                    </el-select>
+                <el-form-item label="项目级别" prop="projectLevel">
+                  <el-select v-model="form.projectLevel" placeholder="请选择" style="width: 100%" clearable>
+                    <el-option v-for="item in projectLevelOptions" :key="item.value" :label="item.label" :value="String(item.value)" />
+                  </el-select>
                 </el-form-item>
               </el-col>
               <el-col :span="8">
-                <el-form-item label="产品支持" prop="productSupport">
-                    <el-select v-model="form.productSupport" placeholder="请选择" style="width: 100%" clearable filterable @change="handleProductSupportChange">
-                      <el-option v-for="item in computedProductSupportOptions" :key="item.staffId || item.userId" :label="(item.staffCode || item.userName ? '(' + (item.staffCode || item.userName) + ') ' : '') + (item.staffName || item.nickName)" :value="String(item.staffId || item.userId)" />
-                    </el-select>
+                <el-form-item label="项目类型" prop="businessType">
+                  <el-select v-model="form.businessType" placeholder="请选择" style="width: 100%" clearable>
+                    <el-option v-for="item in projectTypeOptions" :key="item.value" :label="item.label" :value="String(item.value)" />
+                  </el-select>
                 </el-form-item>
               </el-col>
             </el-row>
-            <el-form-item label="项目名称" prop="projectName">
-              <el-input v-model="form.projectName" placeholder="请输入项目名称" maxlength="200" show-word-limit />
-            </el-form-item>
           </div>
 
           <!-- 项目情况 -->
           <div class="section-block">
             <div class="section-title">项目情况</div>
             <el-row :gutter="24">
+              <el-col :span="8">
+                <el-form-item label="登记日期" prop="createTimeStr">
+                  <el-input v-model="form.createTimeStr" placeholder="无" disabled style="width: 100%" />
+                </el-form-item>
+              </el-col>
               <el-col :span="8">
                 <el-form-item label="金额(万)" prop="amount">
                   <el-input-number v-model="form.amount" :precision="2" :step="1" :min="0" controls-position="right" style="width: 100%" />
@@ -91,18 +89,16 @@
                   <el-input-number v-model="form.entryFee" :precision="2" :step="1" :min="0" controls-position="right" style="width: 100%" />
                 </el-form-item>
               </el-col>
+            </el-row>
+            <el-row :gutter="24">
               <el-col :span="8">
                 <el-form-item label="投标保证金" prop="bidBond">
                   <el-input-number v-model="form.bidBond" :precision="2" :step="1" :min="0" controls-position="right" style="width: 100%" />
                 </el-form-item>
               </el-col>
-            </el-row>
-            <el-row :gutter="24">
               <el-col :span="8">
                 <el-form-item label="赢单率(%)" prop="winningRate">
-                  <el-input v-model="form.winningRate" placeholder="请输入" type="number">
-                    <template #append>%</template>
-                  </el-input>
+                  <el-input v-model="form.winningRate" placeholder="请输入" type="number" maxlength="6" />
                 </el-form-item>
               </el-col>
               <el-col :span="8">
@@ -110,24 +106,31 @@
                   <el-date-picker v-model="form.signUpDeadline" type="date" value-format="YYYY-MM-DD" placeholder="请选择" style="width: 100%" />
                 </el-form-item>
               </el-col>
+            </el-row>
+            <el-row :gutter="24">
               <el-col :span="8">
                 <el-form-item label="投标截止时间" prop="tenderDeadline">
                   <el-date-picker v-model="form.tenderDeadline" type="date" value-format="YYYY-MM-DD" placeholder="请选择" style="width: 100%" />
                 </el-form-item>
               </el-col>
-            </el-row>
-            <el-row :gutter="24">
-               <el-col :span="8">
+              <el-col :span="8">
+                <el-form-item label="标书汇编完成时间" prop="compilationTime">
+                  <el-date-picker v-model="form.compilationTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择" style="width: 100%" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
                  <el-form-item label="服务期(年)" prop="standardPeriod">
                    <el-input v-model="form.standardPeriod" placeholder="请输入" maxlength="50" />
                  </el-form-item>
                </el-col>
+            </el-row>
+            <el-row :gutter="24">
                <el-col :span="8">
                  <el-form-item label="服务时间段" prop="serviceTime">
                    <el-input v-model="form.serviceTime" placeholder="请输入" maxlength="100" />
                  </el-form-item>
                </el-col>
-              <el-col :span="8">
+              <el-col :span="16">
                 <el-form-item label="入围类型" prop="shortlistedType">
                   <el-select v-model="form.shortlistedType" placeholder="请选择" style="width: 100%" clearable>
                     <el-option v-for="item in shortlistedTypeOptions" :key="item.value" :label="item.label" :value="String(item.value)" />
@@ -136,64 +139,67 @@
               </el-col>
             </el-row>
             <el-row :gutter="24">
-              <el-col :span="8">
+              <el-col :span="16">
                 <el-form-item label="物资类目" prop="profession">
-                  <el-select v-model="form.profession" placeholder="请选择" style="width: 100%" clearable>
-                    <el-option v-for="item in professionOptions" :key="item.id" :label="item.industryCategoryName" :value="String(item.id)" />
+                  <el-select v-model="form.profession" placeholder="请选择" style="width: 100%" clearable multiple>
+                    <el-option v-for="item in professionOptions" :key="item.id || item.value" :label="item.industryCategoryName || item.label" :value="String(item.id || item.value)" />
                   </el-select>
                 </el-form-item>
               </el-col>
+            </el-row>
+            <el-row :gutter="24">
                <el-col :span="8">
                  <el-form-item label="招标代理机构" prop="biddingAgency">
                    <el-input v-model="form.biddingAgency" placeholder="请输入" maxlength="100" />
                  </el-form-item>
                </el-col>
-               <el-col :span="8">
-                 <el-form-item label="代理机构联系方式" prop="agencyContact" class="label-nowrap">
+               <el-col :span="16">
+                 <el-form-item label="机构联系方式" prop="agencyContact">
                    <el-input v-model="form.agencyContact" placeholder="请输入" maxlength="50" />
                  </el-form-item>
                </el-col>
             </el-row>
-            <el-form-item label="标期类型" prop="bidPeriodType">
-              <el-radio-group v-model="form.bidPeriodType">
-                <el-radio :value="1">单项目入围</el-radio>
-                <el-radio :value="2">周期性框架</el-radio>
-              </el-radio-group>
-            </el-form-item>
-             <el-form-item label="招标链接" prop="biddingLink" v-if="form.bidPeriodType === 2">
-               <el-input v-model="form.biddingLink" placeholder="请输入/粘贴链接" maxlength="500" />
-             </el-form-item>
-            <el-form-item label="入围要求" prop="condition">
-              <el-input v-model="form.condition" type="textarea" :rows="3" placeholder="请输入" maxlength="500" show-word-limit />
-            </el-form-item>
-            <el-form-item label="项目描述" prop="projectDesc">
-              <el-input v-model="form.projectDesc" type="textarea" :rows="3" placeholder="请输入项目描述" maxlength="500" show-word-limit />
-            </el-form-item>
-          </div>
-
-          <!-- 附件 -->
-          <div class="section-block no-border">
-            <div class="section-title attachment-header">
-              <span>附件</span>
-              <el-upload
-                :action="uploadFileUrl"
-                :headers="headers"
-                :on-success="handleUploadSuccess"
-                :show-file-list="false"
-                multiple
-                class="upload-btn"
-              >
-                <el-button link type="primary" icon="Upload">上传附件</el-button>
-              </el-upload>
-            </div>
-            <el-table :data="fileList" border class="file-table">
-              <el-table-column label="文件名称" prop="name" show-overflow-tooltip />
-              <el-table-column label="操作" width="100" align="center">
-                 <template #default="scope">
-                   <el-button link type="danger" @click="handleDeleteFile(scope.$index)">删除</el-button>
-                 </template>
-              </el-table-column>
-            </el-table>
+            <el-row :gutter="24">
+              <el-col :span="8">
+                <el-form-item label="标期类型" prop="bidPeriodType">
+                  <el-radio-group v-model="form.bidPeriodType">
+                    <el-radio :value="1">单项目入围</el-radio>
+                    <el-radio :value="2">周期性框架</el-radio>
+                  </el-radio-group>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8" v-if="form.bidPeriodType === 2">
+                <el-form-item label="预计下次投标时间" prop="nextBiddingTime">
+                  <el-date-picker v-model="form.nextBiddingTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择" style="width: 100%" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8" v-if="form.bidPeriodType === 2">
+                <el-form-item label="提前提醒天数" prop="noticeAdvanceDays">
+                  <el-input v-model="form.noticeAdvanceDays" placeholder="请输入" maxlength="50" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="24">
+              <el-col :span="24">
+                 <el-form-item label="招标链接" prop="biddingLink">
+                   <el-input v-model="form.biddingLink" placeholder="请输入/粘贴链接" maxlength="500" />
+                 </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="24">
+              <el-col :span="24">
+                <el-form-item label="入围要求" prop="condition">
+                  <el-input v-model="form.condition" type="textarea" :rows="3" placeholder="请输入" maxlength="500" show-word-limit />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="24">
+              <el-col :span="24">
+                <el-form-item label="项目描述" prop="projectDesc">
+                  <el-input v-model="form.projectDesc" type="textarea" :rows="3" placeholder="请输入项目描述" maxlength="500" show-word-limit />
+                </el-form-item>
+              </el-col>
+            </el-row>
           </div>
         </el-form>
       </div>
@@ -208,9 +214,9 @@
 </template>
 
 <script setup>
-import { ref, reactive, watch, computed, getCurrentInstance } from 'vue';
+import { ref, reactive, watch, computed, getCurrentInstance, onMounted } from 'vue';
 import { getProjectSelection, updateProjectSelection } from '@/api/saleManage/projectSelection/index';
-import { listCustomerInfo } from "@/api/customer/customerInfo/index";
+import { listCustomerInfo, getCustomerInfo } from "@/api/customer/customerInfo/index";
 import { listByIds } from "@/api/system/oss/index";
 import { globalHeaders } from '@/utils/request';
 import { Upload } from '@element-plus/icons-vue';
@@ -223,7 +229,8 @@ const props = defineProps({
   projectLevelOptions: Array,
   projectTypeOptions: Array,
   shortlistedTypeOptions: Array,
-  professionOptions: Array
+  professionOptions: Array,
+  industryOptions: Array
 });
 
 const emit = defineEmits(['update:modelValue', 'success']);
@@ -239,6 +246,8 @@ const fileList = ref([]);
 const uploadFileUrl = import.meta.env.VITE_APP_BASE_API + '/resource/oss/upload';
 const headers = globalHeaders();
 
+const { J0001: saleStatusOptions } = toRefs(reactive(proxy.useDict('J0001')));
+
 const form = reactive({});
 
 const rules = reactive({
@@ -331,7 +340,10 @@ const loadDetail = (id) => {
     form.projectLevel = data.projectLevel ? String(data.projectLevel) : '';
     form.businessType = data.businessType ? String(data.businessType) : '';
     form.shortlistedType = data.shortlistedType ? String(data.shortlistedType) : '';
-    form.profession = data.profession ? String(data.profession) : '';
+    form.profession = data.profession ? String(data.profession).split(',') : [];
+    form.customNo = data.customNo ? String(data.customNo) : (data.customerNo ? String(data.customerNo) : '');
+    form.customerNo = data.customerNo ? String(data.customerNo) : (data.customNo ? String(data.customNo) : '');
+    form.projectStatus = (data.projectStatus ?? data.status) != null ? String(data.projectStatus ?? data.status) : '';
 
     // 补全 productSupportName
     if (data.productSupport) {
@@ -339,6 +351,14 @@ const loadDetail = (id) => {
       form.productSupportName = user ? (user.staffName || user.nickName) : '';
     }
 
+    // 部门回显
+    if (form.leader) {
+      const user = props.userOptions?.find(u => String(u.staffId || u.userId) === String(form.leader));
+      form.deptName = user ? (user.deptName || user.departmentName) : (data.deptName || '');
+    } else {
+      form.deptName = data.deptName || '';
+    }
+
     // 字段回显增强:将 VO/DTO 字段名映射回 Entity 字段名
     if (data.customerName && !data.customName) form.customName = data.customerName;
     if (data.winRate && !data.winningRate) form.winningRate = data.winRate;
@@ -348,6 +368,44 @@ const loadDetail = (id) => {
     if (data.winRate && !data.winningRate) form.winningRate = data.winRate;
     if (data.registrationDeadline && !data.signUpDeadline) form.signUpDeadline = data.registrationDeadline;
 
+    if (data.createTime) {
+      form.createTimeStr = proxy.parseTime(data.createTime, '{y}-{m}-{d}');
+    } else {
+      form.createTimeStr = '';
+    }
+
+    // 行业回显
+    if (!form.industryName || form.industryName === '无') {
+      const industryId = data.industryId || data.industry || data.profession;
+      const industryName = props.industryOptions?.find(o => String(o.id) === String(industryId))?.industryCategoryName;
+      if (industryName) {
+        form.industryName = industryName;
+      }
+    }
+
+    if (!form.industryName || form.industryName === '无') {
+      const customer = computedCustomerOptions.value.find(item => String(item.customerNo || item.id) === String(form.customNo));
+      if (customer) {
+        const industryId = customer.industryCategoryId || customer.industryId;
+        const industryName = customer.industryName || props.industryOptions?.find(o => String(o.id) === String(industryId))?.industryCategoryName;
+        if (industryName) {
+          form.industryName = industryName;
+        }
+      }
+    }
+
+    if ((!form.industryName || form.industryName === '无') && (form.customNo || form.customerNo)) {
+      const customerNo = form.customNo || form.customerNo;
+      getCustomerInfo(customerNo).then(cRes => {
+        const cData = cRes.data || cRes;
+        const industryId = cData.industryCategoryId || cData.industryId;
+        const industryName = cData.industryName || props.industryOptions?.find(o => String(o.id) === String(industryId))?.industryCategoryName;
+        if (industryName) {
+          form.industryName = industryName;
+        }
+      }).catch(() => {});
+    }
+
     if (form.fileNo) {
       listByIds(form.fileNo).then(ossRes => {
         fileList.value = (ossRes.data || []).map(i => ({ name: i.originalName, url: i.url, ossId: i.ossId }));
@@ -397,8 +455,10 @@ const handleLeaderChange = (val) => {
   const user = computedUserOptions.value.find(u => String(u.staffId || u.userId) === String(val));
   if (user) {
     form.leaderName = user.staffName || user.nickName;
+    form.deptName = user.deptName || user.departmentName || '';
   } else {
     form.leaderName = undefined;
+    form.deptName = '';
   }
 };
 
@@ -424,11 +484,25 @@ const handleDeleteFile = (index) => {
   form.fileNo = fileList.value.map(f => f.ossId).join(',');
 };
 
+const handleDownload = (row) => {
+  if (row.ossId) {
+    proxy.$download.oss(row.ossId);
+  } else if (row.url) {
+    window.open(row.url, '_blank');
+  } else {
+    proxy.$modal.msgError("下载地址不存在");
+  }
+};
+
 const submitForm = () => {
   formRef.value.validate(valid => {
     if (valid) {
       submitting.value = true;
-      updateProjectSelection(form).then(() => {
+      const postData = {
+        ...form,
+        profession: Array.isArray(form.profession) ? form.profession.join(',') : form.profession
+      };
+      updateProjectSelection(postData).then(() => {
         proxy.$modal.msgSuccess("修改成功");
         visible.value = false;
         emit('success');

+ 8 - 5
src/views/saleManage/projectSelection/index.vue

@@ -185,7 +185,7 @@
           </template>
         </el-table-column>
         <el-table-column label="部门" align="center" prop="deptName" min-width="120" show-overflow-tooltip />
-        <el-table-column label="负责人" align="center" prop="leaderName" width="100">
+        <el-table-column label="业务负责人" align="center" prop="leaderName" width="100">
           <template #default="{ row }">
             <span>{{ row.leaderName || findUserName(row.managerId || row.leader) }}</span>
           </template>
@@ -223,7 +223,7 @@
         <el-table-column label="项目状态" align="center" prop="projectStatus" width="100">
           <template #default="{ row }">
             <span class="status-tag" :class="getStatusClass(row.projectStatus)">
-              {{ statusOptions.find(o => String(o.value) === String(row.projectStatus))?.label || (String(row.projectStatus) === '2' ? '进行中' : row.projectStatus) }}
+              {{ statusOptions.find(o => String(o.value) === String(row.projectStatus))?.label || (String(row.projectStatus) === '2' ? '进行中' : (String(row.projectStatus) === '0' || String(row.projectStatus) === '1' ? '跟进中' : row.projectStatus)) }}
             </span>
           </template>
         </el-table-column>
@@ -261,7 +261,8 @@
       :projectLevelOptions="projectLevelOptions"
       :projectTypeOptions="projectTypeOptions"
       :shortlistedTypeOptions="shortlistedTypeOptions"
-      :professionOptions="industryOptions"
+      :professionOptions="professionOptions"
+      :industryOptions="industryOptions"
       @success="getList"
     />
     
@@ -273,7 +274,8 @@
       :projectLevelOptions="projectLevelOptions"
       :projectTypeOptions="projectTypeOptions"
       :shortlistedTypeOptions="shortlistedTypeOptions"
-      :professionOptions="industryOptions"
+      :professionOptions="professionOptions"
+      :industryOptions="industryOptions"
       @success="getList"
     />
 
@@ -286,7 +288,8 @@
       :projectLevelOptions="projectLevelOptions"
       :projectTypeOptions="projectTypeOptions"
       :shortlistedTypeOptions="shortlistedTypeOptions"
-      :professionOptions="industryOptions"
+      :professionOptions="professionOptions"
+      :industryOptions="industryOptions"
       :deptOptions="deptOptions"
       @edit="handleEdit"
       @success="getList"

+ 3 - 2
src/views/visit/plan/detail.vue

@@ -251,6 +251,7 @@ onMounted(() => {
 .drawer-body { height: calc(100vh - 50px); display: flex; }
 .main-content {
   flex: 1; display: flex; flex-direction: column; background-color: #fff; border-right: 1px solid #f0f0f0;
+  min-width: 0;
   .content-tabs {
     padding: 0 20px; border-bottom: 1px solid #f2f2f2; height: 48px;
     .tab-item {
@@ -260,10 +261,10 @@ onMounted(() => {
       }
     }
   }
-  .content-scroll { flex: 1; overflow-y: auto; padding: 20px; }
+  .content-scroll { flex: 1; overflow: auto; padding: 20px; }
 }
 .side-panel {
-  width: 30%; background-color: #fff; display: flex; flex-direction: column;
+  width: 30%; flex-shrink: 0; background-color: #fff; display: flex; flex-direction: column;
   :deep(.activity-container) {
     .el-tabs__header {
       margin-top: 0;