发布商品,商品图片使用oss服务器地址
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
import { useState } from 'react';
|
||||
import { Button, Descriptions, Drawer, Form, Select, Table, Typography, message } from 'antd';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import { request } from '../lib/api';
|
||||
import { fmtTime } from '../lib/constants';
|
||||
import { useAdminList } from '../lib/useAdminList';
|
||||
|
||||
type Row = {
|
||||
id: string;
|
||||
ticketNo: string;
|
||||
ticketType: string;
|
||||
status: string;
|
||||
refType: string;
|
||||
refId: string;
|
||||
remark?: string;
|
||||
createdAt: string;
|
||||
};
|
||||
|
||||
export default function TicketsPage() {
|
||||
const [filters, setFilters] = useState<Record<string, string>>({});
|
||||
const { data, loading, page, pageSize, setPage, setPageSize, reload } = useAdminList<Row>(
|
||||
'/admin/tickets',
|
||||
() => {
|
||||
const qs = new URLSearchParams();
|
||||
if (filters.ticketType) qs.set('ticketType', filters.ticketType);
|
||||
if (filters.status) qs.set('status', filters.status);
|
||||
return qs;
|
||||
},
|
||||
[filters],
|
||||
);
|
||||
const [detail, setDetail] = useState<Record<string, unknown> | null>(null);
|
||||
const [drawerOpen, setDrawerOpen] = useState(false);
|
||||
|
||||
async function approve(id: string) {
|
||||
await request(`/admin/tickets/${id}/approve`, { method: 'POST', body: JSON.stringify({}) });
|
||||
message.success('已审批通过');
|
||||
reload();
|
||||
setDrawerOpen(false);
|
||||
}
|
||||
|
||||
async function reject(id: string) {
|
||||
await request(`/admin/tickets/${id}/reject`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ remark: '驳回' }),
|
||||
});
|
||||
message.success('已驳回');
|
||||
reload();
|
||||
setDrawerOpen(false);
|
||||
}
|
||||
|
||||
const columns: ColumnsType<Row> = [
|
||||
{ title: '工单号', dataIndex: 'ticketNo', width: 180 },
|
||||
{ title: '类型', dataIndex: 'ticketType', width: 100 },
|
||||
{ title: '状态', dataIndex: 'status', width: 90 },
|
||||
{ title: '关联', width: 140, render: (_, r) => `${r.refType}#${r.refId}` },
|
||||
{ title: '备注', dataIndex: 'remark', ellipsis: true },
|
||||
{ title: '时间', dataIndex: 'createdAt', width: 160, render: fmtTime },
|
||||
{
|
||||
title: '操作', width: 80,
|
||||
render: (_, row) => (
|
||||
<Button type="link" size="small" onClick={async () => {
|
||||
setDetail(await request(`/admin/tickets/${row.id}`));
|
||||
setDrawerOpen(true);
|
||||
}}>详情</Button>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Typography.Title level={4}>工单中心</Typography.Title>
|
||||
<Form layout="inline" style={{ marginBottom: 16 }} onFinish={(v) => { setFilters(v); setPage(1); }}>
|
||||
<Form.Item name="ticketType" label="类型">
|
||||
<Select allowClear style={{ width: 120 }} options={[
|
||||
{ value: 'REFUND', label: '退款' },
|
||||
{ value: 'RESHIPMENT', label: '补发' },
|
||||
{ value: 'ALERT', label: '异常' },
|
||||
]} />
|
||||
</Form.Item>
|
||||
<Form.Item name="status" label="状态"><Input allowClear placeholder="PENDING" /></Form.Item>
|
||||
<Button type="primary" htmlType="submit">筛选</Button>
|
||||
</Form>
|
||||
<Table rowKey="id" loading={loading} columns={columns} dataSource={data?.items ?? []} scroll={{ x: 900 }}
|
||||
pagination={{ current: page, pageSize, total: data?.total ?? 0, showSizeChanger: true, onChange: (p, ps) => { setPage(p); setPageSize(ps); } }} />
|
||||
<Drawer title="工单详情" width={480} open={drawerOpen} onClose={() => setDrawerOpen(false)}
|
||||
extra={detail && (detail.status === 'PENDING' || detail.status === 'OPEN') ? (
|
||||
<>
|
||||
<Button type="primary" onClick={() => approve(String(detail.id))} style={{ marginRight: 8 }}>通过</Button>
|
||||
<Button danger onClick={() => reject(String(detail.id))}>驳回</Button>
|
||||
</>
|
||||
) : null}>
|
||||
{detail && (
|
||||
<Descriptions column={1} bordered size="small">
|
||||
<Descriptions.Item label="工单号">{String(detail.ticketNo)}</Descriptions.Item>
|
||||
<Descriptions.Item label="类型">{String(detail.ticketType)}</Descriptions.Item>
|
||||
<Descriptions.Item label="状态">{String(detail.status)}</Descriptions.Item>
|
||||
<Descriptions.Item label="关联">{String(detail.refType)} #{String(detail.refId)}</Descriptions.Item>
|
||||
<Descriptions.Item label="备注">{String(detail.remark ?? '—')}</Descriptions.Item>
|
||||
</Descriptions>
|
||||
)}
|
||||
</Drawer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user