index.tsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. import { App, Button, DatePicker, Input, Pagination, Popconfirm, Select, Table } from 'antd';
  2. import Card from 'antd/es/card/Card';
  3. import React, { useEffect, useRef, useState } from 'react';
  4. import { delAutoLinkApi, getCorpAutoLinkListApi, GetCorpAutoLinkListProps } from '../../API/bookLink';
  5. import style from './index.less'
  6. import { useAjax } from '@/Hook/useAjax';
  7. import SearchBox from '../../components/searchBox';
  8. import { SearchOutlined, PlusOutlined, DeleteOutlined } from '@ant-design/icons';
  9. import { getBindMpListApi } from '../../API/corpUserAssign';
  10. import { inject, observer } from 'mobx-react';
  11. import { toJS } from 'mobx';
  12. import { LINKTYPE } from './const';
  13. import ModalBookLink from './modalBooklink';
  14. import { useSize } from 'ahooks';
  15. import { bookLinkTableConfig } from './tableConfig';
  16. import dayJs from 'dayjs';
  17. /**
  18. * 书城自动链接管理
  19. * @returns
  20. */
  21. const BookLink: React.FC<{ weComTaskStore: { data: { bookList: TASK_CREATE.BookListProps[], bookPlatForm: TASK_CREATE.BookPlatFormProps[] } } }> = ({ weComTaskStore }) => {
  22. /******************************************/
  23. const { message } = App.useApp()
  24. const { bookPlatForm } = toJS(weComTaskStore.data)
  25. const ref = useRef<HTMLDivElement>(null)
  26. const size = useSize(ref)
  27. const [queryParams, setQueryParams] = useState<GetCorpAutoLinkListProps>({ pageNum: 1, pageSize: 20 })
  28. const [queryParamsNew, setQueryParamsNew] = useState<GetCorpAutoLinkListProps>({ pageNum: 1, pageSize: 20 })
  29. const [mpList, setMplist] = useState<{ label: string, value: number }[]>([])
  30. const [visible, setVisible] = useState<boolean>(false)
  31. const [initialValues, setInitialValues] = useState<any>()
  32. const [selectedRows, setselectedRows] = useState<any[]>([])
  33. const getCorpAutoLinkList = useAjax((params) => getCorpAutoLinkListApi(params))
  34. const delAutoLink = useAjax((params) => delAutoLinkApi(params))
  35. const getBindMpList = useAjax(() => getBindMpListApi())
  36. /******************************************/
  37. useEffect(() => {
  38. getCorpAutoLinkList.run(queryParamsNew)
  39. }, [queryParamsNew])
  40. useEffect(() => {
  41. getBindMpList.run().then(res => {
  42. setMplist(res?.data?.map((item: any) => ({ label: item.name, value: item.id })))
  43. })
  44. }, [])
  45. const handleCopy = (value: any) => {
  46. const { linkType, linkContext, channelName, channelType, platform, mpAccountId } = value
  47. const yueWenCreateLinkDTO: { [x: string]: any } = {
  48. linkType: linkType + '',
  49. channelName,
  50. channelType: channelType + ''
  51. }
  52. switch (linkType) {
  53. case 1:
  54. yueWenCreateLinkDTO.pagePromoLinkCreateDTO = {
  55. ...linkContext,
  56. pageType: linkContext.pageType + ''
  57. }
  58. break
  59. case 2:
  60. yueWenCreateLinkDTO.bookPromoLinkCreateDTO = { ...linkContext, forceStyle: Number(linkContext.forceStyle) }
  61. break
  62. case 3:
  63. yueWenCreateLinkDTO.rechargeActivityLinkDTO = {
  64. ...linkContext,
  65. activityTheme: linkContext.activityTheme + '',
  66. activityTime: [dayJs(linkContext.startTime), dayJs(linkContext.endTime)],
  67. display: linkContext?.display ? linkContext?.display?.split(',') : []
  68. }
  69. break
  70. case 4:
  71. yueWenCreateLinkDTO.giftActivityLinkDTO = {
  72. ...linkContext,
  73. // activityTheme: Number(linkContext.activityTheme),
  74. activityTime: [dayJs(linkContext.startTime), dayJs(linkContext.endTime)],
  75. display: linkContext?.display ? linkContext?.display?.split(',') : [],
  76. resourceType: linkContext.resourceType + ''
  77. }
  78. break
  79. case 5:
  80. yueWenCreateLinkDTO.consumeActivityLinkDTO = {
  81. ...linkContext,
  82. activityTheme: linkContext.activityTheme + '',
  83. activityTime: [dayJs(linkContext.startTime), dayJs(linkContext.endTime)],
  84. display: linkContext?.display ? linkContext?.display?.split(',') : [],
  85. }
  86. break
  87. }
  88. setInitialValues({
  89. platform,
  90. mpAccountIds: [mpAccountId],
  91. yueWenCreateLinkDTOList: [yueWenCreateLinkDTO]
  92. })
  93. setVisible(true)
  94. }
  95. const handleDel = (value: { linkIds: number[] }) => {
  96. const hide = message.loading('正在删除...', 0)
  97. delAutoLink.run(value).then(res => {
  98. hide()
  99. setselectedRows([])
  100. if (res?.data) {
  101. message.success('删除成功')
  102. getCorpAutoLinkList.refresh()
  103. } else {
  104. message.error('删除失败')
  105. }
  106. }).catch(() => hide())
  107. }
  108. return <Card
  109. styles={{ body: { padding: 0, display: 'flex', flexDirection: 'column', height: 'calc(100vh - 74px)', overflow: 'hidden' } }}
  110. >
  111. <div>
  112. <SearchBox
  113. bodyPadding={`10px 16px 4px`}
  114. buttons={<>
  115. <Button type="primary" onClick={() => {
  116. setQueryParamsNew({ ...queryParams, pageNum: 1 })
  117. }} loading={getCorpAutoLinkList.loading} icon={<SearchOutlined />}>搜索</Button>
  118. <Button type="primary" icon={<PlusOutlined />} onClick={() => setVisible(true)}>链接生成</Button>
  119. <Popconfirm
  120. title="确定删除?"
  121. onConfirm={() => { handleDel({ linkIds : selectedRows.map(i => i.id) }) }}
  122. disabled={selectedRows.length === 0}
  123. >
  124. <Button type='primary' danger icon={<DeleteOutlined />} loading={delAutoLink.loading} disabled={selectedRows.length === 0}>删除</Button>
  125. </Popconfirm>
  126. </>}
  127. >
  128. <>
  129. <Select
  130. value={queryParams?.platform}
  131. onChange={(e) => setQueryParams({ ...queryParams, platform: e })}
  132. showSearch
  133. style={{ width: 110 }}
  134. placeholder="书城"
  135. filterOption={(input, option) =>
  136. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  137. }
  138. allowClear
  139. options={bookPlatForm.map(item => ({ value: item.platformKey, label: item.platformName }))}
  140. />
  141. <Select
  142. value={queryParams?.mpAccountId}
  143. onChange={(e) => setQueryParams({ ...queryParams, mpAccountId: e })}
  144. showSearch
  145. style={{ width: 110 }}
  146. placeholder="公众号"
  147. filterOption={(input, option) =>
  148. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  149. }
  150. allowClear
  151. options={mpList}
  152. />
  153. <Select
  154. value={queryParams?.linkType}
  155. onChange={(e) => setQueryParams({ ...queryParams, linkType: e })}
  156. showSearch
  157. style={{ width: 110 }}
  158. placeholder="链接类型"
  159. filterOption={(input, option) =>
  160. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  161. }
  162. allowClear
  163. options={Object.keys(LINKTYPE).map(key => ({ label: LINKTYPE[key], value: key }))}
  164. />
  165. <Input placeholder='请输入渠道名称' style={{ width: 150 }} allowClear value={queryParams?.channelName} onChange={(e) => setQueryParams({ ...queryParams, channelName: e.target.value })} />
  166. <Select
  167. style={{ width: 110 }}
  168. showSearch
  169. placeholder="推广类型"
  170. value={queryParams?.channelType}
  171. onChange={(value) => setQueryParams({ ...queryParams, channelType: value })}
  172. filterOption={(input, option) =>
  173. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  174. }
  175. allowClear
  176. options={[{ label: '外部', value: '1' }, { label: '内部', value: '2' }]}
  177. />
  178. <DatePicker.RangePicker
  179. placeholder={['创建时间开始', '创建时间结束']}
  180. allowClear
  181. value={queryParams?.createTimeStart ? [dayJs(queryParams?.createTimeStart), dayJs(queryParams?.createTimeEnd)] : undefined}
  182. onChange={(_, options) => setQueryParams({ ...queryParams, createTimeStart: options?.[0], createTimeEnd: options?.[1] })}
  183. />
  184. </>
  185. </SearchBox>
  186. </div>
  187. <div className={style.bookLinkTable} ref={ref}>
  188. <Table
  189. dataSource={getCorpAutoLinkList?.data?.data?.records}
  190. columns={bookLinkTableConfig(false, handleCopy, handleDel)}
  191. bordered
  192. pagination={false}
  193. rowKey={'id'}
  194. size='small'
  195. loading={getCorpAutoLinkList?.loading}
  196. scroll={{ y: size?.height && ref.current ? size?.height - ref.current.querySelector('.ant-table-thead').clientHeight : 300 }}
  197. rowSelection={{
  198. selectedRowKeys: selectedRows?.map((item: any) => item?.id),
  199. onSelect: (record: { id: string }, selected: boolean) => {
  200. let newData = JSON.parse(JSON.stringify(selectedRows))
  201. if (selected) {
  202. newData.push({ ...record })
  203. } else {
  204. newData = newData.filter((item: { id: string }) => item.id !== record.id)
  205. }
  206. setselectedRows(newData)
  207. },
  208. onSelectAll: (selected: boolean, _: { id: string }[], changeRows: { id: string }[]) => {
  209. let newData = JSON.parse(JSON.stringify(selectedRows || '[]'))
  210. if (selected) {
  211. changeRows.forEach((item: { id: string }) => {
  212. let index = newData.findIndex((ite: { id: string }) => ite.id === item.id)
  213. if (index === -1) {
  214. newData.push(item)
  215. }
  216. })
  217. } else {
  218. let newSelectAccData = newData.filter((item: { id: string }) => {
  219. let index = changeRows.findIndex((ite: { id: string }) => ite.id === item.id)
  220. if (index !== -1) {
  221. return false
  222. } else {
  223. return true
  224. }
  225. })
  226. newData = newSelectAccData
  227. }
  228. setselectedRows(newData)
  229. }
  230. }}
  231. />
  232. </div>
  233. <div className={style.bookLinkPagination}>
  234. <Pagination
  235. size="small"
  236. total={getCorpAutoLinkList?.data?.data?.total || 0}
  237. showSizeChanger
  238. showQuickJumper
  239. pageSize={getCorpAutoLinkList?.data?.data?.size || 20}
  240. current={getCorpAutoLinkList?.data?.data?.current || 1}
  241. onChange={(page: number, pageSize: number) => {
  242. // ref.current?.scrollTo({ top: 0 })
  243. setTimeout(() => {
  244. setQueryParams({ ...queryParams, pageNum: page, pageSize })
  245. setQueryParamsNew({ ...queryParamsNew, pageNum: page, pageSize })
  246. }, 50)
  247. }}
  248. showTotal={(total: number) => <span style={{ fontSize: 12 }}>共 {total} 条</span>}
  249. />
  250. </div>
  251. {/* 链接生成 模态框 */}
  252. {visible && <ModalBookLink
  253. mpList={mpList}
  254. bookPlatForm={bookPlatForm}
  255. visible={visible}
  256. initialValues={initialValues}
  257. onChange={() => {
  258. setInitialValues(undefined)
  259. setVisible(false)
  260. getCorpAutoLinkList.refresh()
  261. }}
  262. onClose={() => {
  263. setInitialValues(undefined)
  264. setVisible(false)
  265. }}
  266. />}
  267. </Card>
  268. };
  269. export default inject('store')(observer((props: any) => BookLink(props.store)));