完善提示词管理和配置管理的增删改查

This commit is contained in:
2025-04-09 21:48:28 +08:00
parent fda6515891
commit 4e43df00c0
14 changed files with 1100 additions and 484 deletions
+80 -86
View File
@@ -40,13 +40,13 @@ export const EXTENDED_ENVIRONMENT_LABELS: Record<string, string> = {
};
interface ConfigData {
id: string;
id: number;
name: string;
type: string;
environment: string;
is_active: boolean;
config: Record<string, unknown>;
remarks?: string;
remark?: string;
}
interface LoaderData {
@@ -76,11 +76,11 @@ export async function loader({ request }: LoaderFunctionArgs) {
config = detailResponse.data;
}
return json<LoaderData>({
return Response.json({
config,
isEdit: !!config,
types: optionsResponse.data.types,
environments: optionsResponse.data.environments
types: optionsResponse.data?.types || [],
environments: optionsResponse.data?.environments || []
});
}
@@ -103,7 +103,7 @@ export async function action({ request }: ActionFunctionArgs) {
const environment = formData.get("environment") as string;
const config = formData.get("config") as string;
const is_active = formData.get("is_active") === "true";
const remarks = formData.get("remarks") as string;
const remark = formData.get("remark") as string;
const errors: ActionData["errors"] = {};
@@ -131,7 +131,7 @@ export async function action({ request }: ActionFunctionArgs) {
}
if (Object.keys(errors).length > 0) {
return json<ActionData>({ errors });
return Response.json({ errors });
}
try {
@@ -141,7 +141,7 @@ export async function action({ request }: ActionFunctionArgs) {
environment,
config: JSON.parse(config),
is_active,
remarks
remark
};
if (id) {
@@ -161,7 +161,7 @@ export async function action({ request }: ActionFunctionArgs) {
return redirect("/config-lists");
} catch (error) {
console.error("保存配置失败:", error);
return json<ActionData>({
return Response.json({
success: false,
errors: {
general: "保存配置失败,请稍后重试"
@@ -170,18 +170,17 @@ export async function action({ request }: ActionFunctionArgs) {
}
}
// JSON模板数据
const JSON_TEMPLATES = {
// 配置模板常量
const CONFIG_TEMPLATES = {
database: {
database: {
host: "localhost",
port: 5432,
username: "db_user",
password: "******",
name: "app_database",
pool_size: 10,
timeout: 5000,
ssl: false
host: "localhost",
port: 5432,
database: "mydb",
username: "admin",
password: "******",
pool: {
min: 2,
max: 10
}
},
file: {
@@ -220,6 +219,9 @@ export default function ConfigNew() {
const [selectedModule, setSelectedModule] = useState<string>("");
const [selectedEnvironment, setSelectedEnvironment] = useState<string>("");
// 在 ConfigNew 组件中添加状态来跟踪当前选中的模板
const [selectedTemplate, setSelectedTemplate] = useState<keyof typeof CONFIG_TEMPLATES | null>(null);
useEffect(() => {
// 初始化配置数据
if (config) {
@@ -268,6 +270,7 @@ export default function ConfigNew() {
// 格式化JSON
const handleFormatJson = () => {
if (configDataValue.trim() === "") return;
try {
@@ -283,50 +286,6 @@ export default function ConfigNew() {
}
};
// 加载JSON模板
const handleLoadTemplate = (type: keyof typeof JSON_TEMPLATES) => {
const template = JSON_TEMPLATES[type];
setConfigDataValue(JSON.stringify(template, null, 2));
setJsonError(null);
};
// 显示JSON语法高亮
const renderJsonWithSyntaxHighlight = (json: string) => {
try {
// 如果是空字符串,直接返回
if (!json.trim()) return "";
// 解析并格式化JSON
const parsed = JSON.parse(json);
const formatted = JSON.stringify(parsed, null, 2);
// 添加语法高亮
return formatted
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)/g, (match) => {
let cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
match = match.replace(':', '');
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return `<span class="code-json ${cls}">${match}</span>`;
});
} catch (e) {
// 如果解析失败,返回原始JSON
return json;
}
};
return (
<div className="config-new-page">
<div className="flex justify-between items-center mb-4">
@@ -342,6 +301,12 @@ export default function ConfigNew() {
</Button>
</div>
</div>
{actionData?.errors?.general && (
<div className="mb-4 w-full">
<div className="error-message general-error">{actionData.errors.general}</div>
</div>
)}
<Card className="config-form-card">
<Form method="post" id="configForm" className="config-form">
@@ -412,7 +377,7 @@ export default function ConfigNew() {
<div className="error-message">{actionData.errors.type}</div>
)}
<div className="tag-buttons mt-2">
{types.map(type => (
{types.map((type: string) => (
<button
key={type}
type="button"
@@ -449,7 +414,7 @@ export default function ConfigNew() {
<div className="error-message">{actionData.errors.environment}</div>
)}
<div className="tag-buttons mt-2">
{environments.map(env => (
{environments.map((env: string) => (
<button
key={env}
type="button"
@@ -484,7 +449,10 @@ export default function ConfigNew() {
<Button
type="default"
size="small"
onClick={handleFormatJson}
onClick={(e) => {
e.preventDefault();
handleFormatJson();
}}
>
<i className="ri-braces-line mr-1"></i> JSON
</Button>
@@ -501,32 +469,62 @@ export default function ConfigNew() {
<div className="example-title"></div>
</div>
<div className="example-content">
<pre
className="example-pre"
dangerouslySetInnerHTML={{ __html: renderJsonWithSyntaxHighlight(exampleJsonValue) }}
/>
<div className="json-display">
{exampleJsonValue.split('\n').map((line, index) => (
<div key={index} className="json-line">
{line.split('').map((char, charIndex) => {
let className = 'json-char';
if (char === '{' || char === '}') className += ' json-brace';
if (char === '[' || char === ']') className += ' json-bracket';
if (char === '"') className += ' json-quote';
if (char === ':') className += ' json-colon';
if (char === ',') className += ' json-comma';
return (
<span key={charIndex} className={className}>
{char}
</span>
);
})}
</div>
))}
</div>
</div>
<div className="example-footer">
<div className="text-sm font-medium mb-2">:</div>
<div className="flex flex-wrap gap-2">
<Button
type="default"
type="default"
size="small"
onClick={() => handleLoadTemplate('database')}
className={`${selectedTemplate === 'database' ? 'border-[#00684a] text-[#00684a] focus:ring-0' : ''}`}
onClick={(e) => {
e.preventDefault();
setExampleJsonValue(JSON.stringify(CONFIG_TEMPLATES.database, null, 2));
setSelectedTemplate('database');
}}
>
</Button>
<Button
type="default"
type="default"
size="small"
onClick={() => handleLoadTemplate('file')}
className={`${selectedTemplate === 'file' ? 'border-[#00684a] text-[#00684a] focus:ring-0' : ''}`}
onClick={(e) => {
e.preventDefault();
setExampleJsonValue(JSON.stringify(CONFIG_TEMPLATES.file, null, 2));
setSelectedTemplate('file');
}}
>
</Button>
<Button
type="default"
type="default"
size="small"
onClick={() => handleLoadTemplate('ai')}
className={`${selectedTemplate === 'ai' ? 'border-[#00684a] text-[#00684a] focus:ring-0' : ''}`}
onClick={(e) => {
e.preventDefault();
setExampleJsonValue(JSON.stringify(CONFIG_TEMPLATES.ai, null, 2));
setSelectedTemplate('ai');
}}
>
AI服务配置
</Button>
@@ -542,12 +540,12 @@ export default function ConfigNew() {
{/* 备注 */}
<div className="form-group">
<label htmlFor="remarks" className="form-label"></label>
<label htmlFor="remark" className="form-label"></label>
<textarea
id="remarks"
name="remarks"
id="remark"
name="remark"
className="form-textarea"
defaultValue={config?.remarks || ''}
defaultValue={config?.remark || ''}
rows={2}
placeholder="请输入配置备注信息"
/>
@@ -556,11 +554,7 @@ export default function ConfigNew() {
</div>
</div>
{actionData?.errors?.general && (
<div className="form-row">
<div className="error-message general-error">{actionData.errors.general}</div>
</div>
)}
</Form>
</Card>
</div>