Browse Source

完成向上级联->选择通道-003

pull/38/head
panlinlin 4 years ago
parent
commit
f082797d9b
  1. 2
      README.md
  2. 14
      src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
  3. 28
      src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
  4. 37
      src/main/java/com/genersoft/iot/vmp/storager/dao/PatformChannelMapper.java
  5. 7
      src/main/java/com/genersoft/iot/vmp/storager/dao/patformChannelMapper.java
  6. 43
      src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
  7. 22
      src/main/java/com/genersoft/iot/vmp/vmanager/platform/PlatformController.java
  8. 21
      src/main/java/com/genersoft/iot/vmp/vmanager/platform/bean/ChannelReduce.java
  9. 2
      src/main/resources/application.yml
  10. BIN
      src/main/resources/wvp.sqlite
  11. 2
      web_src/src/components/ParentPlatformList.vue
  12. 14
      web_src/src/components/gb28181/chooseChannel.vue
  13. 139
      web_src/src/components/gb28181/chooseChannelForGb.vue

2
README.md

@ -40,7 +40,7 @@ https://gitee.com/18010473990/wvp-GB28181.git
- [X] WEB添加上级平台 - [X] WEB添加上级平台
- [X] 注册 - [X] 注册
- [X] 心跳保活 - [X] 心跳保活
- [ ] 通道选择 - [X] 通道选择
- [ ] 通道推送 - [ ] 通道推送
- [ ] 点播 - [ ] 点播
- [ ] 云台控制 - [ ] 云台控制

14
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java

@ -206,9 +206,9 @@ public interface IVideoManagerStorager {
void outlineForAllParentPlatform(); void outlineForAllParentPlatform();
/** /**
* 查询通道信息 不区分设备 * 查询通道信息不区分设备(已关联平台或全部)
*/ */
PageInfo<ChannelReduce> queryChannelListInAll(int page, int count, String query, Boolean online, Boolean channelType, String parentChannelId); PageInfo<ChannelReduce> queryAllChannelList(int page, int count, String query, Boolean online, Boolean channelType, String platformId, Boolean inPlatform);
/** /**
@ -218,4 +218,14 @@ public interface IVideoManagerStorager {
* @return * @return
*/ */
int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces); int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces);
/**
* 移除上级平台的通道信息
* @param platformId
* @param channelReduces
* @return
*/
int delChannelForGB(String platformId, List<ChannelReduce> channelReduces);
} }

28
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java

