正则相关

This commit is contained in:
2026-05-06 00:40:18 +08:00
parent f843a74715
commit 9faccc2c03
32 changed files with 4814 additions and 346 deletions

View File

@@ -487,3 +487,181 @@
font-size: 13px;
margin-bottom: 16px;
}
/* ==================== 正则规则列表样式 ==================== */
.regex-rules-list {
display: flex;
flex-direction: column;
gap: 8px;
max-height: 400px;
overflow-y: auto;
}
.regex-rule-item {
display: flex;
align-items: center;
gap: 12px;
padding: 12px;
background: var(--color-bg-tertiary);
border-radius: 8px;
transition: all 0.2s;
}
.regex-rule-item:hover {
background: var(--color-bg-hover);
}
.regex-rule-drag {
cursor: grab;
color: var(--color-text-muted);
font-size: 16px;
user-select: none;
}
.regex-rule-info {
flex: 1;
display: flex;
align-items: center;
gap: 8px;
min-width: 0;
}
.regex-rule-name {
font-size: 14px;
font-weight: 500;
color: var(--color-text-primary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.regex-badge {
padding: 2px 6px;
border-radius: 4px;
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
white-space: nowrap;
flex-shrink: 0;
}
.regex-badge.disabled {
background: var(--color-error);
color: white;
}
.regex-badge.prompt {
background: var(--color-info);
color: white;
}
.regex-badge.markdown {
/* 注意Markdown 徽章使用固定紫色,作为功能标识色 */
background: #8844ff;
color: white;
}
.regex-rule-actions {
display: flex;
align-items: center;
gap: 8px;
flex-shrink: 0;
}
/* 开关按钮 */
.toggle-switch {
position: relative;
width: 44px;
height: 24px;
display: inline-block;
}
.toggle-switch input {
opacity: 0;
width: 0;
height: 0;
}
.toggle-slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--color-border);
transition: 0.3s;
border-radius: 24px;
}
.toggle-slider:before {
position: absolute;
content: "";
height: 18px;
width: 18px;
left: 3px;
bottom: 3px;
background-color: white;
transition: 0.3s;
border-radius: 50%;
}
.toggle-switch input:checked + .toggle-slider {
background-color: var(--color-accent);
}
.toggle-switch input:checked + .toggle-slider:before {
transform: translateX(20px);
}
.icon-btn-sm {
padding: 4px 6px;
background: transparent;
border: none;
color: var(--color-text-muted);
cursor: pointer;
border-radius: 4px;
font-size: 12px;
transition: all 0.2s;
}
.icon-btn-sm:hover {
background: var(--color-bg-hover);
color: var(--color-text-primary);
}
.btn-icon {
padding: 6px 10px;
background: var(--color-bg-tertiary);
border: 1px solid var(--color-border);
border-radius: 4px;
color: var(--color-text-secondary);
cursor: pointer;
font-size: 14px;
transition: all 0.2s;
}
.btn-icon:hover {
background: var(--color-bg-hover);
color: var(--color-text-primary);
border-color: var(--color-text-muted);
}
.btn-add-rule {
width: 100%;
padding: 12px;
background: var(--color-bg-tertiary);
border: 2px dashed var(--color-border);
border-radius: 8px;
color: var(--color-text-secondary);
cursor: pointer;
font-size: 14px;
transition: all 0.2s;
}
.btn-add-rule:hover {
background: var(--color-bg-hover);
border-color: var(--color-text-muted);
color: var(--color-text-primary);
}

View File

@@ -5,6 +5,7 @@ import useUserStore from '../../Store/UserSlice'; // ✅ 新增 - 用户角色
import useWorldBookStore from '../../Store/SideBarLeft/WorldBookSlice';
import useApiConfigStore from '../../Store/SideBarLeft/ApiConfigSlice';
import ThemeToggle from './items/ThemeToggle';
import RegexPanel from '../SideBarLeft/tabs/Regex/RegexPanel'; // ✅ 新增:导入正则管理组件
import './TopBar.css';
const Toolbar = () => {
@@ -372,59 +373,13 @@ const Toolbar = () => {
</div>
<div className="setting-section" style={{ marginTop: '20px', paddingTop: '20px', borderTop: '1px solid var(--border-color)' }}>
<h4>则规则管理</h4>
<div style={{ marginBottom: '16px' }}>
<code className="settings-code">
data/regex/
</code>
<ul className="settings-file-list">
<li>📁 global/ - 全局规则</li>
<li>📁 characters/ - 角色卡规则</li>
<li>📁 presets/ - 预设规则</li>
</ul>
</div>
<h4>📝 正则管理</h4>
<p className="settings-hint" style={{ marginBottom: '16px' }}>
管理全局和预设的正则规则
</p>
<div style={{ marginBottom: '16px' }}>
<label style={{ display: 'block', marginBottom: '8px', fontSize: '14px', fontWeight: '500', color: 'var(--color-text-primary)' }}>导入规则文件</label>
<input
type="file"
accept=".json"
onChange={async (e) => {
const file = e.target.files[0];
if (!file) return;
const formData = new FormData();
formData.append('file', file);
try {
const response = await fetch('/api/regex/import', {
method: 'POST',
body: formData
});
const data = await response.json();
if (data.success) {
showSettingsMessage('success', data.message);
} else {
showSettingsMessage('error', '导入失败');
}
} catch (error) {
showSettingsMessage('error', '导入失败');
}
}}
className="settings-input"
/>
<small className="settings-hint">
支持 SillyTavern 格式的规则文件
</small>
</div>
<button
className="btn-primary"
onClick={() => window.open('/api/regex/export/global', '_blank')}
>
导出全局规则
</button>
{/* ✅ 使用 RegexPanel 组件 */}
<RegexPanel />
</div>
<div style={{ marginTop: '20px' }}>