Pārlūkot izejas kodu

优化后台相关漏极

wzh 1 gadu atpakaļ
vecāks
revīzija
1509ba2c89

+ 1 - 0
.gitignore

@@ -3,3 +3,4 @@
 /.classpath
 /.project
 /.settings/
+/.idea/

+ 11 - 0
pom.xml

@@ -38,6 +38,17 @@
 			<artifactId>ojdbc8</artifactId>
 			<version>21.5.0.0</version>
 		</dependency>
+		<!-- IP地址转归属地 -->
+<dependency>
+   <groupId>org.lionsoul</groupId>
+   <artifactId>ip2region</artifactId>
+   <version>2.6.4</version>
+</dependency>
+<dependency>
+    <groupId>com.hankcs</groupId>
+    <artifactId>hanlp</artifactId>
+    <version>portable-1.8.2</version>
+</dependency>
 		  	<dependency>
 			<groupId>com.qiniu</groupId>
 			<artifactId>qiniu-java-sdk</artifactId>

+ 14 - 1
src/main/java/com/qlm/controller/UploadController.java

@@ -21,8 +21,9 @@ import com.qlm.tools.WxUtil;
 @RequestUrl("/upload")
 public class UploadController extends Controller {
 	UploadService uploadService = enhance(UploadService.class);
+	
 	@Clear
-	public void uploadData(){
+	public void receiveData(){
 		
 		Record result = new Record();
 		
@@ -32,4 +33,16 @@ public class UploadController extends Controller {
 		renderJson(result);
 	}
 
+	
+	@Clear
+	public void unbindCode(){
+		String code = getPara("code");
+		String sign = getPara("sign");
+		String time = getPara("time");
+		
+		String line = getPara("line");
+		
+		uploadService.unBindCode(code,line,time,sign);
+		renderJson(new Record());
+	}
 }

+ 18 - 0
src/main/java/com/qlm/controller/jinzai/DeviceController.java

@@ -0,0 +1,18 @@
+package com.qlm.controller.jinzai;
+
+import com.qlm.annotation.RequestUrl;
+import com.qlm.controller.common.CommonController;
+@RequestUrl("/devicelist")
+public class DeviceController extends CommonController {
+	@Override
+	protected String getTableName(String key) {
+		// TODO Auto-generated method stub
+		return "t_jz_device";
+	}
+
+	@Override
+	protected String getPath(String key) {
+		// TODO Auto-generated method stub
+		return "/page/jinzai/devicelist.jsp";
+	}
+}

+ 225 - 0
src/main/java/com/qlm/controller/jinzai/MobileController.java

@@ -0,0 +1,225 @@
+package com.qlm.controller.jinzai;
+
+import java.util.Date;
+import java.util.UUID;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jfinal.aop.Clear;
+import com.jfinal.core.Controller;
+import com.jfinal.kit.HashKit;
+import com.jfinal.kit.HttpKit;
+import com.jfinal.kit.PropKit;
+import com.jfinal.plugin.activerecord.Db;
+import com.jfinal.plugin.activerecord.Record;
+import com.jfinal.weixin.sdk.api.ApiConfig;
+import com.jfinal.weixin.sdk.api.ApiConfigKit;
+import com.jfinal.weixin.sdk.api.JsTicket;
+import com.jfinal.weixin.sdk.api.JsTicketApi;
+import com.jfinal.weixin.sdk.api.JsTicketApi.JsApiType;
+import com.qlm.annotation.RequestUrl;
+import com.qlm.tools.WxUtil;
+import com.qlm.tools.ip.CityInfo;
+import com.qlm.tools.ip.IpAddressUtil;
+
+@RequestUrl("/mobile")
+public class MobileController extends Controller{
+
+	@Clear
+	public void trace(){
+		setJsTicket();
+		render("/mobile/index.jsp");
+	}
+	@Clear
+	public void search(){
+		String code = getPara("code");
+		
+		String latitude = getPara("latitude");
+		
+		String longitude = getPara("longitude");
+		
+		CityInfo locationInfo = getInfo(latitude,longitude);
+		
+		
+		String ipAddress = IpAddressUtil.getIpAddress(getRequest());
+		
+		CityInfo ipInfo = IpAddressUtil.getCityInfoByMemorySearch(ipAddress);
+		
+		String ipProvince = "";
+		
+		String ipCity = "";
+		if(ipInfo != null){
+			ipProvince = ipInfo.getProvince();
+			ipCity = ipInfo.getCity();
+		}
+		
+		
+		if(locationInfo == null){
+			locationInfo = new CityInfo();
+		}
+		String locationCity = locationInfo.getCity();
+		String locationProvince = locationInfo.getProvince();
+
+		
+		
+		String compareCity = "";
+		String compareProvice = "";
+		if(locationInfo != null){
+			compareCity = locationInfo.getCity();
+			compareProvice = locationInfo.getProvince();
+		}
+		
+		if(WxUtil.isNull(compareCity)){
+			compareCity = ipCity;
+			compareProvice = ipProvince;
+		}
+		
+		boolean status = false;
+		String msg ="";
+		
+		Record searchInfo = new Record();
+		Long searchatCount = Db.queryLong("select count(*) from t_jz_searchrecord where child_code = ?",code);
+		
+		if(searchatCount == null){
+			searchatCount = 0L;
+		}
+		searchatCount++;
+		searchInfo.set("child_code", code).set("count", searchatCount).set("create_time", new Date())
+		.set("ip_addr", ipProvince+ipCity)
+		.set("ip", ipAddress).set("location", locationProvince+locationCity);
+		Record result = new Record();
+		boolean cuan = true;
+		Record jinzai_upload_child = Db.findFirst("select * from jinzai_upload_child where child_code = ?",code);
+		if(jinzai_upload_child!=null){
+			String master_code = jinzai_upload_child.getStr("master_code");
+			Record masterInfo = Db.findFirst("select * from jinzai_upload_master where id = ?",master_code);
+			
+			String pinxiang = masterInfo.getStr("pinxiang");
+			result.set("pinxiang", pinxiang);
+			searchInfo.set("product_name", pinxiang);
+			if(!WxUtil.isNull(master_code)){
+				status = true;
+				Record fahuoInfo = Db.findFirst("select * from deliveryorders where CaseCode =?",master_code);
+				if(fahuoInfo != null){
+					String CustomerNo = fahuoInfo.getStr("CustomerNo");
+					
+					String ProductName = fahuoInfo.getStr("ProductName");
+					
+					Record jxsInfo = Db.findFirst("select * from jinzai_jxs_area where code = ?",CustomerNo);
+					if(jxsInfo != null){
+						String saleCity = jxsInfo.getStr("city");
+						String saleProvince = jxsInfo.getStr("province");
+						
+						if(saleCity.equals(compareCity)){
+							cuan = false;
+						}
+						result.set("saleLocation", saleProvince+saleCity);
+						
+						searchInfo.set("kehu", saleProvince+saleCity);
+						result.set("fahuoInfo", fahuoInfo);
+					}
+					
+				}
+				
+				
+			}
+		}
+	
+		if(cuan){
+			searchInfo.set("status", 0);
+		}else{
+			searchInfo.set("status", 1);
+		}
+		Db.save("t_jz_searchrecord", searchInfo);
+		result.set("status", status).set("msg", msg).set("cuan", cuan).set("location", compareProvice+compareCity);
+		renderJson(result);
+		
+	}
+	
+	private static CityInfo getInfo(String latitude,String longitude){
+		if(latitude == null || longitude == null){
+			return null;
+		}
+		String location = latitude+","+longitude;
+		String key = "HTABZ-CBHRQ-WXT5C-BWAGZ-ARXY3-QMB5N";
+		String url = "https://apis.map.qq.com/ws/geocoder/v1/?location="+location+"&key="+key+"&get_poi=0";
+		System.out.println(url);
+		String xmlStr = HttpKit.get(url);
+		JSONObject parseObject = JSONObject.parseObject(xmlStr);
+		String message = parseObject.getString("message");
+		
+		if("Success".equals(message)){
+			JSONObject result = parseObject.getJSONObject("result");
+			JSONObject adInfo = result.getJSONObject("ad_info");
+			String province = adInfo.getString("province");
+			String city = adInfo.getString("city");
+			CityInfo ipInfo = new CityInfo();
+			ipInfo.setCity(city);
+			ipInfo.setProvince(province);
+			return ipInfo;
+		}
+		
+		return null;
+		
+	}
+	
+	public static void main(String[] args) {
+		CityInfo info = getInfo(30.59276+"",114.30525+"");
+		
+	}
+	
+	public void setJsTicket() {
+		ApiConfigKit.setThreadLocalApiConfig(getApiConfig());
+		JsTicket jsApiTicket = JsTicketApi.getTicket(JsApiType.jsapi);
+		String ticket = jsApiTicket.getTicket();
+		String nonce_str = create_nonce_str();
+		// 注意 URL 一定要动态获取,不能 hardcode.
+		String authoUrl = PropKit.get("authoUrl");
+		String url = authoUrl // 项目名称
+				+ getRequest().getServletPath();// 请求页面或其他地址
+		String qs = getRequest().getQueryString(); // 参数
+		if (qs != null) {
+			url = url + "?" + (getRequest().getQueryString());
+		}
+		String timestamp = create_timestamp();
+		// 这里参数的顺序要按照 key 值 ASCII 码升序排序
+		//注意这里参数名必须全部小写,且必须有序
+		String  str = "jsapi_ticket=" + ticket +
+        "&noncestr=" + nonce_str +
+        "&timestamp=" + timestamp +
+        "&url=" + url;
+		String signature = HashKit.sha1(str);
+		setAttr("appId", ApiConfigKit.getApiConfig().getAppId());
+		setAttr("nonceStr", nonce_str);
+		setAttr("timestamp", timestamp);
+		setAttr("url", url);
+		setAttr("signature", signature);
+		setAttr("jsapi_ticket", ticket);
+	}
+	private static String create_timestamp() {
+		return Long.toString(System.currentTimeMillis() / 1000);
+	}
+	
+	private static String create_nonce_str() {
+		return UUID.randomUUID().toString();
+	}
+	
+	public ApiConfig getApiConfig() {
+		ApiConfig ac = new ApiConfig();
+		// 配置微信 API 相关常量
+		ac.setToken("1");
+		ac.setAppId(PropKit.get("appid"));
+		ac.setAppSecret(PropKit.get("appsecret"));
+
+		/**
+		 * 是否对消息进行加密,对应于微信平台的消息加解密方式: 1:true进行加密且必须配置 encodingAesKey
+		 * 2:false采用明文模式,同时也支持混合模式
+		 */
+		ac.setEncryptMessage(PropKit.getBoolean("encryptMessage", false));
+		ac.setEncodingAesKey(PropKit.get("encodingAesKey",
+				"setting it in config file"));
+		return ac;
+	}
+	
+}

+ 41 - 0
src/main/java/com/qlm/controller/jinzai/UploadDataController.java

@@ -0,0 +1,41 @@
+package com.qlm.controller.jinzai;
+
+import com.jfinal.plugin.activerecord.Db;
+import com.jfinal.plugin.activerecord.Record;
+import com.qlm.annotation.RequestUrl;
+import com.qlm.controller.common.CommonController;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@RequestUrl("/uploadData")
+public class UploadDataController extends CommonController {
+
+
+	@Override
+	protected String getTableName(String key) {
+		// TODO Auto-generated method stub
+		return "jinzai_upload_master";
+	}
+
+	@Override
+	protected void formatData(String tableName, List<Record> find) {
+		List<Record> records = Db.find("select * from t_jz_device");
+
+		Map<String, String> collect = records.stream().collect(Collectors.toMap(r -> r.getStr("device_no"), r -> r.getStr("desc")));
+
+
+		for (Record record : find) {
+			String device_no = record.getStr("device_no");
+			String s = collect.get(device_no);
+			record.set("lineName",s);
+		}
+	}
+
+	@Override
+	protected String getPath(String key) {
+		// TODO Auto-generated method stub
+		return "/page/jinzai/upload.jsp";
+	}
+}

+ 40 - 1
src/main/java/com/qlm/service/UploadService.java

@@ -15,6 +15,7 @@ import com.jfinal.aop.Before;
 import com.jfinal.plugin.activerecord.Db;
 import com.jfinal.plugin.activerecord.Record;
 import com.jfinal.plugin.activerecord.tx.Tx;
+import com.qlm.tools.MD5Utils;
 import com.qlm.tools.WxUtil;
 
 public class UploadService {
@@ -33,7 +34,18 @@ public class UploadService {
 			String childCode = jsonObject.getString("i");
 	
 			if("nodata".equals(master)){
-				Db.update("update jinzai_upload_record set master_code = null where child_code = ?",childCode);
+				int update = Db.update("update jinzai_upload_record set master_code = null where child_code = ?",childCode);
+				if(update>0){
+					Record r = new Record();
+					r.set("child_code", childCode).set("create_time", new Date())
+					.set("device_no", deviceId);
+					try{
+						Db.save("jinzai_unbind_record","child_code", r);
+					}catch(Exception e){
+						e.printStackTrace();
+					}
+				}
+			
 			}else{
 				JSONObject jsonObject2 = masterMap.get(master);
 				if(jsonObject2 == null){
@@ -82,4 +94,31 @@ public class UploadService {
 		
 		WxUtil.batchSaveIgnore("jinzai_upload_master", xiangList, "");
 	}
+
+	@Before(Tx.class)
+	public void unBindCode(String code,String line, String time, String sign) {
+		boolean check = checksign(code,time,sign);
+		if(check){
+			int update = Db.update("update jinzai_upload_child set master_code = null where child_code = ?",code);
+			if(update>0){
+				Record r = new Record();
+				r.set("child_code", code).set("create_time", new Date())
+				.set("device_no", line);
+				try{
+					Db.save("jinzai_unbind_record","child_code", r);
+				}catch(Exception e){
+					e.printStackTrace();
+				}
+			}
+			
+		}
+	}
+	
+	private static String key = "wYG(nx%Xlc7vb%Ss1=2L#JZ*gSk^WXuV";
+
+	private boolean checksign(String code, String time, String sign) {
+		String str = time+key;
+		String md5 = MD5Utils.MD5(str).toLowerCase();
+		return md5.equals(sign);
+	}
 }

+ 24 - 0
src/main/java/com/qlm/tools/ip/CityInfo.java

@@ -0,0 +1,24 @@
+package com.qlm.tools.ip;
+public class CityInfo {
+	
+	private String city = "";
+	
+	private String province = "";
+
+	public String getCity() {
+		return city;
+	}
+
+	public void setCity(String city) {
+		this.city = city;
+	}
+
+	public String getProvince() {
+		return province;
+	}
+
+	public void setProvince(String province) {
+		this.province = province;
+	}
+
+}

+ 156 - 0
src/main/java/com/qlm/tools/ip/IpAddressUtil.java

@@ -0,0 +1,156 @@
+package com.qlm.tools.ip;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang3.StringUtils;
+import org.lionsoul.ip2region.xdb.Searcher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.Gson;
+ 
+/**
+ * IP地址Util
+ */
+public class IpAddressUtil {
+	
+	public static void main(String[] args) {
+		CityInfo cityInfoByMemorySearch = getCityInfoByMemorySearch("111.48.134.219");
+//		String ipAddressByOnline = getIpAddressByOnline("111.48.134.219");
+//		System.out.println(ipAddressByOnline);
+	}
+    private static final Logger log = LoggerFactory.getLogger(IpAddressUtil.class);
+
+    static Searcher searcher;
+    static{
+    	URL resource = IpAddressUtil.class.getResource("/ip2region.xdb");
+    	String path = resource.getPath();
+        byte[] cBuff;
+		try {
+			cBuff = Searcher.loadContentFromFile(path);
+			  searcher = Searcher.newWithBuffer(cBuff);
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+        // 2、使用上述的 cBuff 创建一个完全基于内存的查询对象。
+      
+    }
+    // ip2region.xdb 文件地址常量
+ 
+    /**
+     * 缓存整个 xdb 数据,对用户ip地址进行转换
+     * 注:并发使用时,用整个 xdb 数据缓存创建的查询对象可以安全的用于并发,也就是你可以把这个 searcher 对象做成全局对象去跨线程访问。
+     */
+    public static CityInfo getCityInfoByMemorySearch(String ip) {
+        if (StringUtils.isNotEmpty(ip)) {
+            try {
+                // 1、从 XDB_PATH 加载整个 xdb 到内存。
+                // 2、使用上述的 cBuff 创建一个完全基于内存的查询对象。
+                // 3、查询
+                long sTime = System.nanoTime();
+                String region = searcher.search(ip);
+                long cost = TimeUnit.NANOSECONDS.toMicros(System.nanoTime() - sTime);
+                region = region.replace("|0", "");
+                String[] split = region.split("\\|");
+                String province = split[1];
+                String city = split[2];
+                CityInfo ipinfo = new CityInfo();
+                ipinfo.setCity(city);
+                ipinfo.setProvince(province);
+                log.info("{地区: {}, IO操作数: {}, 耗时: {} μs}", region, searcher.getIOCount(), cost);
+                return ipinfo;
+            } catch (Exception e) {
+                log.error("获取IP地址异常:{} ", e.getMessage());
+            }
+        }
+        return null;
+    }
+    
+    public static String getIpAddressByOnline(String ip) {
+        try {
+            //1、创建 URLConnction
+            URL url = new URL("http://ip-api.com/json/" + ip + "?lang=zh-CN");
+ 
+            //2、设置connection的属性
+            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+            connection.setRequestMethod("GET");
+            connection.setConnectTimeout(20000);
+            connection.setReadTimeout(20000);
+            connection.setRequestProperty("content-type", "application/json; charset=utf-8");
+ 
+            //3.连接
+            connection.connect();
+ 
+            //4.获取内容
+            InputStream inputStream = connection.getInputStream();
+ 
+            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
+            String line;
+            StringBuilder sb = new StringBuilder();
+            while ((line = br.readLine()) != null) {
+                sb.append(line);
+            }
+            br.close();
+            //System.out.println(sb);
+ 
+            String str = sb.toString();
+            if (StringUtils.isNotEmpty(str)) {
+                // string转map
+                Gson gson = new Gson();
+                Map<String, Object> map = new HashMap<>();
+                map = gson.fromJson(str, map.getClass());
+                String country = (String) map.get("country");
+                String city = (String) map.get("city");
+                String regionName = (String) map.get("regionName");
+                System.out.println("国家:" + country);
+                System.out.println("城市:" + city);
+                System.out.println("地区:" + regionName);
+                return country + "|" + city + "|" + regionName;
+            }
+        } catch (Exception e) {
+            log.error("在线查询IP地址异常,{}", e.getMessage());
+            throw new RuntimeException(e.getMessage());
+        }
+        return null;
+
+    } 
+    
+    public static  String getIpAddress(HttpServletRequest request) {
+        String ipAddress = null;
+        try {
+            ipAddress = request.getHeader("X-Forwarded-For");
+            if (ipAddress != null && ipAddress.length() != 0 && !"unknown".equalsIgnoreCase(ipAddress)) {
+                // 多次反向代理后会有多个ip值,第一个ip才是真实ip
+                if (ipAddress.contains(",")) {
+                    ipAddress = ipAddress.split(",")[0];
+                }
+            }
+            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+                ipAddress = request.getHeader("Proxy-Client-IP");
+            }
+            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+                ipAddress = request.getHeader("WL-Proxy-Client-IP");
+            }
+            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+                ipAddress = request.getHeader("HTTP_CLIENT_IP");
+            }
+            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+                ipAddress = request.getRemoteAddr();
+            }
+        } catch (Exception e) {
+            log.error("获取IP地址异常,{}", e.getMessage());
+        }
+        return ipAddress;
+    }
+}

+ 7 - 2
src/main/resources/config.properties

@@ -8,9 +8,14 @@ user=root
 password =Qyy#2023.Wzh!
 
 #qrcode
-url=https://d.dnzc.vip
 dbname=jinzai
-
+authoUrl=http://jinzai.dnzc.vip
 oracleUrl = jdbc:oracle:thin:@192.168.0.183:61521/orcl
 oracleUser = pxl
 oraclePass = xuwei417
+
+
+appid=wxe25fed34f9f70ef4
+appsecret=3b9f0ea12741d739c2b513820fa74c9d
+
+

BIN
src/main/resources/ip2region.xdb


BIN
src/main/webapp/img/logo.png


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 709 - 0
src/main/webapp/mobile/index.jsp


BIN
src/main/webapp/mobile/layer-mobile/.DS_Store


+ 14 - 0
src/main/webapp/mobile/layer-mobile/README.md

@@ -0,0 +1,14 @@
+
+## layer mobile
+layer mobile是为移动设备(手机、平板等webkit内核浏览器/webview)量身定做的弹层支撑,采用Native JavaScript编写,完全独立于PC版的layer,您需要按照场景选择使用。
+
+[文档与演示](http://sentsin.com/layui/layer/)   
+
+1. 无需依赖任何库,只加载layer.m.js即可
+2. 小巧玲珑,性能卓越、柔情似水…
+3. 具备无以伦比的自适应功能
+4. 灵活的皮肤自定义支撑,充分确保弹层风格多样化
+5. 丰富、科学的接口,让弹弹弹层无所不能
+
+## 备注
+[官网](http://sentsin.com/layui/layer/)、[有问必答](http://say.sentsin.com/home-48.html)

+ 207 - 0
src/main/webapp/mobile/layer-mobile/layer.js

@@ -0,0 +1,207 @@
+/*!
+
+ @Name:layer mobile v2.0 弹层组件移动版
+ @Author:贤心
+ @License:MIT
+    
+ */
+
+;!function(win){
+  
+"use strict";
+
+var doc = document, query = 'querySelectorAll', claname = 'getElementsByClassName', S = function(s){
+  return doc[query](s);
+};
+
+//默认配置
+var config = {
+  type: 0
+  ,shade: true
+  ,shadeClose: true
+  ,fixed: true
+  ,anim: 'scale' //默认动画类型
+};
+
+var ready = {
+  extend: function(obj){
+    var newobj = JSON.parse(JSON.stringify(config));
+    for(var i in obj){
+      newobj[i] = obj[i];
+    }
+    return newobj;
+  }, 
+  timer: {}, end: {}
+};
+
+//点触事件
+ready.touch = function(elem, fn){
+  elem.addEventListener('click', function(e){
+    fn.call(this, e);
+  }, false);
+};
+
+var index = 0, classs = ['layui-m-layer'], Layer = function(options){
+  var that = this;
+  that.config = ready.extend(options);
+  that.view();
+};
+
+Layer.prototype.view = function(){
+  var that = this, config = that.config, layerbox = doc.createElement('div');
+
+  that.id = layerbox.id = classs[0] + index;
+  layerbox.setAttribute('class', classs[0] + ' ' + classs[0]+(config.type || 0));
+  layerbox.setAttribute('index', index);
+  
+  //标题区域
+  var title = (function(){
+    var titype = typeof config.title === 'object';
+    return config.title
+    ? '<h3 style="'+ (titype ? config.title[1] : '') +'">'+ (titype ? config.title[0] : config.title)  +'</h3>'
+    : '';
+  }());
+  
+  //按钮区域
+  var button = (function(){
+    typeof config.btn === 'string' && (config.btn = [config.btn]);
+    var btns = (config.btn || []).length, btndom;
+    if(btns === 0 || !config.btn){
+      return '';
+    }
+    btndom = '<span yes type="1">'+ config.btn[0] +'</span>'
+    if(btns === 2){
+      btndom = '<span no type="0">'+ config.btn[1] +'</span>' + btndom;
+    }
+    return '<div class="layui-m-layerbtn">'+ btndom + '</div>';
+  }());
+  
+  if(!config.fixed){
+    config.top = config.hasOwnProperty('top') ?  config.top : 100;
+    config.style = config.style || '';
+    config.style += ' top:'+ ( doc.body.scrollTop + config.top) + 'px';
+  }
+  
+  if(config.type === 2){
+    config.content = '<i></i><i class="layui-m-layerload"></i><i></i><p>'+ (config.content||'') +'</p>';
+  }
+  
+  if(config.skin) config.anim = 'up';
+  if(config.skin === 'msg') config.shade = false;
+  
+  layerbox.innerHTML = (config.shade ? '<div '+ (typeof config.shade === 'string' ? 'style="'+ config.shade +'"' : '') +' class="layui-m-layershade"></div>' : '')
+  +'<div class="layui-m-layermain" '+ (!config.fixed ? 'style="position:static;"' : '') +'>'
+    +'<div class="layui-m-layersection">'
+      +'<div class="layui-m-layerchild '+ (config.skin ? 'layui-m-layer-' + config.skin + ' ' : '') + (config.className ? config.className : '') + ' ' + (config.anim ? 'layui-m-anim-' + config.anim : '') +'" ' + ( config.style ? 'style="'+config.style+'"' : '' ) +'>'
+        + title
+        +'<div class="layui-m-layercont">'+ config.content +'</div>'
+        + button
+      +'</div>'
+    +'</div>'
+  +'</div>';
+  
+  if(!config.type || config.type === 2){
+    var dialogs = doc[claname](classs[0] + config.type), dialen = dialogs.length;
+    if(dialen >= 1){
+      layer.close(dialogs[0].getAttribute('index'))
+    }
+  }
+  
+  document.body.appendChild(layerbox);
+  var elem = that.elem = S('#'+that.id)[0];
+  config.success && config.success(elem);
+  
+  that.index = index++;
+  that.action(config, elem);
+};
+
+Layer.prototype.action = function(config, elem){
+  var that = this;
+  
+  //自动关闭
+  if(config.time){
+    ready.timer[that.index] = setTimeout(function(){
+      layer.close(that.index);
+    }, config.time*1000);
+  }
+  
+  //确认取消
+  var btn = function(){
+    var type = this.getAttribute('type');
+    if(type == 0){
+      config.no && config.no();
+      layer.close(that.index);
+    } else {
+      config.yes ? config.yes(that.index) : layer.close(that.index);
+    }
+  };
+  if(config.btn){
+    var btns = elem[claname]('layui-m-layerbtn')[0].children, btnlen = btns.length;
+    for(var ii = 0; ii < btnlen; ii++){
+      ready.touch(btns[ii], btn);
+    }
+  }
+  
+  //点遮罩关闭
+  if(config.shade && config.shadeClose){
+    var shade = elem[claname]('layui-m-layershade')[0];
+    ready.touch(shade, function(){
+      layer.close(that.index, config.end);
+    });
+  }
+
+  config.end && (ready.end[that.index] = config.end);
+};
+
+win.layer = {
+  v: '2.0',
+  index: index,
+  
+  //核心方法
+  open: function(options){
+    var o = new Layer(options || {});
+    return o.index;
+  },
+  
+  close: function(index){
+    var ibox = S('#'+classs[0]+index)[0];
+    if(!ibox) return;
+    ibox.innerHTML = '';
+    doc.body.removeChild(ibox);
+    clearTimeout(ready.timer[index]);
+    delete ready.timer[index];
+    typeof ready.end[index] === 'function' && ready.end[index]();
+    delete ready.end[index];
+  },
+  
+  //关闭所有layer层
+  closeAll: function(){
+    var boxs = doc[claname](classs[0]);
+    for(var i = 0, len = boxs.length; i < len; i++){
+      layer.close((boxs[0].getAttribute('index')|0));
+    }
+  }
+};
+
+'function' == typeof define ? define(function() {
+  return layer;
+}) : function(){
+  
+  var js = document.scripts, script = js[js.length - 1], jsPath = script.src;
+  var path = jsPath.substring(0, jsPath.lastIndexOf("/") + 1);
+  
+  //如果合并方式,则需要单独引入layer.css
+  if(script.getAttribute('merge')) return; 
+  
+  document.head.appendChild(function(){
+    var link = doc.createElement('link');
+    link.href = path + 'need/layer.css?2.0';
+    link.type = 'text/css';
+    link.rel = 'styleSheet'
+    link.id = 'layermcss';
+    return link;
+  }());
+  
+}();
+
+}(window);

+ 87 - 0
src/main/webapp/mobile/layer-mobile/need/layer.css

@@ -0,0 +1,87 @@
+
+/* 
+  layer mobile
+*/
+
+.layui-m-layer{position:relative; z-index: 19891014;}
+.layui-m-layer *{-webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box;}
+.layui-m-layershade,
+.layui-m-layermain{position:fixed; left:0; top:0; width:100%; height:100%;}
+.layui-m-layershade{background-color:rgba(0,0,0, .7); pointer-events:auto;}
+.layui-m-layermain{display:table; font-family: Helvetica, arial, sans-serif; pointer-events: none;}
+.layui-m-layermain .layui-m-layersection{display:table-cell; vertical-align:middle; text-align:center;}
+.layui-m-layerchild{position:relative; display:inline-block; text-align:left; background-color:#fff; font-size:14px; border-radius: 5px; box-shadow: 0 0 8px rgba(0, 0, 0, 0.1);  pointer-events:auto;  -webkit-overflow-scrolling: touch;}
+.layui-m-layerchild{-webkit-animation-fill-mode: both; animation-fill-mode: both; -webkit-animation-duration: .2s; animation-duration: .2s;}
+
+
+/* 弹出动画 */
+@-webkit-keyframes layui-m-anim-scale { /* 默认 */
+	0% {opacity: 0; -webkit-transform: scale(.5); transform: scale(.5)}
+	100% {opacity: 1; -webkit-transform: scale(1); transform: scale(1)}
+}
+@keyframes layui-m-anim-scale { /* 默认 */
+	0% {opacity: 0; -webkit-transform: scale(.5); transform: scale(.5)}
+	100% {opacity: 1; -webkit-transform: scale(1); transform: scale(1)}
+}
+.layui-m-anim-scale{animation-name:  layui-m-anim-scale; -webkit-animation-name:  layui-m-anim-scale;}
+
+@-webkit-keyframes layui-m-anim-up{
+  0%{opacity: 0; -webkit-transform: translateY(800px); transform: translateY(800px)}
+  100%{opacity: 1; -webkit-transform: translateY(0); transform: translateY(0)}
+}
+@keyframes layui-m-anim-up{
+  0%{opacity: 0; -webkit-transform: translateY(800px); transform: translateY(800px)}
+  100%{opacity: 1; -webkit-transform: translateY(0); transform: translateY(0)}
+}
+.layui-m-anim-up{-webkit-animation-name: layui-m-anim-up;animation-name: layui-m-anim-up}
+
+
+.layui-m-layer0 .layui-m-layerchild{width: 90%; max-width: 640px;}
+.layui-m-layer1 .layui-m-layerchild{border:none; border-radius:0;}
+.layui-m-layer2 .layui-m-layerchild{width:auto; max-width:260px; min-width:40px; border:none; background: none; box-shadow: none; color:#fff;}
+.layui-m-layerchild h3{padding: 0 10px; height: 60px; line-height: 60px; font-size:16px; font-weight: 400;  border-radius: 5px 5px 0 0; text-align: center;}
+.layui-m-layerchild h3,
+.layui-m-layerbtn span{ text-overflow:ellipsis; overflow:hidden; white-space:nowrap;}
+.layui-m-layercont{padding: 50px 30px; line-height: 22px; text-align:center;}
+.layui-m-layer1 .layui-m-layercont{padding:0; text-align:left;}
+.layui-m-layer2 .layui-m-layercont{text-align:center; padding: 0; line-height: 0;}
+.layui-m-layer2 .layui-m-layercont i{width:25px; height:25px; margin-left:8px; display:inline-block; background-color:#fff; border-radius:100%;}
+.layui-m-layer2 .layui-m-layercont p{margin-top: 20px;}
+
+/* loading */
+@-webkit-keyframes layui-m-anim-loading{
+    0%,80%,100%{transform:scale(0); -webkit-transform:scale(0)}
+    40%{transform:scale(1); -webkit-transform:scale(1)}
+}
+@keyframes layui-m-anim-loading{
+    0%,80%,100%{transform:scale(0); -webkit-transform:scale(0)}
+    40%{transform:scale(1); -webkit-transform:scale(1)}
+}
+.layui-m-layer2 .layui-m-layercont i{-webkit-animation: layui-m-anim-loading 1.4s infinite ease-in-out; animation: layui-m-anim-loading 1.4s infinite ease-in-out; -webkit-animation-fill-mode: both; animation-fill-mode: both;}
+
+.layui-m-layer2 .layui-m-layercont i:first-child{margin-left:0; -webkit-animation-delay: -.32s; animation-delay: -.32s;}
+.layui-m-layer2 .layui-m-layercont i.layui-m-layerload{-webkit-animation-delay: -.16s; animation-delay: -.16s;}
+.layui-m-layer2 .layui-m-layercont>div{line-height:22px; padding-top:7px; margin-bottom:20px; font-size: 14px;}
+.layui-m-layerbtn{display: box; display: -moz-box; display: -webkit-box; width: 100%; position:relative; height: 50px; line-height: 50px; font-size: 0; text-align:center;  border-top:1px solid #D0D0D0; background-color: #F2F2F2; border-radius: 0 0 5px 5px;}
+.layui-m-layerbtn span{position:relative; display: block; -moz-box-flex: 1; box-flex: 1; -webkit-box-flex: 1;  text-align:center; font-size:14px; border-radius: 0 0 5px 5px; cursor:pointer;}
+.layui-m-layerbtn span[yes]{color: #40AFFE;}
+.layui-m-layerbtn span[no]{border-right: 1px solid #D0D0D0; border-radius: 0 0 0 5px;}
+.layui-m-layerbtn span:active{background-color: #F6F6F6;}
+.layui-m-layerend{position:absolute; right:7px; top:10px; width:30px; height:30px; border: 0; font-weight:400; background: transparent; cursor: pointer; -webkit-appearance: none; font-size:30px;}
+.layui-m-layerend::before, .layui-m-layerend::after{position:absolute; left:5px; top:15px; content:''; width:18px; height:1px; background-color:#999; transform:rotate(45deg); -webkit-transform:rotate(45deg); border-radius: 3px;}
+.layui-m-layerend::after{transform:rotate(-45deg);  -webkit-transform:rotate(-45deg);}
+
+/* 底部对话框风格 */
+body .layui-m-layer .layui-m-layer-footer{position: fixed; width: 95%; max-width: 100%; margin: 0 auto; left:0; right: 0; bottom: 10px; background: none;}
+.layui-m-layer-footer .layui-m-layercont{padding: 20px; border-radius: 5px 5px 0 0; background-color: rgba(255,255,255,.8);}
+.layui-m-layer-footer .layui-m-layerbtn{display: block; height: auto; background: none; border-top: none;}
+.layui-m-layer-footer .layui-m-layerbtn span{background-color: rgba(255,255,255,.8);}
+.layui-m-layer-footer .layui-m-layerbtn span[no]{color: #FD482C; border-top: 1px solid #c2c2c2; border-radius: 0 0 5px 5px;}
+.layui-m-layer-footer .layui-m-layerbtn span[yes]{margin-top: 10px; border-radius: 5px;}
+
+/* 通用提示 */
+body .layui-m-layer .layui-m-layer-msg{width: auto; max-width: 90%; margin: 0 auto; bottom: -150px; background-color: rgba(0,0,0,.7); color: #fff;}
+.layui-m-layer-msg .layui-m-layercont{padding: 10px 20px;}
+
+
+

BIN
src/main/webapp/mobile/scan.jpg


BIN
src/main/webapp/mobile/trace.png


+ 6 - 11
src/main/webapp/page/jinzai/cuan.jsp

@@ -78,8 +78,8 @@
 		                                <div class="col-sm-6">
 		                                   	<select id="status" class="form-control ">
 		                                   	<option value="-1">全部</option>
-		                                   	<option value="0">正常</option>
-		                                   		<option value="1">窜货</option>
+		                                   	<option value="1">正常</option>
+		                                   		<option value="0">窜货</option>
 		                                   	</select> 
 		                              
                 						 </div>
@@ -223,17 +223,12 @@ function initTable(){
           	width:"5%"
         },{
         	field: 'ip_addr',
-            title: '查询城市',
+            title: 'IP地址',
             align: 'center',
             width:"5%"
         },{
         	field: 'location',
-            title: '地址',
-            align: 'center',
-            width:"5%"
-        },{
-        	field: 'search_type',
-            title: '查询类型',
+            title: '定位地址',
             align: 'center',
             width:"5%"
         },{
@@ -253,9 +248,9 @@ function initTable(){
             width:"5%",
             formatter:function(value){
             	if(value == 1){
-            		return "窜货";
+            		return "<div style='color:rgb(30, 188, 106)'>正常</div>";;
             	}else{
-            		return "正常";
+            		return "<div style='color:rgb(245, 69, 49)'>窜货</div>";
             	}
             }
         }

+ 47 - 0
src/main/webapp/page/jinzai/devicelist.jsp

@@ -0,0 +1,47 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+	pageEncoding="UTF-8"%>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
+<c:set var="title" value="设备列表"></c:set>
+<script>
+var dataFormat = [
+                  {
+                      field:"id",
+                      title:"ID",
+                      dataType:"string",/*string;datetime,date*/
+                      pk:true,
+                      edit:false
+                   },
+                   {
+                       field:"device_no",
+                       title:"设备编号",
+                       dataType:"string",/*string;datetime,date*/
+                       edit:true,
+                       isNull:false
+                    },
+                    {
+                        field:"desc",
+                        title:"备注",
+                        dataType:"string",/*string;datetime,date*/
+                        edit:true,
+                     },
+                     {
+                         field:"create_time",
+                         title:"添加时间",
+                         dataType:"string",/*string;datetime,date*/
+                         edit:false,
+                      }
+                    
+                    
+                   
+            ];
+var config = { isEdit:true,isDel:false,isAdd:true,afterEdit:function(){
+	
+}};
+
+</script>
+<%@include file="../common/table.jsp"%>
+
+<script>
+
+
+</script>

+ 98 - 0
src/main/webapp/page/jinzai/upload.jsp

@@ -0,0 +1,98 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+	pageEncoding="UTF-8"%>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
+<c:set var="title" value="订单列表"></c:set>
+<script>
+var dataFormat = [
+
+                   {
+                       field:"task_no",
+                       title:"任务单号",
+                       dataType:"string",/*string;datetime,date*/
+                       edit:true,
+                       isNull:false,
+					   formatter:function(value,data){
+						  return "<div style='word-wrap: normal;word-wrap: break-word;width:150px'>"+value+"</div>"
+					   }
+                    },
+	{
+		field:"id",
+		title:"箱码",
+		dataType:"string",/*string;datetime,date*/
+		edit:true,
+		isNull:false,
+		formatter:function(value,data){
+			return "<div style='word-wrap: normal;word-wrap: break-word;width:150px'>"+value+"</div>"
+		}
+	},{
+		field:"duo_code",
+		title:"托码",
+		dataType:"string",/*string;datetime,date*/
+		edit:true,
+		isNull:false,
+		formatter:function(value,data){
+			return "<div style='word-wrap: normal;word-wrap: break-word;width:150px'>"+value+"</div>"
+		}
+	},{
+		field:"lineName",
+		title:"产线",
+		dataType:"string",/*string;datetime,date*/
+		edit:true,
+		isNull:false
+	},
+                    {
+                        field:"pinxiang",
+                        title:"品项",
+                        dataType:"string",/*string;datetime,date*/
+                        edit:true,
+                        isNull:false
+                     }, {
+                         field:"kouwei",
+                         title:"口味",
+                         dataType:"string",/*string;datetime,date*/
+                         edit:true,
+                         isNull:false
+					  },{
+						field:"produce_date",
+						title:"生产日期",
+						dataType:"string",/*string;datetime,date*/
+						edit:true,
+						isNull:false
+					},
+
+                    {
+                        field:"sku",
+                        title:"sku",
+                        dataType:"string",/*string;datetime,date*/
+                        edit:true,
+                        isNull:false
+                     }
+
+
+
+                    ,
+                    {
+                        field:"guo_time",
+                        title:"绑定时间",
+                        dataType:"string",/*string;datetime,date*/
+                        edit:false,
+                     }
+
+
+
+            ];
+var config = { isEdit:false,isDel:false,isAdd:false,
+	toolBar:[{type:"input",title:"箱码",key:"id"},
+		{type:"input",title:"任务单号",key:"task_no"},
+		{type:"input",title:"托码",key:"duo_code"}
+
+	],
+};
+
+</script>
+<%@include file="../common/table.jsp"%>
+
+<script>
+
+
+</script>

+ 3 - 3
src/main/webapp/page/login.jsp

@@ -13,7 +13,7 @@
 <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
 <c:set value="<%=request.getContextPath()%>" var="ctx"></c:set>
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>${info.name }</title>
+    <title>劲仔食品</title>
     <meta name="keywords" content="关键字">
     <meta name="description" content="描述">
     <link rel="shortcut icon" href="favicon.ico"> 
@@ -31,9 +31,9 @@
     <div class="middle-box  loginscreen  animated fadeInDown" style="background-color: #fff;padding: 0 60px 20px; width: auto; ">
         <div class="">
             <div class="text-center">
-                <h1><img src="${info.loginLogo }" width="100%" /></h1>
+                <h1><img src="${ctx }/img/logo.png" width="70%" /></h1>
             
-            <h3>${info.name }</h3>
+            <h3>劲仔智能物码平台</h3>
             </div>
             <form action="${ctx}/login"
 				method="post" id="portalLoginForm" name="portalLoginForm">

+ 5 - 4
src/main/webapp/page/menu.jsp

@@ -8,7 +8,7 @@
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <meta name="renderer" content="webkit">
-    <title>${info.name }</title>
+    <title>劲仔食品</title>
     <meta name="keywords" content="关键字">
     <meta name="description" content="描述">
     <!--[if lt IE 9]>
@@ -35,7 +35,8 @@
                         <div class="dropdown profile-element text-center">
                             <a data-toggle="dropdown" class="dropdown-toggle" href="#">
                                 <span class="clear">
-                               <span class="block m-t-xs"><strong class="font-bold">${adminView.companyName }</strong></span>
+                                <span><img alt="image" class="" src="${ctx }/img/logo.png" width="50px"></span>
+                               <span class="block m-t-xs"><strong class="font-bold">劲仔食品</strong></span>
                                 <span class="text-muted text-xs block">${adminView.username }<b class="caret"></b></span>
                                 </span>
                             </a>
@@ -47,7 +48,7 @@
                                 </li>
                             </ul>
                         </div>
-                        <div class="logo-element">${info.name }</div>
+                        <div class="logo-element">劲仔食品</div>
                     </li>
                      <!-- 动态菜单 开始 -->
                     ${menus}
@@ -93,7 +94,7 @@
                 <iframe class="J_iframe" name="iframe0" width="100%" height="100%" frameborder="0" seamless></iframe>
             </div>
             <div class="footer">
-                <div class="pull-right">Copyright 2023 ${info.name }
+                <div class="pull-right">Copyright 2024 劲仔食品
                 </div>
             </div>
         </div>