大更新,太多了,具体进游戏查看详细更新内容

反正很多
This commit is contained in:
2025-05-27 11:09:09 +08:00
parent a1e71a6a79
commit 8215cfa3ee
382 changed files with 13838 additions and 2974 deletions

View 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', '[&quot;新&quot;, &quot;热门&quot;]')">
数组示例
</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>