| New file |
| | |
| | | -- save area record |
| | | -- mysql |
| | | insert into `sys_resource` ( `code`, `name`, `resource_id`, `level`, `sort`, `status`) values ( 'area/area.html', 'area管理', null , '2', null , '1'); |
| | | |
| | | insert into `sys_resource` ( `code`, `name`, `resource_id`, `level`, `sort`, `status`) values ( 'area#view', '查询', '', '3', '0', '1'); |
| | | insert into `sys_resource` ( `code`, `name`, `resource_id`, `level`, `sort`, `status`) values ( 'area#btn-add', '新增', '', '3', '1', '1'); |
| | | insert into `sys_resource` ( `code`, `name`, `resource_id`, `level`, `sort`, `status`) values ( 'area#btn-edit', '编辑', '', '3', '2', '1'); |
| | | insert into `sys_resource` ( `code`, `name`, `resource_id`, `level`, `sort`, `status`) values ( 'area#btn-delete', '删除', '', '3', '3', '1'); |
| | | insert into `sys_resource` ( `code`, `name`, `resource_id`, `level`, `sort`, `status`) values ( 'area#btn-export', '导出', '', '3', '4', '1'); |
| | | |
| | | -- sqlserver |
| | | insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'area/area.html', N'area管理', null, '2', null, '1'); |
| | | |
| | | insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'area#view', N'查询', '', '3', '0', '1'); |
| | | insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'area#btn-add', N'新增', '', '3', '1', '1'); |
| | | insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'area#btn-edit', N'编辑', '', '3', '2', '1'); |
| | | insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'area#btn-delete', N'删除', '', '3', '3', '1'); |
| | | insert [dbo].[sys_resource] ( [code], [name], [resource_id], [level], [sort], [status]) values ( N'area#btn-export', N'导出', '', '3', '4', '1'); |
| New file |
| | |
| | | package com.zy.asrs.controller; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.baomidou.mybatisplus.mapper.Wrapper; |
| | | import com.baomidou.mybatisplus.plugins.Page; |
| | | import com.core.common.DateUtils; |
| | | import com.zy.asrs.entity.Area; |
| | | import com.zy.asrs.service.AreaService; |
| | | import com.core.annotations.ManagerAuth; |
| | | import com.core.common.BaseRes; |
| | | import com.core.common.Cools; |
| | | import com.core.common.R; |
| | | import com.zy.common.web.BaseController; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.*; |
| | | |
| | | @RestController |
| | | public class AreaController extends BaseController { |
| | | |
| | | @Autowired |
| | | private AreaService areaService; |
| | | |
| | | @RequestMapping(value = "/area/{id}/auth") |
| | | @ManagerAuth |
| | | public R get(@PathVariable("id") String id) { |
| | | return R.ok(areaService.selectById(String.valueOf(id))); |
| | | } |
| | | |
| | | @RequestMapping(value = "/area/list/auth") |
| | | @ManagerAuth |
| | | public R list(@RequestParam(defaultValue = "1")Integer curr, |
| | | @RequestParam(defaultValue = "10")Integer limit, |
| | | @RequestParam(required = false)String orderByField, |
| | | @RequestParam(required = false)String orderByType, |
| | | @RequestParam(required = false)String condition, |
| | | @RequestParam Map<String, Object> param){ |
| | | EntityWrapper<Area> wrapper = new EntityWrapper<>(); |
| | | excludeTrash(param); |
| | | param.remove("page"); |
| | | param.remove("limit"); |
| | | param.remove("curr"); |
| | | convert(param, wrapper); |
| | | allLike(Area.class, param.keySet(), wrapper, condition); |
| | | if (!Cools.isEmpty(orderByField)){wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));} |
| | | return R.ok(areaService.selectPage(new Page<>(curr, limit), wrapper)); |
| | | } |
| | | |
| | | private <T> void convert(Map<String, Object> map, EntityWrapper<T> wrapper){ |
| | | for (Map.Entry<String, Object> entry : map.entrySet()){ |
| | | String val = String.valueOf(entry.getValue()); |
| | | if (val.contains(RANGE_TIME_LINK)){ |
| | | String[] dates = val.split(RANGE_TIME_LINK); |
| | | wrapper.ge(entry.getKey(), DateUtils.convert(dates[0])); |
| | | wrapper.le(entry.getKey(), DateUtils.convert(dates[1])); |
| | | } else { |
| | | wrapper.like(entry.getKey(), val); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @RequestMapping(value = "/area/add/auth") |
| | | @ManagerAuth |
| | | public R add(Area area) { |
| | | areaService.insert(area); |
| | | return R.ok(); |
| | | } |
| | | |
| | | @RequestMapping(value = "/area/update/auth") |
| | | @ManagerAuth |
| | | public R update(Area area){ |
| | | if (Cools.isEmpty(area) || null==area.getId()){ |
| | | return R.error(); |
| | | } |
| | | areaService.updateById(area); |
| | | return R.ok(); |
| | | } |
| | | |
| | | @RequestMapping(value = "/area/delete/auth") |
| | | @ManagerAuth |
| | | public R delete(@RequestParam(value="ids[]") Long[] ids){ |
| | | for (Long id : ids){ |
| | | areaService.deleteById(id); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | @RequestMapping(value = "/area/export/auth") |
| | | @ManagerAuth |
| | | public R export(@RequestBody JSONObject param){ |
| | | EntityWrapper<Area> wrapper = new EntityWrapper<>(); |
| | | List<String> fields = JSONObject.parseArray(param.getJSONArray("fields").toJSONString(), String.class); |
| | | Map<String, Object> map = excludeTrash(param.getJSONObject("area")); |
| | | convert(map, wrapper); |
| | | List<Area> list = areaService.selectList(wrapper); |
| | | return R.ok(exportSupport(list, fields)); |
| | | } |
| | | |
| | | @RequestMapping(value = "/areaQuery/auth") |
| | | @ManagerAuth |
| | | public R query(String condition) { |
| | | EntityWrapper<Area> wrapper = new EntityWrapper<>(); |
| | | wrapper.like("id", condition); |
| | | Page<Area> page = areaService.selectPage(new Page<>(0, 10), wrapper); |
| | | List<Map<String, Object>> result = new ArrayList<>(); |
| | | for (Area area : page.getRecords()){ |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("id", area.getId()); |
| | | map.put("value", area.getId()); |
| | | result.add(map); |
| | | } |
| | | return R.ok(result); |
| | | } |
| | | |
| | | @RequestMapping(value = "/area/check/column/auth") |
| | | @ManagerAuth |
| | | public R query(@RequestBody JSONObject param) { |
| | | Wrapper<Area> wrapper = new EntityWrapper<Area>().eq(humpToLine(String.valueOf(param.get("key"))), param.get("val")); |
| | | if (null != areaService.selectOne(wrapper)){ |
| | | return R.parse(BaseRes.REPEAT).add(getComment(Area.class, String.valueOf(param.get("key")))); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | } |
| | |
| | | return R.ok(); |
| | | } |
| | | |
| | | @PostMapping(value = "/locMast/batchUpdateArea/auth") |
| | | @ManagerAuth |
| | | public R batchUpdateArea(@RequestBody JSONObject param) { |
| | | List<String> locNos = param.getJSONArray("locNos").toJavaList(String.class); |
| | | Integer areaId = param.getInteger("areaId"); |
| | | if (Cools.isEmpty(locNos) || areaId == null) { |
| | | return R.error("参数错误"); |
| | | } |
| | | locMastService.batchUpdateArea(locNos, areaId.shortValue()); |
| | | return R.ok(); |
| | | } |
| | | |
| | | @RequestMapping(value = "/locMast/init/auth") |
| | | @ManagerAuth(memo = "初始化库位") |
| | | // @Transactional |
| New file |
| | |
| | | package com.zy.asrs.entity; |
| | | |
| | | import com.baomidou.mybatisplus.annotations.TableId; |
| | | import com.baomidou.mybatisplus.enums.IdType; |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.core.common.Cools;import com.baomidou.mybatisplus.annotations.TableField; |
| | | |
| | | import com.core.common.SpringUtils; |
| | | import com.zy.asrs.service.AreaService; |
| | | import com.zy.asrs.service.TagService; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import com.baomidou.mybatisplus.annotations.TableName; |
| | | import java.io.Serializable; |
| | | |
| | | @Data |
| | | @TableName("man_area") |
| | | public class Area implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * ID |
| | | */ |
| | | @ApiModelProperty(value= "ID") |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value= "") |
| | | @TableField("tag_id") |
| | | private Long tagId; |
| | | |
| | | /** |
| | | * 库区id |
| | | */ |
| | | @ApiModelProperty(value= "库区id") |
| | | @TableField("area_id") |
| | | private String areaId; |
| | | |
| | | /** |
| | | * 库区名称 |
| | | */ |
| | | @ApiModelProperty(value= "库区名称") |
| | | @TableField("area_name") |
| | | private String areaName; |
| | | |
| | | /** |
| | | * 库区备注 |
| | | */ |
| | | @ApiModelProperty(value= "库区备注") |
| | | private String memo; |
| | | |
| | | /** |
| | | * 备用字段 |
| | | */ |
| | | @ApiModelProperty(value= "备用字段") |
| | | private String backup1; |
| | | |
| | | /** |
| | | * 备用字段2 |
| | | */ |
| | | @ApiModelProperty(value= "备用字段2") |
| | | private String backup2; |
| | | |
| | | /** |
| | | * 备用字段3 |
| | | */ |
| | | @ApiModelProperty(value= "备用字段3") |
| | | private String backup3; |
| | | |
| | | public Area() {} |
| | | |
| | | public Area(Long id,Long tagId,String areaId,String areaName,String memo,String backup1,String backup2,String backup3) { |
| | | this.id = id; |
| | | this.tagId = tagId; |
| | | this.areaId = areaId; |
| | | this.areaName = areaName; |
| | | this.memo = memo; |
| | | this.backup1 = backup1; |
| | | this.backup2 = backup2; |
| | | this.backup3 = backup3; |
| | | } |
| | | public String getAreaId$(){ |
| | | AreaService service = SpringUtils.getBean(AreaService.class); |
| | | Area area = service.selectOne(new EntityWrapper<Area>().eq("area_id",areaId)); |
| | | if (!Cools.isEmpty(area)){ |
| | | return String.valueOf(area.getAreaName()); |
| | | } |
| | | return null; |
| | | } |
| | | // Area area = new Area( |
| | | // null, // ID[非空] |
| | | // null, // [非空] |
| | | // null, // 库区id[非空] |
| | | // null, // 库区名称 |
| | | // null, // 库区备注 |
| | | // null, // 备用字段 |
| | | // null, // 备用字段2 |
| | | // null // 备用字段3 |
| | | // ); |
| | | |
| | | |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.annotations.TableId; |
| | | import com.baomidou.mybatisplus.annotations.TableName; |
| | | import com.baomidou.mybatisplus.enums.IdType; |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.core.common.Cools; |
| | | import com.core.common.SpringUtils; |
| | | import com.zy.asrs.service.AreaService; |
| | | import com.zy.asrs.service.TagService; |
| | | import com.zy.common.utils.Synchro; |
| | | import com.zy.system.entity.User; |
| | |
| | | @TableField("store_max_date") |
| | | private Integer storeMaxDate; |
| | | |
| | | /** |
| | | * 库区id |
| | | */ |
| | | @ApiModelProperty(value= "库区id") |
| | | @TableField("area_id") |
| | | private String areaId; |
| | | |
| | | public Mat() {} |
| | | |
| | | public Mat(String uuid,Long tagId,String matnr,String maktx,String name,String specs,String model,String color,String brand,String unit,Double price,String sku,Double units,String barcode,String origin,String manu,String manuDate,String itemNum,Double safeQty,Double weight,Double length,Double volume,String threeCode,String supp,String suppCode,Integer beBatch,String deadTime,Integer deadWarn,Integer source,Integer inspect,Integer danger,Integer status,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) { |
| | | public Mat(String uuid,Long tagId,String matnr,String maktx,String name,String specs,String model,String color,String brand,String unit,Double price,String sku,Double units,String barcode,String origin,String manu,String manuDate,String itemNum,Double safeQty,Double weight,Double length,Double volume,String threeCode,String supp,String suppCode,Integer beBatch,String deadTime,Integer deadWarn,Integer source,Integer inspect,Integer danger,Integer status,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo,String areaId) { |
| | | this.uuid = uuid; |
| | | this.tagId = tagId; |
| | | this.matnr = matnr; |
| | |
| | | this.updateBy = updateBy; |
| | | this.updateTime = updateTime; |
| | | this.memo = memo; |
| | | this.areaId = areaId; |
| | | } |
| | | |
| | | // Mat mat = new Mat( |
| | |
| | | return null; |
| | | } |
| | | |
| | | public String getAreaId$(){ |
| | | if (Cools.isEmpty(this.areaId)){ |
| | | return null; |
| | | } |
| | | AreaService service = SpringUtils.getBean(AreaService.class); |
| | | Area area = service.selectOne(new EntityWrapper<Area>().eq("area_id", this.areaId)); |
| | | if (!Cools.isEmpty(area)){ |
| | | return String.valueOf(area.getAreaName()); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public String getBeBatch$(){ |
| | | if (null == this.beBatch){ return null; } |
| | | switch (this.beBatch){ |
| | |
| | | private String color = "#666"; |
| | | private Integer row1; |
| | | private Integer lev1; |
| | | private Short locType2; |
| | | |
| | | public ViewLocMapDto() { |
| | | } |
| | |
| | | this.locNo = locNo; |
| | | this.bay1 = bay1; |
| | | this.locSts = locSts; |
| | | } |
| | | |
| | | public Short getLocType2() { |
| | | return locType2; |
| | | } |
| | | |
| | | public void setLocType2(Short locType2) { |
| | | this.locType2 = locType2; |
| | | } |
| | | |
| | | public String getLocNo() { |
| | |
| | | public void setColor(String color) { |
| | | this.color = color; |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | package com.zy.asrs.mapper; |
| | | |
| | | import com.zy.asrs.entity.Area; |
| | | import com.baomidou.mybatisplus.mapper.BaseMapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | @Mapper |
| | | @Repository |
| | | public interface AreaMapper extends BaseMapper<Area> { |
| | | |
| | | } |
| | |
| | | @Select("select distinct lev1 from asr_loc_mast where row1=#{row1} order by lev1 desc") |
| | | public List<String> getViewLocLevCount(@Param("row1") int row1); |
| | | // |
| | | @Select("select loc_no as locNo, bay1,loc_sts as locSts from asr_loc_mast where row1=#{row1} and lev1=#{lev1} order by bay1") |
| | | @Select("select loc_no as locNo, bay1,loc_sts as locSts, loc_type2 as locType2 from asr_loc_mast where row1=#{row1} and lev1=#{lev1} order by bay1") |
| | | public List<ViewLocMapDto> getViewLocBays(@Param("row1") int row1, @Param("lev1") int lev1); |
| | | |
| | | // 库位Map |
| | | @Select("select distinct bay1 from asr_loc_mast where row1=#{row1} order by bay1") |
| | | public List<String> getViewLocBayCount(@Param("row1") int row1); |
| | | @Select("select lev1,loc_sts as locSts from asr_loc_mast where row1=#{row1} and bay1=#{bay1} order by bay1") |
| | | @Select("select lev1,loc_sts as locSts, loc_type2 as locType2 from asr_loc_mast where row1=#{row1} and bay1=#{bay1} order by bay1") |
| | | public List<ViewLocMapDto> getViewLocLevs(@Param("row1") int row1, @Param("bay1") int bay1); |
| | | @Select("SELECT DISTINCT row1 FROM asr_loc_mast ORDER BY row1 ASC") |
| | | List<Integer> getAllRows(); |
| | | @Select("SELECT DISTINCT bay1 FROM asr_loc_mast ORDER BY bay1 ASC") |
| | | List<String> getAllBays(); |
| | | |
| | | @Select("SELECT row1,lev1,bay1,loc_no as locNo,loc_sts as locSts FROM asr_loc_mast WHERE lev1 = #{layer} ORDER BY row1 ASC, bay1 ASC") |
| | | @Select("SELECT row1,lev1,bay1,loc_no as locNo,loc_sts as locSts, loc_type2 as locType2 FROM asr_loc_mast WHERE lev1 = #{layer} ORDER BY row1 ASC, bay1 ASC") |
| | | List<ViewLocMapDto> getLocMapByLayer(@Param("layer") Integer layer); |
| | | //分页查询站点入出库次数统计 |
| | | public List<ViewInOutBean> queryViewInOutList(ViewInOutBean viewInOut); |
| New file |
| | |
| | | package com.zy.asrs.service; |
| | | |
| | | import com.zy.asrs.entity.Area; |
| | | import com.baomidou.mybatisplus.service.IService; |
| | | |
| | | public interface AreaService extends IService<Area> { |
| | | |
| | | } |
| | |
| | | */ |
| | | List<LocMast> queryFreeLocMast2(Short locType1, Integer rowBeg, Integer rowEnd, Integer bayBeg, Integer bayEnd, Integer levBeg, Integer levEnd); |
| | | |
| | | void batchUpdateArea(List<String> locNos, Short areaId); |
| | | |
| | | List<Integer> getLevList(); |
| | | } |
| New file |
| | |
| | | package com.zy.asrs.service.impl; |
| | | |
| | | import com.zy.asrs.mapper.AreaMapper; |
| | | import com.zy.asrs.entity.Area; |
| | | import com.zy.asrs.service.AreaService; |
| | | import com.baomidou.mybatisplus.service.impl.ServiceImpl; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | @Service("areaService") |
| | | public class AreaServiceImpl extends ServiceImpl<AreaMapper, Area> implements AreaService { |
| | | |
| | | } |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void batchUpdateArea(List<String> locNos, Short areaId) { |
| | | if (Cools.isEmpty(locNos)) return; |
| | | java.util.List<LocMast> list = new java.util.ArrayList<>(); |
| | | for (String locNo : locNos) { |
| | | LocMast loc = new LocMast(); |
| | | loc.setLocNo(locNo); |
| | | loc.setLocType2(areaId); |
| | | list.add(loc); |
| | | } |
| | | this.updateBatchById(list); |
| | | } |
| | | |
| | | @Override |
| | | public List<Integer> getLevList() { |
| | | return this.baseMapper.getLevList(); |
| | | } |
| | |
| | | /** |
| | | * 检查正常库位前方是否堵塞(深库位规则:前方排是否有货或入库任务) |
| | | * |
| | | * 只对属于出库分组规则内的库位进行检查 |
| | | * 如果库位不在分组规则内,则视为不需要严格检查(返回 false,不触发补齐) |
| | | * 判断依据: |
| | | * 1. 只检查属于出库分组规则内的库位(通过分组的 rowList 确定范围) |
| | | * 2. 前方 = 分组中索引大于当前库位的排(假设分组 rowList 已按出库顺序排列,大索引 = 前方更深) |
| | | * 3. 堵塞条件:前方有货(F状态)或有入库任务 |
| | | * |
| | | * @param normalMasts 需要检查的正常库位列表(已通过 isInNormalRule 过滤) |
| | | * @return true = 前方有堵塞(需要补齐),false = 前方清空或无需检查 |
| | |
| | | if (normalMasts == null || normalMasts.isEmpty()) { |
| | | return false; |
| | | } |
| | | // 获取出库分组配置(用于确认规则范围) |
| | | |
| | | // 获取出库分组配置 |
| | | List<LocGroupOrder> locGroupAscOrder = slaveProperties.getLocGroupAscOrder(); |
| | | if (locGroupAscOrder == null || locGroupAscOrder.isEmpty()) { |
| | | return false; // 无配置时默认不检查 |
| | | } |
| | | |
| | | // 假设所有 normalMasts 在同一个分组(常见情况,若多分组可循环处理) |
| | | LocMast representative = normalMasts.get(0); |
| | | LocGroupOrder group = locGroupAscOrder.stream() |
| | | .filter(g -> g.getRowList() != null && g.getRowList().contains(representative.getRow1())) |
| | | .findFirst() |
| | | .orElse(null); |
| | | |
| | | if (group == null || group.getRowList() == null || group.getRowList().isEmpty()) { |
| | | return false; // 不在任何分组,不检查 |
| | | } |
| | | |
| | | List<Integer> fullRows = group.getRowList(); // 分组内所有排号列表(按出库顺序排列) |
| | | |
| | | // 遍历每个正常库位 |
| | | for (LocMast lm : normalMasts) { |
| | |
| | | continue; |
| | | } |
| | | |
| | | // 深库位检查方向:假设 row 越大越深(前方是更大 row 的位置) |
| | | // 你可以根据实际出库方向调整循环条件(例如从小 row 到大 row 或反之) |
| | | for (int row = currentRow + 1; row <= 5; row++) { // 假设深库位范围到 5 排,可调整 |
| | | LocMast front = getLocMastByRow(row, bay1, lev1); |
| | | // 在分组 rowList 中找到当前排的索引 |
| | | int currentIndex = fullRows.indexOf(currentRow); |
| | | if (currentIndex < 0) { |
| | | continue; // 当前排不在分组内,跳过 |
| | | } |
| | | |
| | | // 前方 = 分组中索引更大的位置(假设分组 rowList 从前到后排列,大索引 = 更深) |
| | | // 如果你的分组列表是倒序的(从后到前),则需改为 currentIndex - 1 到 0 |
| | | for (int i = currentIndex + 1; i < fullRows.size(); i++) { |
| | | Integer frontRow = fullRows.get(i); |
| | | LocMast front = getLocMastByRow(frontRow, bay1, lev1); |
| | | if (front == null) { |
| | | continue; |
| | | } |
| | |
| | | return true; |
| | | } |
| | | |
| | | // 有入库任务 → 堵塞 |
| | | WrkMast frontTask = wrkMastService.selectOne( |
| | | new EntityWrapper<WrkMast>() |
| | | .eq("source_loc_no", front.getLocNo()) |
| | | .eq("io_type", 100) // 假设 100 为入库类型,可调整 |
| | | .in("loc_sts", Arrays.asList("S", "Q")) // 支持 loc_sts 为 S 或 Q |
| | | ); |
| | | |
| | | if (frontTask != null) { |
| | | return true; |
| | | } |
| | |
| | | // generator.table="sys_host"; |
| | | // sqlserver |
| | | generator.sqlOsType = SqlOsType.SQL_SERVER; |
| | | generator.url="192.168.4.15:1433;databasename=source"; |
| | | generator.url="localhost:1433;databasename=arydasrs"; |
| | | generator.username="sa"; |
| | | generator.password="sa@123"; |
| | | generator.table="asr_wrk_mast_four_war_vehicle_log"; |
| | | generator.table="man_area"; |
| | | generator.packagePath="com.zy.asrs"; |
| | | generator.build(); |
| | | } |
| New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.zy.asrs.mapper.AreaMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.zy.asrs.entity.Area"> |
| | | <result column="id" property="id" /> |
| | | <result column="tag_id" property="tagId" /> |
| | | <result column="area_id" property="areaId" /> |
| | | <result column="area_name" property="areaName" /> |
| | | <result column="memo" property="memo" /> |
| | | <result column="backup1" property="backup1" /> |
| | | <result column="backup2" property="backup2" /> |
| | | <result column="backup3" property="backup3" /> |
| | | |
| | | </resultMap> |
| | | |
| | | </mapper> |
| | |
| | | <result column="memo" property="memo" /> |
| | | |
| | | <result column="stock" property="stock" /> |
| | | <result column="area_id" property="areaId"/> |
| | | </resultMap> |
| | | |
| | | <select id="listByPage" resultMap="BaseResultMap"> |
| New file |
| | |
| | | var pageCurr; |
| | | layui.config({ |
| | | base: baseUrl + "/static/layui/lay/modules/" |
| | | }).use(['table','laydate', 'form', 'admin'], function(){ |
| | | var table = layui.table; |
| | | var $ = layui.jquery; |
| | | var layer = layui.layer; |
| | | var layDate = layui.laydate; |
| | | var form = layui.form; |
| | | var admin = layui.admin; |
| | | |
| | | // 数据渲染 |
| | | tableIns = table.render({ |
| | | elem: '#area', |
| | | headers: {token: localStorage.getItem('token')}, |
| | | url: baseUrl+'/area/list/auth', |
| | | page: true, |
| | | limit: 15, |
| | | limits: [15, 30, 50, 100, 200, 500], |
| | | toolbar: '#toolbar', |
| | | cellMinWidth: 50, |
| | | height: 'full-120', |
| | | cols: [[ |
| | | {type: 'checkbox'} |
| | | // ,{field: 'id', align: 'center',title: 'ID'} |
| | | // ,{field: 'tagId', align: 'center',title: ''} |
| | | ,{field: 'areaId', align: 'center',title: '库区编号'} |
| | | ,{field: 'areaName', align: 'center',title: '库区名称'} |
| | | ,{field: 'memo', align: 'center',title: '库区备注'} |
| | | // ,{field: 'backup1', align: 'center',title: '备用字段'} |
| | | // ,{field: 'backup2', align: 'center',title: '备用字段2'} |
| | | // ,{field: 'backup3', align: 'center',title: '备用字段3'} |
| | | |
| | | ,{fixed: 'right', title:'操作', align: 'center', toolbar: '#operate', width:120} |
| | | ]], |
| | | request: { |
| | | pageName: 'curr', |
| | | pageSize: 'limit' |
| | | }, |
| | | parseData: function (res) { |
| | | return { |
| | | 'code': res.code, |
| | | 'msg': res.msg, |
| | | 'count': res.data.total, |
| | | 'data': res.data.records |
| | | } |
| | | }, |
| | | response: { |
| | | statusCode: 200 |
| | | }, |
| | | done: function(res, curr, count) { |
| | | if (res.code === 403) { |
| | | top.location.href = baseUrl+"/"; |
| | | } |
| | | pageCurr=curr; |
| | | limit(); |
| | | } |
| | | }); |
| | | |
| | | // 监听排序事件 |
| | | table.on('sort(area)', function (obj) { |
| | | var searchData = {}; |
| | | $.each($('#search-box [name]').serializeArray(), function() { |
| | | searchData[this.name] = this.value; |
| | | }); |
| | | searchData['orderByField'] = obj.field; |
| | | searchData['orderByType'] = obj.type; |
| | | tableIns.reload({ |
| | | where: searchData, |
| | | page: {curr: 1} |
| | | }); |
| | | }); |
| | | |
| | | // 监听头工具栏事件 |
| | | table.on('toolbar(area)', function (obj) { |
| | | var checkStatus = table.checkStatus(obj.config.id).data; |
| | | switch(obj.event) { |
| | | case 'addData': |
| | | showEditModel(); |
| | | break; |
| | | case 'deleteData': |
| | | if (checkStatus.length === 0) { |
| | | layer.msg('请选择要删除的数据', {icon: 2}); |
| | | return; |
| | | } |
| | | del(checkStatus.map(function (d) { |
| | | return d.id; |
| | | })); |
| | | break; |
| | | case 'exportData': |
| | | admin.confirm('确定导出Excel吗', {shadeClose: true}, function(){ |
| | | var titles=[]; |
| | | var fields=[]; |
| | | obj.config.cols[0].map(function (col) { |
| | | if (col.type === 'normal' && col.hide === false && col.toolbar == null) { |
| | | titles.push(col.title); |
| | | fields.push(col.field); |
| | | } |
| | | }); |
| | | var exportData = {}; |
| | | $.each($('#search-box [name]').serializeArray(), function() { |
| | | exportData[this.name] = this.value; |
| | | }); |
| | | var param = { |
| | | 'area': exportData, |
| | | 'fields': fields |
| | | }; |
| | | $.ajax({ |
| | | url: baseUrl+"/area/export/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: JSON.stringify(param), |
| | | dataType:'json', |
| | | contentType:'application/json;charset=UTF-8', |
| | | method: 'POST', |
| | | success: function (res) { |
| | | layer.closeAll(); |
| | | if (res.code === 200) { |
| | | table.exportFile(titles,res.data,'xls'); |
| | | } else if (res.code === 403) { |
| | | top.location.href = baseUrl+"/"; |
| | | } else { |
| | | layer.msg(res.msg, {icon: 2}) |
| | | } |
| | | } |
| | | }); |
| | | }); |
| | | break; |
| | | } |
| | | }); |
| | | |
| | | // 监听行工具事件 |
| | | table.on('tool(area)', function(obj){ |
| | | var data = obj.data; |
| | | switch (obj.event) { |
| | | case 'edit': |
| | | showEditModel(data); |
| | | break; |
| | | case "del": |
| | | del([data.id]); |
| | | break; |
| | | } |
| | | }); |
| | | |
| | | /* 弹窗 - 新增、修改 */ |
| | | function showEditModel(mData) { |
| | | admin.open({ |
| | | type: 1, |
| | | area: '600px', |
| | | title: (mData ? '修改' : '添加') + '订单状态', |
| | | content: $('#editDialog').html(), |
| | | success: function (layero, dIndex) { |
| | | layDateRender(mData); |
| | | form.val('detail', mData); |
| | | form.on('submit(editSubmit)', function (data) { |
| | | var loadIndex = layer.load(2); |
| | | $.ajax({ |
| | | url: baseUrl+"/area/"+(mData?'update':'add')+"/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: data.field, |
| | | method: 'POST', |
| | | success: function (res) { |
| | | layer.close(loadIndex); |
| | | if (res.code === 200){ |
| | | layer.close(dIndex); |
| | | layer.msg(res.msg, {icon: 1}); |
| | | tableReload(); |
| | | } else if (res.code === 403){ |
| | | top.location.href = baseUrl+"/"; |
| | | }else { |
| | | layer.msg(res.msg, {icon: 2}); |
| | | } |
| | | } |
| | | }) |
| | | return false; |
| | | }); |
| | | $(layero).children('.layui-layer-content').css('overflow', 'visible'); |
| | | layui.form.render('select'); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /* 删除 */ |
| | | function del(ids) { |
| | | layer.confirm('确定要删除选中数据吗?', { |
| | | skin: 'layui-layer-admin', |
| | | shade: .1 |
| | | }, function (i) { |
| | | layer.close(i); |
| | | var loadIndex = layer.load(2); |
| | | $.ajax({ |
| | | url: baseUrl+"/area/delete/auth", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: {ids: ids}, |
| | | method: 'POST', |
| | | success: function (res) { |
| | | layer.close(loadIndex); |
| | | if (res.code === 200){ |
| | | layer.msg(res.msg, {icon: 1}); |
| | | tableReload(); |
| | | } else if (res.code === 403){ |
| | | top.location.href = baseUrl+"/"; |
| | | } else { |
| | | layer.msg(res.msg, {icon: 2}); |
| | | } |
| | | } |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | // 搜索 |
| | | form.on('submit(search)', function (data) { |
| | | pageCurr = 1; |
| | | tableReload(false); |
| | | }); |
| | | |
| | | // 重置 |
| | | form.on('submit(reset)', function (data) { |
| | | pageCurr = 1; |
| | | clearFormVal($('#search-box')); |
| | | tableReload(false); |
| | | }); |
| | | |
| | | // 时间选择器 |
| | | function layDateRender(data) { |
| | | setTimeout(function () { |
| | | layDate.render({ |
| | | elem: '.layui-laydate-range' |
| | | ,type: 'datetime' |
| | | ,range: true |
| | | }); |
| | | |
| | | }, 300); |
| | | } |
| | | layDateRender(); |
| | | |
| | | }); |
| | | |
| | | // 关闭动作 |
| | | $(document).on('click','#data-detail-close', function () { |
| | | parent.layer.closeAll(); |
| | | }); |
| | | |
| | | function tableReload(child) { |
| | | var searchData = {}; |
| | | $.each($('#search-box [name]').serializeArray(), function() { |
| | | searchData[this.name] = this.value; |
| | | }); |
| | | tableIns.reload({ |
| | | where: searchData, |
| | | page: {curr: pageCurr} |
| | | }); |
| | | } |
| | |
| | | ,{field: 'store_max', align: 'center',title: '库存上限'} |
| | | ,{field: 'store_min', align: 'center',title: '库存下限'} |
| | | ,{field: 'store_max_date', align: 'center',title: '库龄上限(天)'} |
| | | ,{field: 'areaId$', align: 'center',title: '区域', templet: '#areaTpl'} |
| | | |
| | | ]; |
| | | cols.push.apply(cols, matCols); |
| | | cols.push( |
| | |
| | | admin = layui.admin; |
| | | var treeTable = layui.treeTable; |
| | | var xmSelect = layui.xmSelect; |
| | | |
| | | // 区域数据 |
| | | var areaData = []; |
| | | |
| | | // 加载区域数据 |
| | | $.ajax({ |
| | | url: baseUrl+'/area/list/auth', |
| | | headers: {token: localStorage.getItem('token')}, |
| | | method: 'GET', |
| | | async: false, |
| | | success: function (res) { |
| | | if (res.code === 200 && res.data && res.data.records) { |
| | | // 过滤掉空值 |
| | | areaData = res.data.records.filter(function(item) { |
| | | return item != null && item.areaId != null; |
| | | }); |
| | | console.log('区域数据加载成功:', areaData); |
| | | } else { |
| | | console.error('区域数据加载失败:', res); |
| | | } |
| | | }, |
| | | error: function(err) { |
| | | console.error('区域数据请求失败:', err); |
| | | } |
| | | }); |
| | | |
| | | // 商品分类数据 |
| | | var insTb = treeTable.render({ |
| | |
| | | // 新增自动生成商品编号 |
| | | if (!mData) { |
| | | http.get(baseUrl + "/mat/auto/matnr/auth", null, function (res) { |
| | | $('#matnr').val(res.data); |
| | | $(layero).find('#matnr').val(res.data); |
| | | }) |
| | | } |
| | | // 表单提交事件 |
| | | form.on('submit(editSubmit)', function (data) { |
| | | console.log(data) |
| | | data.field.tagId = insXmSel.getValue('valueStr'); |
| | | data.field.areaId = areaXmSel.getValue('valueStr'); |
| | | if (isEmpty(data.field.tagId)) { |
| | | layer.msg('分类不能为空', {icon: 2}); |
| | | return false; |
| | |
| | | }); |
| | | // 渲染下拉树 |
| | | var insXmSel = xmSelect.render({ |
| | | el: '#tagSel', |
| | | el: $(layero).find('#tagSel')[0], |
| | | height: '250px', |
| | | data: insTb.options.data, |
| | | initValue: mData ? [mData.tagId] : [], |
| | |
| | | expandedKeys: true |
| | | } |
| | | }); |
| | | // 渲染区域下拉选择 |
| | | console.log('准备渲染区域选择器,数据:', areaData); |
| | | console.log('当前商品数据:', mData); |
| | | var areaXmSel = xmSelect.render({ |
| | | el: $(layero).find('#areaSel')[0], |
| | | height: '250px', |
| | | data: areaData.length > 0 ? areaData : [], |
| | | initValue: mData && mData.areaId ? [mData.areaId] : [], |
| | | model: {label: {type: 'text'}}, |
| | | prop: { |
| | | name: 'areaName', |
| | | value: 'areaId' |
| | | }, |
| | | radio: true, |
| | | clickClose: true, |
| | | on: function(data) { |
| | | console.log('区域选择器事件:', data); |
| | | } |
| | | }); |
| | | console.log('区域选择器渲染完成'); |
| | | // 弹窗不出现滚动条 |
| | | $(layero).children('.layui-layer-content').css('overflow', 'visible'); |
| | | layui.form.render('select'); |
| | |
| | | var $ = layui.jquery; |
| | | var layer = layui.layer; |
| | | var form = layui.form; |
| | | var areaMap = {}; |
| | | |
| | | // Handlebars helper for area color |
| | | Handlebars.registerHelper('getAreaColor', function(areaId) { |
| | | if (areaId && areaMap[areaId] && areaMap[areaId].color) { |
| | | return areaMap[areaId].color; |
| | | } |
| | | return 'transparent'; |
| | | }); |
| | | |
| | | // 初始加载 |
| | | loadAreas(); // 加载库区颜色信息 |
| | | loadRowsOptions(); // 加载「排」选项(始终需要) |
| | | loadLayersOptions(); // 加载「层」选项(提前准备) |
| | | getLocTable('byRow', 1); // 默认按排 + 第1排 |
| | | |
| | | // 加载库区信息并显示图例 |
| | | function loadAreas() { |
| | | $.ajax({ |
| | | url: baseUrl + '/area/list/auth?page=1&limit=1000', |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | async: false, |
| | | success: function(res) { |
| | | if (res.code === 200) { |
| | | areaMap = {}; |
| | | var legendHtml = '<div class="area-legend-item" style="cursor:default;font-weight:bold;">库区图例:</div>'; |
| | | // 默认颜色列表,用于自动分配 |
| | | var defaultColors = ['#FF5733', '#33FF57', '#3357FF', '#FF33A1', '#A133FF', '#33FFF5', '#FFD700', '#FF8C00']; |
| | | var colorIndex = 0; |
| | | |
| | | res.data.records.forEach(function(area) { |
| | | var color = area.backup1; |
| | | // 增强颜色校验:如果为空、null字符串或长度过短,则视为无效 |
| | | if (!color || color === 'null' || color.trim().length < 3) { |
| | | color = defaultColors[colorIndex % defaultColors.length]; |
| | | colorIndex++; |
| | | } |
| | | areaMap[area.id] = {name: area.areaName, color: color, fullArea: area}; |
| | | legendHtml += '<div class="area-legend-item" onclick="editAreaColor(\'' + area.id + '\')"><span class="area-color-box" style="background-color:' + color + '"></span>' + area.areaName + '</div>'; |
| | | }); |
| | | $('#areaLegend').html(legendHtml).show(); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | // 编辑库区颜色 |
| | | window.editAreaColor = function(areaId) { |
| | | if (!areaId || !areaMap[areaId]) return; |
| | | var areaData = areaMap[areaId]; |
| | | |
| | | var contentHtml = '<div style="padding: 20px;"><form class="layui-form">' + |
| | | '<div class="layui-form-item">' + |
| | | '<label class="layui-form-label" style="width: auto; padding-left: 0;">库区名称:</label>' + |
| | | '<div class="layui-input-inline" style="line-height: 45px;">' + areaData.name + '</div>' + |
| | | '</div>' + |
| | | '<div class="layui-form-item">' + |
| | | '<label class="layui-form-label" style="width: auto; padding-left: 0;">选择颜色</label>' + |
| | | '<div class="layui-input-inline"><input type="color" id="singleAreaColorPicker" value="' + (areaData.color || '#cccccc') + '" style="height: 38px; width: 100%;"></div>' + |
| | | '</div>' + |
| | | '</form></div>'; |
| | | |
| | | layer.open({ |
| | | type: 1, |
| | | title: '修改库区颜色', |
| | | area: ['350px', '250px'], |
| | | content: contentHtml, |
| | | btn: ['保存', '取消'], |
| | | yes: function(index) { |
| | | var newColor = $('#singleAreaColorPicker').val(); |
| | | if (newColor !== areaData.color) { |
| | | $.ajax({ |
| | | url: baseUrl + '/area/update/auth', |
| | | method: 'POST', |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: { id: areaId, backup1: newColor }, |
| | | success: function(res) { |
| | | if (res.code === 200) { |
| | | layer.msg('颜色已更新'); |
| | | layer.close(index); |
| | | loadAreas(); // 刷新图例和缓存 |
| | | // 刷新地图以应用新颜色 |
| | | var mode = $('#viewMode').val(); |
| | | if (mode === 'byRow') getLocTable('byRow', $('#rowSelect').val()); |
| | | else getLocTable('byLayer', $('#layerSelect').val()); |
| | | } else { |
| | | layer.msg(res.msg || '更新失败'); |
| | | } |
| | | } |
| | | }); |
| | | } else { |
| | | layer.close(index); |
| | | } |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // 加载所有可用排 |
| | | function loadRowsOptions() { |
| | |
| | | // 加载所有可用层(需要后端支持新接口) |
| | | function loadLayersOptions() { |
| | | $.ajax({ |
| | | url: baseUrl + "/report/viewLocMapList/layers.action", // ← 需要新增接口 |
| | | url: baseUrl + "/report/viewLocMapList/layers.action", |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | method: 'POST', |
| | | async: false, |
| | | success: function (res) { |
| | | if (res.code === 200) { |
| | | var tpl = $("#locMastRowTemplate").html(); // 复用模板 |
| | | var tpl = $("#locMastRowTemplate").html(); |
| | | var template = Handlebars.compile(tpl); |
| | | $('#layerSelect').append(template(res)); |
| | | form.render('select'); |
| | |
| | | getLocTable('byLayer', data.value); |
| | | } |
| | | }); |
| | | |
| | | // --- 框选功能 --- |
| | | var isSelectionMode = false; |
| | | var isDragging = false; |
| | | var startX, startY; |
| | | var $selectionBox = $('#selectionBox'); |
| | | var $container = $('#locMapContain'); |
| | | |
| | | $('#btnSelectMode').click(function () { |
| | | isSelectionMode = !isSelectionMode; |
| | | if (isSelectionMode) { |
| | | $(this).text('关闭框选').addClass('layui-btn-danger').removeClass('layui-btn-normal'); |
| | | // 禁用原有点击事件,防止冲突 (通过 CSS pointer-events 或移除 onclick) |
| | | // 这里选择移除 onclick 属性 |
| | | $('.a-loc').each(function(){ |
| | | $(this).attr('data-onclick', $(this).attr('onclick')).removeAttr('onclick'); |
| | | }); |
| | | layer.msg('已开启框选模式,请在库位图上拖拽选择'); |
| | | } else { |
| | | $(this).text('开启框选').addClass('layui-btn-normal').removeClass('layui-btn-danger'); |
| | | $('.loc-selected').removeClass('loc-selected'); |
| | | $('#btnAssignZone').hide(); |
| | | // 恢复点击事件 |
| | | $('.a-loc').each(function(){ |
| | | if($(this).attr('data-onclick')) { |
| | | $(this).attr('onclick', $(this).attr('data-onclick')); |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | |
| | | $container.on('mousedown', function (e) { |
| | | if (!isSelectionMode) return; |
| | | // 如果点在滚动条上,可能也会触发,简单判断目标是否是 container 或 table |
| | | if(e.target.tagName !== 'TD' && e.target.id !== 'locMapContain' && e.target.tagName !== 'TABLE' && e.target.tagName !== 'TBODY' && e.target.tagName !== 'TR') return; |
| | | |
| | | isDragging = true; |
| | | var offset = $container.offset(); |
| | | // 相对于 container 内容的坐标 (包含滚动) |
| | | startX = e.pageX - offset.left + $container.scrollLeft(); |
| | | startY = e.pageY - offset.top + $container.scrollTop(); |
| | | |
| | | $selectionBox.css({ |
| | | left: startX, |
| | | top: startY, |
| | | width: 0, |
| | | height: 0, |
| | | display: 'block' |
| | | }); |
| | | |
| | | // 阻止默认文本选择 |
| | | e.preventDefault(); |
| | | }); |
| | | |
| | | $container.on('mousemove', function (e) { |
| | | if (!isSelectionMode || !isDragging) return; |
| | | var offset = $container.offset(); |
| | | var currentX = e.pageX - offset.left + $container.scrollLeft(); |
| | | var currentY = e.pageY - offset.top + $container.scrollTop(); |
| | | |
| | | var width = Math.abs(currentX - startX); |
| | | var height = Math.abs(currentY - startY); |
| | | var left = Math.min(currentX, startX); |
| | | var top = Math.min(currentY, startY); |
| | | |
| | | $selectionBox.css({ |
| | | width: width, |
| | | height: height, |
| | | left: left, |
| | | top: top |
| | | }); |
| | | }); |
| | | |
| | | $(document).on('mouseup', function (e) { |
| | | if (!isSelectionMode || !isDragging) return; |
| | | isDragging = false; |
| | | $selectionBox.hide(); |
| | | |
| | | // 计算框选区域 (相对于视口,用于 getBoundingClientRect 比较) |
| | | // 或者都转换为相对于 container 的坐标 |
| | | // 这里使用相对于 container 的坐标比较更稳妥 |
| | | |
| | | var boxLeft = parseFloat($selectionBox.css('left')); |
| | | var boxTop = parseFloat($selectionBox.css('top')); |
| | | var boxWidth = parseFloat($selectionBox.css('width')); |
| | | var boxHeight = parseFloat($selectionBox.css('height')); |
| | | var boxRight = boxLeft + boxWidth; |
| | | var boxBottom = boxTop + boxHeight; |
| | | |
| | | // 获取 container 的 offset |
| | | var containerOffset = $container.offset(); |
| | | |
| | | $('.a-loc').each(function () { |
| | | var $el = $(this); |
| | | var elOffset = $el.offset(); |
| | | // 转换为相对于 container 的坐标 (加上 scroll) |
| | | var elLeft = elOffset.left - containerOffset.left + $container.scrollLeft(); |
| | | var elTop = elOffset.top - containerOffset.top + $container.scrollTop(); |
| | | var elWidth = $el.outerWidth(); |
| | | var elHeight = $el.outerHeight(); |
| | | var elRight = elLeft + elWidth; |
| | | var elBottom = elTop + elHeight; |
| | | |
| | | // 碰撞检测 |
| | | if (!(elLeft > boxRight || elRight < boxLeft || elTop > boxBottom || elBottom < boxTop)) { |
| | | $el.toggleClass('loc-selected'); |
| | | } |
| | | }); |
| | | |
| | | if ($('.loc-selected').length > 0) { |
| | | $('#btnAssignZone').show().text('分配库区 (' + $('.loc-selected').length + ')'); |
| | | } else { |
| | | $('#btnAssignZone').hide(); |
| | | } |
| | | }); |
| | | |
| | | // --- 分配库区 --- |
| | | $('#btnAssignZone').click(function () { |
| | | var selectedLocs = []; |
| | | $('.loc-selected').each(function () { |
| | | selectedLocs.push($(this).attr('title')); // title has locNo |
| | | }); |
| | | |
| | | if (selectedLocs.length === 0) return; |
| | | |
| | | // 获取库区列表 |
| | | $.ajax({ |
| | | url: baseUrl + '/area/list/auth?page=1&limit=1000', |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | success: function(listRes) { |
| | | if (listRes.code === 200) { |
| | | var optionsHtml = '<option value="">请选择库区</option>'; |
| | | var areas = listRes.data.records; |
| | | areas.forEach(function(area) { |
| | | optionsHtml += '<option value="' + area.id + '">' + area.areaName + ' (' + area.areaId + ')</option>'; |
| | | }); |
| | | |
| | | var contentHtml = '<div style="padding: 20px;"><form class="layui-form">' + |
| | | '<div class="layui-form-item"><select id="selectArea" lay-filter="selectArea">' + optionsHtml + '</select></div>' + |
| | | '<div class="layui-form-item">' + |
| | | '<label class="layui-form-label" style="width: auto; padding-left: 0;">库区颜色</label>' + |
| | | '<div class="layui-input-inline"><input type="color" id="areaColorPicker" value="#cccccc" style="height: 38px; width: 100%;"></div>' + |
| | | '</div>' + |
| | | '</form></div>'; |
| | | |
| | | layer.open({ |
| | | type: 1, |
| | | title: '分配库区及颜色', |
| | | area: ['400px', '350px'], |
| | | content: contentHtml, |
| | | btn: ['确定', '取消'], |
| | | success: function(layero, index) { |
| | | form.render('select'); |
| | | form.on('select(selectArea)', function(data){ |
| | | var areaId = data.value; |
| | | if(areaId && areaMap[areaId]) { |
| | | $('#areaColorPicker').val(areaMap[areaId].color || '#cccccc'); |
| | | } |
| | | }); |
| | | }, |
| | | yes: function(index) { |
| | | var areaId = $('#selectArea').val(); |
| | | var newColor = $('#areaColorPicker').val(); |
| | | |
| | | if (!areaId) { |
| | | layer.msg('请选择库区'); |
| | | return; |
| | | } |
| | | |
| | | // 1. 更新库区颜色 (如果有变化) |
| | | if (areaMap[areaId] && areaMap[areaId].color !== newColor) { |
| | | $.ajax({ |
| | | url: baseUrl + '/area/update/auth', |
| | | method: 'POST', |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | data: { id: areaId, backup1: newColor }, |
| | | async: false, // 同步更新以确保刷新时颜色正确 |
| | | success: function() { |
| | | loadAreas(); // 刷新图例和缓存 |
| | | } |
| | | }); |
| | | } |
| | | |
| | | // 2. 批量更新库位 |
| | | $.ajax({ |
| | | url: baseUrl + '/locMast/batchUpdateArea/auth', |
| | | method: 'POST', |
| | | headers: {'token': localStorage.getItem('token')}, |
| | | contentType: 'application/json', |
| | | data: JSON.stringify({ |
| | | locNos: selectedLocs, |
| | | areaId: parseInt(areaId) |
| | | }), |
| | | success: function(updRes) { |
| | | if (updRes.code === 200) { |
| | | layer.msg('分配成功'); |
| | | layer.close(index); |
| | | // 刷新 |
| | | var mode = $('#viewMode').val(); |
| | | if (mode === 'byRow') getLocTable('byRow', $('#rowSelect').val()); |
| | | else getLocTable('byLayer', $('#layerSelect').val()); |
| | | |
| | | // 重置状态 |
| | | $('.loc-selected').removeClass('loc-selected'); |
| | | $('#btnAssignZone').hide(); |
| | | // 保持框选模式 |
| | | if(isSelectionMode) { |
| | | // 重新移除onclick |
| | | setTimeout(function(){ |
| | | $('.a-loc').each(function(){ |
| | | $(this).attr('data-onclick', $(this).attr('onclick')).removeAttr('onclick'); |
| | | }); |
| | | }, 500); // 简单延时等待渲染 |
| | | } |
| | | } else { |
| | | layer.msg(updRes.msg || '操作失败'); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | } else { |
| | | layer.msg(listRes.msg || '无法获取库区列表'); |
| | | } |
| | | } |
| | | }); |
| | | }); |
| | | |
| | | }); |
| New file |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="en"> |
| | | <head> |
| | | <meta charset="utf-8"> |
| | | <title></title> |
| | | <meta name="renderer" content="webkit"> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> |
| | | <link rel="stylesheet" href="../../static/layui/css/layui.css" media="all"> |
| | | <link rel="stylesheet" href="../../static/css/admin.css?v=318" media="all"> |
| | | <link rel="stylesheet" href="../../static/css/cool.css" media="all"> |
| | | </head> |
| | | <body> |
| | | |
| | | <div class="layui-fluid"> |
| | | <div class="layui-card"> |
| | | <div class="layui-card-body"> |
| | | <div class="layui-form toolbar" id="search-box"> |
| | | <div class="layui-form-item"> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="id" placeholder="编号" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline" style="width: 300px"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input layui-laydate-range" name="create_time" type="text" placeholder="起始时间 - 终止时间" autocomplete="off" style="width: 300px"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="condition" placeholder="请输入" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline">  |
| | | <button class="layui-btn icon-btn" lay-filter="search" lay-submit> |
| | | <i class="layui-icon"></i>搜索 |
| | | </button> |
| | | <button class="layui-btn icon-btn" lay-filter="reset" lay-submit> |
| | | <i class="layui-icon"></i>重置 |
| | | </button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <table class="layui-hide" id="area" lay-filter="area"></table> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <script type="text/html" id="toolbar"> |
| | | <div class="layui-btn-container"> |
| | | <button class="layui-btn layui-btn-sm" id="btn-add" lay-event="addData">新增</button> |
| | | <button class="layui-btn layui-btn-sm layui-btn-danger" id="btn-delete" lay-event="deleteData">删除</button> |
| | | <button class="layui-btn layui-btn-primary layui-btn-sm" id="btn-export" lay-event="exportData" style="float: right">导出</button> |
| | | </div> |
| | | </script> |
| | | |
| | | <script type="text/html" id="operate"> |
| | | <a class="layui-btn layui-btn-primary layui-btn-xs btn-edit" lay-event="edit">修改</a> |
| | | <a class="layui-btn layui-btn-danger layui-btn-xs btn-edit" lay-event="del">删除</a> |
| | | </script> |
| | | |
| | | <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/cool.js" charset="utf-8"></script> |
| | | <script type="text/javascript" src="../../static/js/area/area.js" charset="utf-8"></script> |
| | | </body> |
| | | <!-- 表单弹窗 --> |
| | | <script type="text/html" id="editDialog"> |
| | | <form id="detail" lay-filter="detail" class="layui-form admin-form model-form"> |
| | | <input name="id" type="hidden"> |
| | | <div class="layui-row"> |
| | | <div class="layui-col-md12"> |
| | | <!-- <div class="layui-form-item">--> |
| | | <!-- <label class="layui-form-label layui-form-required">ID: </label>--> |
| | | <!-- <div class="layui-input-block">--> |
| | | <!-- <input class="layui-input" name="id" placeholder="请输入ID" lay-vertype="tips" lay-verify="required">--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <!-- <div class="layui-form-item">--> |
| | | <!-- <label class="layui-form-label layui-form-required">: </label>--> |
| | | <!-- <div class="layui-input-block">--> |
| | | <!-- <input class="layui-input" name="tagId" placeholder="请输入" lay-vertype="tips" lay-verify="required">--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">库区编号: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="areaId" placeholder="请输入库区id" lay-vertype="tips" lay-verify="required"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">库区名称: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="areaName" placeholder="请输入库区名称"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">库区备注: </label> |
| | | <div class="layui-input-block"> |
| | | <input class="layui-input" name="memo" placeholder="请输入库区备注"> |
| | | </div> |
| | | </div> |
| | | <!-- <div class="layui-form-item">--> |
| | | <!-- <label class="layui-form-label">备用字段-1: </label>--> |
| | | <!-- <div class="layui-input-block">--> |
| | | <!-- <input class="layui-input" name="backup1" placeholder="请输入备用字段">--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <!-- <div class="layui-form-item">--> |
| | | <!-- <label class="layui-form-label">备用字段-2: </label>--> |
| | | <!-- <div class="layui-input-block">--> |
| | | <!-- <input class="layui-input" name="backup2" placeholder="请输入备用字段2">--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <!-- <div class="layui-form-item">--> |
| | | <!-- <label class="layui-form-label">备用字段-3: </label>--> |
| | | <!-- <div class="layui-input-block">--> |
| | | <!-- <input class="layui-input" name="backup3" placeholder="请输入备用字段3">--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | |
| | | </div> |
| | | </div> |
| | | <hr class="layui-bg-gray"> |
| | | <div class="layui-form-item text-right"> |
| | | <button class="layui-btn" lay-filter="editSubmit" lay-submit="">保存</button> |
| | | <button class="layui-btn layui-btn-primary" type="button" ew-event="closeDialog">取消</button> |
| | | </div> |
| | | </form> |
| | | </script> |
| | | </html> |
| | | |
| | |
| | | <span name="tagId" class="layui-badge layui-badge-gray">{{d.tagId$}}</span> |
| | | </script> |
| | | |
| | | <script type="text/html" id="areaTpl"> |
| | | <span name="areaId" class="layui-badge layui-badge-blue">{{d.areaId$}}</span> |
| | | </script> |
| | | |
| | | <script type="text/html" id="toolbar"> |
| | | <div class="layui-btn-container"> |
| | | <button class="layui-btn layui-btn-sm" id="btn-print-batch" lay-event="btnPrintBatch">批量打印</button> |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">配置</label> |
| | | <div class="layui-input-block"> |
| | | <input name="specs" placeholder="请输入配置" class="layui-input"> |
| | | </div> |
| | | </div> |
| | | <!-- <div class="layui-form-item">--> |
| | | <!-- <label class="layui-form-label">配置</label>--> |
| | | <!-- <div class="layui-input-block">--> |
| | | <!-- <input name="specs" placeholder="请输入配置" class="layui-input">--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">单箱净重</label> |
| | |
| | | </div> |
| | | |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">单箱体积</label> |
| | | <label class="layui-form-label">单箱毛重</label> |
| | | <div class="layui-input-block"> |
| | | <input name="volume" placeholder="请输入单箱体积" class="layui-input"> |
| | | <input name="length" placeholder="请输入单箱毛重" class="layui-input"> |
| | | </div> |
| | | </div> |
| | | |
| | | </div> |
| | | |
| | | <div class="layui-col-md6"> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">区域</label> |
| | | <div class="layui-input-block"> |
| | | <div id="areaSel" class="ew-xmselect-tree"></div> |
| | | </div> |
| | | </div> |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label layui-form-required">商品编号</label> |
| | | <div class="layui-input-block"> |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">单箱毛重</label> |
| | | <div class="layui-input-block"> |
| | | <input name="length" placeholder="请输入单箱毛重" class="layui-input"> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="layui-form-item"> |
| | | <label class="layui-form-label">单箱体积</label> |
| | | <div class="layui-input-block"> |
| | | <input name="threeCode" placeholder="请输入箱子尺寸" class="layui-input"> |
| | | </div> |
| | | </div> |
| | | <!-- <div class="layui-form-item">--> |
| | | <!-- <label class="layui-form-label">单箱体积</label>--> |
| | | <!-- <div class="layui-input-block">--> |
| | | <!-- <input name="threeCode" placeholder="请输入箱子尺寸" class="layui-input">--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | |
| | | </div> |
| | | </div> |
| | |
| | | #locMapContain { |
| | | overflow-x: auto; |
| | | width:100%; |
| | | height:700px |
| | | height:700px; |
| | | position: relative; |
| | | } |
| | | .a-loc { |
| | | cursor: pointer; |
| | |
| | | .layui-table td:hover { |
| | | opacity: 0.5; |
| | | } |
| | | </style> |
| | | .loc-selected { |
| | | border: 2px solid red !important; |
| | | box-shadow: 0 0 5px red; |
| | | } |
| | | #selectionBox { |
| | | position: absolute; |
| | | border: 1px dashed #009688; |
| | | background-color: rgba(0, 150, 136, 0.2); |
| | | display: none; |
| | | z-index: 1000; |
| | | pointer-events: none; |
| | | } |
| | | .area-legend-item { |
| | | display: inline-flex; |
| | | align-items: center; |
| | | margin-right: 15px; |
| | | font-size: 14px; |
| | | cursor: pointer; |
| | | padding: 2px 5px; |
| | | border-radius: 4px; |
| | | transition: background-color 0.2s; |
| | | } |
| | | .area-legend-item:hover { |
| | | background-color: #f0f0f0; |
| | | } |
| | | </style> |
| | | </head> |
| | | <body> |
| | | <!-- 搜索栏 --> |
| | |
| | | </select> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="layui-inline" style="margin-left: 20px;"> |
| | | <button class="layui-btn layui-btn-normal" id="btnSelectMode">开启框选</button> |
| | | <button class="layui-btn layui-btn-warm" id="btnAssignZone" style="display:none;">分配库区</button> |
| | | </div> |
| | | </div> |
| | | <div id="areaLegend" style="padding: 5px 15px; background: #fff; border-bottom: 1px solid #eee; display:none;"> |
| | | <!-- Legend items will be injected here --> |
| | | </div> |
| | | <div id="locMapContain"> |
| | | <table class="layui-table" id="locMap" lay-filter="locMap"></table> |
| | | <div id="selectionBox"></div> |
| | | </div> |
| | | <!-- 表格 --> |
| | | |
| | |
| | | {{#each body}} |
| | | <tr> |
| | | {{#each loc}} |
| | | <td class="a-loc" title="{{locNo}}" onclick="locDetl(this)" style="background-color:{{bgc}};color:{{color}}">{{locSts}}</td> |
| | | <td class="a-loc" title="{{locNo}}" onclick="locDetl(this)" |
| | | style="background-color:{{bgc}};color:{{color}};position:relative;{{#if locType2}}box-shadow:inset 0 0 0 4px {{getAreaColor locType2}}{{/if}}"> |
| | | {{locSts}} |
| | | {{#if locType2}}<div style="position:absolute;top:0;right:0;width:0;height:0;border-top:10px solid {{getAreaColor locType2}};border-left:10px solid transparent;"></div>{{/if}} |
| | | </td> |
| | | {{/each}} |
| | | </tr> |
| | | {{/each}} |