| | |
| | | <div class="default-main"> |
| | | <!-- 订单信息 + 申请人信息 + 交易内容(合并为同一卡片) --> |
| | | <el-card shadow="never"> |
| | | <el-descriptions |
| | | :column="2" |
| | | border |
| | | class="mt10 order-desc fixed-label" |
| | | label-width="180px" |
| | | :label-style="labelStyle" |
| | | :content-style="contentStyle" |
| | | > |
| | | <el-descriptions-item :span="2" class="section-header"> |
| | | <template #label> |
| | | <el-icon class="section-icon"><Document /></el-icon> |
| | | <span>订单信息</span> |
| | | </template> |
| | | <template #default></template> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="订单编号">{{ detail.orderNo }}</el-descriptions-item> |
| | | <el-descriptions-item label="交易资源类型">{{ detail.resourceTypeName }}</el-descriptions-item> |
| | | <el-descriptions-item label="申请时间">{{ detail.applyTime }}</el-descriptions-item> |
| | | <el-descriptions-item label="交易状态"> |
| | | <el-tag :type="getStatusType(detail.status)" size="small">{{ detail.statusName }}</el-tag> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | |
| | | <!-- 申请人信息(与订单信息同卡片,复用分隔标题样式) --> |
| | | <el-descriptions |
| | | :column="2" |
| | | border |
| | | class="mt15 order-desc fixed-label" |
| | | label-width="180px" |
| | | :label-style="labelStyle" |
| | | :content-style="contentStyle" |
| | | > |
| | | <el-descriptions-item :span="2" class="section-header"> |
| | | <template #label> |
| | | <el-icon class="section-icon"><User /></el-icon> |
| | | <span>申请人信息</span> |
| | | </template> |
| | | <template #default></template> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="姓名">{{ detail.userName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="单位">{{ detail.unitName || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="部门">{{ detail.userDept || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="用户名">{{ detail.userAccount || '-' }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | <!-- 订单信息 - 使用自定义表格布局 --> |
| | | <div class="order-info-section"> |
| | | <div class="section-header"> |
| | | <el-icon class="section-icon"><Document /></el-icon> |
| | | <span>订单信息</span> |
| | | </div> |
| | | <div class="order-info-grid"> |
| | | <div class="order-info-item"> |
| | | <div class="order-label">订单编号</div> |
| | | <div class="order-content">{{ detail.orderNo }}</div> |
| | | </div> |
| | | <div class="order-info-item"> |
| | | <div class="order-label">交易资源类型</div> |
| | | <div class="order-content">{{ detail.resourceTypeName }}</div> |
| | | </div> |
| | | <div class="order-info-item"> |
| | | <div class="order-label">申请时间</div> |
| | | <div class="order-content">{{ detail.applyTime }}</div> |
| | | </div> |
| | | <div class="order-info-item"> |
| | | <div class="order-label">交易状态</div> |
| | | <div class="order-content"> |
| | | <el-tag :type="getStatusType(detail.status)" size="small">{{ detail.statusName }}</el-tag> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 交易内容(紧随申请人信息,同卡片,复用分隔标题样式) --> |
| | | <el-descriptions |
| | | :column="2" |
| | | border |
| | | class="mt15 order-desc fixed-label" |
| | | label-width="180px" |
| | | :label-style="labelStyle" |
| | | :content-style="contentStyle" |
| | | > |
| | | <el-descriptions-item :span="2" class="section-header"> |
| | | <template #label> |
| | | <el-icon class="section-icon"><Goods /></el-icon> |
| | | <span>交易内容</span> |
| | | </template> |
| | | <template #default></template> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="产品名称"> |
| | | <el-link type="primary" :underline="false">{{ detail.productName }}</el-link> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="提供者">{{ detail.supplier }}</el-descriptions-item> |
| | | <el-descriptions-item label="行业领域">{{ detail.industry }}</el-descriptions-item> |
| | | <el-descriptions-item label="单位工程">{{ detail.projectUnit }}</el-descriptions-item> |
| | | <el-descriptions-item label="产品类型">{{ detail.productType || '-' }}</el-descriptions-item> |
| | | <el-descriptions-item label="产品简介"> |
| | | <div class="desc-wrap">{{ detail.productDesc }}</div> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | |
| | | <!-- 申请人信息 - 使用自定义表格布局 --> |
| | | <div class="applicant-info-section"> |
| | | <div class="section-header"> |
| | | <el-icon class="section-icon"><User /></el-icon> |
| | | <span>申请人信息</span> |
| | | </div> |
| | | <div class="applicant-info-grid"> |
| | | <div class="applicant-info-item"> |
| | | <div class="applicant-label">姓名</div> |
| | | <div class="applicant-content">{{ detail.userName || '-' }}</div> |
| | | </div> |
| | | <div class="applicant-info-item"> |
| | | <div class="applicant-label">单位</div> |
| | | <div class="applicant-content">{{ detail.unitName || '-' }}</div> |
| | | </div> |
| | | <div class="applicant-info-item"> |
| | | <div class="applicant-label">部门</div> |
| | | <div class="applicant-content">{{ detail.userDept || '-' }}</div> |
| | | </div> |
| | | <div class="applicant-info-item"> |
| | | <div class="applicant-label">用户名</div> |
| | | <div class="applicant-content">{{ detail.userAccount || '-' }}</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 交易内容 - 使用自定义表格布局 --> |
| | | <div class="transaction-content-section"> |
| | | <div class="section-header"> |
| | | <el-icon class="section-icon"><Goods /></el-icon> |
| | | <span>交易内容</span> |
| | | </div> |
| | | <div class="transaction-content-grid"> |
| | | <div class="transaction-content-item"> |
| | | <div class="transaction-label">产品名称</div> |
| | | <div class="transaction-content"> |
| | | <el-link type="primary" :underline="false">{{ detail.productName }}</el-link> |
| | | </div> |
| | | </div> |
| | | <div class="transaction-content-item"> |
| | | <div class="transaction-label">提供者</div> |
| | | <div class="transaction-content">{{ detail.supplier }}</div> |
| | | </div> |
| | | <div class="transaction-content-item"> |
| | | <div class="transaction-label">行业领域</div> |
| | | <div class="transaction-content">{{ detail.industry }}</div> |
| | | </div> |
| | | <div class="transaction-content-item"> |
| | | <div class="transaction-label">单位工程</div> |
| | | <div class="transaction-content"> |
| | | <el-tooltip effect="dark" :content="detail.projectUnit || '-'" placement="top" :disabled="!(detail.projectUnit && String(detail.projectUnit).trim())" popper-class="tooltip-wrap"> |
| | | <div class="ellipsis-1">{{ detail.projectUnit || '-' }}</div> |
| | | </el-tooltip> |
| | | </div> |
| | | </div> |
| | | <div class="transaction-content-item"> |
| | | <div class="transaction-label">产品类型</div> |
| | | <div class="transaction-content">{{ detail.productType || '-' }}</div> |
| | | </div> |
| | | <div class="transaction-content-item"> |
| | | <div class="transaction-label">产品简介</div> |
| | | <div class="transaction-content"> |
| | | <el-tooltip effect="dark" :content="detail.productDesc || '-'" placement="top" :disabled="!(detail.productDesc && String(detail.productDesc).trim())" popper-class="tooltip-wrap" trigger="click"> |
| | | <div class="desc-wrap ellipsis-3">{{ detail.productDesc || '-' }}</div> |
| | | </el-tooltip> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 订单详情(移动到交易内容下面,同一卡片内) --> |
| | | <div ref="orderTableWrapRef"> |
| | | <el-table |
| | |
| | | <!-- 审批追踪 --> |
| | | <el-card class="mt15" shadow="never"> |
| | | <div class="title">审批追踪</div> |
| | | |
| | | |
| | | <!-- 标签页 --> |
| | | <!-- <el-tabs v-model="activeTab" class="approval-tabs"> |
| | | <el-tab-pane label="审批记录" name="records"> |
| | |
| | | </el-table> |
| | | </el-tab-pane> |
| | | </el-tabs> --> |
| | | |
| | | |
| | | <!-- 外部系统审批轨迹 iframe --> |
| | | <div class="iframe-wrap" v-if="workflowIframeUrl"> |
| | | <iframe :src="workflowIframeUrl" class="workflow-iframe" referrerpolicy="no-referrer"></iframe> |
| | | </div> |
| | | |
| | | |
| | | </el-card> |
| | | |
| | | <!-- 交易评价(当已评价时显示) --> |
| | | <el-card class="mt15" shadow="never" v-if="showEvaluation"> |
| | | <div class="title">交易评价</div> |
| | | <div class="evaluation-content"> |
| | | <div class="evaluation-form"> |
| | | <div class="rating-section"> |
| | | <div class="rating-items"> |
| | | <div class="rating-row"> |
| | | <div class="rating-item"> |
| | | <label class="required">综合评分:</label> |
| | | <el-rate :model-value="evaluation.overallRating" :max="5" disabled :colors="['#99A9BF', '#F7BA2A', '#FF9900']" /> |
| | | </div> |
| | | <div class="rating-item"> |
| | | <label class="required">服务评分:</label> |
| | | <el-rate :model-value="evaluation.serviceRating" :max="5" disabled :colors="['#99A9BF', '#F7BA2A', '#FF9900']" /> |
| | | </div> |
| | | </div> |
| | | <div class="rating-row"> |
| | | <div class="rating-item"> |
| | | <label class="required">质量评分:</label> |
| | | <el-rate :model-value="evaluation.qualityRating" :max="5" disabled :colors="['#99A9BF', '#F7BA2A', '#FF9900']" /> |
| | | </div> |
| | | <div class="rating-item"> |
| | | <label class="required">速度评分:</label> |
| | | <el-rate :model-value="evaluation.speedRating" :max="5" disabled :colors="['#99A9BF', '#F7BA2A', '#FF9900']" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="form-item"> |
| | | <label class="required">评价内容:</label> |
| | | <div class="eval-text">{{ evaluation.content || '-' }}</div> |
| | | </div> |
| | | |
| | | <div class="form-item"> |
| | | <label>其他信息:</label> |
| | | <div class="eval-meta"> |
| | | <span>是否匿名:{{ evaluation.isAnonymous ? '是' : '否' }}</span> |
| | | <span class="split">|</span> |
| | | <span>评价时间:{{ evaluation.evaluateTime || '-' }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | <!-- 返回按钮 --> |
| | | <div class="action-buttons"> |
| | |
| | | import orderApi from '@/api/orderApi' |
| | | import createAxios from '@/utils/axios' |
| | | import productApi from '@/api/productApi' |
| | | import sysUserService from '@/api/sysUser' |
| | | import { useUserInfo } from '@/stores/modules/userInfo' |
| | | |
| | | const hostUrl = import.meta.env.VITE_AXIOS_BASE_URL |
| | | const route = useRoute() |
| | | const router = useRouter() |
| | | const detail = reactive<any>({ items: [], records: [], nodes: [] }) |
| | | const evaluation = reactive<any>({ |
| | | content: '', |
| | | overallRating: 0, |
| | | serviceRating: 0, |
| | | qualityRating: 0, |
| | | speedRating: 0, |
| | | isAnonymous: false, |
| | | evaluateTime: '' |
| | | }) |
| | | const orderTableWrapRef = ref<HTMLElement | null>(null) |
| | | const activeTab = ref('records') |
| | | const userStore = useUserInfo() |
| | |
| | | }) |
| | | const labelStyle = { width: '180px', maxWidth: '180px' } |
| | | const contentStyle = { width: 'calc(50% - 180px)' } |
| | | |
| | | |
| | | // 文件相关 |
| | | const fileList = ref<any[]>([]) |
| | |
| | | const statusOrder = ['WAIT_UPLOAD', 'WAIT_AUTHORIZE', 'WAIT_CONFIRM', 'COMPLETED', 'EVALUATED'] |
| | | const currentStatus = statusServerToUi[statusName] |
| | | return currentStatus && statusOrder.indexOf(currentStatus) >= statusOrder.indexOf('WAIT_CONFIRM') |
| | | }) |
| | | |
| | | // 是否显示评价卡片(已评价时显示) |
| | | const showEvaluation = computed(() => { |
| | | return (detail.isEvaluate === '已评价') |
| | | }) |
| | | |
| | | // 计算表格数据,添加汇总行 |
| | |
| | | onMounted(async () => { |
| | | const orderId = String(route.params.id || '') |
| | | if (!orderId) return |
| | | |
| | | |
| | | try { |
| | | // 并行获取订单详情和协议类型检查 |
| | | const [orderRes, agreementRes] = await Promise.all([ |
| | | orderApi.getOrderDetail(orderId), |
| | | orderApi.checkAgreementPriceType(orderId) |
| | | ]) |
| | | |
| | | |
| | | const res = orderRes as any |
| | | const data = res?.data || {} |
| | | |
| | | |
| | | // 设置是否为协议订单 |
| | | const agreementResult = agreementRes as any |
| | | isAgreementOrder.value = agreementResult?.data === true |
| | |
| | | } catch (e) { |
| | | // 忽略产品详情失败,不阻塞订单详情 |
| | | } |
| | | |
| | | |
| | | // 获取用户信息 |
| | | try { |
| | | const userRes: any = await sysUserService.getUserdetail({ userId: data.userId }) |
| | | if (userRes?.code === 200 && userRes.data) { |
| | | // 用产品详情补全头信息 |
| | | data.unitName = userRes.data.unitName || data.unitName |
| | | data.userName = userRes.data.name || data.userName |
| | | data.userDept = userRes.data.departmentName || data.userDept |
| | | data.userPhone = userRes.data.phone || data.userPhone |
| | | data.userAccount = userRes.data.username || data.userAccount |
| | | } |
| | | }catch (e){ |
| | | |
| | | } |
| | | |
| | | // 映射订单详情头部信息 |
| | | const head = { |
| | |
| | | projectUnit: data.projectUnit || '-', |
| | | productType: data.productType || '-', |
| | | productDesc: data.productDesc || '-', |
| | | isEvaluate: data.isEvaluate || '未评价' |
| | | } |
| | | |
| | | // 明细项映射 |
| | |
| | | workflowId: data.workflowId || data.processinstId || '' |
| | | }) |
| | | |
| | | // 映射交易评价信息(如果存在) |
| | | if (data.evaluation) { |
| | | evaluation.content = data.evaluation.content || '' |
| | | evaluation.overallRating = Number(data.evaluation.rating || data.evaluation.overallRating || 0) |
| | | evaluation.serviceRating = Number(data.evaluation.serviceRating || 0) |
| | | evaluation.qualityRating = Number(data.evaluation.qualityRating || 0) |
| | | // 后端为 deliveryRating,对齐前端 speedRating 命名 |
| | | evaluation.speedRating = Number(data.evaluation.deliveryRating || data.evaluation.speedRating || 0) |
| | | evaluation.isAnonymous = Boolean(data.evaluation.isAnonymous) |
| | | evaluation.evaluateTime = formatDateTime((data.evaluation.replyTime || data.evaluation.createdAt || data.evaluation.createTime) as any) |
| | | } |
| | | |
| | | // 初始化交易信息备注数据 |
| | | remarkItems.value = (detail.items || []).map((item: any, index: number) => { |
| | | // 计算授权结束时间 |
| | |
| | | endDateObj.setFullYear(endDateObj.getFullYear() + item.period) |
| | | endDate = endDateObj.toISOString().split('T')[0] // 格式化为 YYYY-MM-DD |
| | | } |
| | | |
| | | return { |
| | | |
| | | return { |
| | | name: item.name, |
| | | start: data.applyTime ? data.applyTime.split('T')[0] : '', // 使用订单申请时间 |
| | | end: endDate, |
| | | end: endDate, |
| | | forever: item.period === 0, // 期限为0时设置为永久 |
| | | remark: item.remarks || '' // 使用套件信息中的remarks字段 |
| | | } |
| | |
| | | } |
| | | |
| | | // 表头文字居中,但第一行的"详情"文字靠左对齐 |
| | | const headerCenterStyle: CSSProperties = { |
| | | const headerCenterStyle: CSSProperties = { |
| | | textAlign: 'center', |
| | | fontSize: '14px', |
| | | background: '#f3f6fb' |
| | |
| | | const bodyCellStyle: CSSProperties = { fontSize: '12px' } |
| | | |
| | | // 审批追踪表格样式 |
| | | const recordTableHeaderStyle: CSSProperties = { |
| | | const recordTableHeaderStyle: CSSProperties = { |
| | | textAlign: 'center', |
| | | fontSize: '14px', |
| | | background: '#f3f6fb' |
| | |
| | | const recordTableCellStyle: CSSProperties = { fontSize: '12px' } |
| | | |
| | | // 文件列表表格表头文字居中,但第一列的"交易文件"文字靠左对齐 |
| | | const fileTableHeaderStyle: CSSProperties = { |
| | | const fileTableHeaderStyle: CSSProperties = { |
| | | textAlign: 'center', |
| | | fontSize: '14px', |
| | | background: '#f3f6fb' |
| | |
| | | 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx |
| | | 'application/vnd.openxmlformats-officedocument.presentationml.presentation', // .pptx |
| | | ] |
| | | |
| | | |
| | | // 如果MIME类型匹配,直接返回true |
| | | if (previewableTypes.includes(file.type || '')) { |
| | | return true |
| | | } |
| | | |
| | | |
| | | // 如果MIME类型为空或不匹配,根据文件扩展名判断 |
| | | const fileName = file.name || '' |
| | | const fileExtension = fileName.toLowerCase().split('.').pop() |
| | | |
| | | |
| | | const previewableExtensions = [ |
| | | 'jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', |
| | | 'txt', 'html', 'htm', 'css', 'js', |
| | | 'pdf', |
| | | 'docx', 'xlsx', 'pptx' |
| | | ] |
| | | |
| | | |
| | | return previewableExtensions.includes(fileExtension) |
| | | } |
| | | |
| | |
| | | ElMessage.warning('文件链接不存在') |
| | | return |
| | | } |
| | | |
| | | |
| | | // 获取文件扩展名 |
| | | const fileName = file.name || '' |
| | | const fileExtension = fileName.toLowerCase().split('.').pop() |
| | | |
| | | |
| | | let previewUrl = file.url |
| | | |
| | | |
| | | // 如果文件存储在MinIO,优先使用预览URL |
| | | if (file.url.includes('order-attachments')) { |
| | | try { |
| | |
| | | fileName: file.url |
| | | } |
| | | }) |
| | | |
| | | |
| | | console.log('预览URL响应:', previewResponse) |
| | | |
| | | |
| | | // 检查响应格式 |
| | | const responseData = previewResponse as any |
| | | if (responseData && responseData.code === 200 && responseData.data) { |
| | | previewUrl = responseData.data |
| | | previewUrl = responseData.data.replaceAll("http://192.168.20.52:9000", import.meta.env.VITE_FILE_PREVIEW_URL) |
| | | // previewUrl = responseData.data |
| | | console.log('使用预览URL:', previewUrl) |
| | | } else { |
| | | console.log('预览URL获取失败,使用下载方式') |
| | |
| | | originalName: file.name |
| | | } |
| | | }) |
| | | |
| | | |
| | | // 创建预览URL |
| | | const blob = new Blob([response as any]) |
| | | previewUrl = window.URL.createObjectURL(blob) |
| | |
| | | return |
| | | } |
| | | } |
| | | |
| | | |
| | | // 图片文件直接在新窗口打开 |
| | | if ((file.type && file.type.startsWith('image/')) || |
| | | if ((file.type && file.type.startsWith('image/')) || |
| | | ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(fileExtension)) { |
| | | console.log('预览图片文件:', previewUrl) |
| | | window.open(previewUrl, '_blank') |
| | | return |
| | | } |
| | | |
| | | |
| | | // PDF文件在新窗口打开 |
| | | if (file.type === 'application/pdf' || fileExtension === 'pdf') { |
| | | console.log('预览PDF文件:', previewUrl) |
| | | window.open(previewUrl, '_blank') |
| | | return |
| | | } |
| | | |
| | | |
| | | // 文本文件在新窗口打开 |
| | | if ((file.type && file.type.startsWith('text/')) || |
| | | if ((file.type && file.type.startsWith('text/')) || |
| | | ['txt', 'html', 'htm', 'css', 'js'].includes(fileExtension)) { |
| | | console.log('预览文本文件:', previewUrl) |
| | | window.open(previewUrl, '_blank') |
| | | return |
| | | } |
| | | |
| | | |
| | | // Office文档和其他文件类型,尝试在新窗口打开 |
| | | try { |
| | | console.log('预览其他文件:', previewUrl) |
| | |
| | | ElMessage.warning('文件链接不存在') |
| | | return |
| | | } |
| | | |
| | | |
| | | console.log('开始下载文件:', file.name, 'URL:', file.url) |
| | | |
| | | |
| | | try { |
| | | // 如果文件存储在MinIO,使用后端直接下载API |
| | | if (file.url.includes('order-attachments')) { |
| | | console.log('使用MinIO下载API') |
| | | |
| | | |
| | | // 使用axios通过代理访问后端API |
| | | const response = await createAxios({ |
| | | url: `/admin/file/download`, |
| | |
| | | originalName: file.name |
| | | } |
| | | }) |
| | | |
| | | |
| | | console.log('下载响应:', response) |
| | | |
| | | |
| | | // 创建下载链接 |
| | | const blob = new Blob([response as any]) |
| | | const downloadUrl = window.URL.createObjectURL(blob) |
| | | |
| | | |
| | | console.log('创建下载链接:', downloadUrl) |
| | | |
| | | |
| | | const link = document.createElement('a') |
| | | link.href = downloadUrl |
| | | link.download = file.name || 'download' |
| | | link.target = '_blank' |
| | | link.rel = 'noopener noreferrer' |
| | | |
| | | |
| | | document.body.appendChild(link) |
| | | link.click() |
| | | document.body.removeChild(link) |
| | | |
| | | |
| | | // 清理URL对象 |
| | | window.URL.revokeObjectURL(downloadUrl) |
| | | |
| | | |
| | | ElMessage.success('文件下载成功') |
| | | } else { |
| | | console.log('使用直接URL下载') |
| | |
| | | link.download = file.name || 'download' |
| | | link.target = '_blank' |
| | | link.rel = 'noopener noreferrer' |
| | | |
| | | |
| | | document.body.appendChild(link) |
| | | link.click() |
| | | document.body.removeChild(link) |
| | | |
| | | |
| | | ElMessage.success('开始下载文件') |
| | | } |
| | | } catch (error) { |
| | |
| | | width: calc(50% - 180px) !important; |
| | | } |
| | | |
| | | /* 订单信息自定义布局样式 */ |
| | | .order-info-section { |
| | | border: 1px solid #e4e7ed; |
| | | border-radius: 4px; |
| | | margin-top: 10px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .order-info-section .section-header { |
| | | background: #f3f6fb; |
| | | padding: 12px 16px; |
| | | border-bottom: 1px solid #e4e7ed; |
| | | font-weight: 600; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .order-info-section .section-icon { |
| | | margin-right: 6px; |
| | | color: #409eff; |
| | | } |
| | | |
| | | .order-info-grid { |
| | | display: grid; |
| | | grid-template-columns: 15% 30% 15% 40%; |
| | | width: 100%; |
| | | } |
| | | |
| | | .order-info-item { |
| | | display: contents; |
| | | } |
| | | |
| | | .order-info-item .order-label { |
| | | padding: 12px 16px; |
| | | background: #fafafa; |
| | | border: 1px solid #e4e7ed; |
| | | font-size: 14px; |
| | | color: #606266; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .order-info-item .order-content { |
| | | padding: 12px 16px; |
| | | border: 1px solid #e4e7ed; |
| | | font-size: 14px; |
| | | color: #303133; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | /* 申请人信息自定义布局样式 */ |
| | | .applicant-info-section { |
| | | border: 1px solid #e4e7ed; |
| | | border-radius: 4px; |
| | | margin-top: 15px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .applicant-info-section .section-header { |
| | | background: #f3f6fb; |
| | | padding: 12px 16px; |
| | | border-bottom: 1px solid #e4e7ed; |
| | | font-weight: 600; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .applicant-info-section .section-icon { |
| | | margin-right: 6px; |
| | | color: #409eff; |
| | | } |
| | | |
| | | .applicant-info-grid { |
| | | display: grid; |
| | | grid-template-columns: 15% 30% 15% 40%; |
| | | width: 100%; |
| | | } |
| | | |
| | | .applicant-info-item { |
| | | display: contents; |
| | | } |
| | | |
| | | .applicant-info-item .applicant-label { |
| | | padding: 12px 16px; |
| | | background: #fafafa; |
| | | border: 1px solid #e4e7ed; |
| | | font-size: 14px; |
| | | color: #606266; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .applicant-info-item .applicant-content { |
| | | padding: 12px 16px; |
| | | border: 1px solid #e4e7ed; |
| | | font-size: 14px; |
| | | color: #303133; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | /* 交易内容自定义布局样式 */ |
| | | .transaction-content-section { |
| | | border: 1px solid #e4e7ed; |
| | | border-radius: 4px; |
| | | margin-top: 15px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .transaction-content-section .section-header { |
| | | background: #f3f6fb; |
| | | padding: 12px 16px; |
| | | border-bottom: 1px solid #e4e7ed; |
| | | font-weight: 600; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .transaction-content-section .section-icon { |
| | | margin-right: 6px; |
| | | color: #409eff; |
| | | } |
| | | |
| | | .transaction-content-grid { |
| | | display: grid; |
| | | grid-template-columns: 15% 30% 15% 40%; |
| | | width: 100%; |
| | | } |
| | | |
| | | .transaction-content-item { |
| | | display: contents; |
| | | } |
| | | |
| | | .transaction-content-item .transaction-label { |
| | | padding: 12px 16px; |
| | | background: #fafafa; |
| | | border: 1px solid #e4e7ed; |
| | | font-size: 14px; |
| | | color: #606266; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .transaction-content-item .transaction-content { |
| | | padding: 12px 16px; |
| | | border: 1px solid #e4e7ed; |
| | | font-size: 14px; |
| | | color: #303133; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | |
| | | .desc-wrap { |
| | | white-space: pre-wrap; |
| | | line-height: 22px; |
| | | } |
| | | |
| | | /* 单行省略(用于“单位工程”) */ |
| | | .ellipsis-1 { |
| | | max-height: 22px; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | /* 多行省略(用于“产品简介”,固定为3行,可按需调整) */ |
| | | .ellipsis-3 { |
| | | display: -webkit-box; |
| | | line-clamp: 3; |
| | | -webkit-line-clamp: 3; |
| | | -webkit-box-orient: vertical; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | |
| | | |
| | | /* 审批追踪标签页样式 */ |
| | | .approval-tabs { |
| | |
| | | gap: 8px; |
| | | align-items: center; |
| | | justify-content: center; |
| | | |
| | | |
| | | .preview-btn { |
| | | color: #409eff; |
| | | &:hover { |
| | |
| | | cursor: not-allowed; |
| | | } |
| | | } |
| | | |
| | | |
| | | .download-btn { |
| | | color: #67c23a; |
| | | &:hover { |