feat(network): 项目初始化、请求封装,主包部分页面开发和接口对接等
- 完成登录、配置、统计、设备、我的、修改密码页开发 - 初始化项目tabbar图标、默认图片等 - 重构请求封装,项目配置等
6
App.vue
|
@ -10,14 +10,14 @@
|
|||
if(!configList || configList.length == 0){
|
||||
let configList = [{
|
||||
id:this.$u.guid(32),
|
||||
protocol:'https://',
|
||||
address:'cloud.iot-fast.com',
|
||||
protocol:'http://',
|
||||
address:'192.168.1.17:8848',
|
||||
}]
|
||||
// #ifdef APP-PLUS
|
||||
configList.push({
|
||||
id:this.$u.guid(32),
|
||||
protocol:'http://',
|
||||
address:'192.168.21.22',
|
||||
address:'192.168.1.17:8848',
|
||||
})
|
||||
// #endif
|
||||
uni.setStorageSync('configList',configList)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"name" : "物联网可视化",
|
||||
"appid" : "__UNI__604B8F1",
|
||||
"name" : "德润物联网",
|
||||
"appid" : "__UNI__B7FE99B",
|
||||
"description" : "",
|
||||
"versionName" : "1.0.34",
|
||||
"versionCode" : 1034,
|
||||
"versionName" : "1.0.0",
|
||||
"versionCode" : 100,
|
||||
"transformPx" : false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus" : {
|
||||
|
@ -135,7 +135,7 @@
|
|||
"quickapp" : {},
|
||||
/* 小程序特有相关 */
|
||||
"mp-weixin" : {
|
||||
"appid" : "wx27c271b0cb420015",
|
||||
"appid" : "wxc1dd0068f0f85026",
|
||||
"setting" : {
|
||||
"urlCheck" : false,
|
||||
"postcss" : true,
|
||||
|
|
|
@ -14,7 +14,7 @@ export default {
|
|||
getAppConfig(data){
|
||||
return new Promise((resolve, reject) => {
|
||||
request.customRequest({
|
||||
url: '/admin/admin/site/config',
|
||||
url: '/system/config/front',
|
||||
method: 'GET',
|
||||
},data)
|
||||
.then((res) =>{
|
||||
|
@ -58,7 +58,7 @@ export default {
|
|||
passwordLogin(data){
|
||||
return new Promise((resolve, reject) => {
|
||||
request.customRequest({
|
||||
url: '/user/admin/site/accountLogin',
|
||||
url: '/authorize/login',
|
||||
method: 'POST',
|
||||
},data)
|
||||
.then((res) =>{
|
||||
|
@ -68,6 +68,20 @@ export default {
|
|||
})
|
||||
})
|
||||
},
|
||||
// 获取用户信息
|
||||
userLogout(data){
|
||||
return new Promise((resolve, reject) => {
|
||||
request.TokenRequest({
|
||||
url: '/user-token/reset',
|
||||
method: 'GET',
|
||||
},data)
|
||||
.then((res) =>{
|
||||
resolve(res);
|
||||
}).catch(err =>{
|
||||
reject(err);
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 发送短信验证码
|
||||
sendSms(data){
|
||||
|
@ -103,7 +117,7 @@ export default {
|
|||
getUserInfo(data){
|
||||
return new Promise((resolve, reject) => {
|
||||
request.TokenRequest({
|
||||
url: '/user/admin/member/info',
|
||||
url: '/user/detail',
|
||||
method: 'GET',
|
||||
},data)
|
||||
.then((res) =>{
|
||||
|
@ -134,7 +148,22 @@ export default {
|
|||
updatePwd(data){
|
||||
return new Promise((resolve, reject) => {
|
||||
request.TokenRequest({
|
||||
url: '/user/admin/member/updatePwd',
|
||||
url: '/user/passwd',
|
||||
method: 'PUT',
|
||||
},data)
|
||||
.then((res) =>{
|
||||
resolve(res);
|
||||
}).catch(err =>{
|
||||
reject(err);
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 看板统计查询
|
||||
getDashboardSelect(data){
|
||||
return new Promise((resolve, reject) => {
|
||||
request.TokenRequest({
|
||||
url: '/dashboard/_multi',
|
||||
method: 'POST',
|
||||
},data)
|
||||
.then((res) =>{
|
||||
|
|
|
@ -1,6 +1,21 @@
|
|||
import request from "../../request.js"
|
||||
|
||||
export default {
|
||||
// 获取设备数
|
||||
getDeviceInstanceCount(data){
|
||||
return new Promise((resolve, reject) => {
|
||||
request.TokenRequest({
|
||||
url: '/device/instance/_count',
|
||||
method: 'GET',
|
||||
},data)
|
||||
.then((res) =>{
|
||||
resolve(res);
|
||||
}).catch(err =>{
|
||||
reject(err);
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 获取设备统计数量
|
||||
getDeviceCount(data){
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -20,8 +35,8 @@ export default {
|
|||
getProductList(data){
|
||||
return new Promise((resolve, reject) => {
|
||||
request.TokenRequest({
|
||||
url: '/iot/admin/product/list',
|
||||
method: 'GET',
|
||||
url: '/device-product/_query/no-paging',
|
||||
method: 'POST',
|
||||
},data)
|
||||
.then((res) =>{
|
||||
resolve(res);
|
||||
|
@ -35,7 +50,7 @@ export default {
|
|||
getDeviceList(data){
|
||||
return new Promise((resolve, reject) => {
|
||||
request.TokenRequest({
|
||||
url: '/iot/admin/device/list',
|
||||
url: '/device-instance/_query',
|
||||
method: 'POST',
|
||||
},data)
|
||||
.then((res) =>{
|
||||
|
@ -136,12 +151,25 @@ export default {
|
|||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 告警级别列表
|
||||
// 获取告警记录列表
|
||||
getAlarmList(data){
|
||||
return new Promise((resolve, reject) => {
|
||||
request.TokenRequest({
|
||||
url: '/alarm/record/_query',
|
||||
method: 'POST',
|
||||
},data)
|
||||
.then((res) =>{
|
||||
resolve(res);
|
||||
}).catch(err =>{
|
||||
reject(err);
|
||||
})
|
||||
})
|
||||
},
|
||||
// 获取默认告警级别
|
||||
getAlarmLevelList(data){
|
||||
return new Promise((resolve, reject) => {
|
||||
request.TokenRequest({
|
||||
url: '/iot/admin/alarm/level/list',
|
||||
url: '/alarm/config/default/level',
|
||||
method: 'GET',
|
||||
},data)
|
||||
.then((res) =>{
|
||||
|
@ -151,6 +179,20 @@ export default {
|
|||
})
|
||||
})
|
||||
},
|
||||
// // 告警级别列表
|
||||
// getAlarmLevelList(data){
|
||||
// return new Promise((resolve, reject) => {
|
||||
// request.TokenRequest({
|
||||
// url: '/iot/admin/alarm/level/list',
|
||||
// method: 'GET',
|
||||
// },data)
|
||||
// .then((res) =>{
|
||||
// resolve(res);
|
||||
// }).catch(err =>{
|
||||
// reject(err);
|
||||
// })
|
||||
// })
|
||||
// },
|
||||
|
||||
// 概览页统计(图表)
|
||||
getAlarmRecordStat(data){
|
||||
|
|
|
@ -14,8 +14,8 @@ if(process.env.NODE_ENV === 'development'){
|
|||
// wsUrl = "ws://iotos-ui-dev.iotos.192.168.10.243.nip.io:32764"
|
||||
// configurationUrl = "http://192.168.18.139:8855"
|
||||
// configurationhtmlUrl = "http://hceditor-2d-dev.hceditor.192.168.10.243.nip.io:30405"
|
||||
url = 'https://miot.gkiiot.com'
|
||||
wsUrl = 'wss://miot.gkiiot.com'
|
||||
url = 'http://192.168.1.17:8848'
|
||||
wsUrl = 'ws://192.168.1.17:8848'
|
||||
configurationUrl = 'https://2d.gkiiot.com/prod-api'
|
||||
configurationhtmlUrl = 'https://2d.gkiiot.com'
|
||||
}else{
|
||||
|
|
|
@ -94,7 +94,7 @@ const TokenRequest = (opts, data) => {
|
|||
data: data,
|
||||
method: opts.method,
|
||||
header: {
|
||||
'Authorization': tokenKey,
|
||||
'x-access-token': tokenKey,
|
||||
},
|
||||
}
|
||||
let promise = new Promise(function(resolve, reject) {
|
||||
|
@ -102,7 +102,7 @@ const TokenRequest = (opts, data) => {
|
|||
(res) => {
|
||||
// console.log("请求返回",res)
|
||||
// 令牌过期关闭所有页面跳转登录页
|
||||
if(res[1].data.code==61){
|
||||
if(res[1].data.status==401){
|
||||
uni.showToast({
|
||||
title: '登录已过期,请重新登录',
|
||||
icon: 'none',
|
||||
|
@ -114,7 +114,7 @@ const TokenRequest = (opts, data) => {
|
|||
setTimeout(()=>{
|
||||
uni.reLaunch({url:'/pages/tabbar/login'});
|
||||
},1500)
|
||||
}else if(res[1].data.code>0){
|
||||
}else if(res[1].data.status!=200){
|
||||
uni.showToast({
|
||||
title: res[1].data.message,
|
||||
icon: 'none',
|
||||
|
|
30
pages.json
|
@ -29,6 +29,20 @@
|
|||
// "navigationStyle":"custom"
|
||||
// }
|
||||
// },
|
||||
{
|
||||
"path": "pages/tabbar/dashboard",
|
||||
"style": {
|
||||
"navigationBarTitleText": "统计看板",
|
||||
"navigationBarBackgroundColor": "#FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/tabbar/device",
|
||||
"style": {
|
||||
"navigationBarTitleText": "设备",
|
||||
"navigationBarBackgroundColor": "#FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/tabbar/new",
|
||||
"style": {
|
||||
|
@ -343,15 +357,15 @@
|
|||
},
|
||||
// #endif
|
||||
"list": [{
|
||||
"pagePath": "pages/tabbar/home",
|
||||
"iconPath": "static/image/tabbar/home.png",
|
||||
"selectedIconPath": "static/image/tabbar/home-active.png",
|
||||
"text": "首页"
|
||||
"pagePath": "pages/tabbar/dashboard",
|
||||
"iconPath": "static/image/tabbar/dashboard.png",
|
||||
"selectedIconPath": "static/image/tabbar/dashboard-active.png",
|
||||
"text": "统计"
|
||||
},{
|
||||
"pagePath": "pages/tabbar/workbench",
|
||||
"iconPath": "static/image/tabbar/workbench.png",
|
||||
"selectedIconPath": "static/image/tabbar/workbench-active.png",
|
||||
"text": "工作台"
|
||||
"pagePath": "pages/tabbar/device",
|
||||
"iconPath": "static/image/tabbar/iot.png",
|
||||
"selectedIconPath": "static/image/tabbar/iot-active.png",
|
||||
"text": "设备"
|
||||
},
|
||||
// #ifdef MP-WEIXIN
|
||||
{
|
||||
|
|
|
@ -56,13 +56,13 @@
|
|||
submit(){
|
||||
if(this.verification()){
|
||||
let params={
|
||||
id:this.infoData.id,
|
||||
// id:this.infoData.id,
|
||||
newPassword:this.newPassword,
|
||||
oldPassword:this.oldPassword,
|
||||
}
|
||||
this.$api.updatePwd(params).then(res => {
|
||||
console.log("submit",res);
|
||||
if(res.code==0){
|
||||
if(res.status == 200){
|
||||
this.$u.toast(res.message);
|
||||
this.$store.commit('setTokenKey', '');
|
||||
uni.$u.toast('退出登录成功');
|
||||
|
|
|
@ -1,46 +1,91 @@
|
|||
<template>
|
||||
<view class="config-box">
|
||||
<view class="config-list" v-if="configList.length">
|
||||
<view class="config-item" v-for="(item,index) in configList" :key="item.id" @click="changeConfig(index)">
|
||||
<!-- <u-icon v-if="configIndex==index" class="icon-checkbox-mark" name="checkbox-mark" color="#ff0000" size="50"></u-icon> -->
|
||||
<view class="acitve-box" v-if="configIndex==index">
|
||||
已选择
|
||||
</view>
|
||||
<view class="congfig-txt">
|
||||
{{item.protocol+item.address}}
|
||||
</view>
|
||||
<view class="operate-box">
|
||||
<view class="iconfont icon-bianji1 color-blue" @click.stop="openEdit(index)"></view>
|
||||
<view class="iconfont icon-shanchu color-red" @click.stop="delConfig(index)"></view>
|
||||
<view class="container">
|
||||
<!-- 域名列表 -->
|
||||
<view class="domain-list" v-if="configList.length">
|
||||
<view
|
||||
class="domain-item"
|
||||
:class="{'domain-item-active': configIndex === index}"
|
||||
v-for="(item, index) in configList"
|
||||
:key="item.id"
|
||||
@click="changeConfig(index)"
|
||||
>
|
||||
<view class="domain-item-content">
|
||||
<!-- 单选按钮 -->
|
||||
<view class="radio-wrapper">
|
||||
<u-radio-group v-model="configIndex">
|
||||
<u-radio
|
||||
:name="index"
|
||||
size="40"
|
||||
shape="circle"
|
||||
activeColor="#2979ff"
|
||||
></u-radio>
|
||||
</u-radio-group>
|
||||
</view>
|
||||
|
||||
<!-- 协议标签 -->
|
||||
<view :class="['protocol-tag', item.protocol.includes('https') ? 'https' : 'http']">
|
||||
<text>{{ item.protocol.includes('https') ? 'HTTPS' : 'HTTP' }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 域名 -->
|
||||
<view class="domain-name">
|
||||
<text>{{ item.address }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view @click.stop="openEdit(index)" class="domain-item-btn">
|
||||
<u-icon name="edit-pen" color="#2979ff" size="40"></u-icon>
|
||||
</view>
|
||||
<view @click.stop="delConfig(index)" class="domain-item-btn">
|
||||
<u-icon name="trash" color="#fa3534" size="40"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<u-empty margin-top="200" v-else text="没有域名,请添加" mode="list"></u-empty>
|
||||
<view class="btn-box">
|
||||
<button type="primary" @tap="openAdd">添加域名</button>
|
||||
|
||||
<!-- 添加域名按钮 -->
|
||||
<view class="add-button-wrapper">
|
||||
<u-button
|
||||
type="primary"
|
||||
@click="openAdd"
|
||||
>+ 添加域名</u-button>
|
||||
</view>
|
||||
<u-modal v-model="show" width="700" title="新增/修改域名" ref="uModal" :show-cancel-button="true" :mask-close-able="true" @confirm="addConfig">
|
||||
|
||||
<!-- 添加/编辑域名弹窗 -->
|
||||
<u-modal v-model="show" width="700" :title="form.id ? '编辑域名' : '添加域名'" ref="uModal" :show-cancel-button="true" :mask-close-able="true" @confirm="addConfig">
|
||||
<view class="slot-content">
|
||||
<!-- 网络协议选择 -->
|
||||
<view class="form-item">
|
||||
<view class="form-label">
|
||||
网络协议:
|
||||
网络协议
|
||||
</view>
|
||||
<view class="form-value" @click="protocolShow=true">
|
||||
{{form.protocol?form.protocol:'请选择'}}
|
||||
<view class="iconfont icon-xiangyou1"></view>
|
||||
{{ form.protocol ? form.protocol : '请选择' }}
|
||||
<view class="arrow-icon">
|
||||
<u-icon name="arrow-down" size="28"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 域名输入 -->
|
||||
<view class="form-item">
|
||||
<view class="form-label">
|
||||
域名或ip:
|
||||
域名
|
||||
</view>
|
||||
<view class="form-value">
|
||||
<input type="text" v-model="form.address" placeholder="请输入地址如:192.168.0.1">
|
||||
<input type="text" v-model="form.address" placeholder="请输入域名">
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-modal>
|
||||
|
||||
<!-- 协议选择器 -->
|
||||
<u-select v-model="protocolShow" :list="protocolList" @confirm="confirmProtocol"></u-select>
|
||||
|
||||
<!-- 提示框 -->
|
||||
<u-toast ref="uToast" />
|
||||
</view>
|
||||
</template>
|
||||
|
@ -49,122 +94,122 @@
|
|||
export default {
|
||||
data() {
|
||||
return {
|
||||
configIndex:0,
|
||||
configList:[],
|
||||
form:{
|
||||
id:'',
|
||||
protocol:'',
|
||||
address:'',
|
||||
configIndex: 0,
|
||||
configList: [],
|
||||
form: {
|
||||
id: '',
|
||||
protocol: '',
|
||||
address: '',
|
||||
},
|
||||
protocolShow:false,
|
||||
protocolList:[
|
||||
{
|
||||
value: 'http://',
|
||||
label: 'http://'
|
||||
},
|
||||
protocolShow: false,
|
||||
protocolList: [
|
||||
{
|
||||
value: 'https://',
|
||||
label: 'https://'
|
||||
label: 'HTTPS'
|
||||
},
|
||||
{
|
||||
value: 'http://',
|
||||
label: 'HTTP'
|
||||
}
|
||||
],
|
||||
show:false,
|
||||
show: false,
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
// 小程序只使用https
|
||||
// #ifdef MP-WEIXIN
|
||||
this.protocolList = [
|
||||
{
|
||||
value: 'https://',
|
||||
label: 'https://'
|
||||
}
|
||||
]
|
||||
// this.protocolList = [
|
||||
// {
|
||||
// value: 'https://',
|
||||
// label: 'HTTPS'
|
||||
// }
|
||||
// ]
|
||||
// #endif
|
||||
this.getConfigList();
|
||||
},
|
||||
methods:{
|
||||
getConfigList(){
|
||||
methods: {
|
||||
getConfigList() {
|
||||
uni.getStorage({
|
||||
key:'configList',
|
||||
key: 'configList',
|
||||
}).then(res => {
|
||||
// 如果返回数组为两位就是正确
|
||||
if(res.length==2){
|
||||
if (res.length == 2) {
|
||||
this.configList = res[1].data;
|
||||
}
|
||||
return uni.getStorage({
|
||||
key:'configIndex',
|
||||
key: 'configIndex',
|
||||
})
|
||||
}).then(res => {
|
||||
console.log("configIndex",res)
|
||||
if(res.length==2){
|
||||
console.log("configIndex", res)
|
||||
if (res.length == 2) {
|
||||
this.configIndex = res[1].data;
|
||||
}
|
||||
})
|
||||
},
|
||||
changeConfig(i){
|
||||
console.log("index",i)
|
||||
if(i !== this.configIndex){
|
||||
changeConfig(i) {
|
||||
console.log("index", i)
|
||||
if (i !== this.configIndex) {
|
||||
this.configIndex = i;
|
||||
uni.setStorage({
|
||||
key:'configIndex',
|
||||
key: 'configIndex',
|
||||
data: i,
|
||||
}).then(res => {
|
||||
console.log("修改索引")
|
||||
})
|
||||
}
|
||||
},
|
||||
verification(){
|
||||
if(!this.form.protocol){
|
||||
verification() {
|
||||
if (!this.form.protocol) {
|
||||
this.$refs.uToast.show({
|
||||
title: '请先选择协议!',
|
||||
type: 'error'
|
||||
})
|
||||
return false;
|
||||
}else if(!this.form.address){
|
||||
} else if (!this.form.address) {
|
||||
this.$refs.uToast.show({
|
||||
title: '请先输入地址',
|
||||
type: 'error',
|
||||
})
|
||||
return false;
|
||||
}else if(!this.$u.test.url(this.form.protocol+this.form.address)){
|
||||
} else if (!this.$u.test.url(this.form.protocol + this.form.address)) {
|
||||
this.$refs.uToast.show({
|
||||
title: '请确认输入地址正确',
|
||||
type: 'error',
|
||||
})
|
||||
return false;
|
||||
}else{
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
openAdd(){
|
||||
if(this.configList.length == 0){
|
||||
openAdd() {
|
||||
if (this.configList.length == 0) {
|
||||
this.form = {
|
||||
id:'',
|
||||
protocol:'https://',
|
||||
address:'cloud.iot-fast.com',
|
||||
id: '',
|
||||
protocol: 'http://',
|
||||
address: '192.168.1.17:8848',
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
this.form = {
|
||||
id:'',
|
||||
protocol:'',
|
||||
address:'',
|
||||
id: '',
|
||||
protocol: '',
|
||||
address: '',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.show = true;
|
||||
},
|
||||
addConfig(){
|
||||
console.log("添加页面",this.form)
|
||||
if(this.verification()){
|
||||
if(this.form.id===''){
|
||||
addConfig() {
|
||||
console.log("添加页面", this.form)
|
||||
if (this.verification()) {
|
||||
if (this.form.id === '') {
|
||||
// 新增
|
||||
this.configList.push({
|
||||
id:this.$u.guid(32),
|
||||
protocol:this.form.protocol,
|
||||
address:this.form.address,
|
||||
id: this.$u.guid(32),
|
||||
protocol: this.form.protocol,
|
||||
address: this.form.address,
|
||||
})
|
||||
uni.setStorage({
|
||||
key:'configList',
|
||||
key: 'configList',
|
||||
data: this.configList,
|
||||
}).then(res => {
|
||||
this.$refs.uToast.show({
|
||||
|
@ -172,9 +217,9 @@
|
|||
type: 'success',
|
||||
})
|
||||
})
|
||||
if(this.configList.length==1){
|
||||
if (this.configList.length == 1) {
|
||||
uni.setStorage({
|
||||
key:'configIndex',
|
||||
key: 'configIndex',
|
||||
data: 0,
|
||||
}).then(res => {
|
||||
console.log("添加第一个域名索引为0")
|
||||
|
@ -182,18 +227,18 @@
|
|||
}
|
||||
this.show = false;
|
||||
this.getConfigList()
|
||||
console.log("configList",this.configList)
|
||||
}else{
|
||||
console.log("configList", this.configList)
|
||||
} else {
|
||||
// 编辑
|
||||
this.configList.map(item=>{
|
||||
if(item.id == this.form.id){
|
||||
item.protocol=this.form.protocol;
|
||||
item.address=this.form.address;
|
||||
this.configList.map(item => {
|
||||
if (item.id == this.form.id) {
|
||||
item.protocol = this.form.protocol;
|
||||
item.address = this.form.address;
|
||||
}
|
||||
return item;
|
||||
})
|
||||
uni.setStorage({
|
||||
key:'configList',
|
||||
key: 'configList',
|
||||
data: this.configList,
|
||||
}).then(res => {
|
||||
this.$refs.uToast.show({
|
||||
|
@ -204,28 +249,29 @@
|
|||
this.show = false;
|
||||
this.getConfigList()
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
this.$refs.uModal.clearLoading();
|
||||
}
|
||||
},
|
||||
confirmProtocol(e){
|
||||
confirmProtocol(e) {
|
||||
this.form.protocol = e[0].value;
|
||||
},
|
||||
openEdit(index){
|
||||
this.form = this.configList[index];
|
||||
openEdit(index) {
|
||||
console.log("编辑",index)
|
||||
this.form = JSON.parse(JSON.stringify(this.configList[index]));
|
||||
this.show = true;
|
||||
},
|
||||
delConfig(index){
|
||||
delConfig(index) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确认要删除域名吗?',
|
||||
success: (res)=>{
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
console.log('用户点击确定');
|
||||
|
||||
|
||||
this.configList.splice(index, 1);
|
||||
uni.setStorage({
|
||||
key:'configList',
|
||||
key: 'configList',
|
||||
data: this.configList,
|
||||
}).then(res => {
|
||||
this.$refs.uToast.show({
|
||||
|
@ -233,19 +279,19 @@
|
|||
type: 'success',
|
||||
})
|
||||
})
|
||||
if(this.configIndex<index){
|
||||
}else{
|
||||
if(this.configIndex>index){
|
||||
if (this.configIndex < index) {
|
||||
} else {
|
||||
if (this.configIndex > index) {
|
||||
this.configIndex = this.configIndex - 1;
|
||||
}else if(this.configIndex==index){
|
||||
if(this.configList.length==0){
|
||||
} else if (this.configIndex == index) {
|
||||
if (this.configList.length == 0) {
|
||||
this.configIndex = -1;
|
||||
}else{
|
||||
} else {
|
||||
this.configIndex = 0;
|
||||
}
|
||||
}
|
||||
uni.setStorage({
|
||||
key:'configIndex',
|
||||
key: 'configIndex',
|
||||
data: this.configIndex,
|
||||
}).then(res => {
|
||||
console.log("修改索引")
|
||||
|
@ -261,129 +307,130 @@
|
|||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
page{
|
||||
background: #f5f5f5;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.color-blue{
|
||||
color: $mainColor;
|
||||
page {
|
||||
background-color: #F5F7FA;
|
||||
}
|
||||
.color-red{
|
||||
color: red;
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
background-color: #F5F7FA;
|
||||
padding: 20rpx;
|
||||
}
|
||||
.config-box{
|
||||
.config-list{
|
||||
.config-item{
|
||||
background: #fff;
|
||||
// border-radius: 10rpx;
|
||||
padding: 30rpx 20rpx;
|
||||
padding-left: 70rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
overflow: hidden;
|
||||
.acitve-box{
|
||||
z-index: 888;
|
||||
position: absolute;
|
||||
top: -16rpx;
|
||||
left: -76rpx;
|
||||
width: 200rpx;
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transform: rotate(-40deg) ;
|
||||
padding-top: 30rpx;
|
||||
color: #fff;
|
||||
background: $mainColor;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
.icon-checkbox-mark{
|
||||
position: absolute;
|
||||
top:20rpx;
|
||||
left:10rpx;
|
||||
}
|
||||
.operate-box{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.iconfont{
|
||||
font-weight: bold;
|
||||
margin-left: 20rpx;
|
||||
font-size: 40rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.domain-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
margin-bottom: 120rpx; // 为底部按钮留出空间
|
||||
}
|
||||
|
||||
.slot-content{
|
||||
padding: 20rpx 30rpx;
|
||||
.form-item{
|
||||
|
||||
.domain-item {
|
||||
background-color: #ffffff;
|
||||
border-radius: 12rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
|
||||
&-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10rpx;
|
||||
padding: 35rpx 30rpx;
|
||||
}
|
||||
|
||||
&-active {
|
||||
background-color: #f0f7ff;
|
||||
border: 1rpx solid #2979ff;
|
||||
}
|
||||
.domain-item-btn{
|
||||
margin-left: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.radio-wrapper {
|
||||
margin-right: 0rpx;
|
||||
}
|
||||
|
||||
.protocol-tag {
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 6rpx;
|
||||
margin-right: 20rpx;
|
||||
font-size: 26rpx;
|
||||
&.https {
|
||||
background-color: rgba(41, 121, 255, 0.1);
|
||||
|
||||
.form-label{
|
||||
width: 170rpx;
|
||||
text {
|
||||
color: #2979ff;
|
||||
}
|
||||
.form-value{
|
||||
flex: 1;
|
||||
background: #f0f0f0;
|
||||
border-radius: 8rpx;
|
||||
height: 70rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-right: 20rpx;
|
||||
input{
|
||||
width: 100%;
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
}
|
||||
&:first-child{
|
||||
.form-value{
|
||||
// justify-content: flex-end;
|
||||
padding-left: 20rpx;
|
||||
position: relative;
|
||||
padding-right: 40rpx;
|
||||
.iconfont{
|
||||
position: absolute;
|
||||
right: 6rpx;
|
||||
top: 19rpx;
|
||||
font-size: 37rpx;
|
||||
color: #8a8c90;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.http {
|
||||
background-color: rgba(255, 152, 0, 0.1);
|
||||
|
||||
text {
|
||||
color: #ff9800;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-box{
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 130rpx;
|
||||
padding: 10rpx;
|
||||
padding-bottom: 20rpx;
|
||||
box-sizing: border-box;
|
||||
bottom: 0;
|
||||
|
||||
.domain-name {
|
||||
flex: 1;
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
background-color: #fff;
|
||||
button{
|
||||
width: 95%;
|
||||
background-color: $mainColor;
|
||||
color: #fff;
|
||||
}
|
||||
.bg-grey{
|
||||
background: #e7e7e7;
|
||||
color: #8a8c90;
|
||||
gap: 30rpx;
|
||||
view {
|
||||
padding: 10rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
.add-button-wrapper {
|
||||
padding: 30rpx 20rpx;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.slot-content {
|
||||
padding: 20rpx 30rpx;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.form-label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.form-value {
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 8rpx;
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 20rpx;
|
||||
position: relative;
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.arrow-icon {
|
||||
position: absolute;
|
||||
right: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,458 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<!-- 设备统计卡片 -->
|
||||
<view class="stat-card">
|
||||
<view class="card-header">
|
||||
<view class="header-left">
|
||||
<u-icon name="grid" size="34" color="#666"></u-icon>
|
||||
<text class="header-title">设备统计</text>
|
||||
</view>
|
||||
<view class="header-right" @click="viewDeviceDetails">
|
||||
<text class="detail-text">查看详情</text>
|
||||
<u-icon name="arrow-right" size="28" color="#999"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 设备数量统计 -->
|
||||
<view class="stat-row">
|
||||
<view class="stat-item">
|
||||
<text class="stat-value blue">{{deviceInfo.deviceNum || 0}}</text>
|
||||
<text class="stat-label">设备数量</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<text class="stat-value blue">{{deviceInfo.deviceOnlineNum || 0}}</text>
|
||||
<text class="stat-label">在线数</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<text class="stat-value blue">{{deviceInfo.deviceOfflineNum || 0}}</text>
|
||||
<text class="stat-label">离线数</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 设备消息量统计 -->
|
||||
<view class="stat-row">
|
||||
<view class="stat-item">
|
||||
<text class="stat-value blue">{{deviceInfo.todayMessageNum || 0}}</text>
|
||||
<text class="stat-label">今日设备消息量</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<text class="stat-value blue">{{deviceInfo.thisMonthMessageNum || 0}}</text>
|
||||
<text class="stat-label">当月设备消息量</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 告警统计卡片 -->
|
||||
<view class="stat-card">
|
||||
<view class="card-header">
|
||||
<view class="header-left">
|
||||
<u-icon name="bell" size="34" color="#666"></u-icon>
|
||||
<text class="header-title">告警统计</text>
|
||||
</view>
|
||||
<view class="header-right" @click="viewAlarmDetails">
|
||||
<text class="detail-text">查看详情</text>
|
||||
<u-icon name="arrow-right" size="28" color="#999"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 告警数量统计 -->
|
||||
<view class="stat-row">
|
||||
<view class="stat-item">
|
||||
<text class="stat-value red">{{alarmInfo.todayMessageNum || 0}}</text>
|
||||
<text class="stat-label">今日告警数</text>
|
||||
</view>
|
||||
<view class="stat-item">
|
||||
<text class="stat-value red">{{alarmInfo.thisMonthMessageNum || 0}}</text>
|
||||
<text class="stat-label">当月告警数</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 最新告警列表 -->
|
||||
<view class="alarm-list">
|
||||
<view class="alarm-list-title">最新告警列表</view>
|
||||
|
||||
<!-- 告警项 -->
|
||||
<u-empty v-if="alarmList.length == 0" margin-top="50" text="告警列表为空" mode="list"></u-empty>
|
||||
<view v-else class="alarm-item" v-for="(item, index) in alarmList" :key="index">
|
||||
<view class="alarm-info">
|
||||
<text class="alarm-name">{{ item.alarmName }}</text>
|
||||
<text class="alarm-status">{{ item.state.text }}</text>
|
||||
</view>
|
||||
<view class="alarm-detail">
|
||||
<view :class="['alarm-level', 'alarm-level-' + item.level]">{{ getAlarmName(item.level) }}</view>
|
||||
<text class="alarm-time">{{$u.timeFormat(item.time, 'yyyy-mm-dd hh:MM:ss')}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
deviceInfo:{
|
||||
deviceNum:0,
|
||||
deviceOnlineNum:0,
|
||||
deviceOfflineNum:0,
|
||||
todayMessageNum:0,
|
||||
thisMonthMessageNum:0,
|
||||
},
|
||||
alarmInfo:{
|
||||
todayMessageNum:0,
|
||||
thisMonthMessageNum:0,
|
||||
},
|
||||
alarmLevelList:[
|
||||
{
|
||||
level: 1,
|
||||
title: "超紧急"
|
||||
},
|
||||
{
|
||||
level: 2,
|
||||
title: "紧急"
|
||||
},
|
||||
{
|
||||
level: 3,
|
||||
title: "严重"
|
||||
},
|
||||
{
|
||||
level: 4,
|
||||
title: "一般"
|
||||
},
|
||||
{
|
||||
level: 5,
|
||||
title: "提醒"
|
||||
}
|
||||
],
|
||||
alarmList: []
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.getAlarmLevelList();
|
||||
},
|
||||
onShow() {
|
||||
this.getDeviceInfo();
|
||||
this.getDeviceMessageCount();
|
||||
this.getAlarmMessageCount();
|
||||
this.getAlarmList();
|
||||
},
|
||||
methods: {
|
||||
getAlarmName(level) {
|
||||
const foundItem = this.alarmLevelList.find(item => item.level === level);
|
||||
return foundItem ? foundItem.title : '';
|
||||
},
|
||||
getAlarmLevelList(){
|
||||
this.$api.iotsApi.getAlarmLevelList().then(res => {
|
||||
if(res.status == 200){
|
||||
this.alarmLevelList = res.result.levels || [];
|
||||
}else{
|
||||
this.$u.toast(res.message);
|
||||
}
|
||||
}, error => {
|
||||
this.$u.toast('服务器开小差了呢,请您稍后再试')
|
||||
})
|
||||
},
|
||||
getDeviceInfo(){
|
||||
this.getDeviceCount('deviceNum',{})
|
||||
this.getDeviceCount('deviceOnlineNum',{'terms[0].column':'state','terms[0].value':'online'})
|
||||
this.getDeviceCount('deviceOfflineNum',{'terms[0].column':'state','terms[0].value':'offline'})
|
||||
},
|
||||
viewDeviceDetails() {
|
||||
uni.switchTab({
|
||||
url: '/pages/tabbar/device'
|
||||
});
|
||||
},
|
||||
viewAlarmDetails() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/alarm/statistics-detail'
|
||||
});
|
||||
},
|
||||
getDeviceCount(type,params){
|
||||
this.$api.iotsApi.getDeviceInstanceCount(params).then(res => {
|
||||
if(res.status == 200){
|
||||
this.deviceInfo[type] = res.result;
|
||||
}else{
|
||||
this.$u.toast(res.message);
|
||||
}
|
||||
}, error => {
|
||||
this.$u.toast('服务器开小差了呢,请您稍后再试')
|
||||
})
|
||||
},
|
||||
getDeviceMessageCount(){
|
||||
this.$api.getDashboardSelect([
|
||||
{
|
||||
"dashboard": "device",
|
||||
"object": "message",
|
||||
"measurement": "quantity",
|
||||
"dimension": "agg",
|
||||
"group": "oneday",
|
||||
"params": {
|
||||
"time": "1d",
|
||||
"format": "yyyy-MM-dd",
|
||||
"from": "now-1d"
|
||||
}
|
||||
},
|
||||
{
|
||||
"dashboard": "device",
|
||||
"object": "message",
|
||||
"measurement": "quantity",
|
||||
"dimension": "agg",
|
||||
"group": "thisMonth",
|
||||
"params": {
|
||||
"time": "1M",
|
||||
"format": "yyyy-MM",
|
||||
"limit": 1,
|
||||
"from": "now-1M"
|
||||
}
|
||||
}
|
||||
]).then(res => {
|
||||
if(res.status == 200){
|
||||
if(res.result && Array.isArray(res.result)){
|
||||
res.result.forEach((item)=>{
|
||||
if(item.group === 'oneday'){
|
||||
this.deviceInfo.todayMessageNum = item.data.value || 0;
|
||||
}else if(item.group === 'thisMonth'){
|
||||
this.deviceInfo.thisMonthMessageNum = item.data.value || 0;
|
||||
}
|
||||
})
|
||||
}
|
||||
}else{
|
||||
this.$u.toast(res.message);
|
||||
}
|
||||
}, error => {
|
||||
this.$u.toast('服务器开小差了呢,请您稍后再试')
|
||||
})
|
||||
},
|
||||
getAlarmMessageCount(){
|
||||
this.$api.getDashboardSelect([
|
||||
{
|
||||
"dashboard": "alarm",
|
||||
"object": "record",
|
||||
"measurement": "trend",
|
||||
"dimension": "agg",
|
||||
"group": "today",
|
||||
"params": {
|
||||
"time": "1d",
|
||||
"format": "HH:mm:ss",
|
||||
"from": "2025-04-24 00:00:00",
|
||||
"to": "now"
|
||||
}
|
||||
},
|
||||
{
|
||||
"dashboard": "alarm",
|
||||
"object": "record",
|
||||
"measurement": "trend",
|
||||
"dimension": "agg",
|
||||
"group": "thisMonth",
|
||||
"params": {
|
||||
"time": "1M",
|
||||
"format": "yyyy-MM",
|
||||
"limit": 1,
|
||||
"from": "now-1M"
|
||||
}
|
||||
}
|
||||
]).then(res => {
|
||||
if(res.status == 200){
|
||||
if(res.result && Array.isArray(res.result)){
|
||||
res.result.forEach((item)=>{
|
||||
if(item.group === 'today'){
|
||||
this.alarmInfo.todayMessageNum = item.data.value || 0;
|
||||
}else if(item.group === 'thisMonth'){
|
||||
this.alarmInfo.thisMonthMessageNum = item.data.value || 0;
|
||||
}
|
||||
})
|
||||
}
|
||||
}else{
|
||||
this.$u.toast(res.message);
|
||||
}
|
||||
}, error => {
|
||||
this.$u.toast('服务器开小差了呢,请您稍后再试')
|
||||
})
|
||||
},
|
||||
getAlarmList(){
|
||||
this.$api.iotsApi.getAlarmList({
|
||||
"pageIndex": 0,
|
||||
"pageSize": 5,
|
||||
"sorts": [
|
||||
{
|
||||
"name": "alarmTime",
|
||||
"order": "desc"
|
||||
}
|
||||
],
|
||||
"terms": [
|
||||
{
|
||||
"terms": [
|
||||
{
|
||||
"type": "and",
|
||||
"value": "%warning%",
|
||||
"termType": "like",
|
||||
"column": "state"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}).then(res => {
|
||||
if(res.status == 200){
|
||||
this.alarmList = res.result.data || [];
|
||||
}else{
|
||||
this.$u.toast(res.message);
|
||||
}
|
||||
}, error => {
|
||||
this.$u.toast('服务器开小差了呢,请您稍后再试')
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
background-color: #f5f5f5;
|
||||
padding: 20rpx;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 30rpx;
|
||||
border-bottom: 2px solid #F9F9F9;
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.header-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
margin-left: 10rpx;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.detail-text {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.stat-row {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
margin-bottom: 20rpx;
|
||||
padding: 30rpx;
|
||||
.stat-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
|
||||
.stat-value {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10rpx;
|
||||
|
||||
&.blue {
|
||||
color: #2979ff;
|
||||
}
|
||||
|
||||
&.red {
|
||||
color: #ff5252;
|
||||
}
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.alarm-list {
|
||||
padding: 30rpx;
|
||||
.alarm-list-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.alarm-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.alarm-info {
|
||||
.alarm-name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-bottom: 10rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.alarm-status {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.alarm-detail {
|
||||
text-align: right;
|
||||
|
||||
.alarm-level {
|
||||
display: inline-block;
|
||||
padding: 4rpx 16rpx;
|
||||
border-radius: 6rpx;
|
||||
font-size: 22rpx;
|
||||
margin-bottom: 10rpx;
|
||||
color: #fff;
|
||||
&.alarm-level-1 {
|
||||
background-color: #E50012;
|
||||
}
|
||||
|
||||
&.alarm-level-2 {
|
||||
background-color: #FF9457;
|
||||
}
|
||||
|
||||
&.alarm-level-3 {
|
||||
background-color: #FABD47;
|
||||
}
|
||||
|
||||
&.alarm-level-4 {
|
||||
background-color: #999999;
|
||||
}
|
||||
|
||||
&.alarm-level-5 {
|
||||
background-color: #BBBBBB;
|
||||
}
|
||||
}
|
||||
|
||||
.alarm-time {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,405 @@
|
|||
<template>
|
||||
<view class="device-list-box">
|
||||
<!-- 菜单 -->
|
||||
<view class="device-search">
|
||||
<u-dropdown class="sl-filter" border-bottom>
|
||||
<u-dropdown-item v-model="productId" title="所属产品" height="750" :options="productList" @change="searchChange"></u-dropdown-item>
|
||||
<u-dropdown-item v-model="deviceType" title="设备类型" :options="deviceTypeList" @change="searchChange"></u-dropdown-item>
|
||||
</u-dropdown>
|
||||
<u-search placeholder="请输入设备名称/编号搜索" class="uni-search-bar" v-model="searchVal" @custom="searchChange" @clear="searchChange" @search="searchChange"></u-search>
|
||||
<u-tabs :list="tabsList" bar-width="187" :is-scroll="false" :current="tabIndex" @change="tabChange"></u-tabs>
|
||||
</view>
|
||||
|
||||
<mescroll-body ref="mescrollRef" top="260" @init="mescrollInit" @down="downCallback" :up="upOption" @up="upCallback">
|
||||
<view class="device-box">
|
||||
<view class="device-info">
|
||||
<view class="name">设备总数: <text style="font-size: 24rpx;">{{total}}</text></view>
|
||||
</view>
|
||||
<!-- 设备列表 -->
|
||||
<view class="device-list">
|
||||
<view class="device-item" v-for="(item, index) in dataList" :key="index" @click="goDetail(item)">
|
||||
<!-- 设备名称和类型区域 -->
|
||||
<view class="device-header">
|
||||
<view class="device-title">{{ item.productName }}</view>
|
||||
</view>
|
||||
|
||||
<!-- 设备图片和信息区域 -->
|
||||
<view class="device-content">
|
||||
<!-- 设备图片 -->
|
||||
<view class="device-img-box">
|
||||
<image v-if="item.photoUrl" :src="item.photoUrl" mode="aspectFit"></image>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<image v-else src="http://static.drgyen.com/app/iot-ui-app/image/device/device-card.png" mode="aspectFit"></image>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<image v-else src="/static/app-plus/image/device/device-card.png" mode="aspectFit"></image>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
|
||||
<!-- 设备信息和状态 -->
|
||||
<view class="device-info-box">
|
||||
<!-- 设备状态 -->
|
||||
<view class="device-status-dot" :class="item.state.value">
|
||||
<text>{{ item.state.text }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 设备类型 -->
|
||||
<view class="device-type">{{ item.deviceType.text }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 设备名称 -->
|
||||
<view class="device-name-box">
|
||||
<text class="device-name">{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</mescroll-body>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js"
|
||||
export default {
|
||||
mixins: [MescrollMixin],
|
||||
components: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
upOption:{
|
||||
noMoreSize: 4,
|
||||
textNoMore: '---- 已经到底啦 ----',
|
||||
empty:{
|
||||
tip: '~ 搜索无数据 ~' // 提示
|
||||
}
|
||||
},
|
||||
tabbarIndex:1,
|
||||
productId:null,
|
||||
deviceType:null,
|
||||
searchVal: '',
|
||||
tabIndex: 0, // tab下标
|
||||
|
||||
productList:[],
|
||||
deviceTypeList:[
|
||||
{
|
||||
label: '全部设备',
|
||||
value: null,
|
||||
},
|
||||
{
|
||||
label: '直连设备',
|
||||
value: 'device',
|
||||
},
|
||||
{
|
||||
label: '网关子设备',
|
||||
value: 'childrenDevice',
|
||||
},
|
||||
{
|
||||
label: '网关设备',
|
||||
value: 'gateway',
|
||||
}
|
||||
],
|
||||
|
||||
tabsList:[{
|
||||
name: '全部',
|
||||
value: null
|
||||
}, {
|
||||
name: '禁用',
|
||||
value: 'notActive'
|
||||
}, {
|
||||
name: '在线',
|
||||
value: 'online'
|
||||
}, {
|
||||
name: '离线',
|
||||
value: 'offline'
|
||||
}],
|
||||
dataList: [],
|
||||
total: 0,
|
||||
imgPath:'',
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.getConfigPath();
|
||||
this.getProductList();
|
||||
this.getUserInfo();
|
||||
},
|
||||
methods: {
|
||||
getUserInfo(){
|
||||
this.$api.getUserInfo({}).then(res => {
|
||||
console.log("获取用户信息",res)
|
||||
if(res.status == 200){
|
||||
uni.setStorageSync('userInfo',res.result)
|
||||
}
|
||||
}, error => {
|
||||
})
|
||||
},
|
||||
goDetail(obj){
|
||||
// console.log("跳转设备详情",obj)
|
||||
uni.navigateTo({
|
||||
url:'./device-detail?id=' + obj.id + '&devName=' + obj.devName
|
||||
})
|
||||
},
|
||||
getConfigPath(){
|
||||
let configList = uni.getStorageSync('configList');
|
||||
let configIndex = uni.getStorageSync('configIndex');
|
||||
this.imgPath = configList[configIndex].protocol + configList[configIndex].address;
|
||||
},
|
||||
getDeviceTypeLabel(type) {
|
||||
const typeMap = {
|
||||
'device': '直连设备',
|
||||
'childrenDevice': '网关子设备',
|
||||
'gateway': '网关设备'
|
||||
};
|
||||
return typeMap[type] || '网关设备';
|
||||
},
|
||||
// 切换菜单
|
||||
tabChange(e) {
|
||||
this.tabIndex = e;
|
||||
this.mescroll.resetUpScroll() // 再刷新列表数据
|
||||
},
|
||||
searchChange(e) {
|
||||
// this.searchVal = res.value
|
||||
this.dataList = []// 先置空列表,显示加载进度
|
||||
this.mescroll.resetUpScroll() // 再刷新列表数据
|
||||
},
|
||||
getProductList(){
|
||||
this.$api.iotsApi.getProductList({paging:false}).then(res => {
|
||||
if(res.status == 200 && res.result.length>0){
|
||||
let productList = res.result.map((item)=>{
|
||||
return {
|
||||
label:item.name,
|
||||
value:item.id
|
||||
}
|
||||
})
|
||||
this.productList = [{
|
||||
label: '全部产品',
|
||||
value: null,
|
||||
},...productList];
|
||||
}else{
|
||||
this.productList = [{
|
||||
label: '全部产品',
|
||||
value: null,
|
||||
}];
|
||||
}
|
||||
}, error => {
|
||||
})
|
||||
},
|
||||
upCallback(page) {
|
||||
let pageNum = page.num-1;
|
||||
let params = {
|
||||
"pageIndex": pageNum,
|
||||
"pageSize": page.size,
|
||||
"sorts": [
|
||||
{
|
||||
"name": "createTime",
|
||||
"order": "desc"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"order": "desc"
|
||||
}
|
||||
],
|
||||
"terms": [{
|
||||
"terms": [
|
||||
{ "type": "and", "column": "productId", "termType": "eq", "value": this.productId },
|
||||
{ "type": "and", "column": "state", "termType": "eq", "value": this.tabsList[this.tabIndex].value },
|
||||
{ "type": "and", "column": "deviceType", "termType": "eq", "value": this.deviceType }
|
||||
]
|
||||
},
|
||||
// 新增的 id/name 模糊查询
|
||||
{
|
||||
"terms": [
|
||||
{ "type": "or", "column": "id", "termType": "like", "value": "%"+this.searchVal+"%" },
|
||||
{ "type": "or", "column": "name", "termType": "like", "value": "%"+this.searchVal+"%" }
|
||||
]
|
||||
}],
|
||||
}
|
||||
this.$api.iotsApi.getDeviceList(params).then(res => {
|
||||
if(res.status === 200){
|
||||
let curPageData = res.result && res.result.data;
|
||||
let curPageLen = curPageData && curPageData.length || 0;
|
||||
let totalSize = res.result.total;
|
||||
this.$nextTick(()=>{
|
||||
// 隐藏下拉刷新和上拉加载的状态;
|
||||
this.mescroll.endBySize(curPageLen, totalSize);
|
||||
})
|
||||
//设置列表数据
|
||||
if(page.num == 1) this.dataList = []; //如果是第一页需手动制空列表
|
||||
this.dataList = curPageLen > 0 && this.dataList.concat(curPageData); //追加新数据
|
||||
this.total = totalSize;
|
||||
}else{
|
||||
this.$u.toast(res.msg);
|
||||
this.mescroll.endErr();
|
||||
}
|
||||
}, error => {
|
||||
console.error("API Error:", error);
|
||||
uni.showToast({
|
||||
title: '请求失败,请稍后重试',
|
||||
icon: 'none'
|
||||
});
|
||||
this.mescroll.endErr();
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page{
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/deep/.u-search{
|
||||
padding: 19rpx 20rpx;
|
||||
border-bottom: 1px solid #f4f6f8;
|
||||
}
|
||||
.device-list-box{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f5f5f5;
|
||||
.device-search{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
box-sizing: border-box;
|
||||
height: 260rpx;
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.device-box{
|
||||
.device-info{
|
||||
text-align: right;
|
||||
padding: 20rpx;
|
||||
padding-bottom: 0;
|
||||
.name{
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
.device-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 20rpx;
|
||||
|
||||
.device-item {
|
||||
width: 345rpx;
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
padding: 20rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:nth-child(2n-1) {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
// 设备头部:产品名称
|
||||
.device-header {
|
||||
margin-bottom: 15rpx;
|
||||
|
||||
.device-title {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
// 设备内容:图片和设备信息
|
||||
.device-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15rpx;
|
||||
|
||||
.device-img-box {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.device-info-box {
|
||||
flex: 1;
|
||||
padding-left: 36rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
// 设备状态
|
||||
.device-status-dot {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 24rpx;
|
||||
margin-bottom: 10rpx;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
|
||||
&.online {
|
||||
color: #10CC70;
|
||||
&::before {
|
||||
background-color: #10CC70;
|
||||
}
|
||||
}
|
||||
|
||||
&.offline {
|
||||
color: #E50012;
|
||||
&::before {
|
||||
background-color: #E50012;
|
||||
}
|
||||
}
|
||||
|
||||
&.notActive {
|
||||
color: #FF9000;
|
||||
&::before {
|
||||
background-color: #FF9000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 设备类型
|
||||
.device-type {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 设备名称
|
||||
.device-name-box {
|
||||
.device-name {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
display: block;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -46,7 +46,7 @@
|
|||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="my-item" @click="goItem('none')">
|
||||
<!-- <view class="my-item" @click="goItem('none')">
|
||||
<view class="my-item-left">
|
||||
<view class="my-item-icon color-blue">
|
||||
<view class="iconfont icon-mobile"></view>
|
||||
|
@ -63,7 +63,7 @@
|
|||
<view class="iconfont icon-xiangyou1"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="my-item">
|
||||
<view class="my-item-left">
|
||||
<view class="my-item-icon color-yellow">
|
||||
|
@ -172,12 +172,13 @@
|
|||
},
|
||||
onShow() {
|
||||
let userInfo = uni.getStorageSync('userInfo');
|
||||
console.log("userInfo",userInfo)
|
||||
if(userInfo){
|
||||
this.userInfo = {
|
||||
name:userInfo.username,
|
||||
company:userInfo.realName,
|
||||
name:userInfo.name,
|
||||
company:userInfo.realName || '物联网平台',
|
||||
imgPath:userInfo.avatar,
|
||||
phone:phoneHide(userInfo.mobile)
|
||||
// phone:phoneHide(userInfo.telephone)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -238,16 +239,32 @@
|
|||
if (res.confirm) {
|
||||
console.log('用户点击确定');
|
||||
// this.$store.commit('logout');
|
||||
this.$store.commit('setTokenKey', '');
|
||||
uni.$u.toast('退出登录成功');
|
||||
uni.removeStorageSync('token')
|
||||
uni.removeStorageSync('expire')
|
||||
setTimeout(()=>{
|
||||
uni.reLaunch({
|
||||
url:"../tabbar/login"
|
||||
})
|
||||
return;
|
||||
},200)
|
||||
this.$api.userLogout({}).then(res => {
|
||||
if(res.status == 200){
|
||||
this.$store.commit('setTokenKey', '');
|
||||
uni.$u.toast('退出登录成功');
|
||||
uni.removeStorageSync('token')
|
||||
uni.removeStorageSync('expire')
|
||||
setTimeout(()=>{
|
||||
uni.reLaunch({
|
||||
url:"../tabbar/login"
|
||||
})
|
||||
return;
|
||||
},200)
|
||||
}
|
||||
}, error => {
|
||||
this.$store.commit('setTokenKey', '');
|
||||
uni.$u.toast('退出登录成功');
|
||||
uni.removeStorageSync('token')
|
||||
uni.removeStorageSync('expire')
|
||||
setTimeout(()=>{
|
||||
uni.reLaunch({
|
||||
url:"../tabbar/login"
|
||||
})
|
||||
return;
|
||||
},200)
|
||||
})
|
||||
|
||||
} else if (res.cancel) {
|
||||
console.log('用户点击取消');
|
||||
}
|
||||
|
|
After Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 521 B |
After Width: | Height: | Size: 474 B |
After Width: | Height: | Size: 783 B |
After Width: | Height: | Size: 705 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 534 B |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 494 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 527 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 493 B |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 560 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 510 B |