template.tsx 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import { useAjax } from "@/Hook/useAjax";
  2. import { appComponentConfigGetAppPageList, getHotCategory, getShortBookBanners, getShortBookHotBooks } from "@/services/miniApp/compConfig";
  3. import { Card, Col, Row, Space, Spin } from "antd";
  4. import styles from './DrawerBox/index.less'
  5. import { useEffect, useMemo, useReducer } from "react";
  6. import React from "react";
  7. import { Banners } from "./components/banners";
  8. import { HotBooks } from "./components/hot_books";
  9. import { HotCategory } from "./components/hot_category";
  10. import { useModel } from "@umijs/max";
  11. import { useToken } from "@ant-design/pro-components";
  12. type Config = {
  13. bannerType?: number,//banner类型; 0:小说 1:页面路径 banners组件使用
  14. activityPagePath?: string,//banner类型 1的时候使用页面路径
  15. bannerImage?: string,//banner图片
  16. bookId?: string,//小说ID
  17. categoryId?: string,//分类ID
  18. bookIds?: any[],//用于分类自义定书籍的参数
  19. }
  20. type State = {
  21. tabs: 0 | 1,//男生女生选项
  22. isWorkDirection: boolean,//当前页面是否存在男频女频
  23. compAc: string,//当前选中的组件,切换tabs请0
  24. index: number,//每次操作修改数据都递增,为了检测到数据变动
  25. activePage: string,//当前选中的页面
  26. templateName: string,//模板名称
  27. pageList: any[],//页面表
  28. pageConfigList: {
  29. pageUrl: string,//组件所在页面地址
  30. workDirectionList: {
  31. workDirection?: 0 | 1,//作品方向;0-男频 1-女频
  32. componentConfigList: {
  33. appComponentId: number | string,//组件ID
  34. componentType: string,//组件类型
  35. showRightButton?: boolean,//是否展示左侧按钮
  36. componentName?: string,//组件名称
  37. remark?: string,//备注
  38. configs?: Config[],//组件内的配置
  39. }[]
  40. }[]
  41. }[],
  42. }
  43. type Action = {
  44. params?: any,
  45. type: "setAll",
  46. }
  47. export function reducer(state: State, action: Action) {
  48. let { type, params } = action
  49. switch (type) {
  50. case 'setAll':
  51. return { ...state, ...params }
  52. default:
  53. return state;
  54. }
  55. }
  56. export function Template(params: { data: any }) {
  57. let { data } = params
  58. let { token } = useToken()
  59. let { initialState } = useModel("@@initialState")
  60. // 接口公共参数
  61. let publicData = useMemo(() => {
  62. return {
  63. appId: initialState?.selectApp?.id || "",
  64. appType: initialState?.selectApp?.appType || ""
  65. }
  66. }, [initialState?.selectApp])
  67. const [state, dispatch] = useReducer(reducer, {
  68. tabs: 0,
  69. isWorkDirection: false,
  70. compAc: "",
  71. index: 0,
  72. activePage: "",
  73. pageConfigList: data?.pageConfigList
  74. })
  75. const list = useMemo(() => {
  76. let pageConfig = state?.pageConfigList?.find((page: { pageUrl: any; }) => page.pageUrl === state.activePage)
  77. let list: {
  78. appComponentId: number | string;
  79. componentType: string;
  80. showRightButton?: boolean;
  81. componentName?: string;
  82. remark?: string;
  83. configs?: Config[];
  84. }[] = []
  85. if (state?.isWorkDirection) {
  86. let thePage = pageConfig?.workDirectionList?.find((page: { workDirection: any; }) => page.workDirection == state.tabs)
  87. list = thePage?.componentConfigList || []
  88. } else {
  89. list = pageConfig?.workDirectionList?.[0].componentConfigList || []
  90. }
  91. return list
  92. }, [state])
  93. // 获取全部页面并且处理当前模板有哪些页面
  94. useEffect(() => {
  95. AppComponentConfigGetAppPageList.run(publicData).then(res => {
  96. if (res.code === 200 && data?.pageConfigList?.length > 0) {
  97. let pages: any = []
  98. for (let item of data?.pageConfigList) {
  99. let thatPage = res?.data?.find((page: { pagePath: any; }) => page.pagePath === item.pageUrl)
  100. if (thatPage) {
  101. pages.push(thatPage)
  102. }
  103. }
  104. pages?.length > 0 && dispatch({ type: "setAll", params: { activePage: pages[0].pagePath, isWorkDirection: true, pageList: pages } })
  105. }
  106. })
  107. }, [data])
  108. //api
  109. const GetShortBookHotBooks = useAjax((params) => getShortBookHotBooks(params))
  110. const GetShortBookBanners = useAjax((params) => getShortBookBanners(params))
  111. const GetHotCategory = useAjax((params) => getHotCategory(params))
  112. const AppComponentConfigGetAppPageList = useAjax((params) => appComponentConfigGetAppPageList(params))
  113. // 获取对应组件数据
  114. useEffect(() => {
  115. async function getData() {
  116. if (state.pageConfigList) {
  117. for (let page of state?.pageConfigList) {
  118. for (let wd of page?.workDirectionList) {
  119. for (let comp of wd?.componentConfigList) {
  120. switch (comp?.componentType) {
  121. case "banners":
  122. await GetShortBookBanners.run({ templateName: data?.templateName, workDirection: wd?.workDirection, ...publicData }).then(res => {
  123. comp.configs = res.data
  124. })
  125. break;
  126. case "hot_books":
  127. // await GetShortBookHotBooks.run({ templateName: data?.templateName, workDirection: wd?.workDirection, ...publicData }).then(res => {
  128. // comp.configs = res.data
  129. // })
  130. break;
  131. case "hot_category":
  132. await GetHotCategory.run({ templateName: data?.templateName, workDirection: wd?.workDirection, ...publicData }).then(res => {
  133. if(res.data){
  134. comp.configs = res.data?.bookCategoryList?.map((item: { id: any; }) => {
  135. return { categoryId: item.id, categoryInfo: item }
  136. })
  137. }
  138. })
  139. break;
  140. }
  141. }
  142. }
  143. }
  144. }
  145. }
  146. getData()
  147. }, [])
  148. // 获取配置页面的列表
  149. return <Spin spinning={GetShortBookHotBooks?.loading || GetShortBookBanners?.loading || GetHotCategory?.loading || AppComponentConfigGetAppPageList?.loading}>
  150. <div className={styles.phone} onClick={(e) => {
  151. e.stopPropagation()
  152. }}>
  153. <div className={styles.content} >
  154. {/* 头部男女tabs */}
  155. <Space className={styles.tabs} size={[20, 20]}>
  156. {
  157. ["男生", "女生"].map((s, i) => {
  158. return <strong
  159. key={i}
  160. className={`${styles.tabs_text} ${state?.tabs === i ? styles.tabs_ac : ""}`}
  161. onClick={() => {
  162. dispatch({ type: "setAll", params: { tabs: i, compAc: 0 } })
  163. }}
  164. >
  165. {s}
  166. </strong>
  167. })
  168. }
  169. </Space>
  170. <div className={styles.content_box}>
  171. {/* 内容 */}
  172. {
  173. list?.map(item => {
  174. // console.log("item", item)
  175. return <React.Fragment key={item.appComponentId}>
  176. <div
  177. // className={`${styles.comp} `}
  178. onClick={() => { dispatch({ type: "setAll", params: { compAc: item.componentType } }) }}
  179. >
  180. {/* banners */}
  181. {item.componentType === 'banners' && <Banners data={item.configs || []} />}
  182. {/* 热门书籍*/}
  183. {item.componentType === "hot_books" && <HotBooks data={item} />}
  184. {/* 热门分类 */}
  185. {item.componentType === "hot_category" && <HotCategory data={item} />}
  186. </div>
  187. <div className={styles.compBoxM} />
  188. </React.Fragment>
  189. })
  190. }
  191. </div>
  192. <div className={styles.phone_footer}>
  193. {
  194. state?.pageList?.map((item: { pagePath: React.Key | null | undefined; pageName: string | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | null | undefined; }) => {
  195. return <div key={item.pagePath} className={state.activePage === item.pagePath && styles.footer_ac}>{item.pageName}</div>
  196. })
  197. }
  198. </div>
  199. </div>
  200. </div>
  201. </Spin>
  202. }