Commit 8d120fed1ff05c36bee89e2b473965b0f6378da9

Authored by xp.Huang
2 parents 5844ab50 1e724058

Merge branch 'ft_local_dev' into 'main'

pref:主要是优化了一些代码

See merge request huang/thingskit-app!92
1 <script> 1 <script>
2 -import base from '@/config/baseUrl';  
3 import store from '@/store'; 2 import store from '@/store';
4 -  
5 import { mpUpData, scene } from '@/config/common'; 3 import { mpUpData, scene } from '@/config/common';
  4 +
6 export default { 5 export default {
7 //设置全局变量,解绑时从这里取 6 //设置全局变量,解绑时从这里取
8 globalData: { 7 globalData: {
@@ -20,7 +19,6 @@ export default { @@ -20,7 +19,6 @@ export default {
20 // #endif 19 // #endif
21 }, 20 },
22 onHide() { 21 onHide() {
23 - console.log('App Hide');  
24 } 22 }
25 }; 23 };
26 </script> 24 </script>
@@ -32,7 +32,7 @@ @@ -32,7 +32,7 @@
32 <view class="column"> 32 <view class="column">
33 <text class="text-org-bold">告警值:</text> 33 <text class="text-org-bold">告警值:</text>
34 <text 34 <text
35 - class="text-device-muted">{{ list.details == null ? '暂无数据' : formatDetailText(list.details.data) }}</text> 35 + class="text-device-muted text-clip">{{ list.details == null ? '暂无数据' : formatDetailText(list.details.data) }}</text>
36 </view> 36 </view>
37 <view class="column"> 37 <view class="column">
38 <text class="text-org-bold">告警时间:</text> 38 <text class="text-org-bold">告警时间:</text>
@@ -15,7 +15,8 @@ @@ -15,7 +15,8 @@
15 align-items: center; 15 align-items: center;
16 .column { 16 .column {
17 flex-direction: row; 17 flex-direction: row;
18 - justify-content: space-between; 18 + display:flex;
  19 + // justify-content: space-between;
19 margin-top: 10rpx; 20 margin-top: 10rpx;
20 line-height: 68rpx; 21 line-height: 68rpx;
21 width: 614rpx; 22 width: 614rpx;
1 import { 1 import {
2 getTabbarHeight 2 getTabbarHeight
3 -} from '@/plugins/utils';  
4 -let baseUrl = "https://dev.thingskit.com/api";  
5 -// let baseUrl = "http://192.168.10.136:8080/api";  
6 -let baseDrawioUrl = "https://dev.thingskit.com/thingskit-scada" 3 +} from "@/plugins/utils";
  4 +/**
  5 + * 服务端配置项
  6 + * baseUrl 服务端 api地址
  7 + * baseDrawioUrl 组态地址 注意端口
  8 + * baseWebSocketUrl 服务端 websocket地址
  9 + * socketPrefix websocket前缀 ((https, wss),( http, ws))
  10 + */
  11 +
  12 +// const baseUrl = "http://47.108.221.67:8080/api";
  13 +// const baseDrawioUrl = "http://47.108.221.67:9527/thingskit-scada";
  14 +// const baseWebSocketUrl = "47.108.221.67:8080";
  15 +// const socketPrefix = "ws";
  16 +
  17 +const baseUrl = "http://222.180.200.114:48080/api";
  18 +const baseDrawioUrl = "http://222.180.200.114:48080/thingskit-scada";
  19 +const baseWebSocketUrl = "222.180.200.114:48080";
  20 +const socketPrefix = "ws";
7 21
8 let systemInfo = { 22 let systemInfo = {
9 ...getTabbarHeight(), 23 ...getTabbarHeight(),
10 // #ifdef MP-ALIPAY 24 // #ifdef MP-ALIPAY
11 - navBarH: uni.getSystemInfoSync().statusBarHeight + uni.getSystemInfoSync().titleBarHeight, //菜单栏总高度--单位px 25 + navBarH: uni.getSystemInfoSync().statusBarHeight +
  26 + uni.getSystemInfoSync().titleBarHeight, //菜单栏总高度--单位px
12 titleBarHeight: uni.getSystemInfoSync().titleBarHeight, //标题栏高度--单位px 27 titleBarHeight: uni.getSystemInfoSync().titleBarHeight, //标题栏高度--单位px
13 // #endif 28 // #endif
14 // #ifndef MP-ALIPAY 29 // #ifndef MP-ALIPAY
@@ -18,32 +33,27 @@ let systemInfo = { @@ -18,32 +33,27 @@ let systemInfo = {
18 }; 33 };
19 // 平台 34 // 平台
20 // #ifdef MP-WEIXIN 35 // #ifdef MP-WEIXIN
21 -systemInfo.platform = 'weixin' 36 +systemInfo.platform = "weixin";
22 // #endif 37 // #endif
23 // #ifdef MP-ALIPAY 38 // #ifdef MP-ALIPAY
24 -systemInfo.platform = 'alipay' 39 +systemInfo.platform = "alipay";
25 // #endif 40 // #endif
26 // #ifdef MP-TOUTIAO 41 // #ifdef MP-TOUTIAO
27 -systemInfo.platform = 'toutiao' 42 +systemInfo.platform = "toutiao";
28 // #endif 43 // #endif
29 // #ifdef APP-PLUS 44 // #ifdef APP-PLUS
30 -systemInfo.platform = 'plus' 45 +systemInfo.platform = "plus";
31 // #endif 46 // #endif
32 -console.log(systemInfo, 'systemInfo')  
33 const courtConfig = { 47 const courtConfig = {
34 - publicAppId: '', //公众号appId  
35 - baseUrl, //域名  
36 - baseDrawioUrl, 48 + publicAppId: "", //公众号appId
  49 + baseUrl, //服务端地址
  50 + baseDrawioUrl, //服务端组态地址
  51 + baseWebSocketUrl, //服务端websocket地址
  52 + socketPrefix, //websocket前缀
37 systemInfo: systemInfo, //系统信息 53 systemInfo: systemInfo, //系统信息
38 mapData: { 54 mapData: {
39 - key: '', //地图key  
40 - sk: '', 55 + key: "", //地图key
  56 + sk: "",
41 }, 57 },
42 - share: {  
43 - title: '基于uview2.0快速开发框架', //分享标题  
44 - desc: "基于uview2.0快速开发框架详情", //分享详情  
45 - link: "", // 分享链接  
46 - imgUrl: "", // 分享图  
47 - }  
48 }; 58 };
49 export default Object.assign({}, courtConfig); 59 export default Object.assign({}, courtConfig);
1 import base from "@/config/baseUrl"; 1 import base from "@/config/baseUrl";
2 import store from "@/store"; 2 import store from "@/store";
3 -import {  
4 - judgeLogin  
5 -} from "@/config/login"; 3 +import { judgeLogin } from "@/config/login";
6 4
7 // 初始化请求配置 5 // 初始化请求配置
8 uni.$u.http.setConfig((config) => { 6 uni.$u.http.setConfig((config) => {
9 - const token =  
10 - store.state.userInfo.isToken ||  
11 - uni.getStorageSync("userInfo").isToken ||  
12 - undefined;  
13 - // #ifdef H5  
14 - window.sessionStorage.getItem("userInfo").isToken;  
15 - // #endif  
16 - /* config 为默认全局配置*/  
17 - // const getConfiguration = uni.getStorageSync('getConfiguration').isConfiguration  
18 - // console.log('getConfiguration', getConfiguration);  
19 - // config.baseURL = getConfiguration == true ? base.baseDrawioUrl : base.baseUrl /* 根域名 */  
20 - config.baseURL = base.baseUrl /* 根域名 */  
21 - config.header = {  
22 - "Content-Type": "application/json",  
23 - 'X-Authorization': "Bearer " + token,  
24 - };  
25 - config.custom = {  
26 - load: true, //是否显示加载动画  
27 - isFactory: true, //true:返回的数据成功只返回data false:返回response  
28 - catch: true, //默认数据返回不成功进入catch返回  
29 - auth: true, //token  
30 - };  
31 - return config; 7 + const token =
  8 + store.state.userInfo.isToken ||
  9 + uni.getStorageSync("userInfo").isToken ||
  10 + undefined;
  11 + // #ifdef H5
  12 + window.sessionStorage.getItem("userInfo").isToken;
  13 + // #endif
  14 + /* config 为默认全局配置*/
  15 + // const getConfiguration = uni.getStorageSync('getConfiguration').isConfiguration
  16 + // console.log('getConfiguration', getConfiguration);
  17 + // config.baseURL = getConfiguration == true ? base.baseDrawioUrl : base.baseUrl /* 根域名 */
  18 + config.baseURL = base.baseUrl; /* 根域名 */
  19 + config.header = {
  20 + "Content-Type": "application/json",
  21 + "X-Authorization": "Bearer " + token,
  22 + };
  23 + config.custom = {
  24 + load: true, //是否显示加载动画
  25 + isFactory: true, //true:返回的数据成功只返回data false:返回response
  26 + catch: true, //默认数据返回不成功进入catch返回
  27 + auth: true, //token
  28 + };
  29 + return config;
32 }); 30 });
33 31
34 // 请求拦截 32 // 请求拦截
35 uni.$u.http.interceptors.request.use( 33 uni.$u.http.interceptors.request.use(
36 - (config) => {  
37 - if (store.state.userInfo.isThirdLogin) {  
38 - uni.switchTab({  
39 - url: "../pages/personal/personal",  
40 - });  
41 - }  
42 - // 初始化请求拦截器时,会执行此方法,此时data为undefined,赋予默认{}  
43 - config.data = config.data || {};  
44 - // 根据custom参数中配置的是否需要token,添加对应的请求头  
45 - const getConfiguration = uni.getStorageSync('getConfiguration').isConfiguration  
46 - if (config?.custom?.auth) {  
47 - config.header['X-Authorization'] =  
48 - "Bearer " + store.state.userInfo.isToken ||  
49 - uni.getStorageSync("userInfo").isToken ||  
50 - undefined;  
51 - config.baseURL = getConfiguration == true ? base.baseDrawioUrl : base.baseUrl  
52 - }  
53 - if (config?.custom?.load) {  
54 - //打开加载动画  
55 - store.commit("setLoadingShow", true);  
56 - }  
57 - if (getConfiguration) {  
58 - uni.setStorageSync('config', config)  
59 - } else {  
60 - uni.removeStorageSync('config')  
61 - }  
62 - return config;  
63 - },  
64 - (config) => {  
65 - return Promise.reject(config);  
66 - } 34 + (config) => {
  35 + if (store.state.userInfo.isThirdLogin) {
  36 + uni.switchTab({
  37 + url: "../pages/personal/personal",
  38 + });
  39 + }
  40 + // 初始化请求拦截器时,会执行此方法,此时data为undefined,赋予默认{}
  41 + config.data = config.data || {};
  42 + // 根据custom参数中配置的是否需要token,添加对应的请求头
  43 + const getConfiguration =
  44 + uni.getStorageSync("getConfiguration").isConfiguration;
  45 + if (config?.custom?.auth) {
  46 + config.header["X-Authorization"] =
  47 + "Bearer " + store.state.userInfo.isToken ||
  48 + uni.getStorageSync("userInfo").isToken ||
  49 + undefined;
  50 + config.baseURL =
  51 + getConfiguration == true ? base.baseDrawioUrl : base.baseUrl;
  52 + }
  53 + if (config?.custom?.load) {
  54 + //打开加载动画
  55 + store.commit("setLoadingShow", true);
  56 + }
  57 + if (getConfiguration) {
  58 + uni.setStorageSync("config", config);
  59 + } else {
  60 + uni.removeStorageSync("config");
  61 + }
  62 + return config;
  63 + },
  64 + (config) => {
  65 + return Promise.reject(config);
  66 + }
67 ); 67 );
68 68
69 // 响应拦截 69 // 响应拦截
70 uni.$u.http.interceptors.response.use( 70 uni.$u.http.interceptors.response.use(
71 - (response) => {  
72 - // 关闭加载动画  
73 - store.commit("setLoadingShow", false);  
74 - const data = response.data;  
75 - const custom = response.config?.custom;  
76 - // code: 200、请求成功 其他,没有更多参数 401、被迫下线重新登录、  
77 - if (response.statusCode == 200) {  
78 - return Promise.resolve(data);  
79 - } else if (response.statusCode == 401) {  
80 - // 清空登录信息  
81 - store.commit("emptyUserInfo");  
82 - // 20秒节流,弹窗登录  
83 - uni.$u.throttle(judgeLogin(), 20000);  
84 - return new Promise(() => {});  
85 - } else {}  
86 - },  
87 - (response) => {  
88 - // 关闭加载动画  
89 - store.commit("setLoadingShow", false);  
90 - let show = true;  
91 - let errorData = '请检查网络或服务器'  
92 - let message = response.data?.message || response.data?.msg || response?.errMsg  
93 - if (message == "request:fail url not in domain list") {  
94 - errorData = "检查请求域名是否添加了域名白名单";  
95 - } else if (message == "request:fail timeout") {  
96 - errorData = "请求超时:请检查网络";  
97 - } else if (response.data.status == 401) {  
98 - const isLoginFlag = uni.getStorageSync("userInfo")  
99 - if (!store.state.userInfo.isThirdLogin) {  
100 - const routers = getCurrentPages()  
101 - const currentRoute = routers[routers.length - 1].route  
102 - const isLoginPage = currentRoute.includes('publicLoginSubPage/public/login')  
103 - !isLoginPage && uni.reLaunch({  
104 - url: "/publicLoginSubPage/public/login",  
105 - });  
106 - // 清空登录信息  
107 - store.commit("emptyUserInfo");  
108 - show = false;  
109 - } else {  
110 - uni.switchTab({  
111 - url: "../pages/personal/personal",  
112 - });  
113 - show = false;  
114 - }  
115 -  
116 - } else {  
117 - errorData = message || "";  
118 - }  
119 - if (show) uni.$u.toast(errorData);  
120 - return Promise.reject(response);  
121 - }  
122 -); 71 + (response) => {
  72 + // 关闭加载动画
  73 + store.commit("setLoadingShow", false);
  74 + const data = response.data;
  75 + const custom = response.config?.custom;
  76 + // code: 200、请求成功 其他,没有更多参数 401、被迫下线重新登录、
  77 + if (response.statusCode == 200) {
  78 + return Promise.resolve(data);
  79 + } else if (response.statusCode == 401) {
  80 + // 清空登录信息
  81 + store.commit("emptyUserInfo");
  82 + // 20秒节流,弹窗登录
  83 + uni.$u.throttle(judgeLogin(), 20000);
  84 + return new Promise(() => {});
  85 + } else {
  86 + }
  87 + },
  88 + (response) => {
  89 + // 关闭加载动画
  90 + store.commit("setLoadingShow", false);
  91 + let show = true;
  92 + let errorData = "请检查网络或服务器";
  93 + let message =
  94 + response.data?.message || response.data?.msg || response?.errMsg;
  95 + if (message == "request:fail url not in domain list") {
  96 + errorData = "检查请求域名是否添加了域名白名单";
  97 + } else if (message == "request:fail timeout") {
  98 + errorData = "请求超时:请检查网络";
  99 + } else if (response.data.status == 401) {
  100 + const isLoginFlag = uni.getStorageSync("userInfo");
  101 + if (!store.state.userInfo.isThirdLogin) {
  102 + const routers = getCurrentPages();
  103 + const currentRoute = routers[routers.length - 1].route;
  104 + const isLoginPage = currentRoute.includes(
  105 + "publicLoginSubPage/public/login"
  106 + );
  107 + !isLoginPage &&
  108 + uni.reLaunch({
  109 + url: "/publicLoginSubPage/public/login",
  110 + });
  111 + // 清空登录信息
  112 + store.commit("emptyUserInfo");
  113 + show = false;
  114 + } else {
  115 + uni.switchTab({
  116 + url: "../pages/personal/personal",
  117 + });
  118 + show = false;
  119 + }
  120 + } else if (message == "request:ok") {
  121 + show = false;
  122 + errorData = "";
  123 + } else {
  124 + errorData = message || "";
  125 + }
  126 + if (show) uni.$u.toast(errorData);
  127 + return Promise.reject(response);
  128 + }
  129 +);
1 <template> 1 <template>
2 - <view class="device-detail-page">  
3 - <!-- 公共组件-每个页面必须引入 -->  
4 - <public-module></public-module>  
5 - <u-sticky bgColor="#fff">  
6 - <u-tabs  
7 - :list="list"  
8 - :current="currentTab"  
9 - @click="handleTabClick"  
10 - :activeStyle="{  
11 - fontWeight: 'bold',  
12 - color: '#333'  
13 - }"  
14 - :inactiveStyle="{  
15 - color: '#999'  
16 - }"  
17 - :scrollable="isScrollable"  
18 - />  
19 - </u-sticky>  
20 - <view style="margin-top:30rpx;">  
21 - <basicInfo v-show="currentTab == 0" :deviceDetail="deviceDetail" />  
22 - <realTimeData v-show="currentTab === 1" :recordList="recordList" />  
23 - <historyData  
24 - v-if="currentTab === 2"  
25 - :keys="keys"  
26 - :yesterday="yesterday"  
27 - :today="today"  
28 - :timeDiff="timeDiff"  
29 - :historyData="historyData"  
30 - :entityId="entityId"  
31 - :start="startTs"  
32 - :end="endTs"  
33 - @update="handleUpdate"  
34 - />  
35 - <alarmHistory v-show="currentTab === 3" :deviceId="deviceId" />  
36 - <commondRecord v-if="currentTab === 4" :tbDeviceId="entityId" />  
37 - </view>  
38 - </view> 2 + <view class="device-detail-page">
  3 + <!-- 公共组件-每个页面必须引入 -->
  4 + <public-module></public-module>
  5 + <u-sticky bgColor="#fff">
  6 + <u-tabs
  7 + :list="list"
  8 + :current="currentTab"
  9 + @click="handleTabClick"
  10 + :activeStyle="{
  11 + fontWeight: 'bold',
  12 + color: '#333',
  13 + }"
  14 + :inactiveStyle="{
  15 + color: '#999',
  16 + }"
  17 + :scrollable="isScrollable"
  18 + />
  19 + </u-sticky>
  20 + <view style="margin-top: 30rpx">
  21 + <basicInfo v-show="currentTab == 0" :deviceDetail="deviceDetail" />
  22 + <realTimeData v-show="currentTab === 1" :recordList="recordList" />
  23 + <historyData
  24 + v-if="currentTab === 2"
  25 + :keys="keys"
  26 + :yesterday="yesterday"
  27 + :today="today"
  28 + :timeDiff="timeDiff"
  29 + :historyData="historyData"
  30 + :entityId="entityId"
  31 + :start="startTs"
  32 + :end="endTs"
  33 + @update="handleUpdate"
  34 + />
  35 + <alarmHistory v-show="currentTab === 3" :deviceId="deviceId" />
  36 + <commondRecord v-if="currentTab === 4" :tbDeviceId="entityId" />
  37 + </view>
  38 + </view>
39 </template> 39 </template>
40 40
41 <script> 41 <script>
42 -import fTabbar from '@/components/module/f-tabbar/f-tabbar';  
43 -import basicInfo from './tabDetail/basicInfo.vue';  
44 -import realTimeData from './tabDetail/realtimeData.vue';  
45 -import alarmHistory from './tabDetail/alarmHistory.vue';  
46 -import historyData from './tabDetail/historyData.vue';  
47 -import commondRecord from './tabDetail/CommandRecord.vue';  
48 -import { getDeviceKeys, getHistoryData } from './api/index.js';  
49 -import { formatToDate } from '@/plugins/utils.js'; 42 +import fTabbar from "@/components/module/f-tabbar/f-tabbar";
  43 +import basicInfo from "./tabDetail/basicInfo.vue";
  44 +import realTimeData from "./tabDetail/realtimeData.vue";
  45 +import alarmHistory from "./tabDetail/alarmHistory.vue";
  46 +import historyData from "./tabDetail/historyData.vue";
  47 +import commondRecord from "./tabDetail/CommandRecord.vue";
  48 +import { getDeviceKeys, getHistoryData } from "./api/index.js";
  49 +import { formatToDate } from "@/plugins/utils.js";
50 import MescrollCompMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js"; 50 import MescrollCompMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js";
51 -import moment from 'moment';  
52 -export default {  
53 - mixins: [MescrollCompMixin],  
54 - components: {  
55 - fTabbar,  
56 - basicInfo,  
57 - realTimeData,  
58 - alarmHistory,  
59 - historyData,  
60 - commondRecord  
61 - },  
62 - data() {  
63 - return {  
64 - list: [{ name: '基础信息' }, { name: '实时数据' }, { name: '历史数据' }, { name: '告警记录' }],  
65 - currentTab: 0,  
66 - deviceId: '',  
67 - deviceDetail: {},  
68 - keys: [],  
69 - yesterday: '',  
70 - today: '',  
71 - timeDiff: '',  
72 - historyData: [],  
73 - entityId: '',  
74 - startTs: '',  
75 - endTs: '',  
76 - recordList: [],  
77 - isScrollable: false  
78 - };  
79 - },  
80 - onUnload() {  
81 - // 页面关闭时,销毁webSocket连接,否则第二次会存在连接不到的情况  
82 - uni.closeSocket();  
83 - },  
84 - async onLoad(options) {  
85 - const { id, alarmStatus, lastOnlineTime, tbDeviceId } = options;  
86 - this.deviceId = id;  
87 - const res = await uni.$u.http.get(`/yt/device/${id}`);  
88 - this.deviceDetail = { ...res, alarmStatus, lastOnlineTime }; 51 +import moment from "moment";
  52 +import base from "@/config/baseUrl.js";
89 53
90 - // 设备类型不是网关子设备的添加一个命令记录的选项卡  
91 - if (this.deviceDetail.deviceType !== 'SENSOR') {  
92 - this.list.push({  
93 - name: '命令记录'  
94 - });  
95 - }  
96 - this.isScrollable = this.list.length > 4;  
97 - // 连接webSockte  
98 - const socketTask = uni.connectSocket({  
99 - url: 'wss://dev.thingskit.com/api/ws/plugins/telemetry?token=' + uni.getStorageSync('userInfo').isToken, //仅为示例,并非真实接口地址。  
100 - complete: () => {}  
101 - });  
102 - uni.onSocketOpen(header => {  
103 - socketTask.send({  
104 - data: JSON.stringify({  
105 - attrSubCmds: [],  
106 - tsSubCmds: [  
107 - {  
108 - entityType: 'DEVICE',  
109 - entityId: tbDeviceId,  
110 - scope: 'LATEST_TELEMETRY',  
111 - cmdId: 1  
112 - }  
113 - ],  
114 - historyCmds: [],  
115 - entityDataCmds: [],  
116 - entityDataUnsubscribeCmds: [],  
117 - alarmDataCmds: [],  
118 - alarmDataUnsubscribeCmds: [],  
119 - entityCountCmds: [],  
120 - entityCountUnsubscribeCmds: []  
121 - }),  
122 - success() {}  
123 - });  
124 - });  
125 - socketTask.onMessage(msg => {  
126 - const { data } = JSON.parse(msg.data);  
127 - const newArray = [];  
128 - for (const key in data) {  
129 - const [time, value] = data[key].flat(1);  
130 - let obj = { key, time, value };  
131 - if (this.recordList.length === 0) {  
132 - this.recordList.unshift(obj);  
133 - } else {  
134 - newArray.push(obj);  
135 - }  
136 - }  
137 - newArray.forEach(item => {  
138 - let flag = false;  
139 - this.recordList.forEach(item1 => {  
140 - if (item1.key === item.key) {  
141 - item1.value = item.value;  
142 - item1.time = item.time;  
143 - flag = true;  
144 - }  
145 - });  
146 - if (!flag) {  
147 - this.recordList.unshift(item);  
148 - }  
149 - });  
150 - this.recordList = this.recordList.map(item => {  
151 - return {  
152 - ...item,  
153 - time: formatToDate(item.time, 'YYYY-MM-DD HH:mm:ss')  
154 - };  
155 - });  
156 - }); 54 +export default {
  55 + mixins: [MescrollCompMixin],
  56 + components: {
  57 + fTabbar,
  58 + basicInfo,
  59 + realTimeData,
  60 + alarmHistory,
  61 + historyData,
  62 + commondRecord,
  63 + },
  64 + data() {
  65 + return {
  66 + list: [
  67 + {
  68 + name: "基础信息",
  69 + },
  70 + {
  71 + name: "实时数据",
  72 + },
  73 + {
  74 + name: "历史数据",
  75 + },
  76 + {
  77 + name: "告警记录",
  78 + },
  79 + ],
  80 + currentTab: 0,
  81 + deviceId: "",
  82 + deviceDetail: {},
  83 + keys: [],
  84 + yesterday: "",
  85 + today: "",
  86 + timeDiff: "",
  87 + historyData: [],
  88 + entityId: "",
  89 + startTs: "",
  90 + endTs: "",
  91 + recordList: [],
  92 + isScrollable: false,
  93 + };
  94 + },
  95 + onUnload() {
  96 + // 页面关闭时,销毁webSocket连接,否则第二次会存在连接不到的情况
  97 + uni.closeSocket();
  98 + },
  99 + async onLoad(options) {
  100 + const { id, alarmStatus, lastOnlineTime, tbDeviceId } = options;
  101 + this.deviceId = id;
  102 + const res = await uni.$u.http.get(`/yt/device/${id}`);
  103 + this.deviceDetail = {
  104 + ...res,
  105 + alarmStatus,
  106 + lastOnlineTime,
  107 + };
157 108
158 - const keys = await getDeviceKeys(tbDeviceId);  
159 - this.keys = [keys];  
160 - // 昨天  
161 - this.yesterday = moment()  
162 - .subtract(1, 'days')  
163 - .format('YYYY-MM-DD');  
164 - // 今天  
165 - this.today = moment().format('YYYY-MM-DD');  
166 - // 开始时间  
167 - this.startTs = moment()  
168 - .subtract(1, 'days')  
169 - .format('x');  
170 - // 结束时间  
171 - this.endTs = moment().format('x');  
172 - this.entityId = tbDeviceId; 109 + // 设备类型不是网关子设备的添加一个命令记录的选项卡
  110 + if (this.deviceDetail.deviceType !== "SENSOR") {
  111 + this.list.push({
  112 + name: "命令记录",
  113 + });
  114 + }
  115 + this.isScrollable = this.list.length > 4;
  116 + // 连接webSockte
  117 + const socketTask = uni.connectSocket({
  118 + url:
  119 + `${base.socketPrefix}://${base.baseWebSocketUrl}/api/ws/plugins/telemetry?token=` +
  120 + uni.getStorageSync("userInfo").isToken, //仅为示例,并非真实接口地址。
  121 + complete: () => {},
  122 + });
  123 + uni.onSocketOpen((header) => {
  124 + socketTask.send({
  125 + data: JSON.stringify({
  126 + attrSubCmds: [],
  127 + tsSubCmds: [
  128 + {
  129 + entityType: "DEVICE",
  130 + entityId: tbDeviceId,
  131 + scope: "LATEST_TELEMETRY",
  132 + cmdId: 1,
  133 + },
  134 + ],
  135 + historyCmds: [],
  136 + entityDataCmds: [],
  137 + entityDataUnsubscribeCmds: [],
  138 + alarmDataCmds: [],
  139 + alarmDataUnsubscribeCmds: [],
  140 + entityCountCmds: [],
  141 + entityCountUnsubscribeCmds: [],
  142 + }),
  143 + success() {},
  144 + });
  145 + });
  146 + socketTask.onMessage((msg) => {
  147 + const { data } = JSON.parse(msg.data);
  148 + const newArray = [];
  149 + for (const key in data) {
  150 + const [time, value] = data[key].flat(1);
  151 + let obj = {
  152 + key,
  153 + time,
  154 + value,
  155 + };
  156 + if (this.recordList.length === 0) {
  157 + this.recordList.unshift(obj);
  158 + } else {
  159 + newArray.push(obj);
  160 + }
  161 + }
  162 + newArray.forEach((item) => {
  163 + let flag = false;
  164 + this.recordList.forEach((item1) => {
  165 + if (item1.key === item.key) {
  166 + item1.value = item.value;
  167 + item1.time = item.time;
  168 + flag = true;
  169 + }
  170 + });
  171 + if (!flag) {
  172 + this.recordList.unshift(item);
  173 + }
  174 + });
  175 + this.recordList = this.recordList.map((item) => {
  176 + return {
  177 + ...item,
  178 + time: formatToDate(item.time, "YYYY-MM-DD HH:mm:ss"),
  179 + };
  180 + });
  181 + });
173 182
174 - const data = await getHistoryData({  
175 - entityId: tbDeviceId,  
176 - startTs: this.startTs,  
177 - endTs: this.endTs,  
178 - keys: keys[0],  
179 - interval: 1800000  
180 - });  
181 - this.timeDiff = '30分钟';  
182 - if (!Object.keys(data).length) return; 183 + const keys = await getDeviceKeys(tbDeviceId);
  184 + this.keys = [keys];
  185 + // 昨天
  186 + this.yesterday = moment().subtract(1, "days").format("YYYY-MM-DD");
  187 + // 今天
  188 + this.today = moment().format("YYYY-MM-DD");
  189 + // 开始时间
  190 + this.startTs = moment().subtract(1, "days").format("x");
  191 + // 结束时间
  192 + this.endTs = moment().format("x");
  193 + this.entityId = tbDeviceId;
183 194
184 - this.historyData = data[keys[0]]  
185 - .map(item => {  
186 - return {  
187 - value: item.value,  
188 - ts: formatToDate(item.ts, 'YYYY-MM-DD HH:mm:ss')  
189 - };  
190 - }) 195 + const data = await getHistoryData({
  196 + entityId: tbDeviceId,
  197 + startTs: this.startTs,
  198 + endTs: this.endTs,
  199 + keys: keys[0],
  200 + interval: 1800000,
  201 + });
  202 + this.timeDiff = "30分钟";
  203 + if (!Object.keys(data).length) return;
191 204
192 - },  
193 - methods: {  
194 - handleTabClick({ index }) {  
195 - this.currentTab = index;  
196 - },  
197 - handleUpdate(data) {  
198 - if (!Array.isArray(data)) {  
199 - this.historyData = [];  
200 - return;  
201 - }  
202 - this.historyData = data  
203 - .map(item => {  
204 - return {  
205 - value: item.value,  
206 - ts: formatToDate(item.ts, 'YYYY-MM-DD HH:mm:ss')  
207 - };  
208 - })  
209 - }  
210 - } 205 + this.historyData = data[keys[0]].map((item) => {
  206 + return {
  207 + value: item.value,
  208 + ts: formatToDate(item.ts, "YYYY-MM-DD HH:mm:ss"),
  209 + };
  210 + });
  211 + },
  212 + methods: {
  213 + handleTabClick({ index }) {
  214 + this.currentTab = index;
  215 + },
  216 + handleUpdate(data) {
  217 + if (!Array.isArray(data)) {
  218 + this.historyData = [];
  219 + return;
  220 + }
  221 + this.historyData = data.map((item) => {
  222 + return {
  223 + value: item.value,
  224 + ts: formatToDate(item.ts, "YYYY-MM-DD HH:mm:ss"),
  225 + };
  226 + });
  227 + },
  228 + },
211 }; 229 };
212 </script> 230 </script>
213 231
214 <style lang="scss" scoped> 232 <style lang="scss" scoped>
215 .device-detail-page { 233 .device-detail-page {
216 - height: 100vh;  
217 - background-color: #f8f9fa; 234 + height: 100vh;
  235 + background-color: #f8f9fa;
218 } 236 }
219 -</style> 237 +</style>
  1 +.cu-modal {
  2 + position: fixed;
  3 + top: 0;
  4 + right: 0;
  5 + bottom: 0;
  6 + left: 0;
  7 + z-index: 1110;
  8 + opacity: 0;
  9 + outline: 0;
  10 + text-align: center;
  11 + -ms-transform: scale(1.185);
  12 + transform: scale(1.185);
  13 + backface-visibility: hidden;
  14 + perspective: 2000upx;
  15 + background: rgba(0, 0, 0, 0.6);
  16 + transition: all 0.3s ease-in-out 0s;
  17 + pointer-events: none;
  18 +}
  19 +
  20 +.cu-modal::before {
  21 + content: "\200B";
  22 + display: inline-block;
  23 + height: 100%;
  24 + vertical-align: middle;
  25 +}
  26 +
  27 +.cu-modal.show {
  28 + opacity: 1;
  29 + transition-duration: 0.3s;
  30 + -ms-transform: scale(1);
  31 + transform: scale(1);
  32 + overflow-x: hidden;
  33 + overflow-y: auto;
  34 + pointer-events: auto;
  35 +}
  36 +
  37 +.cu-dialog {
  38 + position: relative;
  39 + display: inline-block;
  40 + vertical-align: middle;
  41 + margin-left: auto;
  42 + margin-right: auto;
  43 + width: 680upx;
  44 + max-width: 100%;
  45 + background-color: #f8f8f8;
  46 + border-radius: 10upx;
  47 + overflow: hidden;
  48 +}
  49 +
  50 +.cu-modal.bottom-modal::before {
  51 + vertical-align: bottom;
  52 +}
  53 +
  54 +.cu-modal.bottom-modal .cu-dialog {
  55 + width: 100%;
  56 + border-radius: 0;
  57 +}
  58 +
  59 +.cu-modal.bottom-modal {
  60 + margin-bottom: -1000upx;
  61 +}
  62 +
  63 +.cu-modal.bottom-modal.show {
  64 + margin-bottom: 0;
  65 +}
  66 +
  67 +.cu-modal.drawer-modal {
  68 + transform: scale(1);
  69 + display: flex;
  70 +}
  71 +
  72 +.cu-modal.drawer-modal .cu-dialog {
  73 + height: 100%;
  74 + min-width: 200upx;
  75 + border-radius: 0;
  76 + margin: initial;
  77 + transition-duration: 0.3s;
  78 +}
  79 +
  80 +.cu-modal.drawer-modal.justify-start .cu-dialog {
  81 + transform: translateX(-100%);
  82 +}
  83 +
  84 +.cu-modal.drawer-modal.justify-end .cu-dialog {
  85 + transform: translateX(100%);
  86 +}
  87 +
  88 +.cu-modal.drawer-modal.show .cu-dialog {
  89 + transform: translateX(0%);
  90 +}
  91 +
  92 +.cu-modal .cu-dialog>.cu-bar:first-child .action {
  93 + min-width: 100rpx;
  94 + margin-right: 0;
  95 + min-height: 100rpx;
  96 +}
@@ -4,17 +4,26 @@ @@ -4,17 +4,26 @@
4 <public-module /> 4 <public-module />
5 <view class="basic-title"> 5 <view class="basic-title">
6 <view class="u-flex"> 6 <view class="u-flex">
7 - <view style="padding-left: 32rpx;"><u-icon v-if="deviceDetail.deviceInfo.longitude !== ''" @click="handleClick" name="map-fill"></u-icon></view> 7 + <view style="padding-left: 32rpx;">
  8 + <u-icon v-if="deviceDetail.deviceInfo.longitude !== ''" @click="handleClick" name="map-fill">
  9 + </u-icon>
  10 + </view>
8 <view style="margin-left: 20rpx;">{{ deviceDetail.name }}</view> 11 <view style="margin-left: 20rpx;">{{ deviceDetail.name }}</view>
9 - <view  
10 - style="margin-left: 20rpx; font-size: 14px;"  
11 - :style="{ color: deviceDetail.deviceState === 'INACTIVE' ? '#666' : deviceDetail.deviceState === 'ONLINE' ? '#377DFF' : '#DE4437' }"  
12 - > 12 + <view style="margin-left: 20rpx; font-size: 14px;"
  13 + :style="{ color: deviceDetail.deviceState === 'INACTIVE' ? '#666' : deviceDetail.deviceState === 'ONLINE' ? '#377DFF' : '#DE4437' }">
13 {{ deviceDetail.deviceState === 'INACTIVE' ? '待激活' : deviceDetail.deviceState === 'ONLINE' ? '在线' : '离线' }} 14 {{ deviceDetail.deviceState === 'INACTIVE' ? '待激活' : deviceDetail.deviceState === 'ONLINE' ? '在线' : '离线' }}
14 </view> 15 </view>
15 </view> 16 </view>
16 - <view style="margin-right: 20rpx;" v-if="deviceDetail.deviceState === 'ONLINE' && deviceDetail.deviceType !== 'SENSOR'">  
17 - <u-button type="primary" shape="circle" size="mini" text="下发命令" @click="showModal" /> 17 + <view style="margin-right: 20rpx;"
  18 + v-if="deviceDetail.deviceState === 'ONLINE' && deviceDetail.deviceType !== 'SENSOR'">
  19 + <!-- #ifdef MP -->
  20 + <u-button type="primary" shape="circle" size="mini" text="下发命令" @click="showModalBtn" />
  21 + <!-- #endif -->
  22 + <!-- #ifdef APP-PLUS -->
  23 + <view class="cu-item" @tap="showModal" data-target="Modal">
  24 + <text>下发命令</text>
  25 + </view>
  26 + <!-- #endif -->
18 </view> 27 </view>
19 </view> 28 </view>
20 <view class="detail"> 29 <view class="detail">
@@ -48,9 +57,60 @@ @@ -48,9 +57,60 @@
48 <view class="detail-value">{{ deviceDetail.description }}</view> 57 <view class="detail-value">{{ deviceDetail.description }}</view>
49 </view> 58 </view>
50 </view> 59 </view>
51 -  
52 <!-- 下发命令 --> 60 <!-- 下发命令 -->
53 - <u-modal :show="showModel" closeOnClickOverlay :showConfirmButton="false" width="720rpx" @close="hiddenModal" @touchmove.stop.prevent="disabledScroll"> 61 + <!-- #ifdef APP-PLUS -->
  62 + <view v-show="showNodal" class="cu-modal" :class="modalName=='Modal'?'show':''">
  63 + <view class="cu-dialog" style="">
  64 + <view class="modal_main">
  65 + <view class='nav-list margin-top'>
  66 + <view style="width: 100%; padding: 0 30rpx;">
  67 + <view style="text-align: center; font-weight:700;margin-top: 40rpx;">命令下发</view>
  68 + <view style="height: 20rpx;"></view>
  69 + <view class="u-flex">
  70 + <text
  71 + style="color: #333; font-size: 14px;font-weight:700;margin-right: 30rpx;">下发类型:</text>
  72 + <view>
  73 + <radio-group style="display: flex;" @change="radioChange">
  74 + <label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in items"
  75 + :key="item.value">
  76 + <view style="display: flex">
  77 + <view style="margin-left: 10rpx;">
  78 + <radio :value="item.value" :checked="index === current" />
  79 + </view>
  80 + <view style="width:10rpx"></view>
  81 + <view style="margin-left: 10rpx;">{{item.name}}</view>
  82 + </view>
  83 + </label>
  84 + </radio-group>
  85 + </view>
  86 + </view>
  87 + <view style="margin-top: 15rpx">
  88 + <view class="cusAppplusContent">
  89 + <textarea v-model="inputCommandVal" placeholder="请输入下发内容(json格式)" />
  90 + </view>
  91 + </view>
  92 + <view class="button-group">
  93 + <view>
  94 + <view class="cusAppplusCancelBtn" @click="cancelCommand"><text
  95 + style="color: #333333">取消</text>
  96 + </view>
  97 + </view>
  98 + <view>
  99 + <view class="cusAppplusConfrimBtn" @click="confirmCommand">
  100 + <text style="color:white">确认</text>
  101 + </view>
  102 + </view>
  103 + </view>
  104 + <view style="height:30rpx"></view>
  105 + </view>
  106 + </view>
  107 + </view>
  108 + </view>
  109 + </view>
  110 + <!-- #endif -->
  111 + <!-- #ifdef MP -->
  112 + <u-modal :show="showModel" closeOnClickOverlay :showConfirmButton="false" width="720rpx" @close="hiddenModal"
  113 + @touchmove.stop.prevent="disabledScroll">
54 <view style="width: 100%; padding: 0 30rpx;"> 114 <view style="width: 100%; padding: 0 30rpx;">
55 <view style="text-align: center; font-weight:700;margin-bottom: 40rpx;">命令下发</view> 115 <view style="text-align: center; font-weight:700;margin-bottom: 40rpx;">命令下发</view>
56 <view class="u-flex"> 116 <view class="u-flex">
@@ -62,144 +122,244 @@ @@ -62,144 +122,244 @@
62 <u-radio activeColor="#3388FF" label="双向" name="TwoWay"></u-radio> 122 <u-radio activeColor="#3388FF" label="双向" name="TwoWay"></u-radio>
63 </u-radio-group> 123 </u-radio-group>
64 </view> 124 </view>
65 - <view style="margin-top: 28rpx;width: 100%;"><u--textarea placeholder="请输入下发内容(json格式)" v-model="inputCommandVal" /></view> 125 + <view style="margin-top: 28rpx;width: 100%;">
  126 + <u--textarea placeholder="请输入下发内容(json格式)" v-model="inputCommandVal" />
  127 + </view>
66 128
67 <view class="button-group"> 129 <view class="button-group">
68 - <view><u-button :customStyle="{ color: '#333' }" color="#e3e3e5" shape="circle" text="取消" @click="cancelCommand"></u-button></view>  
69 - <view><u-button color="#3388ff" shape="circle" text="确认" @click="confirmCommand"></u-button></view> 130 + <view>
  131 + <u-button :customStyle="{ color: '#333' }" color="#e3e3e5" shape="circle" text="取消"
  132 + @click="cancelCommand"></u-button>
  133 + </view>
  134 + <view>
  135 + <u-button color="#3388ff" shape="circle" text="确认" @click="confirmCommand"></u-button>
  136 + </view>
70 </view> 137 </view>
71 </view> 138 </view>
72 </u-modal> 139 </u-modal>
  140 + <!-- #endif -->
73 </view> 141 </view>
74 </template> 142 </template>
75 143
76 <script> 144 <script>
77 -import { formatToDate } from '@/plugins/utils.js';  
78 -import { issueCommand } from '../api/index.js';  
79 -export default {  
80 - props: {  
81 - deviceDetail: {  
82 - type: Object,  
83 - default: () => ({})  
84 - }  
85 - },  
86 - data() {  
87 - return {  
88 - showModel: false,  
89 - commandType: 'OneWay',  
90 - commandValue: {},  
91 - inputCommandVal: ''  
92 - };  
93 - },  
94 - computed: {  
95 - deviceType() {  
96 - return this.deviceDetail.deviceType === 'DIRECT_CONNECTION'  
97 - ? '直连设备'  
98 - : this.deviceDetail.deviceType === 'GATEWAY'  
99 - ? '网关设备'  
100 - : this.deviceDetail.deviceType === 'SENSOR'  
101 - ? '网关子设备'  
102 - : '';  
103 - },  
104 - alarmStatus() {  
105 - return this.deviceDetail.alarmStatus === '0' ? '否' : '是'; 145 + import {
  146 + formatToDate
  147 + } from '@/plugins/utils.js';
  148 + import {
  149 + issueCommand
  150 + } from '../api/index.js';
  151 + export default {
  152 + props: {
  153 + deviceDetail: {
  154 + type: Object,
  155 + default: () => ({})
  156 + }
106 }, 157 },
107 - formatLastOnlineTime() {  
108 - return formatToDate(Number(this.deviceDetail.lastOnlineTime), 'YYYY-MM-DD HH:mm:ss');  
109 - }  
110 - },  
111 - onLoad(e) {  
112 - // 隐藏原生的tabbar  
113 - uni.hideTabBar();  
114 - },  
115 - mounted() {},  
116 - methods: {  
117 - handleClick() {  
118 - const data = {  
119 - longitude: this.deviceDetail.deviceInfo.longitude || 0,  
120 - latitude: this.deviceDetail.deviceInfo.latitude || 0 158 + data() {
  159 + return {
  160 + showNodal: false,
  161 + items: [{
  162 + value: 'OneWay',
  163 + name: '单向',
  164 + checked: 'true'
  165 + },
  166 + {
  167 + value: 'TwoWay',
  168 + name: '双向'
  169 + },
  170 + ],
  171 + current: 0,
  172 + modalName: null,
  173 + showModel: false,
  174 + commandType: 'OneWay',
  175 + commandValue: {},
  176 + inputCommandVal: ''
121 }; 177 };
122 - uni.navigateTo({  
123 - url: '/deviceSubPage/deviceDetailPage/devicePosition?data=' + JSON.stringify(data)  
124 - });  
125 }, 178 },
126 - showModal() {  
127 - this.showModel = true;  
128 - this.inputCommandVal = ''; 179 + computed: {
  180 + deviceType() {
  181 + return this.deviceDetail.deviceType === 'DIRECT_CONNECTION' ?
  182 + '直连设备' :
  183 + this.deviceDetail.deviceType === 'GATEWAY' ?
  184 + '网关设备' :
  185 + this.deviceDetail.deviceType === 'SENSOR' ?
  186 + '网关子设备' :
  187 + '';
  188 + },
  189 + alarmStatus() {
  190 + return this.deviceDetail.alarmStatus === '0' ? '否' : '是';
  191 + },
  192 + formatLastOnlineTime() {
  193 + return formatToDate(Number(this.deviceDetail.lastOnlineTime), 'YYYY-MM-DD HH:mm:ss');
  194 + }
129 }, 195 },
130 - disabledScroll() {  
131 - return; 196 + onLoad(e) {
  197 + // 隐藏原生的tabbar
  198 + uni.hideTabBar();
132 }, 199 },
133 - hiddenModal() {  
134 - this.showModel = false; 200 + mounted() {},
  201 + beforeCreate() {
  202 + this.modalName = null
135 }, 203 },
136 - async confirmCommand() {  
137 - try {  
138 - const commandJsonValue = JSON.parse(this.inputCommandVal);  
139 - this.commandValue.persistent = true;  
140 - this.commandValue.additionalInfo = {  
141 - cmdType: 'API'  
142 - };  
143 - this.commandValue.method = 'methodThingskit';  
144 - this.commandValue.params = {  
145 - params: commandJsonValue 204 + methods: {
  205 + radioChange: function(evt) {
  206 + for (let i = 0; i < this.items.length; i++) {
  207 + if (this.items[i].value === evt.detail.value) {
  208 + this.current = i;
  209 + break;
  210 + }
  211 + }
  212 + this.commandType = evt.detail.value
  213 + },
  214 + handleClick() {
  215 + const data = {
  216 + longitude: this.deviceDetail.deviceInfo.longitude || 0,
  217 + latitude: this.deviceDetail.deviceInfo.latitude || 0
146 }; 218 };
147 - await issueCommand(this.commandType, this.deviceDetail.tbDeviceId, this.commandValue); 219 + uni.navigateTo({
  220 + url: '/deviceSubPage/deviceDetailPage/devicePosition?data=' + JSON.stringify(data)
  221 + });
  222 + },
  223 + showModal(e) {
  224 + this.modalName = e.currentTarget.dataset.target
  225 + this.showNodal = true
  226 + },
  227 + showModalBtn() {
  228 + this.showModel = true;
  229 + this.inputCommandVal = '';
  230 + },
  231 + disabledScroll() {
  232 + return;
  233 + },
  234 + hiddenModal() {
  235 + this.showModel = false;
  236 + this.inputCommandVal = '';
  237 + // #ifdef APP-PLUS
  238 + this.modalName = null
  239 + this.showNodal = false
  240 + // #endif
  241 + },
  242 + async confirmCommand() {
  243 + try {
  244 + const commandJsonValue = JSON.parse(this.inputCommandVal);
  245 + this.commandValue.persistent = true;
  246 + this.commandValue.additionalInfo = {
  247 + cmdType: 'API'
  248 + };
  249 + this.commandValue.method = 'methodThingskit';
  250 + this.commandValue.params = {
  251 + params: commandJsonValue
  252 + };
  253 + await issueCommand(this.commandType, this.deviceDetail.tbDeviceId, this.commandValue);
  254 + this.hiddenModal();
  255 + uni.$u.toast('下发成功~');
  256 + } catch (e) {
  257 + uni.$u.toast('下发失败~');
  258 + }
  259 + },
  260 + cancelCommand() {
148 this.hiddenModal(); 261 this.hiddenModal();
149 - uni.$u.toast('下发成功~');  
150 - } catch (e) {  
151 - uni.$u.toast('下发失败~'); 262 + // #ifdef APP-PLUS
  263 + this.modalName = null
  264 + this.showNodal = false
  265 + // #endif
152 } 266 }
153 - },  
154 - cancelCommand() {  
155 - this.hiddenModal();  
156 } 267 }
157 - }  
158 -}; 268 + };
159 </script> 269 </script>
160 270
161 <style lang="scss" scoped> 271 <style lang="scss" scoped>
162 -.basic-page {  
163 - padding: 0 30rpx;  
164 - .basic-title {  
165 - display: flex;  
166 - justify-content: space-between;  
167 - align-items: center;  
168 - height: 140rpx;  
169 - background-color: #fff;  
170 - border-radius: 20rpx; 272 + @import url('../styles/modal.css');
  273 +
  274 + .cusAppplusContent {
  275 + width: 625rpx;
  276 + height: 400rpx;
  277 + background: #FFFFFF;
  278 + box-shadow: 2px 2px 4px 0px rgba(0, 0, 0, 0.03);
  279 + border-radius: 10px;
  280 +
  281 + }
  282 +
  283 + .cusAppplusCancelBtn {
  284 + background: #e3e3e5;
  285 + border-radius: 38rpx;
  286 + height: 85rpx;
  287 + line-height: 85rpx
  288 + }
  289 +
  290 + .cusAppplusConfrimBtn {
  291 + background: #3388ff;
  292 + border-radius: 38rpx;
  293 + height: 85rpx;
  294 + line-height: 85rpx
  295 + }
  296 +
  297 + .cu-item {
  298 + background: #3388FF;
  299 + border-radius: 12px;
  300 + width: 120rpx;
  301 + height: 48rpx;
  302 + text-align: center;
  303 + line-height: 40rpx;
  304 +
  305 + text {
  306 + font-size: 12px;
  307 + font-family: PingFangSC-Regular, PingFang SC;
  308 + font-weight: 400;
  309 + color: #FFFFFF;
  310 + }
171 } 311 }
172 - .detail {  
173 - background-color: #fff;  
174 - margin-top: 30rpx;  
175 - border-radius: 20rpx;  
176 - width: 690rpx;  
177 - .detail-item {  
178 - padding: 30rpx; 312 +
  313 +
  314 +
  315 + .basic-page {
  316 + padding: 0 30rpx;
  317 +
  318 + .basic-title {
179 display: flex; 319 display: flex;
  320 + justify-content: space-between;
180 align-items: center; 321 align-items: center;
181 - .detail-label {  
182 - color: #333;  
183 - font-size: 15px;  
184 - }  
185 - .detail-value {  
186 - color: #666;  
187 - font-size: 14px;  
188 - margin-left: 30rpx; 322 + height: 140rpx;
  323 + background-color: #fff;
  324 + border-radius: 20rpx;
  325 + }
  326 +
  327 + .detail {
  328 + background-color: #fff;
  329 + margin-top: 30rpx;
  330 + border-radius: 20rpx;
  331 + width: 690rpx;
  332 +
  333 + .detail-item {
  334 + padding: 30rpx;
  335 + display: flex;
  336 + align-items: center;
  337 +
  338 + .detail-label {
  339 + color: #333;
  340 + font-size: 15px;
  341 + }
  342 +
  343 + .detail-value {
  344 + color: #666;
  345 + font-size: 14px;
  346 + margin-left: 30rpx;
  347 + }
189 } 348 }
190 } 349 }
191 } 350 }
192 -}  
193 -/deep/ .u-modal__content {  
194 - padding: 30rpx 0 !important;  
195 -}  
196 -  
197 -.button-group {  
198 - display: flex;  
199 - margin-top: 40rpx;  
200 - justify-content: space-between;  
201 - view {  
202 - width: 300rpx; 351 +
  352 + /deep/ .u-modal__content {
  353 + padding: 30rpx 0 !important;
  354 + }
  355 +
  356 + .button-group {
  357 + display: flex;
  358 + margin-top: 40rpx;
  359 + justify-content: space-between;
  360 +
  361 + view {
  362 + width: 300rpx;
  363 + }
203 } 364 }
204 -}  
205 </style> 365 </style>
1 { 1 {
2 - "name" : "yun-teng-app",  
3 - "appid" : "__UNI__AD0D64F",  
4 - "description" : "thingskit",  
5 - "versionName" : "1.0.0",  
6 - "versionCode" : 100,  
7 - "transformPx" : false,  
8 - "app-plus" : {  
9 - "usingComponents" : true,  
10 - "nvueStyleCompiler" : "uni-app",  
11 - "compilerVersion" : 3,  
12 - "splashscreen" : {  
13 - "alwaysShowBeforeRender" : true,  
14 - "waiting" : true,  
15 - "autoclose" : true,  
16 - "delay" : 0  
17 - },  
18 - "modules" : {  
19 - "VideoPlayer" : {},  
20 - "Contacts" : {},  
21 - "OAuth" : {},  
22 - "Messaging" : {},  
23 - "FaceID" : {}  
24 - },  
25 - "distribute" : {  
26 - "android" : {  
27 - "permissions" : [  
28 - "<uses-feature android:name=\"android.hardware.camera\"/>",  
29 - "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",  
30 - "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",  
31 - "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",  
32 - "<uses-permission android:name=\"android.permission.CAMERA\"/>",  
33 - "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",  
34 - "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",  
35 - "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",  
36 - "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",  
37 - "<uses-permission android:name=\"android.permission.INSTALL_PACKAGES\"/>",  
38 - "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",  
39 - "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",  
40 - "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",  
41 - "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",  
42 - "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",  
43 - "<uses-permission android:name=\"android.permission.READ_SMS\"/>",  
44 - "<uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\"/>",  
45 - "<uses-permission android:name=\"android.permission.SEND_SMS\"/>",  
46 - "<uses-permission android:name=\"android.permission.VIBRATE\"/>",  
47 - "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",  
48 - "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",  
49 - "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",  
50 - "<uses-permission android:name=\"android.permission.WRITE_SMS\"/>"  
51 - ]  
52 - },  
53 - "ios" : {},  
54 - "sdkConfigs" : {  
55 - "ad" : {},  
56 - "geolocation" : {  
57 - "system" : {  
58 - "__platform__" : [ "ios", "android" ]  
59 - },  
60 - "amap" : {  
61 - "__platform__" : [ "ios", "android" ],  
62 - "appkey_ios" : "",  
63 - "appkey_android" : ""  
64 - }  
65 - },  
66 - "maps" : {},  
67 - "oauth" : {}  
68 - },  
69 - "splashscreen" : {  
70 - "androidStyle" : "default",  
71 - "android" : {  
72 - "hdpi" : "C:/Users/YunTeng/Pictures/logo.png",  
73 - "xhdpi" : "C:/Users/YunTeng/Pictures/logo.png",  
74 - "xxhdpi" : "C:/Users/YunTeng/Pictures/logo.png"  
75 - }  
76 - }  
77 - }  
78 - },  
79 - "quickapp" : {},  
80 - "mp-weixin" : {  
81 - "appid" : "wx99c411dc3c5571ef",  
82 - "setting" : {  
83 - "urlCheck" : false,  
84 - "minified" : false,  
85 - "es6" : false,  
86 - "postcss" : true  
87 - },  
88 - "usingComponents" : true,  
89 - "permission" : {  
90 - "scope.userLocation" : {  
91 - "desc" : "你的位置信息将用于小程序位置接口的效果展示"  
92 - }  
93 - },  
94 - "lazyCodeLoading" : "requiredComponents",  
95 - //开启分包优化  
96 - "optimization" : {  
97 - "subPackages" : true  
98 - }  
99 - },  
100 - "mp-alipay" : {  
101 - "usingComponents" : true  
102 - },  
103 - "mp-baidu" : {  
104 - "usingComponents" : true  
105 - },  
106 - "mp-toutiao" : {  
107 - "usingComponents" : true  
108 - },  
109 - "uniStatistics" : {  
110 - "enable" : false  
111 - },  
112 - "vueVersion" : "2",  
113 - "h5" : {  
114 - "sdkConfigs" : {  
115 - "maps" : {}  
116 - },  
117 - "router" : {  
118 - "base" : "minImage/h5/"  
119 - }  
120 - } 2 + "name": "yun-teng-app",
  3 + "appid": "__UNI__AD0D64F",
  4 + "description": "thingskit",
  5 + "versionName": "1.0.0",
  6 + "versionCode": 100,
  7 + "transformPx": false,
  8 + "app-plus": {
  9 + "usingComponents": true,
  10 + "nvueStyleCompiler": "uni-app",
  11 + "compilerVersion": 3,
  12 + "splashscreen": {
  13 + "alwaysShowBeforeRender": true,
  14 + "waiting": false,
  15 + "autoclose": true,
  16 + "delay": 0
  17 + },
  18 + "modules": {
  19 + "VideoPlayer": {},
  20 + "Maps": {},
  21 + "Contacts": {},
  22 + "FaceID": {},
  23 + "Messaging": {},
  24 + "OAuth": {}
  25 + },
  26 + "compatible": {
  27 + "ignoreVersion": true
  28 + },
  29 + "distribute": {
  30 + "android": {
  31 + "permissions": [
  32 + "<uses-feature android:name=\"android.hardware.camera\"/>",
  33 + "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
  34 + "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
  35 + "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
  36 + "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
  37 + "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
  38 + "<uses-permission android:name=\"android.permission.CAMERA\"/>",
  39 + "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
  40 + "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
  41 + "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
  42 + "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
  43 + "<uses-permission android:name=\"android.permission.INSTALL_PACKAGES\"/>",
  44 + "<uses-permission android:name=\"android.permission.INTERNET\"/>",
  45 + "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
  46 + "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
  47 + "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
  48 + "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
  49 + "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
  50 + "<uses-permission android:name=\"android.permission.READ_SMS\"/>",
  51 + "<uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\"/>",
  52 + "<uses-permission android:name=\"android.permission.SEND_SMS\"/>",
  53 + "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
  54 + "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
  55 + "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
  56 + "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
  57 + "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
  58 + "<uses-permission android:name=\"android.permission.WRITE_SMS\"/>"
  59 + ],
  60 + "autoSdkPermissions": true
  61 + },
  62 + "ios": {
  63 + "dSYMs": false
  64 + },
  65 + "sdkConfigs": {
  66 + "ad": {},
  67 + "geolocation": {
  68 + "system": {
  69 + "__platform__": ["ios", "android"]
  70 + },
  71 + "amap": {
  72 + "__platform__": ["ios", "android"],
  73 + "appkey_ios": "",
  74 + "appkey_android": ""
  75 + }
  76 + },
  77 + "maps": {
  78 + "amap": {
  79 + "appkey_ios": "5221d1373233c782efac82fb176f7f7d",
  80 + "appkey_android": "5221d1373233c782efac82fb176f7f7d"
  81 + }
  82 + },
  83 + "oauth": {}
  84 + },
  85 + "splashscreen": {
  86 + "androidStyle": "default",
  87 + "android": {}
  88 + },
  89 + "icons": {
  90 + "android": {
  91 + "xxhdpi": "C:/Users/YunTeng/Desktop/公司图标/微信图片_20220506171238.png",
  92 + "xhdpi": "C:/Users/YunTeng/Desktop/公司图标/微信图片_20220506171238.png",
  93 + "hdpi": "C:/Users/YunTeng/Desktop/公司图标/微信图片_20220506171238.png",
  94 + "xxxhdpi": "C:/Users/YunTeng/Desktop/公司图标/微信图片_20220506171238.png"
  95 + }
  96 + }
  97 + }
  98 + },
  99 + "quickapp": {},
  100 + "mp-weixin": {
  101 + "appid": "wx99c411dc3c5571ef",
  102 + "setting": {
  103 + "urlCheck": false,
  104 + "minified": true,
  105 + "es6": false,
  106 + "postcss": true
  107 + },
  108 + "usingComponents": true,
  109 + "permission": {
  110 + "scope.userLocation": {
  111 + "desc": "你的位置信息将用于小程序位置接口的效果展示"
  112 + }
  113 + },
  114 + "lazyCodeLoading": "requiredComponents",
  115 + "optimization": {
  116 + "subPackages": true
  117 + }
  118 + },
  119 + "mp-alipay": {
  120 + "usingComponents": true
  121 + },
  122 + "mp-baidu": {
  123 + "usingComponents": true
  124 + },
  125 + "mp-toutiao": {
  126 + "usingComponents": true
  127 + },
  128 + "uniStatistics": {
  129 + "enable": false
  130 + },
  131 + "vueVersion": "2",
  132 + "h5": {
  133 + "sdkConfigs": {
  134 + "maps": {}
  135 + },
  136 + "router": {
  137 + "base": "minImage/h5/"
  138 + }
  139 + }
121 } 140 }
@@ -39,7 +39,8 @@ @@ -39,7 +39,8 @@
39 <text class="item-text home-text-muted">告警统计</text> 39 <text class="item-text home-text-muted">告警统计</text>
40 </view> 40 </view>
41 <view class="item-child-bottom u-flex"> 41 <view class="item-child-bottom u-flex">
42 - <view @click="navigatorAlarmStatus(['ACTIVE_UNACK', 'ACTIVE_ACK'])" class="u-flex sigle-child"> 42 + <view @click="navigatorAlarmStatus(['ACTIVE_UNACK', 'ACTIVE_ACK'])"
  43 + class="u-flex sigle-child">
43 <view class="sigle-text"> 44 <view class="sigle-text">
44 <text class="home-text-total">{{ alertData.noHandle }}</text> 45 <text class="home-text-total">{{ alertData.noHandle }}</text>
45 </view> 46 </view>
@@ -72,7 +73,9 @@ @@ -72,7 +73,9 @@
72 </view> --> 73 </view> -->
73 <view @click="openCamera" class="grid-item"> 74 <view @click="openCamera" class="grid-item">
74 <view class="item-center"> 75 <view class="item-center">
75 - <view class="center"><image class="image" src="../../static/camer.png"></image></view> 76 + <view class="center">
  77 + <image class="image" src="../../static/camer.png"></image>
  78 + </view>
76 <view class="center-text"><text class="text text-muted" style="">摄像头管理</text></view> 79 <view class="center-text"><text class="text text-muted" style="">摄像头管理</text></view>
77 </view> 80 </view>
78 </view> 81 </view>
@@ -84,7 +87,9 @@ @@ -84,7 +87,9 @@
84 </view> --> 87 </view> -->
85 <view @click="openOrgStatus" class="grid-item"> 88 <view @click="openOrgStatus" class="grid-item">
86 <view class="item-center"> 89 <view class="item-center">
87 - <view class="center"><image class="image" src="../../static/status.png"></image></view> 90 + <view class="center">
  91 + <image class="image" src="../../static/status.png"></image>
  92 + </view>
88 <view class="center-text"><text class="text text-muted">组态</text></view> 93 <view class="center-text"><text class="text text-muted">组态</text></view>
89 </view> 94 </view>
90 </view> 95 </view>
@@ -96,81 +101,83 @@ @@ -96,81 +101,83 @@
96 </template> 101 </template>
97 102
98 <script> 103 <script>
99 -import fTabbar from '@/components/module/f-tabbar/f-tabbar';  
100 -import { mapActions } from 'vuex'; 104 + import fTabbar from '@/components/module/f-tabbar/f-tabbar';
  105 + import {
  106 + mapActions
  107 + } from 'vuex';
101 108
102 -export default {  
103 - components: {  
104 - fTabbar  
105 - },  
106 - data() {  
107 - return {  
108 - deviceData: {  
109 - onLine: 0,  
110 - unLine: 0,  
111 - noActive: 0  
112 - },  
113 - alertData: {  
114 - noHandle: 0,  
115 - doneHandle: 0,  
116 - errorReport: 0  
117 - }  
118 - };  
119 - },  
120 - onLoad() {  
121 - // 隐藏原生的tabbar  
122 - uni.hideTabBar();  
123 - this.getDeviceTotalData();  
124 - uni.setStorageSync('getConfiguration', {  
125 - isConfiguration: false  
126 - });  
127 - uni.removeStorageSync('getConfiguration');  
128 - },  
129 - methods: {  
130 - ...mapActions(['updateBadgeTotal']),  
131 - getDeviceTotalData() {  
132 - uni.$u.http.get('/yt/homepage/app?login=false').then(res => {  
133 - if (res) {  
134 - this.deviceData.onLine = res.totalDevice?.onLine;  
135 - this.deviceData.unLine = res.totalDevice?.offLine;  
136 - this.deviceData.noActive = res.totalDevice?.inActive;  
137 - this.alertData.noHandle = res.totalAlarm?.activedAlarm;  
138 - this.alertData.doneHandle = res.totalAlarm?.clearedAck;  
139 - this.alertData.errorReport = res.totalAlarm?.clearedUnack;  
140 - //异步实时更新告警徽标数  
141 - this.updateBadgeTotal(res.totalAlarm?.activedAlarm);  
142 - }  
143 - });  
144 - },  
145 - showToastWip() {  
146 - uni.$u.toast('拼命开发中 ...');  
147 - },  
148 - openCamera() {  
149 - uni.navigateTo({  
150 - url: 'camera/camera'  
151 - }); 109 + export default {
  110 + components: {
  111 + fTabbar
152 }, 112 },
153 - openOrgStatus() {  
154 - uni.navigateTo({  
155 - url: 'configuration/configuration'  
156 - }); 113 + data() {
  114 + return {
  115 + deviceData: {
  116 + onLine: 0,
  117 + unLine: 0,
  118 + noActive: 0
  119 + },
  120 + alertData: {
  121 + noHandle: 0,
  122 + doneHandle: 0,
  123 + errorReport: 0
  124 + }
  125 + };
157 }, 126 },
158 - //告警状态查询  
159 - navigatorAlarmStatus(e) {  
160 - uni.reLaunch({  
161 - url: '../alarm/alarm?type=' + JSON.stringify(e) 127 + onLoad() {
  128 + // 隐藏原生的tabbar
  129 + uni.hideTabBar();
  130 + this.getDeviceTotalData();
  131 + uni.setStorageSync('getConfiguration', {
  132 + isConfiguration: false
162 }); 133 });
  134 + uni.removeStorageSync('getConfiguration');
163 }, 135 },
164 - //设备状态查询  
165 - navigatorDeviceStatus(e) {  
166 - uni.reLaunch({  
167 - url: `../device/device?deviceState=${e}`  
168 - }); 136 + methods: {
  137 + ...mapActions(['updateBadgeTotal']),
  138 + getDeviceTotalData() {
  139 + uni.$u.http.get('/yt/homepage/app?login=false').then(res => {
  140 + if (res) {
  141 + this.deviceData.onLine = res.totalDevice?.onLine;
  142 + this.deviceData.unLine = res.totalDevice?.offLine;
  143 + this.deviceData.noActive = res.totalDevice?.inActive;
  144 + this.alertData.noHandle = res.totalAlarm?.activedAlarm;
  145 + this.alertData.doneHandle = res.totalAlarm?.clearedAck;
  146 + this.alertData.errorReport = res.totalAlarm?.clearedUnack;
  147 + //异步实时更新告警徽标数
  148 + this.updateBadgeTotal(res.totalAlarm?.activedAlarm);
  149 + }
  150 + });
  151 + },
  152 + showToastWip() {
  153 + uni.$u.toast('拼命开发中 ...');
  154 + },
  155 + openCamera() {
  156 + uni.navigateTo({
  157 + url: 'camera/camera'
  158 + });
  159 + },
  160 + openOrgStatus() {
  161 + uni.navigateTo({
  162 + url: 'configuration/configuration'
  163 + });
  164 + },
  165 + //告警状态查询
  166 + navigatorAlarmStatus(e) {
  167 + uni.reLaunch({
  168 + url: '../alarm/alarm?type=' + JSON.stringify(e)
  169 + });
  170 + },
  171 + //设备状态查询
  172 + navigatorDeviceStatus(e) {
  173 + uni.reLaunch({
  174 + url: `../device/device?deviceState=${e}`
  175 + });
  176 + }
169 } 177 }
170 - }  
171 -}; 178 + };
172 </script> 179 </script>
173 180
174 <style lang="scss" scoped> 181 <style lang="scss" scoped>
175 -@import './static/index.scss'; 182 + @import './static/index.scss';
176 </style> 183 </style>
1 -import Vue from 'vue';  
2 -import moment from 'moment';  
3 -const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss';  
4 -//金额过滤  
5 -Vue.filter('money', function(val) {  
6 - if (val) {  
7 - let value = Math.round(parseFloat(val) * 100) / 100;  
8 - let valMoney = value.toString().split(".");  
9 - if (valMoney.length == 1) {  
10 - value = value.toString() + ".00";  
11 - return value;  
12 - }  
13 - if (valMoney.length > 1) {  
14 - if (valMoney[1].length < 2) {  
15 - value = value.toString() + "0";  
16 - }  
17 - return value;  
18 - }  
19 - return value;  
20 - } else {  
21 - return "0.00";  
22 - }  
23 -}); 1 +import Vue from "vue";
  2 +import moment from "moment";
  3 +const DATE_TIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
24 //手机号中间4位为* 4 //手机号中间4位为*
25 -Vue.filter('phone', function(val) {  
26 - var tel = val;  
27 - tel = "" + tel;  
28 - var telShort = tel.replace(tel.substring(3, 7), "****")  
29 - return telShort  
30 -}) 5 +Vue.filter("phone", function (val) {
  6 + var tel = val;
  7 + tel = "" + tel;
  8 + var telShort = tel.replace(tel.substring(3, 7), "****");
  9 + return telShort;
  10 +});
31 //获取系统信息、判断ipX安全距离 11 //获取系统信息、判断ipX安全距离
32 -export const getTabbarHeight = function() {  
33 - var systemInfo = uni.getSystemInfoSync()  
34 - var data = {  
35 - ...systemInfo,  
36 - tabbarH: 50, //tabbar高度--单位px  
37 - tabbarPaddingB: 0, //tabbar底部安全距离高度--单位px  
38 - device: systemInfo.system.indexOf('iOS') != -1 ? 'iOS' : 'Android', //苹果或者安卓设备  
39 - }  
40 - let modelArr = ['10,3', '10,6', 'X', 'XR', 'XS', '11', '12', '13', '14', '15', '16'];  
41 - let model = systemInfo.model;  
42 - model && modelArr.forEach(item => {  
43 - //适配iphoneX以上的底部,给tabbar一定高度的padding-bottom  
44 - if (model.indexOf(item) != -1 && (model.indexOf('iPhone') != -1 || model.indexOf('iphone') != -1)) {  
45 - data.tabbarH = 70  
46 - data.tabbarPaddingB = 20  
47 - }  
48 - })  
49 - return data;  
50 -} 12 +export const getTabbarHeight = function () {
  13 + var systemInfo = uni.getSystemInfoSync();
  14 + var data = {
  15 + ...systemInfo,
  16 + tabbarH: 50, //tabbar高度--单位px
  17 + tabbarPaddingB: 0, //tabbar底部安全距离高度--单位px
  18 + device: systemInfo.system.indexOf("iOS") != -1 ? "iOS" : "Android", //苹果或者安卓设备
  19 + };
  20 + let modelArr = [
  21 + "10,3",
  22 + "10,6",
  23 + "X",
  24 + "XR",
  25 + "XS",
  26 + "11",
  27 + "12",
  28 + "13",
  29 + "14",
  30 + "15",
  31 + "16",
  32 + ];
  33 + let model = systemInfo.model;
  34 + model &&
  35 + modelArr.forEach((item) => {
  36 + //适配iphoneX以上的底部,给tabbar一定高度的padding-bottom
  37 + if (
  38 + model.indexOf(item) != -1 &&
  39 + (model.indexOf("iPhone") != -1 || model.indexOf("iphone") != -1)
  40 + ) {
  41 + data.tabbarH = 70;
  42 + data.tabbarPaddingB = 20;
  43 + }
  44 + });
  45 + return data;
  46 +};
51 47
52 -//计算两点距离  
53 -export const commonDistance = function(lat1, lng1, lat2, lng2) {  
54 - var f = ((lat1 + lat2) / 2) * Math.PI / 180.0;  
55 - var g = ((lat1 - lat2) / 2) * Math.PI / 180.0;  
56 - var l = ((lng1 - lng2) / 2) * Math.PI / 180.0;  
57 - var sg = Math.sin(g);  
58 - var sl = Math.sin(l);  
59 - var sf = Math.sin(f);  
60 - var s, c, w, r, d, h1, h2;  
61 - var a = 6378137.0; //地球的直径  
62 - var fl = 1 / 298.257;  
63 - sg = sg * sg;  
64 - sl = sl * sl;  
65 - sf = sf * sf;  
66 - s = sg * (1 - sl) + (1 - sf) * sl;  
67 - c = (1 - sg) * (1 - sl) + sf * sl;  
68 - w = Math.atan(Math.sqrt(s / c));  
69 - r = Math.sqrt(s * c) / w;  
70 - d = 2 * w * a;  
71 - h1 = (3 * r - 1) / 2 / c;  
72 - h2 = (3 * r + 1) / 2 / s;  
73 - var num = d * (1 + fl * (h1 * sf * (1 - sg) - h2 * (1 - sf) * sg))  
74 - // 换算单位  
75 - if (num == undefined) {  
76 - num = "0.0 m"  
77 - };  
78 - if (num < 1000) {  
79 - num = (Math.round(num)).toFixed(1) + "m"  
80 - } else if (num > 1000) {  
81 - num = (Math.round(num / 100) / 10).toFixed(1) + "km"  
82 - }  
83 - return num  
84 -}  
85 // px转upx 48 // px转upx
86 -export const px2upx = function(n) {  
87 - return n / (uni.upx2px(n) / n);  
88 -}  
89 -  
90 -// 判断两时间段之间活动状态、判断活动还有多长时间开始、多长时间结束----添加定时器运行此方法可倒计时  
91 -// var startTime = new Date(item.startTime.replace(/-/g, '/')).getTime(); //转时间戳  
92 -// var closeTime = new Date(item.closeTime.replace(/-/g, '/')).getTime(); //转时间戳  
93 -// var djs = this.djsTime(startTime, closeTime);  
94 -export const djsTime = function(startTime, endTime) {  
95 - var bbb = new Date().getTime(),  
96 - leftTime = startTime - bbb,  
97 - rightTime = endTime - bbb,  
98 - djsTime = '',  
99 - speed = 0,  
100 - activityStatus = 0, //活动状态 1:未开始 2:进行中 3:已结束  
101 - dd, hh, mm, ss;  
102 - if (leftTime > 0) { //还未开始  
103 - activityStatus = 1  
104 - dd = Math.floor(leftTime / 1000 / 60 / 60 / 24);  
105 - hh = Math.floor((leftTime / 1000 / 60 / 60) % 24) < 10 ? '0' + Math.floor((leftTime / 1000 / 60 / 60) %  
106 - 24) : Math.floor((leftTime / 1000 / 60 / 60) % 24);  
107 - mm = Math.floor((leftTime / 1000 / 60) % 60) < 10 ? '0' + Math.floor((leftTime / 1000 / 60) % 60) : Math  
108 - .floor((leftTime / 1000 / 60) % 60);  
109 - ss = Math.floor((leftTime / 1000) % 60) < 10 ? '0' + Math.floor((leftTime / 1000) % 60) : Math.floor((  
110 - leftTime / 1000) % 60);  
111 - if (dd != 0) {  
112 - djsTime = dd + "天 " + hh + ":" + mm + ":" + ss;  
113 - } else {  
114 - djsTime = hh + ":" + mm + ":" + ss;  
115 - }  
116 - } else if (leftTime <= 0) {  
117 - if (rightTime > 0) { //进行中  
118 - activityStatus = 2;  
119 - speed = (1 - rightTime / (endTime - startTime)) * 100;  
120 - dd = Math.floor(rightTime / 1000 / 60 / 60 / 24);  
121 - hh = Math.floor((rightTime / 1000 / 60 / 60) % 24) < 10 ? '0' + Math.floor((rightTime / 1000 / 60 /  
122 - 60) % 24) : Math.floor((rightTime / 1000 / 60 / 60) % 24);  
123 - mm = Math.floor((rightTime / 1000 / 60) % 60) < 10 ? '0' + Math.floor((rightTime / 1000 / 60) % 60) :  
124 - Math.floor((rightTime / 1000 / 60) % 60);  
125 - ss = Math.floor((rightTime / 1000) % 60) < 10 ? '0' + Math.floor((rightTime / 1000) % 60) : Math.floor((  
126 - rightTime / 1000) % 60);  
127 - if (dd != 0) {  
128 - djsTime = dd + "天 " + hh + ":" + mm + ":" + ss;  
129 - } else {  
130 - djsTime = hh + ":" + mm + ":" + ss;  
131 - }  
132 - } else { //已结束  
133 - speed = 100;  
134 - djsTime = '已结束';  
135 - activityStatus = 3;  
136 - }  
137 - }  
138 - var item = {  
139 - djsTime: djsTime, //距离当前时间差  
140 - activityStatus: activityStatus, //活动状态 1:未开始 2:进行中 3:已结束  
141 - speed: speed, //进度(单位%)  
142 - dd: dd, //天  
143 - hh: hh, //小时  
144 - mm: mm, //分  
145 - ss: ss, //秒  
146 - }  
147 - return item;  
148 -} 49 +export const px2upx = function (n) {
  50 + return n / (uni.upx2px(n) / n);
  51 +};
149 52
150 // 小程序获取定位权限判断 53 // 小程序获取定位权限判断
151 // isOpenSetting 默认false:不检验授权,true:检验授权后获取地址 54 // isOpenSetting 默认false:不检验授权,true:检验授权后获取地址
152 function getMpLocation(successCallback, errCallback, isOpenSetting) { 55 function getMpLocation(successCallback, errCallback, isOpenSetting) {
153 - uni.getSetting({  
154 - success: res => {  
155 - if (res.authSetting['scope.userLocation'] || !isOpenSetting) {  
156 - uni.getLocation({  
157 - // #ifndef MP-ALIPAY  
158 - type: 'gcj02',  
159 - // #endif  
160 - success(res) {  
161 - console.log('successCallback')  
162 - successCallback(res);  
163 - },  
164 - fail(err) {  
165 - console.log("位置信息错误", err);  
166 - errCallback("位置信息获取失败");  
167 - }  
168 - });  
169 - } else {  
170 - errCallback("“位置信息”未授权");  
171 - isOpenSetting && uni.showModal({  
172 - title: '提示',  
173 - content: '请先在设置页面打开“位置信息”使用权限',  
174 - confirmText: '去设置',  
175 - cancelText: '再逛会',  
176 - success: res => {  
177 - if (res.confirm) {  
178 - uni.openSetting();  
179 - }  
180 - }  
181 - });  
182 - }  
183 - }  
184 - }); 56 + uni.getSetting({
  57 + success: (res) => {
  58 + if (res.authSetting["scope.userLocation"] || !isOpenSetting) {
  59 + uni.getLocation({
  60 + // #ifndef MP-ALIPAY
  61 + type: "gcj02",
  62 + // #endif
  63 + success(res) {
  64 + console.log("successCallback");
  65 + successCallback(res);
  66 + },
  67 + fail(err) {
  68 + console.log("位置信息错误", err);
  69 + errCallback("位置信息获取失败");
  70 + },
  71 + });
  72 + } else {
  73 + errCallback("“位置信息”未授权");
  74 + isOpenSetting &&
  75 + uni.showModal({
  76 + title: "提示",
  77 + content: "请先在设置页面打开“位置信息”使用权限",
  78 + confirmText: "去设置",
  79 + cancelText: "再逛会",
  80 + success: (res) => {
  81 + if (res.confirm) {
  82 + uni.openSetting();
  83 + }
  84 + },
  85 + });
  86 + }
  87 + },
  88 + });
185 } 89 }
186 // 获取地址信息 90 // 获取地址信息
187 let locationAuthorize = true; 91 let locationAuthorize = true;
188 -export const getAppLatLon = function(successCallback, errCallback, isOpenSetting) {  
189 - const _this = this;  
190 - // #ifdef MP-WEIXIN  
191 - if (locationAuthorize && isOpenSetting) {  
192 - uni.authorize({  
193 - scope: 'scope.userLocation',  
194 - success: () => {  
195 - getMpLocation(successCallback, errCallback, isOpenSetting);  
196 - locationAuthorize = false;  
197 - },  
198 - fail: () => {  
199 - locationAuthorize = false;  
200 - }  
201 - });  
202 - } else {  
203 - getMpLocation(successCallback, errCallback, isOpenSetting);  
204 - }  
205 - // #endif  
206 - // #ifdef MP-ALIPAY  
207 - getMpLocation(successCallback, errCallback, false);  
208 - // #endif  
209 - // #ifdef H5  
210 - uni.getLocation({  
211 - type: 'gcj02',  
212 - success(res) {  
213 - console.log('successCallback')  
214 - successCallback(res);  
215 - },  
216 - fail(err) {  
217 - console.log("位置信息错误", err);  
218 - errCallback("位置信息获取失败");  
219 - }  
220 - });  
221 - // #endif  
222 -} 92 +export const getAppLatLon = function (
  93 + successCallback,
  94 + errCallback,
  95 + isOpenSetting
  96 +) {
  97 + const _this = this;
  98 + // #ifdef MP-WEIXIN
  99 + if (locationAuthorize && isOpenSetting) {
  100 + uni.authorize({
  101 + scope: "scope.userLocation",
  102 + success: () => {
  103 + getMpLocation(successCallback, errCallback, isOpenSetting);
  104 + locationAuthorize = false;
  105 + },
  106 + fail: () => {
  107 + locationAuthorize = false;
  108 + },
  109 + });
  110 + } else {
  111 + getMpLocation(successCallback, errCallback, isOpenSetting);
  112 + }
  113 + // #endif
  114 + // #ifdef MP-ALIPAY
  115 + getMpLocation(successCallback, errCallback, false);
  116 + // #endif
  117 + // #ifdef H5
  118 + uni.getLocation({
  119 + type: "gcj02",
  120 + success(res) {
  121 + console.log("successCallback");
  122 + successCallback(res);
  123 + },
  124 + fail(err) {
  125 + console.log("位置信息错误", err);
  126 + errCallback("位置信息获取失败");
  127 + },
  128 + });
  129 + // #endif
  130 +};
223 131
224 export function formatToDate(date = undefined, format = DATE_TIME_FORMAT) { 132 export function formatToDate(date = undefined, format = DATE_TIME_FORMAT) {
225 - return moment(date).format(format); 133 + return moment(date).format(format);
226 } 134 }
@@ -7,7 +7,9 @@ @@ -7,7 +7,9 @@
7 </view> 7 </view>
8 <view v-if="!nextStatus" style="margin-top: 40rpx;" class="f__login"> 8 <view v-if="!nextStatus" style="margin-top: 40rpx;" class="f__login">
9 <view class="loginPhone"> 9 <view class="loginPhone">
10 - <view class="form-row"><u-input v-model="phone" type="number" placeholder="请输入手机号码" border="bottom" /></view> 10 + <view class="form-row">
  11 + <u-input v-model="phone" type="number" placeholder="请输入手机号码" border="bottom" />
  12 + </view>
11 <view class="form-row"> 13 <view class="form-row">
12 <u-input type="number" v-model="vCode" placeholder="请输入验证码" border="bottom"> 14 <u-input type="number" v-model="vCode" placeholder="请输入验证码" border="bottom">
13 <template slot="suffix"> 15 <template slot="suffix">
@@ -22,15 +24,23 @@ @@ -22,15 +24,23 @@
22 <view class="loginPhone"> 24 <view class="loginPhone">
23 <view class="form-row u-flex"> 25 <view class="form-row u-flex">
24 <u-input v-model="password" :password="showPasswordF" placeholder="请设置6-20位新的登录密码" border="bottom"> 26 <u-input v-model="password" :password="showPasswordF" placeholder="请设置6-20位新的登录密码" border="bottom">
25 - <template slot="suffix" @click="showPasswordModeF">  
26 - <view style="padding:20rpx"><u-icon :name="showPasswordF ? '/static/eye-hide.png' : '/static/eye.png'"></u-icon></view> 27 + <template slot="suffix">
  28 + <view @click="showPasswordMode" style="padding: 10rpx">
  29 + <u-icon width="18" height="14" :name="
  30 + showPasswordF ? '/static/eye-hide.png' : '/static/eye.png'
  31 + "></u-icon>
  32 + </view>
27 </template> 33 </template>
28 </u-input> 34 </u-input>
29 </view> 35 </view>
30 <view class="form-row u-flex"> 36 <view class="form-row u-flex">
31 <u-input v-model="rePassword" :password="showPasswordS" placeholder="请再次输入新的登录密码" border="bottom"> 37 <u-input v-model="rePassword" :password="showPasswordS" placeholder="请再次输入新的登录密码" border="bottom">
32 - <template slot="suffix" @click="showPasswordModeS">  
33 - <view style="padding:20rpx"><u-icon :name="showPasswordS ? '/static/eye-hide.png' : '/static/eye.png'"></u-icon></view> 38 + <template slot="suffix">
  39 + <view @click="showPasswordModeS" style="padding: 10rpx">
  40 + <u-icon width="18" height="14" :name="
  41 + showPasswordS ? '/static/eye-hide.png' : '/static/eye.png'
  42 + "></u-icon>
  43 + </view>
34 </template> 44 </template>
35 </u-input> 45 </u-input>
36 </view> 46 </view>
@@ -41,161 +51,161 @@ @@ -41,161 +51,161 @@
41 </template> 51 </template>
42 52
43 <script> 53 <script>
44 -var clear;  
45 -export default {  
46 - data() {  
47 - return {  
48 - readonly: false,  
49 - codeText: '发送验证码',  
50 - phone: '', //号码  
51 - vCode: '', //验证码  
52 - nextStatus: false,  
53 - password: '',  
54 - rePassword: '',  
55 - showPasswordF: true,  
56 - showPasswordS: true  
57 - };  
58 - },  
59 - methods: {  
60 - //验证码按钮文字状态  
61 - getCodeState() {  
62 - const _this = this;  
63 - this.readonly = true;  
64 - this.codeText = '60s后重新获取';  
65 - var s = 60;  
66 - clear = setInterval(() => {  
67 - s--;  
68 - _this.codeText = s + 's后重新获取';  
69 - if (s <= 0) {  
70 - clearInterval(clear);  
71 - _this.codeText = '发送验证码';  
72 - _this.readonly = false;  
73 - }  
74 - }, 1000); 54 + var clear;
  55 + export default {
  56 + data() {
  57 + return {
  58 + readonly: false,
  59 + codeText: '发送验证码',
  60 + phone: '', //号码
  61 + vCode: '', //验证码
  62 + nextStatus: false,
  63 + password: '',
  64 + rePassword: '',
  65 + showPasswordF: true,
  66 + showPasswordS: true
  67 + };
75 }, 68 },
76 - //获取验证码  
77 - getVcode() {  
78 - if (this.readonly) {  
79 - uni.showToast({  
80 - title: '验证码已发送~',  
81 - icon: 'none'  
82 - });  
83 - return;  
84 - }  
85 - if (this.phone == '') {  
86 - uni.showToast({  
87 - title: '请输入手机号~',  
88 - icon: 'none'  
89 - });  
90 - return;  
91 - }  
92 - const phoneRegular = /^1\d{10}$/;  
93 - if (!phoneRegular.test(this.phone)) {  
94 - uni.showToast({  
95 - title: '手机号格式不正确~',  
96 - icon: 'none'  
97 - });  
98 - return;  
99 - }  
100 - let httpData = {};  
101 - // 获取验证码接口  
102 - uni.$u.http  
103 - .post(`/yt/noauth/reset_code/${this.phone}`)  
104 - .then(res => {  
105 - this.getCodeState(); //开始倒计时  
106 - })  
107 - .catch(err => { 69 + methods: {
  70 + //验证码按钮文字状态
  71 + getCodeState() {
  72 + const _this = this;
  73 + this.readonly = true;
  74 + this.codeText = '60s后重新获取';
  75 + var s = 60;
  76 + clear = setInterval(() => {
  77 + s--;
  78 + _this.codeText = s + 's后重新获取';
  79 + if (s <= 0) {
  80 + clearInterval(clear);
  81 + _this.codeText = '发送验证码';
  82 + _this.readonly = false;
  83 + }
  84 + }, 1000);
  85 + },
  86 + //获取验证码
  87 + getVcode() {
  88 + if (this.readonly) {
108 uni.showToast({ 89 uni.showToast({
109 - title: err.data.msg, 90 + title: '验证码已发送~',
110 icon: 'none' 91 icon: 'none'
111 }); 92 });
112 - });  
113 - },  
114 - onNextSubmit() {  
115 - const phoneRegular = /^1\d{10}$/;  
116 - if (this.phone == '') {  
117 - uni.showToast({  
118 - title: '请输入手机号码~',  
119 - icon: 'none'  
120 - });  
121 - return;  
122 - } else if (!phoneRegular.test(this.phone)) {  
123 - uni.showToast({  
124 - title: '手机号格式不正确~',  
125 - icon: 'none'  
126 - });  
127 - return;  
128 - }  
129 - if (this.vCode == '') {  
130 - uni.showToast({  
131 - title: '请输入验证码~',  
132 - icon: 'none'  
133 - });  
134 - return;  
135 - } else if (!/^\d{6}$/.test(this.vCode)) {  
136 - uni.showToast({  
137 - title: '验证码格式不正确~',  
138 - icon: 'none'  
139 - });  
140 - return;  
141 - }  
142 - this.nextStatus = true;  
143 - },  
144 - showPhone() {  
145 - this.nextStatus = false;  
146 - },  
147 - onSubmit() {  
148 - const passReg = /^(?=.*?[A-Z])(?=(.*[a-z]){1,})(?=(.*[\d]){1,})(?=(.*[\W]){1,})(?!.*\s).{8,}$/;  
149 - if (this.password == '' && this.rePassword == '') {  
150 - uni.showToast({  
151 - title: '请输入密码~',  
152 - icon: 'none'  
153 - });  
154 - return;  
155 - } else if (!passReg.test(this.password) && !passReg.test(this.rePassword)) {  
156 - //uni.showToast,字数过长,会造成手机上显示不完全,官方bug,采用uni.showModal  
157 - uni.showModal({  
158 - title: '提示',  
159 - content: '密码格式不正确(至少一个大写英文字母、至少一个小写英文字母、至少一位数字、至少一个特殊字符、最少八个字符)~',  
160 - showCancel: false  
161 - });  
162 - return;  
163 - }  
164 - if (this.password !== this.rePassword) return uni.$u.toast('两次输入密码不一致');  
165 - let httpData = {  
166 - password: this.password,  
167 - phoneNumber: this.phone,  
168 - userId: this.vCode  
169 - };  
170 - uni.$u.http  
171 - .post(`/yt/noauth/reset/${this.phone}`, httpData)  
172 - .then(res => { 93 + return;
  94 + }
  95 + if (this.phone == '') {
173 uni.showToast({ 96 uni.showToast({
174 - title: '重置密码成功~', 97 + title: '请输入手机号~',
175 icon: 'none' 98 icon: 'none'
176 - }).then(res => {  
177 - uni.reLaunch({  
178 - url: '/publicLoginSubPage/public/login' 99 + });
  100 + return;
  101 + }
  102 + const phoneRegular = /^1\d{10}$/;
  103 + if (!phoneRegular.test(this.phone)) {
  104 + uni.showToast({
  105 + title: '手机号格式不正确~',
  106 + icon: 'none'
  107 + });
  108 + return;
  109 + }
  110 + let httpData = {};
  111 + // 获取验证码接口
  112 + uni.$u.http
  113 + .post(`/yt/noauth/reset_code/${this.phone}`)
  114 + .then(res => {
  115 + this.getCodeState(); //开始倒计时
  116 + })
  117 + .catch(err => {
  118 + uni.showToast({
  119 + title: err.data.msg,
  120 + icon: 'none'
179 }); 121 });
180 }); 122 });
181 - })  
182 - .catch(err => { 123 + },
  124 + onNextSubmit() {
  125 + const phoneRegular = /^1\d{10}$/;
  126 + if (this.phone == '') {
183 uni.showToast({ 127 uni.showToast({
184 - title: err.data.msg, 128 + title: '请输入手机号码~',
185 icon: 'none' 129 icon: 'none'
186 }); 130 });
187 - });  
188 - },  
189 - showPasswordModeF() {  
190 - this.showPasswordF = !this.showPasswordF;  
191 - },  
192 - showPasswordModeS() {  
193 - this.showPasswordS = !this.showPasswordS; 131 + return;
  132 + } else if (!phoneRegular.test(this.phone)) {
  133 + uni.showToast({
  134 + title: '手机号格式不正确~',
  135 + icon: 'none'
  136 + });
  137 + return;
  138 + }
  139 + if (this.vCode == '') {
  140 + uni.showToast({
  141 + title: '请输入验证码~',
  142 + icon: 'none'
  143 + });
  144 + return;
  145 + } else if (!/^\d{6}$/.test(this.vCode)) {
  146 + uni.showToast({
  147 + title: '验证码格式不正确~',
  148 + icon: 'none'
  149 + });
  150 + return;
  151 + }
  152 + this.nextStatus = true;
  153 + },
  154 + showPhone() {
  155 + this.nextStatus = false;
  156 + },
  157 + onSubmit() {
  158 + const passReg = /^(?=.*?[A-Z])(?=(.*[a-z]){1,})(?=(.*[\d]){1,})(?=(.*[\W]){1,})(?!.*\s).{8,}$/;
  159 + if (this.password == '' && this.rePassword == '') {
  160 + uni.showToast({
  161 + title: '请输入密码~',
  162 + icon: 'none'
  163 + });
  164 + return;
  165 + } else if (!passReg.test(this.password) && !passReg.test(this.rePassword)) {
  166 + //uni.showToast,字数过长,会造成手机上显示不完全,官方bug,采用uni.showModal
  167 + uni.showModal({
  168 + title: '提示',
  169 + content: '密码格式不正确(至少一个大写英文字母、至少一个小写英文字母、至少一位数字、至少一个特殊字符、最少八个字符)~',
  170 + showCancel: false
  171 + });
  172 + return;
  173 + }
  174 + if (this.password !== this.rePassword) return uni.$u.toast('两次输入密码不一致');
  175 + let httpData = {
  176 + password: this.password,
  177 + phoneNumber: this.phone,
  178 + userId: this.vCode
  179 + };
  180 + uni.$u.http
  181 + .post(`/yt/noauth/reset/${this.phone}`, httpData)
  182 + .then(res => {
  183 + uni.showToast({
  184 + title: '重置密码成功~',
  185 + icon: 'none'
  186 + }).then(res => {
  187 + uni.reLaunch({
  188 + url: '/publicLoginSubPage/public/login'
  189 + });
  190 + });
  191 + })
  192 + .catch(err => {
  193 + uni.showToast({
  194 + title: err.data.msg,
  195 + icon: 'none'
  196 + });
  197 + });
  198 + },
  199 + showPasswordMode() {
  200 + this.showPasswordF = !this.showPasswordF;
  201 + },
  202 + showPasswordModeS() {
  203 + this.showPasswordS = !this.showPasswordS;
  204 + }
194 } 205 }
195 - }  
196 -}; 206 + };
197 </script> 207 </script>
198 208
199 <style lang="scss" scoped> 209 <style lang="scss" scoped>
200 -@import './static/findPassword.scss'; 210 + @import './static/findPassword.scss';
201 </style> 211 </style>
1 <template> 1 <template>
2 - <view  
3 - class="login-page"  
4 - style="background-size: 750rpx 1400rpx; min-height: 100vh;"  
5 - :style="{ backgroundImage: 'url(' + (mpOwnConfig.bg !== undefined ? mpOwnConfig.bg : `${defaultLogo}`) + ')' }"  
6 - > 2 + <view class="login-page" style="background-size: 750rpx 1400rpx; min-height: 100vh" :style="{
  3 + backgroundImage:
  4 + 'url(' +
  5 + (mpOwnConfig.bg !== undefined ? mpOwnConfig.bg : `${defaultLogo}`) +
  6 + ')',
  7 + }">
7 <!-- 公共组件-每个页面必须引入 --> 8 <!-- 公共组件-每个页面必须引入 -->
8 <public-module></public-module> 9 <public-module></public-module>
9 <view class="u-flex login-main"> 10 <view class="u-flex login-main">
10 <view class="content"> 11 <view class="content">
11 <view class="hello login-text-muted">您好,</view> 12 <view class="hello login-text-muted">您好,</view>
12 <!-- <view class="hello-welcome login-text-muted">欢迎来到ThingsKit!</view> --> 13 <!-- <view class="hello-welcome login-text-muted">欢迎来到ThingsKit!</view> -->
13 - <view style="width:587rpx" class="text-clip hello-welcome login-text-muted">欢迎来到{{ mpOwnConfig.name !== undefined ? mpOwnConfig.name : 'ThingsKit' }}!</view> 14 + <view style="width: 587rpx" class="text-clip hello-welcome login-text-muted">欢迎来到{{
  15 + mpOwnConfig.name !== undefined ? mpOwnConfig.name : "ThingsKit"
  16 + }}!</view>
14 </view> 17 </view>
15 </view> 18 </view>
16 19
17 <view class="f__login"> 20 <view class="f__login">
18 <view class="loginPhone"> 21 <view class="loginPhone">
19 - <view class="form-row u-flex"><u-input v-model="loginForm.username" type="text" placeholder="请输入登录账号" border="bottom" /></view> 22 + <view class="form-row u-flex">
  23 + <u-input v-model="loginForm.username" type="text" placeholder="请输入登录账号" border="bottom" />
  24 + </view>
20 25
21 <view class="form-row u-flex"> 26 <view class="form-row u-flex">
22 - <u-input v-model="loginForm.password" :password="showPassword" placeholder="请输入登录密码" border="bottom"> 27 + <u-input v-model="loginForm.password" :password="showPassword" placeholder="请输入登录密码"
  28 + border="bottom">
23 <template slot="suffix"> 29 <template slot="suffix">
24 <view @click="showPasswordMode" style="padding: 10rpx"> 30 <view @click="showPasswordMode" style="padding: 10rpx">
25 - <u-icon width="18" height="14" :name="showPassword ? '/static/eye-hide.png' : '/static/eye.png'"></u-icon> 31 + <u-icon width="18" height="14" :name="
  32 + showPassword ? '/static/eye-hide.png' : '/static/eye.png'
  33 + "></u-icon>
26 </view> 34 </view>
27 </template> 35 </template>
28 </u-input> 36 </u-input>
29 </view> 37 </view>
30 38
31 - <button class="submit" size="default" @click="onSubmitFunc"><text class="text">登录</text></button> 39 + <button class="submit" size="default" @click="onSubmitFunc">
  40 + <text class="text">登录</text>
  41 + </button>
32 42
33 <view class="u-flex row-item"> 43 <view class="u-flex row-item">
34 <view class="row-phone login-text-gray" @click="openCodeFunc">手机验证码登录</view> 44 <view class="row-phone login-text-gray" @click="openCodeFunc">手机验证码登录</view>
@@ -41,7 +51,9 @@ @@ -41,7 +51,9 @@
41 51
42 <view style="height: 20rpx"></view> 52 <view style="height: 20rpx"></view>
43 53
44 - <button class="link-image" @tap="onWenxinAuthorization"><image class="image" src="../../static/weixin.png" mode="aspectFill"></image></button> 54 + <button class="link-image" @tap="onWenxinAuthorization">
  55 + <image class="image" src="../../static/weixin.png" mode="aspectFill"></image>
  56 + </button>
45 </view> 57 </view>
46 </view> 58 </view>
47 </view> 59 </view>
@@ -49,246 +61,262 @@ @@ -49,246 +61,262 @@
49 </template> 61 </template>
50 62
51 <script> 63 <script>
52 -import { mapMutations, mapActions, mapState } from 'vuex';  
53 -import { loginApp } from '@/config/login';  
54 -import baseUrl from '@/config/baseUrl.js';  
55 -import WXBizDataCrypt from '@/config/WXBizDataCrypt.js'; 64 + import {
  65 + mapMutations,
  66 + mapActions,
  67 + mapState
  68 + } from "vuex";
  69 + import {
  70 + loginApp
  71 + } from "@/config/login";
  72 + import baseUrl from "@/config/baseUrl.js";
  73 + import WXBizDataCrypt from "@/config/WXBizDataCrypt.js";
56 74
57 -export default {  
58 - data() {  
59 - return {  
60 - loginForm: {  
61 - username: '', 75 + export default {
  76 + data() {
  77 + return {
  78 + loginForm: {
  79 + username: "",
62 80
63 - password: ''  
64 - },  
65 - showPassword: true,  
66 - code: '',  
67 - openid: '',  
68 - mpOwnConfig: {},  
69 - defaultLogo: '/static/login.png'  
70 - };  
71 - },  
72 - onLoad() {  
73 - wx.login({  
74 - success: res => {  
75 - if (res.code) {  
76 - this.code = res.code;  
77 - //这里获取openid  
78 - } else {  
79 - return;  
80 - }  
81 - }  
82 - });  
83 - },  
84 - computed: {  
85 - ...mapState(['plateInfo'])  
86 - },  
87 - mounted() {  
88 - this.getPlateForm();  
89 - },  
90 - onShow() {  
91 - this.getPlateForm();  
92 - },  
93 - methods: {  
94 - //获取平台定制信息  
95 - getPlateForm() {  
96 - uni.$u.http.get('/yt/app_design/get').then(res => {  
97 - if (res) {  
98 - this.mpOwnConfig = {  
99 - bg: res.background,  
100 - logo: res.logo,  
101 - name: res.name  
102 - };  
103 - } 81 + password: "",
  82 + },
  83 + showPassword: true,
  84 + code: "",
  85 + openid: "",
  86 + mpOwnConfig: {},
  87 + defaultLogo: "/static/login.png",
  88 + };
  89 + },
  90 + onLoad() {
  91 + //#ifdef MP-WEIXIN
  92 + wx.login({
  93 + success: (res) => {
  94 + if (res.code) {
  95 + this.code = res.code;
  96 + //这里获取openid
  97 + } else {
  98 + return;
  99 + }
  100 + },
104 }); 101 });
  102 + //#endif
  103 + },
  104 + computed: {
  105 + ...mapState(["plateInfo"]),
  106 + },
  107 + mounted() {
  108 + this.getPlateForm();
  109 + },
  110 + onShow() {
  111 + this.getPlateForm();
105 }, 112 },
106 - ...mapMutations(['setUserInfo', 'setPlateInfo']),  
107 - ...mapActions(['updateBadgeTotal']),  
108 - //微信授权登录  
109 - //#ifdef MP-WEIXIN  
110 - onWenxinAuthorization() {  
111 - wx.getUserProfile({  
112 - desc: '微信第三方授权',  
113 - success: reswenxin => {  
114 - if (reswenxin.errMsg === 'getUserProfile:ok' && reswenxin.encryptedData) {  
115 - //获取用户信息  
116 - let obj = {  
117 - avatarUrl: reswenxin.userInfo.avatarUrl,  
118 - thirdUserId: this.openid 113 + methods: {
  114 + //获取平台定制信息
  115 + getPlateForm() {
  116 + uni.$u.http.get("/yt/app_design/get").then((res) => {
  117 + if (res) {
  118 + this.mpOwnConfig = {
  119 + bg: res.background,
  120 + logo: res.logo,
  121 + name: res.name,
119 }; 122 };
120 - //判断是否需要绑定  
121 - uni.$u.http  
122 - .get(`/yt/third/login/${this.code}`)  
123 - .then(res => {  
124 - if (res.token == '' || (res.token == null && res.thirdUserId)) {  
125 - //需要绑定  
126 - let userInfo = {  
127 - isThirdLogin: true, //用于判断是否是第三方登录并且需要绑定账号  
128 - avatar: obj.avatarUrl,  
129 - thirdUserId: res.thirdUserId  
130 - };  
131 - this.setUserInfo(userInfo);  
132 - //设置全局变量openId  
133 - getApp().globalData.openId = res.thirdUserId;  
134 - uni.reLaunch({  
135 - url: '../../pages/personal/personal'  
136 - });  
137 - } else {  
138 - // 不需要绑定,直接第三方登录使用  
139 - let resObj = {  
140 - refreshToken: res.refreshToken,  
141 - isToken: res.token  
142 - };  
143 - let userInfo = {  
144 - ...resObj,  
145 - token: true, //token用于判断是否登录  
146 - isThirdLoginAndNoDind: true, //用于判断是否是第三方登录并且不需要绑定账号  
147 - thirdUserId: res.thirdUserId  
148 - };  
149 - //设置全局变量openId  
150 - getApp().globalData.openId = res.thirdUserId;  
151 - if (userInfo.token) { 123 + }
  124 + });
  125 + },
  126 + ...mapMutations(["setUserInfo", "setPlateInfo"]),
  127 + ...mapActions(["updateBadgeTotal"]),
  128 + //微信授权登录
  129 + //#ifdef MP-WEIXIN
  130 + onWenxinAuthorization() {
  131 + wx.getUserProfile({
  132 + desc: "微信第三方授权",
  133 + success: (reswenxin) => {
  134 + if (
  135 + reswenxin.errMsg === "getUserProfile:ok" &&
  136 + reswenxin.encryptedData
  137 + ) {
  138 + //获取用户信息
  139 + let obj = {
  140 + avatarUrl: reswenxin.userInfo.avatarUrl,
  141 + thirdUserId: this.openid,
  142 + };
  143 + //判断是否需要绑定
  144 + uni.$u.http
  145 + .get(`/yt/third/login/${this.code}`)
  146 + .then((res) => {
  147 + if (res.token == "" || (res.token == null && res.thirdUserId)) {
  148 + //需要绑定
  149 + let userInfo = {
  150 + isThirdLogin: true, //用于判断是否是第三方登录并且需要绑定账号
  151 + avatar: obj.avatarUrl,
  152 + thirdUserId: res.thirdUserId,
  153 + };
152 this.setUserInfo(userInfo); 154 this.setUserInfo(userInfo);
153 - }  
154 - uni.showToast({  
155 - title: '第三方账号登录成功',  
156 - icon: 'none'  
157 - }).then(async res => {  
158 - this.saveUserInfo();  
159 - await this.getAlarmTotalData(); 155 + //设置全局变量openId
  156 + getApp().globalData.openId = res.thirdUserId;
160 uni.reLaunch({ 157 uni.reLaunch({
161 - url: '/pages/personal/personal' 158 + url: "../../pages/personal/personal",
162 }); 159 });
163 - });  
164 - }  
165 - })  
166 - .catch(e => {  
167 - if (e?.data?.data === null) {  
168 - uni.$u.toast(e.data?.msg);  
169 - }  
170 - });  
171 - }  
172 - }, 160 + } else {
  161 + // 不需要绑定,直接第三方登录使用
  162 + let resObj = {
  163 + refreshToken: res.refreshToken,
  164 + isToken: res.token,
  165 + };
  166 + let userInfo = {
  167 + ...resObj,
  168 + token: true, //token用于判断是否登录
  169 + isThirdLoginAndNoDind: true, //用于判断是否是第三方登录并且不需要绑定账号
  170 + thirdUserId: res.thirdUserId,
  171 + };
  172 + //设置全局变量openId
  173 + getApp().globalData.openId = res.thirdUserId;
  174 + if (userInfo.token) {
  175 + this.setUserInfo(userInfo);
  176 + }
  177 + uni
  178 + .showToast({
  179 + title: "第三方账号登录成功",
  180 + icon: "none",
  181 + })
  182 + .then(async (res) => {
  183 + this.saveUserInfo();
  184 + await this.getAlarmTotalData();
  185 + uni.reLaunch({
  186 + url: "/pages/personal/personal",
  187 + });
  188 + });
  189 + }
  190 + })
  191 + .catch((e) => {
  192 + if (e?.data?.data === null) {
  193 + uni.$u.toast(e.data?.msg);
  194 + }
  195 + });
  196 + }
  197 + },
173 198
174 - fail: res => {  
175 - //拒绝授权 199 + fail: (res) => {
  200 + //拒绝授权
176 201
177 - return;  
178 - }  
179 - });  
180 - }, 202 + return;
  203 + },
  204 + });
  205 + },
181 206
182 - //#endif 207 + //#endif
183 208
184 - saveUserInfo() {  
185 - //储存个人信息  
186 - uni.$u.http.get('/yt/user/me/info').then(res => { 209 + saveUserInfo() {
  210 + //储存个人信息
  211 + uni.$u.http.get("/yt/user/me/info").then((res) => {
  212 + if (res) {
  213 + this.setUserInfo(res);
  214 + }
  215 + });
  216 + //储存平台信息
  217 + uni.$u.http.get("/yt/platform/get").then((res) => {
  218 + if (res) {
  219 + this.setPlateInfo(res);
  220 + }
  221 + });
  222 + },
  223 + async getAlarmTotalData() {
  224 + const res = await uni.$u.http.get("/yt/homepage/app?login=true");
187 if (res) { 225 if (res) {
188 - this.setUserInfo(res); 226 + //异步实时更新告警徽标数
  227 + this.updateBadgeTotal(res.totalAlarm?.activedAlarm);
189 } 228 }
190 - });  
191 - //储存平台信息  
192 - uni.$u.http.get('/yt/platform/get').then(res => {  
193 - if (res) {  
194 - this.setPlateInfo(res); 229 + },
  230 + onSubmitFunc() {
  231 + if (this.loginForm.username == "") {
  232 + return uni.$u.toast("请输入登录账号~");
195 } 233 }
196 - });  
197 - },  
198 - async getAlarmTotalData() {  
199 - const res = await uni.$u.http.get('/yt/homepage/app?login=true');  
200 - if (res) {  
201 - //异步实时更新告警徽标数  
202 - this.updateBadgeTotal(res.totalAlarm?.activedAlarm);  
203 - }  
204 - },  
205 - onSubmitFunc() {  
206 - if (this.loginForm.username == '') {  
207 - return uni.$u.toast('请输入登录账号~');  
208 - }  
209 - const passReg = /^(?=.*?[A-Z])(?=(.*[a-z]){1,})(?=(.*[\d]){1,})(?=(.*[\W]){1,})(?!.*\s).{8,}$/; 234 + const passReg =
  235 + /^(?=.*?[A-Z])(?=(.*[a-z]){1,})(?=(.*[\d]){1,})(?=(.*[\W]){1,})(?!.*\s).{8,}$/;
210 236
211 - if (this.loginForm.password == '') {  
212 - uni.showToast({  
213 - title: '请输入登录密码~', 237 + if (this.loginForm.password == "") {
  238 + uni.showToast({
  239 + title: "请输入登录密码~",
214 240
215 - icon: 'none'  
216 - });  
217 - return;  
218 - } else if (!passReg.test(this.loginForm.password)) {  
219 - //uni.showToast,字数过长,会造成手机上显示不完全,官方bug,采用uni.showModal  
220 - uni.showModal({  
221 - title: '提示',  
222 - content: '密码格式不正确(至少一个大写英文字母、至少一个小写英文字母、至少一位数字、至少一个特殊字符、最少八个字符)~',  
223 - showCancel: false  
224 - });  
225 - return;  
226 - }  
227 - uni.$u.http  
228 - .post('/auth/login', this.loginForm) 241 + icon: "none",
  242 + });
  243 + return;
  244 + } else if (!passReg.test(this.loginForm.password)) {
  245 + //uni.showToast,字数过长,会造成手机上显示不完全,官方bug,采用uni.showModal
  246 + uni.showModal({
  247 + title: "提示",
  248 + content: "密码格式不正确(至少一个大写英文字母、至少一个小写英文字母、至少一位数字、至少一个特殊字符、最少八个字符)~",
  249 + showCancel: false,
  250 + });
  251 + return;
  252 + }
  253 + uni.$u.http
  254 + .post("/auth/login", this.loginForm)
229 255
230 - .then(res => {  
231 - if (res) {  
232 - // 储存登录信息 256 + .then((res) => {
  257 + if (res) {
  258 + // 储存登录信息
233 259
234 - let resObj = {  
235 - refreshToken: res.refreshToken, 260 + let resObj = {
  261 + refreshToken: res.refreshToken,
236 262
237 - isToken: res.token  
238 - }; 263 + isToken: res.token,
  264 + };
239 265
240 - let userInfo = {  
241 - ...resObj, 266 + let userInfo = {
  267 + ...resObj,
242 268
243 - token: true, //token用于判断是否登录 269 + token: true, //token用于判断是否登录
244 270
245 - isThirdLogin: false,  
246 - isThirdLoginAndNoDind: false  
247 - }; 271 + isThirdLogin: false,
  272 + isThirdLoginAndNoDind: false,
  273 + };
248 274
249 - if (userInfo.token) {  
250 - this.setUserInfo(userInfo);  
251 - } 275 + if (userInfo.token) {
  276 + this.setUserInfo(userInfo);
  277 + }
252 278
253 - uni.showToast({  
254 - title: '登录成功~', 279 + uni
  280 + .showToast({
  281 + title: "登录成功~",
255 282
256 - icon: 'none'  
257 - }).then(async res => {  
258 - this.saveUserInfo();  
259 - await this.getAlarmTotalData();  
260 - uni.reLaunch({  
261 - url: '/pages/personal/personal'  
262 - });  
263 - });  
264 - }  
265 - }) 283 + icon: "none",
  284 + })
  285 + .then(async (res) => {
  286 + this.saveUserInfo();
  287 + uni.reLaunch({
  288 + url: "/pages/personal/personal",
  289 + });
  290 + await this.getAlarmTotalData();
  291 + });
  292 + }
  293 + })
266 294
267 - .catch(e => {  
268 - uni.$u.toast(e.data?.message); 295 + .catch((e) => {
  296 + uni.$u.toast(e.data?.message);
  297 + });
  298 + },
  299 + openCodeFunc() {
  300 + uni.navigateTo({
  301 + url: "../other/code",
269 }); 302 });
  303 + },
  304 + findPassrordFunc() {
  305 + uni.navigateTo({
  306 + url: "../other/findPassword",
  307 + });
  308 + },
  309 + showPasswordMode() {
  310 + this.showPassword = !this.showPassword;
  311 + },
270 }, 312 },
271 - openCodeFunc() {  
272 - uni.navigateTo({  
273 - url: '../other/code'  
274 - });  
275 - },  
276 - findPassrordFunc() {  
277 - uni.navigateTo({  
278 - url: '../other/findPassword'  
279 - });  
280 - },  
281 - showPasswordMode() {  
282 - this.showPassword = !this.showPassword;  
283 - }  
284 - }  
285 -}; 313 + };
286 </script> 314 </script>
287 315
288 <style lang="scss" scoped> 316 <style lang="scss" scoped>
289 -@import './static/login.scss'; 317 + @import "./static/login.scss";
290 318
291 -/deep/ button {  
292 - background: rgba(0, 0, 0, 0);  
293 -} 319 + /deep/ button {
  320 + background: rgba(0, 0, 0, 0);
  321 + }
294 </style> 322 </style>
@@ -49,6 +49,7 @@ button { @@ -49,6 +49,7 @@ button {
49 ///////////////////////////////////////////////////////////////小程序、app抽取公共样式///////////////////////////////////////////////////////////////////// 49 ///////////////////////////////////////////////////////////////小程序、app抽取公共样式/////////////////////////////////////////////////////////////////////
50 //通用(设备、告警、摄像头分页头部组织和设备数和设备、告警里面的详情(左边的文本) 50 //通用(设备、告警、摄像头分页头部组织和设备数和设备、告警里面的详情(左边的文本)
51 .text-org-bold { 51 .text-org-bold {
  52 + width:200rpx;
52 color: #333333; 53 color: #333333;
53 font-family: PingFangSC-Medium, PingFang SC; 54 font-family: PingFangSC-Medium, PingFang SC;
54 font-weight: 400; 55 font-weight: 400;