wulianwei 1 rok temu
rodzic
commit
2cc4abf69f
40 zmienionych plików z 1252 dodań i 167 usunięć
  1. 22 2
      pom.xml
  2. 8 1
      src/main/java/com/tuoren/forward/aspect/HandleLogAspect.java
  3. 41 39
      src/main/java/com/tuoren/forward/config/OtherDataSourceConfiguration.java
  4. 3 1
      src/main/java/com/tuoren/forward/config/SaTokenConfigure.java
  5. 227 30
      src/main/java/com/tuoren/forward/config/amqp/AmqpClient1.java
  6. 235 36
      src/main/java/com/tuoren/forward/config/amqp/AmqpClient2.java
  7. 2 0
      src/main/java/com/tuoren/forward/constant/CommonConstant.java
  8. 13 0
      src/main/java/com/tuoren/forward/controller/ModelController.java
  9. 36 1
      src/main/java/com/tuoren/forward/controller/OpenController.java
  10. 71 0
      src/main/java/com/tuoren/forward/controller/StationLocationController.java
  11. 17 0
      src/main/java/com/tuoren/forward/controller/UserController.java
  12. 8 0
      src/main/java/com/tuoren/forward/entity/Model.java
  13. 3 0
      src/main/java/com/tuoren/forward/entity/Permission.java
  14. 20 0
      src/main/java/com/tuoren/forward/entity/dto/StationLocationDto.java
  15. 9 0
      src/main/java/com/tuoren/forward/entity/req/DeviceRecordSearchReq.java
  16. 17 0
      src/main/java/com/tuoren/forward/entity/req/StationLocationReq.java
  17. 3 0
      src/main/java/com/tuoren/forward/entity/req/UserAddOpenReq.java
  18. 6 0
      src/main/java/com/tuoren/forward/entity/req/UserAddReq.java
  19. 19 0
      src/main/java/com/tuoren/forward/entity/req/UserEditPwdReq.java
  20. 3 0
      src/main/java/com/tuoren/forward/entity/resp/DeviceResp.java
  21. 1 1
      src/main/java/com/tuoren/forward/interceptor/MybatisInterceptor.java
  22. 13 2
      src/main/java/com/tuoren/forward/mapper/ModelMapper.java
  23. 1 1
      src/main/java/com/tuoren/forward/mapper/ProductMapper.java
  24. 5 0
      src/main/java/com/tuoren/forward/mapper/StationLocationMapper.java
  25. 6 0
      src/main/java/com/tuoren/forward/mapper/UserMapper.java
  26. 20 3
      src/main/java/com/tuoren/forward/service/DeviceService.java
  27. 2 0
      src/main/java/com/tuoren/forward/service/LogService.java
  28. 41 6
      src/main/java/com/tuoren/forward/service/ModelService.java
  29. 89 0
      src/main/java/com/tuoren/forward/service/StationLocationService.java
  30. 70 4
      src/main/java/com/tuoren/forward/service/UserService.java
  31. 66 0
      src/main/java/com/tuoren/forward/util/AliyunMessageUtil.java
  32. 8 12
      src/main/java/com/tuoren/forward/util/RemoteUtil.java
  33. 1 12
      src/main/resources/application.yml
  34. 30 0
      src/main/resources/db/migration/V1.0.2__modle_update.sql
  35. 3 3
      src/main/resources/mapper/DeviceMapper.xml
  36. 3 0
      src/main/resources/mapper/LogMapper.xml
  37. 83 9
      src/main/resources/mapper/ModelMapper.xml
  38. 15 4
      src/main/resources/mapper/PermissionMapper.xml
  39. 18 0
      src/main/resources/mapper/StationLocationMapper.xml
  40. 14 0
      src/main/resources/mapper/UserMapper.xml

+ 22 - 2
pom.xml

@@ -73,7 +73,7 @@
 		<dependency>
 		    <groupId>com.alibaba.fastjson2</groupId>
 		    <artifactId>fastjson2</artifactId>
-		    <version>2.0.40</version>
+		    <version>2.0.51</version>
 		</dependency>
 
 		<dependency>
@@ -140,7 +140,27 @@
 		    <groupId>org.flywaydb</groupId>
 		    <artifactId>flyway-mysql</artifactId>
 		</dependency>
-
+		<!--阿里云短信服务-->
+		<dependency>
+	      <groupId>com.aliyun</groupId>
+	      <artifactId>dysmsapi20170525</artifactId>
+	      <version>2.0.24</version>
+	    </dependency>
+	    <dependency>
+	      <groupId>com.aliyun</groupId>
+	      <artifactId>tea-openapi</artifactId>
+	      <version>0.3.2</version>
+	    </dependency>
+	    <dependency>
+	      <groupId>com.aliyun</groupId>
+	      <artifactId>tea-console</artifactId>
+	      <version>0.0.1</version>
+	    </dependency>
+	    <dependency>
+	      <groupId>com.aliyun</groupId>
+	      <artifactId>tea-util</artifactId>
+	      <version>0.2.21</version>
+	    </dependency>
         <!--<dependency>
         	<groupId>com.demo</groupId>
         	<artifactId>forward</artifactId>

+ 8 - 1
src/main/java/com/tuoren/forward/aspect/HandleLogAspect.java

@@ -1,5 +1,6 @@
 package com.tuoren.forward.aspect;
 
+import java.awt.List;
 import java.lang.reflect.Method;
 import java.lang.reflect.Parameter;
 import java.util.Date;
@@ -21,6 +22,7 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 
+import com.alibaba.fastjson2.JSONArray;
 import com.alibaba.fastjson2.JSONObject;
 import com.tuoren.forward.annotation.HandleLog;
 import com.tuoren.forward.constant.CodeMsg;
