Browse Source

Merge branch 'master' of http://121.36.46.135:3000/mes-ljz/mescloud

sunxianglong 5 tháng trước cách đây
mục cha
commit
3665615232

+ 113 - 0
src/main/java/com/jeesite/modules/mes/api/MesProductRecordControllerApi.java

@@ -0,0 +1,113 @@
+package com.jeesite.modules.mes.api;
+
+import com.jeesite.common.config.Global;
+import com.jeesite.common.lang.StringUtils;
+import com.jeesite.modules.mes.entity.MesLine;
+import com.jeesite.modules.mes.entity.MesLineProcess;
+import com.jeesite.modules.mes.entity.MesProductRecord;
+import com.jeesite.modules.mes.resp.CommonResp;
+import com.jeesite.modules.mes.resp.ParamsResp;
+import com.jeesite.modules.mes.service.MesLineProcessService;
+import com.jeesite.modules.mes.service.MesLineService;
+import com.jeesite.modules.mes.service.MesProductCateService;
+import com.jeesite.modules.mes.service.MesProductRecordService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.util.ObjectUtils;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Author: zh
+ * @Date: 2026/5/9 下午1:34
+ * @Description: com.jeesite.modules.mes.api
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/mes/mesProductRecordApi")
+public class MesProductRecordControllerApi {
+    @Autowired
+    private MesLineService mesLineService;
+
+    @Autowired
+    private MesProductRecordService mesProductRecordService;
+
+    @Autowired
+    private MesProductCateService mesProductCateService;
+
+    @Autowired
+    private MesLineProcessService mesLineProcessService;
+
+
+
+    //半成品/成品生成订单模板(可能要加拍照功能)
+    @PostMapping(value = "createProduct")
+    @ResponseBody
+    public CommonResp save(@Validated MesProductRecord mesProductRecord, HttpServletRequest request) {
+        CommonResp<String> resp = new CommonResp<>();
+
+        if(mesProductRecord.getIsNewRecord() && mesProductRecord.getLineSn().isEmpty()){ // 新增
+                resp.setResult(Global.FALSE);
+                resp.setMessage("产线编号不能为空!");
+                return resp;
+        }
+
+        List<ParamsResp> params = new ArrayList<>();
+
+        MesLine ml = new MesLine();
+        ml.setSn(mesProductRecord.getLineSn());
+        ml.setStatus("0");
+        MesLine mesLine = mesLineService.findInfo(ml);
+        if(ObjectUtils.isEmpty(mesLine)){
+            resp.setResult(Global.FALSE);
+            resp.setMessage("产线编号不正确!");
+            return resp;
+        }
+        String cateSn = mesLine.getProductCate();
+        MesProductRecord mpr = mesProductRecordService.findBySnCate(mesProductRecord.getSn(),cateSn);
+        if(!ObjectUtils.isEmpty(mpr)){
+            resp.setResult(Global.FALSE);
+            resp.setMessage("产品编号重复!");
+            return resp;
+        }
+
+        // 检验工件码
+        if(!mesProductCateService.checkSn(mesProductRecord.getSn())){
+
+            resp.setResult(Global.FALSE);
+            resp.setMessage("工件码格式不正确!");
+            return resp;
+        }
+
+        // 获取上线工位
+        MesLineProcess mesLineProcess1 = mesLineProcessService.getOnLineOprno(mesLine.getSn());
+        if(ObjectUtils.isEmpty(mesLineProcess1)){
+            resp.setResult(Global.FALSE);
+            resp.setMessage("未配置上线工位!");
+            return resp;
+        }
+        try{
+            mesProductRecord.setOprno(mesLineProcess1.getOprno());
+            mesProductRecord.setLineSn(mesLineProcess1.getLineSn());
+            mesProductRecord.setCateSn(cateSn);
+
+            mesProductRecordService.add(mesProductRecord,params,null);
+
+        }catch (Exception e){
+            e.printStackTrace();
+            resp.setResult(Global.FALSE);
+            resp.setMessage("操作失败!");
+            return resp;
+        }
+        resp.setResult(Global.TRUE);
+        resp.setMessage("操作成功!");
+        return resp;
+    }
+
+
+}

+ 15 - 0
src/main/java/com/jeesite/modules/mes/dao/MesInboundDao.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.MesInbound;
+
+/**
+ * 入库表DAO接口
+ * @author system
+ * @version 2026-05-09
+ */
+@MyBatisDao
+public interface MesInboundDao extends CrudDao<MesInbound> {
+	
+}

