import { type MetaFunction, type LoaderFunctionArgs, type ActionFunctionArgs } from "@remix-run/node"; import { useLoaderData, useSearchParams, useFetcher, Link } from "@remix-run/react"; import { useState, useEffect } from "react"; import { Button } from "~/components/ui/Button"; import { Card } from "~/components/ui/Card"; import { FilterPanel, FilterSelect, SearchFilter } from "~/components/ui/FilterPanel"; import { Modal } from "~/components/ui/Modal"; import { Pagination } from "~/components/ui/Pagination"; import { Table } from "~/components/ui/Table"; import { Tag } from "~/components/ui/Tag"; import { getConfigLists, getConfigOptions, updateConfigStatus, type ConfigItem } from "~/api/system_setting/config-lists"; import configListsStyles from "~/styles/pages/config-lists_index.css?url"; import { toastService } from "~/components/ui/Toast"; import { messageService } from "~/components/ui/MessageModal"; export const links = () => [ { rel: "stylesheet", href: configListsStyles } ]; export const meta: MetaFunction = () => { return [ { title: "系统配置管理 - 中国烟草AI合同及卷宗审核系统" }, { name: "description", content: "管理系统配置,包括数据库、文件存储、AI引擎等配置项" }, { name: "keywords", content: "系统配置,配置管理,中国烟草,参数设置" } ]; }; // 配置环境枚举 export enum ConfigEnvironment { DEV = 'dev', TEST = 'test', PROD = 'prod' } // 配置模块枚举 export enum ConfigModule { SYSTEM = 'system', AUTH = 'auth', FILE = 'file', AI = 'ai', NOTIFICATION = 'notification' } // 环境标签映射 export const ENVIRONMENT_LABELS: Record = { [ConfigEnvironment.DEV]: '开发环境', [ConfigEnvironment.TEST]: '测试环境', [ConfigEnvironment.PROD]: '生产环境' }; // 模块标签映射 export const MODULE_LABELS: Record = { [ConfigModule.SYSTEM]: '系统', [ConfigModule.AUTH]: '认证', [ConfigModule.FILE]: '文件', [ConfigModule.AI]: 'AI配置', [ConfigModule.NOTIFICATION]: '通知' }; // 操作响应 interface ActionResponse { result: boolean; message: string; } export async function loader({ request }: LoaderFunctionArgs) { const url = new URL(request.url); const name = url.searchParams.get("name") || ""; const type = url.searchParams.get("type") || ""; const environment = url.searchParams.get("environment") || ""; const is_active = url.searchParams.get("is_active") ? url.searchParams.get("is_active") === "true" : undefined; const currentPage = parseInt(url.searchParams.get("page") || "1", 10); const pageSize = parseInt(url.searchParams.get("pageSize") || "10", 10); try { // 获取配置列表 const configsResponse = await getConfigLists({ name, type, environment, is_active, page: currentPage, pageSize }); if (configsResponse.error || !configsResponse.data) { throw new Error(configsResponse.error || "获取配置列表失败"); } // 获取配置选项 const optionsResponse = await getConfigOptions(); if (optionsResponse.error || !optionsResponse.data) { throw new Error(optionsResponse.error || "获取配置选项失败"); } return Response.json({ configs: configsResponse.data, totalCount: configsResponse.total, currentPage, pageSize, totalPages: Math.ceil(configsResponse.total / pageSize), types: optionsResponse.data.types, environments: optionsResponse.data.environments }, { headers: { "Cache-Control": "max-age=60, s-maxage=180" } }); } catch (error) { console.error('加载配置列表失败:', error); return Response.json({ error: error || '加载配置列表失败', status: 500 }, { status: 500 }); } } export async function action({ request }: ActionFunctionArgs) { const formData = await request.formData(); const _action = formData.get('_action'); const configId = formData.get('configId'); if (!configId) { return Response.json({ result: false, message: "缺少配置ID" }, { status: 400 }); } // 进行更新启用和禁用的状态 try { if (_action === 'toggleStatus') { const is_active = formData.get('is_active') === 'true'; const response = await updateConfigStatus(parseInt(configId as string), is_active); if (response.error) { return Response.json({ result: false, message: response.error }, { status: 500 }); } return Response.json({ result: true, message: is_active ? '启用成功' : '禁用成功' }); } return Response.json({ result: false, message: "未知操作" }, { status: 400 }); } catch (error) { console.error('操作配置失败:', error); return Response.json({ result: false, message: error || "操作失败" }, { status: 500 }); } } export default function ConfigListsIndex() { const { configs, totalCount, currentPage, pageSize, types, environments, error } = useLoaderData(); const [searchParams, setSearchParams] = useSearchParams(); const fetcher = useFetcher(); const [showDetailModal, setShowDetailModal] = useState(false); const [selectedConfig, setSelectedConfig] = useState(null); // 处理loader错误 useEffect(() => { if(error) { toastService.error(error); } }, [error]); // 使用useEffect监听fetcher状态变化并显示Toast useEffect(() => { if(fetcher.state === 'idle' && fetcher.data) { if(fetcher.data.result) { toastService.success(fetcher.data.message); } else if (fetcher.data.message) { toastService.error(fetcher.data.message); } } }, [fetcher.state,fetcher.data]); // 处理筛选条件变化 const handleFilterChange = (e: React.ChangeEvent) => { const { name, value } = e.target; const newParams = new URLSearchParams(searchParams); if (value) { newParams.set(name, value); } else { newParams.delete(name); } // 切换筛选条件时,重置到第一页 newParams.set('page', '1'); setSearchParams(newParams); }; // 搜索配置名称 const handleConfigNameSearch = (value: string) => { const newParams = new URLSearchParams(searchParams); value ? newParams.set('name', value) : newParams.delete('name'); // 搜索时,重置到第一页 newParams.set('page', '1'); setSearchParams(newParams); }; // 处理启用和禁用状态 const handleToggleStatus = (config: ConfigItem) => { messageService.show({ title: '提示', message: `确定要${config.is_active ? '禁用' : '启用'}该配置吗?`, type: config.is_active ? 'warning' : 'success', confirmText: '确定', cancelText: '取消', onConfirm: () => { const formData = new FormData(); formData.append('_action', 'toggleStatus'); formData.append('configId', config.id.toString()); formData.append('is_active', String(!config.is_active)); fetcher.submit(formData, { method: 'post' }); } }); }; // 处理查看详情 const handleViewDetail = (config: ConfigItem) => { setSelectedConfig(config); setShowDetailModal(true); }; // 处理分页 const handlePageChange = (page: number) => { const newParams = new URLSearchParams(searchParams); newParams.set('page', page.toString()); setSearchParams(newParams); }; // 处理每页条数变更 const handlePageSizeChange = (size: number) => { const newParams = new URLSearchParams(searchParams); newParams.set('pageSize', size.toString()); newParams.set('page', '1'); // 更改每页条数时,重置到第一页 setSearchParams(newParams); }; // 处理重置筛选 const handleReset = () => { const nameInput = document.querySelector('input[placeholder="请输入配置名称"]') as HTMLInputElement; if(nameInput) nameInput.value = '' setSearchParams(new URLSearchParams()); }; // 关闭详情模态框 const closeDetailModal = () => { setShowDetailModal(false); setSelectedConfig(null); }; // 定义表格列配置 const columns = [ { title: "配置名称", dataIndex: "name" as keyof ConfigItem, key: "name", width: "20%" }, { title: "所属模块", key: "type", width: "10%", render: (_: unknown, record: ConfigItem) => record.type }, { title: "环境", key: "environment", width: "15%", render: (_: unknown, record: ConfigItem) => { return ( {record.environment} ); } }, { title: "状态", key: "is_active", width: "15%", render: (_: unknown, record: ConfigItem) => ( {record.is_active ? '已启用' : '已禁用'} ) }, { title: "最后更新时间", dataIndex: "updated_at" as keyof ConfigItem, key: "updated_at", width: "15%" }, { title: "操作", key: "operation", width: "25%", render: (_: unknown, record: ConfigItem) => (
编辑
) } ]; return (
{/* 页面头部 */}

系统配置管理

{/* 搜索区域 */} {/* */} } noActionDivider={true} > ({ value: type, label: type }))]} onChange={handleFilterChange} className="flex-1 min-w-[200px]" /> ({ value: env, label: env }))]} onChange={handleFilterChange} className="flex-1 min-w-[200px]" /> {/* 表格区域 */} {/* 分页区域 */} {totalCount > 0 && ( )} {/* 配置详情模态框 */} {showDetailModal && selectedConfig && ( 关闭 } >
配置名称
{selectedConfig.name}
所属模块
{selectedConfig.type}
环境
{selectedConfig.environment}
状态
{selectedConfig.is_active ? '已启用' : '已禁用'}
配置数据
                {JSON.stringify(selectedConfig.config, null, 2)}
              
创建时间
{selectedConfig.created_at}
更新时间
{selectedConfig.updated_at}
)} ); } // 错误边界 export function ErrorBoundary() { return (

出错了

加载配置列表时发生错误。请稍后再试,或联系管理员。

); }