Prechádzať zdrojové kódy

销售订单工件绑定和装配订单绑定优化

sunxianglong 2 týždňov pred
rodič
commit
28b08e5624

+ 15 - 0
src/main/java/com/jeesite/modules/mes/dao/MesSaleSnDao.java

@@ -0,0 +1,15 @@
+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.MesSaleSn;
+
+/**
+ * 销售订单工件绑定DAO接口
+ * @author sxl
+ * @version 2026-10-14
+ */
+@MyBatisDao
+public interface MesSaleSnDao extends CrudDao<MesSaleSn> {
+	
+}

+ 10 - 0
src/main/java/com/jeesite/modules/mes/entity/MesProductSale.java

@@ -36,9 +36,19 @@ public class MesProductSale extends DataEntity<MesProductSale> {
 	private String cpCode;		// 成品号
 
 	private String saleQty;   //销售数量
+
+	private String bandQty; //已绑定数量
 	private String shState;		// 审核状态(1=审核后,2=弃审,3=删除)
 	private String mesState;		// mes完成情况(1=未扫码,2=已扫码)
 
+	public String getBandQty() {
+		return bandQty;
+	}
+
+	public void setBandQty(String bandQty) {
+		this.bandQty = bandQty;
+	}
+
 	public MesProductSale() {
 		this(null);
 	}

+ 63 - 0
src/main/java/com/jeesite/modules/mes/entity/MesSaleSn.java

@@ -0,0 +1,63 @@
+package com.jeesite.modules.mes.entity;
+
+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;
+import com.jeesite.common.utils.excel.annotation.ExcelField;
+import com.jeesite.common.utils.excel.annotation.ExcelField.Align;
+import com.jeesite.common.utils.excel.annotation.ExcelFields;
+
+/**
+ * 销售订单工件绑定Entity
+ * @author sxl
+ * @version 2026-10-14
+ */
+@Table(name="mes_sale_sn", alias="a", label="销售订单工件绑定信息", columns={
+		@Column(name="id", attrName="id", label="id", isPK=true),
+		@Column(name="sale_id", attrName="saleId", label="销售订单号"),
+		@Column(name="sn", attrName="sn", label="工件码"),
+		@Column(name="create_date", attrName="createDate", label="创建时间", isUpdate=false, isQuery=false, isUpdateForce=true),
+	}, orderBy="a.id DESC"
+)
+public class MesSaleSn extends DataEntity<MesSaleSn> {
+	
+	private static final long serialVersionUID = 1L;
+	private String saleId;		// 销售订单号
+	private String sn;		// 工件码
+
+	@ExcelFields({
+		@ExcelField(title="id", attrName="id", align=Align.CENTER, sort=10),
+		@ExcelField(title="销售订单号", attrName="saleId", align=Align.CENTER, sort=20),
+		@ExcelField(title="工件码", attrName="sn", align=Align.CENTER, sort=30),
+		@ExcelField(title="创建时间", attrName="createDate", align=Align.CENTER, sort=40),
+	})
+	public MesSaleSn() {
+		this(null);
+	}
+	
+	public MesSaleSn(String id){
+		super(id);
+	}
+	
+	@Size(min=0, max=64, message="销售订单号长度不能超过 64 个字符")
+	public String getSaleId() {
+		return saleId;
+	}
+
+	public void setSaleId(String saleId) {
+		this.saleId = saleId;
+	}
+	
+	@Size(min=0, max=64, message="工件码长度不能超过 64 个字符")
+	public String getSn() {
+		return sn;
+	}
+
+	public void setSn(String sn) {
+		this.sn = sn;
+	}
+	
+}

+ 137 - 0
src/main/java/com/jeesite/modules/mes/service/MesSaleSnService.java

@@ -0,0 +1,137 @@
+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.entity.MesSaleSn;
+import com.jeesite.modules.mes.dao.MesSaleSnDao;
+import com.jeesite.common.service.ServiceException;
+import com.jeesite.common.config.Global;
+import com.jeesite.common.validator.ValidatorUtils;
+import com.jeesite.common.utils.excel.ExcelImport;
+import org.springframework.web.multipart.MultipartFile;
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * 销售订单工件绑定Service
+ * @author sxl
+ * @version 2026-10-14
+ */
+@Service
+public class MesSaleSnService extends CrudService<MesSaleSnDao, MesSaleSn> {
+	
+	/**
+	 * 获取单条数据
+	 * @param mesSaleSn
+	 * @return
+	 */
+	@Override
+	public MesSaleSn get(MesSaleSn mesSaleSn) {
+		return super.get(mesSaleSn);
+	}
+	
+	/**
+	 * 查询分页数据
+	 * @param mesSaleSn 查询条件
+	 * @param mesSaleSn.page 分页对象
+	 * @return
+	 */
+	@Override
+	public Page<MesSaleSn> findPage(MesSaleSn mesSaleSn) {
+		return super.findPage(mesSaleSn);
+	}
+	
+	/**
+	 * 查询列表数据
+	 * @param mesSaleSn
+	 * @return
+	 */
+	@Override
+	public List<MesSaleSn> findList(MesSaleSn mesSaleSn) {
+		return super.findList(mesSaleSn);
+	}
+	
+	/**
+	 * 保存数据(插入或更新)
+	 * @param mesSaleSn
+	 */
+	@Override
+	@Transactional
+	public void save(MesSaleSn mesSaleSn) {
+		super.save(mesSaleSn);
+	}
+
+	/**
+	 * 导入数据
+	 * @param file 导入的数据文件
+	 */
+	@Transactional
+	public String importData(MultipartFile file) {
+		if (file == null){
+			throw new ServiceException(text("请选择导入的数据文件!"));
+		}
+		int successNum = 0; int failureNum = 0;
+		StringBuilder successMsg = new StringBuilder();
+		StringBuilder failureMsg = new StringBuilder();
+		try(ExcelImport ei = new ExcelImport(file, 2, 0)){
+			List<MesSaleSn> list = ei.getDataList(MesSaleSn.class);
+			for (MesSaleSn mesSaleSn : list) {
+				try{
+					ValidatorUtils.validateWithException(mesSaleSn);
+					this.save(mesSaleSn);
+					successNum++;
+					successMsg.append("<br/>" + successNum + "、编号 " + mesSaleSn.getId() + " 导入成功");
+				} catch (Exception e) {
+					failureNum++;
+					String msg = "<br/>" + failureNum + "、编号 " + mesSaleSn.getId() + " 导入失败:";
+					if (e instanceof ConstraintViolationException){
+						ConstraintViolationException cve = (ConstraintViolationException)e;
+						for (ConstraintViolation<?> violation : cve.getConstraintViolations()) {
+							msg += Global.getText(violation.getMessage()) + " ("+violation.getPropertyPath()+")";
+						}
+					}else{
+						msg += e.getMessage();
+					}
+					failureMsg.append(msg);
+					logger.error(msg, e);
+				}
+			}
+		} catch (Exception e) {
+			logger.error(e.getMessage(), e);
+			failureMsg.append(e.getMessage());
+			return failureMsg.toString();
+		}
+		if (failureNum > 0) {
+			failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
+			throw new ServiceException(failureMsg.toString());
+		}else{
+			successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
+		}
+		return successMsg.toString();
+	}
+	
+	/**
+	 * 更新状态
+	 * @param mesSaleSn
+	 */
+	@Override
+	@Transactional
+	public void updateStatus(MesSaleSn mesSaleSn) {
+		super.updateStatus(mesSaleSn);
+	}
+	
+	/**
+	 * 删除数据
+	 * @param mesSaleSn
+	 */
+	@Override
+	@Transactional
+	public void delete(MesSaleSn mesSaleSn) {
+		super.delete(mesSaleSn);
+	}
+	
+}

+ 6 - 0
src/main/java/com/jeesite/modules/mes/web/MesMaterialReportController.java

@@ -259,6 +259,7 @@ public class MesMaterialReportController extends BaseController {
 			return resp;
 		}
 		// 供应商代码,采购订单号,采购订单行号,erp编码,生产日期,生产批次,批次数量
+		String poNo = parts[1].trim();
 		String erpSn = parts[3];
 		String faDate = parts[4].trim();
 		String faNums = parts[6].trim();
@@ -268,6 +269,11 @@ public class MesMaterialReportController extends BaseController {
 			resp.setMessage("二维码规则不正确!");
 			return resp;
 		}
+		if (StringUtils.isEmpty(poNo) || !poNo.startsWith("LJR-PO")) {
+			resp.setResult(Global.FALSE);
+			resp.setMessage("采购订单号必须以LJR-PO开头!");
+			return resp;
+		}
         MesMaterial mesMaterial = new MesMaterial();
 		mesMaterial.setErpSn(erpSn);
 		MesMaterial material = mesMaterialService.findInfo(mesMaterial);

+ 11 - 30
src/main/java/com/jeesite/modules/mes/web/MesOrderSnZpController.java

@@ -12,17 +12,13 @@ import com.jeesite.common.lang.StringUtils;
 import com.jeesite.common.mybatis.mapper.query.QueryType;
 import com.jeesite.modules.erp.entity.MesProductOrder;
 import com.jeesite.modules.erp.service.MesProductOrderService;
-import com.jeesite.modules.mes.entity.MesLine;
 import com.jeesite.modules.mes.entity.MesProduct;
+import com.jeesite.modules.mes.entity.MesProductRecord;
 import com.jeesite.modules.mes.resp.CommonResp;
-import com.jeesite.modules.mes.service.MesLineService;
+import com.jeesite.modules.mes.service.MesProductRecordService;
 import com.jeesite.modules.mes.service.MesProductService;
-import com.jeesite.modules.sys.entity.User;
-import com.jeesite.modules.sys.utils.UserUtils;
-import com.jeesite.modules.utils.ErrorMsg;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.validation.annotation.Validated;
@@ -53,10 +49,7 @@ public class MesOrderSnZpController extends BaseController {
 	@Autowired
 	private MesProductService mesProductService;
 	@Autowired
-	private MesLineService mesLineService;
-	@Lazy
-	@Autowired
-	private MesProductRecordController mesProductRecordController;
+	private MesProductRecordService mesProductRecordService;
 
 	@ModelAttribute
 	public MesOrderSnZp get(String id, boolean isNewRecord) {
@@ -102,7 +95,7 @@ public class MesOrderSnZpController extends BaseController {
 	}
 
 	/**
-	 * 装配订单绑定工件码(OP400 工位质量校验通过后方可绑定)
+	 * 装配订单绑定工件码(OP400 工位结果为 OK 方可绑定)
 	 */
 	@RequestMapping(value = "bandSn")
 	@ResponseBody
@@ -121,26 +114,14 @@ public class MesOrderSnZpController extends BaseController {
 		if (productList == null || productList.isEmpty() || ObjectUtils.isEmpty(productList.get(0))) {
 			return renderResult(Global.FALSE, text("工件不存在!"));
 		}
-		MesProduct mesProduct = productList.get(0);
-		MesLine mesLine = new MesLine();
-		mesLine.setProductCate(mesProduct.getCate());
-		mesLine.setStatus("0");
-		MesLine lineInfo = mesLineService.findInfo(mesLine);
-		if (ObjectUtils.isEmpty(lineInfo) || StringUtils.isEmpty(lineInfo.getSn())) {
-			return renderResult(Global.FALSE, text("产线信息不存在!"));
-		}
-		String lineSn = lineInfo.getSn();
 
-		String userCode = "";
-		User user = UserUtils.getUser();
-		if (user != null && StringUtils.isNotEmpty(user.getUserCode())) {
-			userCode = user.getUserCode();
-		}
-		String ret = mesProductRecordController.checkQualityCommon("OP400", sn, lineSn, userCode);
-		String checkret = ret.substring(3, 5);
-		if (!"OK".equalsIgnoreCase(checkret) && !"NG".equalsIgnoreCase(checkret)) {
-			String lx = ret.substring(0, 3);
-			return renderResult(Global.FALSE, text(ErrorMsg.getErrorMsg(checkret, lx)));
+		MesProductRecord recordQuery = new MesProductRecord();
+		recordQuery.setSn(sn);
+		recordQuery.setOprno("OP400");
+		recordQuery.setCraft("100000");
+		MesProductRecord op400Record = mesProductRecordService.findInfo(recordQuery);
+		if (ObjectUtils.isEmpty(op400Record) || !"OK".equalsIgnoreCase(op400Record.getContent())) {
+			return renderResult(Global.FALSE, text("OP400工位结果不是OK,不允许绑定!"));
 		}
 
 		MesOrderSnZp query = new MesOrderSnZp();

+ 238 - 0
src/main/java/com/jeesite/modules/mes/web/MesSaleSnController.java

@@ -0,0 +1,238 @@
+package com.jeesite.modules.mes.web;
+
+import java.util.List;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.jeesite.common.lang.ObjectUtils;
+import com.jeesite.modules.mes.entity.MesProduct;
+import com.jeesite.modules.mes.entity.MesProductSale;
+import com.jeesite.modules.mes.service.MesProductSaleService;
+import com.jeesite.modules.mes.service.MesProductService;
+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.config.Global;
+import com.jeesite.common.collect.ListUtils;
+import com.jeesite.common.entity.Page;
+import com.jeesite.common.lang.DateUtils;
+import com.jeesite.common.lang.StringUtils;
+import com.jeesite.common.utils.excel.ExcelExport;
+import com.jeesite.common.utils.excel.annotation.ExcelField.Type;
+import org.springframework.web.multipart.MultipartFile;
+import com.jeesite.common.web.BaseController;
+import com.jeesite.modules.mes.entity.MesSaleSn;
+import com.jeesite.modules.mes.service.MesSaleSnService;
+
+/**
+ * 销售订单工件绑定Controller
+ * @author sxl
+ * @version 2026-10-14
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/mes/mesSaleSn")
+public class MesSaleSnController extends BaseController {
+
+	@Autowired
+	private MesSaleSnService mesSaleSnService;
+	@Autowired
+	private MesProductSaleService mesProductSaleService;
+	@Autowired
+	private MesProductService mesProductService;
+
+	/**
+	 * 获取数据
+	 */
+	@ModelAttribute
+	public MesSaleSn get(String id, boolean isNewRecord) {
+		return mesSaleSnService.get(id, isNewRecord);
+	}
+
+	/**
+	 * 查询列表
+	 */
+	@RequiresPermissions("mes:mesSaleSn:view")
+	@RequestMapping(value = {"list", ""})
+	public String list(MesSaleSn mesSaleSn, Model model) {
+		model.addAttribute("mesSaleSn", mesSaleSn);
+		return "modules/mes/mesSaleSnList";
+	}
+
+	/**
+	 * 查询列表数据
+	 */
+	@RequiresPermissions("mes:mesSaleSn:view")
+	@RequestMapping(value = "listData")
+	@ResponseBody
+	public Page<MesSaleSn> listData(MesSaleSn mesSaleSn, HttpServletRequest request, HttpServletResponse response) {
+		mesSaleSn.setPage(new Page<>(request, response));
+		Page<MesSaleSn> page = mesSaleSnService.findPage(mesSaleSn);
+		return page;
+	}
+
+	/**
+	 * 查看编辑表单
+	 */
+	@RequiresPermissions("mes:mesSaleSn:view")
+	@RequestMapping(value = "form")
+	public String form(MesSaleSn mesSaleSn, Model model) {
+		model.addAttribute("mesSaleSn", mesSaleSn);
+		return "modules/mes/mesSaleSnForm";
+	}
+
+	/**
+	 * 保存数据
+	 */
+	@RequiresPermissions("mes:mesSaleSn:edit")
+	@PostMapping(value = "save")
+	@ResponseBody
+	public String save(@Validated MesSaleSn mesSaleSn) {
+		mesSaleSnService.save(mesSaleSn);
+		return renderResult(Global.TRUE, text("保存销售订单工件绑定成功!"));
+	}
+
+	/**
+	 * 导出数据
+	 */
+	@RequiresPermissions("mes:mesSaleSn:view")
+	@RequestMapping(value = "exportData")
+	public void exportData(MesSaleSn mesSaleSn, HttpServletResponse response) {
+		List<MesSaleSn> list = mesSaleSnService.findList(mesSaleSn);
+		String fileName = "销售订单工件绑定" + DateUtils.getDate("yyyyMMddHHmmss") + ".xlsx";
+		try(ExcelExport ee = new ExcelExport("销售订单工件绑定", MesSaleSn.class)){
+			ee.setDataList(list).write(response, fileName);
+		}
+	}
+
+	/**
+	 * 下载模板
+	 */
+	@RequiresPermissions("mes:mesSaleSn:view")
+	@RequestMapping(value = "importTemplate")
+	public void importTemplate(HttpServletResponse response) {
+		MesSaleSn mesSaleSn = new MesSaleSn();
+		List<MesSaleSn> list = ListUtils.newArrayList(mesSaleSn);
+		String fileName = "销售订单工件绑定模板.xlsx";
+		try(ExcelExport ee = new ExcelExport("销售订单工件绑定", MesSaleSn.class, Type.IMPORT)){
+			ee.setDataList(list).write(response, fileName);
+		}
+	}
+
+	/**
+	 * 导入数据
+	 */
+	@ResponseBody
+	@RequiresPermissions("mes:mesSaleSn:edit")
+	@PostMapping(value = "importData")
+	public String importData(MultipartFile file) {
+		try {
+			String message = mesSaleSnService.importData(file);
+			return renderResult(Global.TRUE, "posfull:"+message);
+		} catch (Exception ex) {
+			return renderResult(Global.FALSE, "posfull:"+ex.getMessage());
+		}
+	}
+
+	/**
+	 * 删除数据
+	 */
+	@RequiresPermissions("mes:mesSaleSn:edit")
+	@RequestMapping(value = "delete")
+	@ResponseBody
+	public String delete(MesSaleSn mesSaleSn) {
+		mesSaleSnService.delete(mesSaleSn);
+		return renderResult(Global.TRUE, text("删除销售订单工件绑定成功!"));
+	}
+
+
+	@RequestMapping(value = "findSaleList")
+	@ResponseBody
+	public String findSaleList() {
+		MesProductSale query = new MesProductSale();
+		query.setShState("1");
+		List<MesProductSale> list = mesProductSaleService.findList(query);
+		if (list != null) {
+			for (MesProductSale sale : list) {
+				MesSaleSn boundQuery = new MesSaleSn();
+				boundQuery.setSaleId(sale.getSaleOrder());
+				long bandQty = mesSaleSnService.findCount(boundQuery);
+				sale.setBandQty(String.valueOf(bandQty));
+			}
+		}
+		return renderResult(Global.TRUE, text("查询成功!"), list);
+	}
+
+	/**
+	 * 销售订单绑定工件码(同一工件码只能绑定一次;已绑定数不能大于销售数量)
+	 */
+	@RequestMapping(value = "bandSaleSn")
+	@ResponseBody
+	public String bandSaleSn(String saleId, String sn) {
+		if (StringUtils.isBlank(saleId)) {
+			return renderResult(Global.FALSE, text("销售订单号不能为空!"));
+		}
+		if (StringUtils.isBlank(sn)) {
+			return renderResult(Global.FALSE, text("工件码不能为空!"));
+		}
+		saleId = saleId.trim();
+		sn = sn.trim();
+
+		MesProduct mesProductQuery = new MesProduct();
+		mesProductQuery.setSn(sn);
+		List<MesProduct> productList = mesProductService.findList(mesProductQuery);
+		if (productList == null || productList.isEmpty() || ObjectUtils.isEmpty(productList.get(0))) {
+			return renderResult(Global.FALSE, text("工件不存在!"));
+		}
+
+		MesSaleSn existQuery = new MesSaleSn();
+		existQuery.setSn(sn);
+		if (mesSaleSnService.findCount(existQuery) > 0) {
+			return renderResult(Global.FALSE, text("该工件码已绑定销售订单,不允许重复绑定!"));
+		}
+
+		MesProductSale saleQuery = new MesProductSale();
+		saleQuery.setSaleOrder(saleId);
+		saleQuery.setShState("1");
+		List<MesProductSale> saleList = mesProductSaleService.findList(saleQuery);
+		if (saleList == null || saleList.isEmpty()) {
+			return renderResult(Global.FALSE, text("销售订单不存在!"));
+		}
+		long saleQtyTotal = 0;
+		for (MesProductSale sale : saleList) {
+			if (StringUtils.isBlank(sale.getSaleQty())) {
+				continue;
+			}
+			try {
+				saleQtyTotal += (long) Double.parseDouble(sale.getSaleQty().trim());
+			} catch (NumberFormatException e) {
+				return renderResult(Global.FALSE, text("销售数量格式不正确!"));
+			}
+		}
+		if (saleQtyTotal <= 0) {
+			return renderResult(Global.FALSE, text("销售数量未配置!"));
+		}
+		MesSaleSn boundQuery = new MesSaleSn();
+		boundQuery.setSaleId(saleId);
+		long boundCount = mesSaleSnService.findCount(boundQuery);
+		if (boundCount >= saleQtyTotal) {
+			return renderResult(Global.FALSE, text("该订单已绑定数量已达销售数量,不允许再绑定!"));
+		}
+
+		MesSaleSn mesSaleSn = new MesSaleSn();
+		mesSaleSn.setSaleId(saleId);
+		mesSaleSn.setSn(sn);
+		mesSaleSnService.save(mesSaleSn);
+		return renderResult(Global.TRUE, text("绑定成功!"));
+	}
+
+
+
+
+}

+ 15 - 0
src/main/resources/mappings/modules/mes/MesSaleSnDao.xml

@@ -0,0 +1,15 @@
+<?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.MesSaleSnDao">
+	
+	<!-- 查询数据
+	<select id="findList" resultType="MesSaleSn">
+		SELECT ${sqlMap.column.toSql()}
+		FROM ${sqlMap.table.toSql()}
+		<where>
+			${sqlMap.where.toSql()}
+		</where>
+		ORDER BY ${sqlMap.order.toSql()}
+	</select> -->
+	
+</mapper>

+ 66 - 0
src/main/resources/views/modules/mes/mesSaleSnForm.html

@@ -0,0 +1,66 @@
+<% 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(mesSaleSn.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="${mesSaleSn}" action="${ctx}/mes/mesSaleSn/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-12">
+						<div class="form-group">
+							<label class="control-label col-sm-2" title="">
+								<span class="required hide">*</span> ${text('销售订单号')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-4">
+								<#form:input path="saleId" maxlength="64" class="form-control"/>
+							</div>
+						</div>
+					</div>
+				</div>
+				<div class="row">
+					<div class="col-xs-12">
+						<div class="form-group">
+							<label class="control-label col-sm-2" title="">
+								<span class="required hide">*</span> ${text('工件码')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-4">
+								<#form:input path="sn" maxlength="64" 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:mesSaleSn: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>

+ 120 - 0
src/main/resources/views/modules/mes/mesSaleSnList.html

@@ -0,0 +1,120 @@
+<% 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>
+				<a href="#" class="btn btn-default" id="btnExport"><i class="glyphicon glyphicon-export"></i> 导出</a>
+				<% if(hasPermi('mes:mesSaleSn:edit')){ %>
+						<a href="#" class="btn btn-default" id="btnImport"><i class="glyphicon glyphicon-import"></i> 导入</a>
+					<a href="${ctx}/mes/mesSaleSn/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="${mesSaleSn}" action="${ctx}/mes/mesSaleSn/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="saleId" 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="sn" maxlength="64" 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').dataGrid({
+	searchForm: $("#searchForm"),
+	columnModel: [
+		{header:'${text("销售订单号")}', name:'saleId', index:'a.sale_id', width:150, align:"left", frozen:true, formatter: function(val, obj, row, act){
+			return '<a href="${ctx}/mes/mesSaleSn/form?id='+row.id+'" class="btnList" data-title="${text("编辑销售订单工件绑定")}">'+(val||row.id)+'</a>';
+		}},
+		{header:'${text("工件码")}', name:'sn', index:'a.sn', width:150, align:"left"},
+		{header:'${text("操作")}', name:'actions', width:120, formatter: function(val, obj, row, act){
+			var actions = [];
+			//<% if(hasPermi('mes:mesSaleSn:edit')){ %>
+				actions.push('<a href="${ctx}/mes/mesSaleSn/form?id='+row.id+'" class="btnList" title="${text("编辑销售订单工件绑定")}"><i class="fa fa-pencil"></i></a>&nbsp;');
+				actions.push('<a href="${ctx}/mes/mesSaleSn/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><script>
+$('#btnExport').click(function(){
+	js.ajaxSubmitForm($('#searchForm'), {
+		url:'${ctx}/mes/mesSaleSn/exportData',
+		downloadFile:true
+	});
+});
+$('#btnImport').click(function(){
+	js.layer.open({
+		type: 1,
+		area: ['400px'],
+		title: '${text("导入销售订单工件绑定")}',
+		resize: false,
+		scrollbar: true,
+		content: js.template('importTpl'),
+		btn: ['<i class="fa fa-check"></i> ${text("导入")}',
+			'<i class="fa fa-remove"></i> ${text("关闭")}'],
+		btn1: function(index, layero){
+			var form = {
+				inputForm: layero.find('#inputForm'),
+				file: layero.find('#file').val()
+			};
+		    if (form.file == '' || (!js.endWith(form.file, '.xls') && !js.endWith(form.file, '.xlsx'))){
+		    	js.showMessage("${text('文件不正确,请选择后缀为“xls”或“xlsx”的文件。')}", null, 'warning');
+		        return false;
+		    }
+			js.ajaxSubmitForm(form.inputForm, function(data){
+				js.showMessage(data.message);
+				if(data.result == Global.TRUE){
+					js.layer.closeAll();
+				}
+				page();
+			}, "json");
+			return true;
+		}
+	});
+});
+</script>
+<script id="importTpl" type="text/template">//<!--
+<form id="inputForm" action="${ctx}/mes/mesSaleSn/importData" method="post" enctype="multipart/form-data"
+	class="form-horizontal mt20 mb10" style="overflow:auto;max-height:200px;">
+	<div class="row">
+		<div class="col-xs-12 col-xs-offset-1">
+			<input type="file" id="file" name="file" class="form-file"/>
+			<div class="mt10 pt5" style="color:red">
+				${text('提示:仅允许导入“xls”或“xlsx”格式文件!')}
+			</div>
+			<div class="mt10 pt5">
+				<a href="${ctx}/mes/mesSaleSn/importTemplate" class="btn btn-default btn-xs"><i class="fa fa-file-excel-o"></i> ${text('下载模板')}</a>
+			</div>
+		</div>
+	</div>
+</form>
+//--></script>