@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce; import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce;
import org.apache.ibatis.annotations.*; import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
@ -11,6 +12,7 @@ import java.util.List;
* 用于存储设备通道信息 * 用于存储设备通道信息
*/ */
@Mapper @Mapper
@Repository
public interface DeviceChannelMapper { public interface DeviceChannelMapper {
@Insert("INSERT INTO device_channel (channelId, deviceId, name, manufacture, model, owner, civilCode, block, " + @Insert("INSERT INTO device_channel (channelId, deviceId, name, manufacture, model, owner, civilCode, block, " +
@ -79,18 +81,22 @@ public interface DeviceChannelMapper {
@Select(value = {" <script>" + @Select(value = {" <script>" +
"SELECT * FROM ( "+ "SELECT * FROM ( "+
" SELECT dc.channelId, dc.deviceId, dc.name, de.manufacturer, de.hostAddress, " + " SELECT dc.channelId, dc.deviceId, dc.name, de.manufacturer, de.hostAddress, " +
"(SELECT count(0) FROM device_channel WHERE parentId=dc.channelId) as subCount " + "(SELECT count(0) FROM device_channel WHERE parentId=dc.channelId) as subCount, " +
"FROM device_channel dc LEFT JOIN device de ON dc.deviceId = de.deviceId" + "pc.platformId " +
"FROM device_channel dc " +
"LEFT JOIN device de ON dc.deviceId = de.deviceId " +
"LEFT JOIN platform_gb_channel pc on pc.deviceId = dc.deviceId AND pc.channelId = dc.channelId " +
" WHERE 1=1 " +
" <if test=\"query != null\"> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " +
" <if test=\"online == true\" > AND dc.status=1</if> " +
" <if test=\"online == false\" > AND dc.status=0</if> " +
" <if test=\"platformId != null and inPlatform == true\"> AND pc.platformId=#{platformId} </if> " +
") dcr" +
" WHERE 1=1 " + " WHERE 1=1 " +
" <if test=\"query != null\"> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " + " <if test=\"hasSubChannel!= null and hasSubChannel == true\" > AND subCount >0</if> " +
" <if test=\"parentChannelId != null\"> AND dc.parentId=#{parentChannelId} </if> " + " <if test=\"hasSubChannel!= null and hasSubChannel == false\" > AND subCount=0</if> " +
" <if test=\"online == true\" > AND dc.status=1</if>" +
" <if test=\"online == false\" > AND dc.status=0</if>) dcr" +
" WHERE 1=1 " +
" <if test=\"hasSubChannel == true\" > AND subCount >0</if>" +
" <if test=\"hasSubChannel == false\" > AND subCount=0</if>" +
" </script>"}) " </script>"})
List<ChannelReduce> queryChannelListInAll(String query, Boolean online, Boolean hasSubChannel, String parentChannelId); List<ChannelReduce> queryChannelListInAll(String query, Boolean online, Boolean hasSubChannel, String platformId, Boolean inPlatform);
} }

37
src/main/java/com/genersoft/iot/vmp/storager/dao/PatformChannelMapper.java

@ -0,0 +1,37 @@
package com.genersoft.iot.vmp.storager.dao;
import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface PatformChannelMapper {
/**
* 查询列表里已经关联的
*/
@Select("<script> "+
"SELECT deviceAndChannelId FROM platform_gb_channel WHERE platformId='${platformId}' AND deviceAndChannelId in" +
"<foreach collection='deviceAndChannelIds' open='(' item='id_' separator=',' close=')'> '${id_}'</foreach>" +
"</script>")
List<String> findChannelRelatedPlatform(String platformId, List<String> deviceAndChannelIds);
@Insert("<script> "+
"INSERT INTO platform_gb_channel (channelId, deviceId, platformId, deviceAndChannelId) VALUES" +
"<foreach collection='channelReducesToAdd' item='item' separator=','> ('${item.channelId}','${item.deviceId}', '${platformId}', '${item.deviceId}_${item.channelId}' )</foreach>" +
"</script>")
int addChannels(String platformId, List<ChannelReduce> channelReducesToAdd);
@Delete("<script> "+
"DELETE FROM platform_gb_channel WHERE deviceAndChannelId in" +
"<foreach collection='channelReducesToDel' item='item' open='(' separator=',' close=')' > '${item.deviceId}_${item.channelId}'</foreach>" +
"</script>")
int delChannelForGB(String platformId, List<ChannelReduce> channelReducesToDel);
}

7
src/main/java/com/genersoft/iot/vmp/storager/dao/patformChannelMapper.java

@ -1,7 +0,0 @@
package com.genersoft.iot.vmp.storager.dao;
import org.mapstruct.Mapper;
@Mapper
public interface patformChannelMapper {
}

43
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java

@ -9,6 +9,7 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
import com.genersoft.iot.vmp.storager.dao.DeviceMapper; import com.genersoft.iot.vmp.storager.dao.DeviceMapper;
import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper; import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper;
import com.genersoft.iot.vmp.storager.dao.PatformChannelMapper;
import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce; import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
@ -39,6 +40,9 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
@Autowired @Autowired
private IRedisCatchStorage redisCatchStorage; private IRedisCatchStorage redisCatchStorage;
@Autowired
private PatformChannelMapper patformChannelMapper;
@ -275,17 +279,46 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
@Override @Override
public PageInfo<ChannelReduce> queryChannelListInAll(int page, int count, String query, Boolean online, public PageInfo<ChannelReduce> queryAllChannelList(int page, int count, String query, Boolean online,
Boolean channelType, String parentChannelId) { Boolean channelType, String platformId, Boolean inPlatform) {
PageHelper.startPage(page, count); PageHelper.startPage(page, count);
List<ChannelReduce> all = deviceChannelMapper.queryChannelListInAll(query, online, channelType, parentChannelId); List<ChannelReduce> all = deviceChannelMapper.queryChannelListInAll(query, online, channelType, platformId, inPlatform);
return new PageInfo<>(all); return new PageInfo<>(all);
} }
@Transactional
@Override @Override
public int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces) { public int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces) {
return 0;
Map<String, ChannelReduce> deviceAndChannels = new HashMap<>();
for (ChannelReduce channelReduce : channelReduces) {
deviceAndChannels.put(channelReduce.getDeviceId() + "_" + channelReduce.getChannelId(), channelReduce);
}
List<String> deviceAndChannelList = new ArrayList<>(deviceAndChannels.keySet());
// 查询当前已经存在的
List<String> relatedPlatformchannels = patformChannelMapper.findChannelRelatedPlatform(platformId, deviceAndChannelList);
if (relatedPlatformchannels != null) {
deviceAndChannelList.removeAll(relatedPlatformchannels);
}
for (String relatedPlatformchannel : relatedPlatformchannels) {
deviceAndChannels.remove(relatedPlatformchannel);
}
List<ChannelReduce> channelReducesToAdd = new ArrayList<>(deviceAndChannels.values());
// 对剩下的数据进行存储
int result = 0;
if (channelReducesToAdd.size() > 0) {
result = patformChannelMapper.addChannels(platformId, channelReducesToAdd);
}
return result;
}
@Override
public int delChannelForGB(String platformId, List<ChannelReduce> channelReduces) {
int result = patformChannelMapper.delChannelForGB(platformId, channelReduces);
return result;
} }
} }

