diff --git a/src/pages/app/package/index.tsx b/src/pages/app/package/index.tsx
index dbcdee6..6a5c1cd 100644
--- a/src/pages/app/package/index.tsx
+++ b/src/pages/app/package/index.tsx
@@ -1,11 +1,11 @@
-import { useTranslation } from '@/i18n.ts'
-import { Button, Form, Popconfirm, Divider, Space, Tooltip, Badge } from 'antd'
-import { useAtom, useAtomValue } from 'jotai'
+import {useTranslation} from '@/i18n.ts'
+import {Button, Form, Popconfirm, Divider, Space, Tooltip, Badge} from 'antd'
+import {useAtom, useAtomValue} from 'jotai'
import {
deleteAppPackageAtom,
saveOrUpdateAppPackageAtom, appPackageAtom, appPackagesAtom, appPackageSearchAtom, packageAppAtom,
} from '@/store/app/package'
-import { useEffect, useMemo, useState } from 'react'
+import {useEffect, useMemo, useState} from 'react'
import Action from '@/components/action/Action.tsx'
import {
BetaSchemaForm,
@@ -13,199 +13,407 @@ import {
ProFormColumnsType,
} from '@ant-design/pro-components'
import ListPageLayout from '@/layout/ListPageLayout.tsx'
-import { useStyle } from './style'
-import { FilterOutlined } from '@ant-design/icons'
-import { getValueCount, unSetColumnRules } from '@/utils'
-import { Table as ProTable } from '@/components/table'
+import {useStyle} from './style'
+import {FilterOutlined} from '@ant-design/icons'
+import {getValueCount, unSetColumnRules} from '@/utils'
+import {Table as ProTable} from '@/components/table'
import Switch from '@/components/switch'
+import aPPServ from "@/service/app/package.ts";
+import {useDialog} from "@/components/dialog";
const i18nPrefix = 'appPackages.list'
const AppPackage = () => {
- const { styles, cx } = useStyle()
- const { t } = useTranslation()
- const [ form ] = Form.useForm()
- const [ filterForm ] = Form.useForm()
- const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateAppPackageAtom)
- const [ search, setSearch ] = useAtom(appPackageSearchAtom)
- const [ currentAppPackage, setAppPackage ] = useAtom(appPackageAtom)
- const { data, isFetching, isLoading, refetch } = useAtomValue(appPackagesAtom)
- const { mutate: deleteAppPackage, isPending: isDeleting } = useAtomValue(deleteAppPackageAtom)
- const { mutate: packageApp, isPending: packageing } = useAtomValue(packageAppAtom)
-
- const [ open, setOpen ] = useState(false)
- const [ openFilter, setFilterOpen ] = useState(false)
- const [ searchKey, setSearchKey ] = useState(search?.title)
+ const {styles, cx} = useStyle()
+ const {t} = useTranslation()
+ const [form] = Form.useForm()
+ const [filterForm] = Form.useForm()
+ const {mutate: saveOrUpdate, isPending: isSubmitting, isSuccess} = useAtomValue(saveOrUpdateAppPackageAtom)
+ const [search, setSearch] = useAtom(appPackageSearchAtom)
+ const [currentAppPackage, setAppPackage] = useAtom(appPackageAtom)
+ const {data, isFetching, isLoading, refetch} = useAtomValue(appPackagesAtom)
+ const {mutate: deleteAppPackage, isPending: isDeleting} = useAtomValue(deleteAppPackageAtom)
+ const {mutate: packageApp, isPending: packageing} = useAtomValue(packageAppAtom)
+
+ const [open, setOpen] = useState(false)
+ const [openFilter, setFilterOpen] = useState(false)
+ const [searchKey, setSearchKey] = useState(search?.title)
+ const [trafficEnabled, setTrafficEnabled] = useState(false);
+
+ const [, dialog, openDialog] = useDialog({
+ title: '提示',
+ children:
您还未购买流量套餐!
,
+ okText: '去购买',
+ onOk: () => {
- const columns = useMemo(() => {
+ }
+ })
+
+ const handleTrafficSwitchClick = async () => {
+ const data = await aPPServ.check()
+ setTrafficEnabled(data.data.success)
+ if (!data.data.success) {
+ openDialog()
+ }
+ };
+
+ const drawerColumns = useMemo(() => {
return [
{
title: 'ID',
dataIndex: 'id',
hideInTable: true,
hideInSearch: true,
- formItemProps: { hidden: true }
+ formItemProps: {hidden: true}
},
{
- title: t(`${i18nPrefix}.columns.package_name`, '包名'),
- dataIndex: 'package_name',
+ title: t(`${i18nPrefix}.columns.app_name`, '应用名称'),
+ dataIndex: 'app_name',
+ valueType: 'text',
+ fieldProps: {
+ maxLength: 10,
+ showCount: true,
+ },
formItemProps: {
+ tooltip: '手机端建议不超过6个字',
rules: [
{
required: true,
- message: t('message.required', '包名必填')
+ message: t('message.required', '应用名称必填')
}
]
}
},
-
{
- title: t(`${i18nPrefix}.columns.app_name`, '应用名'),
- dataIndex: 'app_name',
+ title: t(`${i18nPrefix}.columns.package_name`, '包名'),
+ dataIndex: 'package_name',
+ valueType: 'text',
+ fieldProps: {
+ placeholder: '例: com.baidu.app',
+ maxLength: 20,
+ showCount: true,
+ },
formItemProps: {
rules: [
{
required: true,
- message: t('message.required', '应用名必填')
+ message: t('message.required', '包名必填')
}
]
}
},
-
{
- title: t(`${i18nPrefix}.columns.app_icon`, '应用图标'),
+ title: t(`${i18nPrefix}.columns.app_icon`, '应用图标链接'),
dataIndex: 'app_icon',
+ valueType: 'input',
formItemProps: {
+ tooltip: '建议图标最大尺寸512x512,格式png,Win应用可以直接用favicon.ico链接',
rules: [
{
required: true,
message: t('message.required', '应用图标必填')
+ },
+ {
+ pattern: /^(http|https):\/\/[^\s$.?#].[^\s]*$/,
+ message: t('message.invalidUrl', '请输入有效的URL')
}
]
}
},
-
{
- title: t(`${i18nPrefix}.columns.web_url`, '主页地址'),
+ title: t(`${i18nPrefix}.columns.web_url`, '应用主页链接'),
dataIndex: 'web_url',
+ valueType: 'input',
formItemProps: {
+ tooltip: '填自己网站的链接',
rules: [
{
required: true,
- message: t('message.required', '主页地址必填')
+ message: t('message.required', '应用主页链接必填')
+ },
+ {
+ pattern: /^(http|https):\/\/[^\s$.?#].[^\s]*$/,
+ message: t('message.invalidUrl', '请输入有效的URL')
}
]
}
},
-
{
- title: t(`${i18nPrefix}.columns.splash_url`, '启动图'),
- dataIndex: 'splash_url',
+ title: t(`${i18nPrefix}.columns.os`, '目标系统'),
+ dataIndex: 'os',
+ valueType: 'select',
+ fieldProps: {
+ options: [
+ {label: 'Android', value: 0},
+ {label: 'Windows', value: 1}
+ ],
+ defaultValue: 0,
+ allowClear: false
+ },
+ render: (_text, record) => {
+ //0未处理 1队列中 2打包中 3打包成功 4打包失败
+ return
+ },
+ formItemProps: {
+ rules: [
+ {
+ required: true,
+ }
+ ]
+ }
},
-
{
- title: t(`${i18nPrefix}.columns.conf`, '配置地址'),
- dataIndex: 'conf',
+ title: t(`${i18nPrefix}.columns.enable_traffic`, '是否启用流量加速功能'),
+ dataIndex: 'enable_traffic',
+ valueType: 'switch',
+ fieldProps: {
+ onClick: handleTrafficSwitchClick,
+ checked: trafficEnabled
+ },
+ formItemProps: {
+ tooltip: '防屏蔽功能,需先购买流量套餐',
+ }
+ },
+ {
+ title: t(`${i18nPrefix}.columns.x_86`, '是否支持32位操作系统'),
+ dataIndex: 'x_86',
+ valueType: 'switch',
formItemProps: {
+ tooltip: 'Android则是arm-v7a',
+ }
+ },
+ {
+ title: t(`${i18nPrefix}.columns.splash_url`, 'Android启动页图片链接'),
+ dataIndex: 'splash_url',
+ valueType: 'input',
+ formItemProps: {
+ tooltip: '启动页的图片,只支持Android',
rules: [
{
- required: true,
- message: t('message.required', '配置地址必填')
+ pattern: /^(http|https):\/\/[^\s$.?#].[^\s]*$/,
+ message: t('message.invalidUrl', '请输入有效的URL')
}
]
}
},
-
{
- title: t(`${i18nPrefix}.columns.jks_url`, '签名文件地址'),
+ title: t(`${i18nPrefix}.columns.splash_color`, 'Android主题色'),
+ dataIndex: 'splash_color',
+ valueType: 'color',
+ formItemProps: {
+ tooltip: '建议选择启动页图片的底色,效果更美观,只支持Android',
+ }
+ },
+ {
+ title: t(`${i18nPrefix}.columns.jks_url`, 'Android签名文件链接'),
dataIndex: 'jks_url',
+ valueType: 'input',
formItemProps: {
+ tooltip: 'jks签名文件url,不填则使用默认的签名',
rules: [
{
- required: true,
- message: t('message.required', '签名文件地址必填')
+ pattern: /^(http|https):\/\/[^\s$.?#].[^\s]*$/,
+ message: t('message.invalidUrl', '请输入有效的URL')
}
]
}
},
-
{
- title: t(`${i18nPrefix}.columns.app_url`, '应用地址'),
- dataIndex: 'app_url',
+ title: t(`${i18nPrefix}.columns.store_pwd`, 'Android签名文件密码'),
+ dataIndex: 'store_pwd',
+ valueType: 'password',
+ formItemProps: {
+ tooltip: '如果自定义jks签名文件,此项必填',
+ rules: [
+ {
+ validator: (_, value, callback) => {
+ form.validateFields(['jks_url'])
+ .then(() => {
+ const jksUrl = form.getFieldValue('jks_url');
+ if (jksUrl && !value) {
+ callback(t('message.required', '密码必填'));
+ } else {
+ callback();
+ }
+ })
+ .catch(() => callback());
+ }
+ }
+ ]
+ }
},
-
{
- title: t(`${i18nPrefix}.columns.splash_color`, 'App背景色'),
- dataIndex: 'splash_color',
+ title: t(`${i18nPrefix}.columns.key_alias`, 'Android密钥别名'),
+ dataIndex: 'key_alias',
+ valueType: 'input',
+ formItemProps: {
+ tooltip: '如果自定义jks签名文件,此项必填',
+ rules: [
+ {
+ validator: (_, value, callback) => {
+ form.validateFields(['jks_url'])
+ .then(() => {
+ const jksUrl = form.getFieldValue('jks_url');
+ if (jksUrl && !value) {
+ callback(t('message.required', '别名必填'));
+ } else {
+ callback();
+ }
+ })
+ .catch(() => callback());
+ }
+ }
+ ]
+ }
},
+ {
+ title: t(`${i18nPrefix}.columns.key_pwd`, 'Android密钥密码'),
+ dataIndex: 'key_pwd',
+ valueType: 'password',
+ formItemProps: {
+ tooltip: '如果自定义jks签名文件,此项必填',
+ rules: [
+ {
+ validator: (_, value, callback) => {
+ form.validateFields(['jks_url'])
+ .then(() => {
+ const jksUrl = form.getFieldValue('jks_url');
+ if (jksUrl && !value) {
+ callback(t('message.required', '密码必填'));
+ } else {
+ callback();
+ }
+ })
+ .catch(() => callback());
+ }
+ }
+ ]
+ }
+ },
+ ] as ProColumns[]
+ }, [isDeleting, currentAppPackage, search])
+ const columns = useMemo(() => {
+ return [
{
- title: t(`${i18nPrefix}.columns.key_alias`, 'key别名'),
- dataIndex: 'key_alias',
+ title: 'ID',
+ dataIndex: 'id',
+ hideInTable: true,
+ hideInSearch: true,
+ formItemProps: {hidden: true}
+ },
+ {
+ title: t(`${i18nPrefix}.columns.package_name`, '包名'),
+ dataIndex: 'package_name',
formItemProps: {
rules: [
{
required: true,
- message: t('message.required', 'key别名必填')
+ message: t('message.required', '包名必填')
}
]
}
},
{
- title: t(`${i18nPrefix}.columns.store_pwd`, 'jks密码'),
- dataIndex: 'store_pwd',
+ title: t(`${i18nPrefix}.columns.app_name`, '应用名'),
+ dataIndex: 'app_name',
formItemProps: {
rules: [
{
required: true,
- message: t('message.required', 'jks密码必填')
+ message: t('message.required', '应用名必填')
}
]
}
},
{
- title: t(`${i18nPrefix}.columns.key_pwd`, 'key密码'),
- dataIndex: 'key_pwd',
+ title: t(`${i18nPrefix}.columns.app_icon`, '应用图标'),
+ dataIndex: 'app_icon',
formItemProps: {
rules: [
{
required: true,
- message: t('message.required', 'key密码必填')
+ message: t('message.required', '应用图标必填')
}
]
}
},
{
- title: t(`${i18nPrefix}.columns.status`, '状态'),
- dataIndex: 'status',
+ title: t(`${i18nPrefix}.columns.web_url`, '主页地址'),
+ dataIndex: 'web_url',
+ formItemProps: {
+ rules: [
+ {
+ required: true,
+ message: t('message.required', '主页地址必填')
+ }
+ ]
+ }
+ },
+ {
+ title: t(`${i18nPrefix}.columns.os`, '目标系统'),
+ dataIndex: 'os',
valueType: 'select',
fieldProps: {
options: [
- { label: '未处理', value: 0 },
- { label: '队列中', value: 1 },
- { label: '打包中', value: 2 },
- { label: '打包成功', value: 3 },
- { label: '打包失败', value: 4 },
+ {label: 'Android', value: 0},
+ {label: 'Windows', value: 1}
+ ]
+ },
+ formItemProps: {
+ rules: [
+ {
+ required: true,
+ message: t('message.required', 'key密码必填')
+ }
]
},
render: (_text, record) => {
//0未处理 1队列中 2打包中 3打包成功 4打包失败
- return
+ return
}
},
+ {
+ title: t(`${i18nPrefix}.columns.splash_url`, '启动图'),
+ dataIndex: 'splash_url',
+ },
+ {
+ title: t(`${i18nPrefix}.columns.jks_url`, '签名文件地址'),
+ dataIndex: 'jks_url',
+ },
+
+ {
+ title: t(`${i18nPrefix}.columns.app_url`, '应用地址'),
+ dataIndex: 'app_url',
+ },
+
+ {
+ title: t(`${i18nPrefix}.columns.splash_color`, 'App背景色'),
+ dataIndex: 'splash_color',
+ },
+
+ {
+ title: t(`${i18nPrefix}.columns.key_alias`, 'key别名'),
+ dataIndex: 'key_alias',
+ },
{
- title: t(`${i18nPrefix}.columns.message`, '打包信息'),
- dataIndex: 'message',
+ title: t(`${i18nPrefix}.columns.store_pwd`, 'jks密码'),
+ dataIndex: 'store_pwd',
},
{
- title: t(`${i18nPrefix}.columns.x_86`, '32位'),
+ title: t(`${i18nPrefix}.columns.key_pwd`, 'key密码'),
+ dataIndex: 'key_pwd',
+ },
+ {
+ title: t(`${i18nPrefix}.columns.x_86`, '是否支持32位'),
dataIndex: 'x_86',
valueType: 'switch',
render: (_text, record) => {
@@ -218,7 +426,7 @@ const AppPackage = () => {
dataIndex: 'uid',
hideInTable: true,
hideInSearch: true,
- formItemProps: { hidden: true }
+ formItemProps: {hidden: true}
},
{
@@ -230,7 +438,7 @@ const AppPackage = () => {
{
packageApp(record)
}}
@@ -257,20 +465,20 @@ const AppPackage = () => {
]
}
] as ProColumns[]
- }, [ isDeleting, currentAppPackage, search ])
+ }, [isDeleting, currentAppPackage, search])
useEffect(() => {
setSearchKey(search?.title)
filterForm.setFieldsValue(search)
- }, [ search ])
+ }, [search])
useEffect(() => {
if (isSuccess) {
setOpen(false)
}
- }, [ isSuccess ])
+ }, [isSuccess])
return (
@@ -378,13 +586,13 @@ const AppPackage = () => {
setOpen(open)
}}
loading={isSubmitting}
- onValuesChange={(values) => {
+ onValuesChange={() => {
}}
onFinish={async (values) => {
saveOrUpdate(values)
}}
- columns={columns as ProFormColumnsType[]}/>
+ columns={drawerColumns as ProFormColumnsType[]}/>
{
},
render: (props,) => {
return (
-
+