webadmin端增加版本号和部署功能

This commit is contained in:
2026-07-12 13:52:22 +08:00
parent 63af3321dd
commit d271ac5b13
16 changed files with 329 additions and 5 deletions
+16
View File
@@ -72,6 +72,22 @@ export type DashboardStats = {
ordersByStatus: Array<{ status: string; count: number }>;
};
export type SystemVersion = {
id: string;
gitTag: string | null;
commitId: string;
commitMessage: string;
branch: string | null;
deployedBy: string | null;
deployedAt: string;
};
export type DeployTriggerResult = {
accepted: boolean;
started?: boolean;
message: string;
};
export type AdminUserRow = {
id: string;
userNo: string;
+99 -4
View File
@@ -1,6 +1,16 @@
import { useEffect, useState } from 'react';
import { Card, Col, Row, Statistic, Table, Typography } from 'antd';
import { request, type DashboardStats } from '../lib/api';
import { useCallback, useEffect, useState } from 'react';
import {
Button, Card, Col, Descriptions, Modal, Row, Space, Statistic, Table, Typography, message,
} from 'antd';
import { CloudUploadOutlined, ReloadOutlined } from '@ant-design/icons';
import {
request,
type DashboardStats,
type DeployTriggerResult,
type HqProfile,
type SystemVersion,
} from '../lib/api';
import { fmtTime } from '../lib/constants';
const STATUS_LABELS: Record<string, string> = {
PENDING_PAY: '待付款',
@@ -14,19 +24,104 @@ const STATUS_LABELS: Record<string, string> = {
REFUNDED: '已退款',
};
const DEPLOYED_BY_LABELS: Record<string, string> = {
webhook: 'Webhook',
manual: '手动脚本',
admin: 'Admin 发布',
};
export default function DashboardPage() {
const [stats, setStats] = useState<DashboardStats | null>(null);
const [version, setVersion] = useState<SystemVersion | null>(null);
const [loading, setLoading] = useState(true);
const [versionLoading, setVersionLoading] = useState(true);
const [profile, setProfile] = useState<HqProfile | null>(null);
const [deploying, setDeploying] = useState(false);
const isSuperAdmin = profile?.adminRole === 'SUPER_ADMIN';
const loadVersion = useCallback(() => {
setVersionLoading(true);
return request<SystemVersion | null>('/admin/dashboard/version')
.then(setVersion)
.catch(() => setVersion(null))
.finally(() => setVersionLoading(false));
}, []);
useEffect(() => {
request<DashboardStats>('/admin/dashboard/stats')
.then(setStats)
.finally(() => setLoading(false));
}, []);
void loadVersion();
request<HqProfile>('/admin/auth/me').then(setProfile).catch(() => {});
}, [loadVersion]);
function handleDeploy() {
Modal.confirm({
title: '确认发布更新?',
content: '将触发服务器 webhook,拉取 auto-release.env 中配置的 GIT_BRANCH 并执行发版。发版通常需要数分钟,完成后可刷新版本信息。',
okText: '开始发布',
cancelText: '取消',
onOk: async () => {
setDeploying(true);
try {
const result = await request<DeployTriggerResult>('/admin/deploy/trigger', { method: 'POST' });
message.success(result.message || '已触发发布');
} catch (e) {
message.error(e instanceof Error ? e.message : '触发发布失败');
throw e;
} finally {
setDeploying(false);
}
},
});
}
const shortSha = version?.commitId ? version.commitId.slice(0, 7) : '—';
return (
<div>
<Typography.Title level={4}></Typography.Title>
<Card
title="系统版本"
loading={versionLoading}
style={{ marginBottom: 24 }}
extra={
<Space>
<Button icon={<ReloadOutlined />} onClick={() => void loadVersion()}>
</Button>
{isSuperAdmin && (
<Button
type="primary"
icon={<CloudUploadOutlined />}
loading={deploying}
onClick={handleDeploy}
>
</Button>
)}
</Space>
}
>
{version ? (
<Descriptions column={{ xs: 1, sm: 2, lg: 3 }} size="small">
<Descriptions.Item label="分支">{version.branch || '—'}</Descriptions.Item>
<Descriptions.Item label="Tag">{version.gitTag || '—'}</Descriptions.Item>
<Descriptions.Item label="Commit">
<Typography.Text copyable={{ text: version.commitId }}>{shortSha}</Typography.Text>
</Descriptions.Item>
<Descriptions.Item label="提交说明" span={3}>{version.commitMessage}</Descriptions.Item>
<Descriptions.Item label="发布时间">{fmtTime(version.deployedAt)}</Descriptions.Item>
<Descriptions.Item label="触发来源">
{DEPLOYED_BY_LABELS[version.deployedBy || ''] || version.deployedBy || '—'}
</Descriptions.Item>
</Descriptions>
) : (
<Typography.Text type="secondary"></Typography.Text>
)}
</Card>
<Row gutter={[16, 16]} style={{ marginBottom: 24 }}>
<Col xs={24} sm={12} lg={6}>
<Card loading={loading}>