| | |
| | | endTime: "end time", |
| | | errTime: "err time", |
| | | errDesc: "error", |
| | | batchshelving: "Batch Shelving", |
| | | |
| | | |
| | | }, |
| | | |
| | | mission: { |
| | | backpack: 'Backpack', |
| | | code: 'Code', |
| | |
| | | code: 'Send Code', |
| | | }, |
| | | }, |
| | | |
| | | settings: { |
| | | resetPwd: { |
| | | currPwd: 'Current Password', |
| | |
| | | }, |
| | | }, |
| | | }, |
| | | batch: { |
| | | title: 'Batch Shelving Settings', |
| | | startX: 'Start X (mm)', |
| | | startY: 'Start Y (mm)', |
| | | autoOffset: 'Auto Offset', |
| | | rows: 'Rows', |
| | | cols: 'Columns', |
| | | gapX: 'Row Spacing (mm)', |
| | | gapY: 'Column Spacing (mm)', |
| | | angle: 'Shelf Angle (deg)', |
| | | }, |
| | | devices: { |
| | | title: 'Icons', |
| | | shelf: 'SHELF', |
| | |
| | | monitor: 'Console', |
| | | save: 'Save Map', |
| | | clear: 'Clear Map', |
| | | batchshelving: "Batch Shelving", |
| | | adapt: 'ADAPT', |
| | | rotate: 'ROTATE', |
| | | flip: 'FLIP', |
| | |
| | | endTime: "结束时间", |
| | | duration: "持续时长", |
| | | state: "状态", |
| | | |
| | | }, |
| | | action: { |
| | | uuid: "编号", |
| | |
| | | endTime: "完成时间", |
| | | errTime: "异常时间", |
| | | errDesc: "异常", |
| | | batchshelving: "批量上架", |
| | | }, |
| | | mission: { |
| | | backpack: '背篓', |
| | |
| | | }, |
| | | }, |
| | | }, |
| | | batch: { |
| | | title: '货架阵列设置', |
| | | startX: '起点 X (毫米)', |
| | | startY: '起点 Y (毫米)', |
| | | autoOffset: '自动偏移', |
| | | rows: '行数', |
| | | cols: '列数', |
| | | gapX: '行间距 (毫米)', |
| | | gapY: '列间距 (毫米)', |
| | | angle: '货架角度 (度)', |
| | | }, |
| | | devices: { |
| | | title: '图标库', |
| | | shelf: '货架', |
| | |
| | | monitor: '日志监控', |
| | | save: '保存地图', |
| | | clear: '清空地图', |
| | | batchshelving: "批量上架", |
| | | adapt: '适配', |
| | | rotate: '旋转', |
| | | flip: '翻转', |
| | |
| | | addArea: '添加区域', |
| | | cancelAddArea: '取消添加', |
| | | areaList: '区域列表', |
| | | |
| | | }, |
| | | mode: { |
| | | observer: '观察模式', |
| | |
| | | }, |
| | | }, |
| | | } |
| | | |
| | | }; |
| | | |
| | | export default customChineseMessages; |
| | |
| | | import AreaFab from "./header/AreaFab"; |
| | | import MoreOperate from "./header/MoreOperate"; |
| | | import NewsLogDialog from "./NewsLogDialog"; |
| | | import BatchShelfDialog from './BatchShelfDialog'; |
| | | import { DEVICE_TYPE } from './constants'; // 确认路径 |
| | | |
| | | let player; |
| | | let websocket; |
| | | |
| | | const Map = () => { |
| | | |
| | | const notify = useNotification(); |
| | | const [sidebarOpen] = useSidebarState(); |
| | | const translate = useTranslate(); |
| | | |
| | | |
| | | |
| | | // 调试输出 |
| | | console.log('batchshelving translation:', translate('batchshelving')); |
| | | const theme = useTheme(); |
| | | const themeMode = theme.palette.mode; |
| | | |
| | |
| | | |
| | | const [curSprite, setCurSprite] = useState(null); |
| | | const [batchSprites, setBatchSprites] = useState([]); |
| | | |
| | | const [batchDialogOpen, setBatchDialogOpen] = useState(false); |
| | | const [history, setHistory] = useState([]); |
| | | const [historyIndex, setHistoryIndex] = useState(-1); |
| | | const startBatchPlace = () => { |
| | | setBatchDialogOpen(true); |
| | | }; |
| | | const recordAction = (action) => { |
| | | const newHistory = history.slice(0, historyIndex + 1); |
| | | newHistory.push(action); |
| | | setHistory(newHistory); |
| | | setHistoryIndex(newHistory.length - 1); |
| | | }; |
| | | |
| | | const undo = () => { |
| | | if (historyIndex < 0) return; |
| | | const action = history[historyIndex]; |
| | | if (action.type === 'ADD_SHELVES') { |
| | | action.sprites.forEach(sprite => { |
| | | if (sprite.parent) mapContainer.removeChild(sprite); |
| | | sprite.destroy(); |
| | | }); |
| | | if (batchSprites.some(s => action.sprites.includes(s))) { |
| | | setBatchSprites([]); |
| | | setCurSprite(null); |
| | | } |
| | | } |
| | | setHistoryIndex(historyIndex - 1); |
| | | }; |
| | | const handleBatchConfirm = async ({ startX, startY, rows, cols, gapX, gapY, angle }) => { |
| | | const start = { x: startX, y: startY }; |
| | | const angleRad = angle * Math.PI / 180; |
| | | console.log(`从 (${startX}, ${startY}) 生成 ${rows} 行 ${cols} 列,间距(${gapX},${gapY}),角度${angle}°`); |
| | | |
| | | const existingPositions = new Set(); |
| | | if (mapContainer) { |
| | | mapContainer.children.forEach(child => { |
| | | if (child.data?.type === DEVICE_TYPE.SHELF) { |
| | | const key = `${Math.round(child.x * 10)}_${Math.round(child.y * 10)}`; |
| | | existingPositions.add(key); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | let created = 0; |
| | | const newSprites = []; |
| | | for (let i = 0; i < rows; i++) { |
| | | for (let j = 0; j < cols; j++) { |
| | | const posX = start.x + j * gapX; |
| | | const posY = start.y + i * gapY; |
| | | const key = `${Math.round(posX * 10)}_${Math.round(posY * 10)}`; |
| | | if (existingPositions.has(key)) continue; |
| | | |
| | | const sprite = Tool.generateSprite(DEVICE_TYPE.SHELF); |
| | | if (!sprite) continue; |
| | | Tool.initSprite(sprite, DEVICE_TYPE.SHELF); |
| | | sprite.x = posX; |
| | | sprite.y = posY; |
| | | sprite.rotation = angleRad; |
| | | mapContainer.addChild(sprite); |
| | | Tool.beMovable(sprite); |
| | | created++; |
| | | newSprites.push(sprite); |
| | | } |
| | | } |
| | | |
| | | if (newSprites.length) { |
| | | recordAction({ type: 'ADD_SHELVES', sprites: newSprites }); |
| | | } |
| | | |
| | | notify.success(`成功生成 ${created} 个货架,请记得保存地图`); |
| | | setBatchDialogOpen(false); |
| | | }; |
| | | |
| | | |
| | | const [rcsStatus, setRcsStatus] = useState(null); |
| | | const [showRoutes, setShowRoutes] = useState(false); |
| | |
| | | Http.saveMapData(curZone); |
| | | }} |
| | | /> |
| | | <Button |
| | | variant="contained" |
| | | color="secondary" |
| | | onClick={startBatchPlace} |
| | | sx={{ textTransform: 'none' }} |
| | | > |
| | | {translate('batchshelving',{_: '批量货架'})} |
| | | </Button> |
| | | |
| | | <Button onClick={undo} disabled={historyIndex < 0}> |
| | | {translate('ra.action.undo', { _: '撤销' })} |
| | | </Button> |
| | | </> |
| | | )} |
| | | |
| | |
| | | {/* content */} |
| | | <Box |
| | | sx={{ |
| | | flexGrow: 1, // fill remaining of map space |
| | | flexGrow: 1, // fill remaining of map space |
| | | position: 'relative', |
| | | backgroundColor: '#fff', |
| | | ...(mode === MAP_MODE.SETTINGS_MODE && { |
| | |
| | | open={logDialogOpen} |
| | | onClose={() => setLogDialogOpen(false)} |
| | | /> |
| | | <BatchShelfDialog |
| | | open={batchDialogOpen} |
| | | onClose={() => setBatchDialogOpen(false)} |
| | | onConfirm={handleBatchConfirm} |
| | | mapContainer={mapContainer} |
| | | /> |
| | | </Box> |
| | | ); |
| | | } |
| | | |
| | | const MapPage = () => { |
| | | |
| | | |
| | | return ( |
| | | |
| | | <NotificationProvider> |
| | | <Map /> |
| | | </NotificationProvider> |
| | |
| | | let sprite; |
| | | switch (deviceType) { |
| | | case DEVICE_TYPE.SHELF: |
| | | sprite = new PIXI.Sprite(PIXI.Texture.from(shelf)); |
| | | sprite.scale.set(2.0, 2.0); // 调整合适的大小 |
| | | sprite = new PIXI.Sprite(PIXI.Texture.from(shelf, { resourceOptions: { scale: 1 } })); |
| | | // sprite.width = 50; |
| | | // sprite.height = 50; |
| | | sprite.zIndex = DEVICE_Z_INDEX.SHELF; |
| | | break; |
| | | case DEVICE_TYPE.CHARGE: |
| | |
| | | driver-class-name: com.mysql.jdbc.Driver |
| | | url: jdbc:mysql://localhost:3306/rcs_ctu_stable_hik?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true |
| | | username: root |
| | | password: Mysql20260414 |
| | | password: xltys1995 |
| | | type: com.alibaba.druid.pool.DruidDataSource |
| | | druid: |
| | | initial-size: 5 |