| | |
| | | <div class="app-container"> |
| | | <!-- 搜索区域 --> |
| | | <div class="search_form"> |
| | | <el-form :model="searchForm" :inline="true" label-width="auto"> |
| | | <el-form :model="searchForm" :inline="true"> |
| | | <el-form-item label="客户名称"> |
| | | <el-input |
| | | v-model="searchForm.customerName" |
| | | placeholder="请输入客户名称" |
| | | clearable |
| | | prefix-icon="Search" |
| | | style="width: 200px" |
| | | style="width: 200px;" |
| | | @change="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="城市"> |
| | | <el-input |
| | | v-model="searchForm.city" |
| | | placeholder="请输入城市名称" |
| | | clearable |
| | | prefix-icon="Search" |
| | | style="width: 200px" |
| | | @change="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="录入人"> |
| | | <el-select |
| | | v-model="searchForm.entryPerson" |
| | | placeholder="请选择录入人" |
| | | clearable |
| | | filterable |
| | | style="width: 200px" |
| | | @change="handleQuery" |
| | | > |
| | | <el-option |
| | | v-for="item in userList" |
| | | :key="item.nickName" |
| | | :label="item.nickName" |
| | | :value="item.nickName" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="录入日期:"> |
| | | <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" |
| | |
| | | <el-form-item> |
| | | <el-button type="primary" @click="handleQuery">搜索</el-button> |
| | | <el-button @click="resetQuery">重置</el-button> |
| | | <el-button type="primary" @click="handleAdd">新建</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">删除</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div class="actions"> |
| | | <el-button type="primary" @click="handleAdd">新建</el-button> |
| | | <el-button type="danger" plain @click="handleDelete">删除</el-button> |
| | | </div> |
| | | </div> |
| | | <!-- 表格区域 --> |
| | | <div class="table_list"> |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="行业"> |
| | | <el-input v-model="form.industry" placeholder="请输入行业" clearable :disabled="operationType === 'detail' || operationType === 'addOperation'" /> |
| | | </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> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="主营业务收入"> |
| | | <el-input v-model="form.mainBusinessRevenue" placeholder="请输入主营业务收入" clearable :disabled="operationType === 'detail' || operationType === 'addOperation'" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="客户规模"> |
| | | <el-input v-model="form.customerScale" 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> |
| | | </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> |
| | |
| | | </el-row> |
| | | </el-form> |
| | | |
| | | <!-- 附件查看(仅在详情模式下显示) --> |
| | | <div v-if="operationType === 'detail'" class="attachment-section"> |
| | | <el-divider content-position="left">附件材料</el-divider> |
| | | <div v-if="form.businessCommonFiles && form.businessCommonFiles.length > 0"> |
| | | <el-table :data="form.businessCommonFiles" border stripe style="width: 100%"> |
| | | <el-table-column label="附件名称" prop="name" min-width="400" show-overflow-tooltip /> |
| | | <el-table-column fixed="right" label="操作" width="150" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="downloadAttachment(scope.row)">下载</el-button> |
| | | <el-button link type="primary" size="small" @click="previewAttachment(scope.row)">预览</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | <div v-else style="text-align: center; padding: 20px; color: #999;"> |
| | | 暂无附件 |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 变更记录时间线(仅在详情模式下显示) --> |
| | | <div v-if="operationType === 'detail'" class="change-history-section"> |
| | | <el-divider content-position="left">变更记录</el-divider> |
| | |
| | | </el-dialog> |
| | | |
| | | <!-- 附件列表对话框 --> |
| | | <FileList ref="fileListRef" /> |
| | | <FileList ref="fileListRef" @refresh="handleFileListRefresh" /> |
| | | <!-- 文件预览组件 --> |
| | | <filePreview ref="filePreviewRef" /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | import { userListNoPage } from '@/api/system/user.js' |
| | | import {customerList, getSalesLedgerWithProducts} from '@/api/salesManagement/salesLedger.js' |
| | | import FileList from './fileList.vue' |
| | | import filePreview from '@/components/filePreview/index.vue' |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const userStore = useUserStore() |
| | |
| | | // 搜索表单 |
| | | const searchForm = reactive({ |
| | | customerName: '', |
| | | city: '', |
| | | entryPerson: '', |
| | | entryDate: [], |
| | | entryDateStart: '', |
| | | entryDateEnd: '' |
| | |
| | | province: '', |
| | | city: '', |
| | | customerName: '', |
| | | industry: '', |
| | | informationState: '', |
| | | mainBusinessRevenue: '', |
| | | customerScale: '', |
| | | mainProducts: '', |
| | | businessSource: '', |
| | | description: '', |
| | | entryPerson: userStore.nickName, |
| | |
| | | |
| | | // FileList组件引用 |
| | | const fileListRef = ref(null) |
| | | const currentAttachmentRow = ref(null) |
| | | const filePreviewRef = ref(null) |
| | | |
| | | // 上传配置 |
| | | const upload = reactive({ |
| | |
| | | { value: '新建', label: '新建' }, |
| | | { value: '项目跟踪', label: '项目跟踪' }, |
| | | { value: '合同签约', label: '合同签约' }, |
| | | { value: '备案申报', label: '备案申报' }, |
| | | { value: '项目交付', label: '项目交付' }, |
| | | { value: '项目验收', label: '项目验收' } |
| | | ] |
| | |
| | | '新建': 'info', |
| | | '项目跟踪': 'primary', |
| | | '合同签约': 'warning', |
| | | '项目交付': 'success', |
| | | '备案申报': 'primary', |
| | | '项目交付': 'success', |
| | | '项目验收': 'success' |
| | | } |
| | | return typeMap[status] || 'info' |
| | |
| | | '新建': '新建', |
| | | '项目跟踪': '项目跟踪', |
| | | '合同签约': '合同签约', |
| | | '项目交付': '项目交付', |
| | | '备案申报': '备案申报', |
| | | '项目交付': '项目交付', |
| | | '项目验收': '项目验收' |
| | | } |
| | | return textMap[status] || '未知' |
| | |
| | | const resetQuery = () => { |
| | | Object.assign(searchForm, { |
| | | customerName: '', |
| | | city: '', |
| | | entryPerson: '', |
| | | entryDate: [], |
| | | entryDateStart: '', |
| | | entryDateEnd: '' |
| | |
| | | const resetForm = () => { |
| | | Object.assign(form, { |
| | | id: undefined, |
| | | status: '新建', |
| | | status: '', |
| | | province: '', |
| | | city: '', |
| | | customerName: '', |
| | | industry: '', |
| | | informationState: '', |
| | | mainBusinessRevenue: '', |
| | | customerScale: '', |
| | | mainProducts: '', |
| | | businessSource: '', |
| | | description: '', |
| | | entryPerson: userStore.nickName, |
| | |
| | | |
| | | // 查看附件 |
| | | function handleAttachment(row) { |
| | | fileListRef.value.open(row.businessCommonFiles) |
| | | currentAttachmentRow.value = row |
| | | fileListRef.value.open(row.businessCommonFiles, row.id) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | // 下载附件(详情页面) |
| | | function downloadAttachment(row) { |
| | | proxy.$download.name(row.url) |
| | | } |
| | | |
| | | // 预览附件(详情页面) |
| | | function previewAttachment(row) { |
| | | if (filePreviewRef.value) { |
| | | filePreviewRef.value.open(row.url) |
| | | } else { |
| | | // 如果没有预览组件,直接打开链接 |
| | | window.open(row.url, '_blank') |
| | | } |
| | | } |
| | | |
| | | // 附件列表刷新 |
| | | function handleFileListRefresh(rowId) { |
| | | // 重新获取列表数据 |
| | | getList() |
| | | // 等待列表数据更新后,找到对应的行并更新附件列表 |
| | | setTimeout(() => { |
| | | if (currentAttachmentRow.value && tableData.value) { |
| | | const updatedRow = tableData.value.find(item => item.id === currentAttachmentRow.value.id) |
| | | if (updatedRow && updatedRow.businessCommonFiles) { |
| | | currentAttachmentRow.value = updatedRow |
| | | fileListRef.value.open(updatedRow.businessCommonFiles, updatedRow.id) |
| | | } |
| | | } |
| | | }, 300) |
| | | } |
| | | |
| | | onMounted(async () => { |
| | | // 加载用户列表供搜索使用 |
| | | const userLists = await userListNoPage() |
| | | userList.value = userLists.data |
| | | getList() |
| | | }) |
| | | </script> |