| New file |
| | |
| | | <template> |
| | | <PageWrapper title="财务审核详情页" contentBackground> |
| | | <a-card title="基本信息"> |
| | | <a-descriptions title="" :column="3"> |
| | | <a-descriptions-item label="企业名称"> |
| | | <span>{{ formData.customer?.enterpriseName || '-' }}</span> |
| | | </a-descriptions-item> |
| | | <a-descriptions-item label="行业"> |
| | | <span>{{ formData.customer?.industry || '-' }}</span> |
| | | </a-descriptions-item> |
| | | <a-descriptions-item label="客户地址"> |
| | | <span>{{ formData.customer?.customerAddress || '-' }}</span> |
| | | </a-descriptions-item> |
| | | <a-descriptions-item label="对接人"> |
| | | <span>{{ formData.customer?.contactPerson || '-' }}</span> |
| | | </a-descriptions-item> |
| | | <a-descriptions-item label="客户电话"> |
| | | <span>{{ formData.customer?.customerPhone || '-' }}</span> |
| | | </a-descriptions-item> |
| | | <a-descriptions-item label="客户邮箱"> |
| | | <span>{{ formData.customer?.customerEmail || '-' }}</span> |
| | | </a-descriptions-item> |
| | | </a-descriptions> |
| | | </a-card> |
| | | <a-card title="合同信息"> |
| | | <a-descriptions title="" :column="1"> |
| | | <a-descriptions-item label="紧急状态"> |
| | | <span>{{ formData.emergencyStatus === 1 ? '紧急' : formData.emergencyStatus === 3 ? '正常' : '-' }}</span> |
| | | </a-descriptions-item> |
| | | <a-descriptions-item label="合作周期"> |
| | | <span>{{ formData.month ? `${formData.month}月` : '-' }}</span> |
| | | </a-descriptions-item> |
| | | <!-- <a-descriptions-item label="合作开始时间"> |
| | | <span>{{ formData.startDate || '-' }}</span> |
| | | </a-descriptions-item> |
| | | <a-descriptions-item label="合作结束时间"> |
| | | <span>{{ formData.endDate || '-' }}</span> |
| | | </a-descriptions-item> --> |
| | | <a-descriptions-item label="合同"> |
| | | <div v-if="contractFiles.length > 0"> |
| | | <div v-for="file in contractFiles" :key="file.uid"> |
| | | <a @click="handleDownload(file)" style="margin-top: 4px; display: inline-block">{{ getFileName(file) }}</a> |
| | | </div> |
| | | </div> |
| | | <div v-else> |
| | | <span>-</span> |
| | | </div> |
| | | </a-descriptions-item> |
| | | <a-descriptions-item label="附件"> |
| | | <div v-if="attachmentFiles.length > 0"> |
| | | <div v-for="file in attachmentFiles" :key="file.uid"> |
| | | <a @click="handleDownload(file)" style="margin-top: 4px; display: inline-block">{{ getFileName(file) }}</a> |
| | | </div> |
| | | </div> |
| | | <div v-else> |
| | | <span>-</span> |
| | | </div> |
| | | </a-descriptions-item> |
| | | </a-descriptions> |
| | | </a-card> |
| | | <a-card title="语义词信息"> |
| | | <div v-if="semanticWords.length > 0"> |
| | | <a-descriptions title="" :column="1"> |
| | | <a-descriptions-item v-for="word in semanticWords" :key="word.id" :label="`语义词 ${semanticWords.indexOf(word) + 1}`"> |
| | | <div style="display: flex; flex-direction: column; gap: 12px; width: 100%"> |
| | | <div style="display: flex; gap: 16px; width: 100%"> |
| | | <span style="flex: 1;"><strong>类型:</strong>{{ word.category === '1' ? '品牌' : word.category === '2' ? '地区词' : '全国词' }}</span> |
| | | <span style="flex: 1;"><strong>语义词:</strong>{{ word.word || '-' }}</span> |
| | | <span style="flex: 1;"><strong>露出词:</strong>{{ word.outWord || '-' }}</span> |
| | | <span style="flex: 1;"><strong>价格:</strong>{{ word.price ? `${formatPrice(word.price)}元` : '-' }}</span> |
| | | <span style="flex: 1;"><strong>合作周期:</strong>{{ word.month ? `${word.month}月` : '-' }}</span> |
| | | <span style="flex: 1;"><strong>签约排名:</strong>{{ formatRanking(word.ranking) }}</span> |
| | | <span style="flex: 1;"><strong>验收指标(>=):</strong>{{ word.acceptindicator ? `${word.acceptindicator}%` : '-' }}</span> |
| | | </div> |
| | | </div> |
| | | </a-descriptions-item> |
| | | </a-descriptions> |
| | | </div> |
| | | <div v-else> |
| | | <a-empty description="暂无语义词数据" /> |
| | | </div> |
| | | </a-card> |
| | | <!-- 返回按钮 --> |
| | | <div class="action-buttons"> |
| | | <a-button type="default" @click="handleBack" class="back-btn">返回</a-button> |
| | | </div> |
| | | </PageWrapper> |
| | | </template> |
| | | <script lang="ts"> |
| | | import { defineComponent, reactive, ref, onMounted } from 'vue'; |
| | | import { PageWrapper } from '/@/components/Page'; |
| | | import { message } from 'ant-design-vue'; |
| | | import { useRoute, useRouter } from 'vue-router'; |
| | | import { defHttp } from '/@/utils/http/axios'; |
| | | import { getFileAccessHttpUrl } from '/@/utils/common/compUtils'; |
| | | |
| | | export default defineComponent({ |
| | | name: 'DescDetailKehu', |
| | | components: { PageWrapper }, |
| | | setup() { |
| | | const route = useRoute(); |
| | | const router = useRouter(); |
| | | |
| | | // 初始数据 |
| | | const initialData = { |
| | | id: '', |
| | | createTime: '', |
| | | updateBy: null, |
| | | updateTime: null, |
| | | agentsId: null, |
| | | agentsName: null, |
| | | contractFileList: null, |
| | | contractName: '', |
| | | createBy: '', |
| | | customer: { |
| | | id: '', |
| | | createBy: '', |
| | | createTime: '', |
| | | updateBy: null, |
| | | updateTime: null, |
| | | agentsName: null, |
| | | contactPerson: '', |
| | | contract: null, |
| | | customerAddress: '', |
| | | customerEmail: '', |
| | | customerPhone: '', |
| | | enterpriseName: '', |
| | | industry: '', |
| | | semanticWordList: null, |
| | | }, |
| | | customerName: '', |
| | | endDate: '', |
| | | rejectionReasons: null, |
| | | reviewStatus: '', |
| | | semanticWordList: null, |
| | | startDate: '', |
| | | sysOrgCode: '', |
| | | emergencyStatus: 3, // 默认正常状态 |
| | | month: null, // 合作周期(月) |
| | | }; |
| | | |
| | | // 响应式表单数据 |
| | | const formData = reactive({ ...initialData }); |
| | | |
| | | // 语义词列表 |
| | | const semanticWords = ref<any[]>([]); |
| | | |
| | | // 合同文件列表 |
| | | const contractFiles = ref<any[]>([]); |
| | | const attachmentFiles = ref<any[]>([]); |
| | | |
| | | // 加载客户数据 |
| | | const loadCustomerData = async () => { |
| | | const id = route.query.id as string; |
| | | if (id) { |
| | | try { |
| | | // 调用API根据id获取客户数据 |
| | | const result = await defHttp.get({ |
| | | url: '/contract/contract/queryById', |
| | | params: { id }, |
| | | }); |
| | | console.log('客户详情数据:', result); |
| | | if (result) { |
| | | const customerData = result; |
| | | // 填充表单数据 |
| | | Object.assign(formData, customerData); |
| | | // 确保 emergencyStatus 正确设置(1=紧急,3=正常) |
| | | const emergencyStatus = Number(customerData.emergencyStatus); |
| | | if (emergencyStatus === 1 || emergencyStatus === 3) { |
| | | formData.emergencyStatus = emergencyStatus; |
| | | } else { |
| | | formData.emergencyStatus = 3; // 默认正常状态 |
| | | } |
| | | |
| | | // 加载合同文件数据 |
| | | await loadContractFiles(id); |
| | | |
| | | // 加载语义词数据 |
| | | await loadSemanticWords(id); |
| | | } else { |
| | | message.error('加载客户详情数据失败'); |
| | | } |
| | | } catch (error) { |
| | | console.error('加载客户详情数据失败:', error); |
| | | message.error('加载客户详情数据失败'); |
| | | } |
| | | } else { |
| | | message.error('缺少客户ID参数'); |
| | | } |
| | | }; |
| | | |
| | | // 加载合同文件数据 |
| | | const loadContractFiles = async (id: string) => { |
| | | try { |
| | | const result = await defHttp.get({ |
| | | url: '/contract/contract/queryContractFileByMainId', |
| | | params: { id }, |
| | | }); |
| | | console.log('合同文件数据:', result); |
| | | // 这里可以根据返回的数据结构处理合同文件 |
| | | if (result && Array.isArray(result)) { |
| | | // 根据 fileType 区分合同文件和附件 |
| | | const contractFileList: any[] = []; |
| | | const attachmentFileList: any[] = []; |
| | | |
| | | result.forEach((file: any) => { |
| | | const fileItem = { |
| | | uid: file.id, |
| | | name: file.appendixFile || '文件', |
| | | status: 'done', |
| | | url: file.appendixFile, |
| | | }; |
| | | |
| | | if (file.fileType === '合同文件') { |
| | | contractFileList.push(fileItem); |
| | | } else if (file.fileType === '合同附件') { |
| | | attachmentFileList.push(fileItem); |
| | | } |
| | | }); |
| | | |
| | | contractFiles.value = contractFileList; |
| | | attachmentFiles.value = attachmentFileList; |
| | | } |
| | | } catch (error) { |
| | | console.error('加载合同文件失败:', error); |
| | | } |
| | | }; |
| | | |
| | | // 加载语义词数据 |
| | | const loadSemanticWords = async (id: string) => { |
| | | try { |
| | | const result = await defHttp.get({ |
| | | url: '/contract/contract/querySemanticWordByMainId', |
| | | params: { id }, |
| | | }); |
| | | console.log('语义词数据:', result); |
| | | // 这里可以根据返回的数据结构处理语义词 |
| | | if (result && Array.isArray(result)) { |
| | | // 将语义词列表保存到响应式变量中 |
| | | semanticWords.value = result; |
| | | } |
| | | } catch (error) { |
| | | console.error('加载语义词失败:', error); |
| | | } |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | loadCustomerData(); |
| | | }); |
| | | |
| | | // 工具方法:获取文件名(去掉 temp/) |
| | | const getFileName = (file: any) => { |
| | | const name = file.name || ''; |
| | | if (name.startsWith('temp/')) { |
| | | return name.substring(5); |
| | | } |
| | | return name; |
| | | }; |
| | | |
| | | // 文件下载功能 |
| | | const handleDownload = (file: any) => { |
| | | if (!file.url) { |
| | | message.error('文件链接不存在'); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | // 创建一个隐藏的a标签进行下载 |
| | | const link = document.createElement('a'); |
| | | link.href = getFileAccessHttpUrl(file.url); |
| | | link.download = getFileName(file); |
| | | link.target = '_blank'; |
| | | link.style.display = 'none'; |
| | | |
| | | // 添加到DOM中 |
| | | document.body.appendChild(link); |
| | | |
| | | // 触发点击事件 |
| | | link.click(); |
| | | |
| | | // 清理DOM |
| | | document.body.removeChild(link); |
| | | } catch (error) { |
| | | console.error('文件下载失败:', error); |
| | | message.error('文件下载失败'); |
| | | } |
| | | }; |
| | | |
| | | // 返回功能 |
| | | const handleBack = () => { |
| | | router.back(); |
| | | }; |
| | | |
| | | // 格式化价格 |
| | | const formatPrice = (price: number) => { |
| | | if (!price) return '-'; |
| | | return price.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); |
| | | }; |
| | | |
| | | // 格式化签约排名 |
| | | const formatRanking = (ranking: any) => { |
| | | if (ranking === 1 || ranking === 2 || ranking === 3) { |
| | | return ranking.toString(); |
| | | } else if (ranking === '保展现不保排名') { |
| | | return '保展现不保排名'; |
| | | } |
| | | return '-'; |
| | | }; |
| | | |
| | | return { |
| | | formData, |
| | | contractFiles, |
| | | attachmentFiles, |
| | | semanticWords, |
| | | handleDownload, |
| | | handleBack, |
| | | getFileName, |
| | | formatPrice, |
| | | formatRanking, |
| | | }; |
| | | }, |
| | | }); |
| | | </script> |
| | | <style lang="less" scoped> |
| | | .desc-wrap { |
| | | padding: 16px; |
| | | background-color: @component-background; |
| | | } |
| | | |
| | | .action-buttons { |
| | | position: fixed; |
| | | right: 24px; |
| | | bottom: 24px; |
| | | display: flex; |
| | | gap: 12px; |
| | | z-index: 1000; |
| | | |
| | | .back-btn { |
| | | min-width: 80px; |
| | | height: 40px; |
| | | border-radius: 6px; |
| | | font-weight: 500; |
| | | background-color: #f5f5f5; |
| | | border-color: #d9d9d9; |
| | | color: #666; |
| | | |
| | | &:hover { |
| | | background-color: #e6f7ff; |
| | | border-color: #40a9ff; |
| | | color: #40a9ff; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 文件下载链接样式 |
| | | a { |
| | | color: #1890ff; |
| | | text-decoration: none; |
| | | cursor: pointer; |
| | | transition: color 0.3s; |
| | | |
| | | &:hover { |
| | | color: #40a9ff; |
| | | text-decoration: underline; |
| | | } |
| | | |
| | | &:active { |
| | | color: #096dd9; |
| | | } |
| | | } |
| | | </style> |