shenwu 7 달 전
부모
커밋
a51cb04718

+ 1 - 1
src/models/appPageConifg.tsx

@@ -17,7 +17,7 @@ type State = {
     templateName:string,//模板名称
     pageConfigList: {
         pageUrl: string,//组件所在页面地址
-        workDirectionListDTOS: {
+        workDirectionList: {
             workDirection?: 0 | 1,//作品方向;0-男频 1-女频
             componentConfigList: {
                 appComponentId: number | string,//组件ID

+ 6 - 6
src/pages/MiniApp/CompConfig/DrawerBox/compConfig.tsx

@@ -47,10 +47,10 @@ export function CompConfig(props: Props) {
             configs?: Config[];
         }[] = []
         if (state.isWorkDirection) {
-            let thePage = pageConfig?.workDirectionListDTOS?.find(page => page.workDirection == state.tabs)
+            let thePage = pageConfig?.workDirectionList?.find(page => page.workDirection == state.tabs)
             list = thePage?.componentConfigList || []
         } else {
-            list = pageConfig?.workDirectionListDTOS?.[0].componentConfigList || []
+            list = pageConfig?.workDirectionList?.[0].componentConfigList || []
         }
         return list
     }, [state])
@@ -97,7 +97,7 @@ export function CompConfig(props: Props) {
         }
         // 判断当前页面是否存在男女频,获取对应的页面配置列表
         if (state.isWorkDirection) {
-            let thePage = pageConfig?.workDirectionListDTOS?.find(page => page.workDirection == state.tabs)
+            let thePage = pageConfig?.workDirectionList?.find(page => page.workDirection == state.tabs)
             if (thePage) {
                 // 删除的判断
                 if (isDel) {
@@ -109,12 +109,12 @@ export function CompConfig(props: Props) {
         } else {
             if (pageConfig) {
                 if (isDel) {
-                    pageConfig.workDirectionListDTOS[0].componentConfigList = list?.filter(item => item.componentType !== compName)
+                    pageConfig.workDirectionList[0].componentConfigList = list?.filter(item => item.componentType !== compName)
                 } else {
-                    pageConfig.workDirectionListDTOS[0].componentConfigList = list
+                    pageConfig.workDirectionList[0].componentConfigList = list
                 }
             }
-            pageConfig && (pageConfig.workDirectionListDTOS[0].componentConfigList = list)
+            pageConfig && (pageConfig.workDirectionList[0].componentConfigList = list)
         }
         // 修改保存数据到状态管理
         dispatch({

+ 7 - 9
src/pages/MiniApp/CompConfig/DrawerBox/content.tsx

@@ -24,10 +24,10 @@ const DragItem = () => {
             configs?: Config[];
         }[] = []
         if (state.isWorkDirection) {
-            let thePage = pageConfig?.workDirectionListDTOS?.find(page => page.workDirection == state.tabs)
+            let thePage = pageConfig?.workDirectionList?.find(page => page.workDirection == state.tabs)
             list = thePage?.componentConfigList || []
         } else {
-            list = pageConfig?.workDirectionListDTOS?.[0].componentConfigList || []
+            list = pageConfig?.workDirectionList?.[0].componentConfigList || []
         }
         return list
     }, [state])
@@ -65,7 +65,7 @@ const DragItem = () => {
             if (!pageConfig) {
                 pageConfigList.push({
                     pageUrl: activePage,
-                    workDirectionListDTOS: isWorkDirection ? [
+                    workDirectionList: isWorkDirection ? [
                         {
                             workDirection: 0,
                             componentConfigList: []
@@ -83,14 +83,14 @@ const DragItem = () => {
                 pageConfig = pageConfigList.find(page => page.pageUrl === activePage)
             }
             // 存在男女频页面
-            if (isWorkDirection && pageConfig?.workDirectionListDTOS) {
-                for (let page of pageConfig?.workDirectionListDTOS) {
+            if (isWorkDirection && pageConfig?.workDirectionList) {
+                for (let page of pageConfig?.workDirectionList) {
                     if (page.workDirection == tabs) {
                         page.componentConfigList = [...page.componentConfigList, newConfig]
                     }
                 }
-            } else if (pageConfig?.workDirectionListDTOS) {// 不存在男女频页面
-                pageConfig.workDirectionListDTOS[0].componentConfigList = [...pageConfig.workDirectionListDTOS[0].componentConfigList, newConfig]
+            } else if (pageConfig?.workDirectionList) {// 不存在男女频页面
+                pageConfig.workDirectionList[0].componentConfigList = [...pageConfig.workDirectionList[0].componentConfigList, newConfig]
             }
             dispatch({
                 type: 'setAll', params: { pageConfigList, index: state.index + 1 }
@@ -149,13 +149,11 @@ const Content = forwardRef((props: Props, ref) => {
                         </strong>
                     })
                 }
-
             </Space>
             <div className={styles.content_box}>
                 {/* 内容 */}
                 <DragItem />
             </div>
-
         </div>
     </div>
 })

+ 56 - 25
src/pages/MiniApp/CompConfig/DrawerBox/index.less

@@ -1,7 +1,8 @@
 // 左侧组件列表
 .pageList {
-    display:flex;
+    display: flex;
     flex-flow: column;
+
     .box {
         width: 5vw;
         height: 4vw;
@@ -10,14 +11,16 @@
         display: flex;
         align-items: center;
         justify-content: center;
-        font-size:calc(100vw / 150) ;
+        font-size: calc(100vw / 150);
     }
 }
 
 //中间内容区域
 .phone {
-    width: 25vw; /* 宽度设置为窗口宽度的50% */
-    height: calc(22vw *2); /* 按比例设置高度,保持与原始比例一致 */
+    width: 25vw;
+    /* 宽度设置为窗口宽度的50% */
+    height: calc(22vw *2);
+    /* 按比例设置高度,保持与原始比例一致 */
     background: url('../../../../../public/phone.png') no-repeat;
     background-size: 210%;
     background-position-x: 50%;
@@ -25,14 +28,19 @@
     display: flex;
     justify-content: center;
     align-items: center;
+
     // border: 1px solid #000;
     .content {
-        width: 17vw; /* 内容宽度相对于窗口宽度 */
-        height: calc(18vw *2.1); /* 根据比例缩放高度 */
+        width: 17vw;
+        /* 内容宽度相对于窗口宽度 */
+        height: calc(18vw *2.1);
+
+        /* 根据比例缩放高度 */
         // border: 1px solid #000;
-        .tabs{ 
-             margin-bottom: 20px;
-            .tabs_text{
+        .tabs {
+            margin-bottom: 20px;
+
+            .tabs_text {
                 width: 48px;
                 height: 33px;
                 font-family: PingFangSC, PingFang SC;
@@ -40,14 +48,16 @@
                 font-size: calc(100vw / 130);
                 color: #999;
                 line-height: 33px;
-                font-style: normal; 
+                font-style: normal;
                 cursor: pointer;
             }
-            .tabs_ac{
-                font-size: calc(100vw / 100);  
+
+            .tabs_ac {
+                font-size: calc(100vw / 100);
                 color: #000;
                 position: relative;
-                &::after{
+
+                &::after {
                     content: "";
                     width: 20px;
                     height: 2px;
@@ -60,30 +70,50 @@
                 }
             }
         }
-        .content_box{
-            height: calc(18vw *2); /* 根据比例缩放高度 */
+
+        .content_box {
+            height: calc(18vw *2);
+            /* 根据比例缩放高度 */
             overflow-y: auto;
-            &::-webkit-scrollbar{
-                display: none;  /* 隐藏滚动条 */
+
+            &::-webkit-scrollbar {
+                display: none;
+                /* 隐藏滚动条 */
             }
         }
-        .comp{
+
+        .comp {
             cursor: pointer;
             box-sizing: border-box;
-            &:hover{
-                border:1px solid rgb(72, 159, 247);
+            &:hover {
+                border: 1px solid rgb(72, 159, 247);
                 border-radius: 10px;
             }
         }
-        .ac{
-            border:1px dashed rgb(72, 159, 247);
+
+        .ac {
+            border: 1px dashed rgb(72, 159, 247);
             border-radius: 10px;
         }
     }
+
+    .phone_footer {
+        width: 17vw;
+        display: flex;
+        justify-content: space-around;
+        div {
+            font-size: calc(100vw / 150);
+            font-weight: 500;
+        }
+        .footer_ac {
+            color: #F02C4D;
+        }
+    }
 }
+
 .compBoxM {
     height: calc(100vw / 102);
- }
+}
 
 // 右侧参数设置
 .set {
@@ -92,10 +122,11 @@
     overflow-y: auto;
 }
 
-.upDownBtn{
+.upDownBtn {
     margin-left: 8px;
     cursor: pointer;
-    &:hover{
+
+    &:hover {
         color: #40a9ff;
     }
 }

+ 13 - 7
src/pages/MiniApp/CompConfig/DrawerBox/index.tsx

@@ -26,7 +26,7 @@ const ModalForm = forwardRef((props: Props, ref) => {
     const [templateName, setTemplateName] = useState("")
     const AppComponentConfigGetAppPageList = useAjax((params) => appComponentConfigGetAppPageList(params))
     const AppComponentConfigAddOrUpdate = useAjax((params) => appComponentConfigAddOrUpdate(params))//添加
-    console.log("props", props)
+    // console.log("props", props)
     // 接口公共参数
     let publicData = useMemo(() => {
         return {
@@ -36,12 +36,17 @@ const ModalForm = forwardRef((props: Props, ref) => {
     }, [initialState?.selectApp])
     // 获取当前小程序可配置的页面和组件
     useEffect(() => {
-        AppComponentConfigGetAppPageList.run(publicData).then(res => {
-            let page = res?.data?.find((page: { enabledComponent: any; }) => page.enabledComponent)
-            page && dispatch({ type: "setAll", params: { activePage: page?.pagePath, isWorkDirection: true } })
-        })
-    }, [publicData])
-
+        if(open){
+            AppComponentConfigGetAppPageList.run(publicData).then(res => {
+                let page = res?.data?.find((page: { enabledComponent: any; }) => page.enabledComponent)
+                page && dispatch({ type: "setAll", params: { activePage: page?.pagePath, isWorkDirection: true } })
+            })
+        }
+    }, [publicData,open])
+    // 编辑时替换模板名称
+    useEffect(()=>{
+        setTemplateName(state.templateName)
+    },[])
     // close 方法,用于关闭 Drawer
     const close = () => {
         dispatch({
@@ -68,6 +73,7 @@ const ModalForm = forwardRef((props: Props, ref) => {
         AppComponentConfigAddOrUpdate.run({ templateName, pageConfigList: state.pageConfigList, ...publicData }).then(res => {
             if (res.code === 200) {
                 props?.listApi?.refresh()
+                AppComponentConfigGetAppPageList.refresh()
                 close()
             }
         })

+ 2 - 2
src/pages/MiniApp/CompConfig/DrawerBox/pageList.tsx

@@ -80,7 +80,7 @@ const PageList = forwardRef((props: Props, ref) => {
                                 let newComp = { ...comp, pagePath: item.pagePath }
                                 let appType = initialState?.selectApp?.appType || 0
                                 let pageConfig = state.pageConfigList.find(page => page.pageUrl === item.pagePath)
-                                let thePage = pageConfig?.workDirectionListDTOS?.find(page => page.workDirection == state.tabs)
+                                let thePage = pageConfig?.workDirectionList?.find(page => page.workDirection == state.tabs)
                                 let list = thePage?.componentConfigList || []
                                 newComp.disabled = !!list.find(i => i.appComponentId == newComp.id)
                                 if (newComp.enabledAppTypes.includes(appType)) {
@@ -97,7 +97,7 @@ const PageList = forwardRef((props: Props, ref) => {
                                     let newComp = { ...comp, pagePath: item.pagePath }
                                     let appType = initialState?.selectApp?.appType || 0
                                     let pageConfig = state.pageConfigList.find((page: { pageUrl: any; }) => page.pageUrl === item.pagePath)
-                                    let thePage = pageConfig?.workDirectionListDTOS?.find(page => page.workDirection == state.tabs)
+                                    let thePage = pageConfig?.workDirectionList?.find(page => page.workDirection == state.tabs)
                                     let list = thePage?.componentConfigList || []
                                     newComp.disabled = !!list.find(i => i.appComponentId == newComp.id)
                                     if (newComp.enabledAppTypes.includes(appType)) {

+ 2 - 3
src/pages/MiniApp/CompConfig/components/hot_category.tsx

@@ -39,7 +39,6 @@ export function HotCategory(props: {
 
     useEffect(() => {
         if (tag && tag !== prevTag && configs && configs.length > 0 && configs?.[0]?.categoryId) {
-            console.log("tag变化", tag)
             getList.run({ ...publicData, categoryId: tag, pageNum: 1, pageSize: 8 }).then(res => {
                 if (res.code === 200) {
                     setBookData(res?.data?.records)
@@ -84,7 +83,7 @@ export function HotCategory(props: {
         </div>
         <div className={styles.list}>
             {
-                configs?.find(i => i.categoryId == tag)?.bookIds ? configs?.find(i => i.categoryId == tag)?.bookInfos?.map((item: any, index:any) => {
+                configs?.find(i => i.categoryId == tag)?.bookIds ? configs?.find(i => i.categoryId == tag)?.bookInfos?.map((item: any, index: any) => {
                     return <div key={item.id || index} className={styles.box}>
                         <img src={item?.picUrl} onError={(e: any) => {
                             e.target.src = localStorage.getItem("nocover")
@@ -92,7 +91,7 @@ export function HotCategory(props: {
                         <span>{item?.bookName}</span>
                     </div>
                 }) : bookData?.length > 0 ? bookData?.map((item: any, index) => {
-                    return <div key={item || index} className={styles.box}>
+                    return <div key={item.bookId || index} className={styles.box}>
                         <img src={item?.longBookInfo?.picUrl || item?.shortBookInfoVO?.picUrl} onError={(e: any) => {
                             e.target.src = localStorage.getItem("nocover")
                         }} />

+ 28 - 97
src/pages/MiniApp/CompConfig/index.tsx

@@ -8,7 +8,7 @@ import { DeleteOutlined, EditOutlined, ExclamationCircleFilled, PlusOutlined } f
 import { Template } from "./template"
 import { createStyles } from "antd-style";
 import DrawerBox from "./DrawerBox"
-import { appComponentConfigList } from "@/services/miniApp/compConfig"
+import { appComponentConfigList, remove, updateTemplate } from "@/services/miniApp/compConfig"
 const useStyles = createStyles(({ token }) => {
     return {
         active: {
@@ -35,27 +35,17 @@ type DataItem = {
 const Page: React.FC = () => {
     let { token } = useToken()
     let { initialState } = useModel("@@initialState")
-    let { enumList } = useModel("global", (global) => {
-        return {
-            enumList: global.state.enumList
-        }
-    })
-    let [open, setOpen] = useState<any>(null)
-    let [editValues, setEditValues] = useState<any>({})
+    let { dispatch } = useModel("appPageConifg")
     let [activeT, setActiveT] = useState<any>()
     let { styles } = useStyles()
     let getList = useAjax((params) => appComponentConfigList(params))//获取模板列表
-    let add = useAjax((params) => appRechargeTemplateSave(params))//新增模板
-    let switchT = useAjax((params) => appRechargeTemplateSwitch(params))//切换模板
-    let editT = useAjax((params) => appRechargeTemplateUpdate(params))//编辑模板
-    let delT = useAjax((params) => appRechargeTemplateRemove(params))//删除模板
-    let infoT = useAjax((id) => appRechargeTemplateInfo(id))//模板详情
+    let switchT = useAjax((params) => updateTemplate(params))//切换
+    let delT = useAjax((params) => remove(params))//删除
     const formRef = useRef<ProFormInstance>();
     const DrawerBoxRef = useRef<{ close: () => void; openDrawer: () => void }>(null);
     let publicData = useMemo(() => {
         return {
             appId: initialState?.selectApp?.id || "",
-            distributorId: initialState?.currentUser?.distributorId,
             appType: initialState?.selectApp?.appType || ""
         }
     }, [initialState?.selectApp, initialState?.currentUser?.distributorId])
@@ -64,82 +54,23 @@ const Page: React.FC = () => {
         getList.run(publicData).then(res => {
             if (res.data) {
                 let activeObj = res?.data?.find((item: { activateTemplate: any }) => item.activateTemplate)
-                activeObj && setActiveT(activeObj.id)
+                activeObj && setActiveT(activeObj.templateName)
             }
         })
     }, [publicData])
-    // 提交表单
-    const submit = async (values: any) => {
-        let api = editValues?.id ? editT : add
-        if (!values.activateTemplate) {
-            values.activateTemplate = false
-        }
-        if (editValues?.id) {
-            values.id = editValues?.id
-        }
-        values.rechargeConfigs = []
-        if (values.rechargeConfigList?.length > 0) {//首充
-            values.rechargeConfigs.push({
-                firstRecharge: true,//是否首充档位;true:首充 false:非首充
-                rechargeConfigList: values.rechargeConfigList,
-            })
-        }
-        if (values.rechargeConfigList1?.length > 0) {//非首充
-            values.rechargeConfigs.push(
-                {
-                    firstRecharge: false,//是否首充档位;true:首充 false:非首充
-                    rechargeConfigList: values.rechargeConfigList1,
-                }
-            )
-        }
-        delete values.rechargeConfigList
-        delete values.rechargeConfigList1
-        api.run({ ...values, ...publicData }).then(res => {
-            if (res.code === 200) {
-                getList.refresh()
-                message.success(values.id ? "编辑模板成功" : "新建模板成功!")
-                closeForm(false)
-            }
-        })
-    }
-    // 关闭表单弹窗和重置表单内容
-    const closeForm = (b: boolean, values?: any) => {
-        if (!b) {
-            setEditValues({})
-            formRef?.current?.resetFields?.()
-            setOpen(b)
-        } else {
-            setOpen(b)
-            if (values) {
-                infoT.run(values.id).then(res => {
-                    if (res.code === 200) {
-                        let data = res.data
-                        for (let item of data.rechargeConfigs) {
-                            if (item.firstRecharge) {
-                                data.rechargeConfigList = item.rechargeConfigList
-                            } else {
-                                data.rechargeConfigList1 = item.rechargeConfigList
-                            }
-                        }
-                        setEditValues(data)
-                        formRef?.current?.setFieldsValue(data)
-                    }
-                })
-            }
-        }
-    }
+    console.log(activeT)
     // 模板切换
-    const switchTemplate = (id: any) => {
-        let params = { ...publicData, id }
+    const switchTemplate = (templateName: any) => {
+        let params = { ...publicData, templateName }
         Modal.confirm({
-            title: '切换充值模板',
-            content: '是否要切换为当前充值模板?',
+            title: '切换组件模板',
+            content: '是否要切换为当前组件模板?',
             icon: <ExclamationCircleFilled />,
             okText: "切换",
             onOk: () => {
                 switchT.run(params).then(res => {
                     if (res.code === 200) {
-                        setActiveT(id)
+                        setActiveT(templateName)
                         getList.refresh()
                         message.success("切换成功")
                     }
@@ -148,15 +79,16 @@ const Page: React.FC = () => {
         });
     }
     // 模板删除
-    const delTemplate = (id: any) => {
+    const delTemplate = (templateName: any) => {
+        let params = { ...publicData, templateName }
         Modal.confirm({
-            title: '删除充值模板',
-            content: '是否要删除当前充值模板?',
+            title: '删除组件模板',
+            content: '是否要删除当前组件模板?',
             icon: <ExclamationCircleFilled />,
             okType: 'danger',
             okText: "删除",
             onOk: () => {
-                delT.run(id).then(res => {
+                delT.run(params).then(res => {
                     if (res.code === 200) {
                         getList.refresh()
                         message.success("删除成功")
@@ -165,34 +97,33 @@ const Page: React.FC = () => {
             }
         });
     }
+    // 编辑
+    const edit=(data:any)=>{
+        dispatch({type:'setAll',params:{templateName:data?.templateName,pageConfigList:data?.pageConfigList}})
+        DrawerBoxRef?.current?.openDrawer();
+    }
     return <PageContainer
         extra={getList?.data?.data?.length > 0 && <Button type="primary" onClick={DrawerBoxRef?.current?.openDrawer}><PlusOutlined />新增配置</Button>}
     >
         {/* 模板列表 */}
         <Row gutter={[20, 20]}>
-            {/* {
-                getList?.data?.data?.map((item: { id: Key | null | undefined; templateName: string | number | boolean | ReactElement<any, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | null | undefined; rechargeConfigs: any[]; templateType: number; templateDescription: string | number | boolean | ReactElement<any, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | null | undefined }) => {
-                    return <Col key={item.id} style={{ cursor: 'pointer' }} onClick={() => { switchTemplate(item.id) }} xs={{ span: 24 }} sm={{ span: 8 }}>
-                        <Card className={activeT === item.id ? styles.active : ""} style={{ background: activeT === item.id ? token.colorPrimaryBgHover : token.colorFillAlter }} hoverable>
+            {
+                getList?.data?.data?.map((item: any) => {
+                    return <Col key={item.templateName} style={{ cursor: 'pointer' }} onClick={() => { switchTemplate(item.templateName) }} >
+                        <Card className={activeT === item.templateName ? styles.active : ""} style={{ background: activeT === item.templateName ? token.colorPrimaryBgHover : token.colorFillAlter }} hoverable>
                             <h3 style={{ fontSize: 16, fontWeight: 500, color: token.colorText, fontFamily: 'PingFang SC' }}>{item.templateName}</h3>
-                            {
-                                item.rechargeConfigs?.map((config, index) => {
-                                    return <React.Fragment key={index}>
-                                        <Template data={config} enmuList={enumList} />
-                                    </React.Fragment>
-                                })
-                            }
+                            <Template data={item} />
                             <p style={{ marginTop: 20, color: token.colorTextSecondary, fontSize: 12 }}>{item.templateDescription}</p>
                             <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'end' }}>
                                 <Space>
-                                    <Button size='small' type='primary' onClick={(e) => { e.stopPropagation(); closeForm(true, item) }}><EditOutlined /></Button>
+                                    <Button size='small' type='primary' onClick={(e) => { e.stopPropagation(); edit(item) }}><EditOutlined /></Button>
                                     <Button size='small' type="primary" danger onClick={(e) => { e.stopPropagation(); delTemplate(item.id) }}><DeleteOutlined /></Button>
                                 </Space>
                             </div>
                         </Card>
                     </Col>
                 })
-            } */}
+            }
             {
                 getList?.data?.data?.length === 0 && <div style={{ width: "100%", height: "100%", marginTop: "10%" }}><Empty description={<Space direction='vertical'><div>暂无模板数据</div><Button type="primary" onClick={DrawerBoxRef?.current?.openDrawer}><PlusOutlined />新增模板</Button></Space>} /></div>
             }

+ 196 - 136
src/pages/MiniApp/CompConfig/template.tsx

@@ -1,142 +1,202 @@
-import { Card, Col, Row } from "antd";
-import jb from '../../../../public//jb.png';
-import vip from '../../../../public//vip.png';
-import top from '../../../../public//top-r1.png';
-import { createStyles } from "antd-style";
-
-
-export function Template(params: { data: any, enmuList: any }) {
-    let { data, enmuList } = params
-    let { firstRecharge, rechargeConfigList } = data
-    const useStyles = createStyles((props) => {
-        let { token } = props
-        let navTheme = localStorage.getItem("navTheme")//全局 2亮色 3黑色
+import { useAjax } from "@/Hook/useAjax";
+import { appComponentConfigGetAppPageList, getHotCategory, getShortBookBanners, getShortBookHotBooks } from "@/services/miniApp/compConfig";
+import { Card, Col, Row, Space, Spin } from "antd";
+import styles from './DrawerBox/index.less'
+import { useEffect, useMemo, useReducer } from "react";
+import React from "react";
+import { Banners } from "./components/banners";
+import { HotBooks } from "./components/hot_books";
+import { HotCategory } from "./components/hot_category";
+import { useModel } from "@umijs/max";
+import { useToken } from "@ant-design/pro-components";
+type Config = {
+    bannerType?: number,//banner类型; 0:小说 1:页面路径 banners组件使用
+    activityPagePath?: string,//banner类型 1的时候使用页面路径
+    bannerImage?: string,//banner图片
+    bookId?: string,//小说ID
+    categoryId?: string,//分类ID
+    bookIds?: any[],//用于分类自义定书籍的参数
+}
+type State = {
+    tabs: 0 | 1,//男生女生选项
+    isWorkDirection: boolean,//当前页面是否存在男频女频
+    compAc: string,//当前选中的组件,切换tabs请0
+    index: number,//每次操作修改数据都递增,为了检测到数据变动
+    activePage: string,//当前选中的页面
+    templateName: string,//模板名称
+    pageList: any[],//页面表
+    pageConfigList: {
+        pageUrl: string,//组件所在页面地址
+        workDirectionList: {
+            workDirection?: 0 | 1,//作品方向;0-男频 1-女频
+            componentConfigList: {
+                appComponentId: number | string,//组件ID
+                componentType: string,//组件类型
+                showRightButton?: boolean,//是否展示左侧按钮
+                componentName?: string,//组件名称
+                remark?: string,//备注
+                configs?: Config[],//组件内的配置
+            }[]
+        }[]
+    }[],
+}
+type Action = {
+    params?: any,
+    type: "setAll",
+}
+export function reducer(state: State, action: Action) {
+    let { type, params } = action
+    switch (type) {
+        case 'setAll':
+            return { ...state, ...params }
+        default:
+            return state;
+    }
+}
+export function Template(params: { data: any }) {
+    let { data } = params
+    let { token } = useToken()
+    let { initialState } = useModel("@@initialState")
+    // 接口公共参数
+    let publicData = useMemo(() => {
         return {
-            cardBox: {
-                position: 'relative'
-            },
-            bgVip: {
-                backgroundImage: "linear-gradient(180deg, #fff1dc 60%, #fffdfa 100%)",
-                color: navTheme == "3" ? "#000" : "unset"
-            },
-            bg: {
-                backgroundImage: 'linear-gradient(180deg, #ffeced 60%, #fffafa 100%)',
-                color: navTheme == "3" ? "#000" : "unset"
-            },
-            topRight: {
-                lineHeight: '20px',
-                background: "#ff2441",
-                position: 'absolute',
-                top: 0,
-                right: 0,
-                fontSize: 12,
-                borderRadius: "0px 8px 0 8px",
-            },
-            topRightVip: {
-                background: "#ffd89d !important",
-            },
-            // 
-            topRightSpan1: { display: 'inline-block', background: `url(${top}) no-repeat`, minWidth: 40, height: 20, padding: "0 10px 0 6px", backgroundSize: "100% 100%", color: "#fff" },
-            topRightSpan2: { color: "#fff", display: 'inline-block', padding: "0 5px" },
-            del: { fontSize: 14, textDecoration: 'line-through', marginLeft: 7, color: token.colorTextTertiary, fontWeight: "500" }
+            appId: initialState?.selectApp?.id || "",
+            appType: initialState?.selectApp?.appType || ""
         }
-    });
-    let { styles } = useStyles()
-
-    return <Card bordered={false} >
-        <Row gutter={[0, 15]}>
-            {
-                rechargeConfigList?.map((item: any, index: any) => {
-                    let {
-                        color,//背景色
-                        description,//整数购买文案
-                        extra,//右上角描述值
-                        gearType,//充值类型
-                        gift,//赠送
-                        obtain,//获得书币/vip每天价格
-                        price,//价格
-                        subscript,//右上角文案 首充|超值等
-                        vipDays,//vip天数
-                    } = item
-                    switch (gearType) {
-                        case 1://充值
-                            return <Col key={index} span={11} offset={index % 2 === 0 ? 0 : 1} >
-                                <Card className={`${styles.cardBox} ${color && styles.bg}`} styles={{ body: { maxHeight: 90, padding: '20px 15px' } }}>
-                                    {/* 右上角 */}
-                                    <div className={`${styles.topRight}`} style={subscript ? { borderRadius: "8px 8px 0 8px", } : {}} >
-                                        {
-                                            <>
-                                                {subscript && <span className={styles.topRightSpan1}>{subscript}</span>}
-                                                <span className={styles.topRightSpan2} style={subscript ? { transform: 'translateX(-4px)' } : {}}>多送{extra}元</span>
-                                            </>
-                                        }
-                                    </div>
-                                    <div style={{ display: 'flex', flexFlow: 'column' }}>
-                                        <strong >
-                                            <span style={{ fontSize: '20px', marginRight: 3 }} >¥</span>
-                                            <span style={{ fontSize: 22, fontFamily: 'Yuewen Font' }}>{price}</span>
-                                        </strong>
-                                        <span style={{ fontSize: 12, marginTop: 2, color: "#777", display: 'block' }}>{obtain}书币 送{gift}书券</span>
-                                    </div>
-                                    {color && <img src={jb} style={{ position: 'absolute', right: 0, bottom: 0, width: 50 }} />}
-                                </Card>
-                            </Col>
-                        case 2://vip
-                            let vipEnum = enmuList?.VIP_DAYS?.values;
-                            let vipStr = vipEnum?.find((i: { value: any; }) => i.value === vipDays)?.description || ""
-                            return <Col key={index} span={11} offset={index % 2 === 0 ? 0 : 1} >
-                                <Card className={`${styles.cardBox} ${color && styles.bgVip}`} styles={{ body: { maxHeight: 90, padding: '20px 15px' } }}>
-                                    {/* 右上角 */}
-                                    <div className={`${styles.topRight} ${styles.topRightVip}`} style={subscript ? { borderRadius: "8px 8px 0 8px", } : {}}>
-                                        {
-                                            <>
-                                                {subscript && <span className={styles.topRightSpan1}>{subscript}</span>}
-                                                <span className={styles.topRightSpan2}>{vipStr}</span>
-                                            </>
-                                        }
-                                    </div>
-                                    <div style={{ display: 'flex', flexFlow: 'column' }}>
-                                        <strong >
-                                            <span style={{ fontSize: '20px', marginRight: 3 }} >¥</span>
-                                            <span style={{ fontSize: 22, fontFamily: 'Yuewen Font' }}>{price}</span>
-                                        </strong>
-                                        <span style={{ fontSize: 12, marginTop: 2, color: "#777", display: 'block' }}>¥{obtain}元/天</span>
-                                    </div>
-                                    {color && <img src={vip} style={{ position: 'absolute', right: 0, bottom: 0, width: 30 }} />}
-                                </Card>
-                            </Col>
-                        case 3://整本
-                            return <Col key={index} span={11} offset={index % 2 === 0 ? 0 : 1} >
-                                <Card className={`${styles.cardBox} `} styles={{ body: { maxHeight: 90, padding: '20px 15px' } }}>
-                                    {/* 右上角 */}
-                                    <div className={styles.topRight}>
-                                        {
-                                            subscript ? <> <span>{item.description}</span></> : <>
-                                                <span className={styles.topRightSpan1}>{subscript}</span>
-                                                <span className={styles.topRightSpan2}>{item.description}</span>
-                                            </>
+    }, [initialState?.selectApp])
+    const [state, dispatch] = useReducer(reducer, {
+        tabs: 0,
+        isWorkDirection: false,
+        compAc: "",
+        index: 0,
+        activePage: "",
+        pageConfigList: data?.pageConfigList
+    })
+    const list = useMemo(() => {
+        let pageConfig = state?.pageConfigList?.find((page: { pageUrl: any; }) => page.pageUrl === state.activePage)
+        let list: {
+            appComponentId: number | string;
+            componentType: string;
+            showRightButton?: boolean;
+            componentName?: string;
+            remark?: string;
+            configs?: Config[];
+        }[] = []
+        if (state?.isWorkDirection) {
+            let thePage = pageConfig?.workDirectionList?.find((page: { workDirection: any; }) => page.workDirection == state.tabs)
+            list = thePage?.componentConfigList || []
+        } else {
+            list = pageConfig?.workDirectionList?.[0].componentConfigList || []
+        }
+        return list
+    }, [state])
+    // 获取全部页面并且处理当前模板有哪些页面
+    useEffect(() => {
+        AppComponentConfigGetAppPageList.run(publicData).then(res => {
+            if (res.code === 200 && data?.pageConfigList?.length > 0) {
+                let pages: any = []
+                for (let item of data?.pageConfigList) {
+                    let thatPage = res?.data?.find((page: { pagePath: any; }) => page.pagePath === item.pageUrl)
+                    if (thatPage) {
+                        pages.push(thatPage)
+                    }
+                }
+                pages?.length > 0 && dispatch({ type: "setAll", params: { activePage: pages[0].pagePath, isWorkDirection: true, pageList: pages } })
+            }
+        })
+    }, [data])
+    //api
+    const GetShortBookHotBooks = useAjax((params) => getShortBookHotBooks(params))
+    const GetShortBookBanners = useAjax((params) => getShortBookBanners(params))
+    const GetHotCategory = useAjax((params) => getHotCategory(params))
+    const AppComponentConfigGetAppPageList = useAjax((params) => appComponentConfigGetAppPageList(params))
+    // 获取对应组件数据
+    useEffect(() => {
+        async function getData() {
+            if (state.pageConfigList) {
+                for (let page of state?.pageConfigList) {
+                    for (let wd of page?.workDirectionList) {
+                        for (let comp of wd?.componentConfigList) {
+                            switch (comp?.componentType) {
+                                case "banners":
+                                    await GetShortBookBanners.run({ templateName: data?.templateName, workDirection: wd?.workDirection, ...publicData }).then(res => {
+                                        comp.configs = res.data
+                                    })
+                                    break;
+                                case "hot_books":
+                                    // await GetShortBookHotBooks.run({ templateName: data?.templateName, workDirection: wd?.workDirection, ...publicData }).then(res => {
+                                    //     comp.configs = res.data
+                                    // })
+                                    break;
+                                case "hot_category":
+                                    await GetHotCategory.run({ templateName: data?.templateName, workDirection: wd?.workDirection, ...publicData }).then(res => {
+                                        if(res.data){
+                                            comp.configs = res.data?.bookCategoryList?.map((item: { id: any; }) => {
+                                                return { categoryId: item.id, categoryInfo: item }
+                                            })
                                         }
-                                    </div>
-                                    <div style={{ display: 'flex', flexFlow: 'column' }}>
-                                        <strong >
-                                            <span style={{ fontSize: '20px', marginRight: 3 }} >¥</span>
-                                            <span style={{ fontSize: 22, fontFamily: 'Yuewen Font' }}>{price}</span>
-                                            {/* {isVip && item.gift && <span className={styles.del}>¥{item.gift}</span>} */}
-                                        </strong>
-                                        {/* {isVip ?
-                                    <span style={{ fontSize: 12, marginTop: 2, color: "#777", display: 'block' }}>{isOne ? "仅" : "¥"}{item.extra}元/天</span>
-                                    :
-                                    <span style={{ fontSize: 12, marginTop: 2, color: "#777", display: 'block' }}>{item.gift}书币 送{item.extra}书券</span>} */}
-                                    </div>
-                                    {/* {isOne && <img src={isVip ? vip : jb} style={{ position: 'absolute', right: 0, bottom: 0, width: isVip ? 30 : 50 }} />} */}
-                                </Card>
-                            </Col>
-                        default:
-                            break;
+                                    })
+                                    break;
+                            }
+                        }
                     }
-
-                })
+                }
             }
-        </Row>
-    </Card >
+        }
+        getData()
+    }, [])
+    // 获取配置页面的列表
+    return <Spin spinning={GetShortBookHotBooks?.loading || GetShortBookBanners?.loading || GetHotCategory?.loading || AppComponentConfigGetAppPageList?.loading}>
+        <div className={styles.phone} onClick={(e) => {
+            e.stopPropagation()
+        }}>
+            <div className={styles.content} >
+                {/* 头部男女tabs */}
+                <Space className={styles.tabs} size={[20, 20]}>
+                    {
+                        ["男生", "女生"].map((s, i) => {
+                            return <strong
+                                key={i}
+                                className={`${styles.tabs_text} ${state?.tabs === i ? styles.tabs_ac : ""}`}
+                                onClick={() => {
+                                    dispatch({ type: "setAll", params: { tabs: i, compAc: 0 } })
+                                }}
+                            >
+                                {s}
+                            </strong>
+                        })
+                    }
+                </Space>
+                <div className={styles.content_box}>
+                    {/* 内容 */}
+                    {
+                        list?.map(item => {
+                            // console.log("item", item)
+                            return <React.Fragment key={item.appComponentId}>
+                                <div
+                                    // className={`${styles.comp} `}
+                                    onClick={() => { dispatch({ type: "setAll", params: { compAc: item.componentType } }) }}
+                                >
+                                    {/* banners */}
+                                    {item.componentType === 'banners' && <Banners data={item.configs || []} />}
+                                    {/* 热门书籍*/}
+                                    {item.componentType === "hot_books" && <HotBooks data={item} />}
+                                    {/* 热门分类 */}
+                                    {item.componentType === "hot_category" && <HotCategory data={item} />}
+                                </div>
+                                <div className={styles.compBoxM} />
+                            </React.Fragment>
+                        })
+                    }
+                </div>
+                <div className={styles.phone_footer}>
+                    {
+                        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; }) => {
+                            return <div key={item.pagePath} className={state.activePage === item.pagePath && styles.footer_ac}>{item.pageName}</div>
+                        })
+                    }
+                </div>
+            </div>
+        </div>
+    </Spin>
 }

+ 54 - 5
src/services/miniApp/compConfig/index.tsx

@@ -4,20 +4,34 @@ type Page = {
     pageSize: number | string,
     pageNum: number | string
 }
-interface PublicParams{
+interface PublicParams {
     appId: string,//微信小程序组件ID
     appType: string,//小程序类型 1:微信小程序、2:抖音小程序
 }
-export interface Params extends Page,PublicParams{}
-/**微信小程序组件模板分页列表 */
+export interface Params extends Page, PublicParams { }
+/**全部组件列表 */
 export async function appComponentConfigList(params: Params) {
     return request(api + '/admin/appComponentConfig/list', {
         method: 'GET',
         params
     });
 }
-
-
+/**模板切换 */
+export async function updateTemplate(params: any) {
+    let { templateName, ...data } = params
+    return request(api + `/admin/appComponentConfig/updateTemplate/${templateName}`, {
+        method: 'PUT',
+        params: data
+    });
+}
+/**模板删除 */
+export async function remove(params: any) {
+    let { templateName, ...data } = params
+    return request(api + `/admin/appComponentConfig/remove/${templateName}`, {
+        method: 'PUT',
+        params: data
+    });
+}
 /**新增修改 */
 export async function appComponentConfigAddOrUpdate(data: any) {
     return request(api + '/admin/appComponentConfig/addOrUpdate', {
@@ -34,3 +48,38 @@ export async function appComponentConfigGetAppPageList(params: Params) {
     });
 }
 
+
+type CompParams = {
+    appId: string | number,//微信小程序本地 id
+    appType: string,//应用类型
+    templateName: string,//模板名称
+    workDirection: number,//作品方向
+}
+/**获取短篇热门小说列表组件信息 */
+export async function getShortBookHotBooks(params: CompParams) {
+    return request(api + '/admin/appComponentConfig/getHotBooks', {
+        method: 'GET',
+        params
+    });
+}
+
+
+
+/**获取短篇首页banners列表组件信息 */
+export async function getShortBookBanners(params: CompParams) {
+    return request(api + '/admin/appComponentConfig/getBanners', {
+        method: 'GET',
+        params
+    });
+}
+
+
+
+/**获取热门分类列表组件信息 */
+export async function getHotCategory(params: CompParams) {
+    return request(api + '/admin/appComponentConfig/getHotCategory', {
+        method: 'GET',
+        params
+    });
+}
+