22
src/main/java/com/genersoft/iot/vmp/vmanager/platform/PlatformController.java

@ -151,15 +151,21 @@ public class PlatformController {
@RequestMapping("/platforms/channelList") @RequestMapping("/platforms/channelList")
@ResponseBody @ResponseBody
public PageInfo<ChannelReduce> channelList(int page, int count, public PageInfo<ChannelReduce> channelList(int page, int count,
@RequestParam(required = false) String platformId,
@RequestParam(required = false) String query, @RequestParam(required = false) String query,
@RequestParam(required = false) Boolean online, @RequestParam(required = false) Boolean online,
@RequestParam(required = false) Boolean choosed,
@RequestParam(required = false) Boolean channelType){ @RequestParam(required = false) Boolean channelType){
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("查询所有所有通道API调用"); logger.debug("查询所有所有通道API调用");
} }
PageInfo<ChannelReduce> channelReduces = null;
PageInfo<ChannelReduce> channelReduces = storager.queryChannelListInAll(page, count, query, online, channelType, null); if (platformId != null ) {
channelReduces = storager.queryAllChannelList(page, count, query, online, channelType, platformId, choosed);
}else {
channelReduces = storager.queryAllChannelList(page, count, query, online, channelType, null, false);
}
return channelReduces; return channelReduces;
} }
@ -177,5 +183,17 @@ public class PlatformController {
return new ResponseEntity<>(String.valueOf(result > 0), HttpStatus.OK); return new ResponseEntity<>(String.valueOf(result > 0), HttpStatus.OK);
} }
@RequestMapping("/platforms/delChannelForGB")
@ResponseBody
public ResponseEntity<String> delChannelForGB(@RequestBody UpdateChannelParam param){
if (logger.isDebugEnabled()) {
logger.debug("给上级平台添加国标通道API调用");
}
int result = storager.delChannelForGB(param.getPlatformId(), param.getChannelReduces());
return new ResponseEntity<>(String.valueOf(result > 0), HttpStatus.OK);
}
} }

21
src/main/java/com/genersoft/iot/vmp/vmanager/platform/bean/ChannelReduce.java