+ 100 - 0
src/main/java/com/jeesite/modules/mes/entity/MesInbound.java

@@ -0,0 +1,100 @@
+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 system
+ * @version 2026-05-09
+ */
+@Table(name="mes_inbound", alias="a", label="入库表信息", columns={
+		@Column(name="id", attrName="id", label="id", isPK=true),
+		@Column(name="sn", attrName="sn", label="工件码"),
+		@Column(name="product_order", attrName="productOrder", label="生产订单编号"),
+		@Column(name="storage_location", attrName="storageLocation", label="仓位"),
+		@Column(name="line_sn", attrName="lineSn", label="产线编码"),
+		@Column(name="remark", attrName="remark", label="备注"),
+		@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 MesInbound extends DataEntity<MesInbound> {
+	
+	private static final long serialVersionUID = 1L;
+	private String sn;		// 工件码
+	private String productOrder;		// 生产订单编号
+	private String storageLocation;		// 仓位
+	private String lineSn;		// 产线编码
+	private String remark;		// 备注
+
+	@ExcelFields({
+		@ExcelField(title="工件码", attrName="sn", align=Align.CENTER, sort=20),
+		@ExcelField(title="生产订单编号", attrName="productOrder", align=Align.CENTER, sort=30),
+		@ExcelField(title="仓位", attrName="storageLocation", align=Align.CENTER, sort=40),
+		@ExcelField(title="产线编码", attrName="lineSn", align=Align.CENTER, sort=50),
+		@ExcelField(title="备注", attrName="remark", align=Align.CENTER, sort=60),
+	})
+	public MesInbound() {
+		this(null);
+	}
+	
+	public MesInbound(String id){
+		super(id);
+	}
+	
+	@Size(min=0, max=255, message="工件码长度不能超过 255 个字符")
+	public String getSn() {
+		return sn;
+	}
+
+	public void setSn(String sn) {
+		this.sn = sn;
+	}
+	
+	@Size(min=0, max=255, message="生产订单编号长度不能超过 255 个字符")
+	public String getProductOrder() {
+		return productOrder;
+	}
+
+	public void setProductOrder(String productOrder) {
+		this.productOrder = productOrder;
+	}
+	
+	@Size(min=0, max=255, message="仓位长度不能超过 255 个字符")
+	public String getStorageLocation() {
+		return storageLocation;
+	}
+
+	public void setStorageLocation(String storageLocation) {
+		this.storageLocation = storageLocation;
+	}
+	
+	@Size(min=0, max=255, message="产线编码长度不能超过 255 个字符")
+	public String getLineSn() {
+		return lineSn;
+	}
+
+	public void setLineSn(String lineSn) {
+		this.lineSn = lineSn;
+	}
+	
+	@Size(min=0, max=255, message="备注长度不能超过 255 个字符")
+	public String getRemark() {
+		return remark;
+	}
+
+	public void setRemark(String remark) {
+		this.remark = remark;
+	}
+	
+}

+ 137 - 0
src/main/java/com/jeesite/modules/mes/service/MesInboundService.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.MesInbound;
+import com.jeesite.modules.mes.dao.MesInboundDao;
+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 system
+ * @version 2026-05-09
+ */
+@Service
+public class MesInboundService extends CrudService<MesInboundDao, MesInbound> {
+	
+	/**
+	 * 获取单条数据
+	 * @param mesInbound
+	 * @return
+	 */
+	@Override
+	public MesInbound get(MesInbound mesInbound) {
+		return super.get(mesInbound);
+	}
+	
+	/**
+	 * 查询分页数据
+	 * @param mesInbound 查询条件
+	 * @param mesInbound.page 分页对象
+	 * @return
+	 */
+	@Override
+	public Page<MesInbound> findPage(MesInbound mesInbound) {
+		return super.findPage(mesInbound);
+	}
+	
+	/**
+	 * 查询列表数据
+	 * @param mesInbound
+	 * @return
+	 */
+	@Override
+	public List<MesInbound> findList(MesInbound mesInbound) {
+		return super.findList(mesInbound);
+	}
+	
+	/**
+	 * 保存数据(插入或更新)
+	 * @param mesInbound
+	 */
+	@Override
+	@Transactional
+	public void save(MesInbound mesInbound) {
+		super.save(mesInbound);
+	}
+
+	/**
+	 * 导入数据
+	 * @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<MesInbound> list = ei.getDataList(MesInbound.class);
+			for (MesInbound mesInbound : list) {
+				try{
+					ValidatorUtils.validateWithException(mesInbound);
+					this.save(mesInbound);
+					successNum++;
+					successMsg.append("<br/>" + successNum + "、编号 " + mesInbound.getId() + " 导入成功");
+				} catch (Exception e) {
+					failureNum++;
+					String msg = "<br/>" + failureNum + "、编号 " + mesInbound.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 mesInbound
+	 */
+	@Override
+	@Transactional
+	public void updateStatus(MesInbound mesInbound) {
+		super.updateStatus(mesInbound);
+	}
+	
+	/**
+	 * 删除数据
+	 * @param mesInbound
+	 */
+	@Override
+	@Transactional
+	public void delete(MesInbound mesInbound) {
+		super.delete(mesInbound);
+	}
+	
+}

+ 144 - 0
src/main/java/com/jeesite/modules/mes/web/MesInboundController.java

@@ -0,0 +1,144 @@
+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.config.Global;
+import com.jeesite.common.collect.ListUtils;
+import com.jeesite.common.entity.Page;
+import com.jeesite.common.lang.DateUtils;
+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.MesInbound;
+import com.jeesite.modules.mes.service.MesInboundService;
+
+/**
+ * 入库表Controller
+ * @author system
+ * @version 2026-05-09
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/mes/mesInbound")
+public class MesInboundController extends BaseController {
+
+	@Autowired
+	private MesInboundService mesInboundService;
+	
+	/**
+	 * 获取数据
+	 */
+	@ModelAttribute
+	public MesInbound get(String id, boolean isNewRecord) {
+		return mesInboundService.get(id, isNewRecord);
+	}
+	
+	/**
+	 * 查询列表
+	 */
+	@RequiresPermissions("mes:mesInbound:view")
+	@RequestMapping(value = {"list", ""})
+	public String list(MesInbound mesInbound, Model model) {
+		model.addAttribute("mesInbound", mesInbound);
+		return "modules/mes/mesInboundList";
+	}
+	
+	/**
+	 * 查询列表数据
+	 */
+	@RequiresPermissions("mes:mesInbound:view")
+	@RequestMapping(value = "listData")
+	@ResponseBody
+	public Page<MesInbound> listData(MesInbound mesInbound, HttpServletRequest request, HttpServletResponse response) {
+		mesInbound.setPage(new Page<>(request, response));
+		Page<MesInbound> page = mesInboundService.findPage(mesInbound);
+		return page;
+	}
+
+	/**
+	 * 查看编辑表单
+	 */
+	@RequiresPermissions("mes:mesInbound:view")
+	@RequestMapping(value = "form")
+	public String form(MesInbound mesInbound, Model model) {
+		model.addAttribute("mesInbound", mesInbound);
+		return "modules/mes/mesInboundForm";
+	}
+
+	/**
+	 * 保存数据
+	 */
+	@RequiresPermissions("mes:mesInbound:edit")
+	@PostMapping(value = "save")
+	@ResponseBody
+	public String save(@Validated MesInbound mesInbound) {
+		mesInboundService.save(mesInbound);
+		return renderResult(Global.TRUE, text("保存入库表成功!"));
+	}
+
+	/**
+	 * 导出数据
+	 */
+	@RequiresPermissions("mes:mesInbound:view")
+	@RequestMapping(value = "exportData")
+	public void exportData(MesInbound mesInbound, HttpServletResponse response) {
+		List<MesInbound> list = mesInboundService.findList(mesInbound);
+		String fileName = "入库表" + DateUtils.getDate("yyyyMMddHHmmss") + ".xlsx";
+		try(ExcelExport ee = new ExcelExport("入库表", MesInbound.class)){
+			ee.setDataList(list).write(response, fileName);
+		}
+	}
+
+	/**
+	 * 下载模板
+	 */
+	@RequiresPermissions("mes:mesInbound:view")
+	@RequestMapping(value = "importTemplate")
+	public void importTemplate(HttpServletResponse response) {
+		MesInbound mesInbound = new MesInbound();
+		List<MesInbound> list = ListUtils.newArrayList(mesInbound);
+		String fileName = "入库表模板.xlsx";
+		try(ExcelExport ee = new ExcelExport("入库表", MesInbound.class, Type.IMPORT)){
+			ee.setDataList(list).write(response, fileName);
+		}
+	}
+
+	/**
+	 * 导入数据
+	 */
+	@ResponseBody
+	@RequiresPermissions("mes:mesInbound:edit")
+	@PostMapping(value = "importData")
+	public String importData(MultipartFile file) {
+		try {
+			String message = mesInboundService.importData(file);
+			return renderResult(Global.TRUE, "posfull:"+message);
+		} catch (Exception ex) {
+			return renderResult(Global.FALSE, "posfull:"+ex.getMessage());
+		}
+	}
+	
+	/**
+	 * 删除数据
+	 */
+	@RequiresPermissions("mes:mesInbound:edit")
+	@RequestMapping(value = "delete")
+	@ResponseBody
+	public String delete(MesInbound mesInbound) {
+		mesInboundService.delete(mesInbound);
+		return renderResult(Global.TRUE, text("删除入库表成功!"));
+	}
+	
+}

+ 15 - 0
src/main/resources/mappings/modules/mes/MesInboundDao.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.MesInboundDao">
+	
+	<!-- 查询数据
+	<select id="findList" resultType="MesInbound">
+		SELECT ${sqlMap.column.toSql()}
+		FROM ${sqlMap.table.toSql()}
+		<where>
+			${sqlMap.where.toSql()}
+		</where>
+		ORDER BY ${sqlMap.order.toSql()}
+	</select> -->
+	
+</mapper>

BIN
src/main/resources/static/screen/imgs/background.png


BIN
src/main/resources/static/screen/imgs/logo.png


+ 1 - 1
src/main/resources/views/include/sysIndex/topMenuCorp.html

@@ -24,5 +24,5 @@
 	</script>
 </li>
 <% }else if(__info_type == '0'){ %>
-<li><a href="#"><i class="fa fa-diamond"></i> 金巨石</a></li>
+<li><a href="#"><i class="fa fa-diamond"></i> 鲁匠人</a></li>
 <% } %>

