Browse Source

插件购买

main
cs 3 months ago
parent
commit
0339219b20
  1. 77
      src/pages/app/plugin/index.tsx
  2. 15
      src/pages/app/plugin/style.ts
  3. 12
      src/service/app/package.ts
  4. 42
      src/store/app/package.ts
  5. 27
      src/types/app/package.d.ts

77
src/pages/app/plugin/index.tsx

@ -0,0 +1,77 @@
import {Button, Card, List, message, Select} from 'antd'
import React, {useState} from 'react'
import {useStyle} from './style'
import {useAtomValue} from "jotai";
import {appAllListAtom, appPluginBuyAtom, appPluginListAtom} from "@/store/app/package.ts";
import ListPageLayout from "@/layout/ListPageLayout.tsx";
import {DollarOutlined} from "@ant-design/icons";
import {APP} from "@/types/app/package";
const i18nPrefix = 'appPackages.list'
const AppPackage = () => {
const {styles, cx} = useStyle()
const {data} = useAtomValue(appPluginListAtom)
const {mutate: buyPlugin, isPending: buyPending} = useAtomValue(appPluginBuyAtom)
const {data: allApp} = useAtomValue(appAllListAtom)
const [whitelistApp, setWhitelistApp] = useState(0);
const buy = (item: APP.IAppPlugin) => {
if (item.code == "traffic") {
buyPlugin({plugin_id: item.id, code: item.code})
} else if (item.code == "whitelist") {
if (whitelistApp == 0) {
message.warning('请先选择应用')
return
}
buyPlugin({plugin_id: item.id, code: item.code, app_id: whitelistApp})
}
}
return (
<ListPageLayout className={styles.container}>
<List
grid={{
gutter: 16,
xs: 1,
sm: 2,
md: 2,
lg: 3,
xl: 4,
xxl: 6,
}}
dataSource={data?.rows}
renderItem={(item) => (
<List.Item>
<Card
title={item.name}
style={{height: 400}}
styles={{body: {height: 300, overflow: 'hidden'}}}
actions={[
item.code == "whitelist" ? (
<Select placeholder="请选择应用">
{allApp?.map((item) => (
<option key={item.id} value={item.id}>
{item.app_name}
</option>
))}</Select>
) : null,
<Button type="primary" icon={<DollarOutlined/>} onClick={() => buy(item)}
loading={buyPending}>
${item.month_price}
</Button>,
]}
>
<p>{item.description}</p>
</Card>
</List.Item>
)}
/>
</ListPageLayout>
)
}
export default AppPackage

15
src/pages/app/plugin/style.ts

@ -0,0 +1,15 @@
import { createStyles } from '@/theme'
export const useStyle = createStyles(({ token, css, cx, prefixCls }, props: any) => {
const prefix = `${prefixCls}-${token?.proPrefix}-appPackage-plugin-page`
const container = css`
.zcss-kfly0u{
background: transparent;
}
`
return {
container: cx(prefix, props?.className, container),
}
})

12
src/service/app/package.ts

@ -28,6 +28,18 @@ const appPackage = {
getPkgStatus: async (params: any) => {
return await request.get<APP.IAppPkgStatus>(`/package/status`, { ...params })
},
getPluginList: async () => {
return await request.get<IPageResult<APP.IAppPlugin>>(`/package/plugin/list`)
},
getAppAllList: async () => {
return await request.get<APP.IBaseArrRes<APP.IAppPackage>>(`/package/allList`)
},
buyPlugin: async (params: any) => {
return await request.post<APP.IAppBoolRes>(`/package/plugin/buy`, { ...params })
},
}
export default appPackage

42
src/store/app/package.ts

@ -114,3 +114,45 @@ export const packageAppAtom = atomWithMutation((get) => {
}
}
})
/**
*
*/
export const appPluginListAtom = atomWithQuery(() => {
return {
queryKey: [ 'appPlugin' ],
queryFn: async ({ queryKey: [ , ] }) => {
const list = await aPPServ.getPluginList()
return list.data
}
}
})
/**
*
*/
export const appPluginBuyAtom = atomWithMutation(() => {
return {
mutationKey: [ 'appPlugin' ],
mutationFn: async (param: any) => {
const list = await aPPServ.buyPlugin(param)
return list.data
},
onSuccess: () => {
message.success('购买成功')
}
}
})
/**
*
*/
export const appAllListAtom = atomWithQuery(() => {
return {
queryKey: [ 'appAllList' ],
queryFn: async ({ queryKey: [ , ] }) => {
const list = await aPPServ.getAppAllList()
return list.data.list
}
}
})

27
src/types/app/package.d.ts

@ -32,6 +32,13 @@ export namespace APP {
}
/**
* Bool类型返回结果
*/
export interface IBaseArrRes<T> {
list: T[];
}
/**
*
*/
export interface IAppPkgStatus {
@ -44,4 +51,24 @@ export namespace APP {
position: number;
total: number;
}
/**
*
*/
export interface IAppPlugin {
id: number;
name: string;
description: string;
status: number;
month_price: number;
quarter_price: number;
half_year_price: number;
year_price: number;
two_year_price: number;
three_year_price: number;
onetime_price: number;
reset_price: number;
extra: number; //备用字段,如果是流量套餐则是流量额度
code: string;
}
}
Loading…
Cancel
Save