mirror of
https://github.com/perfect-panel/ppanel-web.git
synced 2026-02-06 03:30:25 -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>
|
||||
|
||||
# Changelog
|
||||
|
||||
# [1.3.0](https://github.com/perfect-panel/ppanel-web/compare/v1.2.0...v1.3.0) (2025-08-15)
|
||||
|
||||
|
||||
### ♻ 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
|
||||
|
||||
* **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))
|
||||
* **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))
|
||||
|
||||
- **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))
|
||||
- **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))
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
* **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**: 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))
|
||||
* **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))
|
||||
* **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))
|
||||
* **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**: 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))
|
||||
* **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))
|
||||
* Update privacy policy and terms of service schemas to use correct field names ([0e6ba5b](https://github.com/perfect-panel/ppanel-web/commit/0e6ba5b))
|
||||
- **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**: 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))
|
||||
- **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))
|
||||
- **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))
|
||||
- **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**: 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))
|
||||
- **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))
|
||||
- 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>
|
||||
|
||||
|
||||
@ -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) => {
|
||||
await updateSubscribeApplication({
|
||||
...row.original,
|
||||
proxy_template: '',
|
||||
is_default: checked,
|
||||
});
|
||||
tableRef.current?.refresh();
|
||||
@ -289,7 +288,6 @@ export function ProtocolForm() {
|
||||
if (editingClient) {
|
||||
await updateSubscribeApplication({
|
||||
...data,
|
||||
proxy_template: '',
|
||||
is_default: editingClient.is_default,
|
||||
id: editingClient.id,
|
||||
});
|
||||
|
||||
@ -53,11 +53,6 @@ export const navs = [
|
||||
url: '/dashboard/product',
|
||||
icon: 'flat-color-icons:shop',
|
||||
},
|
||||
{
|
||||
title: 'Application Management',
|
||||
url: '/dashboard/application',
|
||||
icon: 'flat-color-icons:touchscreen-smartphone',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@ -1,46 +1,5 @@
|
||||
{
|
||||
"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",
|
||||
"confirm": "Confirm",
|
||||
"confirmDelete": "Are you sure you want to delete?",
|
||||
|
||||
@ -1,46 +1,5 @@
|
||||
{
|
||||
"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": "取消",
|
||||
"confirm": "确认",
|
||||
"confirmDelete": "确定删除吗?",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// @ts-ignore
|
||||
|
||||
|
||||
// API 更新时间:
|
||||
// API 唯一标识:
|
||||
import * as ads from './ads';
|
||||
|
||||
@ -2,133 +2,6 @@
|
||||
/* eslint-disable */
|
||||
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 */
|
||||
export async function getCurrencyConfig(options?: { [key: string]: any }) {
|
||||
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;
|
||||
};
|
||||
|
||||
type ApplicationConfig = {
|
||||
app_id: number;
|
||||
encryption_key: string;
|
||||
encryption_method: string;
|
||||
domains: string[];
|
||||
startup_picture: string;
|
||||
startup_picture_skip_time: number;
|
||||
};
|
||||
|
||||
type ApplicationPlatform = {
|
||||
ios?: ApplicationVersion[];
|
||||
macos?: ApplicationVersion[];
|
||||
@ -223,23 +214,6 @@ declare namespace API {
|
||||
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 = {
|
||||
subject: string;
|
||||
content: string;
|
||||
@ -424,14 +398,6 @@ declare namespace API {
|
||||
id: number;
|
||||
};
|
||||
|
||||
type DeleteApplicationRequest = {
|
||||
id: number;
|
||||
};
|
||||
|
||||
type DeleteApplicationVersionRequest = {
|
||||
id: number;
|
||||
};
|
||||
|
||||
type DeleteCouponRequest = {
|
||||
id: number;
|
||||
};
|
||||
@ -1682,25 +1648,6 @@ declare namespace API {
|
||||
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 = {
|
||||
id: number;
|
||||
method: string;
|
||||
@ -1795,7 +1742,6 @@ declare namespace API {
|
||||
scheme?: string;
|
||||
user_agent: string;
|
||||
is_default: boolean;
|
||||
proxy_template: string;
|
||||
template: string;
|
||||
output_format: string;
|
||||
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 */
|
||||
export async function checkVerificationCode(
|
||||
body: API.CheckVerificationCodeRequest,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// @ts-ignore
|
||||
|
||||
|
||||
// API 更新时间:
|
||||
// API 唯一标识:
|
||||
import * as auth from './auth';
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
type ApplicationConfig = {
|
||||
app_id: number;
|
||||
encryption_key: string;
|
||||
encryption_method: string;
|
||||
domains: string[];
|
||||
startup_picture: string;
|
||||
startup_picture_skip_time: number;
|
||||
};
|
||||
|
||||
type ApplicationPlatform = {
|
||||
ios?: ApplicationVersion[];
|
||||
macos?: ApplicationVersion[];
|
||||
@ -265,11 +256,6 @@ declare namespace API {
|
||||
list: Ads[];
|
||||
};
|
||||
|
||||
type GetAppcationResponse = {
|
||||
config: ApplicationConfig;
|
||||
applications: ApplicationResponseInfo[];
|
||||
};
|
||||
|
||||
type GetAvailablePaymentMethodsResponse = {
|
||||
list: PaymentMethod[];
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// @ts-ignore
|
||||
/* eslint-disable */
|
||||
|
||||
import request from '@/utils/request';
|
||||
|
||||
/** 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 */
|
||||
export async function checkVerificationCode(
|
||||
body: API.CheckVerificationCodeRequest,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// @ts-ignore
|
||||
|
||||
|
||||
// API 更新时间:
|
||||
// API 唯一标识:
|
||||
import * as auth from './auth';
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
type ApplicationConfig = {
|
||||
app_id: number;
|
||||
encryption_key: string;
|
||||
encryption_method: string;
|
||||
domains: string[];
|
||||
startup_picture: string;
|
||||
startup_picture_skip_time: number;
|
||||
};
|
||||
|
||||
type ApplicationPlatform = {
|
||||
ios?: ApplicationVersion[];
|
||||
macos?: ApplicationVersion[];
|
||||
@ -265,11 +256,6 @@ declare namespace API {
|
||||
list: Ads[];
|
||||
};
|
||||
|
||||
type GetAppcationResponse = {
|
||||
config: ApplicationConfig;
|
||||
applications: ApplicationResponseInfo[];
|
||||
};
|
||||
|
||||
type GetAvailablePaymentMethodsResponse = {
|
||||
list: PaymentMethod[];
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// @ts-ignore
|
||||
|
||||
|
||||
// API 更新时间:
|
||||
// API 唯一标识:
|
||||
import * as announcement from './announcement';
|
||||
|
||||
@ -2,17 +2,6 @@
|
||||
/* eslint-disable */
|
||||
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 */
|
||||
export async function querySubscribeGroupList(options?: { [key: string]: any }) {
|
||||
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;
|
||||
};
|
||||
|
||||
type ApplicationConfig = {
|
||||
app_id: number;
|
||||
encryption_key: string;
|
||||
encryption_method: string;
|
||||
domains: string[];
|
||||
startup_picture: string;
|
||||
startup_picture_skip_time: number;
|
||||
};
|
||||
|
||||
type ApplicationPlatform = {
|
||||
ios?: ApplicationVersion[];
|
||||
macos?: ApplicationVersion[];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user