feat(consignment): 补齐寄卖前端权限门控,收口调拨状态与运营体验
权限门控(P1-8 剩余): - 新增 resolveAdminPermission(sessionPermissions, code):会话接口的最新权限列表优先, 接口异常才回退登录时的本地快照;空数组也判无权限,避免"刚被收回权限仍能点"。 - 寄售仓库面板:consignment.manage 控制手动入库/编辑/作废/退单回库/匹配开关(无权限时开关禁用)。 - 寄卖提报面板:consignment.review 控制审核入库/驳回。 - 接单平台页:无 consignment.view 不渲染两个寄卖 tab,并把 URL/localStorage 的旧选择拉回工单页。 数据约束(P2-19 剩余): - 迁移 080:allocation_status 历史非法值归位「待安排」(备注留痕)后加 CHECK(待安排/已安排), 并顺手修正 077 遗留的"收集链接/玩家提交"权限描述文案。 - 编辑接口拒绝直接改 allocationStatus(400 consignment_allocation_status_update_forbidden)。 运营体验: - 两个面板补 isError 错误态与重试;审核通过/驳回加 confirmLoading 与提交中守卫(防双提交)。 - 待审徽标改用后端真实总数(原来只统计当前页);编辑弹窗押金不再兜底 ¥100(会误写押金)。 - 履约拦截弹窗冷静期文案不再硬编码"3 天",改为按商品规则设定。 - 核实并撤回"倒计时时区偏移"误报:deadlineAt 为带 Z 的 ISO,前端无偏移问题。 验证:后端 412 例(409 通过)、前端 21 例(新增 5 例权限解析)全绿, typecheck / lint / format / check:sql / build 通过;迁移 001→080 在全新空库跑通并在 dev 库应用。
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
} from '@ant-design/icons'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import {
|
||||
Alert,
|
||||
Badge,
|
||||
Button,
|
||||
Card,
|
||||
@@ -33,8 +34,10 @@ import {
|
||||
fetchAdminConsignmentSubmissions,
|
||||
rejectAdminConsignmentSubmission,
|
||||
} from '@/services/admin/consignment'
|
||||
import { fetchAdminSession } from '@/services/admin/auth'
|
||||
import { fetchAdminWorkerUsers } from '@/services/admin/worker-platform'
|
||||
import type { ConsignmentSubmission } from '@/types/consignment'
|
||||
import { resolveAdminPermission } from '@/utils/admin-auth'
|
||||
|
||||
const { Text } = Typography
|
||||
|
||||
@@ -51,6 +54,17 @@ export default function ConsignmentSubmissionsPanel() {
|
||||
const [viewingSubmission, setViewingSubmission] = useState<ConsignmentSubmission | null>(null)
|
||||
const [rejectNote, setRejectNote] = useState('')
|
||||
const [approveForm] = Form.useForm()
|
||||
const [approving, setApproving] = useState(false)
|
||||
const [rejecting, setRejecting] = useState(false)
|
||||
|
||||
// 通过/驳回要 consignment.review:后端接口已挂权限,前端不隐藏会让人点了必 403
|
||||
const adminSessionQuery = useQuery({
|
||||
queryKey: ['admin-session'],
|
||||
queryFn: fetchAdminSession,
|
||||
retry: false,
|
||||
})
|
||||
const sessionPermissions = adminSessionQuery.data?.data.user.permissions
|
||||
const canReviewConsignment = resolveAdminPermission(sessionPermissions, 'consignment.review')
|
||||
|
||||
const workersQuery = useQuery({
|
||||
queryKey: ['admin-worker-users-consignment-options'],
|
||||
@@ -82,10 +96,23 @@ export default function ConsignmentSubmissionsPanel() {
|
||||
|
||||
const submissions = submissionsQuery.data?.data.items || []
|
||||
const submissionTotal = submissionsQuery.data?.data.total || 0
|
||||
const pendingCount = submissions.filter((s) => s.status === 'pending_review').length
|
||||
|
||||
// 待审徽标必须用后端总数:原来只统计当前页(pageSize=20 时最多显示 20,且翻页就变)。
|
||||
const pendingTotalQuery = useQuery({
|
||||
queryKey: ['admin-consignment-submissions-pending-total'],
|
||||
queryFn: () =>
|
||||
fetchAdminConsignmentSubmissions({
|
||||
status: 'pending_review',
|
||||
page: 1,
|
||||
pageSize: 1,
|
||||
}),
|
||||
refetchInterval: 60_000,
|
||||
})
|
||||
const pendingCount = pendingTotalQuery.data?.data.total || 0
|
||||
|
||||
async function handleApproveSubmit() {
|
||||
if (!approveModalItem) return
|
||||
if (!approveModalItem || approving) return
|
||||
setApproving(true)
|
||||
try {
|
||||
const values = await approveForm.validateFields()
|
||||
const costPriceFen = Math.round(Number(values.costPrice || 0) * 100)
|
||||
@@ -118,23 +145,28 @@ export default function ConsignmentSubmissionsPanel() {
|
||||
|
||||
message.success('审核通过!已正式存入寄售库存待匹配!')
|
||||
setApproveModalItem(null)
|
||||
await submissionsQuery.refetch()
|
||||
await Promise.all([submissionsQuery.refetch(), pendingTotalQuery.refetch()])
|
||||
} catch (err: any) {
|
||||
if (err.errorFields) return
|
||||
message.error(err.message || '审核入库失败')
|
||||
} finally {
|
||||
setApproving(false)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleRejectConfirm() {
|
||||
if (!rejectModalItem) return
|
||||
if (!rejectModalItem || rejecting) return
|
||||
setRejecting(true)
|
||||
try {
|
||||
await rejectAdminConsignmentSubmission(rejectModalItem.id, { reviewNote: rejectNote })
|
||||
message.success('已驳回该提报申请')
|
||||
setRejectModalItem(null)
|
||||
setRejectNote('')
|
||||
await submissionsQuery.refetch()
|
||||
await Promise.all([submissionsQuery.refetch(), pendingTotalQuery.refetch()])
|
||||
} catch (err: any) {
|
||||
message.error(err.message || '驳回失败')
|
||||
} finally {
|
||||
setRejecting(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,7 +288,7 @@ export default function ConsignmentSubmissionsPanel() {
|
||||
>
|
||||
详情
|
||||
</Button>
|
||||
{record.status === 'pending_review' ? (
|
||||
{record.status === 'pending_review' && canReviewConsignment ? (
|
||||
<>
|
||||
<Button
|
||||
size="small"
|
||||
@@ -338,6 +370,23 @@ export default function ConsignmentSubmissionsPanel() {
|
||||
</Card>
|
||||
|
||||
<Card size="small">
|
||||
{submissionsQuery.isError ? (
|
||||
<Alert
|
||||
type="error"
|
||||
showIcon
|
||||
style={{ marginBottom: 12 }}
|
||||
message="读取寄卖提报单失败"
|
||||
description={
|
||||
(submissionsQuery.error as any)?.message ||
|
||||
'请检查网络或稍后重试;也可能是当前账号缺少 consignment.view 权限。'
|
||||
}
|
||||
action={
|
||||
<Button size="small" onClick={() => void submissionsQuery.refetch()}>
|
||||
重试
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
) : null}
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={submissionColumns}
|
||||
@@ -363,6 +412,7 @@ export default function ConsignmentSubmissionsPanel() {
|
||||
width={680}
|
||||
onCancel={() => setApproveModalItem(null)}
|
||||
onOk={handleApproveSubmit}
|
||||
confirmLoading={approving}
|
||||
okText="审核通过并正式入库"
|
||||
okType="primary"
|
||||
destroyOnClose
|
||||
@@ -519,6 +569,7 @@ export default function ConsignmentSubmissionsPanel() {
|
||||
open={Boolean(rejectModalItem)}
|
||||
onCancel={() => setRejectModalItem(null)}
|
||||
onOk={handleRejectConfirm}
|
||||
confirmLoading={rejecting}
|
||||
okText="确认驳回"
|
||||
okType="danger"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user