修改了许多测试时遇到的问题
This commit is contained in:
@@ -12,6 +12,8 @@ import './App.css'
|
|||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const isAuthenticated = () => {
|
const isAuthenticated = () => {
|
||||||
|
// 临时免登录,方便预览
|
||||||
|
// return true
|
||||||
return localStorage.getItem('admin_token') !== null
|
return localStorage.getItem('admin_token') !== null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,12 +39,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.admin-menu .ant-menu-item-selected {
|
.admin-menu .ant-menu-item-selected {
|
||||||
background: linear-gradient(135deg, #1890ff 0%, #36cfc9 100%);
|
background: linear-gradient(135deg, #1890ff 0%, #36cfc9 100%) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-menu .ant-menu-item-selected a,
|
.admin-menu .ant-menu-item-selected .ant-menu-title-content,
|
||||||
.admin-menu .ant-menu-item-selected .anticon {
|
.admin-menu .ant-menu-item-selected .anticon {
|
||||||
color: #fff;
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-menu .ant-menu-item-selected:hover {
|
||||||
|
background: linear-gradient(135deg, #1890ff 0%, #36cfc9 100%) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-header {
|
.admin-header {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card:hover {
|
.stat-card:hover {
|
||||||
@@ -32,30 +33,63 @@
|
|||||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stat-card .ant-card-body {
|
||||||
|
padding: 20px;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.stat-content {
|
.stat-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
min-height: 72px;
|
||||||
|
padding: 8px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-icon {
|
.stat-icon {
|
||||||
width: 56px;
|
width: 64px;
|
||||||
height: 56px;
|
height: 64px;
|
||||||
border-radius: 12px;
|
border-radius: 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 24px;
|
font-size: 28px;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-info {
|
.stat-info {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-title {
|
.stat-title {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 8px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .ant-statistic-content {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .ant-statistic-content-prefix {
|
||||||
|
font-size: 18px;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card .ant-statistic-content-suffix {
|
||||||
|
font-size: 14px;
|
||||||
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.today-row {
|
.today-row {
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ const Dashboard = () => {
|
|||||||
value={card.value}
|
value={card.value}
|
||||||
prefix={card.prefix}
|
prefix={card.prefix}
|
||||||
precision={card.precision || 0}
|
precision={card.precision || 0}
|
||||||
valueStyle={{ color: card.color, fontSize: '24px', fontWeight: 600 }}
|
valueStyle={{ color: card.color }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ const FileManagement = () => {
|
|||||||
title: '文件名',
|
title: '文件名',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
key: 'name',
|
key: 'name',
|
||||||
|
width: 280,
|
||||||
render: (text: string, record: File) => (
|
render: (text: string, record: File) => (
|
||||||
<Space>
|
<Space>
|
||||||
{getFileIcon(text)}
|
{getFileIcon(text)}
|
||||||
@@ -145,39 +146,45 @@ const FileManagement = () => {
|
|||||||
title: '类型',
|
title: '类型',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
key: 'type',
|
key: 'type',
|
||||||
width: 100,
|
width: 90,
|
||||||
|
align: 'center' as const,
|
||||||
render: (text: string) => getFileTypeTag(text),
|
render: (text: string) => getFileTypeTag(text),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '大小',
|
title: '大小',
|
||||||
dataIndex: 'size',
|
dataIndex: 'size',
|
||||||
key: 'size',
|
key: 'size',
|
||||||
width: 120,
|
width: 100,
|
||||||
|
align: 'center' as const,
|
||||||
render: (size: number) => formatFileSize(size),
|
render: (size: number) => formatFileSize(size),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '页数',
|
title: '页数',
|
||||||
dataIndex: 'page_count',
|
dataIndex: 'page_count',
|
||||||
key: 'page_count',
|
key: 'page_count',
|
||||||
width: 100,
|
width: 90,
|
||||||
|
align: 'center' as const,
|
||||||
render: (count: number) => count ? `${count} 页` : '-',
|
render: (count: number) => count ? `${count} 页` : '-',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '用户ID',
|
title: '用户ID',
|
||||||
dataIndex: 'user_id',
|
dataIndex: 'user_id',
|
||||||
key: 'user_id',
|
key: 'user_id',
|
||||||
|
width: 140,
|
||||||
render: (text: string) => <Tag>{text?.substring(0, 8)}...</Tag>,
|
render: (text: string) => <Tag>{text?.substring(0, 8)}...</Tag>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '上传时间',
|
title: '上传时间',
|
||||||
dataIndex: 'created_at',
|
dataIndex: 'created_at',
|
||||||
key: 'created_at',
|
key: 'created_at',
|
||||||
|
width: 180,
|
||||||
render: (text: string) => new Date(text).toLocaleString('zh-CN'),
|
render: (text: string) => new Date(text).toLocaleString('zh-CN'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'action',
|
key: 'action',
|
||||||
width: 180,
|
width: 160,
|
||||||
|
fixed: 'right' as const,
|
||||||
render: (_: unknown, record: File) => (
|
render: (_: unknown, record: File) => (
|
||||||
<Space>
|
<Space>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
Card,
|
Card,
|
||||||
@@ -118,7 +118,7 @@ const OrderManagement = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getActionItems = (record: Order) => {
|
const getActionItems = (record: Order) => {
|
||||||
const items = []
|
const items: { key: string; label: string; icon: React.ReactNode; danger?: boolean; onClick: () => void }[] = []
|
||||||
if (record.status === 'paid') {
|
if (record.status === 'paid') {
|
||||||
items.push({
|
items.push({
|
||||||
key: 'printing',
|
key: 'printing',
|
||||||
@@ -163,6 +163,7 @@ const OrderManagement = () => {
|
|||||||
title: '用户ID',
|
title: '用户ID',
|
||||||
dataIndex: 'user_id',
|
dataIndex: 'user_id',
|
||||||
key: 'user_id',
|
key: 'user_id',
|
||||||
|
width: 140,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
render: (text: string) => <Tag>{text?.substring(0, 8)}...</Tag>,
|
render: (text: string) => <Tag>{text?.substring(0, 8)}...</Tag>,
|
||||||
},
|
},
|
||||||
@@ -170,6 +171,8 @@ const OrderManagement = () => {
|
|||||||
title: '金额',
|
title: '金额',
|
||||||
dataIndex: 'amount',
|
dataIndex: 'amount',
|
||||||
key: 'amount',
|
key: 'amount',
|
||||||
|
width: 120,
|
||||||
|
align: 'center' as const,
|
||||||
render: (amount: number) => (
|
render: (amount: number) => (
|
||||||
<Text strong style={{ color: '#f5222d' }}>
|
<Text strong style={{ color: '#f5222d' }}>
|
||||||
¥{amount?.toFixed(2)}
|
¥{amount?.toFixed(2)}
|
||||||
@@ -180,18 +183,22 @@ const OrderManagement = () => {
|
|||||||
title: '状态',
|
title: '状态',
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
key: 'status',
|
key: 'status',
|
||||||
|
width: 120,
|
||||||
|
align: 'center' as const,
|
||||||
render: (status: string) => getStatusTag(status),
|
render: (status: string) => getStatusTag(status),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '创建时间',
|
title: '创建时间',
|
||||||
dataIndex: 'created_at',
|
dataIndex: 'created_at',
|
||||||
key: 'created_at',
|
key: 'created_at',
|
||||||
|
width: 180,
|
||||||
render: (text: string) => new Date(text).toLocaleString('zh-CN'),
|
render: (text: string) => new Date(text).toLocaleString('zh-CN'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'action',
|
key: 'action',
|
||||||
width: 150,
|
width: 140,
|
||||||
|
fixed: 'right' as const,
|
||||||
render: (_: unknown, record: Order) => (
|
render: (_: unknown, record: Order) => (
|
||||||
<Space>
|
<Space>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -112,18 +112,24 @@ const PriceManagement = () => {
|
|||||||
title: '纸张尺寸',
|
title: '纸张尺寸',
|
||||||
dataIndex: 'paper_size',
|
dataIndex: 'paper_size',
|
||||||
key: 'paper_size',
|
key: 'paper_size',
|
||||||
|
width: 120,
|
||||||
|
align: 'center' as const,
|
||||||
render: (text: string) => <Tag color="purple">{text}</Tag>,
|
render: (text: string) => <Tag color="purple">{text}</Tag>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '颜色类型',
|
title: '颜色类型',
|
||||||
dataIndex: 'color_type',
|
dataIndex: 'color_type',
|
||||||
key: 'color_type',
|
key: 'color_type',
|
||||||
|
width: 120,
|
||||||
|
align: 'center' as const,
|
||||||
render: (type: string) => getColorTypeTag(type),
|
render: (type: string) => getColorTypeTag(type),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '单面价格',
|
title: '单面价格',
|
||||||
dataIndex: 'single_sided_price',
|
dataIndex: 'single_sided_price',
|
||||||
key: 'single_sided_price',
|
key: 'single_sided_price',
|
||||||
|
width: 140,
|
||||||
|
align: 'center' as const,
|
||||||
render: (price: number) => (
|
render: (price: number) => (
|
||||||
<Text strong style={{ color: '#f5222d' }}>
|
<Text strong style={{ color: '#f5222d' }}>
|
||||||
¥{price?.toFixed(2)}/页
|
¥{price?.toFixed(2)}/页
|
||||||
@@ -134,6 +140,8 @@ const PriceManagement = () => {
|
|||||||
title: '双面价格',
|
title: '双面价格',
|
||||||
dataIndex: 'double_sided_price',
|
dataIndex: 'double_sided_price',
|
||||||
key: 'double_sided_price',
|
key: 'double_sided_price',
|
||||||
|
width: 140,
|
||||||
|
align: 'center' as const,
|
||||||
render: (price: number) => (
|
render: (price: number) => (
|
||||||
<Text strong style={{ color: '#f5222d' }}>
|
<Text strong style={{ color: '#f5222d' }}>
|
||||||
¥{price?.toFixed(2)}/页
|
¥{price?.toFixed(2)}/页
|
||||||
@@ -144,12 +152,14 @@ const PriceManagement = () => {
|
|||||||
title: '创建时间',
|
title: '创建时间',
|
||||||
dataIndex: 'created_at',
|
dataIndex: 'created_at',
|
||||||
key: 'created_at',
|
key: 'created_at',
|
||||||
|
width: 180,
|
||||||
render: (text: string) => new Date(text).toLocaleString('zh-CN'),
|
render: (text: string) => new Date(text).toLocaleString('zh-CN'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'action',
|
key: 'action',
|
||||||
width: 180,
|
width: 160,
|
||||||
|
fixed: 'right' as const,
|
||||||
render: (_: unknown, record: PriceItem) => (
|
render: (_: unknown, record: PriceItem) => (
|
||||||
<Space>
|
<Space>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
Card,
|
Card,
|
||||||
Form,
|
Form,
|
||||||
Input,
|
Input,
|
||||||
|
InputNumber,
|
||||||
Select,
|
Select,
|
||||||
Switch,
|
Switch,
|
||||||
Button,
|
Button,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
Table,
|
Table,
|
||||||
Tag,
|
Tag,
|
||||||
Spin,
|
Spin,
|
||||||
|
Space,
|
||||||
} from 'antd'
|
} from 'antd'
|
||||||
import {
|
import {
|
||||||
BarChartOutlined,
|
BarChartOutlined,
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ const UserManagement = () => {
|
|||||||
title: '用户',
|
title: '用户',
|
||||||
dataIndex: 'nickname',
|
dataIndex: 'nickname',
|
||||||
key: 'nickname',
|
key: 'nickname',
|
||||||
|
width: 200,
|
||||||
render: (text: string, record: User) => (
|
render: (text: string, record: User) => (
|
||||||
<Space>
|
<Space>
|
||||||
<Avatar src={record.avatar} icon={<UserOutlined />} />
|
<Avatar src={record.avatar} icon={<UserOutlined />} />
|
||||||
@@ -85,6 +86,7 @@ const UserManagement = () => {
|
|||||||
title: 'OpenID',
|
title: 'OpenID',
|
||||||
dataIndex: 'openid',
|
dataIndex: 'openid',
|
||||||
key: 'openid',
|
key: 'openid',
|
||||||
|
width: 220,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
render: (text: string) => (
|
render: (text: string) => (
|
||||||
<Tag color="blue" style={{ fontFamily: 'monospace' }}>
|
<Tag color="blue" style={{ fontFamily: 'monospace' }}>
|
||||||
@@ -96,18 +98,21 @@ const UserManagement = () => {
|
|||||||
title: '手机号',
|
title: '手机号',
|
||||||
dataIndex: 'phone',
|
dataIndex: 'phone',
|
||||||
key: 'phone',
|
key: 'phone',
|
||||||
|
width: 140,
|
||||||
render: (text: string) => text || <Tag color="default">未绑定</Tag>,
|
render: (text: string) => text || <Tag color="default">未绑定</Tag>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '注册时间',
|
title: '注册时间',
|
||||||
dataIndex: 'created_at',
|
dataIndex: 'created_at',
|
||||||
key: 'created_at',
|
key: 'created_at',
|
||||||
|
width: 180,
|
||||||
render: (text: string) => new Date(text).toLocaleString('zh-CN'),
|
render: (text: string) => new Date(text).toLocaleString('zh-CN'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'action',
|
key: 'action',
|
||||||
width: 120,
|
width: 100,
|
||||||
|
fixed: 'right' as const,
|
||||||
render: (_: unknown, record: User) => (
|
render: (_: unknown, record: User) => (
|
||||||
<Button
|
<Button
|
||||||
type="text"
|
type="text"
|
||||||
|
|||||||
Reference in New Issue
Block a user