大更新,太多了,具体进游戏查看详细更新内容
反正很多
This commit is contained in:
627
Server/JsonEdit/templates/json_editor.html
Normal file
627
Server/JsonEdit/templates/json_editor.html
Normal file
@@ -0,0 +1,627 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>简易JSON编辑器 - 批量添加键值</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: #f5f5f5;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.header {
|
||||
background: #4a90e2;
|
||||
color: white;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
display: grid;
|
||||
grid-template-columns: 300px 1fr;
|
||||
gap: 0;
|
||||
min-height: 600px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background: #f8f9fa;
|
||||
border-right: 1px solid #dee2e6;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.editor-area {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.section {
|
||||
background: white;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 5px;
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.section h3 {
|
||||
margin-bottom: 15px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.btn {
|
||||
background: #4a90e2;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
margin: 5px 5px 5px 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: #357abd;
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
background: #28a745;
|
||||
}
|
||||
|
||||
.btn-success:hover {
|
||||
background: #218838;
|
||||
}
|
||||
|
||||
.input-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.input-group label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.input-group input {
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.input-group input:focus {
|
||||
outline: none;
|
||||
border-color: #4a90e2;
|
||||
}
|
||||
|
||||
#jsonEditor {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 5px;
|
||||
padding: 15px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
#jsonEditor:focus {
|
||||
outline: none;
|
||||
border-color: #4a90e2;
|
||||
}
|
||||
|
||||
.file-upload {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.file-upload input[type=file] {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 10px 15px;
|
||||
margin-bottom: 15px;
|
||||
border-radius: 5px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
border: 1px solid #c3e6cb;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
border: 1px solid #f5c6cb;
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
background: #d1ecf1;
|
||||
color: #0c5460;
|
||||
border: 1px solid #bee5eb;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.main-content {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>🔧 JSON批量编辑器</h1>
|
||||
<p>批量添加键值对到JSON文件</p>
|
||||
</div>
|
||||
|
||||
<div class="main-content">
|
||||
<!-- 侧边栏 -->
|
||||
<div class="sidebar">
|
||||
<!-- 文件操作 -->
|
||||
<div class="section">
|
||||
<h3>📁 文件操作</h3>
|
||||
<div class="file-upload btn">
|
||||
<input type="file" id="fileInput" accept=".json" />
|
||||
上传JSON文件
|
||||
</div>
|
||||
<button class="btn btn-success" onclick="downloadJSON()">
|
||||
下载修改后的JSON
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 批量添加键值 -->
|
||||
<div class="section">
|
||||
<h3>⚡ 批量添加键值</h3>
|
||||
<div class="input-group">
|
||||
<label for="keyName">键名:</label>
|
||||
<input type="text" id="keyName" placeholder="例: 能否购买" />
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="keyValue">键值:</label>
|
||||
<input type="text" id="keyValue" placeholder="支持多种类型,见下方说明" />
|
||||
</div>
|
||||
<button class="btn btn-success" onclick="batchAddProperty()">
|
||||
批量添加到所有对象
|
||||
</button>
|
||||
|
||||
<div style="margin-top: 15px; padding: 10px; background: #f8f9fa; border-radius: 5px; font-size: 12px;">
|
||||
<strong>支持的数据类型:</strong><br>
|
||||
• 字符串: hello world<br>
|
||||
• 数字: 123 或 3.14<br>
|
||||
• 布尔值: true 或 false<br>
|
||||
• 空值: null<br>
|
||||
• 对象: {"key": "value"}<br>
|
||||
• 数组: [1, 2, 3]<br>
|
||||
<small style="color: #666;">系统会自动识别并转换数据类型</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 快速示例 -->
|
||||
<div class="section">
|
||||
<h3>📝 快速示例</h3>
|
||||
<button class="btn" onclick="loadSampleJSON()">
|
||||
加载示例数据
|
||||
</button>
|
||||
|
||||
<div style="margin-top: 15px;">
|
||||
<strong style="font-size: 12px;">快速填入示例键值:</strong><br>
|
||||
<button class="btn" style="font-size: 11px; padding: 5px 10px; margin: 2px;" onclick="fillExample('能否购买', 'true')">
|
||||
布尔值示例
|
||||
</button>
|
||||
<button class="btn" style="font-size: 11px; padding: 5px 10px; margin: 2px;" onclick="fillExample('价格', '150')">
|
||||
数字示例
|
||||
</button>
|
||||
<button class="btn" style="font-size: 11px; padding: 5px 10px; margin: 2px;" onclick="fillExample('备注', '新增属性')">
|
||||
字符串示例
|
||||
</button>
|
||||
<button class="btn" style="font-size: 11px; padding: 5px 10px; margin: 2px;" onclick="fillExample('tags', '["新", "热门"]')">
|
||||
数组示例
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- JSON格式化操作 -->
|
||||
<div class="section">
|
||||
<h3>🔧 格式化操作</h3>
|
||||
<button class="btn" onclick="formatJSONStandard()">
|
||||
标准格式化
|
||||
</button>
|
||||
<button class="btn btn-success" onclick="minifyJSON()">
|
||||
最小化(压缩)
|
||||
</button>
|
||||
<button class="btn" style="background: #17a2b8;" onclick="oneLinePerObject()">
|
||||
一行化(一个对象一行)
|
||||
</button>
|
||||
<button class="btn" style="background: #6f42c1; color: white;" onclick="validateJSON()">
|
||||
验证JSON格式
|
||||
</button>
|
||||
|
||||
<div style="margin-top: 15px; padding: 10px; background: #f8f9fa; border-radius: 5px; font-size: 12px;">
|
||||
<strong>格式化说明:</strong><br>
|
||||
• <strong>标准格式化</strong>: 2空格缩进,易于阅读<br>
|
||||
• <strong>最小化</strong>: 去除空格,节省空间<br>
|
||||
• <strong>一行化</strong>: 每个对象占一行,便于比较<br>
|
||||
• <strong>验证格式</strong>: 检查JSON语法是否正确<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 编辑区域 -->
|
||||
<div class="editor-area">
|
||||
<!-- 消息区域 -->
|
||||
<div id="messageArea"></div>
|
||||
|
||||
<!-- JSON编辑器 -->
|
||||
<textarea id="jsonEditor" placeholder="在此输入或上传JSON数据..."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 初始化
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.getElementById('fileInput').addEventListener('change', handleFileUpload);
|
||||
});
|
||||
|
||||
// 显示消息
|
||||
function showMessage(message, type = 'success') {
|
||||
const messageArea = document.getElementById('messageArea');
|
||||
let alertClass = 'alert-success';
|
||||
|
||||
if (type === 'error') {
|
||||
alertClass = 'alert-error';
|
||||
} else if (type === 'info') {
|
||||
alertClass = 'alert-info';
|
||||
}
|
||||
|
||||
messageArea.innerHTML = `
|
||||
<div class="alert ${alertClass}">
|
||||
${message}
|
||||
</div>
|
||||
`;
|
||||
|
||||
setTimeout(() => {
|
||||
messageArea.innerHTML = '';
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
// 加载示例JSON
|
||||
function loadSampleJSON() {
|
||||
const sampleJSON = {
|
||||
"测试作物": {
|
||||
"花费": 1,
|
||||
"生长时间": 3,
|
||||
"收益": 9999,
|
||||
"品质": "普通"
|
||||
},
|
||||
"小麦": {
|
||||
"花费": 120,
|
||||
"生长时间": 120,
|
||||
"收益": 100,
|
||||
"品质": "普通"
|
||||
},
|
||||
"稻谷": {
|
||||
"花费": 100,
|
||||
"生长时间": 240,
|
||||
"收益": 120,
|
||||
"品质": "普通"
|
||||
}
|
||||
};
|
||||
|
||||
document.getElementById('jsonEditor').value = JSON.stringify(sampleJSON, null, 2);
|
||||
showMessage('示例数据已加载');
|
||||
}
|
||||
|
||||
// 快速填入示例键值对
|
||||
function fillExample(keyName, keyValue) {
|
||||
document.getElementById('keyName').value = keyName;
|
||||
document.getElementById('keyValue').value = keyValue;
|
||||
showMessage(`已填入示例: ${keyName} = ${keyValue}`, 'info');
|
||||
}
|
||||
|
||||
// 文件上传处理
|
||||
function handleFileUpload(event) {
|
||||
const file = event.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
if (!file.name.toLowerCase().endsWith('.json')) {
|
||||
showMessage('请选择JSON文件', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
try {
|
||||
const content = e.target.result;
|
||||
JSON.parse(content); // 验证JSON格式
|
||||
document.getElementById('jsonEditor').value = content;
|
||||
showMessage('文件上传成功');
|
||||
} catch (error) {
|
||||
showMessage('JSON格式错误: ' + error.message, 'error');
|
||||
}
|
||||
};
|
||||
reader.readAsText(file);
|
||||
|
||||
// 清空文件输入
|
||||
event.target.value = '';
|
||||
}
|
||||
|
||||
// 批量添加属性
|
||||
function batchAddProperty() {
|
||||
const keyName = document.getElementById('keyName').value.trim();
|
||||
const keyValue = document.getElementById('keyValue').value.trim();
|
||||
const jsonContent = document.getElementById('jsonEditor').value.trim();
|
||||
|
||||
if (!keyName) {
|
||||
showMessage('请输入键名', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!jsonContent) {
|
||||
showMessage('请输入或上传JSON数据', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let jsonData = JSON.parse(jsonContent);
|
||||
|
||||
// 智能类型转换
|
||||
let processedValue = parseValue(keyValue);
|
||||
|
||||
// 批量添加属性
|
||||
const result = addPropertyToAllObjects(jsonData, keyName, processedValue);
|
||||
|
||||
if (result.count > 0) {
|
||||
document.getElementById('jsonEditor').value = JSON.stringify(jsonData, null, 2);
|
||||
showMessage(`成功为 ${result.count} 个对象添加了属性 "${keyName}": ${JSON.stringify(processedValue)}`);
|
||||
} else {
|
||||
showMessage('未找到可添加属性的对象', 'info');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
showMessage('JSON格式错误: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 智能解析值的类型
|
||||
function parseValue(value) {
|
||||
// 如果输入为空,返回空字符串
|
||||
if (value === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
// 尝试解析为null
|
||||
if (value.toLowerCase() === 'null') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 尝试解析为undefined(虽然JSON不支持,但转为null)
|
||||
if (value.toLowerCase() === 'undefined') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 尝试解析为布尔值
|
||||
if (value.toLowerCase() === 'true') {
|
||||
return true;
|
||||
}
|
||||
if (value.toLowerCase() === 'false') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 尝试解析为数字
|
||||
if (!isNaN(value) && !isNaN(parseFloat(value))) {
|
||||
// 检查是否为整数
|
||||
if (Number.isInteger(parseFloat(value))) {
|
||||
return parseInt(value, 10);
|
||||
} else {
|
||||
return parseFloat(value);
|
||||
}
|
||||
}
|
||||
|
||||
// 尝试解析为JSON对象或数组
|
||||
if ((value.startsWith('{') && value.endsWith('}')) ||
|
||||
(value.startsWith('[') && value.endsWith(']'))) {
|
||||
try {
|
||||
return JSON.parse(value);
|
||||
} catch (e) {
|
||||
// 如果解析失败,当作字符串处理
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
// 默认当作字符串处理
|
||||
return value;
|
||||
}
|
||||
|
||||
// 递归为所有对象添加属性
|
||||
function addPropertyToAllObjects(obj, key, value) {
|
||||
let count = 0;
|
||||
|
||||
function traverse(current) {
|
||||
if (typeof current === 'object' && current !== null) {
|
||||
if (Array.isArray(current)) {
|
||||
// 处理数组
|
||||
current.forEach(item => traverse(item));
|
||||
} else {
|
||||
// 处理对象
|
||||
current[key] = value;
|
||||
count++;
|
||||
|
||||
// 继续递归处理嵌套对象
|
||||
Object.values(current).forEach(val => {
|
||||
if (typeof val === 'object' && val !== null && val !== current) {
|
||||
traverse(val);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
traverse(obj);
|
||||
return { count };
|
||||
}
|
||||
|
||||
// 下载JSON
|
||||
function downloadJSON() {
|
||||
const content = document.getElementById('jsonEditor').value.trim();
|
||||
|
||||
if (!content) {
|
||||
showMessage('没有可下载的内容', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 验证JSON格式
|
||||
JSON.parse(content);
|
||||
|
||||
const blob = new Blob([content], { type: 'application/json' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = `edited_json_${new Date().getTime()}.json`;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(url);
|
||||
|
||||
showMessage('JSON文件下载成功');
|
||||
} catch (error) {
|
||||
showMessage('JSON格式错误,无法下载: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 标准格式化JSON
|
||||
function formatJSONStandard() {
|
||||
const content = document.getElementById('jsonEditor').value.trim();
|
||||
|
||||
if (!content) {
|
||||
showMessage('请输入JSON数据', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const jsonData = JSON.parse(content);
|
||||
const formatted = JSON.stringify(jsonData, null, 2);
|
||||
document.getElementById('jsonEditor').value = formatted;
|
||||
showMessage('JSON标准格式化完成');
|
||||
} catch (error) {
|
||||
showMessage('JSON格式错误: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 最小化JSON(压缩)
|
||||
function minifyJSON() {
|
||||
const content = document.getElementById('jsonEditor').value.trim();
|
||||
|
||||
if (!content) {
|
||||
showMessage('请输入JSON数据', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const jsonData = JSON.parse(content);
|
||||
const minified = JSON.stringify(jsonData);
|
||||
document.getElementById('jsonEditor').value = minified;
|
||||
showMessage('JSON最小化完成');
|
||||
} catch (error) {
|
||||
showMessage('JSON格式错误: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 一行化格式(一个对象一行)
|
||||
function oneLinePerObject() {
|
||||
const content = document.getElementById('jsonEditor').value.trim();
|
||||
|
||||
if (!content) {
|
||||
showMessage('请输入JSON数据', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const jsonData = JSON.parse(content);
|
||||
let formatted = '';
|
||||
|
||||
if (Array.isArray(jsonData)) {
|
||||
// 如果是数组,每个元素占一行
|
||||
formatted = '[\n';
|
||||
jsonData.forEach((item, index) => {
|
||||
formatted += ' ' + JSON.stringify(item);
|
||||
if (index < jsonData.length - 1) {
|
||||
formatted += ',';
|
||||
}
|
||||
formatted += '\n';
|
||||
});
|
||||
formatted += ']';
|
||||
} else if (typeof jsonData === 'object' && jsonData !== null) {
|
||||
// 如果是对象,每个键值对占一行
|
||||
formatted = '{\n';
|
||||
const keys = Object.keys(jsonData);
|
||||
keys.forEach((key, index) => {
|
||||
formatted += ' ' + JSON.stringify(key) + ': ' + JSON.stringify(jsonData[key]);
|
||||
if (index < keys.length - 1) {
|
||||
formatted += ',';
|
||||
}
|
||||
formatted += '\n';
|
||||
});
|
||||
formatted += '}';
|
||||
} else {
|
||||
// 基本类型直接输出
|
||||
formatted = JSON.stringify(jsonData);
|
||||
}
|
||||
|
||||
document.getElementById('jsonEditor').value = formatted;
|
||||
showMessage('JSON一行化格式完成');
|
||||
} catch (error) {
|
||||
showMessage('JSON格式错误: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 验证JSON格式
|
||||
function validateJSON() {
|
||||
const content = document.getElementById('jsonEditor').value.trim();
|
||||
|
||||
if (!content) {
|
||||
showMessage('请输入JSON数据', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
JSON.parse(content);
|
||||
showMessage('JSON格式验证通过');
|
||||
} catch (error) {
|
||||
showMessage('JSON格式错误: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user