import React, { useState, useRef, useEffect } from 'react'; 
 | 
import * as THREE from 'three' 
 | 
import { Spin, Descriptions, Button } from 'antd'; 
 | 
import { FormattedMessage, useIntl, useModel } from '@umijs/max'; 
 | 
import { LoadingOutlined } from '@ant-design/icons'; 
 | 
import { createStyles } from 'antd-style'; 
 | 
import * as Utils from '../../utils' 
 | 
import Http from '@/utils/http'; 
 | 
import ShelfThree from './shelfThree' 
 | 
  
 | 
const useStyles = createStyles(({ token, css }) => { 
 | 
    return { 
 | 
        infoBox: { 
 | 
            height: '100%', 
 | 
            display: 'flex', 
 | 
            gap: '0px', 
 | 
        }, 
 | 
        threeInfo: { 
 | 
            height: '100%', 
 | 
            width: '60%', 
 | 
        }, 
 | 
        spinWrapper: { 
 | 
            height: '100%', 
 | 
        }, 
 | 
        threeContainer: { 
 | 
            zIndex: 99, 
 | 
            width: '100%', 
 | 
            height: '100%', 
 | 
        }, 
 | 
        tableInfo: { 
 | 
            height: '100%', 
 | 
            width: '40%', 
 | 
            padding: '0 10px 0 15px', 
 | 
            overflow: 'auto', 
 | 
        }, 
 | 
        tableButton: { 
 | 
            width: '100%', 
 | 
            marginBottom: '10px', 
 | 
            fontWeight: 'bold', 
 | 
            letterSpacing: '1px', 
 | 
        } 
 | 
    } 
 | 
}) 
 | 
  
 | 
let shelfThree; 
 | 
  
 | 
const startThree = (dom) => { 
 | 
    shelfThree = new ShelfThree(dom); 
 | 
    shelfThree.startup(); 
 | 
} 
 | 
  
 | 
const endThree = () => { 
 | 
    if (shelfThree) { 
 | 
        shelfThree.destroy(); 
 | 
        shelfThree = null; 
 | 
    } 
 | 
} 
 | 
  
 | 
const fetchShelfInfo = async (locNo) => { 
 | 
    const res = await Http.doGet('/api/map/shelf/info', { locNo: locNo }); 
 | 
    if (res?.data && shelfThree) { 
 | 
        shelfThree.generateMesh((loader, addObject) => { 
 | 
            const promises = []; 
 | 
            const singleHeight = 123; 
 | 
            for (const item of res.data) { 
 | 
                const { lev } = Utils.parseLocNo(item.locNo); 
 | 
                promises.push(new Promise((resolve) => { 
 | 
                    loader.load('model/04.fbx', (mesh) => { 
 | 
                        mesh.position.set(0, singleHeight * (lev - 1), 0); 
 | 
                        mesh.scale.set(5, 5, 5); 
 | 
                        mesh.name = item.locNo; 
 | 
                        mesh.traverse(function (child) { 
 | 
                            if (child.isMesh) { 
 | 
                                if (child.name === '货架') { 
 | 
                                    child.material.color.set(0x4680BF); 
 | 
                                } 
 | 
                                let palletVisible = true, cargoVisible = true; 
 | 
                                switch (item.locSts) { 
 | 
                                    case 'D': 
 | 
                                        cargoVisible = false; 
 | 
                                        break; 
 | 
                                    case 'O': 
 | 
                                        palletVisible = false; 
 | 
                                        cargoVisible = false; 
 | 
                                        break; 
 | 
                                    default: 
 | 
                                        break; 
 | 
                                } 
 | 
                                if (child.name === '托盘') { 
 | 
                                    child.visible = palletVisible; 
 | 
                                    child.material.color.set(0xBEBEBE); 
 | 
                                } 
 | 
                                if (child.name === '不规则') { 
 | 
                                    child.visible = cargoVisible; 
 | 
                                    child.material.color.set(0xE8B67E); 
 | 
                                } 
 | 
                                child.name = item.locNo 
 | 
                                child.castShadow = true; 
 | 
                                child.receiveShadow = true; 
 | 
                            } 
 | 
                        }); 
 | 
                        addObject(mesh); 
 | 
                        resolve(); 
 | 
                    }) 
 | 
                })); 
 | 
            } 
 | 
  
 | 
            Promise.all(promises).then(() => { 
 | 
                shelfThree.setNewSelectedMesh(locNo); 
 | 
                shelfThree.rePerspective(singleHeight * res.data.length); 
 | 
            }).catch(error => { 
 | 
                console.error(error); 
 | 
            }); 
 | 
        }) 
 | 
    } 
 | 
} 
 | 
  
 | 
