214 lines
6.1 KiB
HTML
214 lines
6.1 KiB
HTML
<style>
|
||
.timeline-container {
|
||
padding: 20px;
|
||
position: relative;
|
||
}
|
||
|
||
.timeline {
|
||
position: relative;
|
||
margin: 0;
|
||
padding: 0;
|
||
}
|
||
|
||
.timeline::before {
|
||
content: '';
|
||
position: absolute;
|
||
left: 18px;
|
||
top: 0;
|
||
bottom: 0;
|
||
width: 2px;
|
||
background: #e4e7ed;
|
||
}
|
||
|
||
.timeline-item {
|
||
position: relative;
|
||
padding-left: 40px;
|
||
margin-bottom: 30px;
|
||
}
|
||
|
||
.timeline-item:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.timeline-marker {
|
||
position: absolute;
|
||
left: 10px;
|
||
top: 4px;
|
||
width: 16px;
|
||
height: 16px;
|
||
background-color: #409EFF;
|
||
border: 2px solid #fff;
|
||
border-radius: 50%;
|
||
box-shadow: 0 0 0 2px #409EFF;
|
||
z-index: 1;
|
||
}
|
||
|
||
.timeline-content {
|
||
background: #f9f9f9;
|
||
border-radius: 4px;
|
||
padding: 10px 15px;
|
||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||
}
|
||
|
||
.timeline-title {
|
||
font-weight: bold;
|
||
color: #333;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.timeline-time {
|
||
font-size: 12px;
|
||
color: #999;
|
||
margin-top: 8px;
|
||
}
|
||
|
||
/* 内层进度日志样式 */
|
||
.timeline-progress {
|
||
margin-top: 10px;
|
||
border-left: 2px solid #d0d4db;
|
||
padding-left: 15px;
|
||
}
|
||
|
||
.timeline-progress-item {
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.progress-time {
|
||
font-size: 13px;
|
||
color: #888;
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.progress-user {
|
||
font-weight: 600;
|
||
color: #409EFF;
|
||
margin-right: 6px;
|
||
}
|
||
|
||
.progress-remark {
|
||
color: #555;
|
||
}
|
||
</style>
|
||
|
||
<div class="panel panel-default panel-intro">
|
||
<div class="panel-body">
|
||
<div id="myTabContent" class="tab-content">
|
||
<div class="timeline" id="log-timeline"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 图片预览弹窗 -->
|
||
<div id="image-preview-overlay" style="display:none;position:fixed;top:0;left:0;width:100vw;height:100vh;background:rgba(0,0,0,0.6);z-index:9999;justify-content:center;align-items:center;">
|
||
<img id="image-preview-img" src="" style="max-width:90%;max-height:90%;box-shadow:0 0 20px #000;border-radius:6px;" />
|
||
</div>
|
||
|
||
<style>
|
||
.progress-images img:hover {
|
||
box-shadow: 0 0 4px rgba(0, 0, 0, 0.4);
|
||
cursor: pointer;
|
||
}
|
||
</style>
|
||
|
||
<script>
|
||
const logs = {$logs}; // 后端传入的数据,格式保持和你的一致
|
||
const cdnurl = '{$cdnurl}';
|
||
|
||
function getRoleLabel(role) {
|
||
return '';
|
||
}
|
||
|
||
function renderTimeline(logs) {
|
||
const container = document.getElementById('log-timeline');
|
||
container.innerHTML = '';
|
||
|
||
// 外层倒序时间
|
||
logs.sort((a, b) => new Date(b.create_time) - new Date(a.create_time));
|
||
|
||
logs.forEach(log => {
|
||
const item = document.createElement('div');
|
||
item.className = 'timeline-item';
|
||
|
||
// 外层用户显示,带角色标签
|
||
const outerRoleLabel = getRoleLabel(log.role);
|
||
const outerUserDisplay = `${outerRoleLabel}${log.admin_user || '系统'}`;
|
||
|
||
// 内层进度日志HTML(时间顺序)
|
||
const progressHTML = (log.progress_logs || [])
|
||
.sort((a, b) => new Date(a.create_time) - new Date(b.create_time))
|
||
.map(progress => {
|
||
const innerRoleLabel = getRoleLabel(progress.role);
|
||
const innerUserDisplay = `${innerRoleLabel}${progress.admin_user || '系统'}`;
|
||
return `
|
||
<div class="timeline-progress-item">
|
||
<span class="progress-time">${progress.create_time}</span>
|
||
<span class="progress-user">${progress.status_text}</span>
|
||
<span class="progress-user">${innerUserDisplay}</span>
|
||
<span class="progress-remark">${progress.remark || '无内容'}</span>
|
||
${renderProgressImages(progress.images)}
|
||
</div>
|
||
`;
|
||
}).join('');
|
||
|
||
item.innerHTML = `
|
||
<div class="timeline-marker"></div>
|
||
<div class="timeline-content">
|
||
<h4 class="timeline-title">${log.order_status_text || '无状态'}</h4>
|
||
|
||
<p>${log.create_time} ${outerUserDisplay} ${log.remark || '无'} </p>
|
||
|
||
${progressHTML ? `<div class="timeline-progress">${progressHTML}</div>` : ''}
|
||
</div>
|
||
`;
|
||
|
||
container.appendChild(item);
|
||
});
|
||
}
|
||
|
||
renderTimeline(logs);
|
||
|
||
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
const overlay = document.getElementById('image-preview-overlay');
|
||
const previewImg = document.getElementById('image-preview-img');
|
||
|
||
// 事件委托:图片点击弹窗
|
||
document.body.addEventListener('click', function (e) {
|
||
if (e.target.tagName === 'IMG' && e.target.dataset.preview === 'true') {
|
||
previewImg.src = e.target.src;
|
||
overlay.style.display = 'flex';
|
||
}
|
||
});
|
||
|
||
// 点击遮罩关闭
|
||
overlay.addEventListener('click', function () {
|
||
overlay.style.display = 'none';
|
||
previewImg.src = '';
|
||
});
|
||
});
|
||
|
||
function renderProgressImages(imageStr) {
|
||
if (!imageStr || typeof imageStr !== 'string') return '';
|
||
|
||
const imageList = imageStr.split(',')
|
||
.map(url => url.trim())
|
||
.filter(Boolean);
|
||
|
||
if (!imageList.length) return '';
|
||
|
||
return `
|
||
<div class="progress-images" style="margin-top: 6px;">
|
||
${imageList.map(img => {
|
||
const fullUrl = img.startsWith('http') ? img : cdnurl + img;
|
||
return `
|
||
<img src="${fullUrl}" data-preview="true"
|
||
style="width:40px;height:40px;border-radius:4px;border:1px solid #ccc;margin-right:5px;"
|
||
onerror="this.style.display='none'" />
|
||
`;
|
||
}).join('')}
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
</script>
|