add message
All checks were successful
Build and Deploy Web / build-and-deploy (push) Successful in 1m34s
All checks were successful
Build and Deploy Web / build-and-deploy (push) Successful in 1m34s
This commit is contained in:
parent
b4108961fa
commit
94ac3687e5
26
src/api/feedback.ts
Normal file
26
src/api/feedback.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import request from './request';
|
||||||
|
import type { ApiResponse, PaginatedResponse } from './request';
|
||||||
|
|
||||||
|
// 意见反馈类型
|
||||||
|
export interface Feedback {
|
||||||
|
id: number;
|
||||||
|
user_phone: string;
|
||||||
|
user_nickname: string;
|
||||||
|
content: string;
|
||||||
|
contact: string;
|
||||||
|
created_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取反馈列表
|
||||||
|
export const getFeedbacks = (params?: {
|
||||||
|
page?: number;
|
||||||
|
page_size?: number;
|
||||||
|
phone?: string;
|
||||||
|
}) => {
|
||||||
|
return request.get<unknown, ApiResponse<PaginatedResponse<Feedback>>>('/api/admin/feedbacks/', { params });
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取反馈详情
|
||||||
|
export const getFeedback = (id: number) => {
|
||||||
|
return request.get<unknown, ApiResponse<Feedback>>(`/api/admin/feedbacks/${id}/`);
|
||||||
|
};
|
||||||
@ -17,6 +17,7 @@ import {
|
|||||||
MobileOutlined,
|
MobileOutlined,
|
||||||
UserOutlined,
|
UserOutlined,
|
||||||
TeamOutlined,
|
TeamOutlined,
|
||||||
|
MessageOutlined,
|
||||||
LogoutOutlined,
|
LogoutOutlined,
|
||||||
MenuFoldOutlined,
|
MenuFoldOutlined,
|
||||||
MenuUnfoldOutlined,
|
MenuUnfoldOutlined,
|
||||||
@ -56,6 +57,11 @@ const menuItems = [
|
|||||||
icon: <TeamOutlined />,
|
icon: <TeamOutlined />,
|
||||||
label: '管理员',
|
label: '管理员',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: '/feedbacks',
|
||||||
|
icon: <MessageOutlined />,
|
||||||
|
label: '意见反馈',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const MainLayout: React.FC = () => {
|
const MainLayout: React.FC = () => {
|
||||||
|
|||||||
134
src/pages/Feedback/index.tsx
Normal file
134
src/pages/Feedback/index.tsx
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
import React, { useRef, useState } from 'react';
|
||||||
|
import { Button, message, Modal, Descriptions } from 'antd';
|
||||||
|
import { ProTable } from '@ant-design/pro-components';
|
||||||
|
import type { ProColumns, ActionType } from '@ant-design/pro-components';
|
||||||
|
import { getFeedbacks } from '../../api/feedback';
|
||||||
|
import type { Feedback } from '../../api/feedback';
|
||||||
|
|
||||||
|
const FeedbackPage: React.FC = () => {
|
||||||
|
const actionRef = useRef<ActionType>(null);
|
||||||
|
const [detailVisible, setDetailVisible] = useState(false);
|
||||||
|
const [currentRecord, setCurrentRecord] = useState<Feedback | null>(null);
|
||||||
|
|
||||||
|
const handleView = (record: Feedback) => {
|
||||||
|
setCurrentRecord(record);
|
||||||
|
setDetailVisible(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const columns: ProColumns<Feedback>[] = [
|
||||||
|
{
|
||||||
|
title: 'ID',
|
||||||
|
dataIndex: 'id',
|
||||||
|
width: 80,
|
||||||
|
search: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '用户手机号',
|
||||||
|
dataIndex: 'user_phone',
|
||||||
|
width: 140,
|
||||||
|
render: (_, record) => {
|
||||||
|
const phone = record.user_phone;
|
||||||
|
return phone ? phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2') : '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '用户昵称',
|
||||||
|
dataIndex: 'user_nickname',
|
||||||
|
width: 120,
|
||||||
|
search: false,
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '反馈内容',
|
||||||
|
dataIndex: 'content',
|
||||||
|
ellipsis: true,
|
||||||
|
search: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '联系方式',
|
||||||
|
dataIndex: 'contact',
|
||||||
|
width: 140,
|
||||||
|
search: false,
|
||||||
|
render: (_, record) => record.contact || '-',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '提交时间',
|
||||||
|
dataIndex: 'created_at',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
width: 180,
|
||||||
|
search: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
width: 80,
|
||||||
|
search: false,
|
||||||
|
render: (_, record) => (
|
||||||
|
<Button type="link" size="small" onClick={() => handleView(record)}>
|
||||||
|
查看
|
||||||
|
</Button>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ProTable<Feedback>
|
||||||
|
headerTitle="意见反馈"
|
||||||
|
rowKey="id"
|
||||||
|
actionRef={actionRef}
|
||||||
|
columns={columns}
|
||||||
|
cardBordered
|
||||||
|
request={async (params) => {
|
||||||
|
try {
|
||||||
|
const res = await getFeedbacks({
|
||||||
|
page: params.current,
|
||||||
|
page_size: params.pageSize,
|
||||||
|
phone: params.user_phone,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
data: res.data.items,
|
||||||
|
total: res.data.total,
|
||||||
|
success: true,
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
message.error('获取数据失败');
|
||||||
|
return { data: [], total: 0, success: false };
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
pagination={{
|
||||||
|
defaultPageSize: 10,
|
||||||
|
showSizeChanger: true,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Modal
|
||||||
|
title="反馈详情"
|
||||||
|
open={detailVisible}
|
||||||
|
onCancel={() => setDetailVisible(false)}
|
||||||
|
footer={null}
|
||||||
|
width={600}
|
||||||
|
>
|
||||||
|
{currentRecord && (
|
||||||
|
<Descriptions column={1} style={{ marginTop: 24 }}>
|
||||||
|
<Descriptions.Item label="用户手机号">
|
||||||
|
{currentRecord.user_phone}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="用户昵称">
|
||||||
|
{currentRecord.user_nickname || '-'}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="反馈内容">
|
||||||
|
<div style={{ whiteSpace: 'pre-wrap' }}>{currentRecord.content}</div>
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="联系方式">
|
||||||
|
{currentRecord.contact || '-'}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="提交时间">
|
||||||
|
{currentRecord.created_at}
|
||||||
|
</Descriptions.Item>
|
||||||
|
</Descriptions>
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FeedbackPage;
|
||||||
@ -9,6 +9,7 @@ import BatchDetail from '../pages/Batch/Detail';
|
|||||||
import DevicePage from '../pages/Device';
|
import DevicePage from '../pages/Device';
|
||||||
import UserPage from '../pages/User';
|
import UserPage from '../pages/User';
|
||||||
import AdminPage from '../pages/Admin';
|
import AdminPage from '../pages/Admin';
|
||||||
|
import FeedbackPage from '../pages/Feedback';
|
||||||
import { useAuthStore } from '../store/useAuthStore';
|
import { useAuthStore } from '../store/useAuthStore';
|
||||||
|
|
||||||
// 路由守卫组件
|
// 路由守卫组件
|
||||||
@ -68,6 +69,10 @@ const router = createBrowserRouter([
|
|||||||
path: 'admins',
|
path: 'admins',
|
||||||
element: <AdminPage />,
|
element: <AdminPage />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'feedbacks',
|
||||||
|
element: <FeedbackPage />,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user