| | |
| | | @change="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="状态"> |
| | | <el-select |
| | | v-model="searchForm.status" |
| | | placeholder="请选择状态" |
| | | clearable |
| | | style="width: 160px" |
| | | @change="handleQuery" |
| | | > |
| | | <el-option |
| | | v-for="item in statusOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="录入人"> |
| | | <el-select |
| | | v-model="searchForm.entryPerson" |
| | |
| | | :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" /> |
| | |
| | | <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"> |
| | |
| | | {{ 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 |
| | |
| | | size="small" |
| | | @click="handleAddOperation(row)" |
| | | > |
| | | 添加描述 |
| | | 添加拜访记录 |
| | | </el-button> |
| | | <el-button |
| | | link |
| | |
| | | </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"> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="信息化现状"> |
| | | <el-input v-model="form.informationState" placeholder="请输入信息化现状" clearable :disabled="operationType === 'detail' || operationType === 'addOperation'" /> |
| | | <el-form-item label="主营产品"> |
| | | <el-input v-model="form.mainProducts" placeholder="请输入主营产品" clearable :disabled="operationType === 'detail' || operationType === 'addOperation'" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="主营产品"> |
| | | <el-input v-model="form.mainProducts" placeholder="请输入主营产品" clearable :disabled="operationType === 'detail' || operationType === 'addOperation'" /> |
| | | <el-form-item label="信息化现状"> |
| | | <el-input v-model="form.informationState" placeholder="请输入信息化现状" clearable :disabled="operationType === 'detail' || operationType === 'addOperation'" /> |
| | | </el-form-item> |
| | | </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> |
| | | |
| | |
| | | <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"> |
| | | 文件格式支持 |
| | |
| | | </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> |
| | |
| | | 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({ |
| | |
| | | const searchForm = reactive({ |
| | | customerName: '', |
| | | city: '', |
| | | status: '', |
| | | entryPerson: '', |
| | | entryDate: [], |
| | | entryDateStart: '', |
| | |
| | | customerScale: '', |
| | | mainProducts: '', |
| | | businessSource: '', |
| | | contractAmount: '', |
| | | description: '', |
| | | renContent: '', |
| | | paymentDescription: '', |
| | | entryPerson: userStore.nickName, |
| | | entryDate: dayjs().format('YYYY-MM-DD') |
| | | }) |
| | | |
| | | const renovationPlaceholder = '1.标准化:\n2.定制化:\n3.外采:' |
| | | |
| | | // 变更记录数据(模拟数据) |
| | | const changeHistory = ref([]) |
| | |
| | | const statusOptions = [ |
| | | { value: '新建', label: '新建' }, |
| | | { value: '项目跟踪', label: '项目跟踪' }, |
| | | { value: '放弃', label: '放弃' }, |
| | | { value: '合同签约', label: '合同签约' }, |
| | | { value: '备案申报', label: '备案申报' }, |
| | | { value: '项目交付', label: '项目交付' }, |
| | | { value: '项目验收', label: '项目验收' } |
| | | { value: '项目验收', label: '项目验收' }, |
| | | { value: '项目回款', label: '项目回款' }, |
| | | { value: '回补贴', label: '回补贴' } |
| | | ] |
| | | |
| | | // 省份选项 |
| | |
| | | const typeMap = { |
| | | '新建': 'info', |
| | | '项目跟踪': 'primary', |
| | | '放弃': 'danger', |
| | | '合同签约': 'warning', |
| | | '备案申报': 'primary', |
| | | '项目交付': 'success', |
| | | '项目验收': 'success' |
| | | '项目验收': 'success', |
| | | '项目回款': 'success', |
| | | '回补贴': 'success' |
| | | } |
| | | return typeMap[status] || 'info' |
| | | } |
| | |
| | | const textMap = { |
| | | '新建': '新建', |
| | | '项目跟踪': '项目跟踪', |
| | | '放弃': '放弃', |
| | | '合同签约': '合同签约', |
| | | '备案申报': '备案申报', |
| | | '项目交付': '项目交付', |
| | | '项目验收': '项目验收' |
| | | '项目验收': '项目验收', |
| | | '项目回款': '项目回款', |
| | | '回补贴': '回补贴' |
| | | } |
| | | return textMap[status] || '未知' |
| | | } |
| | |
| | | Object.assign(searchForm, { |
| | | customerName: '', |
| | | city: '', |
| | | status: '', |
| | | entryPerson: '', |
| | | entryDate: [], |
| | | entryDateStart: '', |
| | |
| | | }) |
| | | } |
| | | |
| | | // 签约金额合计(复用全局 summarizeTable) |
| | | const contractAmountSummaryMethod = (param) => { |
| | | return proxy.summarizeTable(param, ["contractAmount"]); |
| | | } |
| | | |
| | | // 分页变化 |
| | | const paginationChange = (pagination) => { |
| | | page.current = pagination.page |
| | |
| | | resetForm() |
| | | |
| | | // 加载用户列表和客户列表 |
| | | let userLists = await userListNoPage() |
| | | userList.value = userLists.data |
| | | await loadUserList() |
| | | customerList().then((res) => { |
| | | customerOption.value = res |
| | | }) |
| | |
| | | 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') // 设置录入时间为当天 |
| | | }) |
| | |
| | | operationType.value = 'detail' |
| | | |
| | | // 加载用户列表和客户列表 |
| | | let userLists = await userListNoPage() |
| | | userList.value = userLists.data |
| | | await loadUserList() |
| | | customerList().then((res) => { |
| | | customerOption.value = res |
| | | }) |
| | |
| | | operationType.value = 'edit' |
| | | |
| | | // 加载用户列表和客户列表 |
| | | let userLists = await userListNoPage() |
| | | userList.value = userLists.data |
| | | await loadUserList() |
| | | customerList().then((res) => { |
| | | customerOption.value = res |
| | | }) |
| | |
| | | submitData = { |
| | | status: form.status, |
| | | description: form.description, |
| | | paymentDescription: form.paymentDescription, |
| | | entryPerson: form.entryPerson, |
| | | entryDate: form.entryDate, |
| | | tempFileIds: tempFileIds, |
| | |
| | | customerScale: '', |
| | | mainProducts: '', |
| | | businessSource: '', |
| | | contractAmount: '', |
| | | description: '', |
| | | renContent: '', |
| | | paymentDescription: '', |
| | | entryPerson: userStore.nickName, |
| | | entryDate: dayjs().format('YYYY-MM-DD') |
| | | }) |
| | |
| | | |
| | | onMounted(async () => { |
| | | // 加载用户列表供搜索使用 |
| | | const userLists = await userListNoPage() |
| | | userList.value = userLists.data |
| | | await loadUserList() |
| | | getList() |
| | | }) |
| | | </script> |