From 3f96c9c6502243b06efd4bb34a189e72e3a5557c Mon Sep 17 00:00:00 2001
From: yearning <10538594+wangweifeng1999@user.noreply.gitee.com>
Date: 星期一, 28 九月 2026 19:24:55 +0800
Subject: [PATCH] 复制项目

---
 frontend/src/pages/AdminSystemSettingsPage.tsx |   91 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 91 insertions(+), 0 deletions(-)

diff --git a/frontend/src/pages/AdminSystemSettingsPage.tsx b/frontend/src/pages/AdminSystemSettingsPage.tsx
new file mode 100644
index 0000000..33f318c
--- /dev/null
+++ b/frontend/src/pages/AdminSystemSettingsPage.tsx
@@ -0,0 +1,91 @@
+import { useEffect, useState } from "react";
+import { Button, Card, Form, Input, Upload, message, Image, Space } from "antd";
+import { UploadOutlined } from "@ant-design/icons";
+import { api } from "../api";
+import { logoSrc, useSystemSettings } from "../systemSettings";
+
+export default function AdminSystemSettingsPage() {
+  const { settings, refresh, logoCacheKey } = useSystemSettings();
+  const [form] = Form.useForm<{ system_name: string }>();
+  const [saving, setSaving] = useState(false);
+
+  useEffect(() => {
+    form.setFieldsValue({ system_name: settings.system_name });
+  }, [settings.system_name, form]);
+
+  const logo = logoSrc(settings.logo_url, logoCacheKey);
+
+  return (
+    <Card title="绯荤粺璁剧疆">
+      <Form
+        form={form}
+        layout="vertical"
+        style={{ maxWidth: 480 }}
+        onFinish={async (v) => {
+          setSaving(true);
+          try {
+            await api.put("/api/admin/settings", { system_name: v.system_name });
+            message.success("宸蹭繚瀛�");
+            await refresh();
+          } catch (e: unknown) {
+            const msg =
+              (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail || "淇濆瓨澶辫触";
+            message.error(msg);
+          } finally {
+            setSaving(false);
+          }
+        }}
+      >
+        <Form.Item name="system_name" label="绯荤粺鍚嶇О" rules={[{ required: true, max: 128 }]}>
+          <Input placeholder="鏄剧ず鍦ㄩ《鏍忋�佺櫥褰曢〉涓庢祻瑙堝櫒鏍囬" />
+        </Form.Item>
+        <Button type="primary" htmlType="submit" loading={saving}>淇濆瓨鍚嶇О</Button>
+      </Form>
+
+      <Card type="inner" title="绯荤粺 Logo" style={{ marginTop: 24, maxWidth: 480 }}>
+        {logo && (
+          <div style={{ marginBottom: 16 }}>
+            <Image src={logo} alt="Logo" style={{ maxHeight: 64, maxWidth: 200, objectFit: "contain" }} />
+          </div>
+        )}
+        <Space wrap>
+          <Upload
+            accept=".png,.jpg,.jpeg,.webp,.svg,.gif"
+            showUploadList={false}
+            beforeUpload={async (file) => {
+              const fd = new FormData();
+              fd.append("file", file);
+              try {
+                await api.post("/api/admin/settings/logo", fd);
+                message.success("Logo 宸叉洿鏂�");
+                await refresh();
+              } catch (e: unknown) {
+                const msg =
+                  (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail || "涓婁紶澶辫触";
+                message.error(msg);
+              }
+              return false;
+            }}
+          >
+            <Button icon={<UploadOutlined />}>涓婁紶 Logo</Button>
+          </Upload>
+          {logo && (
+            <Button
+              danger
+              onClick={async () => {
+                await api.delete("/api/admin/settings/logo");
+                message.success("宸茬Щ闄� Logo");
+                await refresh();
+              }}
+            >
+              绉婚櫎 Logo
+            </Button>
+          )}
+        </Space>
+        <p style={{ color: "#8c8c8c", fontSize: 12, marginTop: 12 }}>
+          寤鸿閫忔槑搴� PNG/WebP锛岄珮搴︾害 32鈥�48px锛屾渶澶� 2MB銆�
+        </p>
+      </Card>
+    </Card>
+  );
+}

--
Gitblit v1.8.0