Compare commits
2 Commits
615d9433fe
...
ac580599b3
| Author | SHA1 | Date | |
|---|---|---|---|
| ac580599b3 | |||
| faae7032f1 |
@@ -3,226 +3,47 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>数据管理</title>
|
||||
<style>
|
||||
body {margin: 0;font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;background: #fafafa;}
|
||||
/* 导航栏样式 */
|
||||
.sidebar {position: fixed;top: 0;left: 0;width: 180px;height: 100vh;background: #1e1e2e;color: white;padding: 20px;box-shadow: 2px 0 5px rgba(0,0,0,0.1);z-index: 1000;display: flex;
|
||||
flex-direction: column;align-items: center;}
|
||||
.user-id {text-align: center;margin-bottom: 0px;}
|
||||
.sidebar h3 {margin-top: 0;font-size: 18px;color: #add8e6;text-align: center; margin-bottom: 20px;}
|
||||
.navigation-links {width: 100%;margin-top: 60px;}
|
||||
.sidebar a,
|
||||
.sidebar button {display: block;color: #8be9fd;text-decoration: none;margin: 10px 0;font-size: 16px;padding: 15px;border-radius: 4px;background: transparent;
|
||||
border: none;cursor: pointer; width: calc(100% - 40px);text-align: left;transition: all 0.2s ease;}
|
||||
.sidebar a:hover,
|
||||
.sidebar button:hover {color: #ff79c6;background-color: rgba(139, 233, 253, 0.2);}
|
||||
/* 主内容区 */
|
||||
.main-content {
|
||||
margin-left: 200px;
|
||||
padding: 20px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 原有样式保持不变 */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 6px 18px rgba(0,0,0,0.06);
|
||||
padding: 20px;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 20px;
|
||||
}
|
||||
th, td {
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 12px 8px;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
th {
|
||||
background-color: #f8f9fa;
|
||||
font-weight: 600;
|
||||
}
|
||||
img {
|
||||
max-width: 120px;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 6px;
|
||||
cursor: pointer; /* 添加指针样式 */
|
||||
}
|
||||
.btn {
|
||||
padding: 6px 10px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
margin: 2px;
|
||||
}
|
||||
.btn-primary {
|
||||
background: #1677ff;
|
||||
color: #fff;
|
||||
}
|
||||
.btn-danger {
|
||||
background: #ff4d4f;
|
||||
color: #fff;
|
||||
}
|
||||
.btn-secondary {
|
||||
background: #f0f0f0;
|
||||
color: #333;
|
||||
}
|
||||
.muted {
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
}
|
||||
.modal {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
display: none;
|
||||
background: rgba(0,0,0,0.4);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
.modal .dialog {
|
||||
width: 720px;
|
||||
max-width: 92vw;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
textarea {
|
||||
width: 100%;
|
||||
min-height: 240px;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
font-size: 14px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
resize: vertical;
|
||||
}
|
||||
#kvForm {
|
||||
border: 1px solid #eee;
|
||||
border-radius: 6px;
|
||||
padding: 8px;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* 搜索区域样式 */
|
||||
.search-container {
|
||||
background: #f8f9fa;
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.search-controls {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.search-input {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
padding: 8px 12px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.search-result {
|
||||
margin-top: 10px;
|
||||
padding: 10px;
|
||||
background: #e8f4ff;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.search-result.empty {
|
||||
background: #fff8e8;
|
||||
}
|
||||
.search-result.error {
|
||||
background: #ffe8e8;
|
||||
}
|
||||
|
||||
/* 加载动画 */
|
||||
.loading {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 3px solid #f3f3f3;
|
||||
border-top: 3px solid #1677ff;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 768px) {
|
||||
.search-controls {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
.search-input {
|
||||
min-width: auto;
|
||||
}
|
||||
.btn {
|
||||
width: 100%;
|
||||
margin: 2px 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 图片放大模态框 */
|
||||
.image-modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 2000;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0,0,0,0.9);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.image-modal-content {
|
||||
margin: auto;
|
||||
display: block;
|
||||
width: 80%;
|
||||
max-width: 800px;
|
||||
max-height: 80%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
object-fit: contain; /* 保持图片比例,完整显示 */
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.image-modal-close {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 35px;
|
||||
color: #f1f1f1;
|
||||
font-size: 40px;
|
||||
font-weight: bold;
|
||||
transition: 0.3s;
|
||||
cursor: pointer;
|
||||
z-index: 2001;
|
||||
}
|
||||
|
||||
.image-modal-close:hover {
|
||||
color: #bbb;
|
||||
}
|
||||
<style>
|
||||
body{margin:0;font-family:sans-serif;background:#fafafa}
|
||||
.sidebar{position:fixed;top:0;left:0;width:180px;height:100vh;background:#1e1e2e;color:white;padding:20px;box-shadow:2px 0 5px rgba(0,0,0,.1);z-index:1000;display:flex;flex-direction:column;align-items:center}
|
||||
.user-id{text-align:center;margin-bottom:0}
|
||||
.sidebar h3{margin:0;font-size:18px;color:#add8e6;text-align:center;margin-bottom:20px}
|
||||
.navigation-links{width:100%;margin-top:60px}
|
||||
.sidebar a,.sidebar button{display:block;color:#8be9fd;text-decoration:none;margin:10px 0;font-size:16px;padding:15px;border-radius:4px;background:transparent;border:none;cursor:pointer;width:calc(100% - 40px);text-align:left;transition:.2s}
|
||||
.sidebar a:hover,.sidebar button:hover{color:#ff79c6;background-color:rgba(139,233,253,.2)}
|
||||
.main-content{margin-left:200px;padding:20px;color:#333}
|
||||
.container{max-width:1200px;margin:0 auto;background:#fff;border-radius:10px;box-shadow:0 6px 18px rgba(0,0,0,.06);padding:20px}
|
||||
table{width:100%;border-collapse:collapse;margin-top:20px}
|
||||
th,td{border-bottom:1px solid #eee;padding:12px 8px;text-align:left;vertical-align:top}
|
||||
th{background:#f8f9fa;font-weight:600}
|
||||
img{max-width:120px;border:1px solid #eee;border-radius:6px;cursor:pointer}
|
||||
.btn{padding:6px 10px;border:none;border-radius:6px;cursor:pointer;font-size:14px;margin:2px}
|
||||
.btn-primary{background:#1677ff;color:#fff}
|
||||
.btn-danger{background:#ff4d4f;color:#fff}
|
||||
.btn-secondary{background:#f0f0f0;color:#333}
|
||||
.muted{color:#666;font-size:12px}
|
||||
.modal{position:fixed;inset:0;display:none;background:rgba(0,0,0,.4);align-items:center;justify-content:center;z-index:1000}
|
||||
.modal .dialog{width:720px;max-width:92vw;background:#fff;border-radius:10px;padding:20px;max-height:80vh;overflow-y:auto}
|
||||
textarea{width:100%;min-height:240px;font-family:monospace;font-size:14px;padding:10px;border:1px solid #ddd;border-radius:4px;resize:vertical}
|
||||
#kvForm{border:1px solid #eee;border-radius:6px;padding:8px;max-height:300px;overflow:auto}
|
||||
.search-container{background:#f8f9fa;padding:15px;border-radius:8px;margin-bottom:20px}
|
||||
.search-controls{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-bottom:10px}
|
||||
.search-input{flex:1;min-width:200px;padding:8px 12px;border:1px solid #ddd;border-radius:4px;font-size:14px}
|
||||
.search-result{margin-top:10px;padding:10px;background:#e8f4ff;border-radius:4px;font-size:14px}
|
||||
.search-result.empty{background:#fff8e8}
|
||||
.search-result.error{background:#ffe8e8}
|
||||
.loading{display:inline-block;width:20px;height:20px;border:3px solid #f3f3f3;border-top:3px solid #1677ff;border-radius:50%;animation:spin 1s linear infinite}
|
||||
@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}
|
||||
@media(max-width:768px){.search-controls{flex-direction:column;align-items:stretch}.search-input{min-width:auto}.btn{width:100%;margin:2px 0}}
|
||||
.image-modal{display:none;position:fixed;z-index:2000;left:0;top:0;width:100%;height:100%;background:rgba(0,0,0,.9);overflow:hidden}
|
||||
.image-modal-content{margin:auto;display:block;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);max-width:80%;max-height:80%;object-fit:contain;border-radius:8px;box-shadow:0 10px 30px rgba(0,0,0,.5);cursor:grab;transition:transform .3s ease}
|
||||
.image-modal-content.dragging{cursor:grabbing}
|
||||
.image-modal-close{position:absolute;top:15px;right:35px;color:#f1f1f1;font-size:40px;font-weight:bold;transition:.3s;cursor:pointer;z-index:2001}
|
||||
.image-modal-close:hover{color:#bbb}
|
||||
.zoom-controls{position:absolute;bottom:30px;left:50%;transform:translateX(-50%);display:flex;gap:10px;z-index:2001}
|
||||
.zoom-btn{background:rgba(255,255,255,.7);border:none;border-radius:50%;width:40px;height:40px;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 10px rgba(0,0,0,.3);transition:background .3s}
|
||||
.zoom-btn:hover{background:rgba(255,255,255,.9)}
|
||||
.zoom-info{position:absolute;top:15px;left:15px;color:#f1f1f1;font-size:14px;z-index:2001;background:rgba(0,0,0,.5);padding:5px 10px;border-radius:4px}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -302,7 +123,13 @@
|
||||
<!-- 图片放大模态框 -->
|
||||
<div id="imageModal" class="image-modal">
|
||||
<span class="image-modal-close">×</span>
|
||||
<div class="zoom-info">缩放: <span id="zoomValue">100%</span></div>
|
||||
<img class="image-modal-content" id="expandedImage">
|
||||
<div class="zoom-controls">
|
||||
<button class="zoom-btn" id="zoomOutBtn">-</button>
|
||||
<button class="zoom-btn" id="resetZoomBtn">1:1</button>
|
||||
<button class="zoom-btn" id="zoomInBtn">+</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@@ -330,6 +157,10 @@ const syncFromTextBtn = document.getElementById('syncFromTextBtn');
|
||||
const imageModal = document.getElementById('imageModal');
|
||||
const expandedImage = document.getElementById('expandedImage');
|
||||
const imageModalClose = document.querySelector('.image-modal-close');
|
||||
const zoomInBtn = document.getElementById('zoomInBtn');
|
||||
const zoomOutBtn = document.getElementById('zoomOutBtn');
|
||||
const resetZoomBtn = document.getElementById('resetZoomBtn');
|
||||
const zoomValue = document.getElementById('zoomValue');
|
||||
|
||||
// 全局变量
|
||||
let currentId = '';
|
||||
@@ -337,6 +168,16 @@ let currentWriter = '';
|
||||
let currentImage = '';
|
||||
let allDataCache = []; // 缓存所有数据,避免重复请求
|
||||
|
||||
// 图片缩放相关变量
|
||||
let currentScale = 1;
|
||||
let currentX = 0;
|
||||
let currentY = 0;
|
||||
let isDragging = false;
|
||||
let dragStartX = 0;
|
||||
let dragStartY = 0;
|
||||
let imgStartX = 0;
|
||||
let imgStartY = 0;
|
||||
|
||||
// 搜索功能
|
||||
async function performSearch(type) {
|
||||
const query = searchQueryInput.value.trim();
|
||||
@@ -727,6 +568,30 @@ document.getElementById('logoutBtn').addEventListener('click', async () => {
|
||||
}
|
||||
});
|
||||
|
||||
// 图片缩放功能
|
||||
function updateZoom() {
|
||||
expandedImage.style.transform = `translate(-50%, -50%) scale(${currentScale}) translate(${currentX}px, ${currentY}px)`;
|
||||
zoomValue.textContent = `${Math.round(currentScale * 100)}%`;
|
||||
}
|
||||
|
||||
function resetZoom() {
|
||||
currentScale = 1;
|
||||
currentX = 0;
|
||||
currentY = 0;
|
||||
updateZoom();
|
||||
}
|
||||
|
||||
function zoomIn() {
|
||||
currentScale *= 1.2;
|
||||
updateZoom();
|
||||
}
|
||||
|
||||
function zoomOut() {
|
||||
currentScale /= 1.2;
|
||||
if (currentScale < 0.1) currentScale = 0.1; // 最小缩放限制
|
||||
updateZoom();
|
||||
}
|
||||
|
||||
// 图片放大功能
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// 为所有图片添加点击事件监听器
|
||||
@@ -735,6 +600,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const imgSrc = e.target.src;
|
||||
expandedImage.src = imgSrc;
|
||||
imageModal.style.display = 'block';
|
||||
|
||||
// 重置缩放状态
|
||||
resetZoom();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -749,6 +617,91 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
imageModal.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// 缩放按钮事件
|
||||
zoomInBtn.addEventListener('click', zoomIn);
|
||||
zoomOutBtn.addEventListener('click', zoomOut);
|
||||
resetZoomBtn.addEventListener('click', resetZoom);
|
||||
|
||||
// 鼠标滚轮缩放
|
||||
expandedImage.addEventListener('wheel', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (e.deltaY < 0) {
|
||||
zoomIn();
|
||||
} else {
|
||||
zoomOut();
|
||||
}
|
||||
});
|
||||
|
||||
// 拖拽功能
|
||||
expandedImage.addEventListener('mousedown', function(e) {
|
||||
isDragging = true;
|
||||
dragStartX = e.clientX;
|
||||
dragStartY = e.clientY;
|
||||
imgStartX = currentX;
|
||||
imgStartY = currentY;
|
||||
expandedImage.classList.add('dragging');
|
||||
});
|
||||
|
||||
document.addEventListener('mousemove', function(e) {
|
||||
if (isDragging) {
|
||||
const deltaX = e.clientX - dragStartX;
|
||||
const deltaY = e.clientY - dragStartY;
|
||||
currentX = imgStartX + deltaX / currentScale;
|
||||
currentY = imgStartY + deltaY / currentScale;
|
||||
updateZoom();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('mouseup', function() {
|
||||
isDragging = false;
|
||||
expandedImage.classList.remove('dragging');
|
||||
});
|
||||
|
||||
// 触摸事件支持(移动端)
|
||||
expandedImage.addEventListener('touchstart', function(e) {
|
||||
if (e.touches.length === 1) {
|
||||
isDragging = true;
|
||||
dragStartX = e.touches[0].clientX;
|
||||
dragStartY = e.touches[0].clientY;
|
||||
imgStartX = currentX;
|
||||
imgStartY = currentY;
|
||||
} else if (e.touches.length === 2) {
|
||||
// 双指缩放
|
||||
initialDistance = getDistance(e.touches[0], e.touches[1]);
|
||||
initialScale = currentScale;
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('touchmove', function(e) {
|
||||
e.preventDefault();
|
||||
if (isDragging && e.touches.length === 1) {
|
||||
const deltaX = e.touches[0].clientX - dragStartX;
|
||||
const deltaY = e.touches[0].clientY - dragStartY;
|
||||
currentX = imgStartX + deltaX / currentScale;
|
||||
currentY = imgStartY + deltaY / currentScale;
|
||||
updateZoom();
|
||||
} else if (e.touches.length === 2) {
|
||||
// 双指缩放
|
||||
const currentDistance = getDistance(e.touches[0], e.touches[1]);
|
||||
const scale = (currentDistance / initialDistance) * initialScale;
|
||||
currentScale = Math.max(0.1, Math.min(scale, 10)); // 限制缩放范围
|
||||
updateZoom();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('touchend', function() {
|
||||
isDragging = false;
|
||||
});
|
||||
|
||||
// 计算两点间距离
|
||||
function getDistance(touch1, touch2) {
|
||||
return Math.sqrt(
|
||||
Math.pow(touch2.clientX - touch1.clientX, 2) +
|
||||
Math.pow(touch2.clientY - touch1.clientY, 2)
|
||||
);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user