Skip to content

Commit 3547d14

Browse files
committed
feat(strategy): 添加策略订阅者功能
- 新增 ModalSubscriber 组件用于显示策略订阅者列表 - 在策略列表页面添加订阅者按钮和相关逻辑 - 从 API 获取策略订阅者数据并展示 - 添加订阅者相关的通知类型展示
1 parent 1884f61 commit 3547d14

File tree

4 files changed

+150
-0
lines changed

4 files changed

+150
-0
lines changed

src/api/global.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,8 @@ export enum ActionKey {
410410
CANCEL_SUBSCRIBE = '__cancel_subscribe__',
411411
/** 订阅 */
412412
SUBSCRIBE = '__subscribe__',
413+
/** 订阅者 */
414+
SUBSCRIBER = '__subscriber__',
413415
/** 启用 */
414416
ENABLE = '__enable__',
415417
/** 禁用 */

src/pages/strategy/list/index.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import MetricEditModal from './edit-modal-metric'
3030
import { PortEditModal } from './edit-modal-port'
3131
import StrategyTypeModal from './edit-modal-strategy-type'
3232
import { ModalSubscribe } from './modal-subscribe'
33+
import ModalSubscriber from './modal-subscriber'
3334
import { formList, getColumnList } from './options'
3435

3536
const { confirm } = Modal
@@ -64,6 +65,7 @@ const StrategyMetric: React.FC = () => {
6465
const [openHttpDetailModal, setOpenHttpDetailModal] = useState(false)
6566

6667
const [openSubscribeModal, setOpenSubscribeModal] = useState(false)
68+
const [openSubscriberModal, setOpenSubscriberModal] = useState(false)
6769

6870
const [detail, setDetail] = useState<StrategyItem>()
6971

@@ -104,6 +106,11 @@ const StrategyMetric: React.FC = () => {
104106
setOpenSubscribeModal(true)
105107
}
106108

109+
const handleOpenSubscriberModal = (item?: StrategyItem) => {
110+
setDetail(item)
111+
setOpenSubscriberModal(true)
112+
}
113+
107114
const handleMetricEditOk = () => {
108115
setOpenMetricEditModal(false)
109116
setDetail(undefined)
@@ -145,6 +152,11 @@ const StrategyMetric: React.FC = () => {
145152
setDetail(undefined)
146153
}
147154

155+
const handleCloseSubscriberModal = () => {
156+
setOpenSubscriberModal(false)
157+
setDetail(undefined)
158+
}
159+
148160
const handleDetailModal = (item: StrategyItem) => {
149161
setDetail(item)
150162
switch (item.strategyType) {
@@ -326,6 +338,9 @@ const StrategyMetric: React.FC = () => {
326338
case ActionKey.SUBSCRIBE:
327339
handleOpenSubscribeModal(item)
328340
break
341+
case ActionKey.SUBSCRIBER:
342+
handleOpenSubscriberModal(item)
343+
break
329344
case ActionKey.DELETE:
330345
confirm({
331346
title: '请确认是否删除该策略组?',
@@ -385,6 +400,13 @@ const StrategyMetric: React.FC = () => {
385400

386401
return (
387402
<div className='h-full flex flex-col gap-3 p-3'>
403+
<ModalSubscriber
404+
title={`【${detail?.name}】策略订阅者`}
405+
width='60%'
406+
open={openSubscriberModal}
407+
onClose={handleCloseSubscriberModal}
408+
strategyId={detail?.id}
409+
/>
388410
<ModalSubscribe
389411
title={`订阅【${detail?.name}】策略`}
390412
// width='60%'
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import { NotifyType } from '@/api/enum'
2+
import { StrategySubscriberItem, UserItem } from '@/api/model-types'
3+
import { getStrategySubscriber, StrategySubscriberRequest } from '@/api/subscriber'
4+
import AutoTable from '@/components/table'
5+
import { useRequest } from 'ahooks'
6+
import { Avatar, Checkbox, Modal, ModalProps, theme } from 'antd'
7+
import { useEffect, useState } from 'react'
8+
9+
export interface ModalSubscriberProps extends ModalProps {
10+
strategyId?: number
11+
onClose: () => void
12+
}
13+
14+
const { useToken } = theme
15+
16+
export default function ModalSubscriber({ open, strategyId = 0, onClose, ...reset }: ModalSubscriberProps) {
17+
const { token } = useToken()
18+
const [datasource, setDatasource] = useState<StrategySubscriberItem[]>([])
19+
const [total, setTotal] = useState(0)
20+
const { run: initStrategySubscriber, loading } = useRequest(getStrategySubscriber, {
21+
manual: true,
22+
onSuccess: (res) => {
23+
setDatasource(res.subscribers)
24+
setTotal(res.pagination.total)
25+
}
26+
})
27+
const [searchParams, setSearchParams] = useState<StrategySubscriberRequest>({
28+
strategyId: strategyId,
29+
pagination: { pageNum: 1, pageSize: 100 }
30+
})
31+
32+
useEffect(() => {
33+
if (strategyId && open) {
34+
initStrategySubscriber({ ...searchParams, strategyId })
35+
}
36+
}, [strategyId, open, initStrategySubscriber, searchParams])
37+
38+
const columns = [
39+
{
40+
title: '用户名',
41+
dataIndex: 'user',
42+
key: 'user',
43+
render: (user: UserItem) => {
44+
return (
45+
<div>
46+
<Avatar src={user.avatar} size={24} className='mr-2'>
47+
{user.name.charAt(0).toUpperCase()}
48+
</Avatar>
49+
<span className='ml-2'>{`${user.name} (${user.nickname})`}</span>
50+
</div>
51+
)
52+
}
53+
},
54+
{
55+
title: '通知类型',
56+
dataIndex: 'notifyType',
57+
key: 'notifyType',
58+
render: (notifyType: NotifyType) => {
59+
const checkedList: NotifyType[] = []
60+
if (notifyType & NotifyType.NOTIFY_PHONE) {
61+
checkedList.push(NotifyType.NOTIFY_PHONE)
62+
}
63+
if (notifyType & NotifyType.NOTIFY_EMAIL) {
64+
checkedList.push(NotifyType.NOTIFY_EMAIL)
65+
}
66+
if (notifyType & NotifyType.NOTIFY_SMS) {
67+
checkedList.push(NotifyType.NOTIFY_SMS)
68+
}
69+
return (
70+
<Checkbox.Group
71+
value={checkedList}
72+
options={[
73+
{ label: '手机', value: NotifyType.NOTIFY_PHONE },
74+
{ label: '邮件', value: NotifyType.NOTIFY_EMAIL },
75+
{ label: '短信', value: NotifyType.NOTIFY_SMS }
76+
]}
77+
/>
78+
)
79+
}
80+
}
81+
]
82+
83+
// 切换分页
84+
const handleTurnPage = (page: number, pageSize: number) => {
85+
setSearchParams({
86+
...searchParams,
87+
pagination: {
88+
pageNum: page,
89+
pageSize: pageSize
90+
}
91+
})
92+
}
93+
94+
return (
95+
<Modal title='订阅者' open={open} onClose={onClose} footer={null} loading={loading} {...reset}>
96+
<AutoTable
97+
rowKey={(record) => record.id}
98+
dataSource={datasource}
99+
total={total}
100+
loading={loading}
101+
columns={columns}
102+
handleTurnPage={handleTurnPage}
103+
pageSize={searchParams.pagination.pageSize}
104+
pageNum={searchParams.pagination.pageNum}
105+
showSizeChanger={true}
106+
style={{
107+
background: token.colorBgContainer,
108+
borderRadius: token.borderRadius
109+
}}
110+
scroll={{
111+
y: 500,
112+
x: 1000
113+
}}
114+
size='middle'
115+
/>
116+
</Modal>
117+
)
118+
}

src/pages/strategy/list/options.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,14 @@ export const getColumnList = (props: GroupColumnProps): ColumnsType<StrategyItem
173173
</Button>
174174
)
175175
},
176+
{
177+
key: ActionKey.SUBSCRIBER,
178+
label: (
179+
<Button size='small' type='link'>
180+
订阅者
181+
</Button>
182+
)
183+
},
176184
{
177185
key: ActionKey.OPERATION_LOG,
178186
label: (

0 commit comments

Comments
 (0)