hou 2 дней назад
Родитель
Сommit
d4ff8e4428

+ 59 - 0
db/mysql/mes_delivery_note.sql

@@ -0,0 +1,59 @@
+-- 物料管理 / 送货单记录
+-- 送货单主表,以及送货单与成品批次的绑定关系
+
+CREATE TABLE IF NOT EXISTS `mes_delivery_note` (
+  `id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '编号',
+  `sn` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '送货单号',
+  `customer` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '客户',
+  `contact` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '联系人',
+  `phone` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '电话',
+  `address` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '送货地址',
+  `delivery_date` datetime NULL DEFAULT NULL COMMENT '送货日期',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建者',
+  `create_date` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新者',
+  `update_date` datetime NULL DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE KEY `uk_mes_delivery_note_sn` (`sn`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '送货单' ROW_FORMAT = DYNAMIC;
+
+CREATE TABLE IF NOT EXISTS `mes_delivery_note_batch` (
+  `id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '编号',
+  `delivery_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '送货单id',
+  `batch_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '成品批次id',
+  `batch_sn` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '批次码',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建者',
+  `create_date` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新者',
+  `update_date` datetime NULL DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE KEY `uk_mes_delivery_note_batch` (`batch_id`) USING BTREE,
+  KEY `idx_mes_delivery_note_batch_delivery` (`delivery_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '送货单绑定成品批次' ROW_FORMAT = DYNAMIC;
+
+INSERT INTO `js_sys_menu`
+(`menu_code`, `parent_code`, `parent_codes`, `tree_sort`, `tree_sorts`, `tree_leaf`, `tree_level`,
+ `tree_names`, `menu_name`, `menu_type`, `menu_href`, `menu_target`, `menu_icon`, `menu_color`, `menu_title`,
+ `permission`, `weight`, `is_show`, `sys_code`, `module_codes`, `component`, `params`, `status`,
+ `create_by`, `create_date`, `update_by`, `update_date`, `remarks`)
+SELECT
+'2099101500000000001', p.`menu_code`, CONCAT(p.`parent_codes`, p.`menu_code`, ','),
+900, CONCAT(p.`tree_sorts`, '0000000900,'), '1', p.`tree_level` + 1,
+CONCAT(p.`tree_names`, '/送货单记录'), '送货单记录', '1',
+'/mes/mesDeliveryNote/list', '', '', '', '',
+'mes:mesDeliveryNote:view,mes:mesDeliveryNote:edit', 40, '1', 'default', 'core', NULL, NULL, '0',
+'system', NOW(), 'system', NOW(), '送货单及成品批次绑定'
+FROM `js_sys_menu` p
+WHERE p.`menu_code` = '1667359431003865088'
+  AND NOT EXISTS (SELECT 1 FROM `js_sys_menu` WHERE `menu_code` = '2099101500000000001');
+
+INSERT INTO `js_sys_role_menu` (`role_code`, `menu_code`)
+SELECT rm.`role_code`, '2099101500000000001'
+FROM `js_sys_role_menu` rm
+WHERE rm.`menu_code` = '1667359431003865088'
+  AND NOT EXISTS (
+    SELECT 1 FROM `js_sys_role_menu` x
+    WHERE x.`role_code` = rm.`role_code`
+      AND x.`menu_code` = '2099101500000000001'
+  );

+ 13 - 0
src/main/java/com/jeesite/modules/mes/dao/MesDeliveryNoteBatchDao.java

@@ -0,0 +1,13 @@
+package com.jeesite.modules.mes.dao;
+
+import com.jeesite.common.dao.CrudDao;
+import com.jeesite.common.mybatis.annotation.MyBatisDao;
+import com.jeesite.modules.mes.entity.MesDeliveryNoteBatch;
+
+/**
+ * 送货单绑定成品批次DAO
+ */
+@MyBatisDao
+public interface MesDeliveryNoteBatchDao extends CrudDao<MesDeliveryNoteBatch> {
+
+}

+ 13 - 0
src/main/java/com/jeesite/modules/mes/dao/MesDeliveryNoteDao.java

@@ -0,0 +1,13 @@
+package com.jeesite.modules.mes.dao;
+
+import com.jeesite.common.dao.CrudDao;
+import com.jeesite.common.mybatis.annotation.MyBatisDao;
+import com.jeesite.modules.mes.entity.MesDeliveryNote;
+
+/**
+ * 送货单DAO
+ */
+@MyBatisDao
+public interface MesDeliveryNoteDao extends CrudDao<MesDeliveryNote> {
+
+}

+ 139 - 0
src/main/java/com/jeesite/modules/mes/entity/MesDeliveryNote.java

@@ -0,0 +1,139 @@
+package com.jeesite.modules.mes.entity;
+
+import java.util.Date;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.jeesite.common.entity.DataEntity;
+import com.jeesite.common.mybatis.annotation.Column;
+import com.jeesite.common.mybatis.annotation.Table;
+import com.jeesite.common.mybatis.mapper.query.QueryType;
+
+/**
+ * 送货单
+ */
+@Table(name="mes_delivery_note", alias="a", label="送货单", columns={
+		@Column(name="id", attrName="id", label="编号", isPK=true),
+		@Column(name="sn", attrName="sn", label="送货单号", queryType=QueryType.LIKE),
+		@Column(name="customer", attrName="customer", label="客户", queryType=QueryType.LIKE),
+		@Column(name="contact", attrName="contact", label="联系人", queryType=QueryType.LIKE),
+		@Column(name="phone", attrName="phone", label="电话", queryType=QueryType.LIKE),
+		@Column(name="address", attrName="address", label="送货地址", queryType=QueryType.LIKE),
+		@Column(name="delivery_date", attrName="deliveryDate", label="送货日期", isUpdateForce=true),
+		@Column(name="remark", attrName="remark", label="备注", queryType=QueryType.LIKE),
+		@Column(name="create_by", attrName="createBy", label="创建者", isUpdate=false, isQuery=false),
+		@Column(name="create_date", attrName="createDate", label="创建时间", isUpdate=false, isQuery=false, isUpdateForce=true),
+		@Column(name="update_by", attrName="updateBy", label="更新者", isQuery=false),
+		@Column(name="update_date", attrName="updateDate", label="更新时间", isQuery=false, isUpdateForce=true),
+	}, orderBy="a.update_date DESC"
+)
+public class MesDeliveryNote extends DataEntity<MesDeliveryNote> {
+
+	private static final long serialVersionUID = 1L;
+	private String sn;
+	private String customer;
+	private String contact;
+	private String phone;
+	private String address;
+	private Date deliveryDate;
+	private String remark;
+	private Long batchCount;
+
+	public MesDeliveryNote() {
+		this(null);
+	}
+
+	public MesDeliveryNote(String id) {
+		super(id);
+	}
+
+	@NotBlank(message="送货单号不能为空")
+	@Size(min=0, max=64, message="送货单号长度不能超过 64 个字符")
+	public String getSn() {
+		return sn;
+	}
+
+	public void setSn(String sn) {
+		this.sn = sn;
+	}
+
+	@Size(min=0, max=200, message="客户长度不能超过 200 个字符")
+	public String getCustomer() {
+		return customer;
+	}
+
+	public void setCustomer(String customer) {
+		this.customer = customer;
+	}
+
+	@Size(min=0, max=100, message="联系人长度不能超过 100 个字符")
+	public String getContact() {
+		return contact;
+	}
+
+	public void setContact(String contact) {
+		this.contact = contact;
+	}
+
+	@Size(min=0, max=50, message="电话长度不能超过 50 个字符")
+	public String getPhone() {
+		return phone;
+	}
+
+	public void setPhone(String phone) {
+		this.phone = phone;
+	}
+
+	@Size(min=0, max=500, message="送货地址长度不能超过 500 个字符")
+	public String getAddress() {
+		return address;
+	}
+
+	public void setAddress(String address) {
+		this.address = address;
+	}
+
+	@JsonFormat(pattern = "yyyy-MM-dd")
+	public Date getDeliveryDate() {
+		return deliveryDate;
+	}
+
+	public void setDeliveryDate(Date deliveryDate) {
+		this.deliveryDate = deliveryDate;
+	}
+
+	public Date getDeliveryDate_gte() {
+		return sqlMap.getWhere().getValue("delivery_date", QueryType.GTE);
+	}
+
+	public void setDeliveryDate_gte(Date deliveryDate) {
+		sqlMap.getWhere().and("delivery_date", QueryType.GTE, deliveryDate);
+	}
+
+	public Date getDeliveryDate_lte() {
+		return sqlMap.getWhere().getValue("delivery_date", QueryType.LTE);
+	}
+
+	public void setDeliveryDate_lte(Date deliveryDate) {
+		sqlMap.getWhere().and("delivery_date", QueryType.LTE, deliveryDate);
+	}
+
+	@Size(min=0, max=500, message="备注长度不能超过 500 个字符")
+	public String getRemark() {
+		return remark;
+	}
+
+	public void setRemark(String remark) {
+		this.remark = remark;
+	}
+
+	public Long getBatchCount() {
+		return batchCount;
+	}
+
+	public void setBatchCount(Long batchCount) {
+		this.batchCount = batchCount;
+	}
+}

+ 68 - 0
src/main/java/com/jeesite/modules/mes/entity/MesDeliveryNoteBatch.java

@@ -0,0 +1,68 @@
+package com.jeesite.modules.mes.entity;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+
+import com.jeesite.common.entity.DataEntity;
+import com.jeesite.common.mybatis.annotation.Column;
+import com.jeesite.common.mybatis.annotation.Table;
+import com.jeesite.common.mybatis.mapper.query.QueryType;
+
+/**
+ * 送货单绑定成品批次
+ */
+@Table(name="mes_delivery_note_batch", alias="a", label="送货单绑定成品批次", columns={
+		@Column(name="id", attrName="id", label="编号", isPK=true),
+		@Column(name="delivery_id", attrName="deliveryId", label="送货单"),
+		@Column(name="batch_id", attrName="batchId", label="成品批次"),
+		@Column(name="batch_sn", attrName="batchSn", label="批次码", queryType=QueryType.LIKE),
+		@Column(name="create_by", attrName="createBy", label="创建者", isUpdate=false, isQuery=false),
+		@Column(name="create_date", attrName="createDate", label="创建时间", isUpdate=false, isQuery=false, isUpdateForce=true),
+		@Column(name="update_by", attrName="updateBy", label="更新者", isQuery=false),
+		@Column(name="update_date", attrName="updateDate", label="更新时间", isQuery=false, isUpdateForce=true),
+	}, orderBy="a.update_date DESC"
+)
+public class MesDeliveryNoteBatch extends DataEntity<MesDeliveryNoteBatch> {
+
+	private static final long serialVersionUID = 1L;
+	private String deliveryId;
+	private String batchId;
+	private String batchSn;
+
+	public MesDeliveryNoteBatch() {
+		this(null);
+	}
+
+	public MesDeliveryNoteBatch(String id) {
+		super(id);
+	}
+
+	@NotBlank(message="送货单不能为空")
+	@Size(min=0, max=64, message="送货单长度不能超过 64 个字符")
+	public String getDeliveryId() {
+		return deliveryId;
+	}
+
+	public void setDeliveryId(String deliveryId) {
+		this.deliveryId = deliveryId;
+	}
+
+	@NotBlank(message="成品批次不能为空")
+	@Size(min=0, max=64, message="成品批次长度不能超过 64 个字符")
+	public String getBatchId() {
+		return batchId;
+	}
+
+	public void setBatchId(String batchId) {
+		this.batchId = batchId;
+	}
+
+	@Size(min=0, max=100, message="批次码长度不能超过 100 个字符")
+	public String getBatchSn() {
+		return batchSn;
+	}
+
+	public void setBatchSn(String batchSn) {
+		this.batchSn = batchSn;
+	}
+}

+ 45 - 0
src/main/java/com/jeesite/modules/mes/service/MesDeliveryNoteBatchService.java

@@ -0,0 +1,45 @@
+package com.jeesite.modules.mes.service;
+
+import java.util.List;
+
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeesite.common.entity.Page;
+import com.jeesite.common.service.CrudService;
+import com.jeesite.modules.mes.dao.MesDeliveryNoteBatchDao;
+import com.jeesite.modules.mes.entity.MesDeliveryNoteBatch;
+
+/**
+ * 送货单绑定成品批次Service
+ */
+@Service
+public class MesDeliveryNoteBatchService extends CrudService<MesDeliveryNoteBatchDao, MesDeliveryNoteBatch> {
+
+	@Override
+	public MesDeliveryNoteBatch get(MesDeliveryNoteBatch mesDeliveryNoteBatch) {
+		return super.get(mesDeliveryNoteBatch);
+	}
+
+	@Override
+	public Page<MesDeliveryNoteBatch> findPage(MesDeliveryNoteBatch mesDeliveryNoteBatch) {
+		return super.findPage(mesDeliveryNoteBatch);
+	}
+
+	@Override
+	public List<MesDeliveryNoteBatch> findList(MesDeliveryNoteBatch mesDeliveryNoteBatch) {
+		return super.findList(mesDeliveryNoteBatch);
+	}
+
+	@Override
+	@Transactional
+	public void save(MesDeliveryNoteBatch mesDeliveryNoteBatch) {
+		super.save(mesDeliveryNoteBatch);
+	}
+
+	@Override
+	@Transactional
+	public void delete(MesDeliveryNoteBatch mesDeliveryNoteBatch) {
+		super.delete(mesDeliveryNoteBatch);
+	}
+}

+ 130 - 0
src/main/java/com/jeesite/modules/mes/service/MesDeliveryNoteService.java

@@ -0,0 +1,130 @@
+package com.jeesite.modules.mes.service;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeesite.common.collect.ListUtils;
+import com.jeesite.common.entity.Page;
+import com.jeesite.common.lang.StringUtils;
+import com.jeesite.common.mybatis.mapper.query.QueryType;
+import com.jeesite.common.service.CrudService;
+import com.jeesite.common.service.ServiceException;
+import com.jeesite.modules.mes.dao.MesDeliveryNoteDao;
+import com.jeesite.modules.mes.entity.MesDeliveryNote;
+import com.jeesite.modules.mes.entity.MesDeliveryNoteBatch;
+import com.jeesite.modules.mes.entity.MesProductBatch;
+
+/**
+ * 送货单Service
+ */
+@Service
+public class MesDeliveryNoteService extends CrudService<MesDeliveryNoteDao, MesDeliveryNote> {
+
+	@Autowired
+	private MesDeliveryNoteBatchService mesDeliveryNoteBatchService;
+
+	@Autowired
+	private MesProductBatchService mesProductBatchService;
+
+	@Override
+	public MesDeliveryNote get(MesDeliveryNote mesDeliveryNote) {
+		return super.get(mesDeliveryNote);
+	}
+
+	@Override
+	public Page<MesDeliveryNote> findPage(MesDeliveryNote mesDeliveryNote) {
+		Page<MesDeliveryNote> page = super.findPage(mesDeliveryNote);
+		if (page.getList() != null) {
+			for (MesDeliveryNote note : page.getList()) {
+				note.setBatchCount(countBatch(note.getId()));
+			}
+		}
+		return page;
+	}
+
+	@Override
+	public List<MesDeliveryNote> findList(MesDeliveryNote mesDeliveryNote) {
+		return super.findList(mesDeliveryNote);
+	}
+
+	@Override
+	@Transactional
+	public void save(MesDeliveryNote mesDeliveryNote) {
+		if (StringUtils.isBlank(mesDeliveryNote.getSn())) {
+			throw new ServiceException(text("送货单号不能为空"));
+		}
+		MesDeliveryNote query = new MesDeliveryNote();
+		query.setSn(null);
+		query.getSqlMap().getWhere().and("sn", QueryType.EQ, mesDeliveryNote.getSn());
+		List<MesDeliveryNote> exists = findList(query);
+		for (MesDeliveryNote item : exists) {
+			if (!StringUtils.equals(item.getId(), mesDeliveryNote.getId())) {
+				throw new ServiceException(text("送货单号已存在"));
+			}
+		}
+		super.save(mesDeliveryNote);
+	}
+
+	@Override
+	@Transactional
+	public void delete(MesDeliveryNote mesDeliveryNote) {
+		if (countBatch(mesDeliveryNote.getId()) > 0) {
+			throw new ServiceException(text("该送货单已绑定成品批次,请先解除绑定"));
+		}
+		super.delete(mesDeliveryNote);
+	}
+
+	public long countBatch(String deliveryId) {
+		if (StringUtils.isBlank(deliveryId)) {
+			return 0;
+		}
+		MesDeliveryNoteBatch query = new MesDeliveryNoteBatch();
+		query.setDeliveryId(deliveryId);
+		Long count = mesDeliveryNoteBatchService.findCount(query);
+		return count == null ? 0 : count;
+	}
+
+	@Transactional
+	public void bindBatches(String deliveryId, String batchIds) {
+		MesDeliveryNote note = get(new MesDeliveryNote(deliveryId));
+		if (note == null || StringUtils.isBlank(note.getId())) {
+			throw new ServiceException(text("送货单不存在"));
+		}
+		if (StringUtils.isBlank(batchIds)) {
+			throw new ServiceException(text("请选择成品批次"));
+		}
+		String[] ids = batchIds.split(",");
+		int bindNum = 0;
+		for (String batchId : ids) {
+			if (StringUtils.isBlank(batchId)) {
+				continue;
+			}
+			MesProductBatch batch = mesProductBatchService.get(new MesProductBatch(batchId.trim()));
+			if (batch == null || StringUtils.isBlank(batch.getId())) {
+				throw new ServiceException(text("成品批次不存在"));
+			}
+			MesDeliveryNoteBatch boundQuery = new MesDeliveryNoteBatch();
+			boundQuery.setBatchId(batch.getId());
+			List<MesDeliveryNoteBatch> boundList = mesDeliveryNoteBatchService.findList(boundQuery);
+			if (!ListUtils.isEmpty(boundList)) {
+				MesDeliveryNoteBatch bound = boundList.get(0);
+				if (StringUtils.equals(bound.getDeliveryId(), deliveryId)) {
+					continue;
+				}
+				throw new ServiceException(text("批次 " + batch.getBatchSn() + " 已绑定其他送货单"));
+			}
+			MesDeliveryNoteBatch row = new MesDeliveryNoteBatch();
+			row.setDeliveryId(deliveryId);
+			row.setBatchId(batch.getId());
+			row.setBatchSn(batch.getBatchSn());
+			mesDeliveryNoteBatchService.save(row);
+			bindNum++;
+		}
+		if (bindNum == 0) {
+			throw new ServiceException(text("所选成品批次已绑定当前送货单"));
+		}
+	}
+}

+ 196 - 0
src/main/java/com/jeesite/modules/mes/web/MesDeliveryNoteController.java

@@ -0,0 +1,196 @@
+package com.jeesite.modules.mes.web;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.jeesite.common.codec.EncodeUtils;
+import com.jeesite.common.config.Global;
+import com.jeesite.common.entity.Page;
+import com.jeesite.common.lang.StringUtils;
+import com.jeesite.common.mybatis.mapper.query.QueryType;
+import com.alibaba.fastjson.JSONValidator;
+import com.jeesite.common.service.ServiceException;
+import com.jeesite.common.web.BaseController;
+import com.jeesite.modules.mes.entity.MesDeliveryNote;
+import com.jeesite.modules.mes.entity.MesDeliveryNoteBatch;
+import com.jeesite.modules.mes.entity.MesProduct;
+import com.jeesite.modules.mes.entity.MesProductBatch;
+import com.jeesite.modules.mes.service.MesDeliveryNoteBatchService;
+import com.jeesite.modules.mes.service.MesDeliveryNoteService;
+import com.jeesite.modules.mes.service.MesProductBatchService;
+import com.jeesite.modules.mes.service.MesProductService;
+
+/**
+ * 送货单Controller
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/mes/mesDeliveryNote")
+public class MesDeliveryNoteController extends BaseController {
+
+	@Autowired
+	private MesDeliveryNoteService mesDeliveryNoteService;
+
+	@Autowired
+	private MesDeliveryNoteBatchService mesDeliveryNoteBatchService;
+
+	@Autowired
+	private MesProductBatchService mesProductBatchService;
+
+	@Autowired
+	private MesProductService mesProductService;
+
+	@ModelAttribute
+	public MesDeliveryNote get(String id, boolean isNewRecord) {
+		return mesDeliveryNoteService.get(id, isNewRecord);
+	}
+
+	@RequiresPermissions("mes:mesDeliveryNote:view")
+	@RequestMapping(value = {"list", ""})
+	public String list(MesDeliveryNote mesDeliveryNote, Model model) {
+		model.addAttribute("mesDeliveryNote", mesDeliveryNote);
+		return "modules/mes/mesDeliveryNoteList";
+	}
+
+	@RequiresPermissions("mes:mesDeliveryNote:view")
+	@RequestMapping(value = "listData")
+	@ResponseBody
+	public Page<MesDeliveryNote> listData(MesDeliveryNote mesDeliveryNote, HttpServletRequest request, HttpServletResponse response) {
+		mesDeliveryNote.setPage(new Page<>(request, response));
+		return mesDeliveryNoteService.findPage(mesDeliveryNote);
+	}
+
+	@RequiresPermissions("mes:mesDeliveryNote:view")
+	@RequestMapping(value = "form")
+	public String form(MesDeliveryNote mesDeliveryNote, Model model) {
+		model.addAttribute("mesDeliveryNote", mesDeliveryNote);
+		return "modules/mes/mesDeliveryNoteForm";
+	}
+
+	@RequiresPermissions("mes:mesDeliveryNote:edit")
+	@PostMapping(value = "save")
+	@ResponseBody
+	public String save(@Validated MesDeliveryNote mesDeliveryNote) {
+		try {
+			mesDeliveryNoteService.save(mesDeliveryNote);
+		} catch (ServiceException ex) {
+			return renderResult(Global.FALSE, ex.getMessage());
+		}
+		return renderResult(Global.TRUE, text("保存送货单成功!"));
+	}
+
+	@RequiresPermissions("mes:mesDeliveryNote:edit")
+	@RequestMapping(value = "delete")
+	@ResponseBody
+	public String delete(MesDeliveryNote mesDeliveryNote) {
+		try {
+			mesDeliveryNoteService.delete(mesDeliveryNote);
+		} catch (ServiceException ex) {
+			return renderResult(Global.FALSE, ex.getMessage());
+		}
+		return renderResult(Global.TRUE, text("删除送货单成功!"));
+	}
+
+	@RequiresPermissions("mes:mesDeliveryNote:view")
+	@RequestMapping(value = "bind")
+	public String bind(MesDeliveryNote mesDeliveryNote, Model model) {
+		model.addAttribute("mesDeliveryNote", mesDeliveryNote);
+		return "modules/mes/mesDeliveryNoteBind";
+	}
+
+	@RequiresPermissions("mes:mesDeliveryNote:view")
+	@RequestMapping(value = "bindListData")
+	@ResponseBody
+	public Page<MesDeliveryNoteBatch> bindListData(MesDeliveryNoteBatch mesDeliveryNoteBatch, HttpServletRequest request, HttpServletResponse response) {
+		mesDeliveryNoteBatch.setPage(new Page<>(request, response));
+		return mesDeliveryNoteBatchService.findPage(mesDeliveryNoteBatch);
+	}
+
+	@RequiresPermissions("mes:mesDeliveryNote:view")
+	@RequestMapping(value = "batchProducts")
+	public String batchProducts(String batchSn, Model model) {
+		model.addAttribute("batchSn", batchSn);
+		return "modules/mes/mesDeliveryNoteProducts";
+	}
+
+	@RequiresPermissions("mes:mesDeliveryNote:view")
+	@RequestMapping(value = "batchProductData")
+	@ResponseBody
+	public Page<MesProduct> batchProductData(MesProduct mesProduct, HttpServletRequest request, HttpServletResponse response) {
+		String batchSn = mesProduct.getBatchSn();
+		mesProduct.setBatchSn(null);
+		if (StringUtils.isBlank(batchSn)) {
+			mesProduct.getSqlMap().getWhere().and("id", QueryType.EQ, "-1");
+		} else {
+			mesProduct.getSqlMap().getWhere().and("batch_sn", QueryType.EQ, batchSn);
+		}
+		String sn = mesProduct.getSn();
+		if (StringUtils.isNotBlank(sn)) {
+			mesProduct.setSn(null);
+			mesProduct.getSqlMap().getWhere().and("sn", QueryType.LIKE, sn);
+		}
+		mesProduct.setPage(new Page<>(request, response));
+		return mesProductService.findPage(mesProduct);
+	}
+
+	@RequiresPermissions("mes:mesDeliveryNote:edit")
+	@PostMapping(value = "bindBatch")
+	@ResponseBody
+	public String bindBatch(String deliveryId, String batchIds) {
+		try {
+			mesDeliveryNoteService.bindBatches(deliveryId, batchIds);
+		} catch (ServiceException ex) {
+			return renderResult(Global.FALSE, ex.getMessage());
+		}
+		return renderResult(Global.TRUE, text("绑定成品批次成功!"));
+	}
+
+	@RequiresPermissions("mes:mesDeliveryNote:edit")
+	@RequestMapping(value = "unbindBatch")
+	@ResponseBody
+	public String unbindBatch(MesDeliveryNoteBatch mesDeliveryNoteBatch) {
+		mesDeliveryNoteBatchService.delete(mesDeliveryNoteBatch);
+		return renderResult(Global.TRUE, text("解除绑定成功!"));
+	}
+
+	@RequiresPermissions("mes:mesDeliveryNote:view")
+	@RequestMapping(value = "batchSelect")
+	public String batchSelect(MesProductBatch mesProductBatch, String selectData, Model model) {
+		String selectDataJson = EncodeUtils.decodeUrl(selectData);
+		if (selectDataJson != null && JSONValidator.from(selectDataJson).validate()) {
+			model.addAttribute("selectData", selectDataJson);
+		}
+		model.addAttribute("mesProductBatch", mesProductBatch);
+		return "modules/mes/mesProductBatchSelect";
+	}
+
+	@RequiresPermissions("mes:mesDeliveryNote:view")
+	@RequestMapping(value = "batchSelectData")
+	@ResponseBody
+	public Page<MesProductBatch> batchSelectData(MesProductBatch mesProductBatch, HttpServletRequest request, HttpServletResponse response) {
+		List<MesDeliveryNoteBatch> boundList = mesDeliveryNoteBatchService.findList(new MesDeliveryNoteBatch());
+		if (boundList != null && !boundList.isEmpty()) {
+			String[] boundIds = boundList.stream()
+					.map(MesDeliveryNoteBatch::getBatchId)
+					.filter(StringUtils::isNotBlank)
+					.distinct()
+					.toArray(String[]::new);
+			if (boundIds.length > 0) {
+				mesProductBatch.getSqlMap().getWhere().and("id", QueryType.NOT_IN, boundIds);
+			}
+		}
+		mesProductBatch.setPage(new Page<>(request, response));
+		return mesProductBatchService.findPage(mesProductBatch);
+	}
+}

+ 5 - 0
src/main/resources/mappings/modules/mes/MesDeliveryNoteBatchDao.xml

@@ -0,0 +1,5 @@
+<?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.jeesite.modules.mes.dao.MesDeliveryNoteBatchDao">
+
+</mapper>

+ 5 - 0
src/main/resources/mappings/modules/mes/MesDeliveryNoteDao.xml

@@ -0,0 +1,5 @@
+<?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.jeesite.modules.mes.dao.MesDeliveryNoteDao">
+
+</mapper>

+ 101 - 0
src/main/resources/views/modules/mes/mesDeliveryNoteBind.html

@@ -0,0 +1,101 @@
+<% layout('/layouts/default.html', {title: '绑定成品批次', libs: ['dataGrid']}){ %>
+<div class="main-content">
+	<div class="box box-main">
+		<div class="box-header">
+			<div class="box-title">
+				<i class="fa fa-link"></i> ${text('绑定成品批次')}(${mesDeliveryNote.sn})
+			</div>
+			<div class="box-tools pull-right">
+				<% if(hasPermi('mes:mesDeliveryNote:edit')){ %>
+					<a href="#" class="btn btn-default" id="btnBind" title="${text('绑定成品批次')}"><i class="fa fa-plus"></i> ${text('绑定成品批次')}</a>
+				<% } %>
+				<a href="javascript:" class="btn btn-default" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</a>
+			</div>
+		</div>
+		<div class="box-body">
+			<div class="form-unit">${text('送货单信息')}</div>
+			<table class="table table-bordered">
+				<tr>
+					<th class="mpc-header" style="width:120px;">${text('送货单号')}</th>
+					<td>${mesDeliveryNote.sn}</td>
+					<th class="mpc-header" style="width:120px;">${text('客户')}</th>
+					<td>${mesDeliveryNote.customer}</td>
+				</tr>
+				<tr>
+					<th class="mpc-header">${text('联系人')}</th>
+					<td>${mesDeliveryNote.contact}</td>
+					<th class="mpc-header">${text('电话')}</th>
+					<td>${mesDeliveryNote.phone}</td>
+				</tr>
+				<tr>
+					<th class="mpc-header">${text('送货地址')}</th>
+					<td>${mesDeliveryNote.address}</td>
+					<th class="mpc-header">${text('送货日期')}</th>
+					<td>${mesDeliveryNote.deliveryDate != null ? @DateUtils.formatDate(mesDeliveryNote.deliveryDate, "yyyy-MM-dd") : ""}</td>
+				</tr>
+			</table>
+			<div class="form-unit">${text('已绑定成品批次')}</div>
+			<#form:form id="searchForm" action="${ctx}/mes/mesDeliveryNote/bindListData" method="post" class="form-inline"
+					data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
+				<input type="hidden" name="deliveryId" value="${mesDeliveryNote.id}"/>
+				<div class="form-group">
+					<label class="control-label">${text('批次码')}:</label>
+					<div class="control-inline">
+						<input type="text" name="batchSn" maxlength="100" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
+					<button type="reset" class="btn btn-default btn-sm">${text('重置')}</button>
+				</div>
+			</#form:form>
+			<table id="dataGrid"></table>
+			<div id="dataGridPage"></div>
+		</div>
+	</div>
+</div>
+<div class="hide" style="display:none"><#form:listselect id="batchSelect" title="${text('选择成品批次')}"
+	url="${ctx}/mes/mesDeliveryNote/batchSelect" allowClear="false"
+	checkbox="true" itemCode="id" itemName="batchSn"/></div>
+<% } %>
+<script>
+$('#dataGrid').dataGrid({
+	searchForm: $("#searchForm"),
+	columnModel: [
+		{header:'${text("批次码")}', name:'batchSn', index:'a.batch_sn', width:220, align:"center", formatter: function(val, obj, row, act){
+			if (!val){
+				return '';
+			}
+			return '<a href="${ctx}/mes/mesDeliveryNote/batchProducts?batchSn='+encodeURIComponent(val)+'" class="btnList" data-title="${text("批次工件")}">'+val+'</a>';
+		}},
+		{header:'${text("绑定时间")}', name:'createDate', index:'a.create_date', width:160, align:"center"},
+		{header:'${text("操作")}', name:'actions', width:80, formatter: function(val, obj, row, act){
+			var actions = [];
+			//<% if(hasPermi('mes:mesDeliveryNote:edit')){ %>
+				actions.push('<a href="${ctx}/mes/mesDeliveryNote/unbindBatch?id='+row.id+'" class="btnList" title="${text("解除绑定")}" data-confirm="${text("确认要解除该成品批次的绑定吗?")}"><i class="fa fa-unlink"></i></a>&nbsp;');
+			//<% } %>
+			return actions.join('');
+		}}
+	]
+});
+$('#btnBind').click(function(){
+	$('#batchSelectCode').val('');
+	$('#batchSelectName').val('').click();
+});
+function listselectCallback(id, action, index, layero){
+	if (id == 'batchSelect' && action == 'ok'){
+		var ids = $('#batchSelectCode').val();
+		if (ids){
+			js.ajaxSubmit('${ctx}/mes/mesDeliveryNote/bindBatch', {
+				deliveryId: '${mesDeliveryNote.id}',
+				batchIds: ids
+			}, function(data){
+				js.showMessage(data.message);
+				page();
+			});
+		}else{
+			js.showMessage('${text("请选择成品批次")}');
+		}
+	}
+}
+</script>

+ 110 - 0
src/main/resources/views/modules/mes/mesDeliveryNoteForm.html

@@ -0,0 +1,110 @@
+<% layout('/layouts/default.html', {title: '送货单', libs: ['validate']}){ %>
+<div class="main-content">
+	<div class="box box-main">
+		<div class="box-header with-border">
+			<div class="box-title">
+				<i class="fa icon-note"></i> ${text(mesDeliveryNote.isNewRecord ? '新增送货单' : '编辑送货单')}
+			</div>
+			<div class="box-tools pull-right">
+				<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
+			</div>
+		</div>
+		<#form:form id="inputForm" model="${mesDeliveryNote}" action="${ctx}/mes/mesDeliveryNote/save" method="post" class="form-horizontal">
+			<div class="box-body">
+				<div class="form-unit">${text('基本信息')}</div>
+				<#form:hidden path="id"/>
+				<div class="row">
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required">*</span> ${text('送货单号')}:</label>
+							<div class="col-sm-8">
+								<#form:input path="sn" maxlength="64" class="form-control required"/>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('客户')}:</label>
+							<div class="col-sm-8">
+								<#form:input path="customer" maxlength="200" class="form-control"/>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('联系人')}:</label>
+							<div class="col-sm-8">
+								<#form:input path="contact" maxlength="100" class="form-control"/>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('电话')}:</label>
+							<div class="col-sm-8">
+								<#form:input path="phone" maxlength="50" class="form-control"/>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('送货地址')}:</label>
+							<div class="col-sm-8">
+								<#form:input path="address" maxlength="500" class="form-control"/>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('送货日期')}:</label>
+							<div class="col-sm-8">
+								<#form:input path="deliveryDate" readonly="true" maxlength="20" class="form-control laydate"
+									dataFormat="date" data-type="date" data-format="yyyy-MM-dd"/>
+							</div>
+						</div>
+					</div>
+					<div class="col-xs-6">
+						<div class="form-group">
+							<label class="control-label col-sm-4" title="">
+								<span class="required hide">*</span> ${text('备注')}:</label>
+							<div class="col-sm-8">
+								<#form:input path="remark" maxlength="500" class="form-control"/>
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+			<div class="box-footer">
+				<div class="row">
+					<div class="col-sm-offset-2 col-sm-10">
+						<% if (hasPermi('mes:mesDeliveryNote:edit')){ %>
+							<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>&nbsp;
+						<% } %>
+						<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
+					</div>
+				</div>
+			</div>
+		</#form:form>
+	</div>
+</div>
+<% } %>
+<script>
+$("#inputForm").validate({
+	submitHandler: function(form){
+		js.ajaxSubmitForm($(form), function(data){
+			js.showMessage(data.message);
+			if(data.result == Global.TRUE){
+				js.closeCurrentTabPage(function(contentWindow){
+					contentWindow.page();
+				});
+			}
+		}, "json");
+	}
+});
+</script>

+ 87 - 0
src/main/resources/views/modules/mes/mesDeliveryNoteList.html

@@ -0,0 +1,87 @@
+<% layout('/layouts/default.html', {title: '送货单记录', libs: ['dataGrid']}){ %>
+<div class="main-content">
+	<div class="box box-main">
+		<div class="box-header">
+			<div class="box-title">
+				<i class="fa icon-notebook"></i> ${text('送货单记录')}
+			</div>
+			<div class="box-tools pull-right">
+				<a href="#" class="btn btn-default" id="btnSearch" title="${text('查询')}"><i class="fa fa-filter"></i> ${text('查询')}</a>
+				<% if(hasPermi('mes:mesDeliveryNote:edit')){ %>
+					<a href="${ctx}/mes/mesDeliveryNote/form" class="btn btn-default btnTool" title="${text('新增送货单')}"><i class="fa fa-plus"></i> ${text('新增')}</a>
+				<% } %>
+				<a href="#" class="btn btn-default" id="btnSetting" title="${text('设置')}"><i class="fa fa-navicon"></i></a>
+			</div>
+		</div>
+		<div class="box-body">
+			<#form:form id="searchForm" model="${mesDeliveryNote}" action="${ctx}/mes/mesDeliveryNote/listData" method="post" class="form-inline hide"
+					data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
+				<div class="form-group">
+					<label class="control-label">${text('送货单号')}:</label>
+					<div class="control-inline">
+						<#form:input path="sn" maxlength="64" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('客户')}:</label>
+					<div class="control-inline">
+						<#form:input path="customer" maxlength="200" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('联系人')}:</label>
+					<div class="control-inline">
+						<#form:input path="contact" maxlength="100" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('送货日期')}:</label>
+					<div class="control-inline">
+						<#form:input path="deliveryDate_gte" readonly="true" maxlength="20" class="form-control laydate width-date"
+							dataFormat="date" data-type="date" data-format="yyyy-MM-dd" data-done="deliveryDate_lte.click()"/>
+						&nbsp;-&nbsp;
+						<#form:input path="deliveryDate_lte" readonly="true" maxlength="20" class="form-control laydate width-date"
+							dataFormat="date" data-type="date" data-format="yyyy-MM-dd"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
+					<button type="reset" class="btn btn-default btn-sm">${text('重置')}</button>
+				</div>
+			</#form:form>
+			<table id="dataGrid"></table>
+			<div id="dataGridPage"></div>
+		</div>
+	</div>
+</div>
+<% } %>
+<script>
+$('#dataGrid').dataGrid({
+	searchForm: $("#searchForm"),
+	columnModel: [
+		{header:'${text("送货单号")}', name:'sn', index:'a.sn', width:150, align:"center", frozen:true, formatter: function(val, obj, row, act){
+			return '<a href="${ctx}/mes/mesDeliveryNote/form?id='+row.id+'" class="btnList" data-title="${text("编辑送货单")}">'+(val||row.id)+'</a>';
+		}},
+		{header:'${text("客户")}', name:'customer', index:'a.customer', width:160, align:"center"},
+		{header:'${text("联系人")}', name:'contact', index:'a.contact', width:100, align:"center"},
+		{header:'${text("电话")}', name:'phone', index:'a.phone', width:120, align:"center"},
+		{header:'${text("送货地址")}', name:'address', index:'a.address', width:200, align:"left"},
+		{header:'${text("送货日期")}', name:'deliveryDate', index:'a.delivery_date', width:110, align:"center"},
+		{header:'${text("已绑批次")}', name:'batchCount', width:80, align:"center"},
+		{header:'${text("备注")}', name:'remark', index:'a.remark', width:160, align:"left"},
+		{header:'${text("创建时间")}', name:'createDate', index:'a.create_date', width:150, align:"center"},
+		{header:'${text("操作")}', name:'actions', width:140, formatter: function(val, obj, row, act){
+			var actions = [];
+			//<% if(hasPermi('mes:mesDeliveryNote:edit')){ %>
+				actions.push('<a href="${ctx}/mes/mesDeliveryNote/form?id='+row.id+'" class="btnList" title="${text("编辑送货单")}"><i class="fa fa-pencil"></i></a>&nbsp;');
+				actions.push('<a href="${ctx}/mes/mesDeliveryNote/bind?id='+row.id+'" class="btnList" title="${text("绑定成品批次")}"><i class="fa fa-link"></i></a>&nbsp;');
+				actions.push('<a href="${ctx}/mes/mesDeliveryNote/delete?id='+row.id+'" class="btnList" title="${text("删除送货单")}" data-confirm="${text("确认要删除该送货单吗?")}"><i class="fa fa-trash-o"></i></a>&nbsp;');
+			//<% } %>
+			return actions.join('');
+		}}
+	],
+	ajaxSuccess: function(data){
+
+	}
+});
+</script>

+ 47 - 0
src/main/resources/views/modules/mes/mesDeliveryNoteProducts.html

@@ -0,0 +1,47 @@
+<% layout('/layouts/default.html', {title: '批次工件', libs: ['dataGrid']}){ %>
+<div class="main-content">
+	<div class="box box-main">
+		<div class="box-header">
+			<div class="box-title">
+				<i class="fa icon-notebook"></i> ${text('批次工件')}(${batchSn})
+			</div>
+			<div class="box-tools pull-right">
+				<a href="javascript:" class="btn btn-default" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</a>
+			</div>
+		</div>
+		<div class="box-body">
+			<#form:form id="searchForm" action="${ctx}/mes/mesDeliveryNote/batchProductData" method="post" class="form-inline"
+					data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
+				<input type="hidden" name="batchSn" value="${batchSn}"/>
+				<div class="form-group">
+					<label class="control-label">${text('工件码')}:</label>
+					<div class="control-inline">
+						<input type="text" name="sn" maxlength="100" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
+					<button type="reset" class="btn btn-default btn-sm">${text('重置')}</button>
+				</div>
+			</#form:form>
+			<table id="dataGrid"></table>
+			<div id="dataGridPage"></div>
+		</div>
+	</div>
+</div>
+<% } %>
+<script>
+$('#dataGrid').dataGrid({
+	searchForm: $("#searchForm"),
+	columnModel: [
+		{header:'${text("工件码")}', name:'sn', index:'a.sn', width:260, align:"center"},
+		{header:'${text("类型")}', name:'cate', index:'a.cate', width:100, align:"center"},
+		{header:'${text("状态")}', name:'state', index:'a.state', width:100, align:"center", formatter: function(val, obj, row, act){
+			return js.getDictLabel(${@DictUtils.getDictListJson('mes_product_status')}, val, '${text("未知")}', true);
+		}},
+		{header:'${text("打包批号")}', name:'batchSn', index:'a.batch_sn', width:160, align:"center"},
+		{header:'${text("绑定人")}', name:'bindBy', index:'a.bind_by', width:100, align:"center"},
+		{header:'${text("绑定时间")}', name:'bindDate', index:'a.bind_date', width:160, align:"center"}
+	]
+});
+</script>

+ 115 - 0
src/main/resources/views/modules/mes/mesProductBatchSelect.html

@@ -0,0 +1,115 @@
+<% layout('/layouts/default.html', {title: '选择成品批次', libs: ['dataGrid']}){ %>
+<div class="main-content">
+	<div class="box box-main">
+		<div class="box-body">
+			<#form:form id="searchForm" model="${mesProductBatch}" action="${ctx}/mes/mesDeliveryNote/batchSelectData" method="post" class="form-inline"
+					data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
+				<div class="form-group">
+					<label class="control-label">${text('批次码')}:</label>
+					<div class="control-inline">
+						<#form:input path="batchSn" maxlength="100" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('备注')}:</label>
+					<div class="control-inline">
+						<#form:input path="remark" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
+					<button type="reset" class="btn btn-default btn-sm">${text('重置')}</button>
+				</div>
+			</#form:form>
+			<div class="row">
+				<div class="col-xs-10 pr10">
+					<table id="dataGrid"></table>
+					<div id="dataGridPage"></div>
+				</div>
+				<div class="col-xs-2 pl0">
+					<div id="selectData" class="tags-input"></div>
+				</div>
+			</div>
+		</div>
+	</div>
+</div>
+<% } %>
+<script>
+var selectData = ${isNotBlank(selectData!) ? selectData! : "{\}"},
+selectNum = 0, dataGrid = $('#dataGrid').dataGrid({
+	searchForm: $("#searchForm"),
+	columnModel: [
+		{header:'${text("批次码")}', name:'batchSn', index:'a.batch_sn', width:180, align:"left"},
+		{header:'${text("备注")}', name:'remark', index:'a.remark', width:180, align:"left"},
+		{header:'${text("创建时间")}', name:'createDate', index:'a.create_date', width:150, align:"center"},
+		{header:'行数据', name:'rowData', hidden:true, formatter: function(val, obj, row, act){
+			return JSON.stringify(row);
+		}}
+	],
+	autoGridHeight: function(){
+		var height = $(window).height() - $('#searchForm').height() - $('#dataGridPage').height() - 74;
+		$('.tags-input').height($('.ui-jqgrid').height() - 10);
+		return height;
+	},
+	showCheckbox: '${parameter.checkbox}' == 'true',
+	multiboxonly: false,
+	ajaxSuccess: function(data){
+		$.each(selectData, function(key, value){
+			dataGrid.dataGrid('setSelectRow', key);
+		});
+		initSelectTag();
+	},
+	onSelectRow: function(id, isSelect, event){
+		if ('${parameter.checkbox}' == 'true'){
+			if(isSelect){
+				selectData[id] = JSON.parse(dataGrid.dataGrid('getRowData', id).rowData);
+			}else{
+				delete selectData[id];
+			}
+		}else{
+			selectData = {};
+			selectData[id] = JSON.parse(dataGrid.dataGrid('getRowData', id).rowData);
+		}
+		initSelectTag();
+	},
+	onSelectAll: function(ids, isSelect){
+		if ('${parameter.checkbox}' == 'true'){
+			for (var i=0; i<ids.length; i++){
+				if(isSelect){
+					selectData[ids[i]] = JSON.parse(dataGrid.dataGrid('getRowData', ids[i]).rowData);
+				}else{
+					delete selectData[ids[i]];
+				}
+			}
+		}
+		initSelectTag();
+	},
+	ondblClickRow: function(id, rownum, colnum, event){
+		if ('${parameter.checkbox}' != 'true'){
+			js.layer.$('#' + window.name).closest('.layui-layer')
+				.find(".layui-layer-btn0").trigger("click");
+		}
+		initSelectTag();
+	}
+});
+function initSelectTag(){
+	selectNum = 0;
+	var html = [];
+	$.each(selectData, function(key, value){
+		selectNum ++;
+		html.push('<span class="tag" id="'+key+'_tags-input"><span>'+(value.batchSn||key)+' </span>'
+			+ '<a href="#" onclick="removeSelectTag(\''+key+'\');" title="${text("取消选择")}">x</a></span>');
+	});
+	html.unshift('<div class="title">${text("当前已选择 {0\} 项", "<span id=\"selectNum\">'+selectNum+'</span>")}:</div>');
+	$('#selectData').empty().append(html.join(''));
+}
+function removeSelectTag(key){
+	delete selectData[key];
+	dataGrid.dataGrid('resetSelection', key);
+	$('#selectNum').html(--selectNum);
+	$('#'+key+'_tags-input').remove();
+}
+function getSelectData(){
+	return selectData;
+}
+</script>