| | |
| | | matNew.setMatnr(param.getPackNo()); |
| | | matNew.setMaktx(param.getPackName()); |
| | | matNew.setManuDate(param.getRequestTime()); |
| | | matNew.setDeadWarn(480);//8小时 480分钟 |
| | | matNew.setDeadWarn(360);//6小时 360分钟 |
| | | matNew.setCreateBy(9999L);//9999表示erp下发 |
| | | matNew.setCreateTime(now); |
| | | matNew.setUpdateBy(9999L);//9999表示erp下发 |
| | |
| | | * |
| | | */ |
| | | @Scheduled(cron = "0/3 * * * * ? ") |
| | | private void execute() { |
| | | if (!confirmDeep) return; |
| | | private void execute() |
| | | { |
| | | //if (!confirmDeep) return; |
| | | |
| | | ReturnT<String> result = fireOutHandler.start(); |
| | | if (!result.isSuccess()) { |
| | |
| | | List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>() |
| | | .eq("fire_status", 1) |
| | | .eq("loc_sts", "F")); |
| | | Integer ioType = 101; //入出库类型 |
| | | Integer ioType = 11; //移库 |
| | | Date now = new Date(); |
| | | //优先级99,出库站109:消防箱,101 |
| | | //优先级99,移库到0102501 |
| | | for(LocMast locMast : locMasts){ |
| | | if (Cools.isEmpty(locMast)){ |
| | | continue; |
| | | } |
| | | if (locMast.getPackStatus()==2){//2.测试中 |
| | | continue; |
| | | }else if (locMast.getPackStatus()==3){//3.测试完成 |
| | | continue; |
| | | } |
| | | // 生成工作号 |
| | |
| | | wrkMast.setWrkNo(workNo); |
| | | wrkMast.setIoTime(now); |
| | | wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID |
| | | wrkMast.setIoType(ioType); // 入出库状态 |
| | | wrkMast.setIoPri(99D); // 优先级:99 |
| | | wrkMast.setCrnNo(locMast.getCrnNo()); |
| | | wrkMast.setSourceStaNo(109); // 源站 |
| | | wrkMast.setStaNo(109); // 目标站 |
| | | wrkMast.setIoType(11); // 入出库状态: 11.库格移载 |
| | | wrkMast.setIoPri(99D); |
| | | wrkMast.setCrnNo(1); |
| | | wrkMast.setSourceLocNo(locMast.getLocNo()); // 源库位 |
| | | wrkMast.setLocNo("0102501"); // 目标库位 |
| | | wrkMast.setFullPlt("Y"); // 满板:Y |
| | | wrkMast.setPicking("N"); // 拣料 |
| | | wrkMast.setExitMk("N"); // 退出 |
| | | wrkMast.setEmptyMk("N"); // 空板 |
| | | wrkMast.setBarcode(locMast.getBarcode()); // 托盘码 |
| | | wrkMast.setLinkMis("N"); |
| | | wrkMast.setBarcode(locMast.getBarcode()); |
| | | wrkMast.setAppeUser(9999L); |
| | | wrkMast.setAppeTime(now); |
| | | wrkMast.setModiUser(9999L); |
| | | wrkMast.setModiTime(now); |
| | | if (!wrkMastService.insert(wrkMast)) { |
| | | throw new CoolException("保存工作档失败,出库库位号:"+locMast.getLocNo()); |
| | |
| | | targetLocNo=locMastService.queryFreeLocMast(1,(short)4); |
| | | } |
| | | if (targetLocNo != null){ |
| | | workService.locMove(locMast.getLocNo(),targetLocNo.getLocNo(),(long)Integer.parseInt(testMast.getUserId())); |
| | | workService.locMove(locMast.getLocNo(),targetLocNo.getLocNo(),(long)Integer.parseInt("9935")); |
| | | //4.测试完成上报 |
| | | CombParam combParam = new CombParam(); |
| | | combParam.setPackNo(locDetl.getMatnr()); |
| | |
| | | targetLocNo=locMastService.queryFreeLocMast(1,(short)2); |
| | | } |
| | | if (targetLocNo != null){ |
| | | workService.locMove(locMast.getLocNo(),targetLocNo.getLocNo(),(long)Integer.parseInt(testMast.getUserId())); |
| | | workService.locMove(locMast.getLocNo(),targetLocNo.getLocNo(),(long)9935); |
| | | sign=true; |
| | | }else { |
| | | log.error("测试完成自动移库--->没有空库位!"); |
| | |
| | | sourceLoc.setLocSts("O"); |
| | | sourceLoc.setModiTime(now); |
| | | sourceLoc.setIoTime(now); |
| | | sourceLoc.setFireStatus(0); |
| | | sourceLoc.setPackStatus(0); |
| | | if (!locMastService.updateById(sourceLoc)) { |
| | | // exceptionHandle("库位移转 ===>> 修改源库位状态失败;[workNo={0}],[sourceLoc={1}]", wrkMast.getWrkNo(), wrkMast.getSourceLocNo()); |
| | |
| | | locMast.setBarcode(wrkMast.getBarcode()); |
| | | locMast.setIoTime(now); |
| | | locMast.setModiTime(now); |
| | | locMast.setFireStatus(0); |
| | | LocDetl locDetl = locDetlService.selectOne(new EntityWrapper<LocDetl>().eq("loc_no", locMast.getLocNo())); |
| | | |
| | | |
| | | boolean sign =false; |
| | | if (locMast.getLocType1().equals(sourceLoc.getLocType1())){ |
| | | locMast.setPackStatus(packStatus); |
| | | |
| | | //待测库位转测试库位 |
| | | }else if (locMast.getLocType1().equals((short)1) && sourceLoc.getLocType1().equals((short)3)){ |
| | | locMast.setPackStatus(1); |
| | | TestMast testMast = testMastService.selectOne(new EntityWrapper<TestMast>() |
| | | .eq("loc_no",sourceLoc.getLocNo()) |
| | | .eq("user_id",locMast.getBarcode()) |
| | | .eq("barcode",locDetl.getMatnr()) |
| | | ); |
| | | if(!Cools.isEmpty(testMast)){ |
| | | testMast.setChannel(locMast.getChannel()); |
| | | testMast.setLocNo(wrkMast.getLocNo()); |
| | | testMast.setModiTime(new Date()); |
| | | if (!testMastService.update(testMast,new EntityWrapper<TestMast>() |
| | | .eq("loc_no",sourceLoc.getLocNo()) |
| | | .eq("user_id",locMast.getBarcode()) |
| | | .eq("barcode",locDetl.getMatnr()))){ |
| | | throw new CoolException("更改测试状态失败"); |
| | | } |
| | | }else { |
| | | throw new CoolException("待测库位无物"); |
| | | } |
| | | |
| | | }else { |
| | | //测试库位转静置库位 |
| | | if (locMast.getLocType1().equals((short)4)){ |
| | | locMast.setPackStatus(4); //4:NG |
| | | }else { |
| | | locMast.setPackStatus(5); //5:静置中 |
| | | } |
| | | sign=true; |
| | | if (locMast.getLocType1()==1 && sourceLoc.getLocType1()==2){ |
| | | if (locMast.getLocType1()==2 && sourceLoc.getLocType1()==1){ |
| | | TestMast testMast = testMastService.selectOne(new EntityWrapper<TestMast>() |
| | | .eq("loc_no",sourceLoc.getLocNo()) |
| | | .eq("barcode",locMast.getBarcode()) |
| | | .eq("barcode",locDetl.getMatnr()) |
| | | .eq("status",4) |
| | | ); |
| | | testMast.setStatus(5); |
| | | testMast.setModiTime(new Date()); |
| | | if (!testMastService.update(testMast,new EntityWrapper<TestMast>().eq("loc_no",sourceLoc.getLocNo()).eq("barcode",locMast.getBarcode()).eq("status",4))){ |
| | | if (!testMastService.update(testMast,new EntityWrapper<TestMast>() |
| | | .eq("loc_no",sourceLoc.getLocNo()) |
| | | .eq("barcode",locDetl.getMatnr()) |
| | | .eq("status",4))){ |
| | | throw new CoolException("更改测试状态失败"); |
| | | } |
| | | } |
| | |
| | | locMast.setBarcode(""); |
| | | locMast.setModiTime(now); |
| | | locMast.setIoTime(now); |
| | | locMast.setFireStatus(0); |
| | | locMast.setPackStatus(0); |
| | | if (!locMastService.updateById(locMast)) { |
| | | // exceptionHandle("全板出库 ===>> 修改源库位状态失败;[workNo={0}],[sourceLocNo={1}]", wrkMast.getWrkNo(), wrkMast.getSourceLocNo()); |
| | |
| | | locMast.setBarcode(""); |
| | | locMast.setModiTime(now); |
| | | locMast.setIoTime(now); |
| | | locMast.setFireStatus(0); |
| | | locMast.setPackStatus(0); |
| | | if (!locMastService.updateById(locMast)) { |
| | | // exceptionHandle("空板出库 ===>> 修改源库位状态失败;[workNo={0}],[sourceLocNo={1}]", wrkMast.getWrkNo(), wrkMast.getSourceLocNo()); |
| | |
| | | response, |
| | | success |
| | | ); |
| | | } catch (Exception e) { log.error("", e); } |
| | | } catch (Exception e) { |
| | | log.error("", e); } |
| | | } |
| | | } |
| | | return SUCCESS; |
| | |
| | | rowLastnoService.updateById(rowLastno); |
| | | |
| | | if (crnNo==1){ |
| | | LocMast locMast1 = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_sts", "F").eq("loc_type2", (short) 3)); |
| | | if (!Cools.isEmpty(locMast1)){ |
| | | LocMast locMast1 = locMastService.selectOne(new EntityWrapper<LocMast>() |
| | | .eq("loc_sts", "F") |
| | | .eq("loc_type1", (short) 3)); |
| | | LocMast locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>() |
| | | .eq("loc_sts", "O") |
| | | .eq("loc_type1", (short) 1)); |
| | | if (!Cools.isEmpty(locMast1)||Cools.isEmpty(locMast2)){ |
| | | locMast = locMastService.queryFreeLocMast(2,(short)3); |
| | | if (Cools.isEmpty(locMast)){ |
| | | locMast = locMastService.queryFreeLocMast(1,(short)3); |
| | |
| | | .eq("user_id",param.getBarcode())//查托盘码 |
| | | .eq("status",4)); //完成测试 |
| | | logs=false; |
| | | }else{ |
| | | LocDetl locDetl=locDetlService.selectOne(new EntityWrapper<LocDetl>() |
| | | .eq("matnr",param.getPackNo()) |
| | | .or() |
| | | .eq("zpallet",param.getBarcode())); |
| | | if(!Cools.isEmpty(locDetl)){ |
| | | return R.error("PACK码在库!!!!"); |
| | | } |
| | | |
| | | } |
| | | Date now = new Date(); |
| | | if (true){ |
| | |
| | | LocMast locMast = locMastService.selectById(dto.getLocNo()); |
| | | |
| | | // 生成工作档明细 |
| | | waitPakins.forEach(waitPakin -> { |
| | | for (WaitPakin waitPakin: waitPakins) { |
| | | WrkDetl wrkDetl = new WrkDetl(); |
| | | wrkDetl.sync(waitPakin); |
| | | wrkDetl.setWrkNo(wrkMast.getWrkNo()); |
| | |
| | | if (!wrkDetlService.insert(wrkDetl)) { |
| | | throw new CoolException("保存工作明细失败"); |
| | | } |
| | | TestMast testMast = testMastService.selectOne(new EntityWrapper<TestMast>() |
| | | .eq("barcode", wrkDetl.getMatnr()));//pack码 |
| | | if (Cools.isEmpty(testMast)){ |
| | | //生成测试档 |
| | | testMast=new TestMast(); |
| | | testMast.setChannel(locMast.getChannel()); |
| | | testMast.setUserId(wrkMast.getBarcode());//托盘码 |
| | | testMast.setStatus(1); |
| | | testMast.setBarcode(wrkDetl.getMatnr()); |
| | | testMast.setLocNo(locMast.getLocNo()); |
| | | testMast.setModiTime(now); |
| | | testMast.setAppeTime(now); |
| | | if (!testMastService.insert(testMast)){ |
| | | throw new CoolException(wrkDetl.getMatnr()+"生成测试档失败"); |
| | | |
| | | TestMast testMast = testMastService.selectOne(new EntityWrapper<TestMast>() |
| | | .eq("barcode", wrkDetl.getMatnr()));//pack码 |
| | | if (Cools.isEmpty(testMast)){ |
| | | //生成测试档 |
| | | testMast=new TestMast(); |
| | | //入待测库位通道设为0 |
| | | if(locMast.getChannel()==null) { |
| | | testMast.setChannel(0);//通道设为0 |
| | | }else{ |
| | | testMast.setChannel(locMast.getChannel()); |
| | | } |
| | | testMast.setUserId(wrkMast.getBarcode());//托盘码 |
| | | testMast.setStatus(1); |
| | | testMast.setBarcode(wrkDetl.getMatnr()); |
| | | testMast.setLocNo(locMast.getLocNo()); |
| | | testMast.setModiTime(now); |
| | | testMast.setAppeTime(now); |
| | | if (!testMastService.insert(testMast)){ |
| | | throw new CoolException(wrkDetl.getMatnr()+"生成测试档失败"); |
| | | } |
| | | }else if(wrkMast.getStaNo()==209){ |
| | | testMast.setBarcode(wrkDetl.getMatnr()); |
| | | testMast.setChannel(locMast.getChannel()); |
| | | testMast.setLocNo(locMast.getLocNo()); |
| | | testMast.setUserId(wrkMast.getBarcode());//托盘码 |
| | | testMast.setAppeTime(now); |
| | | if(!testMastService.update(testMast,new EntityWrapper<TestMast>().eq("barcode", wrkDetl.getMatnr()))){ |
| | | throw new CoolException(wrkDetl.getMatnr()+"更新测试档失败"); |
| | | } |
| | | }else { |
| | | testMast.setBarcode(wrkDetl.getMatnr()); |
| | | testMast.setChannel(locMast.getChannel()); |
| | | testMast.setLocNo(locMast.getLocNo()); |
| | | testMast.setStatus(1); |
| | | testMast.setUserId(wrkMast.getBarcode());//托盘码 |
| | | testMast.setAppeTime(now); |
| | | if(!testMastService.update(testMast,new EntityWrapper<TestMast>().eq("barcode", wrkDetl.getMatnr()))){ |
| | | throw new CoolException(wrkDetl.getMatnr()+"更新测试档失败"); |
| | | } |
| | | } |
| | | }else { |
| | | testMast.setBarcode(wrkDetl.getMatnr()); |
| | | testMast.setChannel(locMast.getChannel()); |
| | | testMast.setLocNo(locMast.getLocNo()); |
| | | testMast.setAppeTime(now); |
| | | if(!testMastService.update(testMast,new EntityWrapper<TestMast>().eq("barcode", wrkDetl.getMatnr()))){ |
| | | throw new CoolException(wrkDetl.getMatnr()+"更新测试档失败"); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | |
| | | } |
| | | // 更新入库通知档 ioStatus ===>> Y |
| | | Wrapper<WaitPakin> wrapper = new EntityWrapper<WaitPakin>() |
| | | .eq("zpallet", barcode); |
| | |
| | | if (!locMastService.updateById(locMast)){ |
| | | throw new CoolException("改变库位状态失败"); |
| | | }else{ |
| | | if (locMast.getRow1()<3){ |
| | | //1.扫码上报 |
| | | CombParam combParam = new CombParam(); |
| | | combParam.setPackNo(wrkMast.getBarcode()); |
| | | combParam.setLocNo(wrkMast.getLocNo()); |
| | | combParam.setPackSts(0); |
| | | combParam.setStepSts(1); |
| | | combParam.setRequestTime(DateUtils.convert(now)); |
| | | new PostMesDataUtils().postMesData("MES系统",mesUrl,inpath,combParam); |
| | | } |
| | | // if (locMast.getRow1()<3){ |
| | | // //1.扫码上报 |
| | | // CombParam combParam = new CombParam(); |
| | | // combParam.setPackNo(wrkMast.getBarcode()); |
| | | // combParam.setLocNo(wrkMast.getLocNo()); |
| | | // combParam.setPackSts(0); |
| | | // combParam.setStepSts(1); |
| | | // combParam.setRequestTime(DateUtils.convert(now)); |
| | | // new PostMesDataUtils().postMesData("MES系统",mesUrl,inpath,combParam); |
| | | // } |
| | | } |
| | | } else { |
| | | throw new CoolException(dto.getLocNo()+"目标库位已被占用"); |
| | |
| | | } |
| | | |
| | | var matCols = [ |
| | | {field: 'matnr', align: 'center',title: '商品编号', width: 180} |
| | | {field: 'matnr', align: 'center',title: 'PACK码', width: 180} |
| | | // {field: 'id', align: 'center',title: 'ID'} |
| | | // ,{field: 'uuid', align: 'center',title: '编号'} |
| | | // ,{field: 'tagId$', align: 'center',title: '所属归类'} |
| | |
| | | ] |
| | | |
| | | var detlCols = [ |
| | | {field: 'matnr', align: 'center',title: '商品编号', sort:true} |
| | | {field: 'matnr', align: 'center',title: 'PACK码', sort:true} |
| | | ,{field: 'maktx', align: 'center',title: '商品名称', sort:true} |
| | | ,{field: 'orderNo', align: 'center',title: '单据编号', hide: true} |
| | | ,{field: 'batch', align: 'center',title: '批号', sort:true} |
| | | ,{field: 'anfme', align: 'center',title: '数量'} |
| | | ,{field: 'zpallet', align: 'center',title: 'PACK码'} |
| | | ,{field: 'zpallet', align: 'center',title: '托盘码'} |
| | | |
| | | ,{field: 'specs', align: 'center',title: '配置', hide: false} |
| | | ,{field: 'model', align: 'center',title: '代码', hide: true} |
| | |
| | | function getCol() { |
| | | var cols = [ |
| | | {field: 'locNo$', align: 'center',title: '库位号'}, |
| | | {field: 'matnr', align: 'center',title: '商品编号', sort:true} |
| | | {field: 'matnr', align: 'center',title: 'PACK码', sort:true} |
| | | ,{field: 'maktx', align: 'center',title: '商品名称', sort:true} |
| | | ,{field: 'orderNo', align: 'center',title: '单据编号', hide: false} |
| | | ,{field: 'batch', align: 'center',title: '批号', width: 300, sort:true} |
| | | ,{field: 'anfme', align: 'center',title: '数量'} |
| | | ,{field: 'zpallet', align: 'center',title: 'pack码'} |
| | | ,{field: 'zpallet', align: 'center',title: '托盘码'} |
| | | ,{field: 'specs', align: 'center',title: '配置'} |
| | | ,{field: 'model', align: 'center',title: '代码', hide: true} |
| | | ,{field: 'color', align: 'center',title: '颜色', hide: true} |
| | |
| | | // html += "disabled='disabled' >"; |
| | | // return html; |
| | | // },width:80} |
| | | ,{field: 'barcode', align: 'center',title: 'PACK码'} |
| | | ,{field: 'barcode', align: 'center',title: '托盘码'} |
| | | ,{field: 'modiUser$', align: 'center',title: '修改人员'} |
| | | ,{field: 'modiTime$', align: 'center',title: '修改时间', width: 180} |
| | | ,{ fixed: 'right', title:'操作', align: 'center', toolbar: '#operate'} |
| | |
| | | ,{field: 'channel', align: 'center',title: '通道'} |
| | | ,{field: 'locNo', align: 'center',title: '库位号'} |
| | | ,{field: 'barcode', align: 'center',title: 'PACK码'} |
| | | ,{field: 'userId', align: 'center',title: '用户码'} |
| | | ,{field: 'userId', align: 'center',title: '托盘码'} |
| | | ,{field: 'status$', align: 'center',title: '状态'} |
| | | ,{field: 'modiTime$', align: 'center',title: '修改时间'} |
| | | ,{field: 'appeTime$', align: 'center',title: '添加时间'} |
| | |
| | | ,{field: 'staNo$', align: 'center',title: '目标站'} |
| | | ,{field: 'sourceLocNo$', align: 'center',title: '源库位'} |
| | | ,{field: 'locNo$', align: 'center',title: '目标库位'} |
| | | ,{field: 'barcode', align: 'center',title: 'pack码'} |
| | | ,{field: 'barcode', align: 'center',title: '托盘码'} |
| | | ,{field: 'preHave', align: 'center',title: '先入品', hide: true} |
| | | ,{field: 'takeNone', align: 'center',title: '空操作', hide: true} |
| | | // ,{field: 'picking', align: 'center',title: '拣料', templet:function(row){ |
| | |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="zpallet" placeholder="PACK码" autocomplete="off"> |
| | | <input class="layui-input" type="text" name="zpallet" placeholder="托盘码" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="matnr" placeholder="商品编号" autocomplete="off"> |
| | | <input class="layui-input" type="text" name="matnr" placeholder="Pack码" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <!-- <div class="layui-inline">--> |
| | |
| | | <!-- 表格工具栏2 --> |
| | | <div id="search-box" class="layui-form toolbar" style="padding-top: 5px"> |
| | | <div class="layui-inline"> |
| | | <label class="layui-form-label" style="padding: 8px 15px 8px 15px">商品编号:</label> |
| | | <label class="layui-form-label" style="padding: 8px 15px 8px 15px">PACK码:</label> |
| | | <div class="layui-input-inline"> |
| | | <input name="matnr" class="layui-input" placeholder="输入商品编号"/> |
| | | <input name="matnr" class="layui-input" placeholder="请输入PACK码"/> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | |
| | | |
| | | <div class="layui-col-md6"> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">商品编号</label> |
| | | <label class="layui-form-label layui-form-required">PACK码</label> |
| | | <div class="layui-input-block"> |
| | | <input id="matnr" name="matnr" placeholder="请输入商品编号" class="layui-input" lay-vertype="tips" lay-verify="required" required=""> |
| | | <input id="matnr" name="matnr" placeholder="PACK码" class="layui-input" lay-vertype="tips" lay-verify="required" required=""> |
| | | </div> |
| | | </div> |
| | | |
| | |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="barcode" placeholder="pack码" autocomplete="off"> |
| | | <input class="layui-input" type="text" name="barcode" placeholder="托盘码" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <!-- 日期范围 --> |
| | |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">用户码: </label> |
| | | <label class="layui-form-label">托盘码: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="userId" placeholder="用户码"> |
| | | <input class="layui-input" name="userId" placeholder="托盘码"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | |
| | | <option value="3">测试中</option> |
| | | <option value="4">完成</option> |
| | | <option value="5">已移库</option> |
| | | <option value="6">火警</option> |
| | | </select> |
| | | </div> |
| | | </div> |
| | |
| | | <div id="search-box" class="layui-form layui-card-header"> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="zpallet" placeholder="PACK码" autocomplete="off"> |
| | | <input class="layui-input" type="text" name="zpallet" placeholder="托盘码" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="matnr" placeholder="产品型号" autocomplete="off"> |
| | | <input class="layui-input" type="text" name="matnr" placeholder="Pack码" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <!-- 日期范围 --> |