|
@@ -45,7 +45,19 @@
|
|
|
<view v-show="detailTab === 0">
|
|
<view v-show="detailTab === 0">
|
|
|
<!-- 控制按钮 -->
|
|
<!-- 控制按钮 -->
|
|
|
<view class="flcard control-card" v-if="TabCur == 'gate'">
|
|
<view class="flcard control-card" v-if="TabCur == 'gate'">
|
|
|
- <view class="btn-row">
|
|
|
|
|
|
|
+ <view class="btn-row" v-if="ndoorcount == 1">
|
|
|
|
|
+ <view
|
|
|
|
|
+ class="ctrl-btn"
|
|
|
|
|
+ @click="showPasswordDialog('frontGateOpen_S')"
|
|
|
|
|
+ >打开风门</view
|
|
|
|
|
+ >
|
|
|
|
|
+ <view
|
|
|
|
|
+ class="ctrl-btn"
|
|
|
|
|
+ @click="showPasswordDialog('frontGateClose_S')"
|
|
|
|
|
+ >关闭风门</view
|
|
|
|
|
+ >
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="btn-row" v-else-if="ndoorcount == 2">
|
|
|
<view
|
|
<view
|
|
|
class="ctrl-btn"
|
|
class="ctrl-btn"
|
|
|
@click="showPasswordDialog('frontGateOpen_S')"
|
|
@click="showPasswordDialog('frontGateOpen_S')"
|
|
@@ -67,16 +79,16 @@
|
|
|
>关闭后门</view
|
|
>关闭后门</view
|
|
|
>
|
|
>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="btn-row btn-row-second">
|
|
|
|
|
|
|
+ <view class="btn-row btn-row-second" v-if="ndoorcount == 2">
|
|
|
<view
|
|
<view
|
|
|
class="ctrl-btn ctrl-btn-wide"
|
|
class="ctrl-btn ctrl-btn-wide"
|
|
|
- @click="showPasswordDialog('sameTimeOpen')"
|
|
|
|
|
- >打开前后门</view
|
|
|
|
|
|
|
+ @click="showPasswordDialog('sameTimeClose')"
|
|
|
|
|
+ >全部关闭</view
|
|
|
>
|
|
>
|
|
|
<view
|
|
<view
|
|
|
class="ctrl-btn ctrl-btn-wide"
|
|
class="ctrl-btn ctrl-btn-wide"
|
|
|
- @click="showPasswordDialog('sameTimeClose')"
|
|
|
|
|
- >关闭前后门</view
|
|
|
|
|
|
|
+ @click="showPasswordDialog('sameTimeOpen')"
|
|
|
|
|
+ >全部打开</view
|
|
|
>
|
|
>
|
|
|
<view class="mode-group">
|
|
<view class="mode-group">
|
|
|
<text class="mode-label">控制模式:</text>
|
|
<text class="mode-label">控制模式:</text>
|
|
@@ -128,14 +140,25 @@
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
<view class="flcard deviceback" v-if="TabCur == 'gate'">
|
|
<view class="flcard deviceback" v-if="TabCur == 'gate'">
|
|
|
- <doorAnimate
|
|
|
|
|
|
|
+ <!-- 一道和两道自动风门分别使用对应的 SVG 动画 -->
|
|
|
|
|
+ <autodoorDandao
|
|
|
|
|
+ v-if="ndoorcount == 1"
|
|
|
|
|
+ :main-open="isGateOpen(frontGateStatus)"
|
|
|
|
|
+ ></autodoorDandao>
|
|
|
|
|
+ <autodoorShuangdao
|
|
|
|
|
+ v-else-if="ndoorcount == 2"
|
|
|
|
|
+ :front-open="isGateOpen(frontGateStatus)"
|
|
|
|
|
+ :rear-open="isGateOpen(rearGateStatus)"
|
|
|
|
|
+ ></autodoorShuangdao>
|
|
|
|
|
+ <!-- <doorAnimate
|
|
|
|
|
+ v-else
|
|
|
:gatestate1="frontGateStatus"
|
|
:gatestate1="frontGateStatus"
|
|
|
:gatestate2="midGateStatus"
|
|
:gatestate2="midGateStatus"
|
|
|
:gatestate3="rearGateStatus"
|
|
:gatestate3="rearGateStatus"
|
|
|
:height="height"
|
|
:height="height"
|
|
|
:doorcount="ndoorcount"
|
|
:doorcount="ndoorcount"
|
|
|
>
|
|
>
|
|
|
- </doorAnimate>
|
|
|
|
|
|
|
+ </doorAnimate> -->
|
|
|
</view>
|
|
</view>
|
|
|
<view class="flcard deviceback" v-if="isWindrect">
|
|
<view class="flcard deviceback" v-if="isWindrect">
|
|
|
<windrectAnimate
|
|
<windrectAnimate
|
|
@@ -342,47 +365,65 @@
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
- <u-popup :show="show" mode="bottom" :safeAreaInsetBottom="false">
|
|
|
|
|
- <div class="containers">
|
|
|
|
|
- <view class="passWordName">
|
|
|
|
|
|
|
+ <u-popup
|
|
|
|
|
+ :show="show"
|
|
|
|
|
+ mode="center"
|
|
|
|
|
+ :round="16"
|
|
|
|
|
+ :closeOnClickOverlay="true"
|
|
|
|
|
+ @close="cancelPassword"
|
|
|
|
|
+ >
|
|
|
|
|
+ <view class="password-modal">
|
|
|
|
|
+ <view class="password-modal-header">
|
|
|
|
|
+ <text class="password-modal-title">{{
|
|
|
|
|
+ TabCur == "window" ? "风窗面积设置" : "设备控制验证"
|
|
|
|
|
+ }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="password-modal-divider"></view>
|
|
|
|
|
+ <view class="password-modal-body">
|
|
|
|
|
+ <view class="password-field" v-if="TabCur == 'window'">
|
|
|
|
|
+ <text class="password-field-label">风窗面积</text>
|
|
|
|
|
+ <u-input
|
|
|
|
|
+ class="password-input"
|
|
|
|
|
+ v-model="windowArea"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ border="surround"
|
|
|
|
|
+ placeholder="请输入风窗面积"
|
|
|
|
|
+ :customStyle="{
|
|
|
|
|
+ backgroundColor: '#ffffff',
|
|
|
|
|
+ borderRadius: '12rpx',
|
|
|
|
|
+ }"
|
|
|
|
|
+ ></u-input>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="password-field">
|
|
|
|
|
+ <text class="password-field-label">操作密码</text>
|
|
|
|
|
+ <u-input
|
|
|
|
|
+ class="password-input"
|
|
|
|
|
+ v-model="password"
|
|
|
|
|
+ type="password"
|
|
|
|
|
+ border="surround"
|
|
|
|
|
+ placeholder="请输入操作密码"
|
|
|
|
|
+ confirmType="done"
|
|
|
|
|
+ :customStyle="{
|
|
|
|
|
+ backgroundColor: '#ffffff',
|
|
|
|
|
+ borderRadius: '12rpx',
|
|
|
|
|
+ }"
|
|
|
|
|
+ ></u-input>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="password-modal-footer">
|
|
|
<view
|
|
<view
|
|
|
- class="title"
|
|
|
|
|
- style="margin-top: 15px"
|
|
|
|
|
- v-if="this.TabCur == 'window'"
|
|
|
|
|
- >风窗面积</view
|
|
|
|
|
|
|
+ class="password-modal-btn password-modal-btn-plain"
|
|
|
|
|
+ @tap="cancelPassword"
|
|
|
>
|
|
>
|
|
|
- <u-input
|
|
|
|
|
- class="passArea"
|
|
|
|
|
- style="margin-top: 15px; border-color: #2a94ff"
|
|
|
|
|
- v-model="windowArea"
|
|
|
|
|
- type="text"
|
|
|
|
|
- v-if="this.TabCur == 'window'"
|
|
|
|
|
- ></u-input>
|
|
|
|
|
- </view>
|
|
|
|
|
- <view class="passWordInput">
|
|
|
|
|
- <view style="margin-top: 15px" class="title">输入密码</view>
|
|
|
|
|
- <u-input
|
|
|
|
|
- style="margin-top: 15px; border-color: #2a94ff"
|
|
|
|
|
- v-model="password"
|
|
|
|
|
- type="password"
|
|
|
|
|
- ></u-input>
|
|
|
|
|
|
|
+ <text>取消</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view
|
|
|
|
|
+ class="password-modal-btn password-modal-btn-primary"
|
|
|
|
|
+ @tap="confirmPassword"
|
|
|
|
|
+ >
|
|
|
|
|
+ <text>确认</text>
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
- </div>
|
|
|
|
|
- <view class="btns">
|
|
|
|
|
- <u-button
|
|
|
|
|
- style="margin: 20px"
|
|
|
|
|
- type="primary"
|
|
|
|
|
- @click="confirmPassword()"
|
|
|
|
|
- color="linear-gradient(to right, rgb(53, 138, 254), rgb(38, 171, 244))"
|
|
|
|
|
- >确认</u-button
|
|
|
|
|
- >
|
|
|
|
|
- <u-button
|
|
|
|
|
- style="margin: 20px"
|
|
|
|
|
- type="primary"
|
|
|
|
|
- :plain="true"
|
|
|
|
|
- @click="cancelPassword()"
|
|
|
|
|
- >取消</u-button
|
|
|
|
|
- >
|
|
|
|
|
</view>
|
|
</view>
|
|
|
</u-popup>
|
|
</u-popup>
|
|
|
</view>
|
|
</view>
|
|
@@ -392,6 +433,8 @@
|
|
|
import api from "@/api/api";
|
|
import api from "@/api/api";
|
|
|
import initDictOptions from "@/common/util/dictUtil.js";
|
|
import initDictOptions from "@/common/util/dictUtil.js";
|
|
|
import doorAnimate from "../doorAnimate/doorAnimate.vue";
|
|
import doorAnimate from "../doorAnimate/doorAnimate.vue";
|
|
|
|
|
+import autodoorDandao from "../doorAnimate/autodoor-dandao.vue";
|
|
|
|
|
+import autodoorShuangdao from "../doorAnimate/autodoor-shuangdao.vue";
|
|
|
import windowAnimate from "../windowAnimate/windowAnimate.vue";
|
|
import windowAnimate from "../windowAnimate/windowAnimate.vue";
|
|
|
import windrectAnimate from "../windrectAnimate/windrectAnimate.vue";
|
|
import windrectAnimate from "../windrectAnimate/windrectAnimate.vue";
|
|
|
import fanlocalAnimate from "../fanlocalAnimate/fanlocalAnimate2.vue";
|
|
import fanlocalAnimate from "../fanlocalAnimate/fanlocalAnimate2.vue";
|
|
@@ -456,6 +499,7 @@ export default {
|
|
|
detailTab: 0, // 0实时 1历史 2操作记录
|
|
detailTab: 0, // 0实时 1历史 2操作记录
|
|
|
controlMode: "local", // 控制模式展示:就地/远程
|
|
controlMode: "local", // 控制模式展示:就地/远程
|
|
|
deviceTypeHis: "", //历史数据设备类型
|
|
deviceTypeHis: "", //历史数据设备类型
|
|
|
|
|
+ controlTimers: [], //控制成功后的补充刷新定时器
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
onLoad(query) {
|
|
onLoad(query) {
|
|
@@ -481,6 +525,8 @@ export default {
|
|
|
},
|
|
},
|
|
|
components: {
|
|
components: {
|
|
|
doorAnimate,
|
|
doorAnimate,
|
|
|
|
|
+ autodoorDandao,
|
|
|
|
|
+ autodoorShuangdao,
|
|
|
windowAnimate,
|
|
windowAnimate,
|
|
|
windrectAnimate,
|
|
windrectAnimate,
|
|
|
fanlocalAnimate,
|
|
fanlocalAnimate,
|
|
@@ -505,6 +551,9 @@ export default {
|
|
|
stopTimer() {
|
|
stopTimer() {
|
|
|
// 停止定时器
|
|
// 停止定时器
|
|
|
clearInterval(this.timer);
|
|
clearInterval(this.timer);
|
|
|
|
|
+ // 清掉控制成功后的补充刷新
|
|
|
|
|
+ (this.controlTimers || []).forEach((timer) => clearTimeout(timer));
|
|
|
|
|
+ this.controlTimers = [];
|
|
|
},
|
|
},
|
|
|
// 返回上一个页面
|
|
// 返回上一个页面
|
|
|
backPage() {
|
|
backPage() {
|
|
@@ -513,6 +562,13 @@ export default {
|
|
|
delta: 1,
|
|
delta: 1,
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
|
|
|
+ // 门状态是否打开(与图片动画的判定保持一致)
|
|
|
|
|
+ isGateOpen(state) {
|
|
|
|
|
+ const val = String(state === undefined || state === null ? "" : state)
|
|
|
|
|
+ .trim()
|
|
|
|
|
+ .toLowerCase();
|
|
|
|
|
+ return val === "1" || val === "开启" || val === "打开" || val === "true";
|
|
|
|
|
+ },
|
|
|
|
|
|
|
|
getShowColum() {
|
|
getShowColum() {
|
|
|
new Promise((resolve, reject) => {
|
|
new Promise((resolve, reject) => {
|
|
@@ -583,24 +639,24 @@ export default {
|
|
|
this.getVideoUrlById(this.cameras);
|
|
this.getVideoUrlById(this.cameras);
|
|
|
this.isFirstRequest = false; // 设置为 false,表示已经请求过数据
|
|
this.isFirstRequest = false; // 设置为 false,表示已经请求过数据
|
|
|
}
|
|
}
|
|
|
- if (this.tableData["frontGateClose"] == "1") {
|
|
|
|
|
- this.tableData.frontGateOpen = "关闭";
|
|
|
|
|
- } else if (this.tableData["frontGateClose"] == "0") {
|
|
|
|
|
|
|
+ if (this.tableData["frontGateOpen"] == "1") {
|
|
|
this.tableData.frontGateOpen = "打开";
|
|
this.tableData.frontGateOpen = "打开";
|
|
|
|
|
+ } else if (this.tableData["frontGateOpen"] == "0") {
|
|
|
|
|
+ this.tableData.frontGateOpen = "关闭";
|
|
|
} else {
|
|
} else {
|
|
|
this.tableData.frontGateOpen = "关闭";
|
|
this.tableData.frontGateOpen = "关闭";
|
|
|
}
|
|
}
|
|
|
- if (this.tableData["midGateClose"] == "1") {
|
|
|
|
|
- this.tableData.midGateOpen = "关闭";
|
|
|
|
|
- } else if (this.tableData["midGateClose"] == "0") {
|
|
|
|
|
|
|
+ if (this.tableData["midGateOpen"] == "1") {
|
|
|
this.tableData.midGateOpen = "打开";
|
|
this.tableData.midGateOpen = "打开";
|
|
|
|
|
+ } else if (this.tableData["midGateOpen"] == "0") {
|
|
|
|
|
+ this.tableData.midGateOpen = "关闭";
|
|
|
} else {
|
|
} else {
|
|
|
this.tableData.midGateOpen = "关闭";
|
|
this.tableData.midGateOpen = "关闭";
|
|
|
}
|
|
}
|
|
|
- if (this.tableData["rearGateClose"] == "1") {
|
|
|
|
|
- this.tableData.rearGateOpen = "关闭";
|
|
|
|
|
- } else if (this.tableData["rearGateClose"] == "0") {
|
|
|
|
|
|
|
+ if (this.tableData["rearGateOpen"] == "1") {
|
|
|
this.tableData.rearGateOpen = "打开";
|
|
this.tableData.rearGateOpen = "打开";
|
|
|
|
|
+ } else if (this.tableData["rearGateOpen"] == "0") {
|
|
|
|
|
+ this.tableData.rearGateOpen = "关闭";
|
|
|
} else {
|
|
} else {
|
|
|
this.tableData.rearGateOpen = "关闭";
|
|
this.tableData.rearGateOpen = "关闭";
|
|
|
}
|
|
}
|
|
@@ -709,8 +765,8 @@ export default {
|
|
|
.controlDevice(params)
|
|
.controlDevice(params)
|
|
|
.then((response) => {
|
|
.then((response) => {
|
|
|
if (response.data.code == 200) {
|
|
if (response.data.code == 200) {
|
|
|
- this.getDeviceInfo(IDString);
|
|
|
|
|
- // console.log("操作成功");
|
|
|
|
|
|
|
+ // 控制成功后按设备最新状态刷新,SVG 动画会跟随新状态播放开/关过程
|
|
|
|
|
+ this.refreshAfterControl(IDString);
|
|
|
} else {
|
|
} else {
|
|
|
resolve(response);
|
|
resolve(response);
|
|
|
}
|
|
}
|
|
@@ -720,9 +776,20 @@ export default {
|
|
|
});
|
|
});
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
|
|
|
+ // 控制成功后设备状态通常有延迟,立即刷新并补几次,让动画尽快跟上真实状态
|
|
|
|
|
+ refreshAfterControl(IDString) {
|
|
|
|
|
+ this.getDeviceInfo(IDString);
|
|
|
|
|
+ [800, 1800, 3200].forEach((delay) => {
|
|
|
|
|
+ const timer = setTimeout(() => {
|
|
|
|
|
+ this.getDeviceInfo(IDString);
|
|
|
|
|
+ }, delay);
|
|
|
|
|
+ this.controlTimers.push(timer);
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
// 显示密码输入弹窗
|
|
// 显示密码输入弹窗
|
|
|
showPasswordDialog(controlCode) {
|
|
showPasswordDialog(controlCode) {
|
|
|
this.paramcode = controlCode;
|
|
this.paramcode = controlCode;
|
|
|
|
|
+ this.password = "";
|
|
|
this.show = true;
|
|
this.show = true;
|
|
|
},
|
|
},
|
|
|
// 取消密码输入
|
|
// 取消密码输入
|
|
@@ -1309,34 +1376,90 @@ div.window_new_5 {
|
|
|
transform-origin: center center;
|
|
transform-origin: center center;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.btns {
|
|
|
|
|
|
|
+.password-modal {
|
|
|
|
|
+ width: 620rpx;
|
|
|
|
|
+ max-width: calc(100vw - 64rpx);
|
|
|
|
|
+ padding-bottom: 28rpx;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ border: 1rpx solid #ffffff;
|
|
|
|
|
+ border-radius: 16rpx;
|
|
|
|
|
+ background: #f9f9fb;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.password-modal-header {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ padding: 28rpx 28rpx 20rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.password-modal-title {
|
|
|
|
|
+ color: #1a1a1a;
|
|
|
|
|
+ font-size: 32rpx;
|
|
|
|
|
+ font-weight: 700;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.containers {
|
|
|
|
|
- background-color: #fff;
|
|
|
|
|
|
|
+.password-modal-divider {
|
|
|
|
|
+ height: 1rpx;
|
|
|
|
|
+ margin: 0 24rpx;
|
|
|
|
|
+ background: #eef0f4;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.passWordName {
|
|
|
|
|
- margin: 20px;
|
|
|
|
|
|
|
+.password-modal-body {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
- flex-direction: row;
|
|
|
|
|
- justify-content: space-around;
|
|
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 20rpx;
|
|
|
|
|
+ padding: 24rpx 28rpx 28rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.password-field {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 10rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.password-field-label {
|
|
|
|
|
+ color: #5b6270;
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.password-input {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.title {
|
|
|
|
|
- margin-right: 20px;
|
|
|
|
|
- line-height: 40px;
|
|
|
|
|
|
|
+::v-deep .password-input.u-border::after {
|
|
|
|
|
+ border-color: #d8e2f5;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.passWordInput {
|
|
|
|
|
- margin: 20px;
|
|
|
|
|
|
|
+.password-modal-footer {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
- flex-direction: row;
|
|
|
|
|
- justify-content: space-around;
|
|
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 20rpx;
|
|
|
|
|
+ padding: 0 28rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.password-modal-btn {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ height: 64rpx;
|
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
+ border-radius: 8rpx;
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ font-weight: 500;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.passArea {
|
|
|
|
|
- border-color: red;
|
|
|
|
|
|
|
+.password-modal-btn-plain {
|
|
|
|
|
+ color: #0065f8;
|
|
|
|
|
+ border: 1rpx solid #0065f8;
|
|
|
|
|
+ background: #ffffff;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.password-modal-btn-primary {
|
|
|
|
|
+ color: #ffffff;
|
|
|
|
|
+ background: #0065f8;
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|