diff --git a/apps/webUI.js b/apps/webUI.js
index 06c23d7..060bcf6 100644
--- a/apps/webUI.js
+++ b/apps/webUI.js
@@ -29,9 +29,7 @@ export class WebUI extends plugin {
this.isOpenWebUI = this.toolsConfig.isOpenWebUI;
}
- async rWebSwitch(e) {
- config.updateField("tools", "isOpenWebUI", !this.isOpenWebUI);
- const realIsOpenWebUI = config.getConfig("tools").isOpenWebUI;
+ async initData(e, realIsOpenWebUI) {
if (realIsOpenWebUI) {
Promise.all([getBotStatus(e), getBotVersionInfo(e), getBotLoginInfo(e)]).then(values => {
const status = values[0].data;
@@ -44,13 +42,20 @@ export class WebUI extends plugin {
})
})
}
+ }
+
+ async rWebSwitch(e) {
+ config.updateField("tools", "isOpenWebUI", !this.isOpenWebUI);
+ const realIsOpenWebUI = config.getConfig("tools").isOpenWebUI;
+ // 初始化数据
+ await this.initData(e, realIsOpenWebUI);
// 这里有点延迟,需要写反
- e.reply(`R插件 WebUI:${ realIsOpenWebUI ? "开启\n🚀 请重启以启动 WebUI" : "关闭" }`);
+ e.reply(`R插件可视化面板:${ realIsOpenWebUI ? "✅已开启" : "❌已关闭" },重启后生效`);
return true;
}
async rWebStatus(e) {
- e.reply(`R插件 WebUI:${ this.toolsConfig.isOpenWebUI ? "开启" : "关闭" }`);
+ e.reply(`R插件可视化面板:${ this.toolsConfig.isOpenWebUI ? "✅开启" : "❌关闭" }`);
return true;
}
}
diff --git a/server/components/common/ConfigItem.jsx b/server/components/common/ConfigItem.jsx
new file mode 100644
index 0000000..33b36bf
--- /dev/null
+++ b/server/components/common/ConfigItem.jsx
@@ -0,0 +1,47 @@
+import React from 'react';
+
+export const ConfigToggle = ({ label, checked, onChange }) => (
+
- {/* 成功提示 */}
通用配置
- {/* 基础配置部分 */}
基础配置
- {/* 路径和大小限制配置 */ }
+ {/* 基础配置 */}
+ {renderInputGroup(GENERIC_CONFIG.basicInputs)}
+
+ {/* 代理配置 */}
+
代理设置
+ {renderInputGroup(GENERIC_CONFIG.proxyInputs)}
+
+ {/* 流媒体配置 */}
+
流媒体设置
+ {renderInputGroup(GENERIC_CONFIG.streamInputs)}
+
+ {/* 并发配置 */}
+
并发设置
+ {renderInputGroup(GENERIC_CONFIG.concurrencyInputs)}
+
+ {/* DeepL API配置 */}
+
API设置
+ {GENERIC_CONFIG.textareas.map(item => (
+
+
+
+ ))}
+
+ {/* 开关配置 */}
+ {GENERIC_CONFIG.toggles.map(item => (
+
+ handleConfigChange(item.key, value)}
+ />
+ {item.hint && (
+
+ {item.hint}
+
+ )}
+
+ ))}
+
+ {/* 其他配置 */}
+
其他设置
+ {renderInputGroup(GENERIC_CONFIG.otherInputs)}
+
+ {/* AI配置 */}
+
AI设置
+ {renderInputGroup(GENERIC_CONFIG.aiInputs)}
-
- {/* 代理配置 */ }
-
-
- {/* 其他基础配置 */ }
-
-
- {/* 并发和定时配置 */ }
-
-
- {/* DeepL API配置 */ }
-
-
-
-
- {/* 开关配置 */ }
-
-
-
- NCQQ不用开启,其他ICQQ、LLO需要开启
-
-
-
- {/* 小红书 Cookie */ }
-
-
- setConfig({ ...config, xiaohongshuCookie: e.target.value }) }
- placeholder="请输入小红书的Cookie..."
- className="input input-bordered"
- />
-
-
- {/* 定时清理配置 */ }
-
-
-
setConfig({ ...config, autoclearTrashtime: e.target.value }) }
- placeholder="请输入Cron表达式..."
- className="input input-bordered"
- />
+ {GENERIC_CONFIG.aiSelects.map(item => (
+
+ handleConfigChange(item.key, value)}
+ options={item.options}
+ />
+ {item.hint && (
+
+ {item.hint}
+
+ )}
+
+ ))}
- {/* 保存按钮 */ }
+ {/* 保存按钮 */}
diff --git a/server/components/contents/ncm.jsx b/server/components/contents/ncm.jsx
index f4de29e..1f2aefa 100644
--- a/server/components/contents/ncm.jsx
+++ b/server/components/contents/ncm.jsx
@@ -2,57 +2,85 @@ import { useState, useEffect } from 'react';
import { NETEASECLOUD_QUALITY_LIST } from "../../../constants/constant.js";
import { readYamlConfig, updateYamlConfig } from '../../utils/yamlHelper';
import Toast from "../toast.jsx";
+import { ConfigToggle, ConfigInput, ConfigSelect } from '../common/ConfigItem';
+
+// 定义配置项
+const NCM_CONFIG = {
+ textareas: [
+ {
+ key: 'neteaseCookie',
+ label: 'Cookie',
+ placeholder: '请输入网易云Cookie...'
+ }
+ ],
+ inputs: [
+ {
+ key: 'neteaseCloudAPIServer',
+ label: '自建API服务器地址',
+ type: 'text',
+ placeholder: '请输入API服务器地址...'
+ },
+ {
+ key: 'neteaseUserId',
+ label: '用户ID',
+ type: 'text',
+ placeholder: '网易云用户ID',
+ hint: '不要手动更改!'
+ },
+ {
+ key: 'songRequestMaxList',
+ label: '点歌最大列表数',
+ type: 'number'
+ }
+ ],
+ toggles: [
+ { key: 'useLocalNeteaseAPI', label: '使用自建API' },
+ { key: 'useNeteaseSongRequest', label: '开启点歌功能' },
+ { key: 'isSendVocal', label: '发送群语音' }
+ ],
+ selects: [
+ {
+ key: 'neteaseCloudAudioQuality',
+ label: '音频质量',
+ options: NETEASECLOUD_QUALITY_LIST
+ }
+ ]
+};
+
+// 默认配置
+const DEFAULT_CONFIG = {
+ useLocalNeteaseAPI: false,
+ useNeteaseSongRequest: false,
+ isSendVocal: true,
+ songRequestMaxList: 10,
+ neteaseCookie: '',
+ neteaseCloudAPIServer: '',
+ neteaseCloudAudioQuality: 'exhigh',
+ neteaseUserId: ''
+};
export default function Ncm() {
- const [config, setConfig] = useState({
- useLocalNeteaseAPI: false,
- useNeteaseSongRequest: false,
- isSendVocal: true,
- songRequestMaxList: 10,
- neteaseCookie: '',
- neteaseCloudAPIServer: '',
- neteaseCloudAudioQuality: 'exhigh',
- neteaseUserId: ''
- });
-
+ const [config, setConfig] = useState(DEFAULT_CONFIG);
const [loading, setLoading] = useState(false);
- // 读取配置
useEffect(() => {
const loadConfig = async () => {
const yamlConfig = await readYamlConfig();
if (yamlConfig) {
- setConfig({
- useLocalNeteaseAPI: yamlConfig.useLocalNeteaseAPI ?? false,
- useNeteaseSongRequest: yamlConfig.useNeteaseSongRequest ?? false,
- isSendVocal: yamlConfig.isSendVocal ?? true,
- songRequestMaxList: yamlConfig.songRequestMaxList || 10,
- neteaseCookie: yamlConfig.neteaseCookie || '',
- neteaseCloudAPIServer: yamlConfig.neteaseCloudAPIServer || '',
- neteaseCloudAudioQuality: yamlConfig.neteaseCloudAudioQuality || 'exhigh',
- neteaseUserId: yamlConfig.neteaseUserId || ''
+ const newConfig = {};
+ Object.keys(DEFAULT_CONFIG).forEach(key => {
+ newConfig[key] = yamlConfig[key] ?? DEFAULT_CONFIG[key];
});
+ setConfig(newConfig);
}
};
-
loadConfig();
}, []);
- // 保存配置
const handleSave = async () => {
setLoading(true);
try {
- const success = await updateYamlConfig({
- useLocalNeteaseAPI: config.useLocalNeteaseAPI,
- useNeteaseSongRequest: config.useNeteaseSongRequest,
- isSendVocal: config.isSendVocal,
- songRequestMaxList: config.songRequestMaxList,
- neteaseCookie: config.neteaseCookie,
- neteaseCloudAPIServer: config.neteaseCloudAPIServer,
- neteaseCloudAudioQuality: config.neteaseCloudAudioQuality,
- neteaseUserId: config.neteaseUserId
- });
-
+ const success = await updateYamlConfig(config);
if (success) {
document.getElementById('ncm-toast-success').classList.remove('hidden');
setTimeout(() => {
@@ -66,141 +94,79 @@ export default function Ncm() {
}
};
- // 重置配置
- const handleReset = async () => {
- const yamlConfig = await readYamlConfig();
- if (yamlConfig) {
- setConfig({
- useLocalNeteaseAPI: yamlConfig.useLocalNeteaseAPI ?? false,
- useNeteaseSongRequest: yamlConfig.useNeteaseSongRequest ?? false,
- isSendVocal: yamlConfig.isSendVocal ?? true,
- songRequestMaxList: yamlConfig.songRequestMaxList || 10,
- neteaseCookie: yamlConfig.neteaseCookie || '',
- neteaseCloudAPIServer: yamlConfig.neteaseCloudAPIServer || '',
- neteaseCloudAudioQuality: yamlConfig.neteaseCloudAudioQuality || 'exhigh',
- neteaseUserId: yamlConfig.neteaseUserId || ''
- });
- }
+ const handleConfigChange = (key, value) => {
+ setConfig(prev => ({ ...prev, [key]: value }));
};
return (
- {/* 成功提示 */}
网易云音乐配置
- {/* 基础配置部分 */}
基础配置
- {/* 文本输入配置 */}
-
-
+ {/* 文本域配置 */}
+ {NCM_CONFIG.textareas.map(item => (
+
-
-
- setConfig({ ...config, neteaseCloudAPIServer: e.target.value })}
- placeholder="请输入API服务器地址..."
- className="input input-bordered w-full"
- />
-
-
-
- setConfig({ ...config, neteaseUserId: e.target.value })}
- placeholder="网易云用户ID"
- className="input input-bordered w-full"
- />
-
+ ))}
+
+ {/* 输入框配置 */}
+
+ {NCM_CONFIG.inputs.map(item => (
+
+ handleConfigChange(item.key, value)}
+ placeholder={item.placeholder}
+ />
+ {item.hint && (
+
+ {item.hint}
+
+ )}
+
+ ))}
- {/* 开关配置部分 */}
+ {/* 开关配置 */}
- {/* 其他配置 */}
+ {/* 选择框配置 */}
-
-
- setConfig({ ...config, songRequestMaxList: parseInt(e.target.value) })}
- className="input input-bordered"
+ {NCM_CONFIG.selects.map(item => (
+ handleConfigChange(item.key, value)}
+ options={item.options}
/>
-
-
-
-
-
+ ))}
@@ -209,7 +175,7 @@ export default function Ncm() {