@@ -164,7 +166,12 @@ public class HandleLogAspect {
         for(int i=0;i<params.length;i++) {
         	Parameter param = params[i];
         	if(param.getAnnotation(RequestBody.class) != null) {
-        		String paramStr = JSONObject.toJSONString(args[i]);
+        		String paramStr = "";
+        		if(param.getClass().equals(List.class)) {
+        			paramStr = JSONArray.toJSONString(args[i]);
+        		}else {
+        			paramStr = JSONObject.from(args[i]).toString();
+        		}
         		if(paramStr.length() > 200) {
         			paramStr = paramStr.substring(0,200);
         		}

+ 41 - 39
src/main/java/com/tuoren/forward/config/OtherDataSourceConfiguration.java

@@ -1,39 +1,41 @@
-package com.tuoren.forward.config;
-
-import javax.sql.DataSource;
-
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import com.zaxxer.hikari.HikariDataSource;
-
-//@Configuration
-public class OtherDataSourceConfiguration {
-
-	
-
-    @Bean("nbDataSourceProperties")
-    @ConfigurationProperties("spring.datasource.nb")
-    public DataSourceProperties nbDataSourceProperties() {
-        return new DataSourceProperties();
-    }
-
-    @Bean("nbDataSource")
-    @Qualifier(value = "nbDataSource")
-    // 留意下面这行
-    @ConfigurationProperties(prefix = "spring.datasource.nb.hikari")
-    public HikariDataSource nbDataSource(@Qualifier("nbDataSourceProperties") DataSourceProperties nbDataSourceProperties) {
-        return nbDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
-    }
-
-
-    @Bean( "nbJdbcTemplate")
-    @Qualifier(value = "nbJdbcTemplate")
-    public JdbcTemplate secondaryJdbcTemplate(@Qualifier("nbDataSource") DataSource dataSource) {
-        return new JdbcTemplate(dataSource);
-    }
-
-}
+/*
+ * package com.tuoren.forward.config;
+ * 
+ * import javax.sql.DataSource;
+ * 
+ * import org.springframework.beans.factory.annotation.Qualifier; import
+ * org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import
+ * org.springframework.boot.context.properties.ConfigurationProperties; import
+ * org.springframework.context.annotation.Bean; import
+ * org.springframework.jdbc.core.JdbcTemplate;
+ * 
+ * import com.zaxxer.hikari.HikariDataSource;
+ * 
+ * //@Configuration public class OtherDataSourceConfiguration {
+ * 
+ * 
+ * 
+ * @Bean("nbDataSourceProperties")
+ * 
+ * @ConfigurationProperties("spring.datasource.nb") public DataSourceProperties
+ * nbDataSourceProperties() { return new DataSourceProperties(); }
+ * 
+ * @Bean("nbDataSource")
+ * 
+ * @Qualifier(value = "nbDataSource") // 留意下面这行
+ * 
+ * @ConfigurationProperties(prefix = "spring.datasource.nb.hikari") public
+ * HikariDataSource nbDataSource(@Qualifier("nbDataSourceProperties")
+ * DataSourceProperties nbDataSourceProperties) { return
+ * nbDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.
+ * class).build(); }
+ * 
+ * 
+ * @Bean( "nbJdbcTemplate")
+ * 
+ * @Qualifier(value = "nbJdbcTemplate") public JdbcTemplate
+ * secondaryJdbcTemplate(@Qualifier("nbDataSource") DataSource dataSource) {
+ * return new JdbcTemplate(dataSource); }
+ * 
+ * }
+ */

+ 3 - 1
src/main/java/com/tuoren/forward/config/SaTokenConfigure.java

@@ -25,7 +25,9 @@ public class SaTokenConfigure {
 	//路径白名单
 	static String[] excludes = {
 		//"/**",// 取消认证
-		"/user/login",  //登录页面
+		"/user/login",  //登录
+		"/user/register",  //注册
+		"/user/editPassword",  //修改密码
 		"/doc.html",  //api地址
 		"/webjars/**",  //api资源
 		"/swagger-ui/**",  //swagger

+ 227 - 30
src/main/java/com/tuoren/forward/config/amqp/AmqpClient1.java

@@ -3,6 +3,8 @@ package com.tuoren.forward.config.amqp;
 import java.net.URI;
 import java.util.Date;
 import java.util.Hashtable;
+import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
@@ -31,20 +33,26 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.data.mongodb.core.MongoTemplate;
 import org.springframework.stereotype.Component;
 
+import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
 import com.tuoren.forward.config.mqtt.MqttUtil;
 import com.tuoren.forward.constant.CommonConstant;
 import com.tuoren.forward.entity.Device;
+import com.tuoren.forward.entity.Model;
 import com.tuoren.forward.entity.SatasticDay;
 import com.tuoren.forward.entity.StationLocation;
 import com.tuoren.forward.entity.User;
+import com.tuoren.forward.entity.dto.ModelDto;
 import com.tuoren.forward.mapper.DeviceMapper;
+import com.tuoren.forward.mapper.ModelMapper;
 import com.tuoren.forward.mapper.SatasticDayMapper;
 import com.tuoren.forward.mapper.StationLocationMapper;
 import com.tuoren.forward.mapper.UserMapper;
+import com.tuoren.forward.service.StationLocationService;
 import com.tuoren.forward.util.RemoteUtil;
 import com.tuoren.forward.util.UUIDUtil;
 
+import cn.hutool.core.util.ReUtil;
 import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
 
@@ -92,6 +100,12 @@ public class AmqpClient1 {
     @Autowired
     StationLocationMapper stationLocationMapper; 
     
+    @Autowired
+    StationLocationService stationLocationService;
+    
+    @Autowired
+    ModelMapper modelMapper;
+    
   //业务处理异步线程池,线程池参数可以根据您的业务特点调整,或者您也可以用其他异步方式处理接收到的消息。
     private final static ExecutorService executorService = new ThreadPoolExecutor(
         Runtime.getRuntime().availableProcessors(),
@@ -176,82 +190,112 @@ public class AmqpClient1 {
             JSONObject json = JSONObject.parseObject(content);
             repackJson(json);
             String deviceName = json.getString("deviceName");
-            String productKey = json.getString("productKey");
+//            String productKey = json.getString("productKey");
+            String productKey = "1dbfd476b7nm2";
             JSONObject items = json.getJSONObject("items");
+            aliyunTranslate(items);
+            String valiStr =modelValidate(productKey,items);
+            String reason="";
+            String code ="success";
+            if(!StringUtils.isEmpty(valiStr)) {
+            	log.info("不符合产品模型:"+valiStr);
+            	reason = "不符合产品模型:"+valiStr;
+            	code ="fail";
+            }
+      
             JSONObject localJson = null;
      
             String hospitalCode = !items.containsKey("userId") ? "" : items.getString("userId");
-            User owner = userMapper.selectByCode(hospitalCode);
-    		if(owner == null) {
-    			log.info("不存在该医院:"+hospitalCode);
-    			return;
-    		}
+            String tenentId = "";
+            if(!StringUtils.isEmpty(hospitalCode)) {
+            	User owner = userMapper.selectByCode(hospitalCode);
+            	if(owner == null) {
+        			log.info("不存在该医院:"+hospitalCode);
+        			//return;
+        		}else {
+        			tenentId = owner.getId();
+        		}
+            }
             String ci = !items.containsKey("ci") ? "" : items.getString("ci");
             String lac = !items.containsKey("lac") ? "" : items.getString("lac");
             if(!"".equals(ci) && !"".equals(lac)) {
             	String mnc = !items.containsKey("mnc") ? "00" : items.getString("mnc");
             	localJson = getLocation(mnc,lac,ci);
-            	items.put("location", localJson);            	
+//            	items.put("location", localJson);      
+            	items.putAll(localJson);
             }
         
     		JSONObject mongoJson = new JSONObject();
     		Device exist = deviceMapper.selectByMac(deviceName);
+    		Device record = new Device();
     		if(exist == null) {
-    			Device record = new Device();
     			String deviceId = UUIDUtil.get32UUID();
     			record.setId(deviceId);
     			record.setCreatetime(date);
     			record.setModifytime(date);
     			record.setMac(deviceName);
     			record.setProductId(productKey);
-    			record.setTenantId(owner.getId());
+    			record.setTenantId(tenentId);
     			if(localJson != null) {
     				record.setLat(localJson.getString("lat"));
     				record.setLng(localJson.getString("lng"));
     				record.setAddress(localJson.getString("address"));
     				record.setRadius(localJson.getString("radius"));
     			}
-    			record.setData(items.toString());
+    			record.setData(packItemsTime(items,json.getLong("gmtCreate")).toString());
     			deviceMapper.insertSelective(record);
     			mongoJson.put("deviceId", deviceId);
     		}else {
-    			Device record = new Device();
+    			record = exist;
     			record.setId(exist.getId());
     			record.setModifytime(date);
-    			record.setTenantId(owner.getId());
+    			record.setProductId(productKey);
+    			record.setTenantId(tenentId);
     			if(localJson != null) {
     				record.setLat(localJson.getString("lat"));
     				record.setLng(localJson.getString("lng"));
     				record.setAddress(localJson.getString("address"));
     				record.setRadius(localJson.getString("radius"));
     			}
-    			record.setData( items.toString());
+    			JSONObject newItems = packItemsTime(items, json.getLong("gmtCreate"));
+    			String lastData = record.getData();
+    			if(!StringUtils.isEmpty(lastData)) {
+    				JSONObject lastItems = JSONObject.parseObject(lastData);
+    				lastItems.putAll(newItems);
+    				newItems = lastItems;
+    			}
+    			record.setData( newItems.toString());
     			deviceMapper.updateByPrimaryKeySelective2(record);
     			mongoJson.put("deviceId", exist.getId());
     		}
     		mongoJson.put("deviceMac", deviceName);
     		mongoJson.put("time", json.getLong("gmtCreate"));
-    		mongoJson.put("tenantId", owner.getId());
+    		mongoJson.put("tenantId", tenentId);
     		mongoJson.put("items", items);
+    		mongoJson.put("content", content);
+    		mongoJson.put("reason", reason);
+    		mongoJson.put("code", code);
     		mongoTemplate.insert(mongoJson, CommonConstant.MONGO_COLLECTION_DEVICE_RECORD);
     		
     		String sataType = "forward";
     		SatasticDay existSata = satasticDayMapper.selectSataTodayByType(sataType);
     		if(existSata == null) {
-    			SatasticDay record = new SatasticDay();
-    			record.setId(UUIDUtil.get32UUID());
-    			record.setType(sataType);
-    			record.setNum(1);
-    			record.setCreatedate(date);
-    			satasticDayMapper.insert(record);
+    			SatasticDay recordSta = new SatasticDay();
+    			recordSta.setId(UUIDUtil.get32UUID());
+    			recordSta.setType(sataType);
+    			recordSta.setNum(1);
+    			recordSta.setCreatedate(date);
+    			satasticDayMapper.insert(recordSta);
     		}else {
     			existSata.setNum(existSata.getNum()+1);
     			satasticDayMapper.updateByPrimaryKey(existSata);
     		}
     		
-    		if(mqttUtil != null) {
-    			log.info("mqtt publish1:"+  json.toString());
-    			mqttUtil.pub(CommonConstant.MQTT_PUBLISH_PREFIX+hospitalCode, json.toString());
+    		if(mqttUtil != null && !StringUtils.isEmpty(hospitalCode)) {
+    			JSONObject mqttJson = JSONObject.from(record);
+    			mqttJson.put("items", items);
+    			log.info("mqtt publish1:"+  mqttJson.toString());
+    			mqttUtil.pub(CommonConstant.MQTT_PUBLISH_PREFIX+hospitalCode, mqttJson.toString());
     		}
         } catch (Exception e) {
         	log.error("processMessage occurs error ", e);
@@ -266,11 +310,12 @@ public class AmqpClient1 {
     		String location = remoteUtil.localtion(mnc, lac, ci);
         	if(!StringUtils.isEmpty(location)) {
         		localJson =  JSONObject.parseObject(location);
-        		String newPoint = remoteUtil.getBaiduPoint(localJson.getString("lng"),localJson.getString("lat"));
+        		System.out.println("localJson:"+localJson.toString());
+        		String newPoint = remoteUtil.getBaiduPoint2(localJson.getString("lng"),localJson.getString("lat"));
             	if(!StringUtils.isEmpty(newPoint)) {
             		JSONObject pointJson =  JSONObject.parseObject(newPoint);
-            		localJson.put("lng", pointJson.getString("x"));
-            		localJson.put("lat", pointJson.getString("y"));
+            		localJson.put("lng", pointJson.getDouble("x"));
+            		localJson.put("lat", pointJson.getDouble("y"));
             	}
             	staLocation = new StationLocation();
             	staLocation.setId(UUIDUtil.get32UUID());
@@ -283,17 +328,131 @@ public class AmqpClient1 {
             	staLocation.setRadius(localJson.getString("radius"));
             	staLocation.setCreatetime(date);
             	staLocation.setModifytime(date);
-            	stationLocationMapper.insert(staLocation);
+            	stationLocationService.add(staLocation);
         	}
     	}else {
     		localJson = new JSONObject();
-    		localJson.put("lng", staLocation.getLng());
-    		localJson.put("lat", staLocation.getLat());
+    		localJson.put("lng", Double.parseDouble(staLocation.getLng()));
+    		localJson.put("lat", Double.parseDouble(staLocation.getLat()));
     		localJson.put("address", staLocation.getAddress());
-    		localJson.put("radius", staLocation.getRadius());
+    		localJson.put("radius", Integer.parseInt(staLocation.getRadius()));
     	}
     	return localJson;
     }
+    
+    /**
+     * @title 验证产品模型
+     * @param productId
+     * @param items
+     * @return
+     */
+    private String modelValidate(String productId,JSONObject items) {
+    	 ModelDto dto = new ModelDto();
+         dto.setProductId(productId);
+         List<Model> models = modelMapper.select(dto);
+         List<Model> cmodels = modelMapper.selectCommon(new ModelDto());
+         models.addAll(cmodels);
+         JSONObject newItems = new JSONObject(items);
+         for(String key : newItems.keySet()) {
+        	 Optional<Model> result = models.stream().filter(m->m.getTitle().equals(key)).findAny();
+        	 if(!result.isPresent()) {
+        		 items.remove(key);
+        		 continue;
+        	 }
+				/*
+				 * Model m = result.get(); String resultStr =
+				 * validateOne(m,items.getString(key)); if(!StringUtils.isEmpty(resultStr)) {
+				 * return resultStr; }
+				 */
+         }         
+    	return "";
+    }
+    
+	private static String validateOne(Model m, String value) {
+		String title = m.getTitle();
+		JSONObject define = JSONObject.parseObject(m.getDefine());
+		JSONObject range = define.getJSONObject("range");
+		if (range == null) {
+			return "";
+		}
+		switch (m.getType()) {
+		case "int": {
+			Integer min = range.containsKey("min") ? range.getInteger("min") : null;
+			Integer max = range.containsKey("max") ? range.getInteger("max") : null;
+			if (define.getBoolean("isArray")) {
+				if (!StringUtils.isEmpty(value)) {
+					String[] arr = value.split(",");
+					for (String s : arr) {
+						if (ReUtil.isMatch("^-?\\d*$", s)) {
+							int v = Integer.parseInt(s);
+							if ((min != null && min > v) || (max != null && max < v)) {
+								return "字段:" + title + " 数值超出范围";
+							}
+						}
+					}
+				}
+			} else {
+				if (ReUtil.isMatch("^-?\\d*$", value)) {
+					int v = Integer.parseInt(value);
+					if ((min != null && min > v) || (max != null && max < v)) {
+						return "字段:" + title + " 数值超出范围";
+					}
+				}
+			}
+			break;
+		}
+		case "float": {
+			Double min = range.containsKey("min") ? range.getDouble("min") : null;
+			Double max = range.containsKey("max") ? range.getDouble("max") : null;
+			if (define.getBoolean("isArray")) {
+				if (!StringUtils.isEmpty(value)) {
+					String[] arr = value.split(",");
+					for (String s : arr) {
+						if (ReUtil.isMatch("^-?\\d+([.]?\\d+)?$", s)) {
+							Double v = Double.parseDouble(s);
+							if ((min != null && min > v) || (max != null && max < v)) {
+								return "字段:" + title + " 数值超出范围";
+							}
+						}
+					}
+				}
+			} else {
+				if (ReUtil.isMatch("^-?\\d+([.]?\\d+)?$", value)) {
+					Double v = Double.parseDouble(value);
+					if ((min != null && min > v) || (max != null && max < v)) {
+						return "字段:" + title + " 数值超出范围";
+					}
+				}
+			}
+			break;
+		}
+		case "String": {
+			Integer len = range.containsKey("len") ? range.getInteger("len") : null;
+			if (define.getBoolean("isArray")) {
+				if (!StringUtils.isEmpty(value)) {
+					String[] arr = value.split(",");
+					for (String s : arr) {
+						if (len != null && len < s.length()) {
+							return "字段:" + title + " 数值超出范围";
+						}
+					}
+				}
+			} else {
+				if (len != null && len < value.length()) {
+					return "字段:" + title + " 数值超出范围";
+				}
+			}
+			break;
+		}
+		case "enum": {
+			if (!range.containsKey(value)) {
+				return "字段:" + title + " 数值超出范围";
+			}
+			break;
+		}
+		}
+		return "";
+	}
     private static JmsConnectionListener jmsConnectionListener = new JmsConnectionListener() {
         /**
          * 连接成功建立。
@@ -360,4 +519,42 @@ public class AmqpClient1 {
     	}
     	json.replace("items", items);
     }
+    
+    public static void aliyunTranslate(JSONObject items) {
+    	items.put("networkType", 1);//4G
+    	items.put("electricity", items.get("electricQuantity"));
+    	items.put("infusionId", items.get("classification"));
+    	items.put("ultimateDose", items.get("maxDose"));
+    	items.put("continueDose", items.get("flow"));
+    	items.put("finishDose", items.get("finishedDose"));
+    	items.put("appendDose", items.get("singleDose"));
+    	items.put("validTimes", items.get("pcaValid"));
+    	items.put("invalidTimes", items.get("pcaInvalid"));
+
+    	items.put("alarm", new int[] {items.getInteger("alarmStatus")});
+    	if(items.getInteger("warnLowBattery") == 1) {
+    		items.put("forcast", new int[]{3});
+    	}
+    	if(items.getInteger("warnAnalgesicPoor") == 1) {
+    		items.put("forcast", new int[]{2});
+    	}
+    	if(items.getInteger("warnWillFinished") == 1) {
+    		items.put("forcast", new int[]{1});
+    	}
+    	if(!items.containsKey("forcast")) {
+    		items.put("forcast", new int[]{0});
+    	}
+
+    }
+    
+    public static JSONObject packItemsTime(JSONObject items, Long timestamp) {
+    	JSONObject newItems = new JSONObject();
+    	for(String key:items.keySet()) {
+    		JSONObject temp = new JSONObject();
+    		temp.put("value", items.get(key));
+    		temp.put("time", timestamp);
+    		newItems.put(key, temp);
+    	}
+    	return newItems;
+    }
 }

+ 235 - 36
src/main/java/com/tuoren/forward/config/amqp/AmqpClient2.java

@@ -3,6 +3,8 @@ package com.tuoren.forward.config.amqp;
 import java.net.URI;
 import java.util.Date;
 import java.util.Hashtable;
+import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
@@ -35,16 +37,21 @@ import com.alibaba.fastjson2.JSONObject;
 import com.tuoren.forward.config.mqtt.MqttUtil;
 import com.tuoren.forward.constant.CommonConstant;
 import com.tuoren.forward.entity.Device;
+import com.tuoren.forward.entity.Model;
 import com.tuoren.forward.entity.SatasticDay;
 import com.tuoren.forward.entity.StationLocation;
 import com.tuoren.forward.entity.User;
+import com.tuoren.forward.entity.dto.ModelDto;
 import com.tuoren.forward.mapper.DeviceMapper;
+import com.tuoren.forward.mapper.ModelMapper;
 import com.tuoren.forward.mapper.SatasticDayMapper;
 import com.tuoren.forward.mapper.StationLocationMapper;
 import com.tuoren.forward.mapper.UserMapper;
+import com.tuoren.forward.service.StationLocationService;
 import com.tuoren.forward.util.RemoteUtil;
 import com.tuoren.forward.util.UUIDUtil;
 
+import cn.hutool.core.util.ReUtil;
 import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
 
@@ -90,7 +97,13 @@ public class AmqpClient2 {
     MongoTemplate mongoTemplate;
     
     @Autowired
-    StationLocationMapper stationLocationMapper; 
+    StationLocationMapper stationLocationMapper;
+    
+    @Autowired
+    StationLocationService stationLocationService; 
+    
+    @Autowired
+    ModelMapper modelMapper;
     
   //业务处理异步线程池,线程池参数可以根据您的业务特点调整,或者您也可以用其他异步方式处理接收到的消息。
     private final static ExecutorService executorService = new ThreadPoolExecutor(
@@ -172,12 +185,23 @@ public class AmqpClient2 {
             }
             byte[] body = message.getBody(byte[].class);
             String content = new String(body);
-            log.info("下发数据内容1:"+content);
+            log.info("下发数据内容2:"+content);
             JSONObject json = JSONObject.parseObject(content);
             repackJson(json);
             String deviceName = json.getString("deviceName");
-            String productKey = json.getString("productKey");
+//          String productKey = json.getString("productKey");
+            String productKey = "1dbfd476b7nm2";
             JSONObject items = json.getJSONObject("items");
+            aliyunTranslate(items);
+            String valiStr =modelValidate(productKey,items);
+            String reason="";
+            String code ="success";
+            if(!StringUtils.isEmpty(valiStr)) {
+            	log.info("不符合产品模型:"+valiStr);
+            	reason = "不符合产品模型:"+valiStr;
+            	code ="fail";
+            }
+      
             JSONObject localJson = null;
      
             String hospitalCode = !items.containsKey("userId") ? "" : items.getString("userId");
@@ -191,82 +215,100 @@ public class AmqpClient2 {
             	hospitalCode = remoteUtil.getHospitalCode(deviceName);
             	if(StringUtils.isEmpty(hospitalCode)) {
   				  log.info("设备没有对应医院:"+deviceName);
-  				  return;
+  				 // return;
   			    }
             }
-            User owner = userMapper.selectByCode(hospitalCode);
-    		if(owner == null) {
-    			log.info("不存在该医院:"+hospitalCode);
-    			return;
-    		}
-            
+            String tenentId = "";
+            if(!StringUtils.isEmpty(hospitalCode)) {
+            	User owner = userMapper.selectByCode(hospitalCode);
+            	if(owner == null) {
+        			log.info("不存在该医院:"+hospitalCode);
+        			//return;
+        		}else {
+        			tenentId = owner.getId();
+        		}
+            }
+
             String ci = !items.containsKey("ci") ? "" : items.getString("ci");
             String lac = !items.containsKey("lac") ? "" : items.getString("lac");
             if(!"".equals(ci) && !"".equals(lac)) {
             	String mnc = !items.containsKey("mnc") ? "00" : items.getString("mnc");
             	localJson = getLocation(mnc,lac,ci);
-            	items.put("location", localJson);            	
+//            	items.put("location", localJson);      
+            	items.putAll(localJson);
             }
-            
-            
+        
     		JSONObject mongoJson = new JSONObject();
     		Device exist = deviceMapper.selectByMac(deviceName);
+    		Device record = new Device();
     		if(exist == null) {
-    			Device record = new Device();
     			String deviceId = UUIDUtil.get32UUID();
     			record.setId(deviceId);
     			record.setCreatetime(date);
     			record.setModifytime(date);
     			record.setMac(deviceName);
     			record.setProductId(productKey);
-    			record.setTenantId(owner.getId());
+    			record.setTenantId(tenentId);
     			if(localJson != null) {
     				record.setLat(localJson.getString("lat"));
     				record.setLng(localJson.getString("lng"));
     				record.setAddress(localJson.getString("address"));
     				record.setRadius(localJson.getString("radius"));
     			}
-    			record.setData(items.toString());
+    			record.setData(packItemsTime(items,json.getLong("gmtCreate")).toString());
     			deviceMapper.insertSelective(record);
     			mongoJson.put("deviceId", deviceId);
     		}else {
-    			Device record = new Device();
+    			record = exist;
     			record.setId(exist.getId());
     			record.setModifytime(date);
-    			record.setTenantId(owner.getId());
+    			record.setProductId(productKey);
+    			record.setTenantId(tenentId);
     			if(localJson != null) {
     				record.setLat(localJson.getString("lat"));
     				record.setLng(localJson.getString("lng"));
     				record.setAddress(localJson.getString("address"));
     				record.setRadius(localJson.getString("radius"));
     			}
-    			record.setData( items.toString());
+    			JSONObject newItems = packItemsTime(items, json.getLong("gmtCreate"));
+    			String lastData = record.getData();
+    			if(!StringUtils.isEmpty(lastData)) {
+    				JSONObject lastItems = JSONObject.parseObject(lastData);
+    				lastItems.putAll(newItems);
+    				newItems = lastItems;
+    			}
+    			record.setData( newItems.toString());
     			deviceMapper.updateByPrimaryKeySelective2(record);
     			mongoJson.put("deviceId", exist.getId());
     		}
     		mongoJson.put("deviceMac", deviceName);
     		mongoJson.put("time", json.getLong("gmtCreate"));
-    		mongoJson.put("tenantId", owner.getId());
+    		mongoJson.put("tenantId", tenentId);
     		mongoJson.put("items", items);
+    		mongoJson.put("content", content);
+    		mongoJson.put("reason", reason);
+    		mongoJson.put("code", code);
     		mongoTemplate.insert(mongoJson, CommonConstant.MONGO_COLLECTION_DEVICE_RECORD);
     		
     		String sataType = "forward";
     		SatasticDay existSata = satasticDayMapper.selectSataTodayByType(sataType);
     		if(existSata == null) {
-    			SatasticDay record = new SatasticDay();
-    			record.setId(UUIDUtil.get32UUID());
-    			record.setType(sataType);
-    			record.setNum(1);
-    			record.setCreatedate(date);
-    			satasticDayMapper.insert(record);
+    			SatasticDay recordSta = new SatasticDay();
+    			recordSta.setId(UUIDUtil.get32UUID());
+    			recordSta.setType(sataType);
+    			recordSta.setNum(1);
+    			recordSta.setCreatedate(date);
+    			satasticDayMapper.insert(recordSta);
     		}else {
     			existSata.setNum(existSata.getNum()+1);
     			satasticDayMapper.updateByPrimaryKey(existSata);
     		}
     		
-    		if(mqttUtil != null) {
-    			log.info("mqtt publish1:"+  json.toString());
-    			mqttUtil.pub(CommonConstant.MQTT_PUBLISH_PREFIX+hospitalCode, json.toString());
+    		if(mqttUtil != null && !StringUtils.isEmpty(hospitalCode)) {
+    			JSONObject mqttJson = JSONObject.from(record);
+    			mqttJson.put("items", items);
+    			log.info("mqtt publish2:"+  mqttJson.toString());
+    			mqttUtil.pub(CommonConstant.MQTT_PUBLISH_PREFIX+hospitalCode, mqttJson.toString());
     		}
         } catch (Exception e) {
         	log.error("processMessage occurs error ", e);
@@ -281,11 +323,11 @@ public class AmqpClient2 {
     		String location = remoteUtil.localtion(mnc, lac, ci);
         	if(!StringUtils.isEmpty(location)) {
         		localJson =  JSONObject.parseObject(location);
-        		String newPoint = remoteUtil.getBaiduPoint(localJson.getString("lng"),localJson.getString("lat"));
+        		String newPoint = remoteUtil.getBaiduPoint2(localJson.getString("lng"),localJson.getString("lat"));
             	if(!StringUtils.isEmpty(newPoint)) {
             		JSONObject pointJson =  JSONObject.parseObject(newPoint);
-            		localJson.put("lng", pointJson.getString("x"));
-            		localJson.put("lat", pointJson.getString("y"));
+            		localJson.put("lng", pointJson.getDouble("x"));
+            		localJson.put("lat", pointJson.getDouble("y"));
             	}
             	staLocation = new StationLocation();
             	staLocation.setId(UUIDUtil.get32UUID());
@@ -298,17 +340,135 @@ public class AmqpClient2 {
             	staLocation.setRadius(localJson.getString("radius"));
             	staLocation.setCreatetime(date);
             	staLocation.setModifytime(date);
-            	stationLocationMapper.insert(staLocation);
+            	stationLocationService.add(staLocation);
         	}
     	}else {
     		localJson = new JSONObject();
-    		localJson.put("lng", staLocation.getLng());
-    		localJson.put("lat", staLocation.getLat());
+    		localJson.put("lng", Double.parseDouble(staLocation.getLng()));
+    		localJson.put("lat", Double.parseDouble(staLocation.getLat()));
     		localJson.put("address", staLocation.getAddress());
-    		localJson.put("radius", staLocation.getRadius());
+    		localJson.put("radius", Integer.parseInt(staLocation.getRadius()));
     	}
     	return localJson;
     }
+    
+    /**
+     * @title 验证产品模型
+     * @param productId
+     * @param items
+     * @return
+     */
+    private String modelValidate(String productId,JSONObject items) {
+    	 ModelDto dto = new ModelDto();
+         dto.setProductId(productId);
+         List<Model> models = modelMapper.select(dto);
+         List<Model> cmodels = modelMapper.selectCommon(new ModelDto());
+         models.addAll(cmodels);
+         JSONObject newItems = new JSONObject(items);
+         for(String key : newItems.keySet()) {
+        	 Optional<Model> result = models.stream().filter(m->m.getTitle().equals(key)).findAny();
+        	 if(!result.isPresent()) {
+        		 items.remove(key);
+        		 continue;
+        	 }
+				/*
+				 * Model m = result.get(); String resultStr =
+				 * validateOne(m,items.getString(key)); if(!StringUtils.isEmpty(resultStr)) {
+				 * return resultStr; }
+				 */
+         }         
+    	return "";
+    }
+    
+	private static String validateOne(Model m, String value) {
+		String title = m.getTitle();
+		JSONObject define = JSONObject.parseObject(m.getDefine());
+		JSONObject range = define.getJSONObject("range");
+		if (range == null) {
+			return "";
+		}
+		switch (m.getType()) {
+		case "int": {
+			Integer min = range.containsKey("min") ? range.getInteger("min") : null;
+			Integer max = range.containsKey("max") ? range.getInteger("max") : null;
+			//if (define.getBoolean("isArray")) {
+			if (false) {
+				if (!StringUtils.isEmpty(value)) {
+					String[] arr = value.split(",");
+					for (String s : arr) {
+						if (ReUtil.isMatch("^-?\\d*$", s)) {
+							int v = Integer.parseInt(s);
+							if ((min != null && min > v) || (max != null && max < v)) {
+								return "字段:" + title + " 数值超出范围";
+							}
+						}
+					}
+				}
+			} else {
+				if (ReUtil.isMatch("^-?\\d*$", value)) {
+					int v = Integer.parseInt(value);
+					if ((min != null && min > v) || (max != null && max < v)) {
+						return "字段:" + title + " 数值超出范围";
+					}
+				}
+			}
+			break;
+		}
+		case "float": {
+			Double min = range.containsKey("min") ? range.getDouble("min") : null;
+			Double max = range.containsKey("max") ? range.getDouble("max") : null;
+			//if (define.getBoolean("isArray")) {
+			if (false) {
+				if (!StringUtils.isEmpty(value)) {
+					String[] arr = value.split(",");
+					for (String s : arr) {
+						if (ReUtil.isMatch("^-?\\d+([.]?\\d+)?$", s)) {
+							Double v = Double.parseDouble(s);
+							if ((min != null && min > v) || (max != null && max < v)) {
+								return "字段:" + title + " 数值超出范围";
+							}
+						}
+					}
+				}
+			} else {
+				if (ReUtil.isMatch("^-?\\d+([.]?\\d+)?$", value)) {
+					Double v = Double.parseDouble(value);
+					if ((min != null && min > v) || (max != null && max < v)) {
+						return "字段:" + title + " 数值超出范围";
+					}
+				}
+			}
+			break;
+		}
+		case "String": {
+			Integer len = range.containsKey("len") ? range.getInteger("len") : null;
+//			if (define.getBoolean("isArray")) {
+			if (false) {
+					String[] arr = value.split(",");
+					for (String s : arr) {
+						if (len != null && len < s.length()) {
+							return "字段:" + title + " 数值超出范围";
+						}
+					}
+			} else {
+				if (len != null && len < value.length()) {
+					return "字段:" + title + " 数值超出范围";
+				}
+			}
+			break;
+		}
+		case "enum": {
+			//if (define.getBoolean("isArray")) {
+			if (false) {
+					
+			}  else if (!range.containsKey(Integer.parseInt(value))) {
+				return "字段:" + title + " 数值超出范围";
+			}
+			break;
+		}
+		}
+		return "";
+	}
     private static JmsConnectionListener jmsConnectionListener = new JmsConnectionListener() {
         /**
          * 连接成功建立。
@@ -375,4 +535,43 @@ public class AmqpClient2 {
     	}
     	json.replace("items", items);
     }
+    
+    public static void aliyunTranslate(JSONObject items) {
+    	items.put("networkType", 2);
+    	items.put("infusionId", items.get("classification"));
+    	items.put("ultimateDose", items.get("maxDose"));
+    	items.put("continueDose", items.get("flow"));
+    	items.put("appendDose", items.get("singleDose"));
+    	items.put("finishDose", items.get("finishedDose"));
+    	items.put("validTimes", items.get("pcaValid"));
+    	items.put("invalidTimes", items.get("pcaInvalid"));
+    	items.put("alarm", new int[] {items.getInteger("alarmStatus")});
+    	if(items.getInteger("warnLowBattery") == 1) {
+    		items.put("forcast", new int[]{3});
+    	}
+    	if(items.getInteger("warnAnalgesicPoor") == 1) {
+    		items.put("forcast", new int[]{2});
+    	}
+    	if(items.getInteger("warnWillFinished") == 1) {
+    		items.put("forcast", new int[]{1});
+    	}
+    	if(!items.containsKey("forcast")) {
+    		items.put("forcast", new int[]{0});
+    	}
+    	
+    	items.put("electric", items.get("electricQuantity"));
+    	
+    	items.put("finishDose", items.get("finishedDose"));
+    }
+    
+    public static JSONObject packItemsTime(JSONObject items, Long timestamp) {
+    	JSONObject newItems = new JSONObject();
+    	for(String key:items.keySet()) {
+    		JSONObject temp = new JSONObject();
+    		temp.put("value", items.get(key));
+    		temp.put("time", timestamp);
+    		newItems.put(key, temp);
+    	}
+    	return newItems;
+    }
 }

+ 2 - 0
src/main/java/com/tuoren/forward/constant/CommonConstant.java

@@ -29,6 +29,8 @@ public final class CommonConstant {
 	
 	public static final String CAPTCHA_REDIS_HASH = "captcha";
 	
+	public static final String CAPTCHA_REDIS_VERYFY = "veryfyCode";
+	
 	public static final String REQUEST_LOG_ATTR= "logAttr";
 	
 	public static final String REQUEST_TIME_ATTR = "timeAttr";

+ 13 - 0
src/main/java/com/tuoren/forward/controller/ModelController.java

@@ -7,6 +7,7 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
 
+import com.tuoren.forward.annotation.HandleLog;
 import com.tuoren.forward.entity.Model;
 import com.tuoren.forward.entity.req.IdReq;
 import com.tuoren.forward.entity.req.ModelSearchReq;
@@ -38,6 +39,16 @@ public class ModelController {
 		return modelService.search(req);
 	}
 	
+	@PostMapping("searchCommon")
+    @ResponseBody
+    @Operation(summary = "查询通用模型")
+	@Parameter(name="token",description = "token",required = true,in = ParameterIn.HEADER)
+	public ResultPage<Model> searchCommon(@RequestBody ModelSearchReq req){
+		log.info("searchCommon>>:{}",req);
+		return modelService.searchCommon(req);
+	}
+	
+	@HandleLog
 	@PostMapping("add")
     @ResponseBody
     @Operation(summary = "添加模型")
@@ -47,6 +58,7 @@ public class ModelController {
 		return modelService.add(req);
 	}
 	
+	@HandleLog
 	@PostMapping("edit")
     @ResponseBody
     @Operation(summary = "修改模型")
@@ -56,6 +68,7 @@ public class ModelController {
 		return modelService.edit(req);
 	}
 	
+	@HandleLog
 	@PostMapping("delete")
     @ResponseBody
     @Operation(summary = "删除模型")

+ 36 - 1
src/main/java/com/tuoren/forward/controller/OpenController.java

@@ -2,6 +2,7 @@ package com.tuoren.forward.controller;
 
 import java.util.concurrent.TimeUnit;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
@@ -9,6 +10,7 @@ import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 
 import com.tuoren.forward.annotation.HandleLog;
@@ -20,14 +22,19 @@ import com.tuoren.forward.entity.req.UserAddOpenReq;
 import com.tuoren.forward.entity.resp.CaptchaResp;
 import com.tuoren.forward.service.HospitalService;
 import com.tuoren.forward.service.UserService;
+import com.tuoren.forward.util.AliyunMessageUtil;
+import com.tuoren.forward.util.Result;
 import com.tuoren.forward.util.ResultData;
 import com.tuoren.forward.util.UUIDUtil;
 
 import cn.hutool.captcha.CaptchaUtil;
 import cn.hutool.captcha.ShearCaptcha;
 import cn.hutool.captcha.generator.MathGenerator;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.ReUtil;
 import cn.hutool.crypto.digest.DigestUtil;
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.extern.slf4j.Slf4j;
 
@@ -46,6 +53,9 @@ public class OpenController {
 	@Autowired
 	UserService userService;
 	
+	@Autowired
+	AliyunMessageUtil aliyunMessageUtil; 
+	
 	private final String SECRET = "yunzhineng";
 	
 //	@PostMapping("addHospital")
@@ -79,6 +89,7 @@ public class OpenController {
 		return userService.addBack(req);
 	}
 	
+	
 	@PostMapping("getCaptcha")
     @ResponseBody
     @Operation(summary = "获取验证码")
@@ -88,7 +99,7 @@ public class OpenController {
 		ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(150, 40, 4, 0);
 		captcha.setGenerator(new MathGenerator(1));
 		captcha.createCode();
-		redisTemplate.opsForHash().put("captcha", captchaKey, captcha.getCode());
+		redisTemplate.opsForHash().put(CommonConstant.CAPTCHA_REDIS_HASH, captchaKey, captcha.getCode());
 		redisTemplate.expire(CommonConstant.CAPTCHA_REDIS_HASH, 2,TimeUnit.MINUTES); //2分钟过期
 		String base64String = "data:image/png;base64,"+captcha.getImageBase64();
 		CaptchaResp resp = new CaptchaResp();
@@ -97,6 +108,30 @@ public class OpenController {
 		return ResultData.success(resp);
 	}
 	
+	@PostMapping("sendVeryCode")
+    @ResponseBody
+    @Operation(summary = "发送手机验证码")
+	@Parameter(name="mobile",description = "手机号码")
+	public Result sendVeryfyCode(@RequestParam String mobile){
+		log.info("sendVeryfyCode>>:"+mobile);
+		if(StringUtils.isEmpty(mobile)) {
+			return Result.fail("手机号码不能为空");
+		}
+		if(!ReUtil.isMatch("^1\\d{10}$", mobile)) {
+			return Result.fail("手机格式错误");
+		}
+		String verifyCode = (String) redisTemplate.opsForHash().get(CommonConstant.CAPTCHA_REDIS_VERYFY, mobile);
+		if(!StringUtils.isEmpty(verifyCode)) {
+			return Result.fail("验证码已发送,请五分钟后再试");
+		}
+		String code = RandomUtil.randomNumbers(4);
+		aliyunMessageUtil.sendVeryCode(mobile, code);
+		redisTemplate.opsForHash().put(CommonConstant.CAPTCHA_REDIS_VERYFY, mobile, code);
+		redisTemplate.expire(CommonConstant.CAPTCHA_REDIS_VERYFY, 5,TimeUnit.MINUTES); //5分钟过期
+		return Result.success();
+	}
+	
+	
 	public static void main(String[] args) {
 		String content="test3&yunzhineng";
 		String md5Hex1 = DigestUtil.md5Hex(content);

+ 71 - 0
src/main/java/com/tuoren/forward/controller/StationLocationController.java

@@ -0,0 +1,71 @@
+package com.tuoren.forward.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.tuoren.forward.annotation.HandleLog;
+import com.tuoren.forward.entity.StationLocation;
+import com.tuoren.forward.entity.req.IdReq;
+import com.tuoren.forward.entity.req.StationLocationReq;
+import com.tuoren.forward.service.StationLocationService;
+import com.tuoren.forward.util.Result;
+import com.tuoren.forward.util.ResultPage;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Controller
+@RequestMapping("stationLocation")
+@Tag(name="基站接口")
+public class StationLocationController {
+
+	@Autowired
+	StationLocationService stationLocationService;
+	
+	@PostMapping("search")
+    @ResponseBody
+    @Operation(summary = "查询基站信息")
+	@Parameter(name="token",description = "token",required = true,in = ParameterIn.HEADER)
+	public ResultPage<StationLocation> search(@RequestBody StationLocationReq req){
+		log.info("search>>:{}",req);
+		return stationLocationService.search(req);
+	}
+	
+	@HandleLog
+	@PostMapping("add")
+    @ResponseBody
+    @Operation(summary = "添加基站信息")
+	@Parameter(name="token",description = "token",required = true,in = ParameterIn.HEADER)
+	public Result add(@RequestBody StationLocation req){
+		log.info("search>>:{}",req);
+		return stationLocationService.add(req);
+	}
+	
+	@HandleLog
+	@PostMapping("edit")
+    @ResponseBody
+    @Operation(summary = "修改基站信息")
+	@Parameter(name="token",description = "token",required = true,in = ParameterIn.HEADER)
+	public Result edit(@RequestBody StationLocation req){
+		log.info("search>>:{}",req);
+		return stationLocationService.edit(req);
+	}
+	
+	@HandleLog
+	@PostMapping("delete")
+    @ResponseBody
+    @Operation(summary = "删除基站信息")
+	@Parameter(name="token",description = "token",required = true,in = ParameterIn.HEADER)
+	public Result delete(@RequestBody IdReq req){
+		log.info("search>>:{}",req);
+		return stationLocationService.delete(req.getId());
+	}
+}

+ 17 - 0
src/main/java/com/tuoren/forward/controller/UserController.java

@@ -13,6 +13,7 @@ import com.tuoren.forward.entity.User;
 import com.tuoren.forward.entity.req.IdReq;
 import com.tuoren.forward.entity.req.LoginReq;
 import com.tuoren.forward.entity.req.UserAddReq;
+import com.tuoren.forward.entity.req.UserEditPwdReq;
 import com.tuoren.forward.entity.req.UserEditSelfReq;
 import com.tuoren.forward.entity.req.UserSearchReq;
 import com.tuoren.forward.entity.resp.LoginResp;
@@ -46,6 +47,22 @@ public class UserController {
 		return userService.login(req);
 	}
 	
+	@PostMapping("register")
+    @ResponseBody
+    @Operation(summary = "注册用户")
+	public Result register(@RequestBody UserAddReq req){
+		log.info("register>>:{}",req);
+		return userService.register(req);
+	}
+	
+	@PostMapping("editPassword")
+    @ResponseBody
+    @Operation(summary = "修改密码")
+	public Result editPassword(@RequestBody UserEditPwdReq req){
+		log.info("editPassword>>:{}",req);
+		return userService.editPassword(req);
+	}
+	
 	@PostMapping("logout")
     @ResponseBody
     @Operation(summary = "退出登录")

+ 8 - 0
src/main/java/com/tuoren/forward/entity/Model.java

@@ -1,5 +1,7 @@
 package com.tuoren.forward.entity;
 
+import java.util.Date;
+
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
@@ -32,4 +34,10 @@ public class Model {
     
     @Schema(description = "租户ID")
     private String tenantId;
+    
+    @Schema(description = "创建时间")
+    private Date createtime;
+    
+    @Schema(description = "修改时间")
+    private Date modifytime;
 }

+ 3 - 0
src/main/java/com/tuoren/forward/entity/Permission.java

@@ -29,4 +29,7 @@ public class Permission {
 
     @Schema(description = "资源图标")
     private String icon;
+    
+    @Schema(description = "别名")
+    private String name;
 }

+ 20 - 0
src/main/java/com/tuoren/forward/entity/dto/StationLocationDto.java

@@ -0,0 +1,20 @@
+package com.tuoren.forward.entity.dto;
+
+import com.tuoren.forward.entity.StationLocation;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+@Data
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+public class StationLocationDto extends StationLocation{
+
+	private String sort;  //排序字段
+	
+	private String order; //排序方式, 'asc':升序, 'desc':降序
+	
+	private String keyWord; //搜索内容
+	
+}

+ 9 - 0
src/main/java/com/tuoren/forward/entity/req/DeviceRecordSearchReq.java

@@ -19,4 +19,13 @@ public class DeviceRecordSearchReq extends PageReq{
 	
 	@Schema(description = "mac")
     private String mac;
+	
+	@Schema(description = "items过滤字段,多字段以逗号隔开,如 field1,field2")
+    private String filter;
+	
+	@Schema(description = "开始时间,时间戳,精确到毫秒")
+	private Long startTimestamp;
+	
+	@Schema(description = "结束时间,时间戳,精确到毫秒")
+	private Long endTimestamp;
 }

+ 17 - 0
src/main/java/com/tuoren/forward/entity/req/StationLocationReq.java

@@ -0,0 +1,17 @@
+package com.tuoren.forward.entity.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+@Data
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = true)
+@Schema(description="基站地址请求")
+public class StationLocationReq extends PageReq{
+
+	@Schema(description = "搜索内容")
+    private String keyWord;
+	
+}

+ 3 - 0
src/main/java/com/tuoren/forward/entity/req/UserAddOpenReq.java

@@ -9,6 +9,9 @@ public class UserAddOpenReq {
 	
 	@Schema(description = "用户名")
     private String username;
+	
+	@Schema(description = "密码")
+    private String password;
 
     @Schema(description = "电话")
     private String mobile;

+ 6 - 0
src/main/java/com/tuoren/forward/entity/req/UserAddReq.java

@@ -14,9 +14,15 @@ public class UserAddReq {
 	
 	@Schema(description = "用户名")
     private String username;
+	
+	@Schema(description = "密码")
+    private String password;
 
     @Schema(description = "电话")
     private String mobile;
+    
+    @Schema(description = "验证码")
+    private String veryfyCode;
 
     @Schema(description = "邮箱")
     private String email;

+ 19 - 0
src/main/java/com/tuoren/forward/entity/req/UserEditPwdReq.java

@@ -0,0 +1,19 @@
+package com.tuoren.forward.entity.req;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+@Schema(description = "用户")
+public class UserEditPwdReq {
+
+	@Schema(description = "密码")
+    private String password;
+
+    @Schema(description = "电话")
+    private String mobile;
+    
+    @Schema(description = "验证码")
+    private String veryfyCode;
+    
+}

+ 3 - 0
src/main/java/com/tuoren/forward/entity/resp/DeviceResp.java

@@ -14,4 +14,7 @@ public class DeviceResp extends Device{
 	
 	@Schema(description = "产品名称")
 	private String productName;
+	
+	@Schema(description = "设备用户")
+	private String username;
 }

+ 1 - 1
src/main/java/com/tuoren/forward/interceptor/MybatisInterceptor.java

@@ -104,7 +104,7 @@ public class MybatisInterceptor implements Interceptor {
 
         StringBuilder sb = new StringBuilder(originalSql);
         limitValue = "'"+limitValue+"'";
-        int index = StringUtils.indexOfAny(sb, "where","WHERE");
+        int index = StringUtils.lastIndexOfAny(sb, "where","WHERE");
         if (index < 0) {
         	int orderIndex = sb.indexOf("order");
         	if(orderIndex < 0) {

+ 13 - 2
src/main/java/com/tuoren/forward/mapper/ModelMapper.java

@@ -2,7 +2,8 @@ package com.tuoren.forward.mapper;
 
 import java.util.List;
 
-import com.tuoren.forward.annotation.SqlLimit;
+import org.apache.ibatis.annotations.Param;
+
 import com.tuoren.forward.entity.Model;
 import com.tuoren.forward.entity.dto.ModelDto;
 
@@ -16,9 +17,19 @@ public interface ModelMapper {
 
     Model selectByPrimaryKey(String id);
     
-    Model selectByTitle(String title);
+    Model selectCommonByTitle(String title);
+    
+    Model selectCommonByCode(String code);
+    
+    Model selectCommonOne(@Param("title") String title,@Param("code") Integer code);
+    
+    Model selectByProductIdAndTitle(@Param("productId") String productId, @Param("title") String title);
+    
+    Model selectOne(@Param("productId") String productId, @Param("title") String title,@Param("code") Integer code);
     
     List<Model> select(ModelDto row);
+    
+    List<Model> selectCommon(ModelDto row);
 
     int updateByPrimaryKeySelective(Model row);
 

+ 1 - 1
src/main/java/com/tuoren/forward/mapper/ProductMapper.java

@@ -6,7 +6,7 @@ import com.tuoren.forward.annotation.SqlLimit;
 import com.tuoren.forward.entity.Product;
 import com.tuoren.forward.entity.dto.ProductDto;
 
-@SqlLimit
+//@SqlLimit
 public interface ProductMapper {
 	
     int deleteByPrimaryKey(String id);

+ 5 - 0
src/main/java/com/tuoren/forward/mapper/StationLocationMapper.java

@@ -1,8 +1,11 @@
 package com.tuoren.forward.mapper;
 
+import java.util.List;
+
 import org.apache.ibatis.annotations.Param;
 
 import com.tuoren.forward.entity.StationLocation;
+import com.tuoren.forward.entity.dto.StationLocationDto;
 
 public interface StationLocationMapper {
     int deleteByPrimaryKey(String id);
@@ -15,6 +18,8 @@ public interface StationLocationMapper {
     
     StationLocation selectOne(@Param("mnc")String mnc, @Param("lac")String lac, @Param("ci")String ci);
 
+    List<StationLocation> select(StationLocationDto row);
+    
     int updateByPrimaryKeySelective(StationLocation row);
 
     int updateByPrimaryKey(StationLocation row);

+ 6 - 0
src/main/java/com/tuoren/forward/mapper/UserMapper.java

@@ -2,6 +2,8 @@ package com.tuoren.forward.mapper;
 
 import java.util.List;
 
+import org.apache.ibatis.annotations.Param;
+
 import com.tuoren.forward.entity.User;
 import com.tuoren.forward.entity.dto.UserDto;
 
@@ -16,6 +18,10 @@ public interface UserMapper {
     
     User selectByUsername(String username);
     
+    User selectByMobile(String mobile);
+    
+    User selectOneOr(@Param("username") String username, @Param("mobile") String mobile);
+    
     User selectByCode(String code);
     
     List<User> select(UserDto row);

+ 20 - 3
src/main/java/com/tuoren/forward/service/DeviceService.java

@@ -2,6 +2,7 @@ package com.tuoren.forward.service;
 
 import java.util.Date;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
@@ -119,16 +120,32 @@ public class DeviceService {
 		}
 		if(!StringUtils.isEmpty(req.getKeyWord())) {
 			query.addCriteria(new Criteria().orOperator(
-					Criteria.where("deviceId").regex(req.getKeyWord())
+					Criteria.where("deviceId").regex(req.getKeyWord()),Criteria.where("deviceMac").regex(req.getKeyWord())
 				));
 		}
-		long totol = mongoTemplate.count(query, "device_record");
+		if(req.getStartTimestamp() != null && req.getEndTimestamp() != null ) {
+			query.addCriteria(Criteria.where("time").gte(req.getStartTimestamp()).lte(req.getEndTimestamp()));
+		}
+
+		long total = mongoTemplate.count(query, "device_record");
 		query.with(Sort.by(Sort.Direction.DESC, "time"));
 		int skip = (req.getPage()-1)*req.getSize();
 		query.skip(skip);
 		query.limit(req.getSize());
 		List<JSONObject> results = mongoTemplate.find(query, JSONObject.class, "device_record");
-		return ResultPage.success(results, totol);
+		if(!StringUtils.isEmpty(req.getFilter())) {
+			String[] fields = req.getFilter().split(",");
+			List<JSONObject> results2 = results.stream().map(item->{
+				JSONObject json = new JSONObject();
+				JSONObject items = item.getJSONObject("items");
+				for(String filed : fields) {
+					json.put(filed, items.get(filed));
+				}
+				return json;
+			}).collect(Collectors.toList());
+			return ResultPage.success(results2, total);
+		}
+		return ResultPage.success(results, total);
 	}
 	
 	/**

+ 2 - 0
src/main/java/com/tuoren/forward/service/LogService.java

@@ -32,4 +32,6 @@ public class LogService {
 		List<Log> logs = logMapper.select(dto);
 		return ResultPage.success(logs, page.getTotal());
 	}
+	
+	
 }

+ 41 - 6
src/main/java/com/tuoren/forward/service/ModelService.java

@@ -1,7 +1,9 @@
 package com.tuoren.forward.service;
 
+import java.util.Date;
 import java.util.List;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -36,19 +38,43 @@ public class ModelService {
 		return ResultPage.success(models,page.getTotal());
 	}
 	
+	/**
+	 * @title 查询通用产品模型
+	 * @param req
+	 * @return ResultPage<Model>
+	 */
+	public ResultPage<Model> searchCommon(ModelSearchReq req){
+		Page<Object> page = PageHelper.startPage(req.getPage(), req.getSize());
+		ModelDto dto = new ModelDto();
+		BeanUtils.copyProperties(req, dto);
+		List<Model> models = modelMapper.selectCommon(dto);
+		return ResultPage.success(models,page.getTotal());
+	}
+	
 	/**
 	 * @title 添加模型
 	 * @param req
 	 * @return Result
 	 */
 	public Result add(Model req) {
-		String userId = AccessTokenUtil.getUserId();
-		Model exist = modelMapper.selectByTitle(req.getTitle());
+		if(StringUtils.isEmpty(req.getTitle()) || req.getCode() == null){
+			return Result.fail("编码或标识不能为空");
+		}
+		Model exist = modelMapper.selectCommonOne(req.getTitle(),req.getCode());
 		if(exist != null) {
-			return Result.fail("模型数据存在");
+			return Result.fail("编码或标识已存在");
 		}
+		String productId = req.getProductId();
+		if(!StringUtils.isEmpty(productId)) {
+			Model exist2 = modelMapper.selectOne(productId,req.getTitle(),req.getCode());
+			if(exist2 != null) {
+				return Result.fail("编码或标识已存在");
+			}
+		}
+		String userId = AccessTokenUtil.getUserId();
 		req.setId(UUIDUtil.get32UUID());
 		req.setTenantId(userId);
+		req.setCreatetime(new Date());
 		modelMapper.insertSelective(req);
 		return Result.success();
 	}
@@ -59,12 +85,21 @@ public class ModelService {
 	 * @return Result
 	 */
 	public Result edit(Model req) {
-		Model exist = modelMapper.selectByTitle(req.getTitle());
+		if(StringUtils.isEmpty(req.getTitle()) || req.getCode() == null){
+			return Result.fail("编码或标识不能为空");
+		}
+		Model exist = modelMapper.selectCommonOne(req.getTitle(),req.getCode());
 		if(exist != null && !exist.getId().equals(req.getId())) {
 			return Result.fail("模型数据存在");
 		}
-		req.setProductId(null);
-		req.setTenantId(null);
+		String productId = req.getProductId();
+		if(!StringUtils.isEmpty(productId)) {
+			Model exist2 = modelMapper.selectOne(productId,req.getTitle(),req.getCode());
+			if(exist2 != null && !exist2.getId().equals(req.getId())) {
+				return Result.fail("模型数据存在");
+			}
+		}
+		req.setModifytime(new Date());
 		modelMapper.updateByPrimaryKeySelective(req);
 		return Result.success();
 	}

+ 89 - 0
src/main/java/com/tuoren/forward/service/StationLocationService.java

@@ -0,0 +1,89 @@
+package com.tuoren.forward.service;
+
+import java.util.Date;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
+import com.tuoren.forward.entity.StationLocation;
+import com.tuoren.forward.entity.dto.StationLocationDto;
+import com.tuoren.forward.entity.req.StationLocationReq;
+import com.tuoren.forward.mapper.StationLocationMapper;
+import com.tuoren.forward.util.Result;
+import com.tuoren.forward.util.ResultPage;
+import com.tuoren.forward.util.UUIDUtil;
+
+@Service
+public class StationLocationService {
+	
+	@Autowired
+	StationLocationMapper stationLocationMapper;
+	
+	/**
+	 * @title 查询基站地址
+	 * @param req
+	 * @return
+	 */
+	public ResultPage<StationLocation> search(StationLocationReq req){
+		Page<Object> page = PageHelper.startPage(req.getPage(), req.getSize());
+		StationLocationDto dto = new StationLocationDto();
+		BeanUtils.copyProperties(req, dto);
+		List<StationLocation> list = stationLocationMapper.select(dto);
+		return ResultPage.success(list, page.getTotal());
+	}
+	
+	/**
+	 * @title 添加基站信息
+	 * @param req
+	 * @return
+	 */
+	@Transactional(rollbackFor = Throwable.class,isolation = Isolation.SERIALIZABLE)
+	public Result add(StationLocation req) {
+		if(StringUtils.isEmpty(req.getCi()) || StringUtils.isEmpty(req.getLac())) {
+			return Result.fail("ci,lac 不能为空");
+		}
+		StationLocation exist = stationLocationMapper.selectOne(req.getMnc()==null?"00":req.getMnc(), req.getLac(),req.getCi());
+		if(exist != null) {
+			return Result.fail("基站信息已存在");
+		}
+		req.setId(UUIDUtil.get32UUID());
+		req.setCreatetime(new Date());
+		stationLocationMapper.insertSelective(req);
+		return Result.success();
+	}
+	
+	/**
+	 * @title 修改基站信息
+	 * @param req
+	 * @return
+	 */
+	public Result edit(StationLocation req) {
+		if(StringUtils.isEmpty(req.getCi()) || StringUtils.isEmpty(req.getLac())) {
+			return Result.fail("ci,lac 不能为空");
+		}
+		StationLocation exist = stationLocationMapper.selectOne(req.getMnc()==null?"00":req.getMnc(), req.getLac(),req.getCi());
+		if(exist != null && !exist.getId().equals(req.getId())) {
+			return Result.fail("基站信息已存在");
+		}
+		req.setModifytime(new Date());
+		stationLocationMapper.updateByPrimaryKeySelective(req);
+		return Result.success();
+	}
+	
+	/*
+	 * @title 删除产品 
+	 * @param id
+	 * @return
+	 */
+	public Result delete(String id) {
+		stationLocationMapper.deleteByPrimaryKey(id);
+		return Result.success();
+	}
+}

+ 70 - 4
src/main/java/com/tuoren/forward/service/UserService.java

@@ -20,6 +20,7 @@ import com.tuoren.forward.entity.dto.UserDto;
 import com.tuoren.forward.entity.req.LoginReq;
 import com.tuoren.forward.entity.req.UserAddOpenReq;
 import com.tuoren.forward.entity.req.UserAddReq;
+import com.tuoren.forward.entity.req.UserEditPwdReq;
 import com.tuoren.forward.entity.req.UserEditSelfReq;
 import com.tuoren.forward.entity.req.UserSearchReq;
 import com.tuoren.forward.entity.resp.LoginResp;
@@ -169,7 +170,7 @@ public class UserService {
     			return Result.fail("用户编码存在");
     		}
     	}
-        User existUser = userMapper.selectByUsername(user.getUsername());
+        User existUser = userMapper.selectOneOr(user.getUsername(),user.getMobile());
         if(existUser==null){
         	user.setId(UUIDUtil.get32UUID());
             user.setPassword(MD5Util.encode32(CommonConstant.INI_PWD));
@@ -191,6 +192,71 @@ public class UserService {
         }		
 	}
 	
+	@Transactional
+	public Result register(UserAddReq req) {
+		User user = new User();
+    	BeanUtils.copyProperties(req, user);
+    	if(StringUtils.isEmpty(req.getMobile()) || StringUtils.isEmpty(req.getVeryfyCode())) {
+    		return Result.fail("手机号或验证码不能为空");
+    	}
+    	String verifyCode = (String) redisTemplate.opsForHash().get(CommonConstant.CAPTCHA_REDIS_VERYFY, req.getMobile());
+		if(!req.getVeryfyCode().equals(verifyCode)) {
+			return Result.fail("验证码错误");
+		}
+    	if(StringUtils.isEmpty(req.getCode())) {
+    		user.setCode(UUIDUtil.getUniqStr().toUpperCase());
+    	}else {
+    		User record = userMapper.selectByCode(req.getCode());
+    		if(record !=null) {
+    			return Result.fail("用户编码存在");
+    		}
+    	}
+    	User existUser = userMapper.selectOneOr(user.getUsername(),user.getMobile());
+        if(existUser==null){
+        	user.setId(UUIDUtil.get32UUID());
+        	if(StringUtils.isEmpty(req.getPassword())) {
+        		user.setPassword(MD5Util.encode32(CommonConstant.INI_PWD));
+        	}else {
+        		user.setPassword(MD5Util.encode32(req.getPassword()));
+        	}
+            user.setCreatetime(new Date());
+            userMapper.insertSelective(user);
+            UserRole ur = new UserRole();
+         	ur.setUserId(user.getId());
+         	ur.setRoleId(CommonConstant.ROLE_USER);
+         	userRoleMapper.insert(ur);
+            return Result.success();
+        }else {
+        	return Result.fail("用户已存在");
+        }		
+	}
+	
+	/**
+	 * @title 修改密码
+	 * @param req
+	 * @return
+	 */
+	@Transactional
+	public Result editPassword(UserEditPwdReq req) {
+		User user = new User();
+    	BeanUtils.copyProperties(req, user);
+    	if(StringUtils.isEmpty(req.getMobile()) || StringUtils.isEmpty(req.getVeryfyCode()) || StringUtils.isEmpty(req.getPassword())) {
+    		return Result.fail(CommonConstant.LACK_PARAM);
+    	}
+    	String verifyCode = (String) redisTemplate.opsForHash().get(CommonConstant.CAPTCHA_REDIS_VERYFY, req.getMobile());
+		if(!req.getVeryfyCode().equals(verifyCode)) {
+			return Result.fail("验证码错误");
+		}
+    	User existUser = userMapper.selectByMobile(user.getMobile());
+        if(existUser==null){
+        	return Result.fail("用户不存在");
+        }
+        user.setId(existUser.getId());
+        user.setPassword(MD5Util.encode32(req.getPassword()));
+        userMapper.updateByPrimaryKeySelective(user);
+        return Result.success();
+	}
+	
 	@Transactional
 	public ResultData<User> addBack(UserAddOpenReq req) {
 		User user = new User();
@@ -203,7 +269,7 @@ public class UserService {
     			return ResultData.failNull("用户编码存在");
     		}
     	}
-        User existUser = userMapper.selectByUsername(user.getUsername());
+    	User existUser = userMapper.selectOneOr(user.getUsername(),user.getMobile());
         if(existUser==null){
         	user.setId(UUIDUtil.get32UUID());
             user.setPassword(MD5Util.encode32(CommonConstant.INI_PWD));
@@ -223,10 +289,10 @@ public class UserService {
 	
 	@Transactional(rollbackFor = Exception.class)
 	public Result edit(UserAddReq req) {
-		User existUser = userMapper.selectByUsername(req.getUsername());
+		User existUser = userMapper.selectOneOr(req.getUsername(),req.getMobile());
 		User existUser2 = userMapper.selectByCode(req.getCode());
 		if(existUser != null && !existUser.getId().equals(req.getId())) {
-			return Result.fail("用户存在");
+			return Result.fail("用户存在");
 		}
 		if(existUser2 != null && !existUser2.getId().equals(req.getId())) {
 			return Result.fail("用户编码存在");

+ 66 - 0
src/main/java/com/tuoren/forward/util/AliyunMessageUtil.java

@@ -0,0 +1,66 @@
+package com.tuoren.forward.util;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import com.aliyun.dysmsapi20170525.Client;
+import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
+import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
+import com.aliyun.teaopenapi.models.Config;
+import com.aliyun.teautil.models.RuntimeOptions;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Component
+public class AliyunMessageUtil {
+	
+	@Value("${aliyun2.accessKey}")
+	private String accessKey;
+	@Value("${aliyun2.accessSecret}")
+    private String accessSecret;
+	
+	private Client client = null;
+	
+	 /**
+     * 使用AK&SK初始化账号Client
+     * @param accessKeyId
+     * @param accessKeySecret
+     * @return Client
+     * @throws Exception
+     */
+    public  Client createClient() throws Exception {
+        // 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
+        // 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html。
+        Config config = new Config()
+                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
+                .setAccessKeyId(accessKey)
+                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
+                .setAccessKeySecret(accessSecret);
+        // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
+        config.endpoint = "dysmsapi.aliyuncs.com";
+        return new Client(config);
+    }
+
+    public void sendVeryCode(String phoneNum,String code) {
+        
+        try {
+        	if(client == null) {
+        		client =  createClient();
+        	}
+            SendSmsRequest sendSmsRequest = new SendSmsRequest()
+                    .setSignName("驼人医疗")
+                    .setTemplateCode("SMS_463623523")
+                    .setPhoneNumbers(phoneNum)
+                    .setTemplateParam("{\"code\":\""+code+"\"}");
+            RuntimeOptions runtime = new RuntimeOptions();
+            SendSmsResponse resp = client.sendSmsWithOptions(sendSmsRequest, runtime);
+            com.aliyun.teaconsole.Client.log(com.aliyun.teautil.Common.toJSONString(resp));
+        } catch (Exception error) {
+            // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
+            // 错误 message
+        	log.error(error.getMessage());
+        }   
+    }
+    
+}

+ 8 - 12
src/main/java/com/tuoren/forward/util/RemoteUtil.java

@@ -50,7 +50,7 @@ public class RemoteUtil {
 	    MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
 	    map.add("coords", lng+","+lat);
 	    map.add("from", "1");
-	    map.add("ak","UZyauBmbunmSuxGmKedUXmrkNjq5WVKr");
+	    map.add("ak","TmUu5RYmGQ7GrYiZsuwndASTQMLYz8KF");
 	    
 	    HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
 	    
@@ -68,18 +68,13 @@ public class RemoteUtil {
 		return "";
 	}
 	
-	public String getBaiduPoint2(String lng,String lat) {
-		HttpHeaders headers = new HttpHeaders();
-	    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
-	    
-	    MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
-	    map.add("coords", lng+","+lat);
-	    map.add("model", "1");
-	    map.add("ak","UZyauBmbunmSuxGmKedUXmrkNjq5WVKr");
-	    
-	    HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
+	public String getBaiduPoint2(String lng,String lat) {	    
+	    StringBuffer param =new StringBuffer("coords="+lng+","+lat);
+	    param.append("&model=2");
+	    param.append("&ak=UZyauBmbunmSuxGmKedUXmrkNjq5WVKr");
 	    
-		String result = restTemplate.postForObject("https://api.map.baidu.com/geoconv/v2/", request, String.class);
+	    String url = "https://api.map.baidu.com/geoconv/v2/?"+param.toString();
+		String result = restTemplate.getForObject(url, String.class);
 		System.out.println("result========="+result);
 		JSONObject json = JSONObject.parseObject(result);
 		if(json.containsKey("result")) {
@@ -92,6 +87,7 @@ public class RemoteUtil {
 		}
 		return "";
 	}
+
 	
 	public String getHospitalCode(String mac) {
 

+ 1 - 12
src/main/resources/application.yml

@@ -115,7 +115,7 @@ aliyun1:
 aliyun2: 
   accessKey: LTAI4G7FA9ytMc76oNkJ45YJ
   accessSecret: R7hOvMfiHb0PYroDqUDXAYgB9htQss
-  consumerGroupId: RJeEjZ6TroTZ5TDrdRYP000100
+  consumerGroupId: AQ2Lk4saOGHYWBzJa39c000100
   iotInstanceId: iot-060a0bgd
   clientId: fe80aba1dfd66b3576ce
   amqpHost: iot-060a0bgd.amqp.iothub.aliyuncs.com
@@ -149,17 +149,6 @@ spring:
         maximum-pool-size: 10
         idle-timeout: 600000
         pool-name: HikariCP-primary
-    nb:
-      url: jdbc:mysql://47.101.214.91:7001/nbnetpump?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
-      username: root
-      password: Tuoren123.
-      driver-class-name: com.mysql.cj.jdbc.Driver
-      # 连接池配置
-      hikari:
-        connection-timeout: 30000
-        maximum-pool-size: 10
-        idle-timeout: 600000
-        pool-name: HikariCP-nb
   flyway:
     #是否启用
     enabled: true

+ 30 - 0
src/main/resources/db/migration/V1.0.2__modle_update.sql

@@ -0,0 +1,30 @@
+update device set data = null;
+
+ALTER TABLE `forward`.`model` 
+ADD COLUMN `createtime` DATETIME NULL COMMENT '创建时间' AFTER `tenant_id`,
+ADD COLUMN `modifytime` DATETIME NULL COMMENT '修改时间' AFTER `createtime`;
+
+update model set createtime='2024-04-09 13:47:58';
+
+ALTER TABLE `forward`.`permission` 
+ADD COLUMN `name` VARCHAR(45) NULL COMMENT '别名' AFTER `icon`;
+
+UPDATE `forward`.`role` SET `id` = 'developer', `name` = '开发人员', `description` = '开发人员' WHERE (`id` = 'worker');
+
+LOCK TABLES `permission` WRITE;
+/*!40000 ALTER TABLE `permission` DISABLE KEYS */;
+INSERT INTO `permission` VALUES (4,0,'home','01',NULL,'管理员首页',0,NULL,'系统首页'),(5,0,'product','01','/product','产品管理',10,NULL,'产品管理'),(6,5,'product::add','03','/product/add','添加产品',20,NULL,'添加产品'),(15,0,'device','01','/device','设备管理相关功能',1,NULL,'设备管理');
+/*!40000 ALTER TABLE `permission` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Dumping data for table `role_permission`
+--
+
+LOCK TABLES `role_permission` WRITE;
+/*!40000 ALTER TABLE `role_permission` DISABLE KEYS */;
+INSERT INTO `role_permission` VALUES ('developer',4),('developer',5),('developer',15),('manager',4),('manager',5),('manager',6),('manager',15),('user',4),('user',5),('user',15);
+/*!40000 ALTER TABLE `role_permission` ENABLE KEYS */;
+UNLOCK TABLES;
+
+

+ 3 - 3
src/main/resources/mapper/DeviceMapper.xml

@@ -61,10 +61,10 @@
   <select id="select" parameterType="DeviceDto" resultType="DeviceResp">
     select 
     <include refid="Base_Column_Relation" />,
-    p.name productName
+    p.name productName,u.username
     from device d
-    left join product p
-    on d.product_id = p.id
+    left join product p on d.product_id = p.id
+    left join user u on d.tenant_id = u.id
     <where>
     	<if test="keyWord != null and keyWord != ''">
     		(

+ 3 - 0
src/main/resources/mapper/LogMapper.xml

@@ -65,6 +65,9 @@
     delete from log
     where id = #{id,jdbcType=VARCHAR}
   </delete>
+  <delete id="clear" >
+    truncate table  log
+  </delete>
   <insert id="insert" parameterType="com.tuoren.forward.entity.Log">
     insert into log (id, ip, userid, 
       username, module, operation, 

+ 83 - 9
src/main/resources/mapper/ModelMapper.xml

@@ -11,9 +11,11 @@
     <result column="remark" jdbcType="VARCHAR" property="remark" />
     <result column="define" jdbcType="VARCHAR" property="define" />
     <result column="tenant_id" jdbcType="VARCHAR" property="tenantId" />
+    <result column="createtime" jdbcType="TIMESTAMP" property="createtime" />
+    <result column="modifytime" jdbcType="TIMESTAMP" property="modifytime" />
   </resultMap>
   <sql id="Base_Column_List">
-    id,code, product_id, name, title, type, remark,define,tenant_id
+    id,code, product_id, name, title, type, remark,define,tenant_id,createtime,modifytime
   </sql>
   <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
     select 
@@ -21,20 +23,53 @@
     from model
     where id = #{id,jdbcType=VARCHAR}
   </select>
-  <select id="selectByTitle" parameterType="java.lang.String" resultMap="BaseResultMap">
+  <select id="selectCommonByTitle" parameterType="java.lang.String" resultMap="BaseResultMap">
     select 
     <include refid="Base_Column_List" />
     from model
-    where title = #{title,jdbcType=VARCHAR} limit 1
+    where (product_id is null or product_id = '') and title = #{title,jdbcType=VARCHAR} limit 1
+  </select>
+  <select id="selectCommonByCode" parameterType="java.lang.Integer" resultMap="BaseResultMap">
+    select 
+    <include refid="Base_Column_List" />
+    from model
+    where (product_id is null or product_id = '') and code = #{code,jdbcType=INTEGER} limit 1
+  </select>
+  <select id="selectCommonOne"  resultMap="BaseResultMap">
+    select 
+    <include refid="Base_Column_List" />
+    from model
+    where (product_id is null or product_id = '') 
+    	and (title = #{title,jdbcType=VARCHAR} or code = #{code,jdbcType=INTEGER}) 
+    limit 1
+  </select>
+  <select id="selectByProductIdAndTitle" parameterType="java.lang.String" resultMap="BaseResultMap">
+    select 
+    <include refid="Base_Column_List" />
+    from model
+    where product_id = #{productId,jdbcType=VARCHAR} and title = #{title,jdbcType=VARCHAR} limit 1
+  </select>
+   <select id="selectOne"  resultMap="BaseResultMap">
+    select 
+    <include refid="Base_Column_List" />
+    from model
+    where product_id = #{productId,jdbcType=VARCHAR} 
+    	and (title = #{title,jdbcType=VARCHAR} or code = #{code,jdbcType=INTEGER}) 
+    limit 1
   </select>
   <select id="select" parameterType="com.tuoren.forward.entity.dto.ModelDto" resultMap="BaseResultMap">
     select 
     <include refid="Base_Column_List" />
     from model
     <where>
-        <if test = "productId !=null and productId != ''">
-        	product_id = #{productId,jdbcType=VARCHAR}
-        </if>
+     <choose>
+	       <when test=" productId !=null and productId != ''">
+	           product_id = #{productId,jdbcType=VARCHAR}
+	      </when>
+	     <otherwise>
+	          product_id is not null and product_id !=''
+	     </otherwise>
+	</choose>
     	<if test="keyWord != null and keyWord != ''">
     		and (
 	    		name like CONCAT('%',#{keyWord,jdbcType=VARCHAR},'%')
@@ -48,17 +83,36 @@
 			<if test="order != null "> ${order}</if>
 	</if>
   </select>
+  
+  <select id="selectCommon"  parameterType="com.tuoren.forward.entity.dto.ModelDto"  resultMap="BaseResultMap">
+    select 
+    <include refid="Base_Column_List" />
+    from model
+    where (product_id is null or product_id = '')
+    <if test="keyWord != null and keyWord != ''">
+    		and (
+	    		name like CONCAT('%',#{keyWord,jdbcType=VARCHAR},'%')
+	    		or
+	    		title like CONCAT('%',#{keyWord,jdbcType=VARCHAR},'%')
+    		)
+    	</if>
+    <if test="sort != null and sort != ''">
+			order by ${sort} 
+			<if test="order != null "> ${order}</if>
+	</if>
+  </select>
   <delete id="deleteByPrimaryKey" parameterType="java.lang.String">
     delete from model
     where id = #{id,jdbcType=VARCHAR}
   </delete>
   <insert id="insert" parameterType="com.tuoren.forward.entity.Model">
     insert into model (id,code, product_id, name, 
-      title, type, remark,define,tenant_id
+      title, type, remark,define,tenant_id, createtime, modifytime
       )
     values (#{id,jdbcType=VARCHAR},#{code,jdbcType=VARCHAR}, #{productId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, 
       #{title,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR}, #{remark,jdbcType=VARCHAR},
-      #{define,jdbcType=VARCHAR},#{tenantId,jdbcType=VARCHAR}
+      #{define,jdbcType=VARCHAR},#{tenantId,jdbcType=VARCHAR},
+       #{createtime,jdbcType=TIMESTAMP}, #{modifytime,jdbcType=TIMESTAMP}
       )
   </insert>
   <insert id="insertSelective" parameterType="com.tuoren.forward.entity.Model">
@@ -91,6 +145,12 @@
       <if test="tenantId != null">
         tenant_id,
       </if>
+      <if test="createtime != null">
+        createtime,
+      </if>
+      <if test="modifytime != null">
+        modifytime,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides=",">
       <if test="id != null">
@@ -120,6 +180,12 @@
       <if test="tenantId != null">
         #{tenantId,jdbcType=VARCHAR},
       </if>
+      <if test="createtime != null">
+        #{createtime,jdbcType=TIMESTAMP},
+      </if>
+      <if test="modifytime != null">
+        #{modifytime,jdbcType=TIMESTAMP},
+      </if>
     </trim>
   </insert>
   <update id="updateByPrimaryKeySelective" parameterType="com.tuoren.forward.entity.Model">
@@ -149,6 +215,12 @@
       <if test="tenantId != null">
         tenant_id = #{tenantId,jdbcType=VARCHAR},
       </if>
+      <if test="createtime != null">
+        createtime = #{createtime,jdbcType=TIMESTAMP},
+      </if>
+      <if test="modifytime != null">
+        modifytime = #{modifytime,jdbcType=TIMESTAMP},
+      </if>
     </set>
     where id = #{id,jdbcType=VARCHAR}
   </update>
@@ -161,7 +233,9 @@
       type = #{type,jdbcType=VARCHAR},
       remark = #{remark,jdbcType=VARCHAR},
       define = #{define,jdbcType=VARCHAR},
-      tenant_id = #{tenantId,jdbcType=VARCHAR}
+      tenant_id = #{tenantId,jdbcType=VARCHAR},
+      createtime = #{createtime,jdbcType=TIMESTAMP},
+      modifytime = #{modifytime,jdbcType=TIMESTAMP}
     where id = #{id,jdbcType=VARCHAR}
   </update>
 </mapper>

+ 15 - 4
src/main/resources/mapper/PermissionMapper.xml

@@ -10,9 +10,10 @@
     <result column="description" jdbcType="VARCHAR" property="description" />
     <result column="orders" jdbcType="INTEGER" property="orders" />
     <result column="icon" jdbcType="VARCHAR" property="icon" />
+    <result column="name" jdbcType="VARCHAR" property="name" />
   </resultMap>
   <sql id="Base_Column_List">
-    id, pid, title, type, url, description, orders, icon
+    id, pid, title, type, url, description, orders, icon, name
   </sql>
   <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
     select 
@@ -105,10 +106,10 @@
   <insert id="insert" parameterType="com.tuoren.forward.entity.Permission">
     insert into permission (id, pid, title, 
       type, url, description, 
-      orders, icon)
+      orders, icon,name)
     values (#{id,jdbcType=INTEGER}, #{pid,jdbcType=INTEGER}, #{title,jdbcType=VARCHAR}, 
       #{type,jdbcType=CHAR}, #{url,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR}, 
-      #{orders,jdbcType=INTEGER}, #{icon,jdbcType=VARCHAR})
+      #{orders,jdbcType=INTEGER}, #{icon,jdbcType=VARCHAR},#{name,jdbcType=VARCHAR})
   </insert>
   <insert id="insertSelective" parameterType="com.tuoren.forward.entity.Permission">
     insert into permission
@@ -137,6 +138,9 @@
       <if test="icon != null">
         icon,
       </if>
+      <if test="name != null">
+        name,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides=",">
       <if test="id != null">
@@ -163,6 +167,9 @@
       <if test="icon != null">
         #{icon,jdbcType=VARCHAR},
       </if>
+      <if test="name != null">
+        #{name,jdbcType=VARCHAR},
+      </if>
     </trim>
   </insert>
   <update id="updateByPrimaryKeySelective" parameterType="com.tuoren.forward.entity.Permission">
@@ -189,6 +196,9 @@
       <if test="icon != null">
         icon = #{icon,jdbcType=VARCHAR},
       </if>
+      <if test="name != null">
+        name = #{name,jdbcType=VARCHAR},
+      </if>
     </set>
     where id = #{id,jdbcType=INTEGER}
   </update>
@@ -200,7 +210,8 @@
       url = #{url,jdbcType=VARCHAR},
       description = #{description,jdbcType=VARCHAR},
       orders = #{orders,jdbcType=INTEGER},
-      icon = #{icon,jdbcType=VARCHAR}
+      icon = #{icon,jdbcType=VARCHAR},
+      name = #{name,jdbcType=VARCHAR}
     where id = #{id,jdbcType=INTEGER}
   </update>
 </mapper>

+ 18 - 0
src/main/resources/mapper/StationLocationMapper.xml

@@ -29,6 +29,24 @@
     where mnc = #{mnc,jdbcType=VARCHAR} and lac = #{lac,jdbcType=VARCHAR} 
     and ci = #{ci,jdbcType=VARCHAR} limit 1
   </select>
+  <select id="select" parameterType="StationLocationDto" resultMap="BaseResultMap">
+    select 
+    <include refid="Base_Column_List" />
+    from station_location
+    <where>
+    	<if test="keyWord != null and keyWord != ''">
+    	(
+    		lac like CONCAT('%',#{keyWord,jdbcType=VARCHAR},'%')
+    		or
+    		ci like CONCAT('%',#{keyWord,jdbcType=VARCHAR},'%')
+    	)
+    	</if>
+    </where>
+    <if test="sort != null and sort != ''">
+			order by ${sort} 
+			<if test="order != null "> ${order}</if>
+	</if>
+  </select>
   <delete id="deleteByPrimaryKey" parameterType="java.lang.String">
     delete from station_location
     where id = #{id,jdbcType=VARCHAR}

+ 14 - 0
src/main/resources/mapper/UserMapper.xml

@@ -31,6 +31,20 @@
 		from user
 		where username = #{username,jdbcType=VARCHAR} limit 1
 	</select>
+  <select id="selectByMobile"
+		parameterType="java.lang.String" resultMap="BaseResultMap">
+		select
+		<include refid="Base_Column_List" />
+		from user
+		where mobile = #{mobile,jdbcType=VARCHAR} limit 1
+	</select>
+  <select id="selectOneOr"
+		parameterType="java.lang.String" resultMap="BaseResultMap">
+		select
+		<include refid="Base_Column_List" />
+		from user
+		where username = #{username,jdbcType=VARCHAR} or mobile = #{mobile,jdbcType=VARCHAR} limit 1
+	</select>
 	<select id="selectByCode"
 		parameterType="java.lang.String" resultMap="BaseResultMap">
 		select