This commit is contained in:
parent
57b841525d
commit
3b93b95177
450
apps/admin/app/dashboard/settings/version/page.tsx
Normal file
450
apps/admin/app/dashboard/settings/version/page.tsx
Normal file
@ -0,0 +1,450 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import {
|
||||||
|
createAppVersion,
|
||||||
|
deleteAppVersion,
|
||||||
|
getAppVersionList,
|
||||||
|
updateAppVersion,
|
||||||
|
} from '@/services/admin/application';
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
|
import { Button } from '@workspace/ui/components/button';
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
} from '@workspace/ui/components/dialog';
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from '@workspace/ui/components/form';
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from '@workspace/ui/components/select';
|
||||||
|
import { Switch } from '@workspace/ui/components/switch';
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableHead,
|
||||||
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
} from '@workspace/ui/components/table';
|
||||||
|
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
|
||||||
|
import { Icon } from '@workspace/ui/custom-components/icon';
|
||||||
|
|
||||||
|
import { useTranslations } from 'next-intl';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import { toast } from 'sonner';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
const versionSchema = z.object({
|
||||||
|
id: z.number().optional(),
|
||||||
|
platform: z.string().min(1),
|
||||||
|
version: z.string().min(1),
|
||||||
|
min_version: z.string().optional(),
|
||||||
|
url: z.string().url(),
|
||||||
|
description: z.string().optional(),
|
||||||
|
force_update: z.boolean(),
|
||||||
|
is_default: z.boolean(),
|
||||||
|
is_in_review: z.boolean(),
|
||||||
|
});
|
||||||
|
|
||||||
|
type VersionFormData = z.infer<typeof versionSchema>;
|
||||||
|
|
||||||
|
export default function VersionPage() {
|
||||||
|
const t = useTranslations('system');
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const [page, setPage] = useState(1);
|
||||||
|
const [pageSize, setPageSize] = useState(10);
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [editingVersion, setEditingVersion] = useState<API.ApplicationVersion | null>(null);
|
||||||
|
|
||||||
|
const { data } = useQuery({
|
||||||
|
queryKey: ['app-versions', page, pageSize],
|
||||||
|
queryFn: async () => {
|
||||||
|
const res = await getAppVersionList({ page, size: pageSize });
|
||||||
|
return res.data?.data;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const form = useForm<VersionFormData>({
|
||||||
|
resolver: zodResolver(versionSchema),
|
||||||
|
defaultValues: {
|
||||||
|
platform: 'android',
|
||||||
|
version: '',
|
||||||
|
min_version: '',
|
||||||
|
url: '',
|
||||||
|
description: '',
|
||||||
|
force_update: false,
|
||||||
|
is_default: false,
|
||||||
|
is_in_review: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const createMutation = useMutation({
|
||||||
|
mutationFn: createAppVersion,
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.success(t('common.saveSuccess'));
|
||||||
|
setOpen(false);
|
||||||
|
form.reset();
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['app-versions'] });
|
||||||
|
},
|
||||||
|
onError: () => {
|
||||||
|
toast.error(t('common.saveFailed'));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateMutation = useMutation({
|
||||||
|
mutationFn: updateAppVersion,
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.success(t('common.saveSuccess'));
|
||||||
|
setOpen(false);
|
||||||
|
setEditingVersion(null);
|
||||||
|
form.reset();
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['app-versions'] });
|
||||||
|
},
|
||||||
|
onError: () => {
|
||||||
|
toast.error(t('common.saveFailed'));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const deleteMutation = useMutation({
|
||||||
|
mutationFn: deleteAppVersion,
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.success(t('common.saveSuccess'));
|
||||||
|
queryClient.invalidateQueries({ queryKey: ['app-versions'] });
|
||||||
|
},
|
||||||
|
onError: () => {
|
||||||
|
toast.error(t('common.saveFailed'));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = (values: VersionFormData) => {
|
||||||
|
const payload = {
|
||||||
|
...values,
|
||||||
|
description: JSON.stringify({ 'en-US': values.description, 'zh-CN': values.description }),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (editingVersion) {
|
||||||
|
updateMutation.mutate({ ...payload, id: editingVersion.id } as API.UpdateAppVersionRequest);
|
||||||
|
} else {
|
||||||
|
createMutation.mutate(payload as API.CreateAppVersionRequest);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEdit = (version: API.ApplicationVersion) => {
|
||||||
|
setEditingVersion(version);
|
||||||
|
let desc = '';
|
||||||
|
if (version.description && typeof version.description === 'object') {
|
||||||
|
desc = Object.values(version.description)[0] || '';
|
||||||
|
} else if (typeof version.description === 'string') {
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(version.description);
|
||||||
|
desc = (Object.values(parsed)[0] as string) || '';
|
||||||
|
} catch (e) {
|
||||||
|
desc = version.description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
form.reset({
|
||||||
|
platform: version.platform,
|
||||||
|
version: version.version,
|
||||||
|
min_version: version.min_version,
|
||||||
|
url: version.url,
|
||||||
|
description: desc,
|
||||||
|
force_update: version.force_update,
|
||||||
|
is_default: version.is_default,
|
||||||
|
is_in_review: version.is_in_review,
|
||||||
|
});
|
||||||
|
setOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDelete = (id: number) => {
|
||||||
|
if (confirm(t('version.confirmDelete'))) {
|
||||||
|
deleteMutation.mutate({ id });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOpenChange = (open: boolean) => {
|
||||||
|
setOpen(open);
|
||||||
|
if (!open) {
|
||||||
|
setEditingVersion(null);
|
||||||
|
form.reset({
|
||||||
|
platform: 'android',
|
||||||
|
version: '',
|
||||||
|
min_version: '',
|
||||||
|
url: '',
|
||||||
|
description: '',
|
||||||
|
force_update: false,
|
||||||
|
is_default: false,
|
||||||
|
is_in_review: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='space-y-4'>
|
||||||
|
<div className='flex items-center justify-between'>
|
||||||
|
<h2 className='text-2xl font-bold tracking-tight'>{t('version.title')}</h2>
|
||||||
|
<Button onClick={() => handleOpenChange(true)}>
|
||||||
|
<Icon icon='mdi:plus' className='mr-2 h-4 w-4' />
|
||||||
|
{t('version.create')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='rounded-md border'>
|
||||||
|
<Table>
|
||||||
|
<TableHeader>
|
||||||
|
<TableRow>
|
||||||
|
<TableHead>ID</TableHead>
|
||||||
|
<TableHead>{t('version.platform')}</TableHead>
|
||||||
|
<TableHead>{t('version.versionNumber')}</TableHead>
|
||||||
|
<TableHead>{t('version.url')}</TableHead>
|
||||||
|
<TableHead>{t('version.force')}</TableHead>
|
||||||
|
<TableHead>{t('version.default')}</TableHead>
|
||||||
|
<TableHead>{t('version.actions')}</TableHead>
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody>
|
||||||
|
{data?.list?.map((version: API.ApplicationVersion) => (
|
||||||
|
<TableRow key={version.id}>
|
||||||
|
<TableCell>{version.id}</TableCell>
|
||||||
|
<TableCell>{version.platform}</TableCell>
|
||||||
|
<TableCell>{version.version}</TableCell>
|
||||||
|
<TableCell className='max-w-[200px] truncate' title={version.url}>
|
||||||
|
{version.url}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>{version.force_update ? t('version.yes') : t('version.no')}</TableCell>
|
||||||
|
<TableCell>{version.is_default ? t('version.yes') : t('version.no')}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<div className='flex space-x-2'>
|
||||||
|
<Button variant='ghost' size='icon' onClick={() => handleEdit(version)}>
|
||||||
|
<Icon icon='mdi:pencil' className='h-4 w-4' />
|
||||||
|
</Button>
|
||||||
|
<Button variant='ghost' size='icon' onClick={() => handleDelete(version.id)}>
|
||||||
|
<Icon icon='mdi:delete' className='h-4 w-4 text-red-500' />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
{!data?.list?.length && (
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={7} className='h-24 text-center'>
|
||||||
|
{t('version.noResults')}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='flex items-center justify-between py-2'>
|
||||||
|
<div className='text-muted-foreground text-sm'>
|
||||||
|
{t('version.total', { count: data?.total || 0 })}
|
||||||
|
</div>
|
||||||
|
<div className='flex items-center space-x-2'>
|
||||||
|
<Select value={String(pageSize)} onValueChange={(val) => setPageSize(Number(val))}>
|
||||||
|
<SelectTrigger className='w-[80px]'>
|
||||||
|
<SelectValue />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value='10'>10</SelectItem>
|
||||||
|
<SelectItem value='20'>20</SelectItem>
|
||||||
|
<SelectItem value='50'>50</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<Button
|
||||||
|
variant='outline'
|
||||||
|
size='sm'
|
||||||
|
onClick={() => setPage(Math.max(1, page - 1))}
|
||||||
|
disabled={page <= 1}
|
||||||
|
>
|
||||||
|
{t('version.previous')}
|
||||||
|
</Button>
|
||||||
|
<span className='text-sm'>{t('version.page', { page })}</span>
|
||||||
|
<Button
|
||||||
|
variant='outline'
|
||||||
|
size='sm'
|
||||||
|
onClick={() => setPage(page + 1)}
|
||||||
|
disabled={!data?.list?.length || data.list.length < pageSize}
|
||||||
|
>
|
||||||
|
{t('version.next')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Dialog open={open} onOpenChange={handleOpenChange}>
|
||||||
|
<DialogContent className='sm:max-w-[600px]'>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>
|
||||||
|
{editingVersion ? t('version.edit') : t('version.createVersion')}
|
||||||
|
</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
<Form {...form}>
|
||||||
|
<form onSubmit={form.handleSubmit(onSubmit)} className='space-y-4'>
|
||||||
|
<div className='grid grid-cols-2 gap-4'>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name='platform'
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t('version.platform')}</FormLabel>
|
||||||
|
<Select onValueChange={field.onChange} defaultValue={field.value}>
|
||||||
|
<FormControl>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder={t('version.platformPlaceholder')} />
|
||||||
|
</SelectTrigger>
|
||||||
|
</FormControl>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value='android'>Android</SelectItem>
|
||||||
|
<SelectItem value='ios'>iOS</SelectItem>
|
||||||
|
<SelectItem value='windows'>Windows</SelectItem>
|
||||||
|
<SelectItem value='macos'>macOS</SelectItem>
|
||||||
|
<SelectItem value='linux'>Linux</SelectItem>
|
||||||
|
<SelectItem value='harmony'>Harmony</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name='version'
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t('version.versionNumber')}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<EnhancedInput
|
||||||
|
value={field.value}
|
||||||
|
onValueChange={field.onChange}
|
||||||
|
placeholder={t('version.versionPlaceholder')}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className='grid grid-cols-2 gap-4'>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name='min_version'
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t('version.minVersion')}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<EnhancedInput
|
||||||
|
value={field.value}
|
||||||
|
onValueChange={field.onChange}
|
||||||
|
placeholder={t('version.versionPlaceholder')}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name='url'
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t('version.downloadUrl')}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<EnhancedInput
|
||||||
|
value={field.value}
|
||||||
|
onValueChange={field.onChange}
|
||||||
|
placeholder='https://...'
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name='description'
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t('version.descriptionField')}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<EnhancedInput
|
||||||
|
value={field.value}
|
||||||
|
onValueChange={field.onChange}
|
||||||
|
placeholder={t('version.descriptionPlaceholder')}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<div className='flex flex-row gap-4'>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name='force_update'
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className='flex flex-1 flex-row items-center justify-between rounded-lg border p-3 shadow-sm'>
|
||||||
|
<div className='space-y-0.5'>
|
||||||
|
<FormLabel>{t('version.forceUpdate')}</FormLabel>
|
||||||
|
</div>
|
||||||
|
<FormControl>
|
||||||
|
<Switch checked={field.value} onCheckedChange={field.onChange} />
|
||||||
|
</FormControl>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name='is_default'
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className='flex flex-1 flex-row items-center justify-between rounded-lg border p-3 shadow-sm'>
|
||||||
|
<div className='space-y-0.5'>
|
||||||
|
<FormLabel>{t('version.default')}</FormLabel>
|
||||||
|
</div>
|
||||||
|
<FormControl>
|
||||||
|
<Switch checked={field.value} onCheckedChange={field.onChange} />
|
||||||
|
</FormControl>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name='is_in_review'
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className='flex flex-1 flex-row items-center justify-between rounded-lg border p-3 shadow-sm'>
|
||||||
|
<div className='space-y-0.5'>
|
||||||
|
<FormLabel>{t('version.inReview')}</FormLabel>
|
||||||
|
</div>
|
||||||
|
<FormControl>
|
||||||
|
<Switch checked={field.value} onCheckedChange={field.onChange} />
|
||||||
|
</FormControl>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<DialogFooter>
|
||||||
|
<Button type='submit'>
|
||||||
|
{editingVersion ? t('version.update') : t('version.create')}
|
||||||
|
</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -38,6 +38,7 @@ const currencySchema = z.object({
|
|||||||
access_key: z.string().optional(),
|
access_key: z.string().optional(),
|
||||||
currency_unit: z.string().min(1),
|
currency_unit: z.string().min(1),
|
||||||
currency_symbol: z.string().min(1),
|
currency_symbol: z.string().min(1),
|
||||||
|
fixed_rate: z.number().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
type CurrencyFormData = z.infer<typeof currencySchema>;
|
type CurrencyFormData = z.infer<typeof currencySchema>;
|
||||||
@ -62,6 +63,7 @@ export default function CurrencyConfig() {
|
|||||||
access_key: '',
|
access_key: '',
|
||||||
currency_unit: 'USD',
|
currency_unit: 'USD',
|
||||||
currency_symbol: '$',
|
currency_symbol: '$',
|
||||||
|
fixed_rate: 0,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -170,6 +172,26 @@ export default function CurrencyConfig() {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name='fixed_rate'
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>{t('currency.fixedRate')}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<EnhancedInput
|
||||||
|
type='number'
|
||||||
|
placeholder={t('currency.fixedRatePlaceholder', { defaultValue: '0' })}
|
||||||
|
value={field.value}
|
||||||
|
onValueChange={(val) => field.onChange(Number(val))}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormDescription>{t('currency.fixedRateDescription')}</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
|
|||||||
@ -77,6 +77,11 @@ export const navs = [
|
|||||||
icon: 'flat-color-icons:currency-exchange',
|
icon: 'flat-color-icons:currency-exchange',
|
||||||
},
|
},
|
||||||
{ title: 'ADS Config', url: '/dashboard/ads', icon: 'flat-color-icons:electrical-sensor' },
|
{ title: 'ADS Config', url: '/dashboard/ads', icon: 'flat-color-icons:electrical-sensor' },
|
||||||
|
{
|
||||||
|
title: 'Version Management',
|
||||||
|
url: '/dashboard/settings/version',
|
||||||
|
icon: 'flat-color-icons:kindle',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,13 @@
|
|||||||
{
|
{
|
||||||
"ADS Config": "ADS Config",
|
"ADS Config": "ADS Config",
|
||||||
"Announcement Management": "Announcement Management",
|
"Announcement Management": "Announcement Management",
|
||||||
|
|
||||||
"Auth Control": "Auth Control",
|
"Auth Control": "Auth Control",
|
||||||
"Balance": "Balance",
|
"Balance": "Balance",
|
||||||
"Commerce": "Commerce",
|
"Commerce": "Commerce",
|
||||||
"Commission": "Commission",
|
"Commission": "Commission",
|
||||||
"Coupon Management": "Coupon Management",
|
"Coupon Management": "Coupon Management",
|
||||||
"Dashboard": "Dashboard",
|
"Dashboard": "Dashboard",
|
||||||
|
|
||||||
"Document Management": "Document Management",
|
"Document Management": "Document Management",
|
||||||
|
|
||||||
"Email": "Email",
|
"Email": "Email",
|
||||||
"Gift": "Gift",
|
"Gift": "Gift",
|
||||||
"Login": "Login",
|
"Login": "Login",
|
||||||
@ -23,7 +20,6 @@
|
|||||||
"Order Management": "Order Management",
|
"Order Management": "Order Management",
|
||||||
"Payment Config": "Payment Config",
|
"Payment Config": "Payment Config",
|
||||||
"Product Management": "Product Management",
|
"Product Management": "Product Management",
|
||||||
|
|
||||||
"Register": "Register",
|
"Register": "Register",
|
||||||
"Reset Subscribe": "Reset Subscribe",
|
"Reset Subscribe": "Reset Subscribe",
|
||||||
"Server Management": "Server Management",
|
"Server Management": "Server Management",
|
||||||
@ -34,10 +30,10 @@
|
|||||||
"System": "System",
|
"System": "System",
|
||||||
"System Config": "System Config",
|
"System Config": "System Config",
|
||||||
"System Tool": "System Tool",
|
"System Tool": "System Tool",
|
||||||
|
|
||||||
"Ticket Management": "Ticket Management",
|
"Ticket Management": "Ticket Management",
|
||||||
"Traffic Details": "Traffic Details",
|
"Traffic Details": "Traffic Details",
|
||||||
"User Detail": "User Detail",
|
"User Detail": "User Detail",
|
||||||
"User Management": "User Management",
|
"User Management": "User Management",
|
||||||
"Users & Support": "Users & Support"
|
"Users & Support": "Users & Support",
|
||||||
|
"Version Management": "Version Management"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,10 @@
|
|||||||
"currencySymbolPlaceholder": "$",
|
"currencySymbolPlaceholder": "$",
|
||||||
"currencyUnit": "Currency Unit",
|
"currencyUnit": "Currency Unit",
|
||||||
"currencyUnitDescription": "Used for display purposes only; changing this will affect all currency units in the system",
|
"currencyUnitDescription": "Used for display purposes only; changing this will affect all currency units in the system",
|
||||||
"currencyUnitPlaceholder": "USD"
|
"currencyUnitPlaceholder": "USD",
|
||||||
|
"fixedRate": "Fixed Exchange Rate",
|
||||||
|
"fixedRatePlaceholder": "0",
|
||||||
|
"fixedRateDescription": "If a fixed rate is set, it will be used instead of the API rate"
|
||||||
},
|
},
|
||||||
"invite": {
|
"invite": {
|
||||||
"title": "Invitation Settings",
|
"title": "Invitation Settings",
|
||||||
@ -135,5 +138,35 @@
|
|||||||
"inputPlaceholder": "Please enter",
|
"inputPlaceholder": "Please enter",
|
||||||
"saveSuccess": "Save Successful",
|
"saveSuccess": "Save Successful",
|
||||||
"saveFailed": "Save Failed"
|
"saveFailed": "Save Failed"
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
"title": "Version Management",
|
||||||
|
"description": "Manage app versions for all platforms",
|
||||||
|
"create": "Create",
|
||||||
|
"edit": "Edit Version",
|
||||||
|
"createVersion": "Create Version",
|
||||||
|
"platform": "Platform",
|
||||||
|
"platformPlaceholder": "Select platform",
|
||||||
|
"versionNumber": "Version",
|
||||||
|
"versionPlaceholder": "1.0.0",
|
||||||
|
"minVersion": "Min Version",
|
||||||
|
"downloadUrl": "Download URL",
|
||||||
|
"descriptionField": "Description",
|
||||||
|
"descriptionPlaceholder": "Update description...",
|
||||||
|
"forceUpdate": "Force Update",
|
||||||
|
"default": "Default",
|
||||||
|
"inReview": "In Review",
|
||||||
|
"actions": "Actions",
|
||||||
|
"url": "URL",
|
||||||
|
"force": "Force",
|
||||||
|
"total": "Total: {count} items",
|
||||||
|
"previous": "Previous",
|
||||||
|
"next": "Next",
|
||||||
|
"page": "Page {page}",
|
||||||
|
"noResults": "No results.",
|
||||||
|
"yes": "Yes",
|
||||||
|
"no": "No",
|
||||||
|
"update": "Update",
|
||||||
|
"confirmDelete": "Are you sure you want to delete?"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,13 @@
|
|||||||
{
|
{
|
||||||
"ADS Config": "广告配置",
|
"ADS Config": "广告配置",
|
||||||
"Announcement Management": "公告管理",
|
"Announcement Management": "公告管理",
|
||||||
|
|
||||||
"Auth Control": "认证控制",
|
"Auth Control": "认证控制",
|
||||||
"Balance": "余额变动",
|
"Balance": "余额变动",
|
||||||
"Commerce": "商务",
|
"Commerce": "商务",
|
||||||
"Commission": "佣金记录",
|
"Commission": "佣金记录",
|
||||||
"Coupon Management": "优惠券管理",
|
"Coupon Management": "优惠券管理",
|
||||||
"Dashboard": "仪表盘",
|
"Dashboard": "仪表盘",
|
||||||
|
|
||||||
"Document Management": "文档管理",
|
"Document Management": "文档管理",
|
||||||
|
|
||||||
"Email": "邮件日志",
|
"Email": "邮件日志",
|
||||||
"Gift": "赠送记录",
|
"Gift": "赠送记录",
|
||||||
"Login": "登录日志",
|
"Login": "登录日志",
|
||||||
@ -23,7 +20,6 @@
|
|||||||
"Order Management": "订单管理",
|
"Order Management": "订单管理",
|
||||||
"Payment Config": "支付配置",
|
"Payment Config": "支付配置",
|
||||||
"Product Management": "商品管理",
|
"Product Management": "商品管理",
|
||||||
|
|
||||||
"Register": "注册日志",
|
"Register": "注册日志",
|
||||||
"Reset Subscribe": "重置订阅",
|
"Reset Subscribe": "重置订阅",
|
||||||
"Server Management": "服务器管理",
|
"Server Management": "服务器管理",
|
||||||
@ -34,10 +30,10 @@
|
|||||||
"System": "系统",
|
"System": "系统",
|
||||||
"System Config": "系统配置",
|
"System Config": "系统配置",
|
||||||
"System Tool": "系统工具",
|
"System Tool": "系统工具",
|
||||||
|
|
||||||
"Ticket Management": "工单管理",
|
"Ticket Management": "工单管理",
|
||||||
"Traffic Details": "流量明细",
|
"Traffic Details": "流量明细",
|
||||||
"User Detail": "用户详情",
|
"User Detail": "用户详情",
|
||||||
"User Management": "用户管理",
|
"User Management": "用户管理",
|
||||||
"Users & Support": "用户与支持"
|
"Users & Support": "用户与支持",
|
||||||
|
"Version Management": "版本管理"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,10 @@
|
|||||||
"currencySymbolPlaceholder": "$",
|
"currencySymbolPlaceholder": "$",
|
||||||
"currencyUnit": "货币单位",
|
"currencyUnit": "货币单位",
|
||||||
"currencyUnitDescription": "仅用于展示使用,更改后系统中所有的货币单位都将发生变更",
|
"currencyUnitDescription": "仅用于展示使用,更改后系统中所有的货币单位都将发生变更",
|
||||||
"currencyUnitPlaceholder": "USD"
|
"currencyUnitPlaceholder": "USD",
|
||||||
|
"fixedRate": "固定汇率",
|
||||||
|
"fixedRatePlaceholder": "0",
|
||||||
|
"fixedRateDescription": "如果设置了固定汇率,将使用此值而非API获取的汇率"
|
||||||
},
|
},
|
||||||
"invite": {
|
"invite": {
|
||||||
"title": "邀请设置",
|
"title": "邀请设置",
|
||||||
@ -137,5 +140,35 @@
|
|||||||
"inputPlaceholder": "请输入",
|
"inputPlaceholder": "请输入",
|
||||||
"saveSuccess": "保存成功",
|
"saveSuccess": "保存成功",
|
||||||
"saveFailed": "保存失败"
|
"saveFailed": "保存失败"
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
"title": "版本管理",
|
||||||
|
"description": "管理各平台应用版本信息",
|
||||||
|
"create": "创建",
|
||||||
|
"edit": "编辑版本",
|
||||||
|
"createVersion": "创建版本",
|
||||||
|
"platform": "平台",
|
||||||
|
"platformPlaceholder": "选择平台",
|
||||||
|
"versionNumber": "版本号",
|
||||||
|
"versionPlaceholder": "1.0.0",
|
||||||
|
"minVersion": "最低版本",
|
||||||
|
"downloadUrl": "下载链接",
|
||||||
|
"descriptionField": "描述",
|
||||||
|
"descriptionPlaceholder": "更新说明...",
|
||||||
|
"forceUpdate": "强制更新",
|
||||||
|
"default": "默认版本",
|
||||||
|
"inReview": "审核中",
|
||||||
|
"actions": "操作",
|
||||||
|
"url": "下载地址",
|
||||||
|
"force": "强制",
|
||||||
|
"total": "共 {count} 条",
|
||||||
|
"previous": "上一页",
|
||||||
|
"next": "下一页",
|
||||||
|
"page": "第 {page} 页",
|
||||||
|
"noResults": "暂无数据",
|
||||||
|
"yes": "是",
|
||||||
|
"no": "否",
|
||||||
|
"update": "更新",
|
||||||
|
"confirmDelete": "确定要删除吗?"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,3 +85,71 @@ export async function getSubscribeApplicationList(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Create App Version POST /v1/admin/application/version */
|
||||||
|
export async function createAppVersion(
|
||||||
|
body: API.CreateAppVersionRequest,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.Response & { data?: API.ApplicationVersion }>(
|
||||||
|
'/v1/admin/application/version',
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update App Version PUT /v1/admin/application/version */
|
||||||
|
export async function updateAppVersion(
|
||||||
|
body: API.UpdateAppVersionRequest,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.Response & { data?: API.ApplicationVersion }>(
|
||||||
|
'/v1/admin/application/version',
|
||||||
|
{
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Delete App Version DELETE /v1/admin/application/version */
|
||||||
|
export async function deleteAppVersion(
|
||||||
|
body: API.DeleteAppVersionRequest,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.Response & { data?: any }>('/v1/admin/application/version', {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
...(options || {}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get App Version List GET /v1/admin/application/version/list */
|
||||||
|
export async function getAppVersionList(
|
||||||
|
params: API.GetAppVersionListParams,
|
||||||
|
options?: { [key: string]: any },
|
||||||
|
) {
|
||||||
|
return request<API.Response & { data?: API.GetAppVersionListResponse }>(
|
||||||
|
'/v1/admin/application/version/list',
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
...(options || {}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
46
apps/admin/services/admin/typings.d.ts
vendored
46
apps/admin/services/admin/typings.d.ts
vendored
@ -65,10 +65,53 @@ declare namespace API {
|
|||||||
|
|
||||||
type ApplicationVersion = {
|
type ApplicationVersion = {
|
||||||
id: number;
|
id: number;
|
||||||
|
platform: string;
|
||||||
url: string;
|
url: string;
|
||||||
version: string;
|
version: string;
|
||||||
description: string;
|
min_version?: string;
|
||||||
|
force_update: boolean;
|
||||||
|
description: Record<string, string>;
|
||||||
is_default: boolean;
|
is_default: boolean;
|
||||||
|
is_in_review: boolean;
|
||||||
|
created_at: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type CreateAppVersionRequest = {
|
||||||
|
platform: string;
|
||||||
|
version: string;
|
||||||
|
min_version?: string;
|
||||||
|
force_update?: boolean;
|
||||||
|
description?: string;
|
||||||
|
url: string;
|
||||||
|
is_default?: boolean;
|
||||||
|
is_in_review?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
type UpdateAppVersionRequest = {
|
||||||
|
id: number;
|
||||||
|
platform: string;
|
||||||
|
version: string;
|
||||||
|
min_version?: string;
|
||||||
|
force_update?: boolean;
|
||||||
|
description?: string;
|
||||||
|
url: string;
|
||||||
|
is_default?: boolean;
|
||||||
|
is_in_review?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
type DeleteAppVersionRequest = {
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type GetAppVersionListParams = {
|
||||||
|
page?: number;
|
||||||
|
size?: number;
|
||||||
|
platform?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type GetAppVersionListResponse = {
|
||||||
|
total: number;
|
||||||
|
list: ApplicationVersion[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type AppUserSubcbribe = {
|
type AppUserSubcbribe = {
|
||||||
@ -398,6 +441,7 @@ declare namespace API {
|
|||||||
access_key: string;
|
access_key: string;
|
||||||
currency_unit: string;
|
currency_unit: string;
|
||||||
currency_symbol: string;
|
currency_symbol: string;
|
||||||
|
fixed_rate?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DeleteAdsRequest = {
|
type DeleteAdsRequest = {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user