+ 91 - 0
src/main/resources/views/modules/mes/mesInboundForm.html

@@ -0,0 +1,91 @@
+<% 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(mesInbound.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="${mesInbound}" action="${ctx}/mes/mesInbound/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 hide">*</span> ${text('工件码')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="sn" maxlength="255" 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('生产订单编号')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="productOrder" maxlength="255" 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('仓位')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="storageLocation" maxlength="255" 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('产线编码')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="lineSn" maxlength="255" 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('备注')}:<i class="fa icon-question hide"></i></label>
+							<div class="col-sm-8">
+								<#form:input path="remark" maxlength="255" 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:mesInbound: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>

+ 142 - 0
src/main/resources/views/modules/mes/mesInboundList.html

@@ -0,0 +1,142 @@
+<% 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:mesInbound:edit')){ %>
+						<a href="#" class="btn btn-default" id="btnImport"><i class="glyphicon glyphicon-import"></i> 导入</a>
+					<a href="${ctx}/mes/mesInbound/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="${mesInbound}" action="${ctx}/mes/mesInbound/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="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('生产订单编号')}:</label>
+					<div class="control-inline">
+						<#form:input path="productOrder" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('仓位')}:</label>
+					<div class="control-inline">
+						<#form:input path="storageLocation" maxlength="255" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('产线编码')}:</label>
+					<div class="control-inline">
+						<#form:input path="lineSn" maxlength="255" 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>
+			<table id="dataGrid"></table>
+			<div id="dataGridPage"></div>
+		</div>
+	</div>
+</div>
+<% } %>
+<script>
+// 初始化DataGrid对象
+$('#dataGrid').dataGrid({
+	searchForm: $("#searchForm"),
+	columnModel: [
+		{header:'${text("工件码")}', name:'sn', index:'a.sn', width:150, align:"left", frozen:true, formatter: function(val, obj, row, act){
+			return '<a href="${ctx}/mes/mesInbound/form?id='+row.id+'" class="btnList" data-title="${text("编辑入库表")}">'+(val||row.id)+'</a>';
+		}},
+		{header:'${text("生产订单编号")}', name:'productOrder', index:'a.product_order', width:150, align:"left"},
+		{header:'${text("仓位")}', name:'storageLocation', index:'a.storage_location', width:150, align:"left"},
+		{header:'${text("产线编码")}', name:'lineSn', index:'a.line_sn', width:150, align:"left"},
+		{header:'${text("备注")}', name:'remark', index:'a.remark', width:150, align:"left"},
+		{header:'${text("更新时间")}', name:'updateDate', index:'a.update_date', width:150, align:"center"},
+		{header:'${text("操作")}', name:'actions', width:120, formatter: function(val, obj, row, act){
+			var actions = [];
+			//<% if(hasPermi('mes:mesInbound:edit')){ %>
+				actions.push('<a href="${ctx}/mes/mesInbound/form?id='+row.id+'" class="btnList" title="${text("编辑入库表")}"><i class="fa fa-pencil"></i></a>&nbsp;');
+				actions.push('<a href="${ctx}/mes/mesInbound/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/mesInbound/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/mesInbound/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/mesInbound/importTemplate" class="btn btn-default btn-xs"><i class="fa fa-file-excel-o"></i> ${text('下载模板')}</a>
+			</div>
+		</div>
+	</div>
+</form>
+//--></script>

+ 1 - 1
src/main/resources/views/themes/default/modules/sys/sysIndex/topMenuCorp.html

@@ -24,5 +24,5 @@
 	</script>
 </li>
 <% }else if(__info_type == '0'){ %>
-<li><a href="#"><i class="fa fa-diamond"></i> 金巨石</a></li>
+<li><a href="#"><i class="fa fa-diamond"></i> 鲁匠人</a></li>
 <% } %>

+ 198 - 106
src/main/resources/views/themes/default/modules/sys/sysLogin.html

@@ -1,119 +1,211 @@
-<% layout('/layouts/default.html', {title: '登录', libs: ['validate'], bodyClass: 'login-page'}){ %>
+<% layout('/layouts/default.html', {title: '登录', libs: ['validate'], bodyClass: 'login-page mes-login-page'}){ %>
 <% include('/include/upgrade.html'){} // 如果客户浏览器版本过低,则显示浏览器升级提示。 %>
-<!-- <link rel="stylesheet" href="${ctxStatic}/icheck/1.0/square/blue.css?${_version}"> -->
 <link rel="stylesheet" href="${ctxStatic}/jquery-toastr/2.1/toastr.min.css?${_version}">
-<link rel="stylesheet" href="${ctxStatic}/modules/sys/sysLogin.css?${_version}">
-<div class="login-box" style="margin:7% auto 300px auto;">
-	<div class="login-logo">
-		<a href="${ctxAdmin}/login">
-			<b>${@Global.getConfig('productNamePrefix')}${@Global.getConfig('productName')}</b>
-			<small>${@Global.getConfig('productVersion')}</small>
-		</a>
-	</div>
-	<div class="login-box-body">
-		<% var defaultSkinName = @Global.getConfig('sys.index.skinName', 'skin-blue-light3');
-		var skinName = cookie('skinName', false, defaultSkinName);
-		if (skinName == 'skin-dark') { %>
-<!--			<a class="switchSkin" href="${ctxAdmin}/switchSkin/${defaultSkinName}" title="${text('浅色模式')}"><i class="fa fa-toggle-off"></i></a>-->
-		<% }else{ %>
-<!--			<a class="switchSkin" href="${ctxAdmin}/switchSkin/skin-dark" title="${text('黑暗模式')}"><i class="fa fa-toggle-on"></i></a>-->
-		<% } %>
-		<% var isLoginByValidCode = @Global.getConfigToBoolean('user.loginByValidCode', 'true'); %>
-		<% if(isLoginByValidCode){ %>
-			<ul id="loginTab" class="nav nav-tabs">
-				<li class="active"><a href="#tab-1" data-toggle="tab" action="${ctxAdmin}/login">${text('账号登录')}</a></li>
-<!--				<li><a href="#tab-2" data-toggle="tab" action="${ctxPath}/account/loginByValidCode">${text('手机登录')}</a></li>-->
-				<% if(isNotBlank(@Global.getConfig('shiro.ldapUrl'))){ %>
-<!--					<li><a href="#tab-3" data-toggle="tab" action="${ctxAdmin}/login-ldap">${text('LDAP登录')}</a></li>-->
+<style>
+	html, body { width: 100%; height: 100%; margin: 0; padding: 0; }
+	body.mes-login-page {
+		overflow: hidden !important;
+		background-image: url("${ctxStatic}/screen/imgs/background.png") !important;
+		background-size: cover !important;
+		background-position: center center !important;
+		background-repeat: no-repeat !important;
+		background-attachment: fixed !important;
+		font-family: "Microsoft YaHei", "PingFang SC", sans-serif !important;
+	}
+	body.mes-login-page::before {
+		content: "";
+		position: fixed;
+		inset: 0;
+		background: rgba(235, 245, 255, 0.45);
+		pointer-events: none;
+		z-index: 1;
+	}
+
+	/* 重置 AdminLTE 自带的 login-box */
+	body.mes-login-page .login-box {
+		position: static !important;
+		width: auto !important;
+		max-width: none !important;
+		margin: 0 !important;
+		padding: 0 !important;
+		background: transparent !important;
+		box-shadow: none !important;
+		border: none !important;
+	}
+	body.mes-login-page .login-logo,
+	body.mes-login-page .login-copyright-old,
+	body.mes-login-page #loginTab,
+	body.mes-login-page .login-box-msg,
+	body.mes-login-page .row,
+	body.mes-login-page .mt5.icheck,
+	body.mes-login-page .icheck { display: none !important; }
+	body.mes-login-page .login-box-body {
+		background: transparent !important;
+		padding: 0 !important;
+		box-shadow: none !important;
+		border: none !important;
+	}
+	body.mes-login-page .tab-content > .tab-pane { display: block !important; }
+
+	/* 左侧品牌区 - logo 图片已包含文字 */
+	.mes-brand {
+		position: fixed;
+		left: 15%;
+		top:  47%;
+		transform: translateY(-50%);
+		z-index: 10;
+	}
+	.mes-brand .mes-brand-logo {
+		height: 110px;
+		width: auto;
+		max-width: 600px;
+		object-fit: contain;
+		display: block;
+	}
+
+	/* 登录卡片 */
+	.mes-login-box {
+		position: fixed;
+		top: 50%;
+		right: 10%;
+		transform: translateY(-50%);
+		width: 480px;
+		min-height: 540px;
+		background: rgba(255, 255, 255, 0.95);
+		box-shadow: 0 10px 40px rgba(30, 60, 120, 0.15);
+		border-radius: 8px;
+		padding: 60px 50px 40px;
+		z-index: 20;
+		box-sizing: border-box;
+	}
+	.mes-login-box h2.mes-login-title {
+		font-size: 26px;
+		font-weight: bold;
+		color: #1F3B7A;
+		margin: 0 0 40px;
+		letter-spacing: 2px;
+	}
+	.mes-login-box .form-group {
+		margin-bottom: 22px;
+		position: relative;
+	}
+	.mes-login-box .form-control {
+		height: 52px !important;
+		width: 100% !important;
+		border: 1px solid #d5dbe8 !important;
+		border-radius: 6px !important;
+		padding: 10px 16px !important;
+		font-size: 15px !important;
+		color: #1F3B7A !important;
+		background: #ffffff !important;
+		box-shadow: none !important;
+		transition: border-color 0.2s, box-shadow 0.2s;
+		display: block !important;
+	}
+	.mes-login-box .form-control::placeholder { color: #8a97b3; }
+	.mes-login-box .form-control:focus {
+		border-color: #1F3B7A !important;
+		box-shadow: 0 0 0 3px rgba(31, 59, 122, 0.08) !important;
+		outline: none !important;
+	}
+	.mes-login-box .has-feedback .form-control-feedback { display: none !important; }
+	.mes-login-box .btn-login {
+		width: 100%;
+		height: 52px;
+		background: #1F3B7A;
+		border: none;
+		border-radius: 6px;
+		color: #ffffff;
+		font-size: 16px;
+		letter-spacing: 6px;
+		font-weight: bold;
+		cursor: pointer;
+		transition: background 0.2s;
+	}
+	.mes-login-box .btn-login:hover,
+	.mes-login-box .btn-login:focus,
+	.mes-login-box .btn-login:active {
+		background: #163066;
+		outline: none;
+	}
+	.mes-login-box .forget-row {
+		text-align: center;
+		margin-top: 18px;
+		font-size: 13px;
+		color: #6b7a99;
+	}
+	.mes-login-box .forget-row a { color: #6b7a99; text-decoration: none; }
+	.mes-login-box .forget-row a:hover { color: #1F3B7A; }
+
+	/* 底部版权 */
+	.mes-copyright {
+		position: fixed;
+		bottom: 24px;
+		left: 0;
+		right: 0;
+		text-align: center;
+		font-size: 13px;
+		color: #3C5A99;
+		letter-spacing: 1px;
+		z-index: 10;
+	}
+</style>
+
+<!-- 左侧品牌 -->
+<div class="mes-brand">
+	<img class="mes-brand-logo" src="${ctxStatic}/screen/imgs/logo.png" alt="鲁匠人MES生产管理系统">
+</div>
+
+<!-- 登录卡片 -->
+<div class="mes-login-box">
+	<h2 class="mes-login-title">欢迎登录</h2>
+	<div class="login-box">
+		<div class="login-box-body">
+			<#form:form id="loginForm" model="${user!}" action="${ctxAdmin}/login" method="post" class="tab-content">
+				<% if(isNotBlank(message!)){ %>
+					<h4 class="login-box-msg text-red">${message}</h4>
 				<% } %>
-			</ul>
-		<% } %>
-		<#form:form id="loginForm" model="${user!}" action="${ctxAdmin}/login" method="post" class="tab-content">
-			<% if(!isLoginByValidCode && isBlank(message!)){ %>
-				<h4 class="login-box-msg">${text('欢迎回来')+'!'}</h4>
-			<% }else if(isNotBlank(message!)){ %>
-				<h4 class="login-box-msg text-red">${message}</h4>
-			<% } %>
-			<div class="form-group has-feedback">
-				<span class="icon-user form-control-feedback" title="${text('登录账号')}"></span>
-				<#form:input type="text" name="username" class="form-control required"
-					data-msg-required="${text('请填写登录账号.')}" placeholder="${text('登录账号')}"
-					value="${cookie('rememberUserCode')}"/>
-			</div>
-			<div class="form-group has-feedback tab-pane tab-1 tab-3 active">
-				<span class="icon-lock form-control-feedback" title="${text('登录密码,鼠标按下显示密码')}"
-					onmousedown="$('#password').attr('type','text')" onmouseup="$('#password').attr('type','password')"
-					onmouseenter="$(this).removeClass('icon-lock').addClass('icon-eye')"
-					onmouseout="$(this).removeClass('icon-eye').addClass('icon-lock')"></span>
-				<#form:input type="password" name="password" class="form-control required"
-					data-msg-required="${text('请填写登录密码.')}" placeholder="${text('登录密码')}" autocomplete="off"/>
-			</div>
-			<% if(@Global.getConfigToBoolean('user.loginCodeCorpUnique', 'false')){ %>
-			<div class="form-group has-feedback">
-				<#form:treeselect id="switchCorpSelect" title="${text('登录租户')}" allowClear="false"
-					name="param_corpCode" url="${ctxAdmin}/sys/corpAdmin/treeData?isShowCode=true" placeholder="${text('登录租户')}"/>
-			</div>
-			<% } %>
-			<div class="form-group has-feedback" id="isValidCodeLogin" style="display:${isValidCodeLogin?'blank':'none'}">
-				<#form:validcode name="validCode" isRequired="true" isRemote="true" isLazy="${!isValidCodeLogin}"/>
-			</div>
-			<div class="form-group has-feedback tab-pane tab-2">
-				<div class="input-group">
-					<input type="text" id="loginValidCode" name="loginValidCode" class="form-control required"
-						data-msg-required="${text('请填写手机验证码.')}" placeholder="${text('手机验证码')}" />
-					<span class="input-group-btn">
-						<input type="button" id="sendLoginValidCode" value="${text('获取手机验证码')}" class="btn btn-flat"/>
-					</span>
+				<div class="form-group has-feedback">
+					<#form:input type="text" name="username" class="form-control required"
+						data-msg-required="${text('请填写登录账号.')}" placeholder="${text('请输入用户名...')}"
+						value="${cookie('rememberUserCode')}"/>
 				</div>
-			</div>
-			<div class="form-group">
-				<div class="mt5 icheck">
-					<label title="${text('公共场所慎用,下次不需要再填写帐号')}"><input type="checkbox"
-						name="rememberUserCode"${isNotBlank(cookie('rememberUserCode'))?' checked':''}
-						class="form-control" data-style="minimal-grey"> ${text('记住账号')}</label> &nbsp; 
-					<label title="${text('公共场所慎用,下次不需要再填写帐号和密码')}"><input type="checkbox"
-						name="rememberMe"${isNotBlank(cookie('rememberMe'))?' checked':''}
-						class="form-control" data-style="minimal-grey"> ${text('自动登录')}</label>
+				<div class="form-group has-feedback tab-pane tab-1 tab-3 active">
+					<#form:input type="password" name="password" class="form-control required"
+						data-msg-required="${text('请填写登录密码.')}" placeholder="${text('请输入密码...')}" autocomplete="off"/>
 				</div>
-			</div>
-			<div class="form-group">
-				<!-- <input type="hidden" name="param_deviceType" value="pc"> -->
-				<input type="hidden" name="__url" value="${parameter.__url!}">
-				<button type="submit" class="btn btn-primary btn-block btn-flat"
-					id="btnSubmit" data-loading="${text('登录验证成功,正在进入...')}"
-					data-login-valid="${text('正在验证登录,请稍候...')}">${text('立即登录')}</button>
-			</div>
-		</#form:form>
-		<div class="row">
-			<div class="col-xs-12">
-<!--				<a href="${ctxPath}/account/forgetPwd" class="pull-left">[ ${text('忘记密码')} ]</a>-->
-				<% if(@Global.getConfigToBoolean('sys.account.registerUser', 'false')){ %>
-					<a href="${ctxPath}/account/registerUser" class="pull-left ml10">[ ${text('注册账号')} ]</a>
-				<% } %>
-				<% if (@com.jeesite.common.i18n.I18nLocaleResolver.enabled()){ %>
-				<div class="dropdown pull-right">
-					<a href="javascript:" class="dropdown-toggle" data-toggle="dropdown" data-hover="dropdown">
-						<i class="fa icon-globe"></i> ${@DictUtils.getDictLabel('sys_lang_type', lang(), 'zh_CN')}
-					</a>
-					<ul class="dropdown-menu">
-						<li class="mt5"></li>
-						<% for(var dict in @DictUtils.getDictList('sys_lang_type')){ %>
-							<li><a href="${ctxPath}/lang/${dict.dictValue}">${dict.dictLabel}</a></li>
-						<% } %>
-						<li class="mt10"></li>
-					</ul>
+				<% if(@Global.getConfigToBoolean('user.loginCodeCorpUnique', 'false')){ %>
+				<div class="form-group has-feedback">
+					<#form:treeselect id="switchCorpSelect" title="${text('登录租户')}" allowClear="false"
+						name="param_corpCode" url="${ctxAdmin}/sys/corpAdmin/treeData?isShowCode=true" placeholder="${text('登录租户')}"/>
 				</div>
 				<% } %>
-			</div>
+				<div class="form-group has-feedback" id="isValidCodeLogin" style="display:${isValidCodeLogin?'blank':'none'}">
+					<#form:validcode name="validCode" isRequired="true" isRemote="true" isLazy="${!isValidCodeLogin}"/>
+				</div>
+				<div class="form-group mt5 icheck" style="display:none">
+					<label><input type="checkbox" name="rememberUserCode"${isNotBlank(cookie('rememberUserCode'))?' checked':''}></label>
+					<label><input type="checkbox" name="rememberMe"${isNotBlank(cookie('rememberMe'))?' checked':''}></label>
+				</div>
+				<div class="form-group">
+					<input type="hidden" name="__url" value="${parameter.__url!}">
+					<button type="submit" class="btn-login"
+						id="btnSubmit" data-loading="${text('登录验证成功,正在进入...')}"
+						data-login-valid="${text('正在验证登录,请稍候...')}">${text('登录')}</button>
+				</div>
+				<div class="forget-row">
+					<a href="javascript:void(0);">${text('忘记密码')}?</a>
+				</div>
+			</#form:form>
 		</div>
 	</div>
-	<div class="login-copyright">
-		&copy; ${@DateUtils.getYear()} ${@Global.getConfig('productName')} - Powered By <a
-			id="loginKey" data-key="${@Global.getConfig('shiro.loginSubmit.secretKey')}"
-			href="#">${@Global.getConfig('companyName')}</a>
-	</div>
+</div>
+
+<div class="mes-copyright">
+	Copyright &copy; ${@DateUtils.getYear()} 鲁匠人MES生产管理系统 &nbsp;&nbsp; 版权所有
+	<a id="loginKey" data-key="${@Global.getConfig('shiro.loginSubmit.secretKey')}" href="#" style="display:none">${@Global.getConfig('companyName')}</a>
 </div>
 <% } %>
 <script src="${ctxStatic}/common/des.js?${_version}"></script>
 <script src="${ctxStatic}/jquery-toastr/2.1/toastr.min.js?${_version}"></script>
-<script src="${ctxStatic}/modules/sys/sysLogin.js?${_version}"></script>
+<script src="${ctxStatic}/modules/sys/sysLogin.js?${_version}"></script>