src/views/salesManagement/opportunityManagement/index.vue
@@ -78,6 +78,8 @@
        :row-key="(row) => row.id"
        height="calc(100vh - 18.5em)"
        stripe
        show-summary
        :summary-method="contractAmountSummaryMethod"
      >
        <el-table-column align="center" type="selection" width="55" fixed="left"/>
        <el-table-column align="center" label="序号" type="index" width="60" />
@@ -94,7 +96,9 @@
        <el-table-column label="省份" prop="province" show-overflow-tooltip />
        <el-table-column label="市" prop="city" show-overflow-tooltip/>
        <el-table-column label="客户名称" prop="customerName" show-overflow-tooltip />
        <el-table-column label="行业" prop="industry" show-overflow-tooltip />
        <el-table-column label="商机来源" prop="businessSource" show-overflow-tooltip />
        <el-table-column label="签约金额" prop="contractAmount" show-overflow-tooltip width="150" />
        <!-- <el-table-column label="客户描述" prop="description" show-overflow-tooltip min-width="200" /> -->
        <el-table-column label="录入人" prop="entryPerson" show-overflow-tooltip width="120" />
        <el-table-column label="更新日期" prop="updateTime" width="120">
@@ -102,7 +106,7 @@
            {{ formatDate(row.updateTime) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" fixed="right" width="220" align="center">
        <el-table-column label="操作" fixed="right" width="240" align="center">
          <template #default="{ row }">
            <el-button
              link
@@ -118,7 +122,7 @@
              size="small"
              @click="handleAddOperation(row)"
            >
              添加描述
              添加拜访记录
            </el-button>
            <el-button
              link
@@ -200,15 +204,40 @@
          </el-select>
        </el-form-item>
        
        <el-form-item label="客户名称" prop="customerName">
          <el-select v-model="form.customerName" placeholder="请选择" clearable :disabled="operationType === 'detail' || operationType === 'addOperation'">
            <el-option v-for="item in customerOption" :key="item.customerName" :label="item.customerName" :value="item.customerName">
              {{
                item.customerName + "——" + item.taxpayerIdentificationNumber
              }}
            </el-option>
          </el-select>
        </el-form-item>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="客户名称" prop="customerName">
              <el-select
                v-model="form.customerName"
                placeholder="请选择"
                clearable
                style="width: 100%"
                :disabled="operationType === 'detail' || operationType === 'addOperation'"
              >
                <el-option
                  v-for="item in customerOption"
                  :key="item.customerName"
                  :label="item.customerName"
                  :value="item.customerName"
                >
                  {{
                    item.customerName + "——" + item.taxpayerIdentificationNumber
                  }}
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="商机来源" prop="businessSource">
              <el-input
                v-model="form.businessSource"
                placeholder="请输入商机来源"
                clearable
                :disabled="operationType === 'detail' || operationType === 'addOperation'"
              />
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-row :gutter="20">
          <el-col :span="12">
@@ -244,17 +273,47 @@
          </el-col>
        </el-row>
        
        <el-form-item label="商机来源" prop="businessSource">
          <el-input v-model="form.businessSource" placeholder="请输入商机来源" :disabled="operationType === 'detail' || operationType === 'addOperation'" />
        <el-form-item label="签约金额" prop="contractAmount">
          <el-input
            v-model="form.contractAmount"
            placeholder="请输入签约金额"
            clearable
            :disabled="operationType === 'detail' || operationType === 'addOperation'"
          >
            <template #append>元</template>
          </el-input>
        </el-form-item>
        
        <el-form-item label="客户描述" prop="description" v-if="operationType !== 'detail'">
        <el-form-item label="拜访记录" prop="description">
          <el-input
            v-model="form.description"
            type="textarea"
            :rows="3"
            placeholder="请输入客户描述"
            :autosize="{ minRows: 4, maxRows: 10 }"
            placeholder="请输入拜访记录"
            show-word-limit
            :disabled="operationType === 'detail'"
          />
        </el-form-item>
        <el-form-item label="改造内容" prop="renContent">
          <el-input
            v-model="form.renContent"
            type="textarea"
            :autosize="{ minRows: 3, maxRows: 8 }"
            :placeholder="renovationPlaceholder"
            show-word-limit
            :disabled="operationType === 'detail' || operationType === 'addOperation'"
          />
        </el-form-item>
        <el-form-item label="付款描述" prop="paymentDescription">
          <el-input
            v-model="form.paymentDescription"
            type="textarea"
            :autosize="{ minRows: 3, maxRows: 10 }"
            placeholder="是否垫资?企业是否开票?企业是否分补贴或额外出钱?"
            show-word-limit
            :disabled="operationType === 'detail' || operationType === 'addOperation'"
          />
        </el-form-item>
        
@@ -279,9 +338,10 @@
          <el-col :span="24">
            <el-form-item label="附件材料:">
              <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload
                :disabled="operationType === 'addOperation'"
                :headers="upload.headers" :data="upload.data" :before-upload="handleBeforeUpload" :on-error="handleUploadError"
                :on-success="handleUploadSuccess" :on-remove="handleRemove">
                <el-button type="primary">上传</el-button>
                <el-button type="primary" :disabled="operationType === 'addOperation'">上传</el-button>
                <template #tip>
                  <div class="el-upload__tip">
                    文件格式支持
@@ -340,7 +400,7 @@
                  </el-tag>
                </div>
                <div class="description-change" v-if="record.description">
                  <span class="label">客户描述:</span>
                  <span class="label">拜访记录:</span>
                  <span class="description-text">{{ record.description }}</span>
                </div>
              </div>
@@ -395,6 +455,25 @@
const tableLoading = ref(false)
const userList = ref([])
const customerOption = ref([])
const DEFAULT_USER_QUERY = { postCode: 'Market_Sales' }
let userListPromise = null
const loadUserList = async (query = DEFAULT_USER_QUERY) => {
  if (userListPromise) return userListPromise
  userListPromise = (async () => {
    try {
      const res = await userListNoPage(query)
      userList.value = res?.data || []
      return userList.value
    } catch (err) {
      console.error('获取用户列表失败:', err)
      userList.value = []
      userListPromise = null
      throw err
    }
  })()
  return userListPromise
}
// 分页配置
const page = reactive({
@@ -430,10 +509,15 @@
  customerScale: '',
  mainProducts: '',
  businessSource: '',
  contractAmount: '',
  description: '',
  renContent: '',
  paymentDescription: '',
  entryPerson: userStore.nickName,
  entryDate: dayjs().format('YYYY-MM-DD')
})
const renovationPlaceholder = '1.标准化:\n2.定制化:\n3.外采:'
// 变更记录数据(模拟数据)
const changeHistory = ref([])
@@ -482,10 +566,13 @@
const statusOptions = [
  { value: '新建', label: '新建' },
  { value: '项目跟踪', label: '项目跟踪' },
  { value: '放弃', label: '放弃' },
  { value: '合同签约', label: '合同签约' },
  { value: '备案申报', label: '备案申报' },
  { value: '项目交付', label: '项目交付' },
  { value: '项目验收', label: '项目验收' }
  { value: '项目验收', label: '项目验收' },
  { value: '项目回款', label: '项目回款' },
  { value: '回补贴', label: '回补贴' }
]
// 省份选项
@@ -497,10 +584,13 @@
  const typeMap = { 
    '新建': 'info', 
    '项目跟踪': 'primary', 
    '放弃': 'danger',
    '合同签约': 'warning', 
    '备案申报': 'primary',
    '项目交付': 'success',
    '项目验收': 'success'
    '项目验收': 'success',
    '项目回款': 'success',
    '回补贴': 'success'
  } 
  return typeMap[status] || 'info' 
@@ -510,10 +600,13 @@
  const textMap = { 
    '新建': '新建', 
    '项目跟踪': '项目跟踪', 
    '放弃': '放弃',
    '合同签约': '合同签约', 
    '备案申报': '备案申报',
    '项目交付': '项目交付',
    '项目验收': '项目验收'
    '项目验收': '项目验收',
    '项目回款': '项目回款',
    '回补贴': '回补贴'
  } 
  return textMap[status] || '未知' 
}
@@ -586,6 +679,11 @@
  })
}
// 签约金额合计(复用全局 summarizeTable)
const contractAmountSummaryMethod = (param) => {
  return proxy.summarizeTable(param, ["contractAmount"]);
}
// 分页变化
const paginationChange = (pagination) => {
  page.current = pagination.page
@@ -604,8 +702,7 @@
  resetForm()
  
  // 加载用户列表和客户列表
  let userLists = await userListNoPage()
  userList.value = userLists.data
  await loadUserList()
  customerList().then((res) => {
    customerOption.value = res
  })
@@ -626,17 +723,16 @@
  operationType.value = 'addOperation'
  
  // 加载用户列表和客户列表
  let userLists = await userListNoPage()
  userList.value = userLists.data
  await loadUserList()
  customerList().then((res) => {
    customerOption.value = res
  })
  
  // 使用当前行数据作为基础,但只能修改状态和客户描述
  // 使用当前行数据作为基础,但只能修改状态和拜访记录;付款描述、改造内容等保留反显
  Object.assign(form, row, {
    // 保留原始商机ID,用于关联操作记录
    status: row.status,
    description: '', // 清空客户描述,允许重新填写
    description: '', // 清空拜访记录,允许重新填写
    entryPerson: userStore.nickName, // 设置录入人为当前账号
    entryDate: dayjs().format('YYYY-MM-DD') // 设置录入时间为当天
  })
@@ -648,8 +744,7 @@
  operationType.value = 'detail'
  
  // 加载用户列表和客户列表
  let userLists = await userListNoPage()
  userList.value = userLists.data
  await loadUserList()
  customerList().then((res) => {
    customerOption.value = res
  })
@@ -691,8 +786,7 @@
  operationType.value = 'edit'
  
  // 加载用户列表和客户列表
  let userLists = await userListNoPage()
  userList.value = userLists.data
  await loadUserList()
  customerList().then((res) => {
    customerOption.value = res
  })
@@ -780,6 +874,7 @@
        submitData = {
          status: form.status,
          description: form.description,
          paymentDescription: form.paymentDescription,
          entryPerson: form.entryPerson,
          entryDate: form.entryDate,
          tempFileIds: tempFileIds,
@@ -857,7 +952,10 @@
    customerScale: '',
    mainProducts: '',
    businessSource: '',
    contractAmount: '',
    description: '',
    renContent: '',
    paymentDescription: '',
    entryPerson: userStore.nickName,
    entryDate: dayjs().format('YYYY-MM-DD')
  })
@@ -947,8 +1045,7 @@
onMounted(async () => {
  // 加载用户列表供搜索使用
  const userLists = await userListNoPage()
  userList.value = userLists.data
  await loadUserList()
  getList()
})
</script>