const ShelfView = (props) => { 
 | 
    const intl = useIntl(); 
 | 
    const { styles } = useStyles(); 
 | 
    const refContainer = useRef(); 
 | 
  
 | 
    const { data, curFloor, curLocNo, setCurLocNo } = props; 
 | 
    const [loading, setLoading] = React.useState(false); 
 | 
  
 | 
    useEffect(() => { 
 | 
        // init curLocNo 
 | 
        const originLocNo = data.no + '-' + curFloor; 
 | 
        setCurLocNo(originLocNo); 
 | 
  
 | 
        endThree(); 
 | 
        setLoading(true); 
 | 
  
 | 
        setTimeout(() => { 
 | 
            startThree(refContainer.current); 
 | 
            shelfThree.handleClick = (objName) => { 
 | 
                setCurLocNo(objName); 
 | 
            }; 
 | 
            fetchShelfInfo(originLocNo); 
 | 
            setLoading(false); 
 | 
        }, 300) 
 | 
  
 | 
        return endThree; 
 | 
    }, [data]); 
 | 
  
 | 
    return ( 
 | 
        <> 
 | 
            <div className={styles.infoBox}> 
 | 
                <div className={`${styles.threeInfo} three-spin`}> 
 | 
                    <Spin 
 | 
                        spinning={loading} 
 | 
                        indicator={<LoadingOutlined spin />} 
 | 
                        size={'large'} 
 | 
                        wrapperClassName={styles.spinWrapper} 
 | 
                    > 
 | 
                        <div ref={refContainer} className={styles.threeContainer}></div> 
 | 
                    </Spin> 
 | 
                </div> 
 | 
                <div className={styles.tableInfo}> 
 | 
                    <Descriptions 
 | 
                        bordered 
 | 
                        layout="vertical" 
 | 
                        column={1} 
 | 
                        items={ 
 | 
                            [ 
 | 
                                { 
 | 
                                    key: '1', 
 | 
                                    label: intl.formatMessage({ id: 'map.loc.no', defaultMessage: '库位号' }), 
 | 
                                    children: curLocNo, 
 | 
                                }, 
 | 
                                { 
 | 
                                    key: '2', 
 | 
                                    label: intl.formatMessage({ id: 'map.pallet.barcode', defaultMessage: '托盘条码' }), 
 | 
                                    children: '80000010', 
 | 
                                }, 
 | 
                                { 
 | 
                                    key: '3', 
 | 
                                    label: intl.formatMessage({ id: 'map.is.enable', defaultMessage: '是否启用' }), 
 | 
                                    children: 'Disabled', 
 | 
                                }, 
 | 
                                { 
 | 
                                    key: '4', 
 | 
                                    label: intl.formatMessage({ id: 'map.loc.operation', defaultMessage: '库位操作' }), 
 | 
                                    children: ( 
 | 
                                        <> 
 | 
                                            <Button className={styles.tableButton} size='large' type="primary" danger> 
 | 
                                                <FormattedMessage id='map.loc.lock' defaultMessage='锁定' /> 
 | 
                                            </Button> 
 | 
                                            <Button className={styles.tableButton} size='large' disabled> 
 | 
                                                <FormattedMessage id='map.loc.unlock' defaultMessage='解锁' /> 
 | 
                                            </Button> 
 | 
                                            <Button className={styles.tableButton} size='large'> 
 | 
                                                <FormattedMessage id='map.loc.reset' defaultMessage='清除库位' /> 
 | 
                                            </Button> 
 | 
                                        </> 
 | 
                                    ) 
 | 
                                }, 
 | 
                            ] 
 | 
                        } 
 | 
                    /> 
 | 
                </div> 
 | 
            </div> 
 | 
        </> 
 | 
    ) 
 | 
} 
 | 
  
 | 
export default ShelfView; 
 |