feat: 佣金提现和备注功能

This commit is contained in:
speakeloudest 2025-09-15 20:31:10 -07:00
parent 8241e95508
commit 5db1e8b15a
5 changed files with 20 additions and 30 deletions

View File

@ -15,7 +15,7 @@ unset APP_NAME # 显式销毁变量
1. 执行 `./scripts/publish-dev.sh` 构建产物在 out-dev文件夹 1. 执行 `./scripts/publish-dev.sh` 构建产物在 out-dev文件夹
2. 上传out/zip.gz到服务器 2. 上传out/zip.gz到服务器
3. tar -xzvf ppanel-user-web-dev.tar.gz 解压 3. tar -xzvf ppanel-user-web-dev.tar.gz 解压
4. tar -xzvf ppanel-user-web-dev.tar.gz 4. tar -xzvf ppanel-admin-web-dev.tar.gz
```shell ```shell
# 第一次启动 # 第一次启动

View File

@ -20,16 +20,23 @@ import { ConfirmButton } from '@workspace/ui/custom-components/confirm-button';
import { formatDate } from '@workspace/ui/utils'; import { formatDate } from '@workspace/ui/utils';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import Link from 'next/link'; import Link from 'next/link';
import { useRef, useState } from 'react'; import React, { useRef, useState } from 'react';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { UserDetail } from './user-detail'; import { UserDetail } from './user-detail';
import UserForm from './user-form'; import UserForm from './user-form';
// 新的子组件,现在管理它自己的备注状态 // 为 RemarkForm 组件定义 props 类型
const RemarkForm = ({ onSave, initialRemark, CloseComponent }) => { interface RemarkFormProps {
const [remark, setRemark] = useState(initialRemark); initialRemark?: string | null;
onSave: (remark: string) => void;
CloseComponent: React.ComponentType<{ asChild?: boolean; children: React.ReactNode }>;
}
const handleInputChange = (event) => { // 新的子组件,在管理它自己的备注状态
const RemarkForm: React.FC<RemarkFormProps> = ({ onSave, initialRemark, CloseComponent }) => {
const [remark, setRemark] = useState<string>(initialRemark ?? '');
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setRemark(event.target.value); setRemark(event.target.value);
}; };

View File

@ -64,32 +64,13 @@ export default function Page() {
header: t('user'), header: t('user'),
cell: ({ row }) => <UserDetail id={row.original.user_id} />, cell: ({ row }) => <UserDetail id={row.original.user_id} />,
}, },
{
accessorKey: 'status',
header: t('status.0'),
cell: ({ row }) => (
<span
className={cn(
'flex items-center gap-2 before:block before:size-1.5 before:animate-pulse before:rounded-full before:ring-2 before:ring-opacity-50',
{
'before:bg-rose-500 before:ring-rose-500': row.original.status === 1,
'before:bg-yellow-500 before:ring-yellow-500': row.original.status === 2,
'before:bg-green-500 before:ring-green-500': row.original.status === 3,
'before:bg-zinc-500 before:ring-zinc-500': row.original.status === 4,
},
)}
>
{t(`status.${row.original.status}`)}
</span>
),
},
{ {
accessorKey: 'updated_at', accessorKey: 'updated_at',
header: t('updatedAt'), header: t('updatedAt'),
cell: ({ row }) => formatDate(row.getValue('updated_at')), cell: ({ row }) => formatDate(row.getValue('updated_at')),
}, },
]} ]}
params={[ /* params={[
{ {
key: 'status', key: 'status',
placeholder: t('status.0'), placeholder: t('status.0'),
@ -100,11 +81,12 @@ export default function Page() {
}, },
], ],
}, },
]} ]}*/
request={async (pagination, filters) => { request={async (pagination, filters) => {
const { data } = await getTicketList({ const { data } = await getTicketList({
...pagination, ...pagination,
...filters, ...filters,
issue_type: 1,
}); });
return { return {
list: data.data?.list || [], list: data.data?.list || [],
@ -166,11 +148,11 @@ export default function Page() {
<div className={cn('bg-accent w-fit rounded-lg p-2 font-medium', {})}> <div className={cn('bg-accent w-fit rounded-lg p-2 font-medium', {})}>
<div> {ticket?.title?.split('-')[1]}</div> <div> {ticket?.title?.split('-')[1]}</div>
<div> {ticket?.description?.split('-')[0]}</div> <div> {ticket?.description?.split('-')[0]}</div>
{ticket?.description?.split('-')[1].includes('data:image') ? ( {ticket?.description?.split('-')[1]?.includes('data:image') ? (
<div> <div>
<div></div> <div></div>
<NextImage <NextImage
src={ticket?.description?.split('-')[1]} src={ticket?.description?.split('-')[1]!}
width={300} width={300}
height={300} height={300}
className='!size-auto object-cover' className='!size-auto object-cover'

View File

@ -864,6 +864,7 @@ declare namespace API {
user_id?: number; user_id?: number;
status?: number; status?: number;
search?: string; search?: string;
issue_type?: number;
}; };
type GetTicketListRequest = { type GetTicketListRequest = {

View File

@ -151,7 +151,7 @@ const WalletDialog: WalletDialogProps = (props) => {
size: 1, size: 1,
issue_type: 1, issue_type: 1,
}); });
if (ticketData?.list?.length > 1) { if (ticketData?.list?.length > 0) {
toast.info('已经存在待处理提现,请耐心等待'); toast.info('已经存在待处理提现,请耐心等待');
return; return;
} }