Commit 595f6442 authored by 赵啸非's avatar 赵啸非

添加设备导入导出功能

parent 3b316c4d
<template> <template>
<div class="page"> <div class="page">
<LayoutTable :data="tableData" :config="tableConfig"> <LayoutTable :data="tableData" :config="tableConfig">
<el-button
slot="table-head-left2"
style="margin-left: 10px"
icon="el-icon-tickets"
size="mini"
@click="handleImport"
>导入</el-button>
<el-button
slot="table-head-left2"
style="margin-left: 10px"
icon="el-icon-tickets"
size="mini"
@click="doExport"
:disabled="isExport"
>导出</el-button>
<el-tag slot="table-body-head" style="margin: 5px" type="success" <el-tag slot="table-body-head" style="margin: 5px" type="success"
>当前在线设备总计:{{ tableData.onlineCount }}</el-tag >当前在线设备总计:{{ tableData.onlineCount }}</el-tag
> >
...@@ -20,7 +35,52 @@ ...@@ -20,7 +35,52 @@
> >
</LayoutTable> </LayoutTable>
<!-- 设备导入对话框 -->
<el-dialog
:title="upload.title"
:visible.sync="upload.open"
width="400px"
append-to-body
>
<el-upload
ref="upload"
:limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport"
:disabled="upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:auto-upload="false"
drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处,或
<em>点击上传</em>
</div>
<div class="el-upload__tip" slot="tip">
<el-checkbox
v-model="upload.updateSupport"
/>是否更新已经存在的数据
<el-link type="primary" style="font-size: 14px" @click="downloadTemplate"
>下载模板</el-link
>
</div>
<div class="el-upload__tip" style="color: red" slot="tip">
提示:仅允许导入“xls”或“xlsx”格式文件!
</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm">确 定</el-button>
<el-button @click="upload.open = false">取 消</el-button>
</div>
</el-dialog>
<dialog-show ref="dialogform" @ok="getData" />
<dialog-show ref="dialogform" @ok="getData" /> <dialog-show ref="dialogform" @ok="getData" />
</div> </div>
</template> </template>
...@@ -34,6 +94,46 @@ export default { ...@@ -34,6 +94,46 @@ export default {
mixins: [table], mixins: [table],
created() {}, created() {},
methods: { methods: {
/** 导入 */
handleImport() {
this.upload.title = "设备导入";
this.upload.open = true;
},
/** 下载模板操作 */
downloadTemplate() {
this.isExport = true;
this.$download("/device/downloadTemplate", {}, { type: "excel" })
.then(() => (this.isExport = false))
.catch((error) => {
this.isExport = false;
this.$message.error(error.message);
});
},
/** 文件上传中处理 */
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true;
},
/** 文件上传成功处理 */
handleFileSuccess(response, file, fileList) {
this.upload.open = false;
this.upload.isUploading = false;
this.$refs.upload.clearFiles();
this.$alert(response.msg, "导入结果", { dangerouslyUseHTMLString: true });
this.getData();
},
/** 提交上传文件 */
submitFileForm() {
this.$refs.upload.submit();
},
/** 导出Excel */
doExport() {
this.isExport = true;
this.$download("/device/exportExcel", {
}, { type: "excel" }).then(() => this.isExport = false).catch(error => {
this.isExport = false;
this.$message.error(error.message);
});
},
/** 重写新增方法 */ /** 重写新增方法 */
toAdd(row) { toAdd(row) {
this.$refs.dialogform.add(row); this.$refs.dialogform.add(row);
...@@ -93,6 +193,20 @@ export default { ...@@ -93,6 +193,20 @@ export default {
}, },
data() { data() {
return { return {
// 用户导入参数
upload: {
// 是否显示弹出层(设备导入)
open: false,
// 弹出层标题(设备导入)
title: "导入设备数据",
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的数据
updateSupport: 0,
// 上传的地址
url: "/m/device/importData",
},
isExport: false,
config: { config: {
getsocketData: null, getsocketData: null,
search: [ search: [
......
...@@ -34,6 +34,10 @@ public class DeviceQueueAuthInfo implements Serializable { ...@@ -34,6 +34,10 @@ public class DeviceQueueAuthInfo implements Serializable {
* 交换机名称 * 交换机名称
*/ */
private String exchangeName; private String exchangeName;
/**
* 队列消息持久化时间
*/
private String messageTtl;
/** /**
* 设备上行topic队列 * 设备上行topic队列
*/ */
...@@ -42,6 +46,10 @@ public class DeviceQueueAuthInfo implements Serializable { ...@@ -42,6 +46,10 @@ public class DeviceQueueAuthInfo implements Serializable {
* 设备下行topic队列 * 设备下行topic队列
*/ */
private String downTopicFilter; private String downTopicFilter;
/**
* 首页
*/
private String homeUrl;
......
package com.mortals.xhx.busiz.security; //package com.mortals.xhx.busiz.security;
//
import cn.hutool.core.util.IdUtil; //import cn.hutool.core.util.IdUtil;
import com.mortals.framework.service.ICacheService; //import com.mortals.framework.service.ICacheService;
import com.mortals.framework.util.StringUtils; //import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.common.key.Constant; //import com.mortals.xhx.common.key.Constant;
import com.mortals.xhx.module.device.model.DeviceEntity; //import com.mortals.xhx.module.device.model.DeviceEntity;
import io.jsonwebtoken.Claims; //import io.jsonwebtoken.Claims;
import lombok.extern.apachecommons.CommonsLog; //import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; //import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; //import org.springframework.stereotype.Component;
//
import javax.servlet.http.HttpServletRequest; //import javax.servlet.http.HttpServletRequest;
import java.util.HashMap; //import java.util.HashMap;
import java.util.Map; //import java.util.Map;
//
import io.jsonwebtoken.Jwts; //import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm; //import io.jsonwebtoken.SignatureAlgorithm;
//
/** ///**
* token验证处理 // * token验证处理
* // *
* @author zxfei // * @author zxfei
*/ // */
@Component //@Component
@CommonsLog //@CommonsLog
public class DeviceTokenService { //public class DeviceTokenService {
// 令牌自定义标识 // // 令牌自定义标识
@Value("${token.header}") // @Value("${token.header}")
private String header; // private String header;
//
// 令牌秘钥 // // 令牌秘钥
@Value("${token.secret}") // @Value("${token.secret}")
private String secret; // private String secret;
//
// 令牌有效期(默认60分钟) // // 令牌有效期(默认60分钟)
@Value("${token.expireTime}") // @Value("${token.expireTime}")
private int expireTime; // private int expireTime;
//
protected static final long MILLIS_SECOND = 1000; // protected static final long MILLIS_SECOND = 1000;
//
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; // protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
//
private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L; // private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;
//
@Autowired // @Autowired
private ICacheService cacheService; // private ICacheService cacheService;
//
/** // /**
* 获取设备信息 // * 获取设备信息
* // *
* @return 设备信息 // * @return 设备信息
*/ // */
public DeviceEntity getLoginDevice(HttpServletRequest request) { // public DeviceEntity getLoginDevice(HttpServletRequest request) {
// 获取请求携带的令牌 // // 获取请求携带的令牌
String token = getToken(request); // String token = getToken(request);
if (StringUtils.isNotEmpty(token)) { // if (StringUtils.isNotEmpty(token)) {
try { // try {
Claims claims = parseToken(token); // Claims claims = parseToken(token);
String uuid = (String) claims.get(Constant.LOGIN_DEVICE_KEY); // String uuid = (String) claims.get(Constant.LOGIN_DEVICE_KEY);
String deviceKey = getTokenKey(uuid); // String deviceKey = getTokenKey(uuid);
DeviceEntity device = cacheService.get(deviceKey, DeviceEntity.class); // DeviceEntity device = cacheService.get(deviceKey, DeviceEntity.class);
return device; // return device;
} catch (Exception e) { // } catch (Exception e) {
log.error("解析jwt token异常!",e); // log.error("解析jwt token异常!",e);
return null; // return null;
} // }
} // }
return null; // return null;
} // }
//
/** // /**
* 设置设备信息 // * 设置设备信息
*/ // */
public void setDevice(DeviceEntity device) { // public void setDevice(DeviceEntity device) {
if (StringUtils.isNotNull(device) && StringUtils.isNotEmpty(device.getToken())) { // if (StringUtils.isNotNull(device) && StringUtils.isNotEmpty(device.getToken())) {
refreshToken(device); // refreshToken(device);
} // }
} // }
//
/** // /**
* 删除用户身份信息 // * 删除用户身份信息
*/ // */
public void delDevice(String token) { // public void delDevice(String token) {
if (StringUtils.isNotEmpty(token)) { // if (StringUtils.isNotEmpty(token)) {
String deviceKey = getTokenKey(token); // String deviceKey = getTokenKey(token);
cacheService.del(deviceKey); // cacheService.del(deviceKey);
} // }
} // }
//
/** // /**
* 创建令牌 // * 创建令牌
* // *
* @param device 设备信息 // * @param device 设备信息
* @return 令牌 // * @return 令牌
*/ // */
public String createToken(DeviceEntity device) { // public String createToken(DeviceEntity device) {
String token = IdUtil.fastSimpleUUID(); // String token = IdUtil.fastSimpleUUID();
device.setToken(token); // device.setToken(token);
refreshToken(device); // refreshToken(device);
Map<String, Object> claims = new HashMap<>(); // Map<String, Object> claims = new HashMap<>();
claims.put(Constant.LOGIN_DEVICE_KEY, token); // claims.put(Constant.LOGIN_DEVICE_KEY, token);
return createToken(claims); // return createToken(claims);
} // }
//
/** // /**
* 验证令牌有效期,相差不足20分钟,自动刷新缓存 // * 验证令牌有效期,相差不足20分钟,自动刷新缓存
* // *
* @param device // * @param device
* @return 令牌 // * @return 令牌
*/ // */
public void verifyToken(DeviceEntity device) { // public void verifyToken(DeviceEntity device) {
long expireTime = device.getExpireTime(); // long expireTime = device.getExpireTime();
long currentTime = System.currentTimeMillis(); // long currentTime = System.currentTimeMillis();
if (expireTime - currentTime <= MILLIS_MINUTE_TEN) { // if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
refreshToken(device); // refreshToken(device);
} // }
} // }
//
/** // /**
* 刷新令牌有效期 // * 刷新令牌有效期
* // *
* @param device 信息 // * @param device 信息
*/ // */
public void refreshToken(DeviceEntity device) { // public void refreshToken(DeviceEntity device) {
device.setLoginTime(System.currentTimeMillis()); // device.setLoginTime(System.currentTimeMillis());
device.setExpireTime(device.getLoginTime() + expireTime * MILLIS_MINUTE); // device.setExpireTime(device.getLoginTime() + expireTime * MILLIS_MINUTE);
// 根据uuid将device缓存 // // 根据uuid将device缓存
String deviceKey = getTokenKey(device.getToken()); // String deviceKey = getTokenKey(device.getToken());
//设置有效时间 单位秒 // //设置有效时间 单位秒
cacheService.setnx(deviceKey, device, expireTime * MILLIS_MINUTE * MILLIS_SECOND); // cacheService.setnx(deviceKey, device, expireTime * MILLIS_MINUTE * MILLIS_SECOND);
} // }
//
//
/** // /**
* 从数据声明生成令牌 // * 从数据声明生成令牌
* // *
* @param claims 数据声明 // * @param claims 数据声明
* @return 令牌 // * @return 令牌
*/ // */
private String createToken(Map<String, Object> claims) { // private String createToken(Map<String, Object> claims) {
String token = Jwts.builder() // String token = Jwts.builder()
.setClaims(claims) // .setClaims(claims)
.signWith(SignatureAlgorithm.HS512, secret).compact(); // .signWith(SignatureAlgorithm.HS512, secret).compact();
return token; // return token;
} // }
//
/** // /**
* 从令牌中获取数据声明 // * 从令牌中获取数据声明
* // *
* @param token 令牌 // * @param token 令牌
* @return 数据声明 // * @return 数据声明
*/ // */
private Claims parseToken(String token) { // private Claims parseToken(String token) {
return Jwts.parser() // return Jwts.parser()
.setSigningKey(secret) // .setSigningKey(secret)
.parseClaimsJws(token) // .parseClaimsJws(token)
.getBody(); // .getBody();
} // }
//
/** // /**
* 从令牌中获取设备编号 // * 从令牌中获取设备编号
* // *
* @param token 令牌 // * @param token 令牌
* @return 用户名 // * @return 用户名
*/ // */
public String getDeviceNumFromToken(String token) { // public String getDeviceNumFromToken(String token) {
Claims claims = parseToken(token); // Claims claims = parseToken(token);
return claims.getSubject(); // return claims.getSubject();
} // }
//
/** // /**
* 获取请求token // * 获取请求token
* // *
* @param request // * @param request
* @return token // * @return token
*/ // */
private String getToken(HttpServletRequest request) { // private String getToken(HttpServletRequest request) {
String token = request.getHeader(header); // String token = request.getHeader(header);
if (StringUtils.isNotEmpty(token) && token.startsWith(Constant.TOKEN_PREFIX)) { // if (StringUtils.isNotEmpty(token) && token.startsWith(Constant.TOKEN_PREFIX)) {
token = token.replace(Constant.TOKEN_PREFIX, ""); // token = token.replace(Constant.TOKEN_PREFIX, "");
} // }
return token; // return token;
} // }
//
private String getTokenKey(String uuid) { // private String getTokenKey(String uuid) {
return Constant.LOGIN_TOKEN_KEY + uuid; // return Constant.LOGIN_TOKEN_KEY + uuid;
} // }
} //}
package com.mortals.xhx.busiz.security.filter; //package com.mortals.xhx.busiz.security.filter;
//
import com.mortals.framework.util.StringUtils; //import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.busiz.security.SecurityUtils; //import com.mortals.xhx.busiz.security.SecurityUtils;
import com.mortals.xhx.busiz.security.DeviceTokenService; //import com.mortals.xhx.busiz.security.DeviceTokenService;
import com.mortals.xhx.module.device.model.DeviceEntity; //import com.mortals.xhx.module.device.model.DeviceEntity;
import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.filter.OncePerRequestFilter; //import org.springframework.web.filter.OncePerRequestFilter;
//
import javax.servlet.FilterChain; //import javax.servlet.FilterChain;
import javax.servlet.ServletException; //import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; //import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; //import javax.servlet.http.HttpServletResponse;
import java.io.IOException; //import java.io.IOException;
//
/** ///**
* token过滤器 验证token有效性 // * token过滤器 验证token有效性
* // *
* @author ruoyi // * @author ruoyi
*/ // */
//@Component ////@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { //public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Autowired // @Autowired
private DeviceTokenService deviceTokenService; // private DeviceTokenService deviceTokenService;
//
@Override // @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) // protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException { // throws ServletException, IOException {
DeviceEntity device = deviceTokenService.getLoginDevice(request); // DeviceEntity device = deviceTokenService.getLoginDevice(request);
if (StringUtils.isNotNull(device) && StringUtils.isNull(SecurityUtils.getAuthentication())) { // if (StringUtils.isNotNull(device) && StringUtils.isNull(SecurityUtils.getAuthentication())) {
deviceTokenService.verifyToken(device); // deviceTokenService.verifyToken(device);
} // }
chain.doFilter(request, response); // chain.doFilter(request, response);
} // }
} //}
...@@ -29,6 +29,7 @@ import com.mortals.xhx.module.product.model.ProductQuery; ...@@ -29,6 +29,7 @@ import com.mortals.xhx.module.product.model.ProductQuery;
import com.mortals.xhx.module.product.service.ProductService; import com.mortals.xhx.module.product.service.ProductService;
import com.mortals.xhx.queue.TbQueueMsgHeaders; import com.mortals.xhx.queue.TbQueueMsgHeaders;
import com.mortals.xhx.queue.TopicPartitionInfo; import com.mortals.xhx.queue.TopicPartitionInfo;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -70,6 +71,8 @@ public class DeviceApiController { ...@@ -70,6 +71,8 @@ public class DeviceApiController {
private int port; private int port;
@Value("${queue.rabbitmq.username:}") @Value("${queue.rabbitmq.username:}")
private String username; private String username;
@Value("${queue.rabbitmq.queue-properties.x-message-ttl:86400000}")
private String messageTtl;
@Value("${token.secret}") @Value("${token.secret}")
private String secret; private String secret;
...@@ -91,7 +94,6 @@ public class DeviceApiController { ...@@ -91,7 +94,6 @@ public class DeviceApiController {
if (deviceEntity.getActive() != ActiveEnum.已激活.getValue()) { if (deviceEntity.getActive() != ActiveEnum.已激活.getValue()) {
throw new AppException("当前设备未激活,请在后台配置后再激活!"); throw new AppException("当前设备未激活,请在后台配置后再激活!");
} }
if (deviceEntity.getStatus() != StatusEnum.启用.getValue()) { if (deviceEntity.getStatus() != StatusEnum.启用.getValue()) {
throw new AppException("当前设备未启用,请在后台启用当前设备!"); throw new AppException("当前设备未启用,请在后台启用当前设备!");
} }
...@@ -101,6 +103,7 @@ public class DeviceApiController { ...@@ -101,6 +103,7 @@ public class DeviceApiController {
authInfo.setPort(port); authInfo.setPort(port);
authInfo.setUsername(username); authInfo.setUsername(username);
authInfo.setPassword(password); authInfo.setPassword(password);
authInfo.setMessageTtl(messageTtl);
authInfo.setVirtualHost(virtualHost); authInfo.setVirtualHost(virtualHost);
PlatformEntity platformEntity = platformService.get(deviceEntity.getPlatformId()); PlatformEntity platformEntity = platformService.get(deviceEntity.getPlatformId());
if (ObjectUtils.isEmpty(platformEntity)) { if (ObjectUtils.isEmpty(platformEntity)) {
...@@ -114,6 +117,7 @@ public class DeviceApiController { ...@@ -114,6 +117,7 @@ public class DeviceApiController {
authInfo.setExchangeName(platformEntity.getPlatformSn() + Constant.EXCHANGE_SPLIT + productEntity.getProductCode()); authInfo.setExchangeName(platformEntity.getPlatformSn() + Constant.EXCHANGE_SPLIT + productEntity.getProductCode());
authInfo.setUploadTopicFilter(Constant.UPLOAD_TOPIC + deviceEntity.getDeviceCode()); authInfo.setUploadTopicFilter(Constant.UPLOAD_TOPIC + deviceEntity.getDeviceCode());
authInfo.setDownTopicFilter(Constant.DOWN_TOPIC + deviceEntity.getDeviceCode()); authInfo.setDownTopicFilter(Constant.DOWN_TOPIC + deviceEntity.getDeviceCode());
authInfo.setHomeUrl(platformEntity.getHomeUrl());
String content = AESUtil.encryptForApp(JSON.toJSONString(authInfo), secret); String content = AESUtil.encryptForApp(JSON.toJSONString(authInfo), secret);
deviceResp.setContent(content); deviceResp.setContent(content);
deviceEntity.setOnlineTime(new Date()); deviceEntity.setOnlineTime(new Date());
......
...@@ -106,6 +106,8 @@ host|String|ip|- ...@@ -106,6 +106,8 @@ host|String|ip|-
port|String|端口|- port|String|端口|-
virtualHost|String|虚拟机|- virtualHost|String|虚拟机|-
exchangeName|String|交换机名称|- exchangeName|String|交换机名称|-
messageTtl|String|队列消息超时时间,毫秒|-
homeUrl|String|首页|-
**响应消息样例:** **响应消息样例:**
``` ```
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment