refactor(platform): 统一控件 - 收敛下拉选择与按钮输入交互样式

This commit is contained in:
ddcat666
2026-09-25 00:01:09 +08:00
parent 5529c18454
commit a755102b09
61 changed files with 661 additions and 237 deletions

View File

@@ -1,4 +1,4 @@
import { App, Button, Form, Input, Select, Skeleton } from "antd";
import { App, Button, Form, Input, Skeleton } from "antd";
import { Switch } from "@/pages/admin/ui/controls";
import { AlertTriangle, BadgeCheck, ChevronDown, FileText, Globe2, KeyRound, LockKeyhole, RefreshCw, RotateCcw, Save, ShieldCheck, Sparkles, UserPlus, UsersRound } from "lucide-react";
import { useCallback, useEffect, useRef, useState, type ReactNode } from "react";
@@ -8,6 +8,7 @@ import { cn } from "@/lib/utils";
import { useAppearanceStore } from "@/stores/use-appearance-store";
import { getAdminLinuxDOSetting, getAdminRegistrationSetting, updateAdminLinuxDOSetting, updateAdminRegistrationSetting, type LinuxDOSetting, type RegistrationSetting } from "@/services/api/wallet";
import { AdminStatusBadge, configuredSecretText, SettingsSectionCard } from "./admin-ui";
import { Select } from "@/components/ui/base/select";
const DEFAULT_AGREEMENT_TEMPLATE = `一、服务说明与接受
欢迎使用本平台提供的 AI 影视与内容创作服务。在注册或使用本平台各项功能前,请务必仔细阅读并理解本协议。当您勾选同意或点击注册、登录按钮,即表示您已自愿接受本协议所有条款的约束。

View File

@@ -1,5 +1,5 @@
import { useEffect, useRef, useState, type ChangeEvent } from "react";
import { App, Button, Form, Input, Modal, Select } from "antd";
import { App, Button, Form, Input, Modal } from "antd";
import { Switch } from "@/pages/admin/ui/controls";
import type { InputRef } from "antd";
import type { ColumnsType } from "antd/es/table";
@@ -24,6 +24,7 @@ import {
import { resourceFileUrl } from "@/services/api/resources";
import { clearAnnouncementPendingReview, readAnnouncementPendingReview, writeAnnouncementPendingReview, type AnnouncementPendingReview } from "./admin-announcement-safety";
import { AdminDataTable, AdminRowActions, AdminStatusBadge, AdminTableEmpty } from "./admin-ui";
import { Select } from "@/components/ui/base/select";
type AnnouncementFormValues = {
title: string;

View File

@@ -1,4 +1,4 @@
import { App, Button, DatePicker, Form, Input, Modal, Popconfirm, Select, Switch } from "antd";
import { App, Button, DatePicker, Form, Input, Modal, Popconfirm, Switch } from "antd";
import type { ColumnsType } from "antd/es/table";
import { Trash2, Edit3, Search } from "lucide-react";
import dayjs, { type Dayjs } from "dayjs";
@@ -23,6 +23,7 @@ import { BANNER_TITLE_MAX_CHARS, bannerTitleCharCount, bannerTitlePlainText, nor
import { AdminDataTable } from "./admin-ui";
import { BannerNoticeTypeSelector } from "./banner-notice-type-selector";
import { BannerNoticePreview, BannerTitleEditor } from "./banner-title-editor";
import { Select } from "@/components/ui/base/select";
type FormValues = {
noticeType: BannerNoticeType;

View File

@@ -1,10 +1,11 @@
import { App, Button, Dropdown, Select, Table } from "antd";
import { App, Button, Dropdown, Table } from "antd";
import type { ButtonProps, MenuProps, TableProps } from "antd";
import { saveAs } from "file-saver";
import { CheckSquare2, ChevronDown, ChevronLeft, ChevronRight, Download, ListFilter, RotateCcw, SearchX, X } from "lucide-react";
import { useEffect, useState, type ReactNode } from "react";
import { cn } from "@/lib/utils";
import { Select } from "@/components/ui/base/select";
export const configuredSecretText = "已配置 · 留空不改";

View File

@@ -1,4 +1,4 @@
import { App, Button, Input, Select, Space, Tag, Tooltip } from "antd";
import { App, Button, Input, Space, Tag, Tooltip } from "antd";
import type { ColumnsType } from "antd/es/table";
import { RefreshCw, Trash2 } from "lucide-react";
import { useCallback, useEffect, useRef, useState } from "react";
@@ -7,6 +7,7 @@ import { useDebouncedValue } from "@/hooks/use-debounced-value";
import { agentLessonCategoryLabel, deleteAdminAgentLesson, listAdminAgentLessons, type AdminAgentLesson } from "@/services/api/admin-agent-lessons";
import { listAdminUsers, type AdminUser } from "@/services/api/auth";
import { AdminDataTable, AdminStatusBadge, AdminTableEmpty } from "./admin-ui";
import { Select } from "@/components/ui/base/select";
function authorLabel(record: AdminAgentLesson) {
if (record.authorDisplayName && record.authorUsername) return `${record.authorDisplayName}(${record.authorUsername})`;

View File

@@ -1,4 +1,4 @@
import { Alert, App, Button, DatePicker, Select, Tabs, Tag } from "antd";
import { Alert, App, Button, DatePicker, Tabs, Tag } from "antd";
import { Tooltip } from "@/pages/admin/ui/controls";
import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react";
@@ -11,6 +11,7 @@ import { useSearchParams } from "react-router";
import { ListToolbar, PaginationBar, AdminDataTable, AdminExportButton, AdminFilterChip, AdminStatusBadge, AdminTableEmpty, type AdminStatusTone } from "./admin-ui";
import { exportAdminAnalytics, getAdminAnalytics, listAdminUsers, type AdminReferenceData, type AdminAnalytics, type AnalyticsFilters } from "@/services/api/auth";
import { analyticsFinanceColumns, formatCredits, formatFinanceCost, formatFinanceMargin } from "./analytics-finance";
import { Select } from "@/components/ui/base/select";
type Props = {
users: AdminReferenceData["users"];

View File

@@ -1,6 +1,6 @@
import type { Editor } from "@tiptap/core";
import { EditorContent, useEditor } from "@tiptap/react";
import { Button, ColorPicker, Select, Tooltip } from "antd";
import { Button, ColorPicker, Tooltip } from "antd";
import { Eraser, X } from "lucide-react";
import { useEffect, useRef, useState } from "react";
@@ -11,6 +11,7 @@ import {
} from "@/components/layout/banner-announcement-content";
import { readBannerNoticeSurface, bannerNoticeTypeLabel } from "@/lib/announcements/banner-notice";
import { BannerNoticeEmojiPopover } from "./banner-notice-emoji-picker";
import { Select } from "@/components/ui/base/select";
import {
BANNER_TITLE_DEFAULT_FONT_SIZE,
BANNER_TITLE_DEFAULT_FONT_WEIGHT,

View File

@@ -1,5 +1,5 @@
import { useEffect, useState } from "react";
import { App, Button, Checkbox, Input, Modal, Popconfirm, Select, Space } from "antd";
import { App, Button, Checkbox, Input, Modal, Popconfirm, Space } from "antd";
import type { ColumnsType } from "antd/es/table";
import { Pencil, Plus, RefreshCw, Search, Trash2 } from "lucide-react";
@@ -14,6 +14,7 @@ import { AdminBatchBar, AdminDataTable, AdminFilterChip, AdminStatusBadge, Admin
import { ChannelOrderDialog } from "./channel-order-dialog";
import { ChannelModelCostSummary } from "./channel-model-cost-summary";
import { ChannelModelRepriceDialog } from "./channel-model-reprice-dialog";
import { Select } from "@/components/ui/base/select";
export function ChannelModelManager({ channel, onChanged }: { channel: ModelChannel; onChanged: () => void | Promise<void> }) {
const { message, modal } = App.useApp();

View File

@@ -1,4 +1,4 @@
import { Alert, Button, Form, Input, InputNumber, Segmented, Select, Switch, type FormInstance } from "antd";
import { Alert, Button, Form, Input, InputNumber, Segmented, Switch, type FormInstance } from "antd";
import { Trash2 } from "lucide-react";
import type { ModelCapabilityConfig } from "@/lib/model-capabilities";
import { modelProtocolSupportsTokenBilling, type ModelProtocol } from "@/lib/model-protocols";
@@ -6,6 +6,7 @@ import type { ModelCapabilityChoice as EditableCapability } from "@/components/m
import type { ChannelModelFormValues as FormValues } from "./channel-model-editor-form";
import { normalizeUpstreamModelKey } from "./channel-model-price-tier-form";
import { CreditCostFields } from "./credit-cost-fields";
import { Select } from "@/components/ui/base/select";
export function PriceTierFields({
index,

View File

@@ -1,9 +1,10 @@
import { useState } from "react";
import { Alert, App, Button, InputNumber, Select, Table } from "antd";
import { Alert, App, Button, InputNumber, Table } from "antd";
import { AdminModal } from "@/pages/admin/ui/overlays";
import { repriceAdminChannelModels, type ChannelModel } from "@/services/api/wallet";
import { specificationLabel } from "./channel-model-cost-summary";
import { formatModelMargin, formatModelPrice, modelRepricePayload, modelRepriceRows, parseSaleInput, previewModelRepricing, type ModelRepriceRow } from "./channel-model-pricing";
import { Select } from "@/components/ui/base/select";
export function ChannelModelRepriceDialog({ channelId, channelName, items, onClose, onSaved }: { channelId: string; channelName: string; items: ChannelModel[]; onClose: () => void; onSaved: () => Promise<void> }) {
const { message } = App.useApp();

View File

@@ -1,7 +1,8 @@
import { Button, Form, Input, Select } from "antd";
import { Button, Form, Input } from "antd";
import { Plus, Trash2 } from "lucide-react";
import { ModelTags } from "@/components/model-tags";
import { modelTagColors, type ModelTag } from "@/lib/model-tags";
import { Select } from "@/components/ui/base/select";
export function ChannelModelTagsEditor() {
const form = Form.useFormInstance();

View File

@@ -1,8 +1,9 @@
import { App, Button, InputNumber, Modal, Select, Spin } from "antd";
import { App, Button, InputNumber, Modal, Spin } from "antd";
import { ArrowDown, ArrowUp, GripVertical, ListOrdered } from "lucide-react";
import { useRef, useState } from "react";
import { AdminEmpty } from "@/pages/admin/components/admin-ui";
import { getChannelOrder, saveChannelOrder, type ChannelOrderItem } from "@/services/api/channel-order";
import { Select } from "@/components/ui/base/select";
export function moveOrderItem<T extends { id: string }>(items: T[], id: string, target: number): T[] {
const from = items.findIndex((item) => item.id === id);

View File

@@ -1,5 +1,5 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { App, Button, Drawer, Form, Input, InputNumber, Modal, Select } from "antd";
import { App, Button, Drawer, Form, Input, InputNumber, Modal } from "antd";
import type { ColumnsType } from "antd/es/table";
import { BadgeCheck, Coins, Plus, RefreshCw, Search, Trash2, Undo2 } from "lucide-react";
@@ -10,6 +10,7 @@ import { listAdminUsers, type AdminReferenceData, type AdminUser } from "@/servi
import { adjustAdminUserCredits, getAdminCreditPolicy, listAdminBillingOrders, resolveAdminBillingOrder, resolveAdminBillingOrders, updateAdminCreditPolicy, type BillingOrder } from "@/services/api/wallet";
import { AdminBatchBar, AdminDataTable, AdminRowActions, AdminStatusBadge, AdminTableEmpty } from "./admin-ui";
import { Select } from "@/components/ui/base/select";
export type CreditOperation = "policy" | "adjustment" | null;

View File

@@ -1,5 +1,5 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { App, Button, Drawer, Form, Input, InputNumber, Modal, Popconfirm, Select, Space } from "antd";
import { App, Button, Drawer, Form, Input, InputNumber, Modal, Popconfirm, Space } from "antd";
import type { ColumnsType } from "antd/es/table";
import { Ban, Copy, Eye, KeyRound, RefreshCw, Search, TicketCheck } from "lucide-react";
@@ -9,6 +9,7 @@ import { useDebouncedValue } from "@/hooks/use-debounced-value";
import { ApiError } from "@/services/api/request";
import { createAdminRedeemBatch, disableAdminRedeemBatch, disableAdminRedeemCode, listAdminRedeemBatchCodes, listAdminRedeemBatches, type AdminRedeemCode, type RedeemBatch } from "@/services/api/wallet";
import { AdminDataTable, AdminExportButton, AdminRowActions, AdminStatusBadge, AdminTableEmpty, type AdminStatusTone } from "./admin-ui";
import { Select } from "@/components/ui/base/select";
type RedeemFormValues = { amount?: number | null; count?: number | null; note?: string; expiresAt?: string };
type PendingRedeemBatch = {

View File

@@ -1,4 +1,4 @@
import { App, Button, Input, Modal, Select } from "antd";
import { App, Button, Input, Modal } from "antd";
import type { ColumnsType } from "antd/es/table";
import { Download, Eye, Search, Trash2 } from "lucide-react";
import { saveAs } from "file-saver";
@@ -9,6 +9,7 @@ import { PaginationBar } from "@/pages/admin/components/admin-ui";
import { useDebouncedValue } from "@/hooks/use-debounced-value";
import { adminResourceFileUrl, deleteAdminResources, downloadAdminResource, getAdminStorageStats, listAdminResources, type AdminStorageResource, type AdminStorageStats } from "@/services/api/admin-storage";
import { AdminBatchBar, AdminDataTable, AdminFilterChip, AdminStatTile, AdminStatusBadge, AdminTableEmpty } from "./admin-ui";
import { Select } from "@/components/ui/base/select";
const pageSizes = [20, 50, 100];