Commit 62919d05 authored by 杨贺晨吉's avatar 杨贺晨吉

feat: 1

parent 8874e05e
......@@ -12,6 +12,7 @@ declare global {
const Col: typeof import('antd')['Col']
const DatePicker: typeof import('antd')['DatePicker']
const DraggerUpload: typeof import('./src/components/common/DraggerUpload')['default']
const Drawer: typeof import('antd')['Drawer']
const Flex: typeof import('antd')['Flex']
const Form: typeof import('antd')['Form']
const Input: typeof import('antd')['Input']
......@@ -25,6 +26,7 @@ declare global {
const Outlet: typeof import('react-router-dom')['Outlet']
const REGEX: typeof import('pixiu-number-toolkit')['REGEX']
const Radio: typeof import('antd')['Radio']
const RejectReason: typeof import('./src/components/common/RejectReason')['default']
const Result: typeof import('antd')['Result']
const Role: typeof import('./src/constants/enums/index')['Role']
const Route: typeof import('react-router-dom')['Route']
......@@ -36,18 +38,19 @@ declare global {
const Spin: typeof import('antd')['Spin']
const Switch: typeof import('antd')['Switch']
const Table: typeof import('antd')['Table']
const TableSelect: typeof import('./src/components/common/TableSelect')['default']
const Upload: typeof import('antd')['Upload']
const UserList: typeof import('./src/constants/userList')['UserList']
const action: typeof import('mobx')['action']
const addMediaAccountAPI: typeof import('./src/apis/mediaAccount/index')['addMediaAccountAPI']
const addMediaAccountAPI: typeof import('./src/apis/media/mediaAccount/index')['addMediaAccountAPI']
const autorun: typeof import('mobx')['autorun']
const axios: typeof import('axios')['default']
const buildREG: typeof import('./src/utils/REG')['buildREG']
const changeAEByIdAPI: typeof import('./src/apis/mediaAccount/index')['changeAEByIdAPI']
const changeAEListByIdAPI: typeof import('./src/apis/mediaAccount/index')['changeAEListByIdAPI']
const changeAEByIdAPI: typeof import('./src/apis/media/mediaAccount/index')['changeAEByIdAPI']
const changeAEListByIdAPI: typeof import('./src/apis/media/mediaAccount/index')['changeAEListByIdAPI']
const changeDate: typeof import('./src/utils/date')['changeDate']
const changePEByIdAPI: typeof import('./src/apis/mediaAccount/index')['changePEByIdAPI']
const changeStatueByIdAPI: typeof import('./src/apis/mediaAccount/index')['changeStatueByIdAPI']
const changePEByIdAPI: typeof import('./src/apis/media/mediaAccount/index')['changePEByIdAPI']
const changeStatueByIdAPI: typeof import('./src/apis/media/mediaAccount/index')['changeStatueByIdAPI']
const checkIsImage: typeof import('./src/utils/upload')['checkIsImage']
const checkIsVideo: typeof import('./src/utils/upload')['checkIsVideo']
const computed: typeof import('mobx')['computed']
......@@ -65,8 +68,10 @@ declare global {
const getFailedRecords: typeof import('./src/apis/index')['getFailedRecords']
const getFileUrl: typeof import('./src/utils/upload')['getFileUrl']
const getImgInfo: typeof import('./src/utils/upload')['getImgInfo']
const getMediaAccountAPI: typeof import('./src/apis/mediaAccount/index')['getMediaAccountAPI']
const getMediaAccountListAPI: typeof import('./src/apis/mediaAccount/index')['getMediaAccountListAPI']
const getMediaAccountAPI: typeof import('./src/apis/media/mediaAccount/index')['getMediaAccountAPI']
const getMediaAccountListAPI: typeof import('./src/apis/media/mediaAccount/index')['getMediaAccountListAPI']
const getMediaAuditAPI: typeof import('./src/apis/audit/mediaAudit/index')['getMediaAuditAPI']
const getMediaAuditListAPI: typeof import('./src/apis/audit/mediaAudit/index')['getMediaAuditListAPI']
const getRealTime: typeof import('./src/apis/index')['getRealTime']
const getSuffix: typeof import('./src/utils/upload')['getSuffix']
const getSvgaInfo: typeof import('./src/utils/upload')['getSvgaInfo']
......@@ -89,6 +94,7 @@ declare global {
const onBecomeObserved: typeof import('mobx')['onBecomeObserved']
const onBecomeUnobserved: typeof import('mobx')['onBecomeUnobserved']
const onReactionError: typeof import('mobx')['onReactionError']
const passOrRefuseAccount: typeof import('./src/apis/audit/mediaAudit/index')['passOrRefuseAccount']
const permission: typeof import('./src/utils/permission')['default']
const precent: typeof import('./src/utils/number')['precent']
const precentAddSuffix: typeof import('./src/utils/number')['precentAddSuffix']
......@@ -140,8 +146,11 @@ declare global {
// for type re-export
declare global {
// @ts-ignore
export type { mediaSearchP, mediaAccountList, mediaAccount, changeParams } from './src/apis/mediaAccount/type'
import('./src/apis/mediaAccount/type')
export type { auditMediaSearchP, mediaAuditList, auditPassOrRefuse } from './src/apis/audit/mediaAudit/type'
import('./src/apis/audit/mediaAudit/type')
// @ts-ignore
export type { mediaSearchP, mediaAccountList, mediaAccount, changeParams } from './src/apis/media/mediaAccount/type'
import('./src/apis/media/mediaAccount/type')
// @ts-ignore
export type { paginationType } from './src/apis/type'
import('./src/apis/type')
......
export const getMediaAuditListAPI = (params: auditMediaSearchP) => {
return request.post<auditMediaSearchP, mediaAuditList[]>('/audit/abc', params)
}
export const getMediaAuditAPI = (id: number | string) => {
return request.post<number, mediaAccount>('/audit/ab3', { id })
}
export const passOrRefuseAccount = (id: number | string, type: number, msg = '') => {
return request.post<auditPassOrRefuse, boolean>('/audit/pass', { id, type, msg })
}
export interface auditMediaSearchP extends paginationType {
mediaId: number | string
}
export interface mediaAuditList {
time: string
mediaName: string
mediaId: string | number
}
export interface auditPassOrRefuse {
type: number
id: number | string
msg?: string
}
// interface[mediaAccount] from media/mediaAccount/type.ts
export const getMediaAuditListAPI = (params: auditMediaSearchP) => {
return request.post<auditMediaSearchP, mediaAuditList[]>('/audit/abc', params)
}
export const getMediaAuditAPI = (id: number | string) => {
return request.post<number, mediaAccount>('/audit/ab3', { id })
}
export const passOrRefuseAccount = (id: number | string, type: number, msg = '') => {
return request.post<auditPassOrRefuse, boolean>('/audit/pass', { id, type, msg })
}
export interface auditMediaSearchP extends paginationType {
mediaId: number | string
}
export interface mediaAuditList {
time: string
mediaName: string
mediaId: string | number
}
export interface auditPassOrRefuse {
type: number
id: number | string
msg?: string
}
// interface[mediaAccount] from media/mediaAccount/type.ts
......@@ -12,6 +12,7 @@ export interface mediaAccountList {
mediaC: string
mediaTime: string
AE: string
AEId: string | number
AEName: string
PE: string
statue: boolean
......@@ -31,7 +32,7 @@ export interface mediaAccount {
export interface changeParams {
mediaId: number | string
statue?: boolean
AE?: string
AE?: number
PE?: string
AEList?: string[]
}
export const getMediaAccountListAPI = (params: mediaSearchP) => {
return request.post<mediaSearchP, mediaAccountList[]>('/ab', params)
}
export const addMediaAccountAPI = (params: mediaAccount) => {
return request.post<mediaAccount, boolean>('/ab3', params)
}
export const getMediaAccountAPI = (id: number | string) => {
return request.post<number, mediaAccount>('/ab3', { id })
}
export const changeStatueByIdAPI = (params: changeParams) => {
return request.post<changeParams, boolean>('/ac', params)
}
export const changeAEByIdAPI = (params: changeParams) => {
return request.post<changeParams, boolean>('/abc', params)
}
export const changePEByIdAPI = (params: changeParams) => {
return request.post<changeParams, boolean>('/abcd', params)
}
export const changeAEListByIdAPI = (params: changeParams) => {
return request.post<changeParams, boolean>('/abcde', params)
}
export interface mediaSearchP extends paginationType {
mediaId: number | string
mediaName: string
AE: string
PE: string
}
export interface mediaAccountList {
mediaId: number | string
mediaName: string
mediaType: string
mediaC: string
mediaTime: string
AE: string
AEId: string | number
AEName: string
PE: string
statue: boolean
}
export interface mediaAccount {
mediaId: string | number
mediaName: string
cName: string
pe: string
phone: string
email: string
account: string
pic1: string
pic2: string
}
export interface changeParams {
mediaId: number | string
statue?: boolean
AE?: number
PE?: string
AEList?: string[]
}
import { dspAccountStore } from './store.ts'
const AddModal: React.FC = observer(() => {
const { isModalOpen: open, setModalOpen, addMediaAccountFc, mediaAccount, setMediaAccount } = dspAccountStore
const [form] = Form.useForm()
const [imageUrl, setImageUrl] = useState<string>()
const [imageUrl2, setImageUrl2] = useState<string>()
const handleCancel = () => {
setModalOpen(false)
}
const handleOk = async (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
e.preventDefault()
form
.validateFields()
.then((values) => {
console.log(values)
addMediaAccountFc({ ...values })
handleCancel()
})
.catch((err) => {
console.error('Validation Failed:', err)
})
}
useEffect(() => {
if (open) {
form.setFieldsValue(mediaAccount)
} else {
// ?
setTimeout(() => {
form.resetFields()
setMediaAccount(undefined)
}, 100)
}
}, [mediaAccount, open])
return (
<Modal title='创建媒体' open={open} onOk={handleOk} onCancel={handleCancel} okText='提交审核'>
<Form
form={form}
labelCol={{ flex: '110px' }}
wrapperCol={{ flex: 1 }}
labelAlign='left'
labelWrap
colon={false}
style={{ maxWidth: 600 }}>
<Form.Item label='媒体名称' name='mediaName' rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item label='公司名称' name='cName' rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item label='对接人姓名' name='pe' rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item label='对接人电话' name='phone' rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item label='对接人邮箱' name='email' rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item label='收款账户信息' name='account' rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item label='营业执照' name='pic1' rules={[{ required: true }]}>
<DraggerUpload
value={imageUrl}
data={{ id: 1, name: 'yhcj' }}
getUploadUrl={(url: string) => {
form.setFieldValue('pic1', url)
setImageUrl(url)
}}
/>
</Form.Item>
<Form.Item label='基本账户信息(开户许可证)' name='pic2' rules={[{ required: true }]}>
<DraggerUpload
value={imageUrl2}
data={{ id: 1, name: 'yhcj' }}
getUploadUrl={(url: string) => {
form.setFieldValue('pic2', url)
setImageUrl2(url)
}}
/>
</Form.Item>
</Form>
</Modal>
)
})
export default AddModal
import List from './list.tsx'
import Search from './search.tsx'
import { dspAccountStore } from './store.ts'
const DSPAccountIndex = observer(() => {
const { searchParams } = dspAccountStore
// 接口获取数据
const {
data = [
{
mediaId: 1234,
mediaName: 'test',
mediaType: 'test',
mediaC: 'test',
mediaTime: 'test',
AE: 'test',
AEId: 1,
AEName: 'test,test2',
PE: 'test',
statue: true,
},
{
mediaId: 2123,
mediaName: 'test2',
mediaType: 'test2',
mediaC: 'test2',
mediaTime: 'test2',
AE: 'test2',
AEId: 2,
AEName: 'test1,test2',
PE: 'test2',
statue: false,
},
],
run,
loading,
} = useRequest(getMediaAccountListAPI, { defaultParams: [searchParams] })
return (
<Spin spinning={loading}>
<Space direction='vertical' style={{ display: 'flex' }} size='middle'>
<Search searchRun={run} />
<List data={data} searchRun={run} />
</Space>
</Spin>
)
})
export default DSPAccountIndex
import type { TableColumnsType } from 'antd'
import AddModal from './addAccount.tsx'
import { dspAccountStore } from './store.ts'
interface ListProp {
data: mediaAccountList[]
searchRun: (param: mediaSearchP) => void
}
const List: React.FC<ListProp> = observer((prop: ListProp) => {
const { data, searchRun } = prop
const { setModalOpen, searchParams, getMediaAccountFc, changeAE, changeAEList, changePE, changeStatue } =
dspAccountStore
const editAddModal = (id: number | string) => {
setModalOpen(true)
getMediaAccountFc(id)
}
const handlePageChange = async (page: number, pageSize: number) => {
const param = {
...searchParams,
pageSize: pageSize,
currentPage: page,
}
searchRun(param)
console.log('handlePageChange', param)
}
const columns: TableColumnsType<mediaAccountList> = [
{
title: '媒体ID',
dataIndex: 'mediaId',
key: 'mediaId',
},
{
title: '媒体名称',
dataIndex: 'mediaName',
key: 'mediaName',
},
{
title: '媒体类型',
dataIndex: 'mediaType',
key: 'mediaType',
},
{
title: '媒体接入方式',
dataIndex: 'mediaC',
key: 'mediaC',
},
{
title: '媒体接入时间',
dataIndex: 'mediaTime',
key: 'mediaTime',
},
{
title: '所属主运营',
dataIndex: 'AE',
key: 'AE',
render: (AE, record) => {
return (
<TableSelect
text={AE}
selectValue={record.AEId}
options={[
{ label: 'text', value: 1 },
{ label: 'text2', value: 2 },
{ label: 'text3', value: 3 },
]}
callback={(value) => changeAE(record.mediaId, value as number)}
/>
)
},
},
{
title: '其他运营',
dataIndex: 'AEName',
key: 'AEName',
render: (AEName, record) => {
return (
<TableSelect
text={AEName}
mode='multiple'
selectValue={AEName}
options={[
{ label: 'text', value: 'text' },
{ label: 'text2', value: 'text2' },
{ label: 'text3', value: 'text3' },
]}
callback={(value) => changeAEList(record.mediaId, value as string[])}
/>
)
},
},
{
title: '所属媒介',
dataIndex: 'PE',
key: 'PE',
render: (PE, record) => {
return (
<TableSelect
text={PE}
selectValue={PE}
options={[
{ label: 'text', value: 'text' },
{ label: 'text2', value: 'text2' },
{ label: 'text3', value: 'text3' },
]}
callback={(value) => changePE(record.mediaId, value as string)}
/>
)
},
},
{
title: '审核状态',
dataIndex: 'statue',
key: 'statue',
render: (statue, record) => (
<Space size='middle'>
<Switch checked={statue} onChange={(checked: boolean) => changeStatue(record.mediaId, checked)} />
</Space>
),
},
{
title: '操作',
key: 'action',
render: (_, record) => (
<Space size='middle'>
<a onClick={() => editAddModal(record.mediaId)}>设置</a>
</Space>
),
},
]
return (
<>
<Table<mediaAccountList>
dataSource={data}
columns={columns}
pagination={{ pageSizeOptions: [10, 20, 50], showQuickJumper: true, total: 500, onChange: handlePageChange }}
/>
<AddModal />
</>
)
})
export default List
const { Item: FormItem } = Form
import { mediaAccountStore } from './store'
import { dspAccountStore } from './store'
interface SearchProp {
searchRun: (param: mediaSearchP) => void
}
const Search: React.FC<SearchProp> = observer((prop: SearchProp) => {
const [form] = Form.useForm()
const { searchRun } = prop
const { setModalOpen, searchParams, setSearchParams } = mediaAccountStore
const { setModalOpen, searchParams, setSearchParams } = dspAccountStore
function handleSearch(e: React.MouseEvent<HTMLElement, MouseEvent>) {
e.preventDefault()
form
......@@ -24,8 +24,8 @@ const Search: React.FC<SearchProp> = observer((prop: SearchProp) => {
setModalOpen(true)
}
return (
<Form className='fill' layout='inline' form={form}>
<Flex className='fill' gap='small' justify='flex-start' wrap>
<Form layout='inline' form={form}>
<Space wrap>
<FormItem label='媒体ID' name='mediaId' rules={[Rules.ids]}>
<Input style={{ width: 200 }} placeholder='请输入媒体ID间隔用,隔开' />
</FormItem>
......@@ -38,14 +38,12 @@ const Search: React.FC<SearchProp> = observer((prop: SearchProp) => {
<FormItem label='媒介' name='PE' rules={[Rules.name]}>
<Input style={{ width: 200 }} placeholder='请输入媒介' />
</FormItem>
</Flex>
<Flex className='fill' justify='flex-end'>
<FormItem layout='vertical' style={{ paddingTop: '10px', display: 'flex', justifyContent: 'flex-end' }}>
<FormItem>
<Button type='primary' onClick={handleAdd}>
创建媒体
</Button>
</FormItem>
<FormItem layout='vertical' style={{ paddingTop: '10px', display: 'flex', justifyContent: 'flex-end' }}>
<FormItem>
<Button
type='primary'
htmlType='submit'
......@@ -53,7 +51,7 @@ const Search: React.FC<SearchProp> = observer((prop: SearchProp) => {
搜索
</Button>
</FormItem>
</Flex>
</Space>
</Form>
)
})
......
class DSPAccountStore {
isModalOpen = false
searchParams: mediaSearchP = {
mediaId: '',
mediaName: '',
AE: '',
PE: '',
pageSize: 15,
currentPage: 1,
}
mediaAccount: mediaAccount | undefined = {
mediaId: '',
mediaName: '',
cName: '',
pe: '',
phone: '',
email: '',
account: '',
pic1: '',
pic2: '',
}
constructor() {
makeAutoObservable(this) // 自动推断类型
}
getModalOpen = () => {
return this.isModalOpen
}
setModalOpen = (value: boolean) => {
this.isModalOpen = value
}
setSearchParams = (value: mediaSearchP) => {
this.searchParams = { ...this.searchParams, ...value }
}
setMediaAccount = (value: mediaAccount | undefined) => {
this.mediaAccount = value ? { ...value } : undefined
}
addMediaAccountFc = (params: mediaAccount) => {
console.log('params', params)
const res = addMediaAccountAPI(params)
console.log(res)
}
getMediaAccountFc = (id: number | string) => {
const res = getMediaAccountAPI(id)
console.log(res)
this.setMediaAccount({
mediaName: 'text',
cName: 'text',
pe: 'text',
phone: 'text',
email: 'text',
account: 'text',
pic1: 'http://yun.dui88.com/-rr2kxnz9cm-e1lpywd8t.png',
pic2: 'http://yun.dui88.com/-rr2kxnz9cm-e1lpywd8t.png',
})
}
changeAE = (id: string | number, value: number) => {
changeAEByIdAPI({ mediaId: id, AE: value })
}
changeAEList = (id: string | number, name: string[]) => {
changeAEListByIdAPI({ mediaId: id, AEList: name })
}
changePE = (id: string | number, name: string) => {
changePEByIdAPI({ mediaId: id, PE: name })
}
changeStatue = (id: string | number, statue: boolean) => {
changeStatueByIdAPI({ mediaId: id, statue })
}
}
export const dspAccountStore = new DSPAccountStore()
import List from '@components/mediaAccount/list.tsx'
import Search from '@components/mediaAccount/search.tsx'
import List from './list.tsx'
import Search from './search.tsx'
import { mediaAccountStore } from './store.ts'
const MediaAccountIndex = observer(() => {
......@@ -9,23 +8,25 @@ const MediaAccountIndex = observer(() => {
const {
data = [
{
mediaId: 1,
mediaId: 1234,
mediaName: 'test',
mediaType: 'test',
mediaC: 'test',
mediaTime: 'test',
AE: 'test',
AEId: 1,
AEName: 'test,test2',
PE: 'test',
statue: true,
},
{
mediaId: 2,
mediaId: 2123,
mediaName: 'test2',
mediaType: 'test2',
mediaC: 'test2',
mediaTime: 'test2',
AE: 'test2',
AEId: 2,
AEName: 'test1,test2',
PE: 'test2',
statue: false,
......
......@@ -9,7 +9,8 @@ interface ListProp {
const List: React.FC<ListProp> = observer((prop: ListProp) => {
const { data, searchRun } = prop
const { setModalOpen, searchParams, getMediaAccountFc } = mediaAccountStore
const { setModalOpen, searchParams, getMediaAccountFc, changeAE, changeAEList, changePE, changeStatue } =
mediaAccountStore
const editAddModal = (id: number | string) => {
setModalOpen(true)
getMediaAccountFc(id)
......@@ -24,31 +25,6 @@ const List: React.FC<ListProp> = observer((prop: ListProp) => {
console.log('handlePageChange', param)
}
const changeStatue = (id: string | number, statue: boolean) => {
console.log(id, statue)
const l = changeStatueByIdAPI({ mediaId: id, statue })
console.log(l)
}
const [flag, changeFlag] = useState(false)
const changeAE = (id: string | number, name: string) => {
console.log(id, name)
const l = changeAEByIdAPI({ mediaId: id, AE: name })
console.log(l)
}
const changeAEList = (id: string | number, name: string[]) => {
console.log(id, name)
const l = changeAEListByIdAPI({ mediaId: id, AEList: name })
console.log(l)
}
const changePE = (id: string | number, name: string) => {
console.log(id, name)
const l = changePEByIdAPI({ mediaId: id, PE: name })
console.log(l)
}
const columns: TableColumnsType<mediaAccountList> = [
{
title: '媒体ID',
......@@ -81,24 +57,16 @@ const List: React.FC<ListProp> = observer((prop: ListProp) => {
key: 'AE',
render: (AE, record) => {
return (
<Space size='middle'>
{flag ? (
<Select
defaultValue={AE}
style={{ width: 120 }}
onChange={async (value) => {
await changeAE(record.mediaId, value)
changeFlag(false)
}}>
<Select.Option value='test'>test</Select.Option>
<Select.Option value='test2'>test2</Select.Option>
</Select>
) : AE ? (
<a onClick={() => changeFlag(true)}>{AE}</a>
) : (
<a onClick={() => changeFlag(true)}>-</a>
)}
</Space>
<TableSelect
text={AE}
selectValue={record.AEId}
options={[
{ label: 'text', value: 1 },
{ label: 'text2', value: 2 },
{ label: 'text3', value: 3 },
]}
callback={(value) => changeAE(record.mediaId, value as number)}
/>
)
},
},
......@@ -108,26 +76,17 @@ const List: React.FC<ListProp> = observer((prop: ListProp) => {
key: 'AEName',
render: (AEName, record) => {
return (
<Space size='middle'>
{flag ? (
<Select
mode='multiple'
defaultValue={AEName?.split(',')}
style={{ width: 120 }}
onChange={async (value) => {
await changeAEList(record.mediaId, value)
changeFlag(false)
}}>
<Select.Option value='test'>test</Select.Option>
<Select.Option value='test1'>test1</Select.Option>
<Select.Option value='test2'>test2</Select.Option>
</Select>
) : AEName ? (
<a onClick={() => changeFlag(true)}>{AEName}</a>
) : (
<a onClick={() => changeFlag(true)}>-</a>
)}
</Space>
<TableSelect
text={AEName}
mode='multiple'
selectValue={AEName}
options={[
{ label: 'text', value: 'text' },
{ label: 'text2', value: 'text2' },
{ label: 'text3', value: 'text3' },
]}
callback={(value) => changeAEList(record.mediaId, value as string[])}
/>
)
},
},
......@@ -137,24 +96,16 @@ const List: React.FC<ListProp> = observer((prop: ListProp) => {
key: 'PE',
render: (PE, record) => {
return (
<Space size='middle'>
{flag ? (
<Select
defaultValue={PE}
style={{ width: 120 }}
onChange={async (value) => {
await changePE(record.mediaId, value)
changeFlag(false)
}}>
<Select.Option value='test'>test</Select.Option>
<Select.Option value='test2'>test2</Select.Option>
</Select>
) : PE ? (
<a onClick={() => changeFlag(true)}>{PE}</a>
) : (
<a onClick={() => changeFlag(true)}>-</a>
)}
</Space>
<TableSelect
text={PE}
selectValue={PE}
options={[
{ label: 'text', value: 'text' },
{ label: 'text2', value: 'text2' },
{ label: 'text3', value: 'text3' },
]}
callback={(value) => changePE(record.mediaId, value as string)}
/>
)
},
},
......
const { Item: FormItem } = Form
import { mediaAccountStore } from './store'
interface SearchProp {
searchRun: (param: mediaSearchP) => void
}
const Search: React.FC<SearchProp> = observer((prop: SearchProp) => {
const [form] = Form.useForm()
const { searchRun } = prop
const { setModalOpen, searchParams, setSearchParams } = mediaAccountStore
function handleSearch(e: React.MouseEvent<HTMLElement, MouseEvent>) {
e.preventDefault()
form
.validateFields()
.then((values) => {
setSearchParams({ ...values })
searchRun({ ...searchParams, ...values })
})
.catch((err) => {
console.error('Validation Failed:', err)
})
}
const handleAdd = () => {
setModalOpen(true)
}
return (
<Form layout='inline' form={form}>
<Space wrap>
<FormItem name='mediaId' rules={[Rules.ids]}>
<Input style={{ width: 200 }} placeholder='请输入媒体ID间隔用,隔开' />
</FormItem>
<FormItem name='mediaName' rules={[Rules.name]}>
<Input style={{ width: 200 }} placeholder='请输入媒体名称' />
</FormItem>
<FormItem name='AE' rules={[Rules.name]}>
<Input style={{ width: 200 }} placeholder='请输入运营' />
</FormItem>
<FormItem name='PE' rules={[Rules.name]}>
<Input style={{ width: 200 }} placeholder='请输入媒介' />
</FormItem>
<FormItem>
<Button type='primary' onClick={handleAdd}>
创建媒体
</Button>
</FormItem>
<FormItem>
<Button
type='primary'
htmlType='submit'
onClick={(e: React.MouseEvent<HTMLElement, MouseEvent>) => handleSearch(e)}>
搜索
</Button>
</FormItem>
</Space>
</Form>
)
})
export default Search
......@@ -59,6 +59,22 @@ class MediaAccountStore {
pic2: 'http://yun.dui88.com/-rr2kxnz9cm-e1lpywd8t.png',
})
}
changeAE = (id: string | number, value: number) => {
changeAEByIdAPI({ mediaId: id, AE: value })
}
changeAEList = (id: string | number, name: string[]) => {
changeAEListByIdAPI({ mediaId: id, AEList: name })
}
changePE = (id: string | number, name: string) => {
changePEByIdAPI({ mediaId: id, PE: name })
}
changeStatue = (id: string | number, statue: boolean) => {
changeStatueByIdAPI({ mediaId: id, statue })
}
}
export const mediaAccountStore = new MediaAccountStore()
import { dspAuditStore } from './store.ts'
const AddModal: React.FC = observer(() => {
const [messageApi, contextHolder] = message.useMessage()
const {
isModalOpen: open,
setModalOpen,
mediaAccount,
getMediaAccountFc,
refuseModeOpen,
refuseMsg,
setRefuseMsg,
setRefuseModeOpen,
} = dspAuditStore
const [form] = Form.useForm()
const idList = [1, 2, 3, 4, 5, 6, 7]
let [indexNumber, setIndexNumber] = useState<number>(1)
const handleCancel = () => {
setModalOpen(false)
}
useEffect(() => {
if (open) {
form.setFieldsValue(mediaAccount)
}
}, [mediaAccount, open, form])
const passAccount = () => {
passOrRefuseAccount(mediaAccount.mediaId, 1)
handleNext()
}
const requestRefuseReason = () => {
passOrRefuseAccount(mediaAccount.mediaId, 0, refuseMsg)
handleNext()
setRefuseModeOpen(false)
}
const handleNext = () => {
if (idList.length > indexNumber) {
getMediaAccountFc(idList[indexNumber])
setIndexNumber(++indexNumber)
} else {
messageApi.info('所有媒体已审核完毕')
}
}
const AuditFooter = (
<Space style={{ display: 'flex', justifyContent: 'flex-end' }}>
<Button onClick={passAccount} type='primary'>
通过
</Button>
<Button onClick={() => setRefuseModeOpen(true)} color='danger'>
拒绝
</Button>
<Button type='primary' onClick={handleNext}>
下一个
</Button>
</Space>
)
return (
<>
<Drawer onClose={handleCancel} title='创建媒体' open={open} footer={AuditFooter} width='720'>
{contextHolder}
<Form
form={form}
labelCol={{ flex: '110px' }}
wrapperCol={{ flex: 1 }}
labelAlign='left'
labelWrap
colon={false}
style={{ maxWidth: 600 }}>
<Form.Item label='媒体名称' name='mediaName' rules={[{ required: true }]}>
<Input disabled={true} />
</Form.Item>
<Form.Item label='公司名称' name='cName' rules={[{ required: true }]}>
<Input disabled={true} />
</Form.Item>
<Form.Item label='对接人姓名' name='pe' rules={[{ required: true }]}>
<Input disabled={true} />
</Form.Item>
<Form.Item label='对接人电话' name='phone' rules={[{ required: true }]}>
<Input disabled={true} />
</Form.Item>
<Form.Item label='对接人邮箱' name='email' rules={[{ required: true }]}>
<Input disabled={true} />
</Form.Item>
<Form.Item label='收款账户信息' name='account' rules={[{ required: true }]}>
<Input disabled={true} />
</Form.Item>
<Form.Item label='营业执照' name='pic1' rules={[{ required: true }]}>
<DraggerUpload value={form.getFieldValue('pic1')} disabled={true} />
</Form.Item>
<Form.Item label='基本账户信息(开户许可证)' name='pic2' rules={[{ required: true }]}>
<DraggerUpload value={form.getFieldValue('pic2')} disabled={true} />
</Form.Item>
</Form>
</Drawer>
<RejectReason
value={refuseMsg}
open={refuseModeOpen}
onOk={requestRefuseReason}
onCancel={() => setRefuseModeOpen(false)}
onChange={(value) => setRefuseMsg(value)}
/>
</>
)
})
export default AddModal
import List from './list.tsx'
import Search from './search.tsx'
import { dspAuditStore } from './store.ts'
const DSPAccountIndex = observer(() => {
const { searchParams } = dspAuditStore
// 接口获取数据
const {
data = [
{
time: '2025-04-01',
mediaId: 1,
mediaName: 'test',
},
{
time: '2025-04-01',
mediaId: 2,
mediaName: 'test2',
},
],
run,
loading,
} = useRequest(getMediaAuditListAPI, { defaultParams: [searchParams] })
return (
<Spin spinning={loading}>
<Space direction='vertical' style={{ display: 'flex' }} size='middle'>
<Search searchRun={run} />
<List data={data} searchRun={run} />
</Space>
</Spin>
)
})
export default DSPAccountIndex
import type { TableColumnsType } from 'antd'
import AddModal from './addAccount.tsx'
import { dspAuditStore } from './store.ts'
interface ListProp {
data: mediaAuditList[]
searchRun: (param: auditMediaSearchP) => void
}
const List: React.FC<ListProp> = observer((prop: ListProp) => {
const { data, searchRun } = prop
const {
setModalOpen,
searchParams,
getMediaAccountFc,
passOrRefuseAccount,
refuseModeOpen,
refuseMsg,
setRefuseMsg,
setRefuseModeOpen,
} = dspAuditStore
const editAddModal = (id: number | string) => {
setModalOpen(true)
getMediaAccountFc(id)
}
const handlePageChange = async (page: number, pageSize: number) => {
const param = {
...searchParams,
pageSize: pageSize,
currentPage: page,
}
searchRun(param)
console.log('handlePageChange', param)
}
const passAccount = (id: number | string) => {
passOrRefuseAccount(id, 1)
}
const [refuseId, setRefuseId] = useState<number | string>(1)
const requestRefuseReason = () => {
passOrRefuseAccount(refuseId, 0, refuseMsg)
}
const columns: TableColumnsType<mediaAuditList> = [
{
title: '创建时间',
dataIndex: 'time',
key: 'time',
},
{
title: 'DSPID',
dataIndex: 'mediaId',
key: 'mediaId',
},
{
title: 'DSP名称',
dataIndex: 'mediaName',
key: 'mediaName',
},
{
title: '操作',
key: 'action',
render: (_, record) => (
<Space size='middle'>
<a onClick={() => passAccount(record.mediaId)}>审核通过</a>
<a
onClick={() => {
setRefuseModeOpen(true)
setRefuseId(record.mediaId)
}}>
审核拒绝
</a>
<a onClick={() => editAddModal(record.mediaId)}>查看</a>
</Space>
),
},
]
return (
<>
<Table<mediaAuditList>
dataSource={data}
columns={columns}
pagination={{ pageSizeOptions: [10, 20, 50], showQuickJumper: true, total: 500, onChange: handlePageChange }}
/>
<AddModal />
<RejectReason
value={refuseMsg}
open={refuseModeOpen}
onOk={requestRefuseReason}
onCancel={() => setRefuseModeOpen(false)}
onChange={(value) => setRefuseMsg(value)}
/>
</>
)
})
export default List
const { Item: FormItem } = Form
import { dspAuditStore } from './store'
interface SearchProp {
searchRun: (param: auditMediaSearchP) => void
}
const Search: React.FC<SearchProp> = observer((prop: SearchProp) => {
const [form] = Form.useForm()
const { searchRun } = prop
const { searchParams, setSearchParams } = dspAuditStore
function handleSearch(e: React.MouseEvent<HTMLElement, MouseEvent>) {
e.preventDefault()
form
.validateFields()
.then((values) => {
setSearchParams({ ...values })
searchRun({ ...searchParams, ...values })
})
.catch((err) => {
console.error('Validation Failed:', err)
})
}
return (
<Form className='searchContext' layout='inline' form={form}>
<FormItem name='mediaId'>
<Input style={{ width: 200 }} placeholder='请输入DSPID或DSP名称' />
</FormItem>
<FormItem>
<Button
type='primary'
htmlType='submit'
onClick={(e: React.MouseEvent<HTMLElement, MouseEvent>) => handleSearch(e)}>
搜索
</Button>
</FormItem>
</Form>
)
})
export default Search
class DSPAuditStore {
isModalOpen = false
searchParams: auditMediaSearchP = {
mediaId: '',
pageSize: 15,
currentPage: 1,
}
mediaAccount: mediaAccount = {
mediaId: '',
mediaName: '',
cName: '',
pe: '',
phone: '',
email: '',
account: '',
pic1: '',
pic2: '',
}
refuseModeOpen = false
refuseMsg = ''
constructor() {
makeAutoObservable(this) // 自动推断类型
}
getModalOpen = () => {
return this.isModalOpen
}
setModalOpen = (value: boolean) => {
this.isModalOpen = value
}
setSearchParams = (value: auditMediaSearchP) => {
this.searchParams = { ...this.searchParams, ...value }
}
setMediaAccount = (value: mediaAccount | undefined) => {
this.mediaAccount = value
? value
: {
mediaId: '',
mediaName: '',
cName: '',
pe: '',
phone: '',
email: '',
account: '',
pic1: '',
pic2: '',
}
}
setRefuseMsg = (value: string) => {
this.refuseMsg = value
}
setRefuseModeOpen = (value: boolean) => {
this.setRefuseMsg('')
this.refuseModeOpen = value
}
getMediaAccountFc = (id: number | string) => {
const res = getMediaAccountAPI(id)
console.log(res)
if (id === 1) {
this.setMediaAccount({
mediaId: 1,
mediaName: 'text',
cName: 'text',
pe: 'text',
phone: 'text',
email: 'text',
account: 'text',
pic1: 'http://yun.dui88.com/-rr2kxnz9cm-e1lpywd8t.png',
pic2: 'http://yun.dui88.com/-rr2kxnz9cm-e1lpywd8t.png',
})
} else if (id === 2) {
setTimeout(() => {
this.setMediaAccount({
mediaId: 2,
mediaName: 'text2',
cName: 'text2',
pe: 'text2',
phone: 'text2',
email: 'text2',
account: 'text2',
pic1: 'http://yun.dui88.com/-rr2kxnz9cm-e1lpywd8t.png',
pic2: 'http://yun.dui88.com/-rr2kxnz9cm-e1lpywd8t.png',
})
})
} else if (id === 3) {
setTimeout(() => {
this.setMediaAccount({
mediaId: 3,
mediaName: 'text3',
cName: 'text3',
pe: 'text3',
phone: 'text3',
email: 'text3',
account: 'text3',
pic1: 'http://yun.dui88.com/-rr2kxnz9cm-e1lpywd8t.png',
pic2: 'http://yun.dui88.com/-rr2kxnz9cm-e1lpywd8t.png',
})
})
}
}
passOrRefuseAccount = (id: string | number, type: number, msg = '') => {
passOrRefuseAccount(id, type, msg)
}
}
export const dspAuditStore = new DSPAuditStore()
import { mediaAuditStore } from './store.ts'
const AddModal: React.FC = observer(() => {
const [messageApi, contextHolder] = message.useMessage()
const {
isModalOpen: open,
setModalOpen,
mediaAccount,
getMediaAccountFc,
refuseModeOpen,
refuseMsg,
setRefuseMsg,
setRefuseModeOpen,
} = mediaAuditStore
const [form] = Form.useForm()
const idList = [1, 2, 3, 4, 5, 6, 7]
let [indexNumber, setIndexNumber] = useState<number>(1)
const handleCancel = () => {
setModalOpen(false)
}
useEffect(() => {
if (open) {
form.setFieldsValue(mediaAccount)
}
}, [mediaAccount, open, form])
const passAccount = () => {
passOrRefuseAccount(mediaAccount.mediaId, 1)
handleNext()
}
const requestRefuseReason = () => {
passOrRefuseAccount(mediaAccount.mediaId, 0, refuseMsg)
handleNext()
setRefuseModeOpen(false)
}
const handleNext = () => {
if (idList.length > indexNumber) {
getMediaAccountFc(idList[indexNumber])
setIndexNumber(++indexNumber)
} else {
messageApi.info('所有媒体已审核完毕')
}
}
const AuditFooter = (
<Space style={{ display: 'flex', justifyContent: 'flex-end' }}>
<Button onClick={passAccount} type='primary'>
通过
</Button>
<Button onClick={() => setRefuseModeOpen(true)} color='danger'>
拒绝
</Button>
<Button type='primary' onClick={handleNext}>
下一个
</Button>
</Space>
)
return (
<>
<Drawer onClose={handleCancel} title='创建媒体' open={open} footer={AuditFooter} width='720'>
{contextHolder}
<Form
form={form}
labelCol={{ flex: '110px' }}
wrapperCol={{ flex: 1 }}
labelAlign='left'
labelWrap
colon={false}
style={{ maxWidth: 600 }}>
<Form.Item label='媒体名称' name='mediaName' rules={[{ required: true }]}>
<Input disabled={true} />
</Form.Item>
<Form.Item label='公司名称' name='cName' rules={[{ required: true }]}>
<Input disabled={true} />
</Form.Item>
<Form.Item label='对接人姓名' name='pe' rules={[{ required: true }]}>
<Input disabled={true} />
</Form.Item>
<Form.Item label='对接人电话' name='phone' rules={[{ required: true }]}>
<Input disabled={true} />
</Form.Item>
<Form.Item label='对接人邮箱' name='email' rules={[{ required: true }]}>
<Input disabled={true} />
</Form.Item>
<Form.Item label='收款账户信息' name='account' rules={[{ required: true }]}>
<Input disabled={true} />
</Form.Item>
<Form.Item label='营业执照' name='pic1' rules={[{ required: true }]}>
<DraggerUpload value={form.getFieldValue('pic1')} disabled={true} />
</Form.Item>
<Form.Item label='基本账户信息(开户许可证)' name='pic2' rules={[{ required: true }]}>
<DraggerUpload value={form.getFieldValue('pic2')} disabled={true} />
</Form.Item>
</Form>
</Drawer>
<RejectReason
value={refuseMsg}
open={refuseModeOpen}
onOk={requestRefuseReason}
onCancel={() => setRefuseModeOpen(false)}
onChange={(value) => setRefuseMsg(value)}
/>
</>
)
})
export default AddModal
import List from './list.tsx'
import Search from './search.tsx'
import { mediaAuditStore } from './store.ts'
const DSPAccountIndex = observer(() => {
const { searchParams } = mediaAuditStore
// 接口获取数据
const {
data = [
{
time: '2025-04-01',
mediaId: 1,
mediaName: 'test',
},
{
time: '2025-04-01',
mediaId: 2,
mediaName: 'test2',
},
],
run,
loading,
} = useRequest(getMediaAuditListAPI, { defaultParams: [searchParams] })
return (
<Spin spinning={loading}>
<Space direction='vertical' style={{ display: 'flex' }} size='middle'>
<Search searchRun={run} />
<List data={data} searchRun={run} />
</Space>
</Spin>
)
})
export default DSPAccountIndex
import type { TableColumnsType } from 'antd'
import AddModal from './addAccount.tsx'
import { mediaAuditStore } from './store.ts'
interface ListProp {
data: mediaAuditList[]
searchRun: (param: auditMediaSearchP) => void
}
const List: React.FC<ListProp> = observer((prop: ListProp) => {
const { data, searchRun } = prop
const {
setModalOpen,
searchParams,
getMediaAccountFc,
passOrRefuseAccount,
refuseModeOpen,
refuseMsg,
setRefuseMsg,
setRefuseModeOpen,
} = mediaAuditStore
const editAddModal = (id: number | string) => {
setModalOpen(true)
getMediaAccountFc(id)
}
const handlePageChange = async (page: number, pageSize: number) => {
const param = {
...searchParams,
pageSize: pageSize,
currentPage: page,
}
searchRun(param)
console.log('handlePageChange', param)
}
const passAccount = (id: number | string) => {
passOrRefuseAccount(id, 1)
}
const [refuseId, setRefuseId] = useState<number | string>(1)
const requestRefuseReason = () => {
passOrRefuseAccount(refuseId, 0, refuseMsg)
}
const columns: TableColumnsType<mediaAuditList> = [
{
title: '创建时间',
dataIndex: 'time',
key: 'time',
},
{
title: '媒体ID',
dataIndex: 'mediaId',
key: 'mediaId',
},
{
title: '媒体名称',
dataIndex: 'mediaName',
key: 'mediaName',
},
{
title: '操作',
key: 'action',
render: (_, record) => (
<Space size='middle'>
<a onClick={() => passAccount(record.mediaId)}>审核通过</a>
<a
onClick={() => {
setRefuseModeOpen(true)
setRefuseId(record.mediaId)
}}>
审核拒绝
</a>
<a onClick={() => editAddModal(record.mediaId)}>查看</a>
</Space>
),
},
]
return (
<>
<Table<mediaAuditList>
dataSource={data}
columns={columns}
pagination={{ pageSizeOptions: [10, 20, 50], showQuickJumper: true, total: 500, onChange: handlePageChange }}
/>
<AddModal />
<RejectReason
value={refuseMsg}
open={refuseModeOpen}
onOk={requestRefuseReason}
onCancel={() => setRefuseModeOpen(false)}
onChange={(value) => setRefuseMsg(value)}
/>
</>
)
})
export default List
const { Item: FormItem } = Form
import { mediaAuditStore } from './store'
interface SearchProp {
searchRun: (param: auditMediaSearchP) => void
}
const Search: React.FC<SearchProp> = observer((prop: SearchProp) => {
const [form] = Form.useForm()
const { searchRun } = prop
const { searchParams, setSearchParams } = mediaAuditStore
function handleSearch(e: React.MouseEvent<HTMLElement, MouseEvent>) {
e.preventDefault()
form
.validateFields()
.then((values) => {
setSearchParams({ ...values })
searchRun({ ...searchParams, ...values })
})
.catch((err) => {
console.error('Validation Failed:', err)
})
}
return (
<Form className='searchContext' layout='inline' form={form}>
<FormItem name='mediaId'>
<Input style={{ width: 200 }} placeholder='请输入媒体ID或者媒体名称' />
</FormItem>
<FormItem>
<Button
type='primary'
htmlType='submit'
onClick={(e: React.MouseEvent<HTMLElement, MouseEvent>) => handleSearch(e)}>
搜索
</Button>
</FormItem>
</Form>
)
})
export default Search
class MediaAuditStore {
isModalOpen = false
searchParams: auditMediaSearchP = {
mediaId: '',
pageSize: 15,
currentPage: 1,
}
mediaAccount: mediaAccount = {
mediaId: '',
mediaName: '',
cName: '',
pe: '',
phone: '',
email: '',
account: '',
pic1: '',
pic2: '',
}
refuseModeOpen = false
refuseMsg = ''
constructor() {
makeAutoObservable(this) // 自动推断类型
}
getModalOpen = () => {
return this.isModalOpen
}
setModalOpen = (value: boolean) => {
this.isModalOpen = value
}
setSearchParams = (value: auditMediaSearchP) => {
this.searchParams = { ...this.searchParams, ...value }
}
setMediaAccount = (value: mediaAccount | undefined) => {
this.mediaAccount = value
? value
: {
mediaId: '',
mediaName: '',
cName: '',
pe: '',
phone: '',
email: '',
account: '',
pic1: '',
pic2: '',
}
}
setRefuseMsg = (value: string) => {
this.refuseMsg = value
}
setRefuseModeOpen = (value: boolean) => {
this.setRefuseMsg('')
this.refuseModeOpen = value
}
getMediaAccountFc = (id: number | string) => {
const res = getMediaAccountAPI(id)
console.log(res)
if (id === 1) {
this.setMediaAccount({
mediaId: 1,
mediaName: 'text',
cName: 'text',
pe: 'text',
phone: 'text',
email: 'text',
account: 'text',
pic1: 'http://yun.dui88.com/-rr2kxnz9cm-e1lpywd8t.png',
pic2: 'http://yun.dui88.com/-rr2kxnz9cm-e1lpywd8t.png',
})
} else if (id === 2) {
setTimeout(() => {
this.setMediaAccount({
mediaId: 2,
mediaName: 'text2',
cName: 'text2',
pe: 'text2',
phone: 'text2',
email: 'text2',
account: 'text2',
pic1: 'http://yun.dui88.com/-rr2kxnz9cm-e1lpywd8t.png',
pic2: 'http://yun.dui88.com/-rr2kxnz9cm-e1lpywd8t.png',
})
})
} else if (id === 3) {
setTimeout(() => {
this.setMediaAccount({
mediaId: 3,
mediaName: 'text3',
cName: 'text3',
pe: 'text3',
phone: 'text3',
email: 'text3',
account: 'text3',
pic1: 'http://yun.dui88.com/-rr2kxnz9cm-e1lpywd8t.png',
pic2: 'http://yun.dui88.com/-rr2kxnz9cm-e1lpywd8t.png',
})
})
}
}
passOrRefuseAccount = (id: string | number, type: number, msg = '') => {
passOrRefuseAccount(id, type, msg)
}
}
export const mediaAuditStore = new MediaAuditStore()
interface IProps {
open: boolean
value: string
onOk: () => void
onCancel: () => void
onChange: (value: string) => void
}
const RejectReason: React.FC<IProps> = memo(({ open, value, onCancel, onOk, onChange, ...rest }) => {
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
onChange(e.target.value)
}
return (
<Modal title='拒绝原因' open={open} onCancel={onCancel} onOk={onOk} {...rest}>
<Input.TextArea value={value} onChange={handleChange} />
</Modal>
)
})
export default RejectReason
interface IOptions {
label: string
value: string | number
}
interface IProps {
text: string
selectValue: string | number | string[] | number[]
options: IOptions[]
callback: (value: string | number | string[] | number[]) => void
mode?: undefined | 'tags' | 'multiple'
}
const TableSelect: React.FC<IProps> = memo(({ text, selectValue, options, mode = undefined, callback, ...rest }) => {
const [edit, setEdit] = useState(false)
const [value, setValue] = useState(selectValue)
const handleAutoSave = (value: string | string[] | number | number[]) => {
// 如果输入内容本质上没发生改变,则不做保存
if (selectValue === value || (Array.isArray(value) && selectValue === value.join(','))) {
setEdit(false)
return
}
Modal.confirm({
title: '确定修改',
content: `确定当前内容吗?`,
okText: '确定',
cancelText: '取消',
async onOk() {
callback(value)
setValue(value)
setEdit(false)
},
onCancel() {
setEdit(false)
setValue(selectValue)
},
})
}
return edit ? (
<Select mode={mode} value={value} onChange={handleAutoSave} options={options} style={{ width: 120 }} />
) : (
<div>
<a onClick={() => setEdit(true)} {...rest}>
{isNothing(text) ? '-' : text}
</a>
</div>
)
})
export default TableSelect
.search-form {
display: flex;
}
\ No newline at end of file
......@@ -4,10 +4,10 @@
@import 'tailwindcss';
@import 'antd/dist/reset.css';
.fill {
width: 100%;
padding: 0;
margin: 0;
.ant-modal-footer>button{
margin-left: 8px
}
.ant-table-wrapper .ant-table-pagination.ant-pagination {
margin: 16px 0 0;
}
\ No newline at end of file
......@@ -40,6 +40,40 @@ const menuItems = [
},
],
},
{
key: '/dsp',
icon: <UserAddOutlined />,
label: 'DSP管理',
children: [
{
key: '/dsp/dspAccount',
label: 'DSP管理',
icon: <UserAddOutlined />,
},
{
key: '/dsp/dspManage',
label: 'DSP流量管理',
icon: <UserAddOutlined />,
},
],
},
{
key: '/audit',
icon: <UserAddOutlined />,
label: '审核',
children: [
{
key: '/audit/dspAudit',
label: 'DSP账号审核',
icon: <UserAddOutlined />,
},
{
key: '/audit/mediaAudit',
label: '媒体账号审核',
icon: <UserAddOutlined />,
},
],
},
]
const BasicLayout: React.FC<React.PropsWithChildren> = ({ children }) => {
......
import DSPAuditIndex from '@/components/audit/dspAudit/index'
const Index = observer(() => {
return <DSPAuditIndex />
})
export default Index
import MediaAuditIndex from '@/components/audit/mediaAudit/index'
const Index = observer(() => {
return <MediaAuditIndex />
})
export default Index
import DSPAccountIndex from '@/components/DSP/dspAccount'
const Index = observer(() => {
return <DSPAccountIndex />
})
export default Index
const Index = observer(() => {
return <div>jhhhh</div>
})
export default Index
import MediaAccountIndex from '@components/mediaAccount/index.tsx'
import MediaAccountIndex from '@/components/Media/mediaAccount'
const Index = observer(() => {
return <MediaAccountIndex />
......
const About = () => <div>About2</div>
export default About
......@@ -43,6 +43,7 @@ export default defineConfig(({ mode }) => ({
imports: [
{
antd: [
'Drawer',
'Space',
'message',
'Spin',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment