mirror of
https://github.com/perfect-panel/ppanel-web.git
synced 2026-02-17 13:51:10 -05:00
♻️ refactor: Remove application management forms and related configurations
This commit is contained in:
parent
a7936de6dc
commit
0c43844a6f
44
CHANGELOG.md
44
CHANGELOG.md
@ -1,39 +1,37 @@
|
|||||||
<a name="readme-top"></a>
|
<a name="readme-top"></a>
|
||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
# [1.3.0](https://github.com/perfect-panel/ppanel-web/compare/v1.2.0...v1.3.0) (2025-08-15)
|
# [1.3.0](https://github.com/perfect-panel/ppanel-web/compare/v1.2.0...v1.3.0) (2025-08-15)
|
||||||
|
|
||||||
|
|
||||||
### ♻ Code Refactoring
|
### ♻ Code Refactoring
|
||||||
|
|
||||||
* Refactoring and adding multiple features ([65c9b9f](https://github.com/perfect-panel/ppanel-web/commit/65c9b9f))
|
- Refactoring and adding multiple features ([65c9b9f](https://github.com/perfect-panel/ppanel-web/commit/65c9b9f))
|
||||||
|
|
||||||
|
|
||||||
### ✨ Features
|
### ✨ Features
|
||||||
|
|
||||||
* **api**: Add getClient API endpoint to retrieve subscription applications ([7a279e6](https://github.com/perfect-panel/ppanel-web/commit/7a279e6))
|
- **api**: Add getClient API endpoint to retrieve subscription applications ([7a279e6](https://github.com/perfect-panel/ppanel-web/commit/7a279e6))
|
||||||
* **marketing**: Add marketing management features and localization updates ([ea08de0](https://github.com/perfect-panel/ppanel-web/commit/ea08de0))
|
- **marketing**: Add marketing management features and localization updates ([ea08de0](https://github.com/perfect-panel/ppanel-web/commit/ea08de0))
|
||||||
* **protocol**: Add template preview functionality with localization support ([0448d21](https://github.com/perfect-panel/ppanel-web/commit/0448d21))
|
- **protocol**: Add template preview functionality with localization support ([0448d21](https://github.com/perfect-panel/ppanel-web/commit/0448d21))
|
||||||
* **subscribe**: Update subscription management localization and add new fields ([1d9b0a4](https://github.com/perfect-panel/ppanel-web/commit/1d9b0a4))
|
- **subscribe**: Update subscription management localization and add new fields ([1d9b0a4](https://github.com/perfect-panel/ppanel-web/commit/1d9b0a4))
|
||||||
|
|
||||||
|
|
||||||
### 🐛 Bug Fixes
|
### 🐛 Bug Fixes
|
||||||
|
|
||||||
* **bun**: Update bun.lockb to reflect dependency changes ([bbcd018](https://github.com/perfect-panel/ppanel-web/commit/bbcd018))
|
- **bun**: Update bun.lockb to reflect dependency changes ([bbcd018](https://github.com/perfect-panel/ppanel-web/commit/bbcd018))
|
||||||
* **editor**: Add Go template editor component and update related schemas ([9d9c3cd](https://github.com/perfect-panel/ppanel-web/commit/9d9c3cd))
|
- **editor**: Add Go template editor component and update related schemas ([9d9c3cd](https://github.com/perfect-panel/ppanel-web/commit/9d9c3cd))
|
||||||
* **editor**: Enhance Go Template Editor to support trimmed template tags and improve range/end matching ([641ed5e](https://github.com/perfect-panel/ppanel-web/commit/641ed5e))
|
- **editor**: Enhance Go Template Editor to support trimmed template tags and improve range/end matching ([641ed5e](https://github.com/perfect-panel/ppanel-web/commit/641ed5e))
|
||||||
* **editor**: Enhance Go Template Editor with schema support and improved completion ([5b21d8a](https://github.com/perfect-panel/ppanel-web/commit/5b21d8a))
|
- **editor**: Enhance Go Template Editor with schema support and improved completion ([5b21d8a](https://github.com/perfect-panel/ppanel-web/commit/5b21d8a))
|
||||||
* **enhaced-input**: Disable autocomplete for EnhancedInput component ([f190c68](https://github.com/perfect-panel/ppanel-web/commit/f190c68))
|
- **enhaced-input**: Disable autocomplete for EnhancedInput component ([f190c68](https://github.com/perfect-panel/ppanel-web/commit/f190c68))
|
||||||
* **global**: Add user agent limit settings to subscription configuration ([822416d](https://github.com/perfect-panel/ppanel-web/commit/822416d))
|
- **global**: Add user agent limit settings to subscription configuration ([822416d](https://github.com/perfect-panel/ppanel-web/commit/822416d))
|
||||||
* **locales**: Update 'conf' output format to use uppercase 'CONF' ([fce9119](https://github.com/perfect-panel/ppanel-web/commit/fce9119))
|
- **locales**: Update 'conf' output format to use uppercase 'CONF' ([fce9119](https://github.com/perfect-panel/ppanel-web/commit/fce9119))
|
||||||
* **locales**: Update "userAccount" label to "user" in multiple localization files ([48415e9](https://github.com/perfect-panel/ppanel-web/commit/48415e9))
|
- **locales**: Update "userAccount" label to "user" in multiple localization files ([48415e9](https://github.com/perfect-panel/ppanel-web/commit/48415e9))
|
||||||
* **protocol-form**: Swap 'description' and 'user_agent' columns for improved clarity in the table ([72a4106](https://github.com/perfect-panel/ppanel-web/commit/72a4106))
|
- **protocol-form**: Swap 'description' and 'user_agent' columns for improved clarity in the table ([72a4106](https://github.com/perfect-panel/ppanel-web/commit/72a4106))
|
||||||
* **protocol-form**: Update protocol options descriptions for clarity and add new security and transport options ([e5d4deb](https://github.com/perfect-panel/ppanel-web/commit/e5d4deb))
|
- **protocol-form**: Update protocol options descriptions for clarity and add new security and transport options ([e5d4deb](https://github.com/perfect-panel/ppanel-web/commit/e5d4deb))
|
||||||
* **protocol**: Add 'conf' output format option and update translations ([292efdf](https://github.com/perfect-panel/ppanel-web/commit/292efdf))
|
- **protocol**: Add 'conf' output format option and update translations ([292efdf](https://github.com/perfect-panel/ppanel-web/commit/292efdf))
|
||||||
* **protpcp-form**: Rename 'schema' to 'scheme' for consistency across the application ([6ab2ba9](https://github.com/perfect-panel/ppanel-web/commit/6ab2ba9))
|
- **protpcp-form**: Rename 'schema' to 'scheme' for consistency across the application ([6ab2ba9](https://github.com/perfect-panel/ppanel-web/commit/6ab2ba9))
|
||||||
* **register**: Update localization files to include trial subscription settings and descriptions ([33daa1f](https://github.com/perfect-panel/ppanel-web/commit/33daa1f))
|
- **register**: Update localization files to include trial subscription settings and descriptions ([33daa1f](https://github.com/perfect-panel/ppanel-web/commit/33daa1f))
|
||||||
* **system**: Add time unit translations for user registration settings in multiple languages ([296a6c1](https://github.com/perfect-panel/ppanel-web/commit/296a6c1))
|
- **system**: Add time unit translations for user registration settings in multiple languages ([296a6c1](https://github.com/perfect-panel/ppanel-web/commit/296a6c1))
|
||||||
* Update privacy policy and terms of service schemas to use correct field names ([0e6ba5b](https://github.com/perfect-panel/ppanel-web/commit/0e6ba5b))
|
- Update privacy policy and terms of service schemas to use correct field names ([0e6ba5b](https://github.com/perfect-panel/ppanel-web/commit/0e6ba5b))
|
||||||
|
|
||||||
<a name="readme-top"></a>
|
<a name="readme-top"></a>
|
||||||
|
|
||||||
|
|||||||
@ -1,282 +0,0 @@
|
|||||||
'use client';
|
|
||||||
|
|
||||||
import {
|
|
||||||
getApplication,
|
|
||||||
getApplicationConfig,
|
|
||||||
updateApplicationConfig,
|
|
||||||
} from '@/services/admin/system';
|
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
|
||||||
import { Icon } from '@iconify/react';
|
|
||||||
import { useQuery } from '@tanstack/react-query';
|
|
||||||
import { Button } from '@workspace/ui/components/button';
|
|
||||||
import {
|
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormDescription,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from '@workspace/ui/components/form';
|
|
||||||
import { ScrollArea } from '@workspace/ui/components/scroll-area';
|
|
||||||
import {
|
|
||||||
Sheet,
|
|
||||||
SheetContent,
|
|
||||||
SheetFooter,
|
|
||||||
SheetHeader,
|
|
||||||
SheetTitle,
|
|
||||||
SheetTrigger,
|
|
||||||
} from '@workspace/ui/components/sheet';
|
|
||||||
import { Textarea } from '@workspace/ui/components/textarea';
|
|
||||||
import { Combobox } from '@workspace/ui/custom-components/combobox';
|
|
||||||
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
|
|
||||||
import { UploadImage } from '@workspace/ui/custom-components/upload-image';
|
|
||||||
import { DicesIcon } from 'lucide-react';
|
|
||||||
import { useTranslations } from 'next-intl';
|
|
||||||
import { uid } from 'radash';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { useForm } from 'react-hook-form';
|
|
||||||
import { toast } from 'sonner';
|
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
const formSchema = z.object({
|
|
||||||
app_id: z.number().optional(),
|
|
||||||
encryption_key: z.string().optional(),
|
|
||||||
encryption_method: z.string().optional(),
|
|
||||||
startup_picture: z.string().optional(),
|
|
||||||
startup_picture_skip_time: z.number().optional(),
|
|
||||||
domains: z.array(z.string()).optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
type FormSchema = z.infer<typeof formSchema>;
|
|
||||||
|
|
||||||
export default function ConfigForm() {
|
|
||||||
const t = useTranslations('product.app');
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
|
|
||||||
const form = useForm<FormSchema>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
app_id: 0,
|
|
||||||
encryption_key: '',
|
|
||||||
encryption_method: '',
|
|
||||||
startup_picture: '',
|
|
||||||
startup_picture_skip_time: 0,
|
|
||||||
domains: [],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const { data, refetch } = useQuery({
|
|
||||||
queryKey: ['getApplicationConfig'],
|
|
||||||
queryFn: async () => {
|
|
||||||
const { data } = await getApplicationConfig();
|
|
||||||
return data.data;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const { data: applications } = useQuery({
|
|
||||||
queryKey: ['getApplication'],
|
|
||||||
queryFn: async () => {
|
|
||||||
const { data } = await getApplication();
|
|
||||||
return data.data?.applications || [];
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (data) {
|
|
||||||
form.reset(data);
|
|
||||||
}
|
|
||||||
}, [data, form]);
|
|
||||||
|
|
||||||
async function onSubmit(values: FormSchema) {
|
|
||||||
setLoading(true);
|
|
||||||
try {
|
|
||||||
await updateApplicationConfig({
|
|
||||||
...values,
|
|
||||||
domains: values.domains?.filter((domain) => domain),
|
|
||||||
} as API.ApplicationConfig);
|
|
||||||
toast.success(t('updateSuccess'));
|
|
||||||
refetch();
|
|
||||||
setOpen(false);
|
|
||||||
} catch (error) {
|
|
||||||
/* empty */
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Sheet open={open} onOpenChange={setOpen}>
|
|
||||||
<SheetTrigger asChild>
|
|
||||||
<Button variant='outline'>
|
|
||||||
<Icon icon='mdi:cog' className='mr-2' />
|
|
||||||
{t('config')}
|
|
||||||
</Button>
|
|
||||||
</SheetTrigger>
|
|
||||||
<SheetContent className='w-[520px] max-w-full md:max-w-screen-md'>
|
|
||||||
<SheetHeader>
|
|
||||||
<SheetTitle>{t('configApp')}</SheetTitle>
|
|
||||||
</SheetHeader>
|
|
||||||
<ScrollArea className='h-[calc(100dvh-48px-36px-36px)]'>
|
|
||||||
<Form {...form}>
|
|
||||||
<form className='space-y-4 py-4'>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name='app_id'
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('selectApp')}</FormLabel>
|
|
||||||
<FormDescription>{t('selectAppDescription')}</FormDescription>
|
|
||||||
<FormControl>
|
|
||||||
<Combobox
|
|
||||||
{...field}
|
|
||||||
options={
|
|
||||||
applications?.map((app) => ({
|
|
||||||
label: app.name,
|
|
||||||
value: app.id,
|
|
||||||
})) || []
|
|
||||||
}
|
|
||||||
value={field.value}
|
|
||||||
onChange={(value) => form.setValue(field.name, value)}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name='encryption_key'
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('communicationKey')}</FormLabel>
|
|
||||||
<FormDescription>{t('communicationKeyDescription')}</FormDescription>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
value={field.value}
|
|
||||||
onValueChange={(value) => form.setValue(field.name, value as string)}
|
|
||||||
suffix={
|
|
||||||
<div className='bg-muted flex h-9 items-center text-nowrap px-3'>
|
|
||||||
<DicesIcon
|
|
||||||
onClick={() => {
|
|
||||||
const id = uid(32).toLowerCase();
|
|
||||||
const formatted = `${id.slice(0, 8)}-${id.slice(8, 12)}-${id.slice(12, 16)}-${id.slice(16, 20)}-${id.slice(20)}`;
|
|
||||||
form.setValue(field.name, formatted);
|
|
||||||
}}
|
|
||||||
className='cursor-pointer'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name='encryption_method'
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('encryption')}</FormLabel>
|
|
||||||
<FormDescription>{t('encryptionDescription')}</FormDescription>
|
|
||||||
<FormControl>
|
|
||||||
<Combobox
|
|
||||||
options={[
|
|
||||||
{ label: 'none', value: 'none' },
|
|
||||||
{ label: 'AES', value: 'aes' },
|
|
||||||
]}
|
|
||||||
value={field.value}
|
|
||||||
onChange={(value) => form.setValue(field.name, value)}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name='startup_picture'
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('startupPicture')}</FormLabel>
|
|
||||||
<FormDescription>{t('startupPictureDescription')}</FormDescription>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
value={field.value}
|
|
||||||
onValueChange={(value) => form.setValue(field.name, value as string)}
|
|
||||||
suffix={
|
|
||||||
<UploadImage
|
|
||||||
className='bg-muted h-9 rounded-none border-none px-2'
|
|
||||||
onChange={(value) => form.setValue('startup_picture', value as string)}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name='startup_picture_skip_time'
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('startupPictureSkip')}</FormLabel>
|
|
||||||
<FormDescription>{t('startupPictureSkipDescription')}</FormDescription>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
{...field}
|
|
||||||
type='number'
|
|
||||||
min={0}
|
|
||||||
suffix='S'
|
|
||||||
value={field.value}
|
|
||||||
onValueChange={(value) =>
|
|
||||||
form.setValue('startup_picture_skip_time', Number(value))
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name='domains'
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className='px-1'>
|
|
||||||
<FormLabel>{t('backupDomains')}</FormLabel>
|
|
||||||
<FormDescription>{t('backupDomainsDescription')}</FormDescription>
|
|
||||||
<FormControl>
|
|
||||||
<Textarea
|
|
||||||
className='h-28'
|
|
||||||
placeholder='example.com'
|
|
||||||
value={field.value?.join('\n')}
|
|
||||||
onChange={(e) => {
|
|
||||||
form.setValue(field.name, e.target.value.split('\n'));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</ScrollArea>
|
|
||||||
<SheetFooter className='flex-row justify-end gap-2 pt-3'>
|
|
||||||
<Button variant='outline' onClick={() => setOpen(false)}>
|
|
||||||
{t('cancel')}
|
|
||||||
</Button>
|
|
||||||
<Button onClick={form.handleSubmit(onSubmit)} disabled={loading}>
|
|
||||||
{loading && <Icon icon='mdi:loading' className='mr-2 animate-spin' />}
|
|
||||||
{t('confirm')}
|
|
||||||
</Button>
|
|
||||||
</SheetFooter>
|
|
||||||
</SheetContent>
|
|
||||||
</Sheet>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,303 +0,0 @@
|
|||||||
'use client';
|
|
||||||
|
|
||||||
import { getSubscribeType } from '@/services/admin/system';
|
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
|
||||||
import { Icon } from '@iconify/react';
|
|
||||||
import { useQuery } from '@tanstack/react-query';
|
|
||||||
import { Button } from '@workspace/ui/components/button';
|
|
||||||
import {
|
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from '@workspace/ui/components/form';
|
|
||||||
import { ScrollArea } from '@workspace/ui/components/scroll-area';
|
|
||||||
import {
|
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from '@workspace/ui/components/select';
|
|
||||||
import {
|
|
||||||
Sheet,
|
|
||||||
SheetContent,
|
|
||||||
SheetFooter,
|
|
||||||
SheetHeader,
|
|
||||||
SheetTitle,
|
|
||||||
SheetTrigger,
|
|
||||||
} from '@workspace/ui/components/sheet';
|
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@workspace/ui/components/tabs';
|
|
||||||
import { ArrayInput } from '@workspace/ui/custom-components/dynamic-Inputs';
|
|
||||||
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
|
|
||||||
import { UploadImage } from '@workspace/ui/custom-components/upload-image';
|
|
||||||
import { useTranslations } from 'next-intl';
|
|
||||||
import { assign, shake } from 'radash';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { useForm } from 'react-hook-form';
|
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
const platforms = ['windows', 'macos', 'linux', 'android', 'ios', 'harmony'];
|
|
||||||
|
|
||||||
const defaultValues = {
|
|
||||||
subscribe_type: 'Clash',
|
|
||||||
name: '',
|
|
||||||
icon: '',
|
|
||||||
url: '',
|
|
||||||
};
|
|
||||||
|
|
||||||
const versionSchema = z.object({
|
|
||||||
url: z.string(),
|
|
||||||
version: z.string().optional(),
|
|
||||||
description: z.string().optional(),
|
|
||||||
is_default: z.boolean().optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const formSchema = z.object({
|
|
||||||
icon: z.string(),
|
|
||||||
name: z.string(),
|
|
||||||
subscribe_type: z.string(),
|
|
||||||
platform: z.object({
|
|
||||||
windows: z.array(versionSchema).optional(),
|
|
||||||
macos: z.array(versionSchema).optional(),
|
|
||||||
linux: z.array(versionSchema).optional(),
|
|
||||||
android: z.array(versionSchema).optional(),
|
|
||||||
ios: z.array(versionSchema).optional(),
|
|
||||||
harmony: z.array(versionSchema).optional(),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
interface FormProps<T> {
|
|
||||||
trigger: React.ReactNode | string;
|
|
||||||
title: string;
|
|
||||||
initialValues?: Partial<T>;
|
|
||||||
onSubmit: (values: T) => Promise<boolean>;
|
|
||||||
loading?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function SubscribeAppForm<
|
|
||||||
T extends API.CreateApplicationRequest | API.UpdateApplicationRequest,
|
|
||||||
>({ trigger, title, loading, initialValues, onSubmit }: FormProps<T>) {
|
|
||||||
const t = useTranslations('product.app');
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
|
|
||||||
type FormSchema = z.infer<typeof formSchema>;
|
|
||||||
|
|
||||||
const form = useForm<FormSchema>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: assign(
|
|
||||||
defaultValues,
|
|
||||||
shake(initialValues, (value) => value === null),
|
|
||||||
),
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
form.reset(
|
|
||||||
assign(
|
|
||||||
defaultValues,
|
|
||||||
shake(initialValues, (value) => value === null),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}, [form, initialValues]);
|
|
||||||
|
|
||||||
const { data: subscribe_types } = useQuery<string[]>({
|
|
||||||
queryKey: ['getSubscribeType'],
|
|
||||||
queryFn: async () => {
|
|
||||||
const { data } = await getSubscribeType();
|
|
||||||
return data.data?.subscribe_types || [];
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Sheet open={open} onOpenChange={setOpen}>
|
|
||||||
<SheetTrigger asChild>
|
|
||||||
{typeof trigger === 'string' ? <Button>{trigger}</Button> : trigger}
|
|
||||||
</SheetTrigger>
|
|
||||||
<SheetContent className='w-[520px] max-w-full md:max-w-screen-md'>
|
|
||||||
<SheetHeader>
|
|
||||||
<SheetTitle>{title}</SheetTitle>
|
|
||||||
</SheetHeader>
|
|
||||||
<ScrollArea className='h-[calc(100dvh-48px-36px-36px)]'>
|
|
||||||
<Form {...form}>
|
|
||||||
<form className='space-y-4 py-4'>
|
|
||||||
<div className='grid grid-cols-2 gap-4'>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name='icon'
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className='col-span-2'>
|
|
||||||
<FormLabel>{t('appIcon')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
required
|
|
||||||
suffix={
|
|
||||||
<UploadImage
|
|
||||||
className='bg-muted h-9 rounded-none border-none px-2'
|
|
||||||
onChange={(value) => {
|
|
||||||
form.setValue(field.name, value as string);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
value={field.value}
|
|
||||||
onValueChange={(value) => {
|
|
||||||
form.setValue(field.name, value as string);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name='name'
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('appName')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<EnhancedInput
|
|
||||||
required
|
|
||||||
type='text'
|
|
||||||
value={field.value}
|
|
||||||
onValueChange={(value) => {
|
|
||||||
form.setValue(field.name, value as string);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name='subscribe_type'
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('subscriptionProtocol')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Select value={field.value} onValueChange={field.onChange}>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder={t('subscriptionProtocol')} />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
{subscribe_types?.map((type) => (
|
|
||||||
<SelectItem key={type} value={type}>
|
|
||||||
{type}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('platform')}</FormLabel>
|
|
||||||
<Tabs defaultValue={platforms[0]}>
|
|
||||||
<TabsList>
|
|
||||||
{platforms.map((platform) => (
|
|
||||||
<TabsTrigger key={platform} value={platform} className='uppercase'>
|
|
||||||
{platform}
|
|
||||||
</TabsTrigger>
|
|
||||||
))}
|
|
||||||
</TabsList>
|
|
||||||
{platforms.map((platform) => (
|
|
||||||
<TabsContent key={platform} value={platform}>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name={`platform.${platform as keyof FormSchema['platform']}`}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormControl>
|
|
||||||
<ArrayInput
|
|
||||||
isReverse
|
|
||||||
className='grid grid-cols-3 gap-4'
|
|
||||||
fields={[
|
|
||||||
{
|
|
||||||
name: 'version',
|
|
||||||
type: 'text',
|
|
||||||
placeholder: t('version'),
|
|
||||||
defaultValue: '1.0.0',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'description',
|
|
||||||
type: 'text',
|
|
||||||
placeholder: t('description'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'is_default',
|
|
||||||
type: 'boolean',
|
|
||||||
placeholder: t('defaultVersion'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'url',
|
|
||||||
type: 'text',
|
|
||||||
placeholder: t('downloadLink'),
|
|
||||||
className: 'col-span-3',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
value={field.value}
|
|
||||||
onChange={(value) => {
|
|
||||||
const filteredValue = value.filter((item) => item.url);
|
|
||||||
|
|
||||||
const newDefaultIndex = value.findIndex(
|
|
||||||
(item, idx) =>
|
|
||||||
item.is_default &&
|
|
||||||
(!field.value?.[idx] || !field.value[idx].is_default),
|
|
||||||
);
|
|
||||||
|
|
||||||
let finalValue = filteredValue;
|
|
||||||
|
|
||||||
if (newDefaultIndex >= 0 && filteredValue[newDefaultIndex]) {
|
|
||||||
finalValue = filteredValue.map((item, index) => ({
|
|
||||||
...item,
|
|
||||||
is_default: index === newDefaultIndex,
|
|
||||||
}));
|
|
||||||
} else if (
|
|
||||||
!filteredValue.some((item) => item.is_default) &&
|
|
||||||
filteredValue.length > 0
|
|
||||||
) {
|
|
||||||
finalValue = filteredValue.map((item, index) => ({
|
|
||||||
...item,
|
|
||||||
is_default: index === 0,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
form.setValue(field.name, finalValue as any);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</TabsContent>
|
|
||||||
))}
|
|
||||||
</Tabs>
|
|
||||||
</FormItem>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</ScrollArea>
|
|
||||||
<SheetFooter className='flex-row justify-end gap-2 pt-3'>
|
|
||||||
<Button variant='outline' onClick={() => setOpen(false)}>
|
|
||||||
{t('cancel')}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
onClick={form.handleSubmit(async (values) => {
|
|
||||||
const success = await onSubmit(values as unknown as T);
|
|
||||||
if (success) setOpen(false);
|
|
||||||
})}
|
|
||||||
disabled={loading}
|
|
||||||
>
|
|
||||||
{loading && <Icon icon='mdi:loading' className='mr-2 animate-spin' />}
|
|
||||||
{t('confirm')}
|
|
||||||
</Button>
|
|
||||||
</SheetFooter>
|
|
||||||
</SheetContent>
|
|
||||||
</Sheet>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,143 +0,0 @@
|
|||||||
'use client';
|
|
||||||
|
|
||||||
import { ProTable, ProTableActions } from '@/components/pro-table';
|
|
||||||
import {
|
|
||||||
createApplication,
|
|
||||||
deleteApplication,
|
|
||||||
getApplication,
|
|
||||||
updateApplication,
|
|
||||||
} from '@/services/admin/system';
|
|
||||||
import { Button } from '@workspace/ui/components/button';
|
|
||||||
import { ConfirmButton } from '@workspace/ui/custom-components/confirm-button';
|
|
||||||
import { useTranslations } from 'next-intl';
|
|
||||||
import Image from 'next/legacy/image';
|
|
||||||
import { useRef, useState } from 'react';
|
|
||||||
import { toast } from 'sonner';
|
|
||||||
import ConfigForm from './config';
|
|
||||||
import SubscribeAppForm from './form';
|
|
||||||
|
|
||||||
export default function SubscribeApp() {
|
|
||||||
const t = useTranslations('product.app');
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const ref = useRef<ProTableActions>(null);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ProTable<API.ApplicationResponseInfo, Record<string, unknown>>
|
|
||||||
action={ref}
|
|
||||||
header={{
|
|
||||||
title: t('appList'),
|
|
||||||
toolbar: (
|
|
||||||
<div className='flex items-center gap-2'>
|
|
||||||
<ConfigForm />
|
|
||||||
<SubscribeAppForm<API.CreateApplicationRequest>
|
|
||||||
trigger={t('create')}
|
|
||||||
title={t('createApp')}
|
|
||||||
loading={loading}
|
|
||||||
onSubmit={async (values) => {
|
|
||||||
setLoading(true);
|
|
||||||
try {
|
|
||||||
await createApplication(values);
|
|
||||||
toast.success(t('createSuccess'));
|
|
||||||
ref.current?.refresh();
|
|
||||||
setLoading(false);
|
|
||||||
return true;
|
|
||||||
} catch (error) {
|
|
||||||
setLoading(false);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
request={async (_pagination, filters) => {
|
|
||||||
const { data } = await getApplication();
|
|
||||||
return {
|
|
||||||
list: data.data?.applications || [],
|
|
||||||
total: 0,
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
columns={[
|
|
||||||
{
|
|
||||||
accessorKey: 'icon',
|
|
||||||
header: t('appIcon'),
|
|
||||||
cell: ({ row }) => (
|
|
||||||
<Image
|
|
||||||
src={row.getValue('icon')}
|
|
||||||
alt={row.getValue('name')}
|
|
||||||
className='h-8 w-8 rounded-md'
|
|
||||||
width={32}
|
|
||||||
height={32}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessorKey: 'name',
|
|
||||||
header: t('appName'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessorKey: 'subscribe_type',
|
|
||||||
header: t('subscriptionProtocol'),
|
|
||||||
cell: ({ row }) => row.getValue('subscribe_type'),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
actions={{
|
|
||||||
render: (row) => [
|
|
||||||
<SubscribeAppForm<API.UpdateApplicationRequest>
|
|
||||||
key='edit'
|
|
||||||
trigger={<Button>{t('edit')}</Button>}
|
|
||||||
title={t('editApp')}
|
|
||||||
loading={loading}
|
|
||||||
initialValues={{
|
|
||||||
...row,
|
|
||||||
}}
|
|
||||||
onSubmit={async (values) => {
|
|
||||||
setLoading(true);
|
|
||||||
try {
|
|
||||||
await updateApplication({
|
|
||||||
...values,
|
|
||||||
id: row.id,
|
|
||||||
});
|
|
||||||
toast.success(t('updateSuccess'));
|
|
||||||
ref.current?.refresh();
|
|
||||||
setLoading(false);
|
|
||||||
return true;
|
|
||||||
} catch (error) {
|
|
||||||
setLoading(false);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>,
|
|
||||||
<ConfirmButton
|
|
||||||
key='delete'
|
|
||||||
trigger={<Button variant='destructive'>{t('delete')}</Button>}
|
|
||||||
title={t('confirmDelete')}
|
|
||||||
description={t('deleteWarning')}
|
|
||||||
onConfirm={async () => {
|
|
||||||
await deleteApplication({ id: row.id! });
|
|
||||||
toast.success(t('deleteSuccess'));
|
|
||||||
ref.current?.refresh();
|
|
||||||
}}
|
|
||||||
cancelText={t('cancel')}
|
|
||||||
confirmText={t('confirm')}
|
|
||||||
/>,
|
|
||||||
],
|
|
||||||
batchRender: (rows) => [
|
|
||||||
<ConfirmButton
|
|
||||||
key='delete'
|
|
||||||
trigger={<Button variant='destructive'>{t('batchDelete')}</Button>}
|
|
||||||
title={t('confirmDelete')}
|
|
||||||
description={t('deleteWarning')}
|
|
||||||
onConfirm={async () => {
|
|
||||||
await Promise.all(rows.map((row) => deleteApplication({ id: row.id! })));
|
|
||||||
toast.success(t('deleteSuccess'));
|
|
||||||
ref.current?.reset();
|
|
||||||
}}
|
|
||||||
cancelText={t('cancel')}
|
|
||||||
confirmText={t('confirm')}
|
|
||||||
/>,
|
|
||||||
],
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -138,7 +138,6 @@ export function ProtocolForm() {
|
|||||||
onCheckedChange={async (checked) => {
|
onCheckedChange={async (checked) => {
|
||||||
await updateSubscribeApplication({
|
await updateSubscribeApplication({
|
||||||
...row.original,
|
...row.original,
|
||||||
proxy_template: '',
|
|
||||||
is_default: checked,
|
is_default: checked,
|
||||||
});
|
});
|
||||||
tableRef.current?.refresh();
|
tableRef.current?.refresh();
|
||||||
@ -289,7 +288,6 @@ export function ProtocolForm() {
|
|||||||
if (editingClient) {
|
if (editingClient) {
|
||||||
await updateSubscribeApplication({
|
await updateSubscribeApplication({
|
||||||
...data,
|
...data,
|
||||||
proxy_template: '',
|
|
||||||
is_default: editingClient.is_default,
|
is_default: editingClient.is_default,
|
||||||
id: editingClient.id,
|
id: editingClient.id,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -53,11 +53,6 @@ export const navs = [
|
|||||||
url: '/dashboard/product',
|
url: '/dashboard/product',
|
||||||
icon: 'flat-color-icons:shop',
|
icon: 'flat-color-icons:shop',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: 'Application Management',
|
|
||||||
url: '/dashboard/application',
|
|
||||||
icon: 'flat-color-icons:touchscreen-smartphone',
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,46 +1,5 @@
|
|||||||
{
|
{
|
||||||
"actions": "Actions",
|
"actions": "Actions",
|
||||||
"app": {
|
|
||||||
"appDownloadURL": "App Download URL",
|
|
||||||
"appIcon": "App Icon",
|
|
||||||
"appList": "App List",
|
|
||||||
"appName": "App Name",
|
|
||||||
"backupDomains": "Backup Domain List",
|
|
||||||
"backupDomainsDescription": "Backup domain list for domain resolution, one domain per line",
|
|
||||||
"batchDelete": "Batch Delete",
|
|
||||||
"cancel": "Cancel",
|
|
||||||
"communicationKey": "Communication Key",
|
|
||||||
"communicationKeyDescription": "Key used for client communication",
|
|
||||||
"config": "Config",
|
|
||||||
"configApp": "App Configuration",
|
|
||||||
"confirm": "Confirm",
|
|
||||||
"confirmDelete": "Are you sure you want to delete?",
|
|
||||||
"create": "Create",
|
|
||||||
"createApp": "Create App",
|
|
||||||
"createSuccess": "Created successfully",
|
|
||||||
"defaultVersion": "Default",
|
|
||||||
"delete": "Delete",
|
|
||||||
"deleteWarning": "Data cannot be recovered after deletion. Please proceed with caution.",
|
|
||||||
"describeDescription": "Used to describe the application, displayed in the app list",
|
|
||||||
"description": "Description",
|
|
||||||
"downloadLink": "Download Link",
|
|
||||||
"edit": "Edit",
|
|
||||||
"editApp": "Edit App",
|
|
||||||
"encryption": "Encryption Method",
|
|
||||||
"encryptionDescription": "Choose the encryption method for client communication. If selected, the client will use this method to communicate with the server",
|
|
||||||
"nameDescription": "Application name, displayed in the app list",
|
|
||||||
"platform": "Platform",
|
|
||||||
"selectApp": "Select App",
|
|
||||||
"selectAppDescription": "Select the app to configure, all settings will apply to the selected app",
|
|
||||||
"startupPicture": "Startup Picture",
|
|
||||||
"startupPictureDescription": "Startup picture, supports network and local images. For network images, please enter the complete image URL",
|
|
||||||
"startupPicturePreview": "Startup Picture Preview",
|
|
||||||
"startupPictureSkip": "Startup Picture Skip Time",
|
|
||||||
"startupPictureSkipDescription": "Startup picture display time in seconds, enter 0 to not display",
|
|
||||||
"subscriptionProtocol": "Subscription Protocol",
|
|
||||||
"updateSuccess": "Updated successfully",
|
|
||||||
"version": "Version"
|
|
||||||
},
|
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"confirm": "Confirm",
|
"confirm": "Confirm",
|
||||||
"confirmDelete": "Are you sure you want to delete?",
|
"confirmDelete": "Are you sure you want to delete?",
|
||||||
|
|||||||
@ -1,46 +1,5 @@
|
|||||||
{
|
{
|
||||||
"actions": "操作",
|
"actions": "操作",
|
||||||
"app": {
|
|
||||||
"appDownloadURL": "应用下载链接",
|
|
||||||
"appIcon": "应用图标",
|
|
||||||
"appList": "应用列表",
|
|
||||||
"appName": "应用名称",
|
|
||||||
"backupDomains": "备用域名列表",
|
|
||||||
"backupDomainsDescription": "用于域名解析的备用域名列表,每行一个域名",
|
|
||||||
"batchDelete": "批量删除",
|
|
||||||
"cancel": "取消",
|
|
||||||
"communicationKey": "通信密钥",
|
|
||||||
"communicationKeyDescription": "用于客户端通信的密钥",
|
|
||||||
"config": "配置",
|
|
||||||
"configApp": "应用配置",
|
|
||||||
"confirm": "确认",
|
|
||||||
"confirmDelete": "确认删除",
|
|
||||||
"create": "创建",
|
|
||||||
"createApp": "创建应用",
|
|
||||||
"createSuccess": "创建成功",
|
|
||||||
"defaultVersion": "默认",
|
|
||||||
"delete": "删除",
|
|
||||||
"deleteWarning": "此操作无法撤销",
|
|
||||||
"describeDescription": "用于描述应用程序,显示在应用列表中",
|
|
||||||
"description": "描述",
|
|
||||||
"downloadLink": "下载链接",
|
|
||||||
"edit": "编辑",
|
|
||||||
"editApp": "编辑应用",
|
|
||||||
"encryption": "加密方法",
|
|
||||||
"encryptionDescription": "选择用于客户端通信的加密方法。如果选择,客户端将使用此方法与服务器通信",
|
|
||||||
"nameDescription": "应用程序名称,显示在应用列表中",
|
|
||||||
"platform": "平台",
|
|
||||||
"selectApp": "选择应用",
|
|
||||||
"selectAppDescription": "选择要配置的应用,所有设置将应用于所选应用",
|
|
||||||
"startupPicture": "启动图片",
|
|
||||||
"startupPictureDescription": "启动图片,支持网络和本地图片。对于网络图片,请输入完整的图片URL",
|
|
||||||
"startupPicturePreview": "启动图片预览",
|
|
||||||
"startupPictureSkip": "启动图片跳过时间",
|
|
||||||
"startupPictureSkipDescription": "启动图片显示时间(秒),输入0表示不显示",
|
|
||||||
"subscriptionProtocol": "订阅协议",
|
|
||||||
"updateSuccess": "更新成功",
|
|
||||||
"version": "版本"
|
|
||||||
},
|
|
||||||
"cancel": "取消",
|
"cancel": "取消",
|
||||||
"confirm": "确认",
|
"confirm": "确认",
|
||||||
"confirmDelete": "确定删除吗?",
|
"confirmDelete": "确定删除吗?",
|
||||||
|
|||||||
@ -2,133 +2,6 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import request from '@/utils/request';
|
import request from '@/utils/request';
|
||||||
|
|
||||||
/** Get application GET /v1/admin/system/application */
|
|
||||||
export async function getApplication(options?: { [key: string]: any }) {
|
|
||||||
return request<API.Response & { data?: API.ApplicationResponse }>(
|
|
||||||
'/v1/admin/system/application',
|
|
||||||
{
|
|
||||||
method: 'GET',
|
|
||||||
...(options || {}),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Update application PUT /v1/admin/system/application */
|
|
||||||
export async function updateApplication(
|
|
||||||
body: API.UpdateApplicationRequest,
|
|
||||||
options?: { [key: string]: any },
|
|
||||||
) {
|
|
||||||
return request<API.Response & { data?: any }>('/v1/admin/system/application', {
|
|
||||||
method: 'PUT',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
data: body,
|
|
||||||
...(options || {}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create application POST /v1/admin/system/application */
|
|
||||||
export async function createApplication(
|
|
||||||
body: API.CreateApplicationRequest,
|
|
||||||
options?: { [key: string]: any },
|
|
||||||
) {
|
|
||||||
return request<API.Response & { data?: any }>('/v1/admin/system/application', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
data: body,
|
|
||||||
...(options || {}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Delete application DELETE /v1/admin/system/application */
|
|
||||||
export async function deleteApplication(
|
|
||||||
body: API.DeleteApplicationRequest,
|
|
||||||
options?: { [key: string]: any },
|
|
||||||
) {
|
|
||||||
return request<API.Response & { data?: any }>('/v1/admin/system/application', {
|
|
||||||
method: 'DELETE',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
data: body,
|
|
||||||
...(options || {}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** get application config GET /v1/admin/system/application_config */
|
|
||||||
export async function getApplicationConfig(options?: { [key: string]: any }) {
|
|
||||||
return request<API.Response & { data?: API.ApplicationConfig }>(
|
|
||||||
'/v1/admin/system/application_config',
|
|
||||||
{
|
|
||||||
method: 'GET',
|
|
||||||
...(options || {}),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** update application config PUT /v1/admin/system/application_config */
|
|
||||||
export async function updateApplicationConfig(
|
|
||||||
body: API.ApplicationConfig,
|
|
||||||
options?: { [key: string]: any },
|
|
||||||
) {
|
|
||||||
return request<API.Response & { data?: any }>('/v1/admin/system/application_config', {
|
|
||||||
method: 'PUT',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
data: body,
|
|
||||||
...(options || {}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Update application version PUT /v1/admin/system/application_version */
|
|
||||||
export async function updateApplicationVersion(
|
|
||||||
body: API.UpdateApplicationVersionRequest,
|
|
||||||
options?: { [key: string]: any },
|
|
||||||
) {
|
|
||||||
return request<API.Response & { data?: any }>('/v1/admin/system/application_version', {
|
|
||||||
method: 'PUT',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
data: body,
|
|
||||||
...(options || {}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Create application version POST /v1/admin/system/application_version */
|
|
||||||
export async function createApplicationVersion(
|
|
||||||
body: API.CreateApplicationVersionRequest,
|
|
||||||
options?: { [key: string]: any },
|
|
||||||
) {
|
|
||||||
return request<API.Response & { data?: any }>('/v1/admin/system/application_version', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
data: body,
|
|
||||||
...(options || {}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Delete application DELETE /v1/admin/system/application_version */
|
|
||||||
export async function deleteApplicationVersion(
|
|
||||||
body: API.DeleteApplicationVersionRequest,
|
|
||||||
options?: { [key: string]: any },
|
|
||||||
) {
|
|
||||||
return request<API.Response & { data?: any }>('/v1/admin/system/application_version', {
|
|
||||||
method: 'DELETE',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
data: body,
|
|
||||||
...(options || {}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get Currency Config GET /v1/admin/system/currency_config */
|
/** Get Currency Config GET /v1/admin/system/currency_config */
|
||||||
export async function getCurrencyConfig(options?: { [key: string]: any }) {
|
export async function getCurrencyConfig(options?: { [key: string]: any }) {
|
||||||
return request<API.Response & { data?: API.CurrencyConfig }>('/v1/admin/system/currency_config', {
|
return request<API.Response & { data?: API.CurrencyConfig }>('/v1/admin/system/currency_config', {
|
||||||
|
|||||||
54
apps/admin/services/admin/typings.d.ts
vendored
54
apps/admin/services/admin/typings.d.ts
vendored
@ -41,15 +41,6 @@ declare namespace API {
|
|||||||
subscribe_type: string;
|
subscribe_type: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ApplicationConfig = {
|
|
||||||
app_id: number;
|
|
||||||
encryption_key: string;
|
|
||||||
encryption_method: string;
|
|
||||||
domains: string[];
|
|
||||||
startup_picture: string;
|
|
||||||
startup_picture_skip_time: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ApplicationPlatform = {
|
type ApplicationPlatform = {
|
||||||
ios?: ApplicationVersion[];
|
ios?: ApplicationVersion[];
|
||||||
macos?: ApplicationVersion[];
|
macos?: ApplicationVersion[];
|
||||||
@ -223,23 +214,6 @@ declare namespace API {
|
|||||||
content: string;
|
content: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type CreateApplicationRequest = {
|
|
||||||
icon: string;
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
subscribe_type: string;
|
|
||||||
platform: ApplicationPlatform;
|
|
||||||
};
|
|
||||||
|
|
||||||
type CreateApplicationVersionRequest = {
|
|
||||||
url: string;
|
|
||||||
version: string;
|
|
||||||
description: string;
|
|
||||||
platform: 'windows' | 'mac' | 'linux' | 'android' | 'ios' | 'harmony';
|
|
||||||
is_default: boolean;
|
|
||||||
application_id: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type CreateBatchSendEmailTaskRequest = {
|
type CreateBatchSendEmailTaskRequest = {
|
||||||
subject: string;
|
subject: string;
|
||||||
content: string;
|
content: string;
|
||||||
@ -424,14 +398,6 @@ declare namespace API {
|
|||||||
id: number;
|
id: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DeleteApplicationRequest = {
|
|
||||||
id: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type DeleteApplicationVersionRequest = {
|
|
||||||
id: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type DeleteCouponRequest = {
|
type DeleteCouponRequest = {
|
||||||
id: number;
|
id: number;
|
||||||
};
|
};
|
||||||
@ -1682,25 +1648,6 @@ declare namespace API {
|
|||||||
popup: boolean;
|
popup: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type UpdateApplicationRequest = {
|
|
||||||
id: number;
|
|
||||||
icon: string;
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
subscribe_type: string;
|
|
||||||
platform: ApplicationPlatform;
|
|
||||||
};
|
|
||||||
|
|
||||||
type UpdateApplicationVersionRequest = {
|
|
||||||
id: number;
|
|
||||||
url: string;
|
|
||||||
version: string;
|
|
||||||
description: string;
|
|
||||||
platform: 'windows' | 'mac' | 'linux' | 'android' | 'ios' | 'harmony';
|
|
||||||
is_default: boolean;
|
|
||||||
application_id: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type UpdateAuthMethodConfigRequest = {
|
type UpdateAuthMethodConfigRequest = {
|
||||||
id: number;
|
id: number;
|
||||||
method: string;
|
method: string;
|
||||||
@ -1795,7 +1742,6 @@ declare namespace API {
|
|||||||
scheme?: string;
|
scheme?: string;
|
||||||
user_agent: string;
|
user_agent: string;
|
||||||
is_default: boolean;
|
is_default: boolean;
|
||||||
proxy_template: string;
|
|
||||||
template: string;
|
template: string;
|
||||||
output_format: string;
|
output_format: string;
|
||||||
download_link?: DownloadLink;
|
download_link?: DownloadLink;
|
||||||
|
|||||||
@ -17,14 +17,6 @@ export async function getAds(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get Tos Content GET /v1/common/application */
|
|
||||||
export async function getApplication(options?: { [key: string]: any }) {
|
|
||||||
return request<API.Response & { data?: API.GetAppcationResponse }>('/v1/common/application', {
|
|
||||||
method: 'GET',
|
|
||||||
...(options || {}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Check verification code POST /v1/common/check_verification_code */
|
/** Check verification code POST /v1/common/check_verification_code */
|
||||||
export async function checkVerificationCode(
|
export async function checkVerificationCode(
|
||||||
body: API.CheckVerificationCodeRequest,
|
body: API.CheckVerificationCodeRequest,
|
||||||
|
|||||||
14
apps/admin/services/common/typings.d.ts
vendored
14
apps/admin/services/common/typings.d.ts
vendored
@ -47,15 +47,6 @@ declare namespace API {
|
|||||||
subscribe_type: string;
|
subscribe_type: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ApplicationConfig = {
|
|
||||||
app_id: number;
|
|
||||||
encryption_key: string;
|
|
||||||
encryption_method: string;
|
|
||||||
domains: string[];
|
|
||||||
startup_picture: string;
|
|
||||||
startup_picture_skip_time: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ApplicationPlatform = {
|
type ApplicationPlatform = {
|
||||||
ios?: ApplicationVersion[];
|
ios?: ApplicationVersion[];
|
||||||
macos?: ApplicationVersion[];
|
macos?: ApplicationVersion[];
|
||||||
@ -265,11 +256,6 @@ declare namespace API {
|
|||||||
list: Ads[];
|
list: Ads[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type GetAppcationResponse = {
|
|
||||||
config: ApplicationConfig;
|
|
||||||
applications: ApplicationResponseInfo[];
|
|
||||||
};
|
|
||||||
|
|
||||||
type GetAvailablePaymentMethodsResponse = {
|
type GetAvailablePaymentMethodsResponse = {
|
||||||
list: PaymentMethod[];
|
list: PaymentMethod[];
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
/* eslint-disable */
|
|
||||||
import request from '@/utils/request';
|
import request from '@/utils/request';
|
||||||
|
|
||||||
/** Get Ads GET /v1/common/ads */
|
/** Get Ads GET /v1/common/ads */
|
||||||
@ -17,14 +17,6 @@ export async function getAds(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get Tos Content GET /v1/common/application */
|
|
||||||
export async function getApplication(options?: { [key: string]: any }) {
|
|
||||||
return request<API.Response & { data?: API.GetAppcationResponse }>('/v1/common/application', {
|
|
||||||
method: 'GET',
|
|
||||||
...(options || {}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Check verification code POST /v1/common/check_verification_code */
|
/** Check verification code POST /v1/common/check_verification_code */
|
||||||
export async function checkVerificationCode(
|
export async function checkVerificationCode(
|
||||||
body: API.CheckVerificationCodeRequest,
|
body: API.CheckVerificationCodeRequest,
|
||||||
|
|||||||
14
apps/user/services/common/typings.d.ts
vendored
14
apps/user/services/common/typings.d.ts
vendored
@ -47,15 +47,6 @@ declare namespace API {
|
|||||||
subscribe_type: string;
|
subscribe_type: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ApplicationConfig = {
|
|
||||||
app_id: number;
|
|
||||||
encryption_key: string;
|
|
||||||
encryption_method: string;
|
|
||||||
domains: string[];
|
|
||||||
startup_picture: string;
|
|
||||||
startup_picture_skip_time: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ApplicationPlatform = {
|
type ApplicationPlatform = {
|
||||||
ios?: ApplicationVersion[];
|
ios?: ApplicationVersion[];
|
||||||
macos?: ApplicationVersion[];
|
macos?: ApplicationVersion[];
|
||||||
@ -265,11 +256,6 @@ declare namespace API {
|
|||||||
list: Ads[];
|
list: Ads[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type GetAppcationResponse = {
|
|
||||||
config: ApplicationConfig;
|
|
||||||
applications: ApplicationResponseInfo[];
|
|
||||||
};
|
|
||||||
|
|
||||||
type GetAvailablePaymentMethodsResponse = {
|
type GetAvailablePaymentMethodsResponse = {
|
||||||
list: PaymentMethod[];
|
list: PaymentMethod[];
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,17 +2,6 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import request from '@/utils/request';
|
import request from '@/utils/request';
|
||||||
|
|
||||||
/** Get application config GET /v1/public/subscribe/application/config */
|
|
||||||
export async function queryApplicationConfig(options?: { [key: string]: any }) {
|
|
||||||
return request<API.Response & { data?: API.ApplicationResponse }>(
|
|
||||||
'/v1/public/subscribe/application/config',
|
|
||||||
{
|
|
||||||
method: 'GET',
|
|
||||||
...(options || {}),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get subscribe group list GET /v1/public/subscribe/group/list */
|
/** Get subscribe group list GET /v1/public/subscribe/group/list */
|
||||||
export async function querySubscribeGroupList(options?: { [key: string]: any }) {
|
export async function querySubscribeGroupList(options?: { [key: string]: any }) {
|
||||||
return request<API.Response & { data?: API.QuerySubscribeGroupListResponse }>(
|
return request<API.Response & { data?: API.QuerySubscribeGroupListResponse }>(
|
||||||
|
|||||||
9
apps/user/services/user/typings.d.ts
vendored
9
apps/user/services/user/typings.d.ts
vendored
@ -41,15 +41,6 @@ declare namespace API {
|
|||||||
subscribe_type: string;
|
subscribe_type: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ApplicationConfig = {
|
|
||||||
app_id: number;
|
|
||||||
encryption_key: string;
|
|
||||||
encryption_method: string;
|
|
||||||
domains: string[];
|
|
||||||
startup_picture: string;
|
|
||||||
startup_picture_skip_time: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ApplicationPlatform = {
|
type ApplicationPlatform = {
|
||||||
ios?: ApplicationVersion[];
|
ios?: ApplicationVersion[];
|
||||||
macos?: ApplicationVersion[];
|
macos?: ApplicationVersion[];
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user