@@ -16,12 +16,13 @@
|
||||
<!-- 1. 会议基本信息 -->
|
||||
<div class="card">
|
||||
<div class="section-title">会议基本信息</div>
|
||||
|
||||
<div class="info-grid" v-loading="loading">
|
||||
<div class="info-row"><span class="info-label">项目编号:</span><span class="info-value code">{{ row.projectNo || '-' }}</span></div>
|
||||
<div class="info-row"><span class="info-label">会议名称:</span><span class="info-value">{{ row.meetingName || '-' }}</span></div>
|
||||
<div class="info-row"><span class="info-label">项目名称:</span><span class="info-value">{{ row.projectName || '-' }}</span></div>
|
||||
<div class="info-row"><span class="info-label">期数:</span><span class="info-value">{{ periodDisplay }}</span></div>
|
||||
<div class="info-row"><span class="info-label">总场次/总期数:</span><span class="info-value">{{ row.totalPeriods ?? '-' }}</span></div>
|
||||
<div class="info-row"><span class="info-label">总场次/总期数:</span><span class="info-value">{{ displayTotalPeriods ?? '-' }}</span></div>
|
||||
<div class="info-row"><span class="info-label">会议开始时间:</span><span class="info-value">{{ fmtDateTime(row.startTime) }}</span></div>
|
||||
<div class="info-row"><span class="info-label">支持单位:</span><span class="info-value">{{ row.orgName || '-' }}</span></div>
|
||||
<div class="info-row"><span class="info-label">会议结束时间:</span><span class="info-value">{{ fmtDateTime(row.endTime) }}</span></div>
|
||||
@@ -81,7 +82,11 @@
|
||||
<el-table :data="attendeeRows" v-loading="attendeeLoading" border size="small" style="width: 100%;" show-summary :summary-method="attendeeSummary" @selection-change="onAttendeeSelectionChange" class="attendee-table">
|
||||
<el-table-column v-if="!isSponsor && !isReadonly" type="selection" width="42" />
|
||||
<el-table-column type="index" label="序号" width="50" align="center" />
|
||||
<el-table-column prop="name" label="医生" min-width="90" />
|
||||
<el-table-column label="医生" min-width="90">
|
||||
<template #default="{ row }">
|
||||
<span :style="(row.hasIntent === 1 || row.hasIntent === '1') ? {} : { color: '#f56c6c' }">{{ row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="联系电话" width="120">
|
||||
<template #default="{ row }">{{ isSponsor ? maskPhone(row.phone) : row.phone }}</template>
|
||||
</el-table-column>
|
||||
@@ -125,10 +130,10 @@
|
||||
<span v-else class="text-muted">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="现场照片" min-width="140" show-overflow-tooltip>
|
||||
<el-table-column label="现场照片" min-width="90" align="center">
|
||||
<template #default="{ row }">
|
||||
<span v-if="!row.onSitePhotos" class="text-muted">-</span>
|
||||
<span v-else>{{ row.onSitePhotos.split(',').length }} 张</span>
|
||||
<el-link :underline="false" v-if="onSitePhotoFiles(row).length" type="primary" @click="openOnSitePhotos(row)">查看</el-link>
|
||||
<span v-else class="text-muted">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="签字" width="70" align="center">
|
||||
@@ -299,71 +304,35 @@
|
||||
<div class="timeline-title">会议已执行</div>
|
||||
<div class="timeline-desc">{{ nodeDesc('PRE') }}</div>
|
||||
</div>
|
||||
<!-- 材料审核三步 (提交 → 合规 → 监察) 并入主时间轴, 两轨并列, 保留重交历史 -->
|
||||
<div :class="['timeline-item', nodeStatus('submit')]">
|
||||
<!-- 材料审核: 单条时间轴, 按轮次循环 (提交 → 合规 → 监察 → 提交 → …), 节点上标注 劳务/会务 -->
|
||||
<div v-if="!timelineEvents.length && !pendingNode" class="timeline-item pending">
|
||||
<div class="timeline-title">执行方提交材料</div>
|
||||
<div v-if="!materialTracks.length" class="timeline-desc pending-text">待执行人员提交</div>
|
||||
<div v-for="track in materialTracks" :key="track.key" class="track-block">
|
||||
<div class="track-label-row">
|
||||
<el-tag v-if="track.label" size="small" effect="plain">{{ track.label }}</el-tag>
|
||||
<span v-if="!track.cycles.length" class="pending-text">待提交</span>
|
||||
<div class="timeline-desc pending-text">待执行人员提交</div>
|
||||
</div>
|
||||
<template v-for="(ev, idx) in timelineEvents" :key="'ev' + idx">
|
||||
<div :class="['timeline-item', eventStatus(ev)]">
|
||||
<div class="timeline-title">
|
||||
{{ stepLabel(ev.step) }}
|
||||
<span v-if="trackTag(ev)" class="track-tag">{{ trackTag(ev) }}</span>
|
||||
</div>
|
||||
<div v-for="(c, i) in track.cycles" :key="i" class="timeline-meta">
|
||||
<span v-if="track.cycles.length > 1" class="cycle-no">第{{ i + 1 }}次</span>
|
||||
<span>{{ c.submit.auditor }}</span>
|
||||
<div v-for="(e, i) in ev.entries" :key="i" class="timeline-meta">
|
||||
<span v-if="ev.entries.length > 1" class="track-mini">{{ e.label }}</span>
|
||||
<span>{{ e.auditor || '—' }}</span>
|
||||
<span class="dot">·</span>
|
||||
<span>{{ fmtDateTime(c.submit.auditTime) }}</span>
|
||||
<span>{{ fmtDateTime(e.auditTime) }}</span>
|
||||
<el-tag v-if="e.auditResult" size="small" :type="e.auditResult === 'REJECTED' ? 'danger' : 'success'">{{ e.auditResult === 'REJECTED' ? '拒绝' : '通过' }}</el-tag>
|
||||
</div>
|
||||
<div v-for="(e, i) in ev.entries" :key="'op' + i">
|
||||
<div v-if="e.opinion" :class="['timeline-opinion', e.auditResult === 'REJECTED' ? 'opinion-reject' : 'opinion-approve']">💬 {{ e.opinion }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="['timeline-item', nodeStatus('compliance')]">
|
||||
<div class="timeline-title">合规审核</div>
|
||||
<div v-if="!materialTracks.length" class="timeline-desc pending-text">待合规审核</div>
|
||||
<div v-for="track in materialTracks" :key="track.key" class="track-block">
|
||||
<div class="track-label-row">
|
||||
<el-tag v-if="track.label" size="small" effect="plain">{{ track.label }}</el-tag>
|
||||
<span v-if="!track.cycles.length" class="pending-text">—</span>
|
||||
</div>
|
||||
<template v-for="(c, i) in track.cycles" :key="i">
|
||||
<div class="timeline-meta">
|
||||
<span v-if="track.cycles.length > 1" class="cycle-no">第{{ i + 1 }}次</span>
|
||||
<template v-if="c.compliance">
|
||||
<span>{{ c.compliance.auditor }}</span>
|
||||
<span class="dot">·</span>
|
||||
<span>{{ fmtDateTime(c.compliance.auditTime) }}</span>
|
||||
<el-tag size="small" :type="c.compliance.auditResult === 'REJECTED' ? 'danger' : 'success'">{{ c.compliance.auditResult === 'REJECTED' ? '拒绝' : '通过' }}</el-tag>
|
||||
</template>
|
||||
<span v-else class="pending-text">待审核</span>
|
||||
</div>
|
||||
<div v-if="c.compliance?.opinion" class="timeline-opinion">💬 {{ c.compliance.opinion }}</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="['timeline-item', nodeStatus('supervision')]">
|
||||
<div class="timeline-title">监察意见</div>
|
||||
<div v-if="!materialTracks.length" class="timeline-desc pending-text">待监察审核</div>
|
||||
<div v-for="track in materialTracks" :key="track.key" class="track-block">
|
||||
<div class="track-label-row">
|
||||
<el-tag v-if="track.label" size="small" effect="plain">{{ track.label }}</el-tag>
|
||||
<span v-if="!track.cycles.length" class="pending-text">—</span>
|
||||
</div>
|
||||
<template v-for="(c, i) in track.cycles" :key="i">
|
||||
<div class="timeline-meta">
|
||||
<span v-if="track.cycles.length > 1" class="cycle-no">第{{ i + 1 }}次</span>
|
||||
<template v-if="c.compliance && c.compliance.auditResult === 'REJECTED'">
|
||||
<span class="pending-text">已退回 · 未进入监察</span>
|
||||
</template>
|
||||
<template v-else-if="c.supervision">
|
||||
<span>{{ c.supervision.auditor }}</span>
|
||||
<span class="dot">·</span>
|
||||
<span>{{ fmtDateTime(c.supervision.auditTime) }}</span>
|
||||
<el-tag size="small" :type="c.supervision.auditResult === 'REJECTED' ? 'danger' : 'success'">{{ c.supervision.auditResult === 'REJECTED' ? '拒绝' : '通过' }}</el-tag>
|
||||
</template>
|
||||
<span v-else class="pending-text">待监察审核</span>
|
||||
</div>
|
||||
<div v-if="c.supervision?.opinion" class="timeline-opinion">💬 {{ c.supervision.opinion }}</div>
|
||||
</template>
|
||||
</template>
|
||||
<div v-if="pendingNode" class="timeline-item pending">
|
||||
<div class="timeline-title">
|
||||
{{ stepLabel(pendingNode.step) }}
|
||||
<span v-if="trackTag(pendingNode)" class="track-tag">{{ trackTag(pendingNode) }}</span>
|
||||
</div>
|
||||
<div class="timeline-desc pending-text">{{ pendingDesc(pendingNode.step) }}</div>
|
||||
</div>
|
||||
<!-- 节点 3/4: 结算 / 完结 -->
|
||||
<div :class="['timeline-item', fixedNodeStatus('POST')]">
|
||||
@@ -622,9 +591,16 @@ function fmtDateTime(v) {
|
||||
if (isNaN(dt.getTime())) return v
|
||||
return `${dt.getFullYear()}-${pad(dt.getMonth() + 1)}-${pad(dt.getDate())} ${pad(dt.getHours())}:${pad(dt.getMinutes())}`
|
||||
}
|
||||
// 执行方看到的"总期数"= 分配给本执行方的场次 (assignedSessions), 而非项目总场次 (total_periods); 其他角色仍用项目总场次
|
||||
const displayTotalPeriods = computed(() => {
|
||||
if (currentRole.value === 'executor') {
|
||||
return row.value.assignedSessions != null ? row.value.assignedSessions : row.value.totalPeriods
|
||||
}
|
||||
return row.value.totalPeriods
|
||||
})
|
||||
const periodDisplay = computed(() => {
|
||||
const p = row.value.periodNo
|
||||
const t = row.value.totalPeriods
|
||||
const t = displayTotalPeriods.value
|
||||
if (p == null && t == null) return '-'
|
||||
if (p == null) return `${t}`
|
||||
if (t == null) return `${p}`
|
||||
@@ -664,6 +640,20 @@ function protocolUrl(row) {
|
||||
function idCardFiles(row) {
|
||||
return (row.idCardAttachments || '').split(',').map(s => s.trim()).filter(Boolean)
|
||||
}
|
||||
/** 现场照片 CSV "url1,url2" 拆成非空数组 */
|
||||
function onSitePhotoFiles(row) {
|
||||
return (row.onSitePhotos || '').split(',').map(s => s.trim()).filter(Boolean)
|
||||
}
|
||||
/** OSS 图片压缩参数 (对齐 PosterService.download): 缩宽 + 压质量 + 转 JPEG, 减小预览体积 */
|
||||
function ossThumb(url, width = 1200) {
|
||||
if (!url || url.includes('x-oss-process')) return url
|
||||
const sep = url.includes('?') ? '&' : '?'
|
||||
return `${url}${sep}x-oss-process=image/resize,w_${width}/quality,q_80/format,jpg`
|
||||
}
|
||||
/** 现场照片预览: 每张带 OSS 压缩参数 → Preview 组件平铺多图 */
|
||||
function openOnSitePhotos(row) {
|
||||
openPreview(onSitePhotoFiles(row).map(u => ossThumb(u)), '现场照片')
|
||||
}
|
||||
|
||||
// ===================== 材料管理 4 个 tab =====================
|
||||
const ROW_CONFIG = [
|
||||
@@ -738,27 +728,73 @@ const materialTracks = computed(() => {
|
||||
})
|
||||
|
||||
/**
|
||||
* 审核时间轴内嵌子步骤 (提交/合规/监察) 状态 — 由物理阶段 (两轨取最小) 推导.
|
||||
* - submit: 越过 NOT_STARTED/RUNNING (已提交过) 即 done
|
||||
* - compliance: RECTIFYING=rejected, AWAITING_COMPLIANCE=pending(当前), 之后=done
|
||||
* - supervision: RECTIFYING=rejected, AWAITING_SUPERVISION=pending(当前), 之后=done
|
||||
* 单条材料审核时间轴: 把两轨(劳务/会务)的 cycle 事件拍平成一条按时间升序的节点流.
|
||||
* 节点 = { step: submit|compliance|supervision, entries: [{label, roundNo, auditor, auditTime, auditResult, opinion}] }
|
||||
* - 同一步骤 + 同一 timestamp 的两轨事件合并成一个节点 (提交全部/审核全部会同时写两轨日志)
|
||||
* - entries.length>1 时, 每行前置 track-mini 标注是哪一轨
|
||||
*/
|
||||
function nodeStatus(slot) {
|
||||
const s = derivePhysicalStage(row.value)
|
||||
if (slot === 'submit') return (s !== 'NOT_STARTED' && s !== 'RUNNING') ? 'done' : 'pending'
|
||||
if (slot === 'compliance') {
|
||||
if (s === 'RECTIFYING') return 'rejected'
|
||||
if (s === 'AWAITING_COMPLIANCE') return 'pending'
|
||||
if (['AWAITING_SUPERVISION', 'AWAITING_SETTLEMENT', 'SETTLED', 'FINISHED'].includes(s)) return 'done'
|
||||
return 'pending'
|
||||
const timelineEvents = computed(() => {
|
||||
const raw = []
|
||||
for (const track of materialTracks.value) {
|
||||
const label = track.label
|
||||
track.cycles.forEach((c, i) => {
|
||||
const roundNo = i + 1
|
||||
if (c.submit) raw.push({ step: 'submit', time: c.submit.auditTime, entry: { label, roundNo, auditor: c.submit.auditor, auditTime: c.submit.auditTime } })
|
||||
if (c.compliance) raw.push({ step: 'compliance', time: c.compliance.auditTime, entry: { label, roundNo, auditor: c.compliance.auditor, auditTime: c.compliance.auditTime, auditResult: c.compliance.auditResult, opinion: c.compliance.opinion } })
|
||||
if (c.supervision) raw.push({ step: 'supervision', time: c.supervision.auditTime, entry: { label, roundNo, auditor: c.supervision.auditor, auditTime: c.supervision.auditTime, auditResult: c.supervision.auditResult, opinion: c.supervision.opinion } })
|
||||
})
|
||||
}
|
||||
if (slot === 'supervision') {
|
||||
if (s === 'RECTIFYING') return 'rejected'
|
||||
if (s === 'AWAITING_SUPERVISION') return 'pending'
|
||||
if (['AWAITING_SETTLEMENT', 'SETTLED', 'FINISHED'].includes(s)) return 'done'
|
||||
return 'pending'
|
||||
raw.sort((a, b) => new Date(a.time).getTime() - new Date(b.time).getTime())
|
||||
const nodes = []
|
||||
for (const ev of raw) {
|
||||
const last = nodes[nodes.length - 1]
|
||||
if (last && last.step === ev.step && last.time === ev.time) { last.entries.push(ev.entry); continue }
|
||||
nodes.push({ step: ev.step, time: ev.time, entries: [ev.entry] })
|
||||
}
|
||||
return 'pending'
|
||||
return nodes
|
||||
})
|
||||
|
||||
/** 当前"待办"节点 (时间轴末尾的灰色占位): 依各轨状态推导下一步该谁动. */
|
||||
const pendingNode = computed(() => {
|
||||
if (!executed.value || isOne(row.value.isSettled) || isOne(row.value.isFinished)) return null
|
||||
const c0 = []; if (laborC0.value) c0.push('劳务'); if (serviceC0.value) c0.push('会务')
|
||||
if (c0.length) return { step: 'compliance', entries: c0.map(l => ({ label: l })) }
|
||||
const c1 = []; if (laborC1.value) c1.push('劳务'); if (serviceC1.value) c1.push('会务')
|
||||
if (c1.length) return { step: 'supervision', entries: c1.map(l => ({ label: l })) }
|
||||
const rej = []
|
||||
if (row.value.laborAuditStage === 'REJECTED') rej.push('劳务')
|
||||
if (row.value.serviceAuditStage === 'REJECTED') rej.push('会务')
|
||||
if (rej.length) return { step: 'submit', entries: rej.map(l => ({ label: l })) }
|
||||
return null
|
||||
})
|
||||
|
||||
function stepLabel(step) {
|
||||
if (step === 'submit') return '执行方提交材料'
|
||||
if (step === 'compliance') return '合规审核'
|
||||
return '监察意见'
|
||||
}
|
||||
/** 节点右侧轨标注: 提交节点带轮次 (劳务·第1次), 审核节点只标轨 (劳务·会务). */
|
||||
function trackTag(node) {
|
||||
const labels = node.entries.map(e => e.label).filter(Boolean)
|
||||
if (!labels.length) return ''
|
||||
if (node.step === 'submit') {
|
||||
const withRound = node.entries.filter(e => e.roundNo != null)
|
||||
if (withRound.length) {
|
||||
if (withRound.length === node.entries.length && withRound.every(e => e.roundNo === withRound[0].roundNo)) {
|
||||
return `${labels.join('·')} · 第${withRound[0].roundNo}次`
|
||||
}
|
||||
return node.entries.map(e => (e.roundNo != null ? `${e.label}·第${e.roundNo}次` : e.label)).filter(Boolean).join(' · ')
|
||||
}
|
||||
}
|
||||
return labels.join('·')
|
||||
}
|
||||
function eventStatus(ev) {
|
||||
return ev.entries.some(e => e.auditResult === 'REJECTED') ? 'rejected' : 'done'
|
||||
}
|
||||
function pendingDesc(step) {
|
||||
if (step === 'submit') return '待重新提交'
|
||||
if (step === 'compliance') return '待合规审核'
|
||||
return '待监察审核'
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -793,9 +829,9 @@ const isAssignedSupervisor = computed(() => isSponsor.value)
|
||||
const isSponsorMain = computed(() => currentRole.value === 'sponsor' && userStore.isMain)
|
||||
const executed = computed(() => isOne(row.value.isExecuted))
|
||||
const frozen = computed(() => isOne(row.value.isFrozen))
|
||||
/** 单轨是否处于「可提交/可编辑」态 (未提交 或 被驳回) */
|
||||
const laborEditable = computed(() => ['NOT_SUBMITTED', 'REJECTED'].includes(row.value.laborAuditStage))
|
||||
const serviceEditable = computed(() => ['NOT_SUBMITTED', 'REJECTED'].includes(row.value.serviceAuditStage))
|
||||
/** 单轨是否处于「可提交/可编辑」态: 执行方仅未提交/被驳回可编辑; 合规(manager)/管理员 永远可编辑 */
|
||||
const laborEditable = computed(() => isManager.value || isAdmin.value || ['NOT_SUBMITTED', 'REJECTED'].includes(row.value.laborAuditStage))
|
||||
const serviceEditable = computed(() => isManager.value || isAdmin.value || ['NOT_SUBMITTED', 'REJECTED'].includes(row.value.serviceAuditStage))
|
||||
/** 单轨状态判定: C0=已提交待合规审 / C1=已提交待支持方审 */
|
||||
function isC0(stage, compliance) { return stage === 'SUBMITTED' && !isOne(compliance) }
|
||||
function isC1(stage, compliance) { return stage === 'SUBMITTED' && isOne(compliance) }
|
||||
@@ -1065,7 +1101,7 @@ async function pushEsign(ids, loadingId) {
|
||||
try {
|
||||
const resp = await request.post('/business/meetingAttendee/esign', ids, { __silentError: true })
|
||||
const sent = (resp && resp.data != null) ? resp.data : ids.length
|
||||
ElMessage.success(`已推送 ${sent} 份电子签 (短信 + 站内信)`)
|
||||
ElMessage.success(`已推送 ${sent} 份电子签`)
|
||||
selectedAttendees.value = []
|
||||
await loadAttendees()
|
||||
} catch (e) {
|
||||
@@ -1214,6 +1250,7 @@ async function lookupExpertByPhone() {
|
||||
f.title = expert.title || f.title
|
||||
f.idCard = expert.idCard || f.idCard
|
||||
f.bankName = expert.bankName || f.bankName
|
||||
f.bankBranch = expert.bankBranch || f.bankBranch
|
||||
f.bankCard = expert.bankCard || f.bankCard
|
||||
f.bankRegion = expert.bankRegion || f.bankRegion
|
||||
f.bankAddress = expert.bankAddress || f.bankAddress
|
||||
@@ -1669,17 +1706,23 @@ function openPreview(urls, title) {
|
||||
previewOpen.value = true
|
||||
}
|
||||
|
||||
// 保存所有待落库内容 (材料/日程海报/邀请函/付款凭证); 成功返回 OCR 提交数, 失败抛错
|
||||
async function doSave() {
|
||||
const { ocrCount } = await saveMaterials()
|
||||
await saveSchedulePoster()
|
||||
await saveInvitation()
|
||||
if (canUploadVoucher.value) await saveVouchers()
|
||||
// 材料落库 → 会议费用待重算, 刷新状态并轮询到汇总完成
|
||||
refreshFee()
|
||||
return ocrCount
|
||||
}
|
||||
|
||||
async function onSave() {
|
||||
if (saving.value) return
|
||||
saving.value = true
|
||||
try {
|
||||
const { saved, ocrCount } = await saveMaterials()
|
||||
await saveSchedulePoster()
|
||||
await saveInvitation()
|
||||
if (canUploadVoucher.value) await saveVouchers()
|
||||
// 材料落库 → 会议费用待重算, 刷新状态并轮询到汇总完成
|
||||
refreshFee()
|
||||
ElMessage.success(`保存成功 (${saved.length} 条)`)
|
||||
const ocrCount = await doSave()
|
||||
ElMessage.success('保存成功')
|
||||
if (ocrCount) ElMessage.info(`已提交 ${ocrCount} 个识别任务 (后台执行)`)
|
||||
} catch (e) {
|
||||
console.error('[meeting-detail] save failed', e)
|
||||
@@ -1844,7 +1887,6 @@ async function confirmAudit() {
|
||||
}
|
||||
|
||||
// ===================== 结算 / 完结 (合规/管理员 手动点击) =====================
|
||||
// 结算前必须先已上传保存付款凭证 (劳务/会务凭证 tab), 后端 settle 校验凭证存在, 缺失则报错.
|
||||
async function onSettle() {
|
||||
try {
|
||||
await ElMessageBox.confirm('确认结算? 结算前请确保已上传劳务/会务付款凭证。', '结算确认', { type: 'warning' })
|
||||
@@ -2028,8 +2070,11 @@ onBeforeUnmount(stopFeePolling)
|
||||
.track-block:last-child { margin-bottom: 0; }
|
||||
.track-label-row { display: flex; align-items: center; gap: 6px; margin-bottom: 2px; }
|
||||
.cycle-no { font-size: 11px; color: #909399; }
|
||||
.timeline-opinion { margin-top: 4px; font-size: 12px; color: #f56c6c; background: #fef0f0; padding: 4px 8px; border-radius: 3px; line-height: 1.5; word-break: break-all; }
|
||||
.timeline-item.done .timeline-opinion { color: #909399; background: #f5f7fa; }
|
||||
.track-tag { display: inline-block; margin-left: 6px; font-size: 11px; font-weight: 400; color: #909399; background: #f5f7fa; border-radius: 3px; padding: 1px 6px; line-height: 1.6; vertical-align: middle; }
|
||||
.track-mini { display: inline-block; min-width: 34px; font-size: 11px; color: #909399; }
|
||||
.timeline-opinion { margin-top: 4px; font-size: 12px; padding: 4px 8px; border-radius: 3px; line-height: 1.5; word-break: break-all; }
|
||||
.timeline-opinion.opinion-reject { color: #f56c6c; background: #fef0f0; }
|
||||
.timeline-opinion.opinion-approve { color: #389e0d; background: #f6ffed; }
|
||||
|
||||
.audit-columns { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; min-width: 0; }
|
||||
.audit-column { margin-bottom: 0; padding: 16px 18px; min-width: 0; }
|
||||
@@ -2261,4 +2306,4 @@ onBeforeUnmount(stopFeePolling)
|
||||
padding: 6px 3px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user