496 lines
13 KiB
Vue
Raw Normal View History

2024-12-09 14:16:57 +08:00
<template>
<page-meta>
<navigation-bar :title="$tt('scene.sceneLink')" title-align="center" background-color="#007AFF" />
</page-meta>
<view class="scene-wrap">
<u-sticky zIndex="98" bgColor="#eef3f7">
<view class="nav-bar">
<view class="left-wrap">
<view style="margin-right: 20rpx;">
<u-icon name="list-dot" size="23" @click="isMenu = true"></u-icon>
</view>
<view v-if="!isSearch" style="margin-right: 20rpx;">
<u-icon name="search" size="23" @click="isSearch = true"></u-icon>
</view>
<view v-else style="margin-right: 20rpx; width: 100%;">
<!-- #ifndef APP-NVUE -->
<u-input :customStyle="{ padding: '6rpx 18rpx'}" v-model="queryParams.sceneName"
:placeholder="$tt('scene.inputSceneName')" shape="circle" @clear="handleClearSearch"
clearable>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<u--input :customStyle="{ padding: '6rpx 18rpx'}" v-model="queryParams.sceneName"
:placeholder="$tt('scene.inputSceneName')" shape="circle" @clear="handleClearSearch"
clearable>
<!-- #endif -->
<template slot="prefix">
<u-icon name="search" size="22" @click="isSearch = false"></u-icon>
</template>
<template slot="suffix">
<u-button :text="$tt('scene.search')" type="primary" shape="circle" size="mini"
@click="handleSearch"></u-button>
</template>
<!-- #ifndef APP-NVUE -->
</u-input>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
</u--input>
<!-- #endif -->
</view>
</view>
<u-icon name="plus-circle-fill" size="23" color='#3c9cff' bold @tap="handleAddScene"></u-icon>
</view>
<view class="tab-wrap">
<u-tabs :list="statusGroup" :scrollable="true" lineWidth="40" lineHeight="2" lineColor="transparent"
:duration="100" :activeStyle="{ fontSize: '36rpx', color: '#3c9cff', fontWeight: 'bold' }"
@change="handleStatusChange">
</u-tabs>
</view>
</u-sticky>
<view class="container-wrap">
<view class="item-wrap" v-for="(item, index) in list" :key="index">
<view class="card" :style="{ margin: index === 0 ? '0 30rpx 30rpx' : '30rpx'}">
<view class="delIcon" @click="handleDelete(item)">
<u-icon size="18" name="close-circle-fill" color="#007aff"></u-icon>
</view>
<view @click="handleSceneDetail(item.sceneId)">
<view class="title">
<u--text lines="1" :text="item.sceneName"></u--text>
<u-icon name="arrow-right" color="#606266" customStyle="margin-right:5px;"
size="14"></u-icon>
</view>
<view class="cond">{{$tt('scene.condition')}}{{getCondName(item.cond)}}</view>
<view class="cond">{{$tt('scene.way')}}{{getExecuteModeName(item.executeMode)}}</view>
<view class="cond">{{$tt('scene.task')}}{{item.actionCount}}</view>
<view class="bottom-wrap" @tap.stop>
<u--text lines="1" prefixIcon="/static/scene/once.png"
iconStyle="width: 14px;height: 14px;margin-right: 3px;" size="13"
:text="$tt('scene.execute')" color='#3C9CFF' lineHeight="16"
@click="handleRunOnce(item)"></u--text>
<u-switch v-model="item.enable" @change="handleSwitchStatus(item)" :activeValue="1"
:inactiveValue="2" activeColor="#3C9CFF" inactiveColor="#dbdbdb" size="18"></u-switch>
</view>
</view>
</view>
</view>
<u-loadmore :status="loadmoreStatus" v-if="total > queryParams.pageSize"
:loading-text="$tt('scene.tryingToLoad')" :loadmoreText="$tt('scene.gentlyPullUp')"
:nomoreText="$tt('scene.emptyData')" marginTop="20" />
</view>
<view class="other">
<u-empty mode="data" :show="total === 0" marginTop="60" :text="$tt('scene.emptyData')"></u-empty>
<u-popup :show="isMenu" mode="top" :closeOnClickOverlay="true" :round="5" @close="isMenu = false">
<view class="menu-popup-wrap">
<view class="group-wrap">
<u-cell-group :border="false">
<view class="cell-wrap">
<u-cell icon="grid" :title="$tt('scene.administration')" :border="false" isLink
@click="goToSceneList"></u-cell>
</view>
</u-cell-group>
</view>
</view>
</u-popup>
</view>
<u-modal :show="isDelete" showCancelButton :confirmText="$tt('common.delete')" @cancel="() => isDelete = false"
:title="$tt('sceneDetail.tips')" :content="deleteContent" @confirm="handleConfirmDelete">
</u-modal>
</view>
</template>
<script>
import {
listScene,
runScene,
updateStatus,
delScene
} from '@/apis/modules/scene';
export default {
2025-03-27 14:23:27 +08:00
beforeRouteEnter(to, from, next) {
2024-12-09 14:16:57 +08:00
// 在进入路由前执行一些操作,例如加载数据等
next(vm => {
// 这里可以访问组件实例 `vm`
vm.onLoad() // 执行加载操作
})
},
2025-03-27 14:23:27 +08:00
data() {
2024-12-09 14:16:57 +08:00
return {
deleteId: '',
isDelete: false,
deleteContent: '',
isMenu: false,
isSearch: true,
// 状态列表
statusGroup: [{
id: null,
name: this.$tt('timing.all')
},
{
id: 1,
name: this.$tt('timing.enable')
},
{
id: 2,
name: this.$tt('timing.notEnabled')
}
],
queryParams: {
pageNum: 1,
pageSize: 4,
enable: null,
sceneName: '',
},
list: [],
total: 0,
loadmoreStatus: 'loadmore', // 刷新和加载相关
};
},
2025-03-27 14:23:27 +08:00
onLoad() {
2024-12-09 14:16:57 +08:00
this.getToken();
if (this.token != '' && this.token != null) {
this.getList();
}
},
2025-03-27 14:23:27 +08:00
onShow() {
2024-12-09 14:16:57 +08:00
// #ifdef MP-WEIXIN
// 检查用户是否登录
if (!this.isLogin()) {
uni.showModal({
title: this.$tt('common.tips'),
content: this.$tt('common.loginTips'),
success: (res) => {
if (res.confirm) {
// 用户点击确定,跳转到登录页面
uni.navigateTo({
url: '/pages/login/index'
});
} else if (res.cancel) {
uni.switchTab({
url: '/pages/tabBar/home/index'
})
console.log('用户点击取消');
}
}
});
}
// #endif
},
methods: {
2025-03-27 14:23:27 +08:00
getToken() {
2024-12-09 14:16:57 +08:00
// 本地缓存获取token
this.token = uni.getStorageSync('token');
// vuex存储token
uni.$u.vuex('vuex_token', this.token);
console.log(this.token)
},
//删除
2025-03-27 14:23:27 +08:00
handleDelete(item) {
2024-12-09 14:16:57 +08:00
this.isDelete = true;
this.deleteId = item.sceneId;
this.deleteContent = `确定删除“${item.sceneName}”?`
},
// 确认删除
2025-03-27 14:23:27 +08:00
handleConfirmDelete() {
2024-12-09 14:16:57 +08:00
delScene(this.deleteId).then(res => {
if (res.code === 200) {
this.list = [];
this.queryParams.pageNum = 1;
this.getList();
} else {
uni.showToast({
icon: 'none',
title: res.msg
});
}
this.isDelete = false;
}).catch(e => {
console.log(e);
});
},
//判断是否登录
2025-03-27 14:23:27 +08:00
isLogin() {
2024-12-09 14:16:57 +08:00
if (this.token == '' || this.token == null) {
return false;
} else {
return true;
}
},
// 场景状态改变事件
2025-03-27 14:23:27 +08:00
handleStatusChange(item) {
2024-12-09 14:16:57 +08:00
this.list = [];
this.queryParams.enable = item.id;
this.queryParams.pageNum = 1;
this.getList();
},
// 场景列表
2025-03-27 14:23:27 +08:00
goToSceneList() {
2024-12-09 14:16:57 +08:00
uni.navigateTo({
url: '/pagesA/scene/list'
});
this.isMenu = false;
},
// 新增场景
2025-03-27 14:23:27 +08:00
handleAddScene() {
2024-12-09 14:16:57 +08:00
// 使用vuex会导致小程序性能问题所以存储本地
let sceneData = {
sceneId: null,
sceneName: '',
remark: '',
enable: 1, // 状态1启动2暂停
cond: 1, // 触发条件1任意条件2所有条件3不满足
silentPeriod: 0, // 静默时间
executeMode: 1, // 执行方式1串行2并行
executeDelay: 0, // 延时执行
hasAlert: 2, // 1包含告警2不包含告警
applicationName: 'fastbee', // 固定值
triggers: [],
actions: [],
};
const storage = uni.getStorageSync('sceneData');
if (storage) {
uni.removeStorageSync('sceneData');
}
uni.setStorageSync('sceneData', sceneData);
uni.removeStorageSync('callback');
uni.navigateTo({
url: '/pagesA/scene/detail'
});
},
// 场景详情
2025-03-27 14:23:27 +08:00
handleSceneDetail(id) {
2024-12-09 14:16:57 +08:00
const storage = uni.getStorageSync('sceneData');
if (storage) {
uni.removeStorageSync('sceneData');
}
const sceneData = {
sceneId: null,
sceneName: '',
remark: '',
enable: 1, // 状态1启动2暂停
cond: 1, // 触发条件1任意条件2所有条件3不满足
silentPeriod: 0, // 静默时间
executeMode: 1, // 执行方式1串行2并行
executeDelay: 0, // 延时执行
hasAlert: 2, // 1包含告警2不包含告警
applicationName: 'fastbee', // 固定值
triggers: [],
actions: [],
};
uni.setStorageSync('sceneData', sceneData);
uni.removeStorageSync('callback');
uni.navigateTo({
url: '/pagesA/scene/detail?sceneId=' + id
});
},
// 获取条件
2025-03-27 14:23:27 +08:00
getCondName(cond) {
2024-12-09 14:16:57 +08:00
if (cond === 1) {
return this.$tt('scene.anyCondition')
} else if (cond === 2) {
return this.$tt('scene.allCondition')
} else if (cond === 3) {
return this.$tt('scene.notConditions')
} else {
return this.$tt('scene.unknown')
}
},
2025-03-27 14:23:27 +08:00
getExecuteModeName(mode) {
2024-12-09 14:16:57 +08:00
if (mode === 1) {
return this.$tt('scene.serial')
} else if (mode === 2) {
return this.$tt('scene.parallel')
} else {
return this.$tt('scene.unknown')
}
},
// 获取场景列表
2025-03-27 14:23:27 +08:00
getList() {
2024-12-09 14:16:57 +08:00
listScene(this.queryParams)
.then(res => {
const {
rows,
total
} = res;
this.list = this.list.concat(rows);
this.total = total;
console.log(rows, '场景联动列表');
})
.catch(err => {
console.log(err);
});
},
// 搜索
2025-03-27 14:23:27 +08:00
handleSearch() {
2024-12-09 14:16:57 +08:00
this.list = [];
this.queryParams.pageNum = 1;
this.getList();
},
2025-03-27 14:23:27 +08:00
handleClearSearch() {
2024-12-09 14:16:57 +08:00
this.handleSearch();
},
// 下拉刷新
2025-03-27 14:23:27 +08:00
onPullDownRefresh() {
2024-12-09 14:16:57 +08:00
console.log('下拉刷新');
this.list = [];
this.total = 0;
this.queryParams.pageNum = 1;
// 模拟网络请求
setTimeout(x => {
this.getList();
uni.stopPullDownRefresh();
}, 1000);
},
// 上拉加载
2025-03-27 14:23:27 +08:00
onReachBottom() {
2024-12-09 14:16:57 +08:00
console.log('上拉加载');
this.loadmoreStatus = 'loading';
this.queryParams.pageNum = ++this.queryParams.pageNum;
// 模拟网络请求
setTimeout(() => {
if ((this.queryParams.pageNum - 1) * this.queryParams.pageSize >= this.total) {
this.loadmoreStatus = 'nomore';
} else {
this.loadmoreStatus = 'loading';
this.getList();
}
}, 1000);
},
//执行一次
2025-03-27 14:23:27 +08:00
handleRunOnce(data) {
2024-12-09 14:16:57 +08:00
const params = {
sceneId: data.sceneId
};
runScene(params).then((res) => {
uni.showToast({
icon: 'none',
title: res.msg
});
});
},
// 切换状态
2025-03-27 14:23:27 +08:00
handleSwitchStatus(data) {
2024-12-09 14:16:57 +08:00
const params = {
sceneId: data.sceneId,
enable: data.enable,
}
updateStatus(params).then((res) => {
if (res.code === 200) {
uni.showToast({
icon: 'none',
title: this.$tt('scene.switchSuccessful')
});
} else {
uni.showToast({
icon: 'none',
title: this.$tt('scene.switchFail')
});
}
});
},
}
};
</script>
<style>
page {
height: 100%;
background: #eef3f7;
}
</style>
<style lang="scss" scoped>
.scene-wrap {
.nav-bar {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 26rpx 26rpx 0;
height: 74rpx;
.left-wrap {
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
}
}
.tab-wrap {
padding: 14rpx 12rpx 0 12rpx;
.add-btn {
padding: 0 20rpx;
}
}
.container-wrap {
margin-top: 12rpx;
padding-bottom: 120rpx;
.item-wrap {
.card {
position: relative;
box-shadow: 0 2rpx 0rpx 0 rgba(0, 0, 0, 0.1);
border-radius: 20rpx;
padding: 30rpx;
background-color: #fff;
.title {
padding: 10rpx 0;
display: flex;
flex-direction: row;
}
.cond {
font-size: 12px;
color: #7e7e7e;
margin-top: 10rpx;
}
.bottom-wrap {
display: flex;
flex-direction: row;
padding: 20rpx 0 10rpx;
}
.delIcon {
position: absolute;
top: -10rpx;
right: -10rpx;
cursor: pointer;
}
}
}
}
.other {
.menu-popup-wrap {
.group-wrap {
background-color: #fff;
border-radius: 10rpx;
.cell-wrap {
padding: 6rpx 0;
&:not(:last-child) {
border-bottom: 1rpx solid #F1F2F5;
}
}
}
}
// 小程序中popup坑
2025-03-27 14:23:27 +08:00
::v-deep .u-safe-bottom {
2024-12-09 14:16:57 +08:00
display: none;
}
}
}
</style>