@ -35,6 +35,11 @@ public class ChannelReduce {
*/ */
private int subCount; private int subCount;
/**
* 平台Id
*/
private String platformId;
public String getChannelId() { public String getChannelId() {
return channelId; return channelId;
@ -75,4 +80,20 @@ public class ChannelReduce {
public void setHostAddress(String hostAddress) { public void setHostAddress(String hostAddress) {
this.hostAddress = hostAddress; this.hostAddress = hostAddress;
} }
public int getSubCount() {
return subCount;
}
public void setSubCount(int subCount) {
this.subCount = subCount;
}
public String getPlatformId() {
return platformId;
}
public void setPlatformId(String platformId) {
this.platformId = platformId;
}
} }

2
src/main/resources/application.yml

@ -1,3 +1,3 @@
spring: spring:
profiles: profiles:
active: dev active: local

BIN
src/main/resources/wvp.sqlite

Binary file not shown.

2
web_src/src/components/ParentPlatformList.vue

@ -155,7 +155,7 @@ export default {
getPlatformList: function() { getPlatformList: function() {
let that = this; let that = this;
this.$axios.get(`/api/platforms/${that.count}/${that.currentPage - 1}`) this.$axios.get(`/api/platforms/${that.count}/${that.currentPage}`)
.then(function (res) { .then(function (res) {
that.total = res.data.total; that.total = res.data.total;
that.platformList = res.data.list; that.platformList = res.data.list;

14
web_src/src/components/gb28181/chooseChannel.vue

@ -4,14 +4,10 @@
<el-dialog title="选择通道" top="2rem" width="70%" :close-on-click-modal="false" :visible.sync="showDialog" :destroy-on-close="true" @close="close()"> <el-dialog title="选择通道" top="2rem" width="70%" :close-on-click-modal="false" :visible.sync="showDialog" :destroy-on-close="true" @close="close()">
<el-tabs v-model="tabActiveName" > <el-tabs v-model="tabActiveName" >
<el-tab-pane label="国标通道" name="gbChannel"> <el-tab-pane label="国标通道" name="gbChannel">
<el-container> <el-container>
<el-main style="background-color: #FFF;"> <el-main style="background-color: #FFF;">
<chooseChannelForGb :chooseChanage=chooseChanage ></chooseChannelForGb> <chooseChannelForGb :platformId=platformId ></chooseChannelForGb>
</el-main> </el-main>
<el-footer>
<el-button size="mini" type="primary" style="float: right" @click="save()">保存</el-button>
</el-footer>
</el-container> </el-container>
@ -41,7 +37,6 @@ export default {
// }; // };
// } // }
}, },
created() {},
data() { data() {
return { return {
isLoging: false, isLoging: false,
@ -49,12 +44,11 @@ export default {
platformId: "", platformId: "",
isLoging: false, isLoging: false,
showDialog: false, showDialog: false,
chooseData: [] chooseData: {}
}; };
}, },
methods: { methods: {
openDialog: function (platformId, closeCallback) { openDialog: function (platformId, closeCallback) {
console.log(platformId) console.log(platformId)
this.platformId = platformId this.platformId = platformId
@ -88,10 +82,6 @@ export default {
}).catch(function (error) { }).catch(function (error) {
console.log(error); console.log(error);
}); });
},
chooseChanage: function(val) {
console.log(val)
this.chooseData = val;
} }
} }
}; };

139
web_src/src/components/gb28181/chooseChannelForGb.vue

@ -3,19 +3,28 @@
<div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;"> <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;">
搜索: <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input> 搜索: <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input>
通道类型: <el-select size="mini" @change="search" style="margin-right: 1rem;" v-model="channelType" placeholder="请选择" default-first-option> 通道类型: <el-select size="mini" @change="search" style="margin-right: 1rem; width:6rem" v-model="channelType" placeholder="请选择" default-first-option>
<el-option label="全部" value=""></el-option> <el-option label="全部" value=""></el-option>
<el-option label="设备" value="false"></el-option> <el-option label="设备" value="false"></el-option>
<el-option label="子目录" value="true"></el-option> <el-option label="子目录" value="true"></el-option>
</el-select> </el-select>
在线状态: <el-select size="mini" style="margin-right: 1rem;" @change="search" v-model="online" placeholder="请选择" default-first-option>
选择状态: <el-select size="mini" style="margin-right: 1rem; width:6rem" v-model="choosed" @change="search" placeholder="请选择" default-first-option>
<el-option label="全部" value=""></el-option>
<el-option label="已选择" value="true"></el-option>
<el-option label="未选择" value="false"></el-option>
</el-select>
在线状态: <el-select size="mini" style="margin-right: 1rem; width:6rem" @change="search" v-model="online" placeholder="请选择" default-first-option>
<el-option label="全部" value=""></el-option> <el-option label="全部" value=""></el-option>
<el-option label="在线" value="true"></el-option> <el-option label="在线" value="true"></el-option>
<el-option label="离线" value="false"></el-option> <el-option label="离线" value="false"></el-option>
</el-select> </el-select>
<el-checkbox @change="shareAllCheckedChanage">全部共享</el-checkbox>
</div> </div>
<el-table ref="gbChannelsTable" :data="gbChannels" border style="width: 100%" @selection-change="chooseChanage" > <el-table ref="gbChannelsTable" :data="gbChannels" border style="width: 100%" @selection-change="checkedChanage" >
<el-table-column type="selection" width="55" align="center" fixed> </el-table-column> <el-table-column type="selection" width="55" align="center" fixed > </el-table-column>
<el-table-column prop="channelId" label="通道编号" width="210"> <el-table-column prop="channelId" label="通道编号" width="210">
</el-table-column> </el-table-column>
<el-table-column prop="name" label="通道名称"> <el-table-column prop="name" label="通道名称">
@ -50,22 +59,32 @@ export default {
// }; // };
// } // }
}, },
props: ['chooseChanage'], props: ['platformId'],
created() { created() {
this.initData(); this.initData();
}, },
data() { data() {
return { return {
gbChannels: [], gbChannels: [],
gbChoosechannel:{},
searchSrt: "", searchSrt: "",
channelType: "", channelType: "",
online: "", online: "",
currentPage: parseInt(this.$route.params.page), choosed: "",
count: parseInt(this.$route.params.count), currentPage: 0,
total: 0 count: 15,
total: 0,
eventEnanle: false
}; };
}, },
watch:{
platformId(newData, oldData){
console.log(newData)
this.initData()
},
},
methods: { methods: {
initData: function() { initData: function() {
this.getChannelList(); this.getChannelList();
@ -75,30 +94,128 @@ export default {
this.initData(); this.initData();
}, },
handleSizeChange: function (val) { handleSizeChange: function (val) {
this.count = val; this.count = val;
console.log(val)
this.initData(); this.initData();
}, },
rowcheckedChanage: function (val, row) {
console.log(val)
console.log(row)
},
checkedChanage: function (val) {
var that = this;
if (!that.eventEnanle) {
return;
}
var tabelData = JSON.parse(JSON.stringify(this.$refs.gbChannelsTable.data));
console.log("checkedChanage")
console.log(val)
var newData = {};
var addData = [];
var delData = [];
if (val.length > 0) {
for (let i = 0; i < val.length; i++) {
const element = val[i];
var key = element.deviceId + "_" + element.channelId;
newData[key] = element;
if (!!!that.gbChoosechannel[key]){
addData.push(element)
}else{
delete that.gbChoosechannel[key]
}
}
var oldKeys = Object.keys(that.gbChoosechannel);
if (oldKeys.length > 0) {
for (let i = 0; i < oldKeys.length; i++) {
const key = oldKeys[i];
delData.push(that.gbChoosechannel[key])
}
}
}else{
var oldKeys = Object.keys(that.gbChoosechannel);
if (oldKeys.length > 0) {
for (let i = 0; i < oldKeys.length; i++) {
const key = oldKeys[i];
delData.push(that.gbChoosechannel[key])
}
}
}
that.gbChoosechannel = newData;
if (Object.keys(addData).length >0) {
that.$axios({
method:"post",
url:"/api/platforms/updateChannelForGB",
data:{
platformId: that.platformId,
channelReduces: addData
}
}).then((res)=>{
console.log("保存成功")
}).catch(function (error) {
console.log(error);
});
}
if (Object.keys(delData).length >0) {
that.$axios({
method:"post",
url:"/api/platforms/delChannelForGB",
data:{
platformId: that.platformId,
channelReduces: delData
}
}).then((res)=>{
console.log("移除成功")
}).catch(function (error) {
console.log(error);
});
}
},
shareAllCheckedChanage: function (val) {
this.chooseChanage(null, val)
},
getChannelList: function () { getChannelList: function () {
let that = this; let that = this;
this.$axios.get(`/api/platforms/channelList`, { this.$axios.get(`/api/platforms/channelList`, {
params: { params: {
page: that.currentPage - 1, page: that.currentPage,
count: that.count, count: that.count,
query: that.searchSrt, query: that.searchSrt,
online: that.online, online: that.online,
choosed: that.choosed,
platformId: that.platformId,
channelType: that.channelType channelType: that.channelType
} }
}) })
.then(function (res) { .then(function (res) {
console.log(res);
that.total = res.data.total; that.total = res.data.total;
that.gbChannels = res.data.list; that.gbChannels = res.data.list;
that.gbChoosechannel = {};
// //
that.$nextTick(() => { that.$nextTick(() => {
that.$refs.gbChannelsTable.doLayout(); that.$refs.gbChannelsTable.doLayout();
//
var chooseGBS = [];
for (let i = 0; i < res.data.list.length; i++) {
const row = res.data.list[i];
console.log(row.platformId)
if (row.platformId == that.platformId) {
that.$refs.gbChannelsTable.toggleRowSelection(row, true);
chooseGBS.push(row)
that.gbChoosechannel[row.deviceId+ "_" + row.channelId] = row;
}
}
that.eventEnanle = true;
// that.checkedChanage(chooseGBS)
}) })
console.log(that.gbChoosechannel)
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);

Loading…
Cancel
Save