This commit is contained in:
parent
7400137b3c
commit
644b20ebef
@ -23,6 +23,10 @@ import {
|
||||
getTicketList,
|
||||
updateTicketStatus,
|
||||
} from "@workspace/ui/services/admin/ticket";
|
||||
import {
|
||||
getUserDetail,
|
||||
updateUserBasicInfo,
|
||||
} from "@workspace/ui/services/admin/user";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toast } from "sonner";
|
||||
@ -42,6 +46,7 @@ export default function Page() {
|
||||
const [ticketId, setTicketId] = useState<any>(null);
|
||||
|
||||
const [message, setMessage] = useState("");
|
||||
const [loadingId, setLoadingId] = useState<any>(null);
|
||||
|
||||
const { data: ticket, refetch: refetchTicket } = useQuery({
|
||||
queryKey: ["getTicket", ticketId],
|
||||
@ -76,43 +81,134 @@ export default function Page() {
|
||||
render(row) {
|
||||
if (row.status !== 4) {
|
||||
return [
|
||||
<Button key="reply" onClick={() => setTicketId(row.id)}>
|
||||
{t("reply", "Reply")}
|
||||
</Button>,
|
||||
<ConfirmButton
|
||||
cancelText={t("cancel", "Cancel")}
|
||||
confirmText={t("confirm", "Confirm")}
|
||||
description={t(
|
||||
"closeWarning",
|
||||
"Once closed, the ticket cannot be operated on. Please proceed with caution."
|
||||
)}
|
||||
description={
|
||||
<div className="flex flex-col gap-2">
|
||||
<p>
|
||||
请确保您已完成线下打款操作。点击确认后,系统将自动扣除用户对应的佣金并关闭此工单,此操作不可撤销。
|
||||
</p>
|
||||
<p className="font-bold text-rose-500 text-sm">
|
||||
※ USDT 提现需手续费 1 USDT
|
||||
</p>
|
||||
<p className="font-bold text-rose-500 text-sm">
|
||||
※ 支付宝/微信提现手续费 5%
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
key="colse"
|
||||
onConfirm={async () => {
|
||||
setLoadingId(row.id);
|
||||
try {
|
||||
const titleStr = row.title || "";
|
||||
const parts = titleStr.split("-");
|
||||
if (parts.length > 1) {
|
||||
const deductAmount = Number.parseFloat(parts[1]);
|
||||
if (!isNaN(deductAmount)) {
|
||||
const res = await getUserDetail({ id: row.user_id });
|
||||
const user = res?.data?.data;
|
||||
if (user && typeof user.commission !== "undefined") {
|
||||
const deductAmountCent = deductAmount * 100;
|
||||
if (Number(user.commission) < deductAmountCent) {
|
||||
toast.error("用户佣金余额不足,无法完成打款扣费");
|
||||
setLoadingId(null);
|
||||
return;
|
||||
}
|
||||
const newCommission =
|
||||
Number(user.commission) - deductAmountCent;
|
||||
await updateUserBasicInfo({
|
||||
user_id: row.user_id,
|
||||
commission: newCommission,
|
||||
} as any);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Update commission failed", e);
|
||||
}
|
||||
|
||||
await updateTicketStatus({
|
||||
id: row.id,
|
||||
status: 4,
|
||||
});
|
||||
toast.success(t("closeSuccess", "Closed successfully"));
|
||||
ref.current?.refresh();
|
||||
setLoadingId(null);
|
||||
}}
|
||||
title={t("confirmClose", "Are you sure you want to close?")}
|
||||
title="确认已完成打款?"
|
||||
trigger={
|
||||
<Button variant="destructive">{t("close", "Close")}</Button>
|
||||
<Button
|
||||
disabled={loadingId === row.id}
|
||||
variant="destructive"
|
||||
>
|
||||
{loadingId === row.id && (
|
||||
<Icon
|
||||
className="mr-2 animate-spin"
|
||||
icon="lucide:loader-2"
|
||||
/>
|
||||
)}
|
||||
确认打款并结单
|
||||
</Button>
|
||||
}
|
||||
/>,
|
||||
];
|
||||
}
|
||||
return [
|
||||
<Button key="check" onClick={() => setTicketId(row.id)} size="sm">
|
||||
{t("check", "Check")}
|
||||
</Button>,
|
||||
];
|
||||
return [];
|
||||
},
|
||||
}}
|
||||
columns={[
|
||||
{
|
||||
accessorKey: "title",
|
||||
header: t("title", "Title"),
|
||||
id: "withdrawal_type",
|
||||
header: "提现类型",
|
||||
cell: ({ row }) => {
|
||||
const title = row.original.title || "";
|
||||
return title.split("-")[0] || title;
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "withdrawal_amount",
|
||||
header: "提现金额",
|
||||
cell: ({ row }) => {
|
||||
const title = row.original.title || "";
|
||||
const parts = title.split("-");
|
||||
if (parts.length < 2) return "";
|
||||
return (
|
||||
<span className="font-bold text-rose-500">${parts[1]}</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "withdrawal_method",
|
||||
header: "提现方式",
|
||||
cell: ({ row }) => {
|
||||
const desc = row.original.description || "";
|
||||
return desc.split("-")[0] || "";
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "withdrawal_content",
|
||||
header: "提现内容",
|
||||
cell: ({ row }) => {
|
||||
const desc = row.original.description || "";
|
||||
const parts = desc.split("-");
|
||||
if (parts.length < 2) return "";
|
||||
const content = parts[1];
|
||||
if (content.startsWith("data:image/")) {
|
||||
return (
|
||||
<img
|
||||
alt="withdrawal"
|
||||
className="h-10 w-10 cursor-zoom-in rounded border object-cover"
|
||||
onClick={() => {
|
||||
const win = window.open();
|
||||
win?.document.write(`<img src="${content}" />`);
|
||||
}}
|
||||
src={content}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return <span className="font-semibold">{content}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "user_id",
|
||||
|
||||
@ -17,7 +17,7 @@ import type { ReactNode } from "react";
|
||||
interface ConfirmationButtonProps {
|
||||
trigger: ReactNode;
|
||||
title: string;
|
||||
description: string;
|
||||
description: ReactNode;
|
||||
onConfirm: () => void | Promise<void>;
|
||||
cancelText?: string;
|
||||
confirmText?: string;
|
||||
@ -36,7 +36,13 @@ export const ConfirmButton: React.FC<ConfirmationButtonProps> = ({
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>{title}</AlertDialogTitle>
|
||||
<AlertDialogDescription>{description}</AlertDialogDescription>
|
||||
<AlertDialogDescription asChild>
|
||||
{typeof description === "string" ? (
|
||||
<span>{description}</span>
|
||||
) : (
|
||||
<div>{description}</div>
|
||||
)}
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>{cancelText}</AlertDialogCancel>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user