shenwu il y a 5 mois
Parent
commit
93a904c02c

+ 2 - 0
package.json

@@ -52,6 +52,7 @@
   "dependencies": {
     "@ant-design/icons": "^4.8.1",
     "@ant-design/pro-components": "^2.6.48",
+    "@types/react-beautiful-dnd": "^13.1.8",
     "@umijs/route-utils": "^2.2.2",
     "ahooks": "^3.8.1",
     "ali-oss": "^6.21.0",
@@ -65,6 +66,7 @@
     "rc-menu": "^9.12.4",
     "rc-util": "^5.38.1",
     "react": "^18.2.0",
+    "react-beautiful-dnd": "^13.1.1",
     "react-cropper": "^2.3.3",
     "react-dom": "^18.2.0",
     "react-helmet-async": "^1.3.0"

+ 17 - 4
src/pages/MiniApp/CompConfig/DrawerBox/content.tsx

@@ -1,6 +1,6 @@
 import { useDrop } from "ahooks";
 import { Col, Row, Space } from "antd";
-import React, { useState, useImperativeHandle, forwardRef, useRef, useMemo } from "react";
+import React, { useState, useImperativeHandle, forwardRef, useRef, useMemo, useEffect } from "react";
 import styles from './index.less'
 import { Banners } from "../components/banners";
 import { useModel } from "@umijs/max";
@@ -19,6 +19,8 @@ const DragItem = () => {
     const { state, dispatch } = useModel("appPageConifg")
     const [isHovering, setIsHovering] = useState(false);
     const dropRef = useRef(null);
+     // 创建一个 ref 数组,存储每个组件的引用
+     const componentRefs = useRef<any>([]);
     const list = useMemo(() => {
         let pageConfig = state.pageConfigList?.find(page => page.pageUrl === state.activePage)
         let list: {
@@ -37,6 +39,10 @@ const DragItem = () => {
         }
         return list
     }, [state])
+    const handleClick = (item: { componentType: any; }, index: string | number) => {
+        dispatch({ type: "setAll", params: { compAc: item.componentType } });
+        // 滚动到对应元素
+    };
     useDrop(dropRef, {
         // 接收到组件拖拽到手机内容内,添加进入数据
         onDom: (content: string, e) => {
@@ -141,7 +147,7 @@ const DragItem = () => {
                 pageConfig.workDirectionList[0].componentConfigList = [...pageConfig.workDirectionList[0].componentConfigList, newConfig]
             }
             dispatch({
-                type: 'setAll', params: { pageConfigList, index: state.index + 1 }
+                type: 'setAll', params: { pageConfigList, index: state.index + 1 ,compAc: componentType}
             })
         },
         onDragOver: (e) => {
@@ -150,13 +156,20 @@ const DragItem = () => {
         onDragEnter: () => setIsHovering(true),
         onDragLeave: () => setIsHovering(false),
     });
+    useEffect(()=>{
+        let index = list?.findIndex(i=>i.componentType === state.compAc)
+        if(index !== -1){
+            componentRefs.current[index].scrollIntoView({ behavior: 'smooth', block: 'start' });
+        }
+    },[state.compAc,list])
     return <div ref={dropRef} style={{ minHeight: '100%' }} >
         {
-            list?.map(item => {
+            list?.map((item,index) => {
                 return <React.Fragment key={item.appComponentId}>
                     <div
                         className={`${styles.comp}  ${state.compAc === item.componentType ? styles.ac : ""}`}
-                        onClick={() => { dispatch({ type: "setAll", params: { compAc: item.componentType } }) }}
+                        onClick={() => handleClick(item, index)}
+                        ref={el => componentRefs.current[index] = el} // 将每个元素的引用存储在 refs 数组中
                     >
                         {/* banners */}
                         {item.componentType === 'banners' && <Banners data={item.configs || []} />}

+ 33 - 2
src/pages/MiniApp/CompConfig/DrawerBox/index.less

@@ -55,7 +55,6 @@
                 font-size: calc(100vw / 100);
                 color: #000;
                 position: relative;
-
                 &::after {
                     content: "";
                     width: 20px;
@@ -142,6 +141,38 @@
 .miniBox{
     background-color: #fff;
     width: calc(100vw / 15);
-    height: calc(20vw *2);
+    max-height: calc(20vw *2);
     margin-left: calc(100vw / 35);
+    background-color: #f0f0f0;
+    padding:calc(100vw / 150);
+    box-sizing: border-box;
+    overflow-y: auto; // 设置为唯一滚动容器
+    .compAc{
+        color: #14a8ec;
+        background-color: #f7f7f7;
+    }
+}
+
+.draggableItem {
+    user-select: none;
+    padding: 10px;
+    text-align: center;
+    margin-bottom: 8px;
+    background-color: #fff;
+    border-radius: 4px;
+    box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.2);
+    &:hover{
+        color: #2db7f5;
+        background-color: #f7f7f7;
+    }
+}
+.nodraggableItem{
+    background-color: #efefef;
+    cursor: no-drop;
+    user-select: none;
+    padding: 10px;
+    text-align: center;
+    margin-bottom: 8px;
+    border-radius: 4px;
+    box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.2);
 }

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

@@ -55,10 +55,10 @@ const ModalForm = forwardRef((props: Props, ref) => {
                 isWorkDirection: false,
                 compAc: "",
                 index: 0,
-                openEdit:false,
+                openEdit: false,
                 activePage: "",
                 pageConfigList: [],
-                templateName:""
+                templateName: ""
             }
         })
         setTemplateName("")

+ 92 - 2
src/pages/MiniApp/CompConfig/DrawerBox/miniBox.tsx

@@ -1,7 +1,97 @@
 
+import { useMemo, useState } from 'react';
 import styles from './index.less'
-function MiniBox(){
-    return <div className={styles.miniBox}>123</div>
+import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
+import { useModel } from '@umijs/max';
+import { Config } from "@/models/appPageConifg";
+import { Tooltip } from 'antd';
+let noDrag = ["banners", "guess_like"]
+function MiniBox() {
+    const { state, dispatch } = useModel("appPageConifg")
+    const list = useMemo(() => {
+        let pageConfig = state.pageConfigList?.find(page => page.pageUrl === state.activePage)
+        let list: {
+            appComponentId: any;
+            componentType: string;
+            showRightButton?: boolean;
+            componentName?: string;
+            remark?: string;
+            configs?: Config[];
+        }[] = []
+        if (state.isWorkDirection) {
+            let thePage = pageConfig?.workDirectionList?.find(page => page.workDirection == state.tabs)
+            list = thePage?.componentConfigList || []
+        } else {
+            list = pageConfig?.workDirectionList?.[0].componentConfigList || []
+        }
+        return list
+    }, [state])
+    // 处理拖动结束
+    const onDragEnd = (result: any) => {
+        const { destination, source } = result;
+        // 如果没有目标位置或目标位置与起始位置相同,则返回
+        if (!destination || destination.index === source.index || destination.index === 0 || destination.index === list.length - 1) return;
+        // 调整列表顺序
+        const reorderedItems = Array.from(list);
+        const [removed] = reorderedItems.splice(source.index, 1);
+        reorderedItems.splice(destination.index, 0, removed);
+        let { tabs, pageConfigList, activePage, isWorkDirection } = state
+        let pageConfig = pageConfigList?.find(page => page.pageUrl === state.activePage)
+        // 存在男女频页面
+        if (isWorkDirection && pageConfig?.workDirectionList) {
+            for (let page of pageConfig?.workDirectionList) {
+                if (page.workDirection == tabs) {
+                    page.componentConfigList = reorderedItems
+                }
+            }
+        }
+        dispatch({
+            type: 'setAll', params: { pageConfigList, index: state.index + 1 }
+        })
+        console.log(reorderedItems)
+    };
+    return list?.length > 0 && <DragDropContext onDragEnd={onDragEnd}>
+        <Droppable droppableId="droppable">
+            {(provided) => (
+                <Tooltip title={<>
+                    1.拖动下方模块改变页面组件排序<br />
+                    2.点击下方模块可快捷选中组件<br />
+                    3.顶部组件和底部组件不可改变顺便
+                </>}
+
+                    color={"#2db7f5"} open={true}>
+                    <div
+                        {...provided.droppableProps}
+                        ref={provided.innerRef}
+                        className={styles.miniBox}
+                    >
+                        {list?.map((item, index) => (
+                            <Draggable
+                                key={item.appComponentId}
+                                draggableId={String(item.appComponentId)}
+                                index={index}
+                                isDragDisabled={noDrag?.includes(item.componentType)}  // 使用isDragDisabled来控制拖动权限
+                            >
+                                {(provided) => (
+                                    <div
+                                        ref={provided.innerRef}
+                                        {...provided.draggableProps}
+                                        {...provided.dragHandleProps}  // 始终传递dragHandleProps
+                                        className={`${noDrag?.includes(item.componentType) ? styles.nodraggableItem : styles.draggableItem} ${state.compAc === item.componentType ? styles.compAc : ""}`} // 使用 CSS 样式而非内联样式
+                                        onClick={() => { dispatch({ type: "setAll", params: { compAc: item.componentType } }) }}
+                                    >
+                                        {item.componentName || item.componentType}
+                                    </div>
+                                )}
+                            </Draggable>
+                        ))}
+                        {provided.placeholder}
+                    </div>
+                </Tooltip>
+            )}
+        </Droppable>
+    </DragDropContext>
+
 }
 
 export default MiniBox

+ 3 - 0
src/pages/MiniApp/CompConfig/components/index.less

@@ -245,6 +245,9 @@
             display: flex;
             align-items: center;
             justify-content: center;
+            white-space: nowrap;       /* 强制文本在一行显示 */
+            overflow: hidden;          /* 超出部分隐藏 */
+            text-overflow: ellipsis;   /* 显示省略号 */
         }
         .tag_ac {
             background: #E